mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
login users based on token cookie
This commit is contained in:
parent
8764fb5aa6
commit
aba6148c43
@ -11,16 +11,8 @@ import (
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/auth"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
|
||||
macaron "gopkg.in/macaron.v1"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/live"
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
httpstatic "github.com/grafana/grafana/pkg/api/static"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
@ -29,11 +21,15 @@ import (
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/registry"
|
||||
"github.com/grafana/grafana/pkg/services/auth"
|
||||
"github.com/grafana/grafana/pkg/services/cache"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/hooks"
|
||||
"github.com/grafana/grafana/pkg/services/rendering"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
macaron "gopkg.in/macaron.v1"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -226,7 +222,7 @@ func (hs *HTTPServer) addMiddlewaresAndStaticRoutes() {
|
||||
|
||||
m.Use(hs.healthHandler)
|
||||
m.Use(hs.metricsEndpoint)
|
||||
m.Use(middleware.GetContextHandler())
|
||||
m.Use(middleware.GetContextHandler(hs.AuthTokenService))
|
||||
m.Use(middleware.Sessioner(&setting.SessionOptions, setting.SessionConnMaxLifetime))
|
||||
m.Use(middleware.OrgRedirect())
|
||||
|
||||
|
@ -42,10 +42,10 @@ func (hs *HTTPServer) LoginView(c *m.ReqContext) {
|
||||
return
|
||||
}
|
||||
|
||||
if !hs.tryLoginUsingRememberCookie(c) {
|
||||
c.HTML(200, ViewIndex, viewData)
|
||||
return
|
||||
}
|
||||
//if !hs.tryLoginUsingRememberCookie(c) {
|
||||
c.HTML(200, ViewIndex, viewData)
|
||||
return
|
||||
//}
|
||||
|
||||
if redirectTo, _ := url.QueryUnescape(c.GetCookie("redirect_to")); len(redirectTo) > 0 {
|
||||
c.SetCookie("redirect_to", "", -1, setting.AppSubUrl+"/")
|
||||
|
@ -3,15 +3,15 @@ package middleware
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"gopkg.in/macaron.v1"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/components/apikeygen"
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/auth"
|
||||
"github.com/grafana/grafana/pkg/services/session"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"gopkg.in/macaron.v1"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -21,7 +21,7 @@ var (
|
||||
ReqOrgAdmin = RoleAuth(m.ROLE_ADMIN)
|
||||
)
|
||||
|
||||
func GetContextHandler() macaron.Handler {
|
||||
func GetContextHandler(ats *auth.UserAuthTokenService) macaron.Handler {
|
||||
return func(c *macaron.Context) {
|
||||
ctx := &m.ReqContext{
|
||||
Context: c,
|
||||
@ -49,7 +49,8 @@ func GetContextHandler() macaron.Handler {
|
||||
case initContextWithApiKey(ctx):
|
||||
case initContextWithBasicAuth(ctx, orgId):
|
||||
case initContextWithAuthProxy(ctx, orgId):
|
||||
case initContextWithUserSessionCookie(ctx, orgId):
|
||||
//case initContextWithUserSessionCookie(ctx, orgId):
|
||||
case initContextWithToken(ctx, orgId, ats):
|
||||
case initContextWithAnonymousUser(ctx):
|
||||
}
|
||||
|
||||
@ -58,6 +59,11 @@ func GetContextHandler() macaron.Handler {
|
||||
|
||||
c.Map(ctx)
|
||||
|
||||
c.Next()
|
||||
|
||||
//if signed in with token
|
||||
//ats.RefreshToken()
|
||||
|
||||
// update last seen every 5min
|
||||
if ctx.ShouldUpdateLastSeenAt() {
|
||||
ctx.Logger.Debug("Updating last user_seen_at", "user_id", ctx.UserId)
|
||||
@ -88,6 +94,25 @@ func initContextWithAnonymousUser(ctx *m.ReqContext) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func initContextWithToken(ctx *m.ReqContext, orgID int64, ts *auth.UserAuthTokenService) bool {
|
||||
user, err := ts.LookupToken(ctx)
|
||||
if err != nil {
|
||||
ctx.Logger.Info("failed to look up user based on cookie")
|
||||
return false
|
||||
}
|
||||
|
||||
query := m.GetSignedInUserQuery{UserId: user.UserId, OrgId: orgID}
|
||||
if err := bus.Dispatch(&query); err != nil {
|
||||
ctx.Logger.Error("Failed to get user with id", "userId", user.UserId, "error", err)
|
||||
return false
|
||||
}
|
||||
|
||||
ctx.SignedInUser = query.Result
|
||||
ctx.IsSignedIn = true
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func initContextWithUserSessionCookie(ctx *m.ReqContext, orgId int64) bool {
|
||||
// initialize session
|
||||
if err := ctx.Session.Start(ctx.Context); err != nil {
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
|
||||
"gopkg.in/macaron.v1"
|
||||
)
|
||||
|
||||
|
@ -3,16 +3,17 @@ package auth
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
macaron "gopkg.in/macaron.v1"
|
||||
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/registry"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -42,7 +43,15 @@ func (s *UserAuthTokenService) UserAuthenticatedHook(user *models.User, c *model
|
||||
}
|
||||
|
||||
c.Resp.Header().Del("Set-Cookie")
|
||||
c.SetCookie(sessionCookieKey, userToken.unhashedToken, setting.AppSubUrl+"/", setting.Domain, false, true)
|
||||
cookie := http.Cookie{
|
||||
Name: sessionCookieKey,
|
||||
Value: url.QueryEscape(userToken.unhashedToken),
|
||||
HttpOnly: true,
|
||||
Expires: time.Now().Add(time.Minute * 10),
|
||||
Domain: setting.Domain,
|
||||
}
|
||||
|
||||
c.Resp.Header().Add("Set-Cookie", cookie.String())
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -51,27 +60,27 @@ func (s *UserAuthTokenService) UserSignedOutHook(c *models.ReqContext) {
|
||||
c.SetCookie(sessionCookieKey, "", -1, setting.AppSubUrl+"/", setting.Domain, false, true)
|
||||
}
|
||||
|
||||
func (s *UserAuthTokenService) RequestMiddleware() macaron.Handler {
|
||||
return func(ctx *models.ReqContext) {
|
||||
authToken := ctx.GetCookie(sessionCookieKey)
|
||||
userToken, err := s.lookupToken(authToken)
|
||||
if err != nil {
|
||||
// func (s *UserAuthTokenService) RequestMiddleware() macaron.Handler {
|
||||
// return func(ctx *models.ReqContext) {
|
||||
// authToken := ctx.GetCookie(sessionCookieKey)
|
||||
// userToken, err := s.LookupToken(authToken)
|
||||
// if err != nil {
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
ctx.Next()
|
||||
// ctx.Next()
|
||||
|
||||
refreshed, err := s.refreshToken(userToken, ctx.RemoteAddr(), ctx.Req.UserAgent())
|
||||
if err != nil {
|
||||
// refreshed, err := s.RefreshToken(userToken, ctx.RemoteAddr(), ctx.Req.UserAgent())
|
||||
// if err != nil {
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
if refreshed {
|
||||
ctx.Resp.Header().Del("Set-Cookie")
|
||||
ctx.SetCookie(sessionCookieKey, userToken.unhashedToken, setting.AppSubUrl+"/", setting.Domain, false, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
// if refreshed {
|
||||
// ctx.Resp.Header().Del("Set-Cookie")
|
||||
// ctx.SetCookie(sessionCookieKey, userToken.unhashedToken, setting.AppSubUrl+"/", setting.Domain, false, true)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
func (s *UserAuthTokenService) CreateToken(userId int64, clientIP, userAgent string) (*userAuthToken, error) {
|
||||
clientIP = util.ParseIPAddress(clientIP)
|
||||
@ -104,7 +113,12 @@ func (s *UserAuthTokenService) CreateToken(userId int64, clientIP, userAgent str
|
||||
return &userToken, nil
|
||||
}
|
||||
|
||||
func (s *UserAuthTokenService) lookupToken(unhashedToken string) (*userAuthToken, error) {
|
||||
func (s *UserAuthTokenService) LookupToken(ctx *models.ReqContext) (*userAuthToken, error) {
|
||||
unhashedToken := ctx.GetCookie(sessionCookieKey)
|
||||
if unhashedToken == "" {
|
||||
return nil, fmt.Errorf("session token cookie is empty")
|
||||
}
|
||||
|
||||
hashedToken := hashToken(unhashedToken)
|
||||
|
||||
var userToken userAuthToken
|
||||
@ -157,7 +171,7 @@ func (s *UserAuthTokenService) lookupToken(unhashedToken string) (*userAuthToken
|
||||
return &userToken, nil
|
||||
}
|
||||
|
||||
func (s *UserAuthTokenService) refreshToken(token *userAuthToken, clientIP, userAgent string) (bool, error) {
|
||||
func (s *UserAuthTokenService) RefreshToken(token *userAuthToken, clientIP, userAgent string) (bool, error) {
|
||||
// lookup token in db
|
||||
// refresh token if needed
|
||||
|
||||
|
@ -27,22 +27,22 @@ func TestUserAuthToken(t *testing.T) {
|
||||
So(token.AuthTokenSeen, ShouldBeFalse)
|
||||
|
||||
Convey("When lookup unhashed token should return user auth token", func() {
|
||||
lookupToken, err := userAuthTokenService.lookupToken(token.unhashedToken)
|
||||
LookupToken, err := userAuthTokenService.LookupToken(token.unhashedToken)
|
||||
So(err, ShouldBeNil)
|
||||
So(lookupToken, ShouldNotBeNil)
|
||||
So(lookupToken.UserId, ShouldEqual, userID)
|
||||
So(lookupToken.AuthTokenSeen, ShouldBeTrue)
|
||||
So(LookupToken, ShouldNotBeNil)
|
||||
So(LookupToken.UserId, ShouldEqual, userID)
|
||||
So(LookupToken.AuthTokenSeen, ShouldBeTrue)
|
||||
|
||||
storedAuthToken, err := ctx.getAuthTokenByID(lookupToken.Id)
|
||||
storedAuthToken, err := ctx.getAuthTokenByID(LookupToken.Id)
|
||||
So(err, ShouldBeNil)
|
||||
So(storedAuthToken, ShouldNotBeNil)
|
||||
So(storedAuthToken.AuthTokenSeen, ShouldBeTrue)
|
||||
})
|
||||
|
||||
Convey("When lookup hashed token should return user auth token not found error", func() {
|
||||
lookupToken, err := userAuthTokenService.lookupToken(token.AuthToken)
|
||||
LookupToken, err := userAuthTokenService.LookupToken(token.AuthToken)
|
||||
So(err, ShouldEqual, ErrAuthTokenNotFound)
|
||||
So(lookupToken, ShouldBeNil)
|
||||
So(LookupToken, ShouldBeNil)
|
||||
})
|
||||
})
|
||||
|
||||
@ -51,25 +51,25 @@ func TestUserAuthToken(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
So(token, ShouldNotBeNil)
|
||||
|
||||
_, err = userAuthTokenService.lookupToken(token.unhashedToken)
|
||||
_, err = userAuthTokenService.LookupToken(token.unhashedToken)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
token, err = ctx.getAuthTokenByID(token.Id)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// set now (now - 23 hours)
|
||||
_, err = userAuthTokenService.refreshToken(token, "192.168.10.11:1234", "some user agent")
|
||||
_, err = userAuthTokenService.RefreshToken(token, "192.168.10.11:1234", "some user agent")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
_, err = userAuthTokenService.lookupToken(token.unhashedToken)
|
||||
_, err = userAuthTokenService.LookupToken(token.unhashedToken)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
stillGood, err := userAuthTokenService.lookupToken(token.unhashedToken)
|
||||
stillGood, err := userAuthTokenService.LookupToken(token.unhashedToken)
|
||||
So(err, ShouldBeNil)
|
||||
So(stillGood, ShouldNotBeNil)
|
||||
|
||||
// set now (new - 2 hours)
|
||||
notGood, err := userAuthTokenService.lookupToken(token.unhashedToken)
|
||||
notGood, err := userAuthTokenService.LookupToken(token.unhashedToken)
|
||||
So(err, ShouldEqual, ErrAuthTokenNotFound)
|
||||
So(notGood, ShouldBeNil)
|
||||
})
|
||||
@ -82,7 +82,7 @@ func TestUserAuthToken(t *testing.T) {
|
||||
prevToken := token.AuthToken
|
||||
unhashedPrev := token.unhashedToken
|
||||
|
||||
refreshed, err := userAuthTokenService.refreshToken(token, "192.168.10.12:1234", "a new user agent")
|
||||
refreshed, err := userAuthTokenService.RefreshToken(token, "192.168.10.12:1234", "a new user agent")
|
||||
So(err, ShouldBeNil)
|
||||
So(refreshed, ShouldBeFalse)
|
||||
|
||||
@ -95,7 +95,7 @@ func TestUserAuthToken(t *testing.T) {
|
||||
return t
|
||||
}
|
||||
|
||||
refreshed, err = userAuthTokenService.refreshToken(token, "192.168.10.12:1234", "a new user agent")
|
||||
refreshed, err = userAuthTokenService.RefreshToken(token, "192.168.10.12:1234", "a new user agent")
|
||||
So(err, ShouldBeNil)
|
||||
So(refreshed, ShouldBeTrue)
|
||||
|
||||
@ -112,13 +112,13 @@ func TestUserAuthToken(t *testing.T) {
|
||||
So(token.SeenAt, ShouldEqual, 0)
|
||||
So(token.PrevAuthToken, ShouldEqual, prevToken)
|
||||
|
||||
lookedUp, err := userAuthTokenService.lookupToken(token.unhashedToken)
|
||||
lookedUp, err := userAuthTokenService.LookupToken(token.unhashedToken)
|
||||
So(err, ShouldBeNil)
|
||||
So(lookedUp, ShouldNotBeNil)
|
||||
So(lookedUp.AuthTokenSeen, ShouldBeTrue)
|
||||
So(lookedUp.SeenAt, ShouldEqual, t.Unix())
|
||||
|
||||
lookedUp, err = userAuthTokenService.lookupToken(unhashedPrev)
|
||||
lookedUp, err = userAuthTokenService.LookupToken(unhashedPrev)
|
||||
So(err, ShouldBeNil)
|
||||
So(lookedUp, ShouldNotBeNil)
|
||||
So(lookedUp.Id, ShouldEqual, token.Id)
|
||||
@ -127,7 +127,7 @@ func TestUserAuthToken(t *testing.T) {
|
||||
return t.Add(2 * time.Minute)
|
||||
}
|
||||
|
||||
lookedUp, err = userAuthTokenService.lookupToken(unhashedPrev)
|
||||
lookedUp, err = userAuthTokenService.LookupToken(unhashedPrev)
|
||||
So(err, ShouldBeNil)
|
||||
So(lookedUp, ShouldNotBeNil)
|
||||
|
||||
@ -136,7 +136,7 @@ func TestUserAuthToken(t *testing.T) {
|
||||
So(lookedUp, ShouldNotBeNil)
|
||||
So(lookedUp.AuthTokenSeen, ShouldBeFalse)
|
||||
|
||||
refreshed, err = userAuthTokenService.refreshToken(token, "192.168.10.12:1234", "a new user agent")
|
||||
refreshed, err = userAuthTokenService.RefreshToken(token, "192.168.10.12:1234", "a new user agent")
|
||||
So(err, ShouldBeNil)
|
||||
So(refreshed, ShouldBeTrue)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user