From 7bbf644dd5eaca77c3e8df57419180486bda0fc2 Mon Sep 17 00:00:00 2001 From: Unknwon Date: Thu, 31 Jul 2014 17:25:34 -0400 Subject: [PATCH] Convert captcha, cache, csrf as middlewares --- cmd/web.go | 30 +- gogs.go | 2 +- modules/base/template.go | 1 - modules/base/tool.go | 28 -- modules/captcha/captcha.go | 201 -------------- modules/captcha/image.go | 487 --------------------------------- modules/captcha/image_test.go | 42 --- modules/captcha/siprng.go | 267 ------------------ modules/captcha/siprng_test.go | 23 -- modules/middleware/auth.go | 9 +- modules/middleware/context.go | 47 +--- modules/setting/setting.go | 19 +- routers/admin/admin.go | 3 +- routers/user/auth.go | 3 +- templates/.VERSION | 2 +- templates/user/signin.tmpl | 1 - templates/user/signup.tmpl | 3 +- 17 files changed, 46 insertions(+), 1122 deletions(-) delete mode 100644 modules/captcha/captcha.go delete mode 100644 modules/captcha/image.go delete mode 100644 modules/captcha/image_test.go delete mode 100644 modules/captcha/siprng.go delete mode 100644 modules/captcha/siprng_test.go diff --git a/cmd/web.go b/cmd/web.go index a0690cda25..bd2eb79dbd 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -14,6 +14,9 @@ import ( "github.com/Unknwon/macaron" "github.com/codegangsta/cli" + "github.com/macaron-contrib/cache" + "github.com/macaron-contrib/captcha" + "github.com/macaron-contrib/csrf" "github.com/macaron-contrib/i18n" "github.com/macaron-contrib/session" @@ -21,7 +24,6 @@ import ( "github.com/gogits/gogs/modules/auth/apiv1" "github.com/gogits/gogs/modules/avatar" "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/captcha" "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/middleware" "github.com/gogits/gogs/modules/middleware/binding" @@ -78,10 +80,20 @@ func newMacaron() *macaron.Macaron { Names: setting.Names, Redirect: true, })) + m.Use(cache.Cacher(cache.Options{ + Adapter: setting.CacheAdapter, + Interval: setting.CacheInternal, + Conn: setting.CacheConn, + })) + m.Use(captcha.Captchaer()) m.Use(session.Sessioner(session.Options{ Provider: setting.SessionProvider, Config: *setting.SessionConfig, })) + m.Use(csrf.Generate(csrf.Options{ + Secret: setting.SecretKey, + SetCookie: true, + })) m.Use(middleware.Contexter()) return m } @@ -121,16 +133,12 @@ func runWeb(*cli.Context) { // Repositories. r.Get("/orgs/:org/repos/search", v1.SearchOrgRepositoreis) - r.Any("**", func(ctx *middleware.Context) { + r.Any("/*", func(ctx *middleware.Context) { ctx.JSON(404, &base.ApiJsonErr{"Not Found", v1.DOC_URL}) }) }) }) - avt := avatar.CacheServer("public/img/avatar/", "public/img/avatar_default.jpg") - os.MkdirAll("public/img/avatar/", os.ModePerm) - m.Get("/avatar/:hash", avt.ServeHTTP) - // User routers. m.Group("/user", func(r *macaron.Router) { r.Get("/login", user.SignIn) @@ -165,10 +173,10 @@ func runWeb(*cli.Context) { m.Get("/user/:username", ignSignIn, user.Profile) // TODO: Legacy - // Captcha service. - cpt := captcha.NewCaptcha("/captcha/", setting.Cache) - m.Map(cpt) - m.Get("/captcha/*", cpt.Handler) + // Gravatar service. + avt := avatar.CacheServer("public/img/avatar/", "public/img/avatar_default.jpg") + os.MkdirAll("public/img/avatar/", os.ModePerm) + m.Get("/avatar/:hash", avt.ServeHTTP) adminReq := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: true, AdminRequire: true}) @@ -199,7 +207,7 @@ func runWeb(*cli.Context) { m.Get("/:username", ignSignIn, user.Profile) if macaron.Env == macaron.DEV { - m.Get("/template/**", dev.TemplatePreview) + m.Get("/template/*", dev.TemplatePreview) dev.RegisterDebugRoutes(m) } diff --git a/gogs.go b/gogs.go index e55d387288..8e3635a1e5 100644 --- a/gogs.go +++ b/gogs.go @@ -17,7 +17,7 @@ import ( "github.com/gogits/gogs/modules/setting" ) -const APP_VER = "0.4.7.0730 Alpha" +const APP_VER = "0.4.7.0731 Alpha" func init() { runtime.GOMAXPROCS(runtime.NumCPU()) diff --git a/modules/base/template.go b/modules/base/template.go index b9968bae65..51b1dfff01 100644 --- a/modules/base/template.go +++ b/modules/base/template.go @@ -103,7 +103,6 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{ "ActionContent2Commits": ActionContent2Commits, "Oauth2Icon": Oauth2Icon, "Oauth2Name": Oauth2Name, - "CreateCaptcha": func() string { return "" }, } type Actioner interface { diff --git a/modules/base/tool.go b/modules/base/tool.go index 830c37f697..a2a155d61f 100644 --- a/modules/base/tool.go +++ b/modules/base/tool.go @@ -13,7 +13,6 @@ import ( "fmt" "hash" "math" - r "math/rand" "strings" "time" @@ -45,33 +44,6 @@ func GetRandomString(n int, alphabets ...byte) string { return string(bytes) } -// RandomCreateBytes generate random []byte by specify chars. -func RandomCreateBytes(n int, alphabets ...byte) []byte { - const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" - var bytes = make([]byte, n) - var randby bool - if num, err := rand.Read(bytes); num != n || err != nil { - r.Seed(time.Now().UnixNano()) - randby = true - } - for i, b := range bytes { - if len(alphabets) == 0 { - if randby { - bytes[i] = alphanum[r.Intn(len(alphanum))] - } else { - bytes[i] = alphanum[b%byte(len(alphanum))] - } - } else { - if randby { - bytes[i] = alphabets[r.Intn(len(alphabets))] - } else { - bytes[i] = alphabets[b%byte(len(alphabets))] - } - } - } - return bytes -} - // http://code.google.com/p/go/source/browse/pbkdf2/pbkdf2.go?repo=crypto func PBKDF2(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte { prf := hmac.New(h, password) diff --git a/modules/captcha/captcha.go b/modules/captcha/captcha.go deleted file mode 100644 index e43e09dc59..0000000000 --- a/modules/captcha/captcha.go +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright 2014 The Gogs Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -// Package captcha a middleware that provides captcha service for Macaron. -package captcha - -import ( - "fmt" - "html/template" - "net/http" - "path" - "strings" - - "github.com/Unknwon/macaron" - - "github.com/gogits/cache" - - "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/log" -) - -var ( - defaultChars = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} -) - -const ( - // default captcha attributes - challengeNums = 6 - expiration = 600 - fieldIdName = "captcha_id" - fieldCaptchaName = "captcha" - cachePrefix = "captcha_" - defaultURLPrefix = "/captcha/" -) - -// Captcha struct -type Captcha struct { - store cache.Cache - - // url prefix for captcha image - URLPrefix string - - // specify captcha id input field name - FieldIdName string - // specify captcha result input field name - FieldCaptchaName string - - // captcha image width and height - StdWidth int - StdHeight int - - // captcha chars nums - ChallengeNums int - - // captcha expiration seconds - Expiration int64 - - // cache key prefix - CachePrefix string -} - -// generate key string -func (c *Captcha) key(id string) string { - return c.CachePrefix + id -} - -// generate rand chars with default chars -func (c *Captcha) genRandChars() []byte { - return base.RandomCreateBytes(c.ChallengeNums, defaultChars...) -} - -// beego filter handler for serve captcha image -func (c *Captcha) Handler(ctx *macaron.Context) { - var chars []byte - - id := path.Base(ctx.Req.RequestURI) - if i := strings.Index(id, "."); i != -1 { - id = id[:i] - } - - key := c.key(id) - - if v, ok := c.store.Get(key).([]byte); ok { - chars = v - } else { - ctx.Status(404) - ctx.Write([]byte("captcha not found")) - return - } - - // reload captcha - if len(ctx.Query("reload")) > 0 { - chars = c.genRandChars() - if err := c.store.Put(key, chars, c.Expiration); err != nil { - ctx.Status(500) - ctx.Write([]byte("captcha reload error")) - log.Error(4, "Reload Create Captcha Error: %v", err) - return - } - } - - img := NewImage(chars, c.StdWidth, c.StdHeight) - if _, err := img.WriteTo(ctx.RW()); err != nil { - log.Error(4, "Write Captcha Image Error: %v", err) - } -} - -// tempalte func for output html -func (c *Captcha) CreateCaptchaHtml() template.HTML { - value, err := c.CreateCaptcha() - if err != nil { - log.Error(4, "Create Captcha Error: %v", err) - return "" - } - - // create html - return template.HTML(fmt.Sprintf(``+ - ``+ - ``+ - ``, c.FieldIdName, value, c.URLPrefix, value, c.URLPrefix, value)) -} - -// create a new captcha id -func (c *Captcha) CreateCaptcha() (string, error) { - // generate captcha id - id := string(base.RandomCreateBytes(15)) - - // get the captcha chars - chars := c.genRandChars() - - // save to store - if err := c.store.Put(c.key(id), chars, c.Expiration); err != nil { - return "", err - } - - return id, nil -} - -// verify from a request -func (c *Captcha) VerifyReq(req *http.Request) bool { - req.ParseForm() - return c.Verify(req.Form.Get(c.FieldIdName), req.Form.Get(c.FieldCaptchaName)) -} - -// direct verify id and challenge string -func (c *Captcha) Verify(id string, challenge string) (success bool) { - if len(challenge) == 0 || len(id) == 0 { - return - } - - var chars []byte - - key := c.key(id) - - if v, ok := c.store.Get(key).([]byte); ok && len(v) == len(challenge) { - chars = v - } else { - return - } - - defer func() { - // finally remove it - c.store.Delete(key) - }() - - // verify challenge - for i, c := range chars { - if c != challenge[i]-48 { - return - } - } - - return true -} - -// create a new captcha.Captcha -func NewCaptcha(urlPrefix string, store cache.Cache) *Captcha { - cpt := &Captcha{} - cpt.store = store - cpt.FieldIdName = fieldIdName - cpt.FieldCaptchaName = fieldCaptchaName - cpt.ChallengeNums = challengeNums - cpt.Expiration = expiration - cpt.CachePrefix = cachePrefix - cpt.StdWidth = stdWidth - cpt.StdHeight = stdHeight - - if len(urlPrefix) == 0 { - urlPrefix = defaultURLPrefix - } - - if urlPrefix[len(urlPrefix)-1] != '/' { - urlPrefix += "/" - } - - cpt.URLPrefix = urlPrefix - - base.TemplateFuncs["CreateCaptcha"] = cpt.CreateCaptchaHtml - return cpt -} diff --git a/modules/captcha/image.go b/modules/captcha/image.go deleted file mode 100644 index c9972ba2c3..0000000000 --- a/modules/captcha/image.go +++ /dev/null @@ -1,487 +0,0 @@ -// Copyright 2014 The Gogs Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package captcha - -import ( - "bytes" - "image" - "image/color" - "image/png" - "io" - "math" -) - -const ( - fontWidth = 11 - fontHeight = 18 - blackChar = 1 - - // Standard width and height of a captcha image. - stdWidth = 240 - stdHeight = 80 - // Maximum absolute skew factor of a single digit. - maxSkew = 0.7 - // Number of background circles. - circleCount = 20 -) - -var font = [][]byte{ - { // 0 - 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, - 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, - }, - { // 1 - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - }, - { // 2 - 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - }, - { // 3 - 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, - 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, - }, - { // 4 - 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, - 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - }, - { // 5 - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, - }, - { // 6 - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, - 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, - 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, - }, - { // 7 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, - }, - { // 8 - 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, - 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, - }, - { // 9 - 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, - 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, - 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, - }, -} - -type Image struct { - *image.Paletted - numWidth int - numHeight int - dotSize int -} - -var prng = &siprng{} - -// randIntn returns a pseudorandom non-negative int in range [0, n). -func randIntn(n int) int { - return prng.Intn(n) -} - -// randInt returns a pseudorandom int in range [from, to]. -func randInt(from, to int) int { - return prng.Intn(to+1-from) + from -} - -// randFloat returns a pseudorandom float64 in range [from, to]. -func randFloat(from, to float64) float64 { - return (to-from)*prng.Float64() + from -} - -func randomPalette() color.Palette { - p := make([]color.Color, circleCount+1) - // Transparent color. - p[0] = color.RGBA{0xFF, 0xFF, 0xFF, 0x00} - // Primary color. - prim := color.RGBA{ - uint8(randIntn(129)), - uint8(randIntn(129)), - uint8(randIntn(129)), - 0xFF, - } - p[1] = prim - // Circle colors. - for i := 2; i <= circleCount; i++ { - p[i] = randomBrightness(prim, 255) - } - return p -} - -// NewImage returns a new captcha image of the given width and height with the -// given digits, where each digit must be in range 0-9. -func NewImage(digits []byte, width, height int) *Image { - m := new(Image) - m.Paletted = image.NewPaletted(image.Rect(0, 0, width, height), randomPalette()) - m.calculateSizes(width, height, len(digits)) - // Randomly position captcha inside the image. - maxx := width - (m.numWidth+m.dotSize)*len(digits) - m.dotSize - maxy := height - m.numHeight - m.dotSize*2 - var border int - if width > height { - border = height / 5 - } else { - border = width / 5 - } - x := randInt(border, maxx-border) - y := randInt(border, maxy-border) - // Draw digits. - for _, n := range digits { - m.drawDigit(font[n], x, y) - x += m.numWidth + m.dotSize - } - // Draw strike-through line. - m.strikeThrough() - // Apply wave distortion. - m.distort(randFloat(5, 10), randFloat(100, 200)) - // Fill image with random circles. - m.fillWithCircles(circleCount, m.dotSize) - return m -} - -// encodedPNG encodes an image to PNG and returns -// the result as a byte slice. -func (m *Image) encodedPNG() []byte { - var buf bytes.Buffer - if err := png.Encode(&buf, m.Paletted); err != nil { - panic(err.Error()) - } - return buf.Bytes() -} - -// WriteTo writes captcha image in PNG format into the given writer. -func (m *Image) WriteTo(w io.Writer) (int64, error) { - n, err := w.Write(m.encodedPNG()) - return int64(n), err -} - -func (m *Image) calculateSizes(width, height, ncount int) { - // Goal: fit all digits inside the image. - var border int - if width > height { - border = height / 4 - } else { - border = width / 4 - } - // Convert everything to floats for calculations. - w := float64(width - border*2) - h := float64(height - border*2) - // fw takes into account 1-dot spacing between digits. - fw := float64(fontWidth + 1) - fh := float64(fontHeight) - nc := float64(ncount) - // Calculate the width of a single digit taking into account only the - // width of the image. - nw := w / nc - // Calculate the height of a digit from this width. - nh := nw * fh / fw - // Digit too high? - if nh > h { - // Fit digits based on height. - nh = h - nw = fw / fh * nh - } - // Calculate dot size. - m.dotSize = int(nh / fh) - // Save everything, making the actual width smaller by 1 dot to account - // for spacing between digits. - m.numWidth = int(nw) - m.dotSize - m.numHeight = int(nh) -} - -func (m *Image) drawHorizLine(fromX, toX, y int, colorIdx uint8) { - for x := fromX; x <= toX; x++ { - m.SetColorIndex(x, y, colorIdx) - } -} - -func (m *Image) drawCircle(x, y, radius int, colorIdx uint8) { - f := 1 - radius - dfx := 1 - dfy := -2 * radius - xo := 0 - yo := radius - - m.SetColorIndex(x, y+radius, colorIdx) - m.SetColorIndex(x, y-radius, colorIdx) - m.drawHorizLine(x-radius, x+radius, y, colorIdx) - - for xo < yo { - if f >= 0 { - yo-- - dfy += 2 - f += dfy - } - xo++ - dfx += 2 - f += dfx - m.drawHorizLine(x-xo, x+xo, y+yo, colorIdx) - m.drawHorizLine(x-xo, x+xo, y-yo, colorIdx) - m.drawHorizLine(x-yo, x+yo, y+xo, colorIdx) - m.drawHorizLine(x-yo, x+yo, y-xo, colorIdx) - } -} - -func (m *Image) fillWithCircles(n, maxradius int) { - maxx := m.Bounds().Max.X - maxy := m.Bounds().Max.Y - for i := 0; i < n; i++ { - colorIdx := uint8(randInt(1, circleCount-1)) - r := randInt(1, maxradius) - m.drawCircle(randInt(r, maxx-r), randInt(r, maxy-r), r, colorIdx) - } -} - -func (m *Image) strikeThrough() { - maxx := m.Bounds().Max.X - maxy := m.Bounds().Max.Y - y := randInt(maxy/3, maxy-maxy/3) - amplitude := randFloat(5, 20) - period := randFloat(80, 180) - dx := 2.0 * math.Pi / period - for x := 0; x < maxx; x++ { - xo := amplitude * math.Cos(float64(y)*dx) - yo := amplitude * math.Sin(float64(x)*dx) - for yn := 0; yn < m.dotSize; yn++ { - r := randInt(0, m.dotSize) - m.drawCircle(x+int(xo), y+int(yo)+(yn*m.dotSize), r/2, 1) - } - } -} - -func (m *Image) drawDigit(digit []byte, x, y int) { - skf := randFloat(-maxSkew, maxSkew) - xs := float64(x) - r := m.dotSize / 2 - y += randInt(-r, r) - for yo := 0; yo < fontHeight; yo++ { - for xo := 0; xo < fontWidth; xo++ { - if digit[yo*fontWidth+xo] != blackChar { - continue - } - m.drawCircle(x+xo*m.dotSize, y+yo*m.dotSize, r, 1) - } - xs += skf - x = int(xs) - } -} - -func (m *Image) distort(amplude float64, period float64) { - w := m.Bounds().Max.X - h := m.Bounds().Max.Y - - oldm := m.Paletted - newm := image.NewPaletted(image.Rect(0, 0, w, h), oldm.Palette) - - dx := 2.0 * math.Pi / period - for x := 0; x < w; x++ { - for y := 0; y < h; y++ { - xo := amplude * math.Sin(float64(y)*dx) - yo := amplude * math.Cos(float64(x)*dx) - newm.SetColorIndex(x, y, oldm.ColorIndexAt(x+int(xo), y+int(yo))) - } - } - m.Paletted = newm -} - -func randomBrightness(c color.RGBA, max uint8) color.RGBA { - minc := min3(c.R, c.G, c.B) - maxc := max3(c.R, c.G, c.B) - if maxc > max { - return c - } - n := randIntn(int(max-maxc)) - int(minc) - return color.RGBA{ - uint8(int(c.R) + n), - uint8(int(c.G) + n), - uint8(int(c.B) + n), - uint8(c.A), - } -} - -func min3(x, y, z uint8) (m uint8) { - m = x - if y < m { - m = y - } - if z < m { - m = z - } - return -} - -func max3(x, y, z uint8) (m uint8) { - m = x - if y > m { - m = y - } - if z > m { - m = z - } - return -} diff --git a/modules/captcha/image_test.go b/modules/captcha/image_test.go deleted file mode 100644 index 35810d0c72..0000000000 --- a/modules/captcha/image_test.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2014 The Gogs Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package captcha - -import ( - "testing" - - "github.com/gogits/gogs/modules/base" -) - -type byteCounter struct { - n int64 -} - -func (bc *byteCounter) Write(b []byte) (int, error) { - bc.n += int64(len(b)) - return len(b), nil -} - -func BenchmarkNewImage(b *testing.B) { - b.StopTimer() - d := base.RandomCreateBytes(challengeNums, defaultChars...) - b.StartTimer() - for i := 0; i < b.N; i++ { - NewImage(d, stdWidth, stdHeight) - } -} - -func BenchmarkImageWriteTo(b *testing.B) { - b.StopTimer() - d := base.RandomCreateBytes(challengeNums, defaultChars...) - b.StartTimer() - counter := &byteCounter{} - for i := 0; i < b.N; i++ { - img := NewImage(d, stdWidth, stdHeight) - img.WriteTo(counter) - b.SetBytes(counter.n) - counter.n = 0 - } -} diff --git a/modules/captcha/siprng.go b/modules/captcha/siprng.go deleted file mode 100644 index c059b9f7bf..0000000000 --- a/modules/captcha/siprng.go +++ /dev/null @@ -1,267 +0,0 @@ -// Copyright 2014 The Gogs Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package captcha - -import ( - "crypto/rand" - "encoding/binary" - "io" - "sync" -) - -// siprng is PRNG based on SipHash-2-4. -type siprng struct { - mu sync.Mutex - k0, k1, ctr uint64 -} - -// siphash implements SipHash-2-4, accepting a uint64 as a message. -func siphash(k0, k1, m uint64) uint64 { - // Initialization. - v0 := k0 ^ 0x736f6d6570736575 - v1 := k1 ^ 0x646f72616e646f6d - v2 := k0 ^ 0x6c7967656e657261 - v3 := k1 ^ 0x7465646279746573 - t := uint64(8) << 56 - - // Compression. - v3 ^= m - - // Round 1. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 2. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - v0 ^= m - - // Compress last block. - v3 ^= t - - // Round 1. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 2. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - v0 ^= t - - // Finalization. - v2 ^= 0xff - - // Round 1. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 2. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 3. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - // Round 4. - v0 += v1 - v1 = v1<<13 | v1>>(64-13) - v1 ^= v0 - v0 = v0<<32 | v0>>(64-32) - - v2 += v3 - v3 = v3<<16 | v3>>(64-16) - v3 ^= v2 - - v0 += v3 - v3 = v3<<21 | v3>>(64-21) - v3 ^= v0 - - v2 += v1 - v1 = v1<<17 | v1>>(64-17) - v1 ^= v2 - v2 = v2<<32 | v2>>(64-32) - - return v0 ^ v1 ^ v2 ^ v3 -} - -// rekey sets a new PRNG key, which is read from crypto/rand. -func (p *siprng) rekey() { - var k [16]byte - if _, err := io.ReadFull(rand.Reader, k[:]); err != nil { - panic(err.Error()) - } - p.k0 = binary.LittleEndian.Uint64(k[0:8]) - p.k1 = binary.LittleEndian.Uint64(k[8:16]) - p.ctr = 1 -} - -// Uint64 returns a new pseudorandom uint64. -// It rekeys PRNG on the first call and every 64 MB of generated data. -func (p *siprng) Uint64() uint64 { - p.mu.Lock() - if p.ctr == 0 || p.ctr > 8*1024*1024 { - p.rekey() - } - v := siphash(p.k0, p.k1, p.ctr) - p.ctr++ - p.mu.Unlock() - return v -} - -func (p *siprng) Int63() int64 { - return int64(p.Uint64() & 0x7fffffffffffffff) -} - -func (p *siprng) Uint32() uint32 { - return uint32(p.Uint64()) -} - -func (p *siprng) Int31() int32 { - return int32(p.Uint32() & 0x7fffffff) -} - -func (p *siprng) Intn(n int) int { - if n <= 0 { - panic("invalid argument to Intn") - } - if n <= 1<<31-1 { - return int(p.Int31n(int32(n))) - } - return int(p.Int63n(int64(n))) -} - -func (p *siprng) Int63n(n int64) int64 { - if n <= 0 { - panic("invalid argument to Int63n") - } - max := int64((1 << 63) - 1 - (1<<63)%uint64(n)) - v := p.Int63() - for v > max { - v = p.Int63() - } - return v % n -} - -func (p *siprng) Int31n(n int32) int32 { - if n <= 0 { - panic("invalid argument to Int31n") - } - max := int32((1 << 31) - 1 - (1<<31)%uint32(n)) - v := p.Int31() - for v > max { - v = p.Int31() - } - return v % n -} - -func (p *siprng) Float64() float64 { return float64(p.Int63()) / (1 << 63) } diff --git a/modules/captcha/siprng_test.go b/modules/captcha/siprng_test.go deleted file mode 100644 index 3b10fe58bf..0000000000 --- a/modules/captcha/siprng_test.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2014 The Gogs Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package captcha - -import "testing" - -func TestSiphash(t *testing.T) { - good := uint64(0xe849e8bb6ffe2567) - cur := siphash(0, 0, 0) - if cur != good { - t.Fatalf("siphash: expected %x, got %x", good, cur) - } -} - -func BenchmarkSiprng(b *testing.B) { - b.SetBytes(8) - p := &siprng{} - for i := 0; i < b.N; i++ { - p.Uint64() - } -} diff --git a/modules/middleware/auth.go b/modules/middleware/auth.go index 741337da0b..29a2d68110 100644 --- a/modules/middleware/auth.go +++ b/modules/middleware/auth.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/Unknwon/macaron" + "github.com/macaron-contrib/csrf" "github.com/gogits/gogs/modules/setting" ) @@ -34,9 +35,11 @@ func Toggle(options *ToggleOptions) macaron.Handler { return } - if !options.DisableCsrf && ctx.Req.Method == "POST" && !ctx.CsrfTokenValid() { - ctx.Error(403, "CSRF token does not match") - return + if !options.SignOutRequire && !options.DisableCsrf && ctx.Req.Method == "POST" { + csrf.Validate(ctx.Context, ctx.csrf) + if ctx.Written() { + return + } } if options.SignInRequire { diff --git a/modules/middleware/context.go b/modules/middleware/context.go index ee203b762d..5300539d42 100644 --- a/modules/middleware/context.go +++ b/modules/middleware/context.go @@ -14,6 +14,8 @@ import ( "time" "github.com/Unknwon/macaron" + "github.com/macaron-contrib/cache" + "github.com/macaron-contrib/csrf" "github.com/macaron-contrib/i18n" "github.com/macaron-contrib/session" @@ -29,14 +31,14 @@ import ( type Context struct { *macaron.Context i18n.Locale + Cache cache.Cache + csrf csrf.CSRF Flash *session.Flash Session session.Store User *models.User IsSigned bool - csrfToken string - Repo struct { IsOwner bool IsTrueOwner bool @@ -70,10 +72,6 @@ func (ctx *Context) Query(name string) string { return ctx.Req.Form.Get(name) } -// func (ctx *Context) Param(name string) string { -// return ctx.p[name] -// } - // HasError returns true if error occurs in form validation. func (ctx *Context) HasApiError() bool { hasErr, ok := ctx.Data["HasError"] @@ -131,33 +129,6 @@ func (ctx *Context) Handle(status int, title string, err error) { ctx.HTML(status, base.TplName(fmt.Sprintf("status/%d", status))) } -func (ctx *Context) CsrfToken() string { - if len(ctx.csrfToken) > 0 { - return ctx.csrfToken - } - - token := ctx.GetCookie("_csrf") - if len(token) == 0 { - token = base.GetRandomString(30) - ctx.SetCookie("_csrf", token) - } - ctx.csrfToken = token - return token -} - -func (ctx *Context) CsrfTokenValid() bool { - token := ctx.Query("_csrf") - if token == "" { - token = ctx.Req.Header.Get("X-Csrf-Token") - } - if token == "" { - return false - } else if ctx.csrfToken != token { - return false - } - return true -} - func (ctx *Context) ServeFile(file string, names ...string) { var name string if len(names) > 0 { @@ -195,14 +166,15 @@ func (ctx *Context) ServeContent(name string, r io.ReadSeeker, params ...interfa // Contexter initializes a classic context for a request. func Contexter() macaron.Handler { - return func(c *macaron.Context, l i18n.Locale, sess session.Store, f *session.Flash) { + return func(c *macaron.Context, l i18n.Locale, cache cache.Cache, sess session.Store, f *session.Flash, x csrf.CSRF) { ctx := &Context{ Context: c, Locale: l, + Cache: cache, + csrf: x, Flash: f, Session: sess, } - // Cache: setting.Cache, // Compute current URL for real-time change language. link := ctx.Req.RequestURI @@ -231,9 +203,8 @@ func Contexter() macaron.Handler { } } - // get or create csrf token - ctx.Data["CsrfToken"] = ctx.CsrfToken() - ctx.Data["CsrfTokenHtml"] = template.HTML(``) + ctx.Data["CsrfToken"] = x.GetToken() + ctx.Data["CsrfTokenHtml"] = template.HTML(``) c.Map(ctx) } diff --git a/modules/setting/setting.go b/modules/setting/setting.go index dbd01051bf..24d041eae5 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -16,8 +16,6 @@ import ( "github.com/Unknwon/goconfig" "github.com/macaron-contrib/session" - "github.com/gogits/cache" - "github.com/gogits/gogs/modules/log" // "github.com/gogits/gogs-ng/modules/ssh" ) @@ -80,9 +78,9 @@ var ( AttachmentEnabled bool // Cache settings. - Cache cache.Cache - CacheAdapter string - CacheConfig string + CacheAdapter string + CacheInternal int + CacheConn string EnableRedis bool EnableMemcache bool @@ -325,20 +323,13 @@ func newCacheService() { switch CacheAdapter { case "memory": - CacheConfig = fmt.Sprintf(`{"interval":%d}`, Cfg.MustInt("cache", "INTERVAL", 60)) + CacheInternal = Cfg.MustInt("cache", "INTERVAL", 60) case "redis", "memcache": - CacheConfig = fmt.Sprintf(`{"conn":"%s"}`, strings.Trim(Cfg.MustValue("cache", "HOST"), "\" ")) + CacheConn = strings.Trim(Cfg.MustValue("cache", "HOST"), "\" ") default: log.Fatal(4, "Unknown cache adapter: %s", CacheAdapter) } - var err error - Cache, err = cache.NewCache(CacheAdapter, CacheConfig) - if err != nil { - log.Fatal(4, "Init cache system failed, adapter: %s, config: %s, %v\n", - CacheAdapter, CacheConfig, err) - } - log.Info("Cache Service Enabled") } diff --git a/routers/admin/admin.go b/routers/admin/admin.go index efdc803b95..4091cb8999 100644 --- a/routers/admin/admin.go +++ b/routers/admin/admin.go @@ -263,7 +263,8 @@ func Config(ctx *middleware.Context) { } ctx.Data["CacheAdapter"] = setting.CacheAdapter - ctx.Data["CacheConfig"] = setting.CacheConfig + ctx.Data["CacheInternal"] = setting.CacheInternal + ctx.Data["CacheConn"] = setting.CacheConn ctx.Data["SessionProvider"] = setting.SessionProvider ctx.Data["SessionConfig"] = setting.SessionConfig diff --git a/routers/user/auth.go b/routers/user/auth.go index 163df34a4a..90194e0c46 100644 --- a/routers/user/auth.go +++ b/routers/user/auth.go @@ -8,10 +8,11 @@ import ( "net/url" "strings" + "github.com/macaron-contrib/captcha" + "github.com/gogits/gogs/models" "github.com/gogits/gogs/modules/auth" "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/captcha" "github.com/gogits/gogs/modules/log" // "github.com/gogits/gogs/modules/mailer" "github.com/gogits/gogs/modules/middleware" diff --git a/templates/.VERSION b/templates/.VERSION index df75938808..82b0c22eb5 100644 --- a/templates/.VERSION +++ b/templates/.VERSION @@ -1 +1 @@ -0.4.7.0730 Alpha \ No newline at end of file +0.4.7.0731 Alpha \ No newline at end of file diff --git a/templates/user/signin.tmpl b/templates/user/signin.tmpl index a66dd285b2..8b67dbd86e 100644 --- a/templates/user/signin.tmpl +++ b/templates/user/signin.tmpl @@ -2,7 +2,6 @@ {{template "ng/base/header" .}}
- {{.CsrfTokenHtml}}

{{.i18n.Tr "sign_in"}}

diff --git a/templates/user/signup.tmpl b/templates/user/signup.tmpl index 5b52850c0f..723314956c 100644 --- a/templates/user/signup.tmpl +++ b/templates/user/signup.tmpl @@ -2,7 +2,6 @@ {{template "ng/base/header" .}}
- {{.CsrfTokenHtml}}

{{.i18n.Tr "sign_up"}}

@@ -29,7 +28,7 @@

- {{CreateCaptcha}} + {{.Captcha.CreateHtml}}