Merge branch 'dev' of github.com:gogits/gogs into dev

This commit is contained in:
Lunny Xiao 2014-04-11 10:28:23 +08:00
commit 8cfa2be433
33 changed files with 398 additions and 268 deletions

View File

@ -5,7 +5,7 @@ Gogs(Go Git Service) is a Self Hosted Git Service in the Go Programming Language
![Demo](http://gowalker.org/public/gogs_demo.gif) ![Demo](http://gowalker.org/public/gogs_demo.gif)
##### Current version: 0.2.3 Alpha ##### Current version: 0.2.4 Alpha
#### Due to testing purpose, data of [try.gogits.org](http://try.gogits.org) has been reset in April 6, 2014 and will reset multiple times after. Please do NOT put your important data on the site. #### Due to testing purpose, data of [try.gogits.org](http://try.gogits.org) has been reset in April 6, 2014 and will reset multiple times after. Please do NOT put your important data on the site.

View File

@ -5,7 +5,7 @@ Gogs(Go Git Service) 是一个由 Go 语言编写的自助 Git 托管服务。
![Demo](http://gowalker.org/public/gogs_demo.gif) ![Demo](http://gowalker.org/public/gogs_demo.gif)
##### 当前版本0.2.3 Alpha ##### 当前版本0.2.4 Alpha
## 开发目的 ## 开发目的

View File

@ -19,7 +19,7 @@ import (
// Test that go1.2 tag above is included in builds. main.go refers to this definition. // Test that go1.2 tag above is included in builds. main.go refers to this definition.
const go12tag = true const go12tag = true
const APP_VER = "0.2.3.0409 Alpha" const APP_VER = "0.2.4.0410 Alpha"
func init() { func init() {
base.AppVer = APP_VER base.AppVer = APP_VER

View File

@ -14,6 +14,8 @@ import (
"path" "path"
"strings" "strings"
"github.com/Unknwon/com"
"github.com/gogits/git" "github.com/gogits/git"
"github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/base"
@ -163,13 +165,11 @@ func getReposFiles(userName, repoName, commitId string, rpath string) ([]*RepoFi
return 0 return 0
} }
cmd := exec.Command("git", "log", "-1", "--pretty=format:%H", commitId, "--", path.Join(dirname, entry.Name)) stdout, _, err := com.ExecCmdDir(repopath, "git", "log", "-1", "--pretty=format:%H", commitId, "--", path.Join(dirname, entry.Name))
cmd.Dir = repopath
out, err := cmd.Output()
if err != nil { if err != nil {
return 0 return 0
} }
filecm, err := repo.GetCommit(string(out)) filecm, err := repo.GetCommit(string(stdout))
if err != nil { if err != nil {
return 0 return 0
} }

View File

@ -80,6 +80,7 @@ type Repository struct {
IsPrivate bool IsPrivate bool
IsBare bool IsBare bool
IsGoget bool IsGoget bool
DefaultBranch string
Created time.Time `xorm:"created"` Created time.Time `xorm:"created"`
Updated time.Time `xorm:"updated"` Updated time.Time `xorm:"updated"`
} }

View File

@ -21,6 +21,7 @@ func init() {
func NewLogger(bufLen int64, mode, config string) { func NewLogger(bufLen int64, mode, config string) {
Mode, Config = mode, config Mode, Config = mode, config
logger = logs.NewLogger(bufLen) logger = logs.NewLogger(bufLen)
logger.SetLogFuncCallDepth(3)
logger.SetLogger(mode, config) logger.SetLogger(mode, config)
} }

View File

@ -11,6 +11,7 @@ import (
"fmt" "fmt"
"html/template" "html/template"
"net/http" "net/http"
"net/url"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -34,6 +35,7 @@ type Context struct {
p martini.Params p martini.Params
Req *http.Request Req *http.Request
Res http.ResponseWriter Res http.ResponseWriter
Flash *Flash
Session session.SessionStore Session session.SessionStore
Cache cache.Cache Cache cache.Cache
User *models.User User *models.User
@ -78,6 +80,7 @@ func (ctx *Context) HasError() bool {
if !ok { if !ok {
return false return false
} }
ctx.Flash.Error(ctx.Data["ErrorMsg"].(string))
return hasErr.(bool) return hasErr.(bool)
} }
@ -88,11 +91,11 @@ func (ctx *Context) HTML(status int, name string, htmlOpt ...HTMLOptions) {
// RenderWithErr used for page has form validation but need to prompt error to users. // RenderWithErr used for page has form validation but need to prompt error to users.
func (ctx *Context) RenderWithErr(msg, tpl string, form auth.Form) { func (ctx *Context) RenderWithErr(msg, tpl string, form auth.Form) {
ctx.Data["HasError"] = true
ctx.Data["ErrorMsg"] = msg
if form != nil { if form != nil {
auth.AssignForm(form, ctx.Data) auth.AssignForm(form, ctx.Data)
} }
ctx.Flash.ErrorMsg = msg
ctx.Data["Flash"] = ctx.Flash
ctx.HTML(200, tpl) ctx.HTML(200, tpl)
} }
@ -239,6 +242,21 @@ func (ctx *Context) CsrfTokenValid() bool {
return true return true
} }
type Flash struct {
url.Values
ErrorMsg, SuccessMsg string
}
func (f *Flash) Error(msg string) {
f.Set("error", msg)
f.ErrorMsg = msg
}
func (f *Flash) Success(msg string) {
f.Set("success", msg)
f.SuccessMsg = msg
}
// InitContext initializes a classic context for a request. // InitContext initializes a classic context for a request.
func InitContext() martini.Handler { func InitContext() martini.Handler {
return func(res http.ResponseWriter, r *http.Request, c martini.Context, rd *Render) { return func(res http.ResponseWriter, r *http.Request, c martini.Context, rd *Render) {
@ -256,9 +274,27 @@ func InitContext() martini.Handler {
// start session // start session
ctx.Session = base.SessionManager.SessionStart(res, r) ctx.Session = base.SessionManager.SessionStart(res, r)
// Get flash.
values, err := url.ParseQuery(ctx.GetCookie("gogs_flash"))
if err != nil {
log.Error("InitContext.ParseQuery(flash): %v", err)
} else if len(values) > 0 {
ctx.Flash = &Flash{Values: values}
ctx.Flash.ErrorMsg = ctx.Flash.Get("error")
ctx.Flash.SuccessMsg = ctx.Flash.Get("success")
ctx.Data["Flash"] = ctx.Flash
ctx.SetCookie("gogs_flash", "", -1)
}
ctx.Flash = &Flash{Values: url.Values{}}
rw := res.(martini.ResponseWriter) rw := res.(martini.ResponseWriter)
rw.Before(func(martini.ResponseWriter) { rw.Before(func(martini.ResponseWriter) {
ctx.Session.SessionRelease(res) ctx.Session.SessionRelease(res)
if flash := ctx.Flash.Encode(); len(flash) > 0 {
ctx.SetCookie("gogs_flash", ctx.Flash.Encode(), 0)
}
}) })
// Get user from session if logined. // Get user from session if logined.

View File

@ -76,7 +76,7 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler {
ctx.Redirect("/") ctx.Redirect("/")
return return
} }
ctx.Handle(404, "RepoAssignment", err) ctx.Handle(500, "RepoAssignment", err)
return return
} }
repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
@ -86,7 +86,7 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler {
gitRepo, err := git.OpenRepository(models.RepoPath(userName, repoName)) gitRepo, err := git.OpenRepository(models.RepoPath(userName, repoName))
if err != nil { if err != nil {
ctx.Handle(404, "RepoAssignment Invalid repo "+models.RepoPath(userName, repoName), err) ctx.Handle(500, "RepoAssignment Invalid repo "+models.RepoPath(userName, repoName), err)
return return
} }
ctx.Repo.GitRepo = gitRepo ctx.Repo.GitRepo = gitRepo
@ -138,7 +138,10 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler {
} }
} else { } else {
branchName = ctx.Repo.Repository.DefaultBranch
if len(branchName) == 0 {
branchName = "master" branchName = "master"
}
goto detect goto detect
} }
@ -157,6 +160,7 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler {
} }
ctx.Data["BranchName"] = ctx.Repo.BranchName ctx.Data["BranchName"] = ctx.Repo.BranchName
ctx.Data["Branches"], _ = models.GetBranches(ctx.User.Name, ctx.Repo.Repository.Name)
ctx.Data["CommitId"] = ctx.Repo.CommitId ctx.Data["CommitId"] = ctx.Repo.CommitId
ctx.Data["IsRepositoryWatching"] = ctx.Repo.IsWatching ctx.Data["IsRepositoryWatching"] = ctx.Repo.IsWatching
} }

View File

@ -16,15 +16,16 @@ import (
"github.com/gogits/gogs/modules/middleware" "github.com/gogits/gogs/modules/middleware"
) )
func NewUser(ctx *middleware.Context, form auth.RegisterForm) { func NewUser(ctx *middleware.Context) {
ctx.Data["Title"] = "New Account" ctx.Data["Title"] = "New Account"
ctx.Data["PageIsUsers"] = true ctx.Data["PageIsUsers"] = true
if ctx.Req.Method == "GET" {
ctx.HTML(200, "admin/users/new") ctx.HTML(200, "admin/users/new")
return
} }
func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) {
ctx.Data["Title"] = "New Account"
ctx.Data["PageIsUsers"] = true
if form.Password != form.RetypePasswd { if form.Password != form.RetypePasswd {
ctx.Data["HasError"] = true ctx.Data["HasError"] = true
ctx.Data["Err_Password"] = true ctx.Data["Err_Password"] = true
@ -55,7 +56,7 @@ func NewUser(ctx *middleware.Context, form auth.RegisterForm) {
case models.ErrUserNameIllegal: case models.ErrUserNameIllegal:
ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), "admin/users/new", &form) ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), "admin/users/new", &form)
default: default:
ctx.Handle(200, "admin.user.NewUser", err) ctx.Handle(500, "admin.user.NewUser", err)
} }
return return
} }
@ -66,25 +67,39 @@ func NewUser(ctx *middleware.Context, form auth.RegisterForm) {
ctx.Redirect("/admin/users") ctx.Redirect("/admin/users")
} }
func EditUser(ctx *middleware.Context, params martini.Params, form auth.AdminEditUserForm) { func EditUser(ctx *middleware.Context, params martini.Params) {
ctx.Data["Title"] = "Edit Account" ctx.Data["Title"] = "Edit Account"
ctx.Data["PageIsUsers"] = true ctx.Data["PageIsUsers"] = true
uid, err := base.StrTo(params["userid"]).Int() uid, err := base.StrTo(params["userid"]).Int()
if err != nil { if err != nil {
ctx.Handle(200, "admin.user.EditUser", err) ctx.Handle(404, "admin.user.EditUser", err)
return return
} }
u, err := models.GetUserById(int64(uid)) u, err := models.GetUserById(int64(uid))
if err != nil { if err != nil {
ctx.Handle(200, "admin.user.EditUser", err) ctx.Handle(500, "admin.user.EditUser", err)
return return
} }
if ctx.Req.Method == "GET" {
ctx.Data["User"] = u ctx.Data["User"] = u
ctx.HTML(200, "admin/users/edit") ctx.HTML(200, "admin/users/edit")
}
func EditUserPost(ctx *middleware.Context, params martini.Params, form auth.AdminEditUserForm) {
ctx.Data["Title"] = "Edit Account"
ctx.Data["PageIsUsers"] = true
uid, err := base.StrTo(params["userid"]).Int()
if err != nil {
ctx.Handle(404, "admin.user.EditUser", err)
return
}
u, err := models.GetUserById(int64(uid))
if err != nil {
ctx.Handle(500, "admin.user.EditUser", err)
return return
} }
@ -96,47 +111,44 @@ func EditUser(ctx *middleware.Context, params martini.Params, form auth.AdminEdi
u.IsActive = form.Active == "on" u.IsActive = form.Active == "on"
u.IsAdmin = form.Admin == "on" u.IsAdmin = form.Admin == "on"
if err := models.UpdateUser(u); err != nil { if err := models.UpdateUser(u); err != nil {
ctx.Handle(200, "admin.user.EditUser", err) ctx.Handle(500, "admin.user.EditUser", err)
return return
} }
ctx.Data["IsSuccess"] = true
ctx.Data["User"] = u
ctx.HTML(200, "admin/users/edit")
log.Trace("%s User profile updated by admin(%s): %s", ctx.Req.RequestURI, log.Trace("%s User profile updated by admin(%s): %s", ctx.Req.RequestURI,
ctx.User.LowerName, ctx.User.LowerName) ctx.User.LowerName, ctx.User.LowerName)
ctx.Data["User"] = u
ctx.Flash.Success("Account profile has been successfully updated.")
ctx.Redirect("/admin/users/" + params["userid"])
} }
func DeleteUser(ctx *middleware.Context, params martini.Params) { func DeleteUser(ctx *middleware.Context, params martini.Params) {
ctx.Data["Title"] = "Edit Account" ctx.Data["Title"] = "Delete Account"
ctx.Data["PageIsUsers"] = true ctx.Data["PageIsUsers"] = true
log.Info("delete")
uid, err := base.StrTo(params["userid"]).Int() uid, err := base.StrTo(params["userid"]).Int()
if err != nil { if err != nil {
ctx.Handle(200, "admin.user.EditUser", err) ctx.Handle(404, "admin.user.EditUser", err)
return return
} }
u, err := models.GetUserById(int64(uid)) u, err := models.GetUserById(int64(uid))
if err != nil { if err != nil {
ctx.Handle(200, "admin.user.EditUser", err) ctx.Handle(500, "admin.user.EditUser", err)
return return
} }
if err = models.DeleteUser(u); err != nil { if err = models.DeleteUser(u); err != nil {
ctx.Data["HasError"] = true
switch err { switch err {
case models.ErrUserOwnRepos: case models.ErrUserOwnRepos:
ctx.Data["ErrorMsg"] = "This account still has ownership of repository, owner has to delete or transfer them first." ctx.Flash.Error("This account still has ownership of repository, owner has to delete or transfer them first.")
ctx.Data["User"] = u ctx.Redirect("/admin/users/" + params["userid"])
ctx.HTML(200, "admin/users/edit")
default: default:
ctx.Handle(200, "admin.user.DeleteUser", err) ctx.Handle(500, "admin.user.DeleteUser", err)
} }
return return
} }
log.Trace("%s User deleted by admin(%s): %s", ctx.Req.RequestURI, log.Trace("%s User deleted by admin(%s): %s", ctx.Req.RequestURI,
ctx.User.LowerName, ctx.User.LowerName) ctx.User.LowerName, ctx.User.LowerName)

View File

@ -63,7 +63,6 @@ func Install(ctx *middleware.Context, form auth.InstallForm) {
ctx.Data["Title"] = "Install" ctx.Data["Title"] = "Install"
ctx.Data["PageIsInstall"] = true ctx.Data["PageIsInstall"] = true
if ctx.Req.Method == "GET" {
// Get and assign value to install form. // Get and assign value to install form.
if len(form.Host) == 0 { if len(form.Host) == 0 {
form.Host = models.DbCfg.Host form.Host = models.DbCfg.Host
@ -96,9 +95,17 @@ func Install(ctx *middleware.Context, form auth.InstallForm) {
auth.AssignForm(form, ctx.Data) auth.AssignForm(form, ctx.Data)
ctx.HTML(200, "install") ctx.HTML(200, "install")
}
func InstallPost(ctx *middleware.Context, form auth.InstallForm) {
if base.InstallLock {
ctx.Handle(404, "install.Install", errors.New("Installation is prohibited"))
return return
} }
ctx.Data["Title"] = "Install"
ctx.Data["PageIsInstall"] = true
if ctx.HasError() { if ctx.HasError() {
ctx.HTML(200, "install") ctx.HTML(200, "install")
return return
@ -197,5 +204,6 @@ func Install(ctx *middleware.Context, form auth.InstallForm) {
} }
log.Info("First-time run install finished!") log.Info("First-time run install finished!")
ctx.Flash.Success("Welcome! We're glad that you choose Gogs, have fun and take care.")
ctx.Redirect("/user/login") ctx.Redirect("/user/login")
} }

View File

@ -82,16 +82,18 @@ func Issues(ctx *middleware.Context) {
ctx.HTML(200, "issue/list") ctx.HTML(200, "issue/list")
} }
func CreateIssue(ctx *middleware.Context, params martini.Params, form auth.CreateIssueForm) { func CreateIssue(ctx *middleware.Context, params martini.Params) {
ctx.Data["Title"] = "Create issue" ctx.Data["Title"] = "Create issue"
ctx.Data["IsRepoToolbarIssues"] = true ctx.Data["IsRepoToolbarIssues"] = true
ctx.Data["IsRepoToolbarIssuesList"] = false ctx.Data["IsRepoToolbarIssuesList"] = false
if ctx.Req.Method == "GET" {
ctx.HTML(200, "issue/create") ctx.HTML(200, "issue/create")
return
} }
func CreateIssuePost(ctx *middleware.Context, params martini.Params, form auth.CreateIssueForm) {
ctx.Data["Title"] = "Create issue"
ctx.Data["IsRepoToolbarIssues"] = true
ctx.Data["IsRepoToolbarIssuesList"] = false
if ctx.HasError() { if ctx.HasError() {
ctx.HTML(200, "issue/create") ctx.HTML(200, "issue/create")
return return
@ -100,7 +102,7 @@ func CreateIssue(ctx *middleware.Context, params martini.Params, form auth.Creat
issue, err := models.CreateIssue(ctx.User.Id, ctx.Repo.Repository.Id, form.MilestoneId, form.AssigneeId, issue, err := models.CreateIssue(ctx.User.Id, ctx.Repo.Repository.Id, form.MilestoneId, form.AssigneeId,
ctx.Repo.Repository.NumIssues, form.IssueName, form.Labels, form.Content, false) ctx.Repo.Repository.NumIssues, form.IssueName, form.Labels, form.Content, false)
if err != nil { if err != nil {
ctx.Handle(200, "issue.CreateIssue(CreateIssue)", err) ctx.Handle(500, "issue.CreateIssue(CreateIssue)", err)
return return
} }
@ -108,7 +110,7 @@ func CreateIssue(ctx *middleware.Context, params martini.Params, form auth.Creat
if err = models.NotifyWatchers(&models.Action{ActUserId: ctx.User.Id, ActUserName: ctx.User.Name, ActEmail: ctx.User.Email, if err = models.NotifyWatchers(&models.Action{ActUserId: ctx.User.Id, ActUserName: ctx.User.Name, ActEmail: ctx.User.Email,
OpType: models.OP_CREATE_ISSUE, Content: fmt.Sprintf("%d|%s", issue.Index, issue.Name), OpType: models.OP_CREATE_ISSUE, Content: fmt.Sprintf("%d|%s", issue.Index, issue.Name),
RepoId: ctx.Repo.Repository.Id, RepoName: ctx.Repo.Repository.Name, RefName: ""}); err != nil { RepoId: ctx.Repo.Repository.Id, RepoName: ctx.Repo.Repository.Name, RefName: ""}); err != nil {
ctx.Handle(200, "issue.CreateIssue(NotifyWatchers)", err) ctx.Handle(500, "issue.CreateIssue(NotifyWatchers)", err)
return return
} }
@ -116,7 +118,7 @@ func CreateIssue(ctx *middleware.Context, params martini.Params, form auth.Creat
if base.Service.NotifyMail { if base.Service.NotifyMail {
tos, err := mailer.SendIssueNotifyMail(ctx.User, ctx.Repo.Owner, ctx.Repo.Repository, issue) tos, err := mailer.SendIssueNotifyMail(ctx.User, ctx.Repo.Owner, ctx.Repo.Repository, issue)
if err != nil { if err != nil {
ctx.Handle(200, "issue.CreateIssue(SendIssueNotifyMail)", err) ctx.Handle(500, "issue.CreateIssue(SendIssueNotifyMail)", err)
return return
} }
@ -132,12 +134,12 @@ func CreateIssue(ctx *middleware.Context, params martini.Params, form auth.Creat
} }
if err = mailer.SendIssueMentionMail(ctx.User, ctx.Repo.Owner, ctx.Repo.Repository, if err = mailer.SendIssueMentionMail(ctx.User, ctx.Repo.Owner, ctx.Repo.Repository,
issue, models.GetUserEmailsByNames(newTos)); err != nil { issue, models.GetUserEmailsByNames(newTos)); err != nil {
ctx.Handle(200, "issue.CreateIssue(SendIssueMentionMail)", err) ctx.Handle(500, "issue.CreateIssue(SendIssueMentionMail)", err)
return return
} }
} }
log.Trace("%d Issue created: %d", ctx.Repo.Repository.Id, issue.Id) log.Trace("%d Issue created: %d", ctx.Repo.Repository.Id, issue.Id)
ctx.Redirect(fmt.Sprintf("/%s/%s/issues/%d", params["username"], params["reponame"], issue.Index)) ctx.Redirect(fmt.Sprintf("/%s/%s/issues/%d", params["username"], params["reponame"], issue.Index))
} }

View File

@ -21,17 +21,20 @@ import (
"github.com/gogits/gogs/modules/middleware" "github.com/gogits/gogs/modules/middleware"
) )
func Create(ctx *middleware.Context, form auth.CreateRepoForm) { func Create(ctx *middleware.Context) {
ctx.Data["Title"] = "Create repository" ctx.Data["Title"] = "Create repository"
ctx.Data["PageIsNewRepo"] = true // For navbar arrow. ctx.Data["PageIsNewRepo"] = true
ctx.Data["LanguageIgns"] = models.LanguageIgns ctx.Data["LanguageIgns"] = models.LanguageIgns
ctx.Data["Licenses"] = models.Licenses ctx.Data["Licenses"] = models.Licenses
if ctx.Req.Method == "GET" {
ctx.HTML(200, "repo/create") ctx.HTML(200, "repo/create")
return
} }
func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) {
ctx.Data["Title"] = "Create repository"
ctx.Data["PageIsNewRepo"] = true
ctx.Data["LanguageIgns"] = models.LanguageIgns
ctx.Data["Licenses"] = models.Licenses
if ctx.HasError() { if ctx.HasError() {
ctx.HTML(200, "repo/create") ctx.HTML(200, "repo/create")
return return
@ -50,18 +53,19 @@ func Create(ctx *middleware.Context, form auth.CreateRepoForm) {
ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), "repo/create", &form) ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), "repo/create", &form)
return return
} }
ctx.Handle(200, "repo.Create", err) ctx.Handle(500, "repo.Create", err)
} }
func Mirror(ctx *middleware.Context, form auth.CreateRepoForm) { func Mirror(ctx *middleware.Context) {
ctx.Data["Title"] = "Mirror repository" ctx.Data["Title"] = "Mirror repository"
ctx.Data["PageIsNewRepo"] = true // For navbar arrow. ctx.Data["PageIsNewRepo"] = true
if ctx.Req.Method == "GET" {
ctx.HTML(200, "repo/mirror") ctx.HTML(200, "repo/mirror")
return
} }
func MirrorPost(ctx *middleware.Context, form auth.CreateRepoForm) {
ctx.Data["Title"] = "Mirror repository"
ctx.Data["PageIsNewRepo"] = true
if ctx.HasError() { if ctx.HasError() {
ctx.HTML(200, "repo/mirror") ctx.HTML(200, "repo/mirror")
return return
@ -80,7 +84,7 @@ func Mirror(ctx *middleware.Context, form auth.CreateRepoForm) {
ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), "repo/mirror", &form) ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), "repo/mirror", &form)
return return
} }
ctx.Handle(200, "repo.Mirror", err) ctx.Handle(500, "repo.Mirror", err)
} }
func Single(ctx *middleware.Context, params martini.Params) { func Single(ctx *middleware.Context, params martini.Params) {
@ -319,27 +323,29 @@ func SettingPost(ctx *middleware.Context) {
switch ctx.Query("action") { switch ctx.Query("action") {
case "update": case "update":
isNameChanged := false
newRepoName := ctx.Query("name") newRepoName := ctx.Query("name")
// Check if repository name has been changed. // Check if repository name has been changed.
if ctx.Repo.Repository.Name != newRepoName { if ctx.Repo.Repository.Name != newRepoName {
isExist, err := models.IsRepositoryExist(ctx.Repo.Owner, newRepoName) isExist, err := models.IsRepositoryExist(ctx.Repo.Owner, newRepoName)
if err != nil { if err != nil {
ctx.Handle(404, "repo.SettingPost(update: check existence)", err) ctx.Handle(500, "repo.SettingPost(update: check existence)", err)
return return
} else if isExist { } else if isExist {
ctx.RenderWithErr("Repository name has been taken in your repositories.", "repo/setting", nil) ctx.RenderWithErr("Repository name has been taken in your repositories.", "repo/setting", nil)
return return
} else if err = models.ChangeRepositoryName(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name, newRepoName); err != nil { } else if err = models.ChangeRepositoryName(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name, newRepoName); err != nil {
ctx.Handle(404, "repo.SettingPost(change repository name)", err) ctx.Handle(500, "repo.SettingPost(change repository name)", err)
return return
} }
log.Trace("%s Repository name changed: %s/%s -> %s", ctx.Req.RequestURI, ctx.User.Name, ctx.Repo.Repository.Name, newRepoName) log.Trace("%s Repository name changed: %s/%s -> %s", ctx.Req.RequestURI, ctx.User.Name, ctx.Repo.Repository.Name, newRepoName)
isNameChanged = true
ctx.Repo.Repository.Name = newRepoName ctx.Repo.Repository.Name = newRepoName
} }
br := ctx.Query("branch")
if models.IsBranchExist(ctx.User.Name, ctx.Repo.Repository.Name, br) {
ctx.Repo.Repository.DefaultBranch = br
}
ctx.Repo.Repository.Description = ctx.Query("desc") ctx.Repo.Repository.Description = ctx.Query("desc")
ctx.Repo.Repository.Website = ctx.Query("site") ctx.Repo.Repository.Website = ctx.Query("site")
ctx.Repo.Repository.IsGoget = ctx.Query("goget") == "on" ctx.Repo.Repository.IsGoget = ctx.Query("goget") == "on"
@ -347,14 +353,10 @@ func SettingPost(ctx *middleware.Context) {
ctx.Handle(404, "repo.SettingPost(update)", err) ctx.Handle(404, "repo.SettingPost(update)", err)
return return
} }
ctx.Data["IsSuccess"] = true
if isNameChanged {
ctx.Redirect(fmt.Sprintf("/%s/%s/settings", ctx.Repo.Owner.Name, ctx.Repo.Repository.Name))
} else {
ctx.HTML(200, "repo/setting")
}
log.Trace("%s Repository updated: %s/%s", ctx.Req.RequestURI, ctx.Repo.Owner.Name, ctx.Repo.Repository.Name) log.Trace("%s Repository updated: %s/%s", ctx.Req.RequestURI, ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
ctx.Flash.Success("Repository options has been successfully updated.")
ctx.Redirect(fmt.Sprintf("/%s/%s/settings", ctx.Repo.Owner.Name, ctx.Repo.Repository.Name))
case "transfer": case "transfer":
if len(ctx.Repo.Repository.Name) == 0 || ctx.Repo.Repository.Name != ctx.Query("repository") { if len(ctx.Repo.Repository.Name) == 0 || ctx.Repo.Repository.Name != ctx.Query("repository") {
ctx.RenderWithErr("Please make sure you entered repository name is correct.", "repo/setting", nil) ctx.RenderWithErr("Please make sure you entered repository name is correct.", "repo/setting", nil)
@ -365,19 +367,18 @@ func SettingPost(ctx *middleware.Context) {
// Check if new owner exists. // Check if new owner exists.
isExist, err := models.IsUserExist(newOwner) isExist, err := models.IsUserExist(newOwner)
if err != nil { if err != nil {
ctx.Handle(404, "repo.SettingPost(transfer: check existence)", err) ctx.Handle(500, "repo.SettingPost(transfer: check existence)", err)
return return
} else if !isExist { } else if !isExist {
ctx.RenderWithErr("Please make sure you entered owner name is correct.", "repo/setting", nil) ctx.RenderWithErr("Please make sure you entered owner name is correct.", "repo/setting", nil)
return return
} else if err = models.TransferOwnership(ctx.User, newOwner, ctx.Repo.Repository); err != nil { } else if err = models.TransferOwnership(ctx.User, newOwner, ctx.Repo.Repository); err != nil {
ctx.Handle(404, "repo.SettingPost(transfer repository)", err) ctx.Handle(500, "repo.SettingPost(transfer repository)", err)
return return
} }
log.Trace("%s Repository transfered: %s/%s -> %s", ctx.Req.RequestURI, ctx.User.Name, ctx.Repo.Repository.Name, newOwner) log.Trace("%s Repository transfered: %s/%s -> %s", ctx.Req.RequestURI, ctx.User.Name, ctx.Repo.Repository.Name, newOwner)
ctx.Redirect("/") ctx.Redirect("/")
return
case "delete": case "delete":
if len(ctx.Repo.Repository.Name) == 0 || ctx.Repo.Repository.Name != ctx.Query("repository") { if len(ctx.Repo.Repository.Name) == 0 || ctx.Repo.Repository.Name != ctx.Query("repository") {
ctx.RenderWithErr("Please make sure you entered repository name is correct.", "repo/setting", nil) ctx.RenderWithErr("Please make sure you entered repository name is correct.", "repo/setting", nil)
@ -385,11 +386,11 @@ func SettingPost(ctx *middleware.Context) {
} }
if err := models.DeleteRepository(ctx.User.Id, ctx.Repo.Repository.Id, ctx.User.LowerName); err != nil { if err := models.DeleteRepository(ctx.User.Id, ctx.Repo.Repository.Id, ctx.User.LowerName); err != nil {
ctx.Handle(200, "repo.Delete", err) ctx.Handle(500, "repo.Delete", err)
return return
} }
log.Trace("%s Repository deleted: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, ctx.Repo.Repository.LowerName) log.Trace("%s Repository deleted: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, ctx.Repo.Repository.LowerName)
ctx.Redirect("/") ctx.Redirect("/")
} }
} }

View File

@ -14,8 +14,16 @@ import (
"github.com/gogits/gogs/modules/middleware" "github.com/gogits/gogs/modules/middleware"
) )
func Setting(ctx *middleware.Context) {
ctx.Data["Title"] = "Setting"
ctx.Data["PageIsUserSetting"] = true
ctx.Data["IsUserPageSetting"] = true
ctx.Data["Owner"] = ctx.User
ctx.HTML(200, "user/setting")
}
// Render user setting page (email, website modify) // Render user setting page (email, website modify)
func Setting(ctx *middleware.Context, form auth.UpdateProfileForm) { func SettingPost(ctx *middleware.Context, form auth.UpdateProfileForm) {
ctx.Data["Title"] = "Setting" ctx.Data["Title"] = "Setting"
ctx.Data["PageIsUserSetting"] = true // For navbar arrow. ctx.Data["PageIsUserSetting"] = true // For navbar arrow.
ctx.Data["IsUserPageSetting"] = true // For setting nav highlight. ctx.Data["IsUserPageSetting"] = true // For setting nav highlight.
@ -23,7 +31,7 @@ func Setting(ctx *middleware.Context, form auth.UpdateProfileForm) {
user := ctx.User user := ctx.User
ctx.Data["Owner"] = user ctx.Data["Owner"] = user
if ctx.Req.Method == "GET" || ctx.HasError() { if ctx.HasError() {
ctx.HTML(200, "user/setting") ctx.HTML(200, "user/setting")
return return
} }
@ -32,13 +40,13 @@ func Setting(ctx *middleware.Context, form auth.UpdateProfileForm) {
if user.Name != form.UserName { if user.Name != form.UserName {
isExist, err := models.IsUserExist(form.UserName) isExist, err := models.IsUserExist(form.UserName)
if err != nil { if err != nil {
ctx.Handle(404, "user.Setting(update: check existence)", err) ctx.Handle(500, "user.Setting(update: check existence)", err)
return return
} else if isExist { } else if isExist {
ctx.RenderWithErr("User name has been taken.", "user/setting", &form) ctx.RenderWithErr("User name has been taken.", "user/setting", &form)
return return
} else if err = models.ChangeUserName(user, form.UserName); err != nil { } else if err = models.ChangeUserName(user, form.UserName); err != nil {
ctx.Handle(404, "user.Setting(change user name)", err) ctx.Handle(500, "user.Setting(change user name)", err)
return return
} }
log.Trace("%s User name changed: %s -> %s", ctx.Req.RequestURI, user.Name, form.UserName) log.Trace("%s User name changed: %s -> %s", ctx.Req.RequestURI, user.Name, form.UserName)
@ -52,47 +60,55 @@ func Setting(ctx *middleware.Context, form auth.UpdateProfileForm) {
user.Avatar = base.EncodeMd5(form.Avatar) user.Avatar = base.EncodeMd5(form.Avatar)
user.AvatarEmail = form.Avatar user.AvatarEmail = form.Avatar
if err := models.UpdateUser(user); err != nil { if err := models.UpdateUser(user); err != nil {
ctx.Handle(200, "setting.Setting", err) ctx.Handle(500, "setting.Setting", err)
return return
} }
ctx.Data["IsSuccess"] = true
ctx.HTML(200, "user/setting")
log.Trace("%s User setting updated: %s", ctx.Req.RequestURI, ctx.User.LowerName) log.Trace("%s User setting updated: %s", ctx.Req.RequestURI, ctx.User.LowerName)
ctx.Flash.Success("Your profile has been successfully updated.")
ctx.Redirect("/user/setting")
} }
func SettingPassword(ctx *middleware.Context, form auth.UpdatePasswdForm) { func SettingPassword(ctx *middleware.Context) {
ctx.Data["Title"] = "Password"
ctx.Data["PageIsUserSetting"] = true
ctx.Data["IsUserPageSettingPasswd"] = true
ctx.HTML(200, "user/password")
}
func SettingPasswordPost(ctx *middleware.Context, form auth.UpdatePasswdForm) {
ctx.Data["Title"] = "Password" ctx.Data["Title"] = "Password"
ctx.Data["PageIsUserSetting"] = true ctx.Data["PageIsUserSetting"] = true
ctx.Data["IsUserPageSettingPasswd"] = true ctx.Data["IsUserPageSettingPasswd"] = true
if ctx.Req.Method == "GET" { if ctx.HasError() {
ctx.HTML(200, "user/password") ctx.HTML(200, "user/password")
return return
} }
user := ctx.User user := ctx.User
newUser := &models.User{Passwd: form.NewPasswd} tmpUser := &models.User{
newUser.EncodePasswd() Passwd: form.OldPasswd,
if user.Passwd != newUser.Passwd { Salt: user.Salt,
ctx.Data["HasError"] = true }
ctx.Data["ErrorMsg"] = "Old password is not correct" tmpUser.EncodePasswd()
if user.Passwd != tmpUser.Passwd {
ctx.Flash.Error("Old password is not correct")
} else if form.NewPasswd != form.RetypePasswd { } else if form.NewPasswd != form.RetypePasswd {
ctx.Data["HasError"] = true ctx.Flash.Error("New password and re-type password are not same")
ctx.Data["ErrorMsg"] = "New password and re-type password are not same"
} else { } else {
newUser.Salt = models.GetUserSalt() user.Passwd = form.NewPasswd
user.Passwd = newUser.Passwd user.Salt = models.GetUserSalt()
user.EncodePasswd()
if err := models.UpdateUser(user); err != nil { if err := models.UpdateUser(user); err != nil {
ctx.Handle(200, "setting.SettingPassword", err) ctx.Handle(200, "setting.SettingPassword", err)
return return
} }
ctx.Data["IsSuccess"] = true log.Trace("%s User password updated: %s", ctx.Req.RequestURI, ctx.User.LowerName)
ctx.Flash.Success("Password is changed successfully. You can now sign in via new password.")
} }
ctx.Data["Owner"] = user ctx.Redirect("/user/setting/password")
ctx.HTML(200, "user/password")
log.Trace("%s User password updated: %s", ctx.Req.RequestURI, ctx.User.LowerName)
} }
func SettingSSHKeys(ctx *middleware.Context, form auth.AddSSHKeyForm) { func SettingSSHKeys(ctx *middleware.Context, form auth.AddSSHKeyForm) {

View File

@ -93,11 +93,10 @@ func SocialSignIn(ctx *middleware.Context, tokens oauth2.Tokens) {
log.Info("login soc id: %v", socid) log.Info("login soc id: %v", socid)
return return
} }
config := &oauth.Config{ config := &oauth.Config{
//ClientId: base.OauthService.Github.ClientId, ClientId: base.OauthService.GitHub.ClientId,
//ClientSecret: base.OauthService.Github.ClientSecret, // FIXME: I don't know why compile error here ClientSecret: base.OauthService.GitHub.ClientSecret,
ClientId: "09383403ff2dc16daaa1",
ClientSecret: "0e4aa0c3630df396cdcea01a9d45cacf79925fea",
RedirectURL: strings.TrimSuffix(base.AppUrl, "/") + ctx.Req.URL.RequestURI(), RedirectURL: strings.TrimSuffix(base.AppUrl, "/") + ctx.Req.URL.RequestURI(),
Scope: base.OauthService.GitHub.Scopes, Scope: base.OauthService.GitHub.Scopes,
AuthURL: "https://github.com/login/oauth/authorize", AuthURL: "https://github.com/login/oauth/authorize",

View File

@ -74,10 +74,9 @@ func Profile(ctx *middleware.Context, params martini.Params) {
ctx.HTML(200, "user/profile") ctx.HTML(200, "user/profile")
} }
func SignIn(ctx *middleware.Context, form auth.LogInForm) { func SignIn(ctx *middleware.Context) {
ctx.Data["Title"] = "Log In" ctx.Data["Title"] = "Log In"
if ctx.Req.Method == "GET" {
if base.OauthService != nil { if base.OauthService != nil {
ctx.Data["OauthEnabled"] = true ctx.Data["OauthEnabled"] = true
ctx.Data["OauthGitHubEnabled"] = base.OauthService.GitHub.Enabled ctx.Data["OauthGitHubEnabled"] = base.OauthService.GitHub.Enabled
@ -115,14 +114,21 @@ func SignIn(ctx *middleware.Context, form auth.LogInForm) {
isSucceed = true isSucceed = true
ctx.Session.Set("userId", user.Id) ctx.Session.Set("userId", user.Id)
ctx.Session.Set("userName", user.Name) ctx.Session.Set("userName", user.Name)
redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")) if redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")); len(redirectTo) > 0 {
if len(redirectTo) > 0 {
ctx.SetCookie("redirect_to", "", -1) ctx.SetCookie("redirect_to", "", -1)
ctx.Redirect(redirectTo) ctx.Redirect(redirectTo)
} else { return
}
ctx.Redirect("/") ctx.Redirect("/")
} }
return
func SignInPost(ctx *middleware.Context, form auth.LogInForm) {
ctx.Data["Title"] = "Log In"
if base.OauthService != nil {
ctx.Data["OauthEnabled"] = true
ctx.Data["OauthGitHubEnabled"] = base.OauthService.GitHub.Enabled
} }
if ctx.HasError() { if ctx.HasError() {
@ -138,7 +144,7 @@ func SignIn(ctx *middleware.Context, form auth.LogInForm) {
return return
} }
ctx.Handle(200, "user.SignIn", err) ctx.Handle(500, "user.SignIn", err)
return return
} }
@ -151,13 +157,13 @@ func SignIn(ctx *middleware.Context, form auth.LogInForm) {
ctx.Session.Set("userId", user.Id) ctx.Session.Set("userId", user.Id)
ctx.Session.Set("userName", user.Name) ctx.Session.Set("userName", user.Name)
redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")) if redirectTo, _ := url.QueryUnescape(ctx.GetCookie("redirect_to")); len(redirectTo) > 0 {
if len(redirectTo) > 0 {
ctx.SetCookie("redirect_to", "", -1) ctx.SetCookie("redirect_to", "", -1)
ctx.Redirect(redirectTo) ctx.Redirect(redirectTo)
} else { return
ctx.Redirect("/")
} }
ctx.Redirect("/")
} }
func SignOut(ctx *middleware.Context) { func SignOut(ctx *middleware.Context) {
@ -168,7 +174,7 @@ func SignOut(ctx *middleware.Context) {
ctx.Redirect("/") ctx.Redirect("/")
} }
func SignUp(ctx *middleware.Context, form auth.RegisterForm) { func SignUp(ctx *middleware.Context) {
ctx.Data["Title"] = "Sign Up" ctx.Data["Title"] = "Sign Up"
ctx.Data["PageIsSignUp"] = true ctx.Data["PageIsSignUp"] = true
@ -178,8 +184,15 @@ func SignUp(ctx *middleware.Context, form auth.RegisterForm) {
return return
} }
if ctx.Req.Method == "GET" {
ctx.HTML(200, "user/signup") ctx.HTML(200, "user/signup")
}
func SignUpPost(ctx *middleware.Context, form auth.RegisterForm) {
ctx.Data["Title"] = "Sign Up"
ctx.Data["PageIsSignUp"] = true
if base.Service.DisenableRegisteration {
ctx.Handle(403, "user.SignUpPost", nil)
return return
} }
@ -213,7 +226,7 @@ func SignUp(ctx *middleware.Context, form auth.RegisterForm) {
case models.ErrUserNameIllegal: case models.ErrUserNameIllegal:
ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), "user/signup", &form) ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), "user/signup", &form)
default: default:
ctx.Handle(200, "user.SignUp", err) ctx.Handle(500, "user.SignUp", err)
} }
return return
} }
@ -240,25 +253,28 @@ func Delete(ctx *middleware.Context) {
ctx.Data["Title"] = "Delete Account" ctx.Data["Title"] = "Delete Account"
ctx.Data["PageIsUserSetting"] = true ctx.Data["PageIsUserSetting"] = true
ctx.Data["IsUserPageSettingDelete"] = true ctx.Data["IsUserPageSettingDelete"] = true
if ctx.Req.Method == "GET" {
ctx.HTML(200, "user/delete") ctx.HTML(200, "user/delete")
return
} }
tmpUser := models.User{Passwd: ctx.Query("password")} func DeletePost(ctx *middleware.Context) {
ctx.Data["Title"] = "Delete Account"
ctx.Data["PageIsUserSetting"] = true
ctx.Data["IsUserPageSettingDelete"] = true
tmpUser := models.User{
Passwd: ctx.Query("password"),
Salt: ctx.User.Salt,
}
tmpUser.EncodePasswd() tmpUser.EncodePasswd()
if len(tmpUser.Passwd) == 0 || tmpUser.Passwd != ctx.User.Passwd { if tmpUser.Passwd != ctx.User.Passwd {
ctx.Data["HasError"] = true ctx.Flash.Error("Password is not correct. Make sure you are owner of this account.")
ctx.Data["ErrorMsg"] = "Password is not correct. Make sure you are owner of this account."
} else { } else {
if err := models.DeleteUser(ctx.User); err != nil { if err := models.DeleteUser(ctx.User); err != nil {
ctx.Data["HasError"] = true
switch err { switch err {
case models.ErrUserOwnRepos: case models.ErrUserOwnRepos:
ctx.Data["ErrorMsg"] = "Your account still have ownership of repository, you have to delete or transfer them first." ctx.Flash.Error("Your account still have ownership of repository, you have to delete or transfer them first.")
default: default:
ctx.Handle(200, "user.Delete", err) ctx.Handle(500, "user.Delete", err)
return return
} }
} else { } else {
@ -267,7 +283,7 @@ func Delete(ctx *middleware.Context) {
} }
} }
ctx.HTML(200, "user/delete") ctx.Redirect("/user/delete")
} }
const ( const (
@ -439,10 +455,17 @@ func ForgotPasswd(ctx *middleware.Context) {
} }
ctx.Data["IsResetRequest"] = true ctx.Data["IsResetRequest"] = true
if ctx.Req.Method == "GET" {
ctx.HTML(200, "user/forgot_passwd") ctx.HTML(200, "user/forgot_passwd")
}
func ForgotPasswdPost(ctx *middleware.Context) {
ctx.Data["Title"] = "Forgot Password"
if base.MailService == nil {
ctx.Handle(403, "user.ForgotPasswdPost", nil)
return return
} }
ctx.Data["IsResetRequest"] = true
email := ctx.Query("email") email := ctx.Query("email")
u, err := models.GetUserByEmail(email) u, err := models.GetUserByEmail(email)
@ -450,7 +473,7 @@ func ForgotPasswd(ctx *middleware.Context) {
if err == models.ErrUserNotExist { if err == models.ErrUserNotExist {
ctx.RenderWithErr("This e-mail address does not associate to any account.", "user/forgot_passwd", nil) ctx.RenderWithErr("This e-mail address does not associate to any account.", "user/forgot_passwd", nil)
} else { } else {
ctx.Handle(404, "user.ResetPasswd(check existence)", err) ctx.Handle(500, "user.ResetPasswd(check existence)", err)
} }
return return
} }
@ -473,6 +496,8 @@ func ForgotPasswd(ctx *middleware.Context) {
} }
func ResetPasswd(ctx *middleware.Context) { func ResetPasswd(ctx *middleware.Context) {
ctx.Data["Title"] = "Reset Password"
code := ctx.Query("code") code := ctx.Query("code")
if len(code) == 0 { if len(code) == 0 {
ctx.Error(404) ctx.Error(404)
@ -480,11 +505,19 @@ func ResetPasswd(ctx *middleware.Context) {
} }
ctx.Data["Code"] = code ctx.Data["Code"] = code
if ctx.Req.Method == "GET" {
ctx.Data["IsResetForm"] = true ctx.Data["IsResetForm"] = true
ctx.HTML(200, "user/reset_passwd") ctx.HTML(200, "user/reset_passwd")
}
func ResetPasswdPost(ctx *middleware.Context) {
ctx.Data["Title"] = "Reset Password"
code := ctx.Query("code")
if len(code) == 0 {
ctx.Error(404)
return return
} }
ctx.Data["Code"] = code
if u := models.VerifyUserActiveCode(code); u != nil { if u := models.VerifyUserActiveCode(code); u != nil {
// Validate password length. // Validate password length.
@ -500,7 +533,7 @@ func ResetPasswd(ctx *middleware.Context) {
u.Salt = models.GetUserSalt() u.Salt = models.GetUserSalt()
u.EncodePasswd() u.EncodePasswd()
if err := models.UpdateUser(u); err != nil { if err := models.UpdateUser(u); err != nil {
ctx.Handle(404, "user.ResetPasswd(UpdateUser)", err) ctx.Handle(500, "user.ResetPasswd(UpdateUser)", err)
return return
} }

View File

@ -11,8 +11,8 @@
<div class="panel-body"> <div class="panel-body">
<br/> <br/>
<form action="/admin/users/{{.User.Id}}" method="post" class="form-horizontal"> <form action="/admin/users/{{.User.Id}}" method="post" class="form-horizontal">
{{if .IsSuccess}}<p class="alert alert-success">Account profile has been successfully updated.</p>{{else if .HasError}}<p class="alert alert-danger form-error">{{.ErrorMsg}}</p>{{end}}
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
{{template "base/alert" .}}
<input type="hidden" value="{{.User.Id}}" name="userId"/> <input type="hidden" value="{{.User.Id}}" name="userId"/>
<div class="form-group"> <div class="form-group">
<label class="col-md-3 control-label">Username: </label> <label class="col-md-3 control-label">Username: </label>

View File

@ -12,7 +12,7 @@
<br/> <br/>
<form action="/admin/users/new" method="post" class="form-horizontal"> <form action="/admin/users/new" method="post" class="form-horizontal">
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
<div class="alert alert-danger form-error{{if .HasError}}{{else}} hidden{{end}}">{{.ErrorMsg}}</div> {{template "base/alert" .}}
<div class="form-group {{if .Err_UserName}}has-error has-feedback{{end}}"> <div class="form-group {{if .Err_UserName}}has-error has-feedback{{end}}">
<label class="col-md-3 control-label">Username: </label> <label class="col-md-3 control-label">Username: </label>
<div class="col-md-7"> <div class="col-md-7">

View File

@ -0,0 +1,2 @@
{{if .Flash.ErrorMsg}}<div class="alert alert-danger form-error">{{.Flash.ErrorMsg}}</div>{{end}}
{{if .Flash.SuccessMsg}}<div class="alert alert-success">{{.Flash.SuccessMsg}}</div>{{end}}

View File

@ -3,7 +3,7 @@
<form action="/install" method="post" class="form-horizontal card" id="install-card"> <form action="/install" method="post" class="form-horizontal card" id="install-card">
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
<h3>Install Steps For First-time Run</h3> <h3>Install Steps For First-time Run</h3>
<div class="alert alert-danger form-error{{if .HasError}}{{else}} hidden{{end}}">{{.ErrorMsg}}</div> {{template "base/alert" .}}
<p class="help-block text-center">Gogs requires MySQL or PostgreSQL, SQLite3 only available for official binary version</p> <p class="help-block text-center">Gogs requires MySQL or PostgreSQL, SQLite3 only available for official binary version</p>
<div class="form-group"> <div class="form-group">
<label class="col-md-3 control-label">Database Type: </label> <label class="col-md-3 control-label">Database Type: </label>
@ -184,11 +184,7 @@
<strong>Enable Register Confirmation</strong> <strong>Enable Register Confirmation</strong>
</label> </label>
</div> </div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-3 col-md-7">
<div class="checkbox"> <div class="checkbox">
<label> <label>
<input name="mail_notify" type="checkbox" {{if .mail_notify}}checked{{end}}> <input name="mail_notify" type="checkbox" {{if .mail_notify}}checked{{end}}>

View File

@ -6,6 +6,7 @@
<div id="issue"> <div id="issue">
<form class="form" action="{{.RepoLink}}/issues/new" method="post" id="issue-create-form"> <form class="form" action="{{.RepoLink}}/issues/new" method="post" id="issue-create-form">
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
{{template "base/alert" .}}
<div class="col-md-1"> <div class="col-md-1">
<img class="avatar" src="{{.SignedUser.AvatarLink}}" alt=""/> <img class="avatar" src="{{.SignedUser.AvatarLink}}" alt=""/>
</div> </div>

View File

@ -4,7 +4,7 @@
<form action="/repo/create" method="post" class="form-horizontal card" id="repo-create"> <form action="/repo/create" method="post" class="form-horizontal card" id="repo-create">
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
<h3>Create New Repository</h3> <h3>Create New Repository</h3>
<div class="alert alert-danger form-error{{if .HasError}}{{else}} hidden{{end}}">{{.ErrorMsg}}</div> {{template "base/alert" .}}
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">Owner<strong class="text-danger">*</strong></label> <label class="col-md-2 control-label">Owner<strong class="text-danger">*</strong></label>
<div class="col-md-8"> <div class="col-md-8">

View File

@ -30,12 +30,16 @@
{{range .Diff.Files}} {{range .Diff.Files}}
<li> <li>
<div class="diff-counter count pull-right"> <div class="diff-counter count pull-right">
{{if Subtract .Addition .Deletion}}
<span class="add" data-line="{{.Addition}}">{{.Addition}}</span> <span class="add" data-line="{{.Addition}}">{{.Addition}}</span>
<span class="bar"> <span class="bar">
<span class="pull-left add"></span> <span class="pull-left add"></span>
<span class="pull-left del"></span> <span class="pull-left del"></span>
</span> </span>
<span class="del" data-line="{{.Deletion}}">{{.Deletion}}</span> <span class="del" data-line="{{.Deletion}}">{{.Deletion}}</span>
{{else}}
<span>BIN</span>
{{end}}
</div> </div>
<!-- todo finish all file status, now modify, add, delete and rename --> <!-- todo finish all file status, now modify, add, delete and rename -->
<span class="status {{DiffTypeToStr .Type}}" data-toggle="tooltip" data-placement="right" title="{{DiffTypeToStr .Type}}">&nbsp;</span> <span class="status {{DiffTypeToStr .Type}}" data-toggle="tooltip" data-placement="right" title="{{DiffTypeToStr .Type}}">&nbsp;</span>
@ -49,12 +53,16 @@
<div class="panel panel-default diff-file-box diff-box file-content" id="diff-2"> <div class="panel panel-default diff-file-box diff-box file-content" id="diff-2">
<div class="panel-heading"> <div class="panel-heading">
<div class="diff-counter count pull-left"> <div class="diff-counter count pull-left">
{{if Subtract .Addition .Deletion}}
<span class="add" data-line="{{.Addition}}">+ {{.Addition}}</span> <span class="add" data-line="{{.Addition}}">+ {{.Addition}}</span>
<span class="bar"> <span class="bar">
<span class="pull-left add"></span> <span class="pull-left add"></span>
<span class="pull-left del"></span> <span class="pull-left del"></span>
</span> </span>
<span class="del" data-line="{{.Deletion}}">- {{.Deletion}}</span> <span class="del" data-line="{{.Deletion}}">- {{.Deletion}}</span>
{{else}}
BIN
{{end}}
</div> </div>
<a class="btn btn-default btn-sm pull-right" href="{{$.SourcePath}}/{{.Name}}">View File</a> <a class="btn btn-default btn-sm pull-right" href="{{$.SourcePath}}/{{.Name}}">View File</a>
<span class="file">{{.Name}}</span> <span class="file">{{.Name}}</span>

View File

@ -4,7 +4,7 @@
<form action="/repo/create" method="post" class="form-horizontal card" id="repo-create"> <form action="/repo/create" method="post" class="form-horizontal card" id="repo-create">
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
<h3>Create Repository Mirror</h3> <h3>Create Repository Mirror</h3>
<div class="alert alert-danger form-error{{if .HasError}}{{else}} hidden{{end}}">{{.ErrorMsg}}</div> {{template "base/alert" .}}
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label">From<strong class="text-danger">*</strong></label> <label class="col-md-2 control-label">From<strong class="text-danger">*</strong></label>
<div class="col-md-8"> <div class="col-md-8">

View File

@ -12,7 +12,7 @@
</div> </div>
<div id="repo-setting-container" class="col-md-9"> <div id="repo-setting-container" class="col-md-9">
{{if .IsSuccess}}<p class="alert alert-success">Repository options has been successfully updated.</p>{{else if .HasError}}<p class="alert alert-danger form-error">{{.ErrorMsg}}</p>{{end}} {{template "base/alert" .}}
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
Repository Options Repository Options
@ -44,14 +44,17 @@
</div> </div>
</div> </div>
<hr> <hr>
<!-- <div class="form-group"> <div class="form-group">
<label class="col-md-3 text-right">Default Branch</label> <label class="col-md-3 text-right">Default Branch</label>
<div class="col-md-9"> <div class="col-md-9">
<select name="branch" id="repo-default-branch" class="form-control"> <select name="branch" id="repo-default-branch" class="form-control">
<option value="">Branch</option> <option value="{{.Repository.DefaultBranch}}">{{.Repository.DefaultBranch}}</option>
{{range .Branches}}
{{if eq . $.Repository.DefaultBranch}}{{else}}<option value="{{.}}">{{.}}</option>{{end}}
{{end}}
</select> </select>
</div> </div>
</div> --> </div>
<div class="form-group"> <div class="form-group">
<div class="col-md-offset-3 col-md-9"> <div class="col-md-offset-3 col-md-9">

View File

@ -2,8 +2,8 @@
{{template "base/navbar" .}} {{template "base/navbar" .}}
<div id="body" class="container text-center"> <div id="body" class="container text-center">
<p style="margin-top: 80px"><img src="/img/500.png" alt="404"/></p> <p style="margin-top: 80px"><img src="/img/500.png" alt="404"/></p>
<hr/> {{if .ErrorMsg}}<hr/>
<p>An error is occurred : {{.ErrorMsg}}</p> <p>An error is occurred : {{.ErrorMsg}}</p>{{end}}
<hr/> <hr/>
<p>Application Version: {{AppVer}}</p> <p>Application Version: {{AppVer}}</p>
</div> </div>

View File

@ -1,24 +1,16 @@
{{template "base/head" .}} {{template "base/head" .}}
{{template "base/navbar" .}} {{template "base/navbar" .}}
<div id="body" class="container" data-page="user"> <div id="body" class="container" data-page="user">
<div id="user-setting-nav" class="col-md-3"> {{template "user/setting_nav" .}}
<h4>Account Setting</h4>
<ul class="list-group">
<li class="list-group-item"><a href="/user/setting">Account Profile</a></li>
<li class="list-group-item"><a href="/user/setting/password">Password</a></li>
<!-- <li class="list-group-item"><a href="/user/setting/notification">Notifications</a></li> -->
<li class="list-group-item"><a href="/user/setting/ssh/">SSH Keys</a></li>
<!-- <li class="list-group-item"><a href="/user/setting/security">Security</a></li> -->
<li class="list-group-item list-group-item-success"><a href="/user/delete">Delete Account</a></li>
</ul>
</div>
<div id="user-setting-container" class="col-md-9"> <div id="user-setting-container" class="col-md-9">
<h4>Delete Account</h4> <h4>Delete Account</h4>
<p class="alert alert-danger">{{if not .HasError}}The operation will delete your account permanently. Sorry to see you go, but we know you'll back soon.{{else}}{{.ErrorMsg}}{{end}}</p> {{template "base/alert" .}}
{{if not .Flash.ErrorMsg}}<p class="alert alert-danger">The operation will delete your account permanently. Sorry to see you go, but we know you'll back soon.</p>{{end}}
<div class="form-group"> <div class="form-group">
<button type="submit" class="btn btn-danger btn-lg" href="#delete-account-modal" id="delete-account" data-toggle="modal">Delete Account</button> <button type="submit" class="btn btn-danger btn-lg" href="#delete-account-modal" id="delete-account" data-toggle="modal">Delete Account</button>
</div> </div>
</div> </div>
<div class="modal fade" id="delete-account-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal fade" id="delete-account-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog"> <div class="modal-dialog">
<form action="/user/delete" method="post" class="modal-content" id="user-delete"> <form action="/user/delete" method="post" class="modal-content" id="user-delete">

View File

@ -4,7 +4,7 @@
<form action="/user/forget_password" method="post" class="form-horizontal card" id="login-card"> <form action="/user/forget_password" method="post" class="form-horizontal card" id="login-card">
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
<h3>Reset Your Password</h3> <h3>Reset Your Password</h3>
<div class="alert alert-danger form-error{{if .HasError}}{{else}} hidden{{end}}">{{.ErrorMsg}}</div> {{template "base/alert" .}}
{{if .IsResetSent}} {{if .IsResetSent}}
<p>A confirmation e-mail has been sent to <b>{{.Email}}</b>, please check your inbox within {{.Hours}} hours.</p> <p>A confirmation e-mail has been sent to <b>{{.Email}}</b>, please check your inbox within {{.Hours}} hours.</p>
<hr/> <hr/>

View File

@ -7,8 +7,7 @@
<h4>Password</h4> <h4>Password</h4>
<form class="form-horizontal" id="password-form" method="post" action="/user/setting/password"> <form class="form-horizontal" id="password-form" method="post" action="/user/setting/password">
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
{{if .IsSuccess}} {{template "base/alert" .}}
<p class="alert alert-success">Password is changed successfully. You can now sign in via new password.</p>{{else if .HasError}}<p class="alert alert-danger form-error">{{.ErrorMsg}}</p>{{end}}
<div class="form-group"> <div class="form-group">
<label class="col-md-3 control-label">Old Password<strong class="text-danger">*</strong></label> <label class="col-md-3 control-label">Old Password<strong class="text-danger">*</strong></label>
<div class="col-md-7"> <div class="col-md-7">
@ -33,7 +32,7 @@
<div class="form-group"> <div class="form-group">
<div class="col-md-offset-3 col-md-7"> <div class="col-md-offset-3 col-md-7">
<button type="submit" class="btn btn-primary">Change Password</button>&nbsp;&nbsp; <button type="submit" class="btn btn-primary">Change Password</button>&nbsp;&nbsp;
<a href="/forget-password/">Forgot your password?</a> <a href="/user/forget_password/">Forgot your password?</a>
</div> </div>
</div> </div>
</form> </form>

View File

@ -4,7 +4,7 @@
<form action="/user/reset_password?code={{.Code}}" method="post" class="form-horizontal card" id="login-card"> <form action="/user/reset_password?code={{.Code}}" method="post" class="form-horizontal card" id="login-card">
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
<h3>Reset Your Pasword</h3> <h3>Reset Your Pasword</h3>
<div class="alert alert-danger form-error{{if .HasError}}{{else}} hidden{{end}}">{{.ErrorMsg}}</div> {{template "base/alert" .}}
{{if .IsResetForm}} {{if .IsResetForm}}
<div class="form-group"> <div class="form-group">
<label class="col-md-4 control-label">Password: </label> <label class="col-md-4 control-label">Password: </label>

View File

@ -7,7 +7,7 @@
<h4>Account Profile</h4> <h4>Account Profile</h4>
<form class="form-horizontal" id="password-form" method="post" action="/user/setting"> <form class="form-horizontal" id="password-form" method="post" action="/user/setting">
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
{{if .IsSuccess}}<p class="alert alert-success">Your profile has been successfully updated.</p>{{else if .HasError}}<p class="alert alert-danger form-error">{{.ErrorMsg}}</p>{{end}} {{template "base/alert" .}}
<p>Your Email will be public and used for Account related notifications and any web based operations made via the web.</p> <p>Your Email will be public and used for Account related notifications and any web based operations made via the web.</p>
<div class="form-group"> <div class="form-group">
<label class="col-md-2 control-label" for="user-setting-username">Username<strong class="text-danger">*</strong></label> <label class="col-md-2 control-label" for="user-setting-username">Username<strong class="text-danger">*</strong></label>

View File

@ -4,7 +4,7 @@
<form action="/user/login" method="post" class="form-horizontal card" id="login-card"> <form action="/user/login" method="post" class="form-horizontal card" id="login-card">
{{.CsrfTokenHtml}} {{.CsrfTokenHtml}}
<h3>Log in</h3> <h3>Log in</h3>
<div class="alert alert-danger form-error{{if .HasError}}{{else}} hidden{{end}}">{{.ErrorMsg}}</div> {{template "base/alert" .}}
<div class="form-group {{if .Err_UserName}}has-error has-feedback{{end}}"> <div class="form-group {{if .Err_UserName}}has-error has-feedback{{end}}">
<label class="col-md-4 control-label">Username: </label> <label class="col-md-4 control-label">Username: </label>
<div class="col-md-6"> <div class="col-md-6">

View File

@ -7,7 +7,7 @@
Sorry, registeration has been disenabled, you can only get account from administrator. Sorry, registeration has been disenabled, you can only get account from administrator.
{{else}} {{else}}
<h3>Sign Up</h3> <h3>Sign Up</h3>
<div class="alert alert-danger form-error{{if .HasError}}{{else}} hidden{{end}}">{{.ErrorMsg}}</div> {{template "base/alert" .}}
<div class="form-group {{if .Err_UserName}}has-error has-feedback{{end}}"> <div class="form-group {{if .Err_UserName}}has-error has-feedback{{end}}">
<label class="col-md-4 control-label">Username: </label> <label class="col-md-4 control-label">Username: </label>
<div class="col-md-6"> <div class="col-md-6">

60
web.go
View File

@ -79,9 +79,12 @@ func runWeb(*cli.Context) {
reqSignOut := middleware.Toggle(&middleware.ToggleOptions{SignOutRequire: true}) reqSignOut := middleware.Toggle(&middleware.ToggleOptions{SignOutRequire: true})
bindIgnErr := binding.BindIgnErr
// Routers. // Routers.
m.Get("/", ignSignIn, routers.Home) m.Get("/", ignSignIn, routers.Home)
m.Any("/install", binding.BindIgnErr(auth.InstallForm{}), routers.Install) m.Get("/install", bindIgnErr(auth.InstallForm{}), routers.Install)
m.Post("/install", bindIgnErr(auth.InstallForm{}), routers.InstallPost)
m.Get("/issues", reqSignIn, user.Issues) m.Get("/issues", reqSignIn, user.Issues)
m.Get("/pulls", reqSignIn, user.Pulls) m.Get("/pulls", reqSignIn, user.Pulls)
m.Get("/stars", reqSignIn, user.Stars) m.Get("/stars", reqSignIn, user.Stars)
@ -95,33 +98,43 @@ func runWeb(*cli.Context) {
m.Get("/avatar/:hash", avt.ServeHTTP) m.Get("/avatar/:hash", avt.ServeHTTP)
m.Group("/user", func(r martini.Router) { m.Group("/user", func(r martini.Router) {
r.Any("/login", binding.BindIgnErr(auth.LogInForm{}), user.SignIn) r.Get("/login", user.SignIn)
r.Any("/login/github", user.SocialSignIn) r.Post("/login", bindIgnErr(auth.LogInForm{}), user.SignInPost)
r.Any("/sign_up", binding.BindIgnErr(auth.RegisterForm{}), user.SignUp) r.Get("/login/github", user.SocialSignIn)
r.Any("/forget_password", user.ForgotPasswd) r.Get("/sign_up", user.SignUp)
r.Any("/reset_password", user.ResetPasswd) r.Post("/sign_up", bindIgnErr(auth.RegisterForm{}), user.SignUpPost)
r.Get("/reset_password", user.ResetPasswd)
r.Post("/reset_password", user.ResetPasswdPost)
}, reqSignOut) }, reqSignOut)
m.Group("/user", func(r martini.Router) { m.Group("/user", func(r martini.Router) {
r.Any("/logout", user.SignOut) r.Get("/logout", user.SignOut)
r.Any("/delete", user.Delete) r.Get("/delete", user.Delete)
r.Any("/setting", binding.BindIgnErr(auth.UpdateProfileForm{}), user.Setting) r.Post("/delete", user.DeletePost)
r.Get("/setting", user.Setting)
r.Post("/setting", bindIgnErr(auth.UpdateProfileForm{}), user.SettingPost)
}, reqSignIn) }, reqSignIn)
m.Group("/user", func(r martini.Router) { m.Group("/user", func(r martini.Router) {
r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds) r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds)
r.Get("/activate", user.Activate) r.Get("/activate", user.Activate)
r.Get("/forget_password", user.ForgotPasswd)
r.Post("/forget_password", user.ForgotPasswdPost)
}) })
m.Group("/user/setting", func(r martini.Router) { m.Group("/user/setting", func(r martini.Router) {
r.Any("/password", binding.BindIgnErr(auth.UpdatePasswdForm{}), user.SettingPassword) r.Get("/password", user.SettingPassword)
r.Any("/ssh", binding.BindIgnErr(auth.AddSSHKeyForm{}), user.SettingSSHKeys) r.Post("/password", bindIgnErr(auth.UpdatePasswdForm{}), user.SettingPasswordPost)
r.Any("/notification", user.SettingNotification) r.Any("/ssh", bindIgnErr(auth.AddSSHKeyForm{}), user.SettingSSHKeys)
r.Any("/security", user.SettingSecurity) r.Get("/notification", user.SettingNotification)
r.Get("/security", user.SettingSecurity)
}, reqSignIn) }, reqSignIn)
m.Get("/user/:username", ignSignIn, user.Profile) m.Get("/user/:username", ignSignIn, user.Profile)
m.Any("/repo/create", reqSignIn, binding.BindIgnErr(auth.CreateRepoForm{}), repo.Create) m.Group("/repo", func(r martini.Router) {
m.Any("/repo/mirror", reqSignIn, binding.BindIgnErr(auth.CreateRepoForm{}), repo.Mirror) m.Get("/create", repo.Create)
m.Post("/create", bindIgnErr(auth.CreateRepoForm{}), repo.CreatePost)
m.Get("/mirror", repo.Mirror)
m.Post("/mirror", bindIgnErr(auth.CreateRepoForm{}), repo.MirrorPost)
}, reqSignIn)
adminReq := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: true, AdminRequire: true}) adminReq := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: true, AdminRequire: true})
@ -132,9 +145,11 @@ func runWeb(*cli.Context) {
r.Get("/config", admin.Config) r.Get("/config", admin.Config)
}, adminReq) }, adminReq)
m.Group("/admin/users", func(r martini.Router) { m.Group("/admin/users", func(r martini.Router) {
r.Any("/new", binding.BindIgnErr(auth.RegisterForm{}), admin.NewUser) r.Get("/new", admin.NewUser)
r.Any("/:userid", binding.BindIgnErr(auth.AdminEditUserForm{}), admin.EditUser) r.Post("/new", bindIgnErr(auth.RegisterForm{}), admin.NewUserPost)
r.Any("/:userid/delete", admin.DeleteUser) r.Get("/:userid", admin.EditUser)
r.Post("/:userid", bindIgnErr(auth.AdminEditUserForm{}), admin.EditUserPost)
r.Get("/:userid/delete", admin.DeleteUser)
}, adminReq) }, adminReq)
if martini.Env == martini.Dev { if martini.Env == martini.Dev {
@ -145,8 +160,9 @@ func runWeb(*cli.Context) {
r.Post("/settings", repo.SettingPost) r.Post("/settings", repo.SettingPost)
r.Get("/settings", repo.Setting) r.Get("/settings", repo.Setting)
r.Get("/action/:action", repo.Action) r.Get("/action/:action", repo.Action)
r.Any("/issues/new", binding.BindIgnErr(auth.CreateIssueForm{}), repo.CreateIssue) r.Get("/issues/new", repo.CreateIssue)
r.Post("/issues/:index", binding.BindIgnErr(auth.CreateIssueForm{}), repo.UpdateIssue) r.Post("/issues/new", bindIgnErr(auth.CreateIssueForm{}), repo.CreateIssuePost)
r.Post("/issues/:index", bindIgnErr(auth.CreateIssueForm{}), repo.UpdateIssue)
r.Post("/comment/:action", repo.Comment) r.Post("/comment/:action", repo.Comment)
}, reqSignIn, middleware.RepoAssignment(true)) }, reqSignIn, middleware.RepoAssignment(true))
@ -154,7 +170,7 @@ func runWeb(*cli.Context) {
r.Get("/issues", repo.Issues) r.Get("/issues", repo.Issues)
r.Get("/issues/:index", repo.ViewIssue) r.Get("/issues/:index", repo.ViewIssue)
r.Get("/releases", repo.Releases) r.Get("/releases", repo.Releases)
r.Any("/releases/new", repo.ReleasesNew) r.Any("/releases/new", repo.ReleasesNew) // TODO:
r.Get("/pulls", repo.Pulls) r.Get("/pulls", repo.Pulls)
r.Get("/branches", repo.Branches) r.Get("/branches", repo.Branches)
}, ignSignIn, middleware.RepoAssignment(true)) }, ignSignIn, middleware.RepoAssignment(true))