inital code for rotate

This commit is contained in:
bergquist
2019-01-17 17:11:52 +01:00
parent aba6148c43
commit c2accfa4c0
5 changed files with 141 additions and 49 deletions
+65 -18
View File
@@ -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
}