From 0f60073adcb83bd3c8a7face718ab075816da48a Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Sun, 12 Apr 2015 21:35:16 -0700 Subject: [PATCH] session tokens converging with user tokens --- server/login.go | 8 ++++-- server/server.go | 6 ++--- server/session/session.go | 54 ++++++++++++++++++++++----------------- 3 files changed, 39 insertions(+), 29 deletions(-) diff --git a/server/login.go b/server/login.go index ce08d861c..3d83c7e43 100644 --- a/server/login.go +++ b/server/login.go @@ -105,13 +105,17 @@ func GetLogin(c *gin.Context) { return } - token, err := session.GenerateToken(c.Request, u) + token := &common.Token{ + // Expiry: settings.Session.Expires, // TODO add this + Login: u.Login, + } + tokenstr, err := session.GenerateToken(c.Request, token) if err != nil { log.Errorf("cannot create token for %s. %s", u.Login, err) c.Redirect(303, "/login#error=internal_error") return } - c.Redirect(303, "/#access_token="+token) + c.Redirect(303, "/#access_token="+tokenstr) } // getLoginOauth2 is the default authorization implementation diff --git a/server/server.go b/server/server.go index a16767b6a..897e7eb72 100644 --- a/server/server.go +++ b/server/server.go @@ -108,13 +108,13 @@ func SetSession(s session.Session) gin.HandlerFunc { func SetUser(s session.Session) gin.HandlerFunc { return func(c *gin.Context) { ds := ToDatastore(c) - login := s.GetLogin(c.Request) - if len(login) == 0 { + token := s.GetLogin(c.Request) + if token == nil { c.Next() return } - u, err := ds.GetUser(login) + u, err := ds.GetUser(token.Login) if err == nil { c.Set("user", u) } diff --git a/server/session/session.go b/server/session/session.go index c4e61ca32..1542c5d62 100644 --- a/server/session/session.go +++ b/server/session/session.go @@ -7,14 +7,13 @@ import ( "github.com/dgrijalva/jwt-go" "github.com/drone/drone/common" - "github.com/drone/drone/common/httputil" "github.com/drone/drone/settings" "github.com/gorilla/securecookie" ) type Session interface { - GenerateToken(*http.Request, *common.User) (string, error) - GetLogin(*http.Request) string + GenerateToken(*http.Request, *common.Token) (string, error) + GetLogin(*http.Request) *common.Token } type session struct { @@ -38,42 +37,49 @@ func New(s *settings.Session) Session { // GenerateToken generates a JWT token for the user session // that can be appended to the #access_token segment to // facilitate client-based OAuth2. -func (s *session) GenerateToken(r *http.Request, user *common.User) (string, error) { +func (s *session) GenerateToken(r *http.Request, t *common.Token) (string, error) { token := jwt.New(jwt.GetSigningMethod("HS256")) - token.Claims["user_id"] = user.Login - token.Claims["audience"] = httputil.GetURL(r) - token.Claims["expires"] = time.Now().UTC().Add(s.expire).Unix() + token.Claims["login"] = t.Login + token.Claims["expiry"] = t.Expiry + + // add optional repos that can be + // access from this session. + if len(t.Repos) != 0 { + token.Claims["repos"] = t.Repos + } + // add optional scopes that can be + // applied to this session. + if len(t.Scopes) != 0 { + token.Claims["scope"] = t.Scopes + } return token.SignedString(s.secret) } // GetLogin gets the currently authenticated user for the // http.Request. The user details will be stored as either // a simple API token or JWT bearer token. -func (s *session) GetLogin(r *http.Request) (_ string) { - token := getToken(r) - if len(token) == 0 { - return +func (s *session) GetLogin(r *http.Request) *common.Token { + t := getToken(r) + if len(t) == 0 { + return nil } - claims := getClaims(token, s.secret) - if claims == nil || claims["user_id"] == nil { - return + claims := getClaims(t, s.secret) + if claims == nil || claims["login"] == nil { + return nil } - userid, ok := claims["user_id"].(string) + loginv, ok := claims["login"] if !ok { - return + return nil } - // tokenid, ok := claims["token_id"].(string) - // if ok { - // _, err := datastore.GetToken(c, int64(tokenid)) - // if err != nil { - // return nil - // } - // } + loginstr, ok := loginv.(string) + if !ok { + return nil + } - return userid + return &common.Token{Login: loginstr} } // getToken is a helper function that extracts the token