diff options
Diffstat (limited to 'routers')
-rw-r--r-- | routers/admin/admin.go | 92 | ||||
-rw-r--r-- | routers/admin/user.go | 35 | ||||
-rw-r--r-- | routers/dashboard.go | 7 | ||||
-rw-r--r-- | routers/repo/issue.go | 85 | ||||
-rw-r--r-- | routers/repo/repo.go | 303 | ||||
-rw-r--r-- | routers/repo/single.go | 307 | ||||
-rw-r--r-- | routers/user/user.go | 65 |
7 files changed, 580 insertions, 314 deletions
diff --git a/routers/admin/admin.go b/routers/admin/admin.go index 2e19b99c..c0f39f71 100644 --- a/routers/admin/admin.go +++ b/routers/admin/admin.go @@ -5,7 +5,10 @@ package admin import ( + "fmt" + "runtime" "strings" + "time" "github.com/codegangsta/martini" @@ -14,10 +17,93 @@ import ( "github.com/gogits/gogs/modules/middleware" ) +var startTime = time.Now() + +var sysStatus struct { + Uptime string + NumGoroutine int + + // General statistics. + MemAllocated string // bytes allocated and still in use + MemTotal string // bytes allocated (even if freed) + MemSys string // bytes obtained from system (sum of XxxSys below) + Lookups uint64 // number of pointer lookups + MemMallocs uint64 // number of mallocs + MemFrees uint64 // number of frees + + // Main allocation heap statistics. + HeapAlloc string // bytes allocated and still in use + HeapSys string // bytes obtained from system + HeapIdle string // bytes in idle spans + HeapInuse string // bytes in non-idle span + HeapReleased string // bytes released to the OS + HeapObjects uint64 // total number of allocated objects + + // Low-level fixed-size structure allocator statistics. + // Inuse is bytes used now. + // Sys is bytes obtained from system. + StackInuse string // bootstrap stacks + StackSys string + MSpanInuse string // mspan structures + MSpanSys string + MCacheInuse string // mcache structures + MCacheSys string + BuckHashSys string // profiling bucket hash table + GCSys string // GC metadata + OtherSys string // other system allocations + + // Garbage collector statistics. + NextGC string // next run in HeapAlloc time (bytes) + LastGC string // last run in absolute time (ns) + PauseTotalNs string + PauseNs string // circular buffer of recent GC pause times, most recent at [(NumGC+255)%256] + NumGC uint32 +} + +func updateSystemStatus() { + sysStatus.Uptime = base.TimeSincePro(startTime) + + m := new(runtime.MemStats) + runtime.ReadMemStats(m) + sysStatus.NumGoroutine = runtime.NumGoroutine() + + sysStatus.MemAllocated = base.FileSize(int64(m.Alloc)) + sysStatus.MemTotal = base.FileSize(int64(m.TotalAlloc)) + sysStatus.MemSys = base.FileSize(int64(m.Sys)) + sysStatus.Lookups = m.Lookups + sysStatus.MemMallocs = m.Mallocs + sysStatus.MemFrees = m.Frees + + sysStatus.HeapAlloc = base.FileSize(int64(m.HeapAlloc)) + sysStatus.HeapSys = base.FileSize(int64(m.HeapSys)) + sysStatus.HeapIdle = base.FileSize(int64(m.HeapIdle)) + sysStatus.HeapInuse = base.FileSize(int64(m.HeapInuse)) + sysStatus.HeapReleased = base.FileSize(int64(m.HeapReleased)) + sysStatus.HeapObjects = m.HeapObjects + + sysStatus.StackInuse = base.FileSize(int64(m.StackInuse)) + sysStatus.StackSys = base.FileSize(int64(m.StackSys)) + sysStatus.MSpanInuse = base.FileSize(int64(m.MSpanInuse)) + sysStatus.MSpanSys = base.FileSize(int64(m.MSpanSys)) + sysStatus.MCacheInuse = base.FileSize(int64(m.MCacheInuse)) + sysStatus.MCacheSys = base.FileSize(int64(m.MCacheSys)) + sysStatus.BuckHashSys = base.FileSize(int64(m.BuckHashSys)) + sysStatus.GCSys = base.FileSize(int64(m.GCSys)) + sysStatus.OtherSys = base.FileSize(int64(m.OtherSys)) + + sysStatus.NextGC = base.FileSize(int64(m.NextGC)) + sysStatus.LastGC = fmt.Sprintf("%.1fs", float64(time.Now().UnixNano()-int64(m.LastGC))/1000/1000/1000) + sysStatus.PauseTotalNs = fmt.Sprintf("%.1fs", float64(m.PauseTotalNs)/1000/1000/1000) + sysStatus.PauseNs = fmt.Sprintf("%.3fs", float64(m.PauseNs[(m.NumGC+255)%256])/1000/1000/1000) + sysStatus.NumGC = m.NumGC +} + func Dashboard(ctx *middleware.Context) { ctx.Data["Title"] = "Admin Dashboard" ctx.Data["PageIsDashboard"] = true ctx.Data["Stats"] = models.GetStatistic() + updateSystemStatus() + ctx.Data["SysStatus"] = sysStatus ctx.HTML(200, "admin/dashboard") } @@ -70,6 +156,12 @@ func Config(ctx *middleware.Context) { ctx.Data["CacheAdapter"] = base.CacheAdapter ctx.Data["CacheConfig"] = base.CacheConfig + ctx.Data["SessionProvider"] = base.SessionProvider + ctx.Data["SessionConfig"] = base.SessionConfig + + ctx.Data["PictureService"] = base.PictureService + ctx.Data["PictureRootPath"] = base.PictureRootPath + ctx.Data["LogMode"] = base.LogMode ctx.Data["LogConfig"] = base.LogConfig diff --git a/routers/admin/user.go b/routers/admin/user.go index d6f85232..7f66c552 100644 --- a/routers/admin/user.go +++ b/routers/admin/user.go @@ -107,3 +107,38 @@ func EditUser(ctx *middleware.Context, params martini.Params, form auth.AdminEdi log.Trace("%s User profile updated by admin(%s): %s", ctx.Req.RequestURI, ctx.User.LowerName, ctx.User.LowerName) } + +func DeleteUser(ctx *middleware.Context, params martini.Params) { + ctx.Data["Title"] = "Edit Account" + ctx.Data["PageIsUsers"] = true + + uid, err := base.StrTo(params["userid"]).Int() + if err != nil { + ctx.Handle(200, "admin.user.EditUser", err) + return + } + + u, err := models.GetUserById(int64(uid)) + if err != nil { + ctx.Handle(200, "admin.user.EditUser", err) + return + } + + if err = models.DeleteUser(u); err != nil { + ctx.Data["HasError"] = true + switch err { + case models.ErrUserOwnRepos: + ctx.Data["ErrorMsg"] = "This account still has ownership of repository, owner has to delete or transfer them first." + ctx.Data["User"] = u + ctx.HTML(200, "admin/users/edit") + default: + ctx.Handle(200, "admin.user.DeleteUser", err) + } + return + } + + log.Trace("%s User deleted by admin(%s): %s", ctx.Req.RequestURI, + ctx.User.LowerName, ctx.User.LowerName) + + ctx.Redirect("/admin/users") +} diff --git a/routers/dashboard.go b/routers/dashboard.go index f61d67b7..dafe9f31 100644 --- a/routers/dashboard.go +++ b/routers/dashboard.go @@ -20,5 +20,12 @@ func Home(ctx *middleware.Context) { func Help(ctx *middleware.Context) { ctx.Data["PageIsHelp"] = true + ctx.Data["Title"] = "Help" ctx.HTML(200, "help") } + +func NotFound(ctx *middleware.Context) { + ctx.Data["PageIsNotFound"] = true + ctx.Data["Title"] = 404 + ctx.Handle(404, "home.NotFound", nil) +} diff --git a/routers/repo/issue.go b/routers/repo/issue.go new file mode 100644 index 00000000..78fe4b25 --- /dev/null +++ b/routers/repo/issue.go @@ -0,0 +1,85 @@ +// Copyright 2014 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package repo + +import ( + "fmt" + + "github.com/codegangsta/martini" + + "github.com/gogits/gogs/models" + "github.com/gogits/gogs/modules/auth" + "github.com/gogits/gogs/modules/base" + "github.com/gogits/gogs/modules/log" + "github.com/gogits/gogs/modules/middleware" +) + +func Issues(ctx *middleware.Context, params martini.Params) { + ctx.Data["Title"] = "Issues" + ctx.Data["IsRepoToolbarIssues"] = true + + milestoneId, _ := base.StrTo(params["milestone"]).Int() + page, _ := base.StrTo(params["page"]).Int() + + var err error + ctx.Data["Issues"], err = models.GetIssues(0, ctx.Repo.Repository.Id, 0, + int64(milestoneId), page, params["state"] == "closed", false, params["labels"], params["sortType"]) + if err != nil { + ctx.Handle(200, "issue.Issues: %v", err) + return + } + + ctx.HTML(200, "repo/issues") +} + +func CreateIssue(ctx *middleware.Context, params martini.Params, form auth.CreateIssueForm) { + if !ctx.Repo.IsOwner { + ctx.Handle(404, "issue.CreateIssue", nil) + return + } + + ctx.Data["Title"] = "Create issue" + + if ctx.Req.Method == "GET" { + ctx.HTML(200, "issue/create") + return + } + + if ctx.HasError() { + ctx.HTML(200, "issue/create") + return + } + + issue, err := models.CreateIssue(ctx.User.Id, form.RepoId, form.MilestoneId, form.AssigneeId, + form.IssueName, form.Labels, form.Content, false) + if err == nil { + log.Trace("%s Issue created: %d", form.RepoId, issue.Id) + ctx.Redirect(fmt.Sprintf("/%s/%s/issues/%d", params["username"], params["reponame"], issue.Index)) + return + } + ctx.Handle(200, "issue.CreateIssue", err) +} + +func ViewIssue(ctx *middleware.Context, params martini.Params) { + issueid, err := base.StrTo(params["issueid"]).Int() + if err != nil { + ctx.Handle(404, "issue.ViewIssue", err) + return + } + + issue, err := models.GetIssueById(int64(issueid)) + if err != nil { + if err == models.ErrIssueNotExist { + ctx.Handle(404, "issue.ViewIssue", err) + } else { + ctx.Handle(200, "issue.ViewIssue", err) + } + return + } + + ctx.Data["Title"] = issue.Name + ctx.Data["Issue"] = issue + ctx.HTML(200, "issue/view") +} diff --git a/routers/repo/repo.go b/routers/repo/repo.go index c83a6df5..0f1ea312 100644 --- a/routers/repo/repo.go +++ b/routers/repo/repo.go @@ -5,8 +5,17 @@ package repo import ( + "path" + "strings" + + "github.com/codegangsta/martini" + + "github.com/gogits/git" + "github.com/gogits/webdav" + "github.com/gogits/gogs/models" "github.com/gogits/gogs/modules/auth" + "github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/middleware" ) @@ -22,11 +31,16 @@ func Create(ctx *middleware.Context, form auth.CreateRepoForm) { return } + if ctx.HasError() { + ctx.HTML(200, "repo/create") + return + } + _, err := models.CreateRepository(ctx.User, form.RepoName, form.Description, form.Language, form.License, form.Visibility == "private", form.InitReadme == "on") if err == nil { log.Trace("%s Repository created: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, form.RepoName) - ctx.Redirect("/"+ctx.User.Name+"/"+form.RepoName, 302) + ctx.Redirect("/" + ctx.User.Name + "/" + form.RepoName) return } else if err == models.ErrRepoAlreadyExist { ctx.RenderWithErr("Repository name has already been used", "repo/create", &form) @@ -59,5 +73,290 @@ func SettingPost(ctx *middleware.Context) { } log.Trace("%s Repository deleted: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, ctx.Repo.Repository.LowerName) - ctx.Redirect("/", 302) + ctx.Redirect("/") +} + +func Branches(ctx *middleware.Context, params martini.Params) { + if !ctx.Repo.IsValid { + return + } + + brs, err := models.GetBranches(params["username"], params["reponame"]) + if err != nil { + ctx.Handle(200, "repo.Branches", err) + return + } else if len(brs) == 0 { + ctx.Handle(404, "repo.Branches", nil) + return + } + + ctx.Data["Username"] = params["username"] + ctx.Data["Reponame"] = params["reponame"] + + ctx.Data["Branchname"] = brs[0] + ctx.Data["Branches"] = brs + ctx.Data["IsRepoToolbarBranches"] = true + + ctx.HTML(200, "repo/branches") +} + +func Single(ctx *middleware.Context, params martini.Params) { + if !ctx.Repo.IsValid { + return + } + + if len(params["branchname"]) == 0 { + params["branchname"] = "master" + } + + // Get tree path + treename := params["_1"] + + if len(treename) > 0 && treename[len(treename)-1] == '/' { + ctx.Redirect("/" + ctx.Repo.Owner.LowerName + "/" + + ctx.Repo.Repository.Name + "/src/" + params["branchname"] + "/" + treename[:len(treename)-1]) + return + } + + ctx.Data["IsRepoToolbarSource"] = true + + // Branches. + brs, err := models.GetBranches(params["username"], params["reponame"]) + if err != nil { + //log.Error("repo.Single(GetBranches): %v", err) + ctx.Handle(404, "repo.Single(GetBranches)", err) + return + } else if ctx.Repo.Repository.IsBare { + ctx.Data["IsBareRepo"] = true + ctx.HTML(200, "repo/single") + return + } + + ctx.Data["Branches"] = brs + + repoFile, err := models.GetTargetFile(params["username"], params["reponame"], + params["branchname"], params["commitid"], treename) + + if err != nil && err != models.ErrRepoFileNotExist { + //log.Error("repo.Single(GetTargetFile): %v", err) + ctx.Handle(404, "repo.Single(GetTargetFile)", err) + return + } + + branchLink := "/" + ctx.Repo.Owner.LowerName + "/" + ctx.Repo.Repository.Name + "/src/" + params["branchname"] + + if len(treename) != 0 && repoFile == nil { + ctx.Handle(404, "repo.Single", nil) + return + } + + if repoFile != nil && repoFile.IsFile() { + if repoFile.Size > 1024*1024 || repoFile.Filemode != git.FileModeBlob { + ctx.Data["FileIsLarge"] = true + } else if blob, err := repoFile.LookupBlob(); err != nil { + //log.Error("repo.Single(repoFile.LookupBlob): %v", err) + ctx.Handle(404, "repo.Single(repoFile.LookupBlob)", err) + } else { + ctx.Data["IsFile"] = true + ctx.Data["FileName"] = repoFile.Name + ext := path.Ext(repoFile.Name) + if len(ext) > 0 { + ext = ext[1:] + } + ctx.Data["FileExt"] = ext + + readmeExist := base.IsMarkdownFile(repoFile.Name) || base.IsReadmeFile(repoFile.Name) + ctx.Data["ReadmeExist"] = readmeExist + if readmeExist { + ctx.Data["FileContent"] = string(base.RenderMarkdown(blob.Contents(), "")) + } else { + ctx.Data["FileContent"] = string(blob.Contents()) + } + } + + } else { + // Directory and file list. + files, err := models.GetReposFiles(params["username"], params["reponame"], + params["branchname"], params["commitid"], treename) + if err != nil { + //log.Error("repo.Single(GetReposFiles): %v", err) + ctx.Handle(404, "repo.Single(GetReposFiles)", err) + return + } + + ctx.Data["Files"] = files + + var readmeFile *models.RepoFile + + for _, f := range files { + if !f.IsFile() || !base.IsReadmeFile(f.Name) { + continue + } else { + readmeFile = f + break + } + } + + if readmeFile != nil { + ctx.Data["ReadmeExist"] = true + // if file large than 1M not show it + if readmeFile.Size > 1024*1024 || readmeFile.Filemode != git.FileModeBlob { + ctx.Data["FileIsLarge"] = true + } else if blob, err := readmeFile.LookupBlob(); err != nil { + //log.Error("repo.Single(readmeFile.LookupBlob): %v", err) + ctx.Handle(404, "repo.Single(readmeFile.LookupBlob)", err) + return + } else { + // current repo branch link + + ctx.Data["FileName"] = readmeFile.Name + ctx.Data["FileContent"] = string(base.RenderMarkdown(blob.Contents(), branchLink)) + } + } + } + + ctx.Data["Username"] = params["username"] + ctx.Data["Reponame"] = params["reponame"] + ctx.Data["Branchname"] = params["branchname"] + + var treenames []string + Paths := make([]string, 0) + + if len(treename) > 0 { + treenames = strings.Split(treename, "/") + for i, _ := range treenames { + Paths = append(Paths, strings.Join(treenames[0:i+1], "/")) + } + + ctx.Data["HasParentPath"] = true + if len(Paths)-2 >= 0 { + ctx.Data["ParentPath"] = "/" + Paths[len(Paths)-2] + } + } + + // Get latest commit according username and repo name + commit, err := models.GetCommit(params["username"], params["reponame"], + params["branchname"], params["commitid"]) + if err != nil { + log.Error("repo.Single(GetCommit): %v", err) + ctx.Handle(404, "repo.Single(GetCommit)", err) + return + } + ctx.Data["LastCommit"] = commit + + ctx.Data["Paths"] = Paths + ctx.Data["Treenames"] = treenames + ctx.Data["BranchLink"] = branchLink + ctx.HTML(200, "repo/single") +} + +func Http(ctx *middleware.Context, params martini.Params) { + /*if !ctx.Repo.IsValid { + return + }*/ + + // TODO: access check + + username := params["username"] + reponame := params["reponame"] + if strings.HasSuffix(reponame, ".git") { + reponame = reponame[:len(reponame)-4] + } + + prefix := path.Join("/", username, params["reponame"]) + server := &webdav.Server{ + Fs: webdav.Dir(models.RepoPath(username, reponame)), + TrimPrefix: prefix, + Listings: true, + } + + server.ServeHTTP(ctx.ResponseWriter, ctx.Req) +} + +func Setting(ctx *middleware.Context, params martini.Params) { + if !ctx.Repo.IsOwner { + ctx.Handle(404, "repo.Setting", nil) + return + } + + ctx.Data["IsRepoToolbarSetting"] = true + + if ctx.Repo.Repository.IsBare { + ctx.Data["IsBareRepo"] = true + ctx.HTML(200, "repo/setting") + return + } + + var title string + if t, ok := ctx.Data["Title"].(string); ok { + title = t + } + + if len(params["branchname"]) == 0 { + params["branchname"] = "master" + } + + ctx.Data["Branchname"] = params["branchname"] + ctx.Data["Title"] = title + " - settings" + ctx.HTML(200, "repo/setting") +} + +func Commits(ctx *middleware.Context, params martini.Params) { + brs, err := models.GetBranches(params["username"], params["reponame"]) + if err != nil { + ctx.Handle(200, "repo.Commits", err) + return + } else if len(brs) == 0 { + ctx.Handle(404, "repo.Commits", nil) + return + } + + ctx.Data["IsRepoToolbarCommits"] = true + commits, err := models.GetCommits(params["username"], + params["reponame"], params["branchname"]) + if err != nil { + ctx.Handle(404, "repo.Commits", nil) + return + } + ctx.Data["Username"] = params["username"] + ctx.Data["Reponame"] = params["reponame"] + ctx.Data["CommitCount"] = commits.Len() + ctx.Data["Commits"] = commits + ctx.HTML(200, "repo/commits") +} + +func Pulls(ctx *middleware.Context) { + ctx.Data["IsRepoToolbarPulls"] = true + ctx.HTML(200, "repo/pulls") +} + +func Action(ctx *middleware.Context, params martini.Params) { + var err error + switch params["action"] { + case "watch": + err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, true) + case "unwatch": + err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, false) + case "desc": + if !ctx.Repo.IsOwner { + ctx.Error(404) + return + } + + ctx.Repo.Repository.Description = ctx.Query("desc") + ctx.Repo.Repository.Website = ctx.Query("site") + err = models.UpdateRepository(ctx.Repo.Repository) + } + + if err != nil { + log.Error("repo.Action(%s): %v", params["action"], err) + ctx.JSON(200, map[string]interface{}{ + "ok": false, + "err": err.Error(), + }) + return + } + ctx.JSON(200, map[string]interface{}{ + "ok": true, + }) } diff --git a/routers/repo/single.go b/routers/repo/single.go deleted file mode 100644 index 37c0fabd..00000000 --- a/routers/repo/single.go +++ /dev/null @@ -1,307 +0,0 @@ -// Copyright 2014 The Gogs Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package repo - -import ( - "path" - "strings" - - "github.com/codegangsta/martini" - - "github.com/gogits/git" - "github.com/gogits/webdav" - - "github.com/gogits/gogs/models" - "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/log" - "github.com/gogits/gogs/modules/middleware" -) - -func Branches(ctx *middleware.Context, params martini.Params) { - if !ctx.Repo.IsValid { - return - } - - brs, err := models.GetBranches(params["username"], params["reponame"]) - if err != nil { - ctx.Handle(200, "repo.Branches", err) - return - } else if len(brs) == 0 { - ctx.Error(404) - return - } - - ctx.Data["Username"] = params["username"] - ctx.Data["Reponame"] = params["reponame"] - - ctx.Data["Branchname"] = brs[0] - ctx.Data["Branches"] = brs - ctx.Data["IsRepoToolbarBranches"] = true - - ctx.HTML(200, "repo/branches") -} - -func Single(ctx *middleware.Context, params martini.Params) { - if !ctx.Repo.IsValid { - return - } - - if len(params["branchname"]) == 0 { - params["branchname"] = "master" - } - - // Get tree path - treename := params["_1"] - - if len(treename) > 0 && treename[len(treename)-1] == '/' { - ctx.Redirect("/"+ctx.Repo.Owner.LowerName+"/"+ - ctx.Repo.Repository.Name+"/src/"+params["branchname"]+"/"+treename[:len(treename)-1], 302) - return - } - - ctx.Data["IsRepoToolbarSource"] = true - - // Branches. - brs, err := models.GetBranches(params["username"], params["reponame"]) - if err != nil { - log.Error("repo.Single(GetBranches): %v", err) - ctx.Error(404) - return - } else if len(brs) == 0 { - ctx.Data["IsBareRepo"] = true - ctx.HTML(200, "repo/single") - return - } - - ctx.Data["Branches"] = brs - - repoFile, err := models.GetTargetFile(params["username"], params["reponame"], - params["branchname"], params["commitid"], treename) - - if err != nil && err != models.ErrRepoFileNotExist { - log.Error("repo.Single(GetTargetFile): %v", err) - ctx.Error(404) - return - } - - branchLink := "/" + ctx.Repo.Owner.LowerName + "/" + ctx.Repo.Repository.Name + "/src/" + params["branchname"] - - if len(treename) != 0 && repoFile == nil { - ctx.Error(404) - return - } - - if repoFile != nil && repoFile.IsFile() { - if repoFile.Size > 1024*1024 || repoFile.Filemode != git.FileModeBlob { - ctx.Data["FileIsLarge"] = true - } else if blob, err := repoFile.LookupBlob(); err != nil { - log.Error("repo.Single(repoFile.LookupBlob): %v", err) - ctx.Error(404) - } else { - ctx.Data["IsFile"] = true - ctx.Data["FileName"] = repoFile.Name - ext := path.Ext(repoFile.Name) - if len(ext) > 0 { - ext = ext[1:] - } - ctx.Data["FileExt"] = ext - - readmeExist := base.IsMarkdownFile(repoFile.Name) || base.IsReadmeFile(repoFile.Name) - ctx.Data["ReadmeExist"] = readmeExist - if readmeExist { - ctx.Data["FileContent"] = string(base.RenderMarkdown(blob.Contents(), "")) - } else { - ctx.Data["FileContent"] = string(blob.Contents()) - } - } - - } else { - // Directory and file list. - files, err := models.GetReposFiles(params["username"], params["reponame"], - params["branchname"], params["commitid"], treename) - if err != nil { - log.Error("repo.Single(GetReposFiles): %v", err) - ctx.Error(404) - return - } - - ctx.Data["Files"] = files - - var readmeFile *models.RepoFile - - for _, f := range files { - if !f.IsFile() || !base.IsReadmeFile(f.Name) { - continue - } else { - readmeFile = f - break - } - } - - if readmeFile != nil { - ctx.Data["ReadmeExist"] = true - // if file large than 1M not show it - if readmeFile.Size > 1024*1024 || readmeFile.Filemode != git.FileModeBlob { - ctx.Data["FileIsLarge"] = true - } else if blob, err := readmeFile.LookupBlob(); err != nil { - log.Error("repo.Single(readmeFile.LookupBlob): %v", err) - ctx.Error(404) - return - } else { - // current repo branch link - - ctx.Data["FileName"] = readmeFile.Name - ctx.Data["FileContent"] = string(base.RenderMarkdown(blob.Contents(), branchLink)) - } - } - } - - ctx.Data["Username"] = params["username"] - ctx.Data["Reponame"] = params["reponame"] - ctx.Data["Branchname"] = params["branchname"] - - var treenames []string - Paths := make([]string, 0) - - if len(treename) > 0 { - treenames = strings.Split(treename, "/") - for i, _ := range treenames { - Paths = append(Paths, strings.Join(treenames[0:i+1], "/")) - } - - ctx.Data["HasParentPath"] = true - if len(Paths)-2 >= 0 { - ctx.Data["ParentPath"] = "/" + Paths[len(Paths)-2] - } - } - - // Get latest commit according username and repo name - commit, err := models.GetCommit(params["username"], params["reponame"], - params["branchname"], params["commitid"]) - if err != nil { - log.Error("repo.Single(GetCommit): %v", err) - ctx.Error(404) - return - } - ctx.Data["LastCommit"] = commit - - ctx.Data["Paths"] = Paths - ctx.Data["Treenames"] = treenames - ctx.Data["BranchLink"] = branchLink - ctx.HTML(200, "repo/single") -} - -func Http(ctx *middleware.Context, params martini.Params) { - /*if !ctx.Repo.IsValid { - return - }*/ - - // TODO: access check - - username := params["username"] - reponame := params["reponame"] - if strings.HasSuffix(reponame, ".git") { - reponame = reponame[:len(reponame)-4] - } - - prefix := path.Join("/", username, params["reponame"]) - server := &webdav.Server{ - Fs: webdav.Dir(models.RepoPath(username, reponame)), - TrimPrefix: prefix, - Listings: true, - } - - server.ServeHTTP(ctx.ResponseWriter, ctx.Req) -} - -func Setting(ctx *middleware.Context, params martini.Params) { - if !ctx.Repo.IsOwner { - ctx.Error(404) - return - } - - ctx.Data["IsRepoToolbarSetting"] = true - - // Branches. - brs, err := models.GetBranches(params["username"], params["reponame"]) - if err != nil { - log.Error("repo.Setting(GetBranches): %v", err) - ctx.Error(404) - return - } else if len(brs) == 0 { - ctx.Data["IsBareRepo"] = true - ctx.HTML(200, "repo/setting") - return - } - - var title string - if t, ok := ctx.Data["Title"].(string); ok { - title = t - } - - if len(params["branchname"]) == 0 { - params["branchname"] = "master" - } - - ctx.Data["Branchname"] = params["branchname"] - ctx.Data["Title"] = title + " - settings" - ctx.HTML(200, "repo/setting") -} - -func Commits(ctx *middleware.Context, params martini.Params) { - brs, err := models.GetBranches(params["username"], params["reponame"]) - if err != nil { - ctx.Handle(200, "repo.Commits", err) - return - } else if len(brs) == 0 { - ctx.Error(404) - return - } - - ctx.Data["IsRepoToolbarCommits"] = true - commits, err := models.GetCommits(params["username"], - params["reponame"], params["branchname"]) - if err != nil { - ctx.Error(404) - return - } - ctx.Data["Username"] = params["username"] - ctx.Data["Reponame"] = params["reponame"] - ctx.Data["CommitCount"] = commits.Len() - ctx.Data["Commits"] = commits - ctx.HTML(200, "repo/commits") -} - -func Issues(ctx *middleware.Context) { - ctx.Data["IsRepoToolbarIssues"] = true - ctx.HTML(200, "repo/issues") -} - -func Pulls(ctx *middleware.Context) { - ctx.Data["IsRepoToolbarPulls"] = true - ctx.HTML(200, "repo/pulls") -} - -func Action(ctx *middleware.Context, params martini.Params) { - var err error - switch params["action"] { - case "watch": - err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, true) - case "unwatch": - err = models.WatchRepo(ctx.User.Id, ctx.Repo.Repository.Id, false) - } - - if err != nil { - log.Error("repo.Action(%s): %v", params["action"], err) - ctx.JSON(200, map[string]interface{}{ - "ok": false, - "err": err.Error(), - }) - return - } - ctx.JSON(200, map[string]interface{}{ - "ok": true, - }) -} diff --git a/routers/user/user.go b/routers/user/user.go index d38eb1ce..a0321f18 100644 --- a/routers/user/user.go +++ b/routers/user/user.go @@ -6,6 +6,7 @@ package user import ( "fmt" + "net/url" "strings" "github.com/codegangsta/martini" @@ -77,7 +78,45 @@ func SignIn(ctx *middleware.Context, form auth.LogInForm) { ctx.Data["Title"] = "Log In" if ctx.Req.Method == "GET" { - ctx.HTML(200, "user/signin") + // Check auto-login. + userName := ctx.GetCookie(base.CookieUserName) + if len(userName) == 0 { + ctx.HTML(200, "user/signin") + return + } + + isSucceed := false + defer func() { + if !isSucceed { + log.Trace("%s auto-login cookie cleared: %s", ctx.Req.RequestURI, userName) + ctx.SetCookie(base.CookieUserName, "", -1) + ctx.SetCookie(base.CookieRememberName, "", -1) + } + }() + + user, err := models.GetUserByName(userName) + if err != nil { + ctx.HTML(200, "user/signin") + return + } + + secret := base.EncodeMd5(user.Rands + user.Passwd) + value, _ := ctx.GetSecureCookie(secret, base.CookieRememberName) + if value != user.Name { + ctx.HTML(200, "user/signin") + return + } + + isSucceed = true + ctx.Session.Set("userId", user.Id) + ctx.Session.Set("userName", user.Name) + redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")) + if len(redirectTo) > 0 { + ctx.SetCookie("redirect_to", "", -1) + ctx.Redirect(redirectTo) + } else { + ctx.Redirect("/") + } return } @@ -88,7 +127,8 @@ func SignIn(ctx *middleware.Context, form auth.LogInForm) { user, err := models.LoginUserPlain(form.UserName, form.Password) if err != nil { - if err.Error() == models.ErrUserNotExist.Error() { + if err == models.ErrUserNotExist { + log.Trace("%s Log in failed: %s/%s", ctx.Req.RequestURI, form.UserName, form.Password) ctx.RenderWithErr("Username or password is not correct", "user/signin", &form) return } @@ -97,14 +137,29 @@ func SignIn(ctx *middleware.Context, form auth.LogInForm) { return } + if form.Remember == "on" { + secret := base.EncodeMd5(user.Rands + user.Passwd) + days := 86400 * base.LogInRememberDays + ctx.SetCookie(base.CookieUserName, user.Name, days) + ctx.SetSecureCookie(secret, base.CookieRememberName, user.Name, days) + } + ctx.Session.Set("userId", user.Id) ctx.Session.Set("userName", user.Name) - ctx.Redirect("/") + redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")) + if len(redirectTo) > 0 { + ctx.SetCookie("redirect_to", "", -1) + ctx.Redirect(redirectTo) + } else { + ctx.Redirect("/") + } } func SignOut(ctx *middleware.Context) { ctx.Session.Delete("userId") ctx.Session.Delete("userName") + ctx.SetCookie(base.CookieUserName, "", -1) + ctx.SetCookie(base.CookieRememberName, "", -1) ctx.Redirect("/") } @@ -246,7 +301,7 @@ func Activate(ctx *middleware.Context) { if len(code) == 0 { ctx.Data["IsActivatePage"] = true if ctx.User.IsActive { - ctx.Error(404) + ctx.Handle(404, "user.Activate", nil) return } // Resend confirmation e-mail. @@ -274,7 +329,7 @@ func Activate(ctx *middleware.Context) { ctx.Session.Set("userId", user.Id) ctx.Session.Set("userName", user.Name) - ctx.Redirect("/", 302) + ctx.Redirect("/") return } |