| @@ -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.3.0410 Alpha" | |||||
| func init() { | func init() { | ||||
| base.AppVer = APP_VER | base.AppVer = APP_VER | ||||
| @@ -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,8 +91,7 @@ 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 | |||||
| ctx.Flash.Error(msg) | |||||
| if form != nil { | if form != nil { | ||||
| auth.AssignForm(form, ctx.Data) | auth.AssignForm(form, ctx.Data) | ||||
| } | } | ||||
| @@ -239,6 +241,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 +273,24 @@ func InitContext() martini.Handler { | |||||
| // start session | // start session | ||||
| ctx.Session = base.SessionManager.SessionStart(res, r) | ctx.Session = base.SessionManager.SessionStart(res, r) | ||||
| ctx.Flash = &Flash{} | |||||
| // Get flash. | |||||
| values, err := url.ParseQuery(ctx.GetCookie("gogs_flash")) | |||||
| if err != nil { | |||||
| log.Error("InitContext.ParseQuery(flash): %v", err) | |||||
| } else { | |||||
| ctx.Flash.Values = values | |||||
| ctx.Data["Flash"] = ctx.Flash | |||||
| } | |||||
| 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(), -1) | |||||
| } | |||||
| }) | }) | ||||
| // Get user from session if logined. | // Get user from session if logined. | ||||
| @@ -23,6 +23,10 @@ import ( | |||||
| "github.com/gogits/gogs/modules/middleware" | "github.com/gogits/gogs/modules/middleware" | ||||
| ) | ) | ||||
| type installRouter int | |||||
| var InstallRouter installRouter = 1 | |||||
| // Check run mode(Default of martini is Dev). | // Check run mode(Default of martini is Dev). | ||||
| func checkRunMode() { | func checkRunMode() { | ||||
| switch base.Cfg.MustValue("", "RUN_MODE") { | switch base.Cfg.MustValue("", "RUN_MODE") { | ||||
| @@ -54,7 +58,7 @@ func GlobalInit() { | |||||
| checkRunMode() | checkRunMode() | ||||
| } | } | ||||
| func Install(ctx *middleware.Context, form auth.InstallForm) { | |||||
| func (r installRouter) Get(ctx *middleware.Context, form auth.InstallForm) { | |||||
| if base.InstallLock { | if base.InstallLock { | ||||
| ctx.Handle(404, "install.Install", errors.New("Installation is prohibited")) | ctx.Handle(404, "install.Install", errors.New("Installation is prohibited")) | ||||
| return | return | ||||
| @@ -63,42 +67,49 @@ 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. | |||||
| if len(form.Host) == 0 { | |||||
| form.Host = models.DbCfg.Host | |||||
| } | |||||
| if len(form.User) == 0 { | |||||
| form.User = models.DbCfg.User | |||||
| } | |||||
| if len(form.Passwd) == 0 { | |||||
| form.Passwd = models.DbCfg.Pwd | |||||
| } | |||||
| if len(form.DatabaseName) == 0 { | |||||
| form.DatabaseName = models.DbCfg.Name | |||||
| } | |||||
| if len(form.DatabasePath) == 0 { | |||||
| form.DatabasePath = models.DbCfg.Path | |||||
| } | |||||
| // Get and assign value to install form. | |||||
| if len(form.Host) == 0 { | |||||
| form.Host = models.DbCfg.Host | |||||
| } | |||||
| if len(form.User) == 0 { | |||||
| form.User = models.DbCfg.User | |||||
| } | |||||
| if len(form.Passwd) == 0 { | |||||
| form.Passwd = models.DbCfg.Pwd | |||||
| } | |||||
| if len(form.DatabaseName) == 0 { | |||||
| form.DatabaseName = models.DbCfg.Name | |||||
| } | |||||
| if len(form.DatabasePath) == 0 { | |||||
| form.DatabasePath = models.DbCfg.Path | |||||
| } | |||||
| if len(form.RepoRootPath) == 0 { | |||||
| form.RepoRootPath = base.RepoRootPath | |||||
| } | |||||
| if len(form.RunUser) == 0 { | |||||
| form.RunUser = base.RunUser | |||||
| } | |||||
| if len(form.Domain) == 0 { | |||||
| form.Domain = base.Domain | |||||
| } | |||||
| if len(form.AppUrl) == 0 { | |||||
| form.AppUrl = base.AppUrl | |||||
| } | |||||
| if len(form.RepoRootPath) == 0 { | |||||
| form.RepoRootPath = base.RepoRootPath | |||||
| } | |||||
| if len(form.RunUser) == 0 { | |||||
| form.RunUser = base.RunUser | |||||
| } | |||||
| if len(form.Domain) == 0 { | |||||
| form.Domain = base.Domain | |||||
| } | |||||
| if len(form.AppUrl) == 0 { | |||||
| form.AppUrl = base.AppUrl | |||||
| } | |||||
| auth.AssignForm(form, ctx.Data) | |||||
| ctx.HTML(200, "install") | |||||
| auth.AssignForm(form, ctx.Data) | |||||
| ctx.HTML(200, "install") | |||||
| } | |||||
| func (r installRouter) Post(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 +208,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") | ||||
| } | } | ||||
| @@ -0,0 +1 @@ | |||||
| {{if .Flash.ErrorMsg}}<div class="alert alert-danger form-error">{{.Flash.ErrorMsg}}</div>{{end}} | |||||
| @@ -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> | ||||
| @@ -74,9 +74,12 @@ func runWeb(*cli.Context) { | |||||
| ignSignIn := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: base.Service.RequireSignInView}) | ignSignIn := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: base.Service.RequireSignInView}) | ||||
| 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.InstallRouter.Get) | |||||
| m.Post("/install", bindIgnErr(auth.InstallForm{}), routers.InstallRouter.Post) | |||||
| 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) | ||||