diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/auth/admin.go | 55 | ||||
-rw-r--r-- | modules/auth/user.go | 2 | ||||
-rw-r--r-- | modules/base/conf.go | 92 | ||||
-rw-r--r-- | modules/base/markdown.go | 4 | ||||
-rw-r--r-- | modules/base/template.go | 11 | ||||
-rw-r--r-- | modules/mailer/mailer.go | 2 | ||||
-rw-r--r-- | modules/middleware/auth.go | 16 | ||||
-rw-r--r-- | modules/middleware/context.go | 17 | ||||
-rw-r--r-- | modules/middleware/repo.go | 2 |
9 files changed, 169 insertions, 32 deletions
diff --git a/modules/auth/admin.go b/modules/auth/admin.go new file mode 100644 index 00000000..eccab007 --- /dev/null +++ b/modules/auth/admin.go @@ -0,0 +1,55 @@ +// 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 auth + +import ( + "net/http" + "reflect" + + "github.com/codegangsta/martini" + + "github.com/gogits/binding" + + "github.com/gogits/gogs/modules/base" + "github.com/gogits/gogs/modules/log" +) + +type AdminEditUserForm struct { + Email string `form:"email" binding:"Required;Email;MaxSize(50)"` + Website string `form:"website" binding:"MaxSize(50)"` + Location string `form:"location" binding:"MaxSize(50)"` + Avatar string `form:"avatar" binding:"Required;Email;MaxSize(50)"` + Active string `form:"active"` + Admin string `form:"admin"` +} + +func (f *AdminEditUserForm) Name(field string) string { + names := map[string]string{ + "Email": "E-mail address", + "Website": "Website", + "Location": "Location", + "Avatar": "Gravatar Email", + } + return names[field] +} + +func (f *AdminEditUserForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) { + if req.Method == "GET" || errors.Count() == 0 { + return + } + + data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) + data["HasError"] = true + AssignForm(f, data) + + if len(errors.Overall) > 0 { + for _, err := range errors.Overall { + log.Error("AdminEditUserForm.Validate: %v", err) + } + return + } + + validate(errors, data, f) +} diff --git a/modules/auth/user.go b/modules/auth/user.go index 491ec65a..f8d8f661 100644 --- a/modules/auth/user.go +++ b/modules/auth/user.go @@ -79,7 +79,7 @@ type UpdateProfileForm struct { func (f *UpdateProfileForm) Name(field string) string { names := map[string]string{ - "Email": "Email address", + "Email": "E-mail address", "Website": "Website", "Location": "Location", "Avatar": "Gravatar Email", diff --git a/modules/base/conf.go b/modules/base/conf.go index fdbf3ad3..863daca6 100644 --- a/modules/base/conf.go +++ b/modules/base/conf.go @@ -15,6 +15,8 @@ import ( "github.com/Unknwon/com" "github.com/Unknwon/goconfig" + "github.com/gogits/cache" + "github.com/gogits/gogs/modules/log" ) @@ -26,20 +28,32 @@ type Mailer struct { } var ( - AppVer string - AppName string - AppLogo string - AppUrl string - Domain string - SecretKey string + AppVer string + AppName string + AppLogo string + AppUrl string + Domain string + SecretKey string + RunUser string + RepoRootPath string + Cfg *goconfig.ConfigFile MailService *Mailer + + Cache cache.Cache + CacheAdapter string + CacheConfig string + + LogMode string + LogConfig string ) var Service struct { - RegisterEmailConfirm bool - ActiveCodeLives int - ResetPwdCodeLives int + RegisterEmailConfirm bool + DisenableRegisteration bool + RequireSignInView bool + ActiveCodeLives int + ResetPwdCodeLives int } func exeDir() (string, error) { @@ -66,19 +80,21 @@ var logLevels = map[string]string{ func newService() { Service.ActiveCodeLives = Cfg.MustInt("service", "ACTIVE_CODE_LIVE_MINUTES", 180) Service.ResetPwdCodeLives = Cfg.MustInt("service", "RESET_PASSWD_CODE_LIVE_MINUTES", 180) + Service.DisenableRegisteration = Cfg.MustBool("service", "DISENABLE_REGISTERATION", false) + Service.RequireSignInView = Cfg.MustBool("service", "REQUIRE_SIGNIN_VIEW", false) } func newLogService() { // Get and check log mode. - mode := Cfg.MustValue("log", "MODE", "console") - modeSec := "log." + mode + LogMode = Cfg.MustValue("log", "MODE", "console") + modeSec := "log." + LogMode if _, err := Cfg.GetSection(modeSec); err != nil { - fmt.Printf("Unknown log mode: %s\n", mode) + fmt.Printf("Unknown log mode: %s\n", LogMode) os.Exit(2) } // Log level. - levelName := Cfg.MustValue("log."+mode, "LEVEL", "Trace") + levelName := Cfg.MustValue("log."+LogMode, "LEVEL", "Trace") level, ok := logLevels[levelName] if !ok { fmt.Printf("Unknown log level: %s\n", levelName) @@ -86,14 +102,13 @@ func newLogService() { } // Generate log configuration. - var config string - switch mode { + switch LogMode { case "console": - config = fmt.Sprintf(`{"level":%s}`, level) + LogConfig = fmt.Sprintf(`{"level":%s}`, level) case "file": logPath := Cfg.MustValue(modeSec, "FILE_NAME", "log/gogs.log") os.MkdirAll(path.Dir(logPath), os.ModePerm) - config = fmt.Sprintf( + LogConfig = fmt.Sprintf( `{"level":%s,"filename":%s,"rotate":%v,"maxlines":%d,"maxsize",%d,"daily":%v,"maxdays":%d}`, level, logPath, Cfg.MustBool(modeSec, "LOG_ROTATE", true), @@ -102,13 +117,13 @@ func newLogService() { Cfg.MustBool(modeSec, "DAILY_ROTATE", true), Cfg.MustInt(modeSec, "MAX_DAYS", 7)) case "conn": - config = fmt.Sprintf(`{"level":%s,"reconnectOnMsg":%v,"reconnect":%v,"net":%s,"addr":%s}`, level, + LogConfig = fmt.Sprintf(`{"level":%s,"reconnectOnMsg":%v,"reconnect":%v,"net":%s,"addr":%s}`, level, Cfg.MustBool(modeSec, "RECONNECT_ON_MSG", false), Cfg.MustBool(modeSec, "RECONNECT", false), Cfg.MustValue(modeSec, "PROTOCOL", "tcp"), Cfg.MustValue(modeSec, "ADDR", ":7020")) case "smtp": - config = fmt.Sprintf(`{"level":%s,"username":%s,"password":%s,"host":%s,"sendTos":%s,"subject":%s}`, level, + LogConfig = fmt.Sprintf(`{"level":%s,"username":%s,"password":%s,"host":%s,"sendTos":%s,"subject":%s}`, level, Cfg.MustValue(modeSec, "USER", "example@example.com"), Cfg.MustValue(modeSec, "PASSWD", "******"), Cfg.MustValue(modeSec, "HOST", "127.0.0.1:25"), @@ -116,8 +131,32 @@ func newLogService() { Cfg.MustValue(modeSec, "SUBJECT", "Diagnostic message from serve")) } - log.NewLogger(Cfg.MustInt64("log", "BUFFER_LEN", 10000), mode, config) - log.Info("Log Mode: %s(%s)", strings.Title(mode), levelName) + log.NewLogger(Cfg.MustInt64("log", "BUFFER_LEN", 10000), LogMode, LogConfig) + log.Info("Log Mode: %s(%s)", strings.Title(LogMode), levelName) +} + +func newCacheService() { + CacheAdapter = Cfg.MustValue("cache", "ADAPTER", "memory") + + switch CacheAdapter { + case "memory": + CacheConfig = fmt.Sprintf(`{"interval":%d}`, Cfg.MustInt("cache", "INTERVAL", 60)) + case "redis", "memcache": + CacheConfig = fmt.Sprintf(`{"conn":"%s"}`, Cfg.MustValue("cache", "HOST")) + default: + fmt.Printf("Unknown cache adapter: %s\n", CacheAdapter) + os.Exit(2) + } + + var err error + Cache, err = cache.NewCache(CacheAdapter, CacheConfig) + if err != nil { + fmt.Printf("Init cache system failed, adapter: %s, config: %s, %v\n", + CacheAdapter, CacheConfig, err) + os.Exit(2) + } + + log.Info("Cache Service Enabled") } func newMailService() { @@ -144,7 +183,7 @@ func newRegisterMailService() { log.Info("Register Mail Service Enabled") } -func init() { +func NewConfigContext() { var err error workDir, err := exeDir() if err != nil { @@ -173,11 +212,20 @@ func init() { AppUrl = Cfg.MustValue("server", "ROOT_URL") Domain = Cfg.MustValue("server", "DOMAIN") SecretKey = Cfg.MustValue("security", "SECRET_KEY") + RunUser = Cfg.MustValue("", "RUN_USER") + + // Determine and create root git reposiroty path. + RepoRootPath = Cfg.MustValue("repository", "ROOT") + if err = os.MkdirAll(RepoRootPath, os.ModePerm); err != nil { + fmt.Printf("models.init(fail to create RepoRootPath(%s)): %v\n", RepoRootPath, err) + os.Exit(2) + } } func NewServices() { newService() newLogService() + newCacheService() newMailService() newRegisterMailService() } diff --git a/modules/base/markdown.go b/modules/base/markdown.go index a9f4cbf0..2273cd77 100644 --- a/modules/base/markdown.go +++ b/modules/base/markdown.go @@ -36,7 +36,7 @@ func isLink(link []byte) bool { func IsMarkdownFile(name string) bool { name = strings.ToLower(name) switch filepath.Ext(name) { - case "md", "markdown": + case ".md", ".markdown", ".mdown": return true } return false @@ -61,7 +61,7 @@ type CustomRender struct { func (options *CustomRender) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) { if len(link) > 0 && !isLink(link) { if link[0] == '#' { - link = append([]byte(options.urlPrefix), link...) + // link = append([]byte(options.urlPrefix), link...) } else { link = []byte(path.Join(options.urlPrefix, string(link))) } diff --git a/modules/base/template.go b/modules/base/template.go index e596d1da..8d95dbea 100644 --- a/modules/base/template.go +++ b/modules/base/template.go @@ -33,6 +33,10 @@ func List(l *list.List) chan interface{} { return c } +var mailDomains = map[string]string{ + "gmail.com": "gmail.com", +} + var TemplateFuncs template.FuncMap = map[string]interface{}{ "AppName": func() string { return AppName @@ -56,7 +60,12 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{ "DateFormat": DateFormat, "List": List, "Mail2Domain": func(mail string) string { - return "mail." + strings.Split(mail, "@")[1] + suffix := strings.SplitN(mail, "@", 2)[1] + domain, ok := mailDomains[suffix] + if !ok { + return "mail." + suffix + } + return domain }, "SubStr": func(str string, start, length int) string { return str[start : start+length] diff --git a/modules/mailer/mailer.go b/modules/mailer/mailer.go index 150607f8..da63e01d 100644 --- a/modules/mailer/mailer.go +++ b/modules/mailer/mailer.go @@ -40,7 +40,7 @@ func (m Message) Content() string { var mailQueue chan *Message -func init() { +func NewMailerContext() { mailQueue = make(chan *Message, base.Cfg.MustInt("mailer", "SEND_BUFFER_LEN", 10)) go processMailQueue() } diff --git a/modules/middleware/auth.go b/modules/middleware/auth.go index d45a21e9..f211de32 100644 --- a/modules/middleware/auth.go +++ b/modules/middleware/auth.go @@ -15,12 +15,12 @@ func SignInRequire(redirect bool) martini.Handler { return func(ctx *Context) { if !ctx.IsSigned { if redirect { - ctx.Redirect("/") + ctx.Redirect("/user/login") } return } else if !ctx.User.IsActive && base.Service.RegisterEmailConfirm { ctx.Data["Title"] = "Activate Your Account" - ctx.Render.HTML(200, "user/active", ctx.Data) + ctx.HTML(200, "user/active") return } } @@ -31,6 +31,18 @@ func SignOutRequire() martini.Handler { return func(ctx *Context) { if ctx.IsSigned { ctx.Redirect("/") + return + } + } +} + +// AdminRequire requires user signed in as administor. +func AdminRequire() martini.Handler { + return func(ctx *Context) { + if !ctx.User.IsAdmin { + ctx.Error(403) + return } + ctx.Data["PageIsAdmin"] = true } } diff --git a/modules/middleware/context.go b/modules/middleware/context.go index 6ac87de3..a25a3dbb 100644 --- a/modules/middleware/context.go +++ b/modules/middleware/context.go @@ -12,8 +12,11 @@ import ( "github.com/codegangsta/martini" "github.com/martini-contrib/sessions" + "github.com/gogits/cache" + "github.com/gogits/gogs/models" "github.com/gogits/gogs/modules/auth" + "github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/log" ) @@ -25,6 +28,7 @@ type Context struct { Req *http.Request Res http.ResponseWriter Session sessions.Session + Cache cache.Cache User *models.User IsSigned bool @@ -61,24 +65,29 @@ func (ctx *Context) HasError() bool { return hasErr.(bool) } +// HTML calls render.HTML underlying but reduce one argument. +func (ctx *Context) HTML(status int, name string, htmlOpt ...HTMLOptions) { + ctx.Render.HTML(status, name, ctx.Data, htmlOpt...) +} + // RenderWithErr used for page has form validation but need to prompt error to users. func (ctx *Context) RenderWithErr(msg, tpl string, form auth.Form) { ctx.Data["HasError"] = true ctx.Data["ErrorMsg"] = msg auth.AssignForm(form, ctx.Data) - ctx.HTML(200, tpl, ctx.Data) + ctx.HTML(200, tpl) } // Handle handles and logs error by given status. func (ctx *Context) Handle(status int, title string, err error) { log.Error("%s: %v", title, err) if martini.Dev == martini.Prod { - ctx.HTML(500, "status/500", ctx.Data) + ctx.HTML(500, "status/500") return } ctx.Data["ErrorMsg"] = err - ctx.HTML(status, fmt.Sprintf("status/%d", status), ctx.Data) + ctx.HTML(status, fmt.Sprintf("status/%d", status)) } // InitContext initializes a classic context for a request. @@ -92,6 +101,7 @@ func InitContext() martini.Handler { Req: r, Res: res, Session: session, + Cache: base.Cache, Render: rd, } @@ -106,6 +116,7 @@ func InitContext() martini.Handler { ctx.Data["SignedUser"] = user ctx.Data["SignedUserId"] = user.Id ctx.Data["SignedUserName"] = user.LowerName + ctx.Data["IsAdmin"] = ctx.User.IsAdmin } ctx.Data["PageStartTime"] = time.Now() diff --git a/modules/middleware/repo.go b/modules/middleware/repo.go index b25c9423..a9a90e3f 100644 --- a/modules/middleware/repo.go +++ b/modules/middleware/repo.go @@ -70,6 +70,7 @@ func RepoAssignment(redirect bool) martini.Handler { } ctx.Repo.Repository = repo ctx.Repo.CloneLink.SSH = fmt.Sprintf("git@%s:%s/%s.git", base.Domain, user.LowerName, repo.LowerName) + ctx.Repo.CloneLink.HTTPS = fmt.Sprintf("https://%s/%s/%s.git", base.Domain, user.LowerName, repo.LowerName) ctx.Data["IsRepositoryValid"] = true ctx.Data["Repository"] = repo @@ -78,5 +79,6 @@ func RepoAssignment(redirect bool) martini.Handler { ctx.Data["CloneLink"] = ctx.Repo.CloneLink ctx.Data["RepositoryLink"] = ctx.Data["Title"] ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner + ctx.Data["IsRepositoryWatching"] = ctx.Repo.IsWatching } } |