forked from gitea/gitea
		
	Add auto-login
This commit is contained in:
		
							parent
							
								
									59ffdbf6f8
								
							
						
					
					
						commit
						cb52f6d07d
					
				| @ -34,6 +34,10 @@ PATH = data/gogs.db | ||||
| [security] | ||||
| ; !!CHANGE THIS TO KEEP YOUR USER DATA SAFE!! | ||||
| SECRET_KEY = !#@FDEWREWR&*( | ||||
| ; Auto-login remember days | ||||
| LOGIN_REMEMBER_DAYS = 7 | ||||
| COOKIE_USERNAME = gogs_awesome | ||||
| COOKIE_REMEMBER_NAME = gogs_incredible | ||||
| 
 | ||||
| [service] | ||||
| ACTIVE_CODE_LIVE_MINUTES = 180 | ||||
|  | ||||
| @ -61,6 +61,7 @@ func (f *RegisterForm) Validate(errors *binding.Errors, req *http.Request, conte | ||||
| type LogInForm struct { | ||||
| 	UserName string `form:"username" binding:"Required;AlphaDash;MaxSize(30)"` | ||||
| 	Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"` | ||||
| 	Remember string `form:"remember"` | ||||
| } | ||||
| 
 | ||||
| func (f *LogInForm) Name(field string) string { | ||||
|  | ||||
| @ -38,6 +38,10 @@ var ( | ||||
| 	RunUser      string | ||||
| 	RepoRootPath string | ||||
| 
 | ||||
| 	LogInRememberDays  int | ||||
| 	CookieUserName     string | ||||
| 	CookieRememberName string | ||||
| 
 | ||||
| 	Cfg         *goconfig.ConfigFile | ||||
| 	MailService *Mailer | ||||
| 
 | ||||
| @ -252,6 +256,10 @@ func NewConfigContext() { | ||||
| 	SecretKey = Cfg.MustValue("security", "SECRET_KEY") | ||||
| 	RunUser = Cfg.MustValue("", "RUN_USER") | ||||
| 
 | ||||
| 	LogInRememberDays = Cfg.MustInt("security", "LOGIN_REMEMBER_DAYS") | ||||
| 	CookieUserName = Cfg.MustValue("security", "COOKIE_USERNAME") | ||||
| 	CookieRememberName = Cfg.MustValue("security", "COOKIE_REMEMBER_NAME") | ||||
| 
 | ||||
| 	PictureService = Cfg.MustValue("picture", "SERVICE") | ||||
| 	PictureRootPath = Cfg.MustValue("picture", "PATH") | ||||
| 
 | ||||
|  | ||||
| @ -5,9 +5,14 @@ | ||||
| package middleware | ||||
| 
 | ||||
| import ( | ||||
| 	"crypto/hmac" | ||||
| 	"crypto/sha1" | ||||
| 	"encoding/base64" | ||||
| 	"fmt" | ||||
| 	"html/template" | ||||
| 	"net/http" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/codegangsta/martini" | ||||
| @ -155,6 +160,44 @@ func (ctx *Context) SetCookie(name string, value string, others ...interface{}) | ||||
| 	ctx.Res.Header().Add("Set-Cookie", cookie.String()) | ||||
| } | ||||
| 
 | ||||
| // Get secure cookie from request by a given key. | ||||
| func (ctx *Context) GetSecureCookie(Secret, key string) (string, bool) { | ||||
| 	val := ctx.GetCookie(key) | ||||
| 	if val == "" { | ||||
| 		return "", false | ||||
| 	} | ||||
| 
 | ||||
| 	parts := strings.SplitN(val, "|", 3) | ||||
| 
 | ||||
| 	if len(parts) != 3 { | ||||
| 		return "", false | ||||
| 	} | ||||
| 
 | ||||
| 	vs := parts[0] | ||||
| 	timestamp := parts[1] | ||||
| 	sig := parts[2] | ||||
| 
 | ||||
| 	h := hmac.New(sha1.New, []byte(Secret)) | ||||
| 	fmt.Fprintf(h, "%s%s", vs, timestamp) | ||||
| 
 | ||||
| 	if fmt.Sprintf("%02x", h.Sum(nil)) != sig { | ||||
| 		return "", false | ||||
| 	} | ||||
| 	res, _ := base64.URLEncoding.DecodeString(vs) | ||||
| 	return string(res), true | ||||
| } | ||||
| 
 | ||||
| // Set Secure cookie for response. | ||||
| func (ctx *Context) SetSecureCookie(Secret, name, value string, others ...interface{}) { | ||||
| 	vs := base64.URLEncoding.EncodeToString([]byte(value)) | ||||
| 	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10) | ||||
| 	h := hmac.New(sha1.New, []byte(Secret)) | ||||
| 	fmt.Fprintf(h, "%s%s", vs, timestamp) | ||||
| 	sig := fmt.Sprintf("%02x", h.Sum(nil)) | ||||
| 	cookie := strings.Join([]string{vs, timestamp, sig}, "|") | ||||
| 	ctx.SetCookie(name, cookie, others...) | ||||
| } | ||||
| 
 | ||||
| func (ctx *Context) CsrfToken() string { | ||||
| 	if len(ctx.csrfToken) > 0 { | ||||
| 		return ctx.csrfToken | ||||
|  | ||||
| @ -77,7 +77,39 @@ func SignIn(ctx *middleware.Context, form auth.LogInForm) { | ||||
| 	ctx.Data["Title"] = "Log In" | ||||
| 
 | ||||
| 	if ctx.Req.Method == "GET" { | ||||
| 		ctx.HTML(200, "user/signin") | ||||
| 		// Check auto-login. | ||||
| 		userName := ctx.GetCookie(base.CookieUserName) | ||||
| 		if len(userName) == 0 { | ||||
| 			ctx.HTML(200, "user/signin") | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		isSucceed := false | ||||
| 		defer func() { | ||||
| 			if !isSucceed { | ||||
| 				log.Trace("%s auto-login cookie cleared: %s", ctx.Req.RequestURI, userName) | ||||
| 				ctx.SetCookie(base.CookieUserName, "", -1) | ||||
| 				ctx.SetCookie(base.CookieRememberName, "", -1) | ||||
| 			} | ||||
| 		}() | ||||
| 
 | ||||
| 		user, err := models.GetUserByName(userName) | ||||
| 		if err != nil { | ||||
| 			ctx.HTML(200, "user/signin") | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		secret := base.EncodeMd5(user.Rands + user.Passwd) | ||||
| 		value, _ := ctx.GetSecureCookie(secret, base.CookieRememberName) | ||||
| 		if value != user.Name { | ||||
| 			ctx.HTML(200, "user/signin") | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		isSucceed = true | ||||
| 		ctx.Session.Set("userId", user.Id) | ||||
| 		ctx.Session.Set("userName", user.Name) | ||||
| 		ctx.Redirect("/") | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -89,6 +121,7 @@ func SignIn(ctx *middleware.Context, form auth.LogInForm) { | ||||
| 	user, err := models.LoginUserPlain(form.UserName, form.Password) | ||||
| 	if err != nil { | ||||
| 		if err == models.ErrUserNotExist { | ||||
| 			log.Trace("%s Log in failed: %s/%s", ctx.Req.RequestURI, form.UserName, form.Password) | ||||
| 			ctx.RenderWithErr("Username or password is not correct", "user/signin", &form) | ||||
| 			return | ||||
| 		} | ||||
| @ -97,6 +130,13 @@ func SignIn(ctx *middleware.Context, form auth.LogInForm) { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if form.Remember == "on" { | ||||
| 		secret := base.EncodeMd5(user.Rands + user.Passwd) | ||||
| 		days := 86400 * base.LogInRememberDays | ||||
| 		ctx.SetCookie(base.CookieUserName, user.Name, days) | ||||
| 		ctx.SetSecureCookie(secret, base.CookieRememberName, user.Name, days) | ||||
| 	} | ||||
| 
 | ||||
| 	ctx.Session.Set("userId", user.Id) | ||||
| 	ctx.Session.Set("userName", user.Name) | ||||
| 	ctx.Redirect("/") | ||||
|  | ||||
| @ -19,6 +19,17 @@ | ||||
|             </div> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="form-group"> | ||||
|             <div class="col-md-6 col-md-offset-4"> | ||||
|                 <div class="checkbox"> | ||||
|                     <label> | ||||
|                         <input type="checkbox" name="remember" {{if .remember}}checked{{end}}> | ||||
|                         <strong>Remember me</strong> | ||||
|                     </label> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="form-group"> | ||||
|             <div class="col-md-offset-4 col-md-6"> | ||||
|                 <button type="submit" class="btn btn-lg btn-primary">Log In</button> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Unknown
						Unknown