Browse Source

login users based on token cookie

bergquist 7 years ago
parent
commit
aba6148c43

+ 6 - 10
pkg/api/http_server.go

@@ -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())
 

+ 4 - 4
pkg/api/login.go

@@ -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+"/")

+ 29 - 4
pkg/middleware/middleware.go

@@ -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 {

+ 0 - 1
pkg/middleware/org_redirect.go

@@ -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"
 )
 

+ 38 - 24
pkg/services/auth/auth_token.go

@@ -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
 

+ 18 - 18
pkg/services/auth/auth_token_test.go

@@ -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)