inital code for rotate
This commit is contained in:
@@ -3,7 +3,6 @@ package auth
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
@@ -45,10 +44,11 @@ func (s *UserAuthTokenService) UserAuthenticatedHook(user *models.User, c *model
|
||||
c.Resp.Header().Del("Set-Cookie")
|
||||
cookie := http.Cookie{
|
||||
Name: sessionCookieKey,
|
||||
Value: url.QueryEscape(userToken.unhashedToken),
|
||||
Value: url.QueryEscape(userToken.UnhashedToken),
|
||||
HttpOnly: true,
|
||||
Expires: time.Now().Add(time.Minute * 10),
|
||||
MaxAge: int(time.Minute * 10),
|
||||
Domain: setting.Domain,
|
||||
Path: setting.AppSubUrl + "/",
|
||||
}
|
||||
|
||||
c.Resp.Header().Add("Set-Cookie", cookie.String())
|
||||
@@ -57,7 +57,18 @@ func (s *UserAuthTokenService) UserAuthenticatedHook(user *models.User, c *model
|
||||
}
|
||||
|
||||
func (s *UserAuthTokenService) UserSignedOutHook(c *models.ReqContext) {
|
||||
c.SetCookie(sessionCookieKey, "", -1, setting.AppSubUrl+"/", setting.Domain, false, true)
|
||||
//c.SetCookie(sessionCookieKey, "", -1, setting.AppSubUrl+"/", setting.Domain, false, true)
|
||||
c.Resp.Header().Del("Set-Cookie")
|
||||
cookie := http.Cookie{
|
||||
Name: sessionCookieKey,
|
||||
Value: "",
|
||||
HttpOnly: true,
|
||||
MaxAge: -1,
|
||||
Domain: setting.Domain,
|
||||
Path: setting.AppSubUrl + "/",
|
||||
}
|
||||
|
||||
c.Resp.Header().Add("Set-Cookie", cookie.String())
|
||||
}
|
||||
|
||||
// func (s *UserAuthTokenService) RequestMiddleware() macaron.Handler {
|
||||
@@ -82,7 +93,7 @@ func (s *UserAuthTokenService) UserSignedOutHook(c *models.ReqContext) {
|
||||
// }
|
||||
// }
|
||||
|
||||
func (s *UserAuthTokenService) CreateToken(userId int64, clientIP, userAgent string) (*userAuthToken, error) {
|
||||
func (s *UserAuthTokenService) CreateToken(userId int64, clientIP, userAgent string) (*models.UserAuthToken, error) {
|
||||
clientIP = util.ParseIPAddress(clientIP)
|
||||
token, err := util.RandomHex(16)
|
||||
if err != nil {
|
||||
@@ -91,7 +102,7 @@ func (s *UserAuthTokenService) CreateToken(userId int64, clientIP, userAgent str
|
||||
|
||||
hashedToken := hashToken(token)
|
||||
|
||||
userToken := userAuthToken{
|
||||
userToken := models.UserAuthToken{
|
||||
UserId: userId,
|
||||
AuthToken: hashedToken,
|
||||
PrevAuthToken: hashedToken,
|
||||
@@ -108,20 +119,15 @@ func (s *UserAuthTokenService) CreateToken(userId int64, clientIP, userAgent str
|
||||
return nil, err
|
||||
}
|
||||
|
||||
userToken.unhashedToken = token
|
||||
userToken.UnhashedToken = token
|
||||
|
||||
return &userToken, nil
|
||||
}
|
||||
|
||||
func (s *UserAuthTokenService) LookupToken(ctx *models.ReqContext) (*userAuthToken, error) {
|
||||
unhashedToken := ctx.GetCookie(sessionCookieKey)
|
||||
if unhashedToken == "" {
|
||||
return nil, fmt.Errorf("session token cookie is empty")
|
||||
}
|
||||
|
||||
func (s *UserAuthTokenService) LookupToken(unhashedToken string) (*models.UserAuthToken, error) {
|
||||
hashedToken := hashToken(unhashedToken)
|
||||
|
||||
var userToken userAuthToken
|
||||
var userToken models.UserAuthToken
|
||||
exists, err := s.SQLStore.NewSession().Where("auth_token = ? OR prev_auth_token = ?", hashedToken, hashedToken).Get(&userToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -166,14 +172,55 @@ func (s *UserAuthTokenService) LookupToken(ctx *models.ReqContext) (*userAuthTok
|
||||
}
|
||||
}
|
||||
|
||||
userToken.unhashedToken = unhashedToken
|
||||
userToken.UnhashedToken = unhashedToken
|
||||
|
||||
return &userToken, nil
|
||||
}
|
||||
|
||||
func (s *UserAuthTokenService) RefreshToken(token *userAuthToken, clientIP, userAgent string) (bool, error) {
|
||||
// lookup token in db
|
||||
// refresh token if needed
|
||||
func (s *UserAuthTokenService) RefreshToken(token *models.UserAuthToken, clientIP, userAgent string) (bool, error) {
|
||||
if token == nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
var needsRotation = false
|
||||
rotatedAt := time.Unix(token.RotatedAt, 0)
|
||||
if token.AuthTokenSeen {
|
||||
needsRotation = rotatedAt.Before(now().Add(time.Duration(-1) * time.Minute))
|
||||
} else {
|
||||
needsRotation = rotatedAt.Before(now().Add(time.Duration(-30) * time.Second))
|
||||
}
|
||||
|
||||
s.log.Info("refresh token", "needs rotation?", needsRotation, "auth_token_seen", token.AuthTokenSeen, "rotated_at", rotatedAt, "token.Id", token.Id)
|
||||
if !needsRotation {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
newToken, _ := util.RandomHex(16)
|
||||
hashedToken := hashToken(newToken)
|
||||
|
||||
sql := `
|
||||
UPDATE user_auth_token
|
||||
SET
|
||||
auth_token_seen = false,
|
||||
seen_at = null,
|
||||
user_agent = ?,
|
||||
client_ip = ?,
|
||||
prev_auth_token = case when auth_token_seen then auth_token else prev_auth_token end,
|
||||
auth_token = ?,
|
||||
rotated_at = ?
|
||||
WHERE id = ? AND (auth_token_seen or rotated_at < ?)`
|
||||
|
||||
res, err := s.SQLStore.NewSession().Exec(sql, userAgent, clientIP, hashedToken, now().Unix(), token.Id, now().Add(time.Duration(-30)*time.Second))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
affected, _ := res.RowsAffected()
|
||||
s.log.Info("rotated", "affected", affected, "auth_token_id", token.Id, "userId", token.UserId, "user_agent", userAgent, "client_ip", clientIP)
|
||||
if affected > 0 {
|
||||
token.UnhashedToken = newToken
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user