aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/auth/admin.go55
-rw-r--r--modules/auth/user.go2
-rw-r--r--modules/base/conf.go92
-rw-r--r--modules/base/markdown.go4
-rw-r--r--modules/base/template.go11
-rw-r--r--modules/mailer/mailer.go2
-rw-r--r--modules/middleware/auth.go16
-rw-r--r--modules/middleware/context.go17
-rw-r--r--modules/middleware/repo.go2
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
}
}