Browse Source

session: add 'scope' field in session.

pull/103/head
Yifan Gu 11 years ago
parent
commit
066fd859ec
  1. 2
      db/migrations/0007_session_scope.sql
  2. 39
      db/migrations/assets.go
  3. 4
      db/session.go
  4. 2
      integration/oidc_test.go
  5. 2
      server/http.go
  6. 2
      server/password_test.go
  7. 2
      server/register_test.go
  8. 6
      server/server.go
  9. 10
      server/server_test.go
  10. 3
      session/manager.go
  11. 10
      session/manager_test.go
  12. 3
      session/session.go

2
db/migrations/0007_session_scope.sql

@ -0,0 +1,2 @@
-- +migrate Up
ALTER TABLE session ADD COLUMN "scope" text;

39
db/migrations/assets.go

File diff suppressed because one or more lines are too long

4
db/session.go

@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net/url"
"strings"
"time"
"github.com/go-gorp/gorp"
@ -42,6 +43,7 @@ type sessionModel struct {
UserID string `db:"user_id"`
Register bool `db:"register"`
Nonce string `db:"nonce"`
Scope string `db:"scope"`
}
func (s *sessionModel) session() (*session.Session, error) {
@ -71,6 +73,7 @@ func (s *sessionModel) session() (*session.Session, error) {
UserID: s.UserID,
Register: s.Register,
Nonce: s.Nonce,
Scope: strings.Fields(s.Scope),
}
if s.CreatedAt != 0 {
@ -101,6 +104,7 @@ func newSessionModel(s *session.Session) (*sessionModel, error) {
UserID: s.UserID,
Register: s.Register,
Nonce: s.Nonce,
Scope: strings.Join(s.Scope, " "),
}
if !s.CreatedAt.IsZero() {

2
integration/oidc_test.go

@ -196,7 +196,7 @@ func TestHTTPExchangeTokenRefreshToken(t *testing.T) {
// this will actually happen due to some interaction between the
// end-user and a remote identity provider
sessionID, err := sm.NewSession("bogus_idpc", ci.Credentials.ID, "bogus", url.URL{}, "", false)
sessionID, err := sm.NewSession("bogus_idpc", ci.Credentials.ID, "bogus", url.URL{}, "", false, nil)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}

2
server/http.go

@ -332,7 +332,7 @@ func handleAuthFunc(srv OIDCServer, idpcs []connector.Connector, tpl *template.T
nonce := q.Get("nonce")
key, err := srv.NewSession(connectorID, acr.ClientID, acr.State, redirectURL, nonce, register)
key, err := srv.NewSession(connectorID, acr.ClientID, acr.State, redirectURL, nonce, register, acr.Scope)
if err != nil {
log.Errorf("Error creating new session: %v: ", err)
redirectAuthError(w, err, acr.State, redirectURL)

2
server/password_test.go

@ -245,7 +245,7 @@ func TestSendResetPasswordEmailHandler(t *testing.T) {
t.Fatalf("case %d: could not make test fixtures: %v", i, err)
}
_, err = f.srv.NewSession("local", "XXX", "", f.redirectURL, "", true)
_, err = f.srv.NewSession("local", "XXX", "", f.redirectURL, "", true, nil)
if err != nil {
t.Fatalf("case %d: could not create new session: %v", i, err)
}

2
server/register_test.go

@ -197,7 +197,7 @@ func TestHandleRegister(t *testing.T) {
t.Fatalf("case %d: could not make test fixtures: %v", i, err)
}
key, err := f.srv.NewSession(tt.connID, "XXX", "", f.redirectURL, "", true)
key, err := f.srv.NewSession(tt.connID, "XXX", "", f.redirectURL, "", true, nil)
t.Logf("case %d: key for NewSession: %v", i, key)
if tt.attachRemote {

6
server/server.go

@ -39,7 +39,7 @@ const (
type OIDCServer interface {
ClientMetadata(string) (*oidc.ClientMetadata, error)
NewSession(connectorID, clientID, clientState string, redirectURL url.URL, nonce string, register bool) (string, error)
NewSession(connectorID, clientID, clientState string, redirectURL url.URL, nonce string, register bool, scope []string) (string, error)
Login(oidc.Identity, string) (string, error)
// CodeToken exchanges a code for an ID token and a refresh token string on success.
CodeToken(creds oidc.ClientCredentials, sessionKey string) (*jose.JWT, string, error)
@ -263,8 +263,8 @@ func (s *Server) ClientMetadata(clientID string) (*oidc.ClientMetadata, error) {
return s.ClientIdentityRepo.Metadata(clientID)
}
func (s *Server) NewSession(ipdcID, clientID, clientState string, redirectURL url.URL, nonce string, register bool) (string, error) {
sessionID, err := s.SessionManager.NewSession(ipdcID, clientID, clientState, redirectURL, nonce, register)
func (s *Server) NewSession(ipdcID, clientID, clientState string, redirectURL url.URL, nonce string, register bool, scope []string) (string, error) {
sessionID, err := s.SessionManager.NewSession(ipdcID, clientID, clientState, redirectURL, nonce, register, scope)
if err != nil {
return "", err
}

10
server/server_test.go

@ -139,7 +139,7 @@ func TestServerNewSession(t *testing.T) {
},
}
key, err := srv.NewSession("bogus_idpc", ci.Credentials.ID, state, ci.Metadata.RedirectURLs[0], nonce, false)
key, err := srv.NewSession("bogus_idpc", ci.Credentials.ID, state, ci.Metadata.RedirectURLs[0], nonce, false, nil)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -195,7 +195,7 @@ func TestServerLogin(t *testing.T) {
sm := session.NewSessionManager(session.NewSessionRepo(), session.NewSessionKeyRepo())
sm.GenerateCode = staticGenerateCodeFunc("fakecode")
sessionID, err := sm.NewSession("test_connector_id", ci.Credentials.ID, "bogus", ci.Metadata.RedirectURLs[0], "", false)
sessionID, err := sm.NewSession("test_connector_id", ci.Credentials.ID, "bogus", ci.Metadata.RedirectURLs[0], "", false, nil)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -292,7 +292,7 @@ func TestServerCodeToken(t *testing.T) {
RefreshTokenRepo: refreshTokenRepo,
}
sessionID, err := sm.NewSession("bogus_idpc", ci.Credentials.ID, "bogus", url.URL{}, "", false)
sessionID, err := sm.NewSession("bogus_idpc", ci.Credentials.ID, "bogus", url.URL{}, "", false, nil)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -343,7 +343,7 @@ func TestServerTokenUnrecognizedKey(t *testing.T) {
ClientIdentityRepo: ciRepo,
}
sessionID, err := sm.NewSession("connector_id", ci.Credentials.ID, "bogus", url.URL{}, "", false)
sessionID, err := sm.NewSession("connector_id", ci.Credentials.ID, "bogus", url.URL{}, "", false, nil)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -416,7 +416,7 @@ func TestServerTokenFail(t *testing.T) {
sm := session.NewSessionManager(session.NewSessionRepo(), session.NewSessionKeyRepo())
sm.GenerateCode = func() (string, error) { return keyFixture, nil }
sessionID, err := sm.NewSession("connector_id", ccFixture.ID, "bogus", url.URL{}, "", false)
sessionID, err := sm.NewSession("connector_id", ccFixture.ID, "bogus", url.URL{}, "", false, nil)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}

3
session/manager.go

@ -44,7 +44,7 @@ type SessionManager struct {
keys SessionKeyRepo
}
func (m *SessionManager) NewSession(connectorID, clientID, clientState string, redirectURL url.URL, nonce string, register bool) (string, error) {
func (m *SessionManager) NewSession(connectorID, clientID, clientState string, redirectURL url.URL, nonce string, register bool, scope []string) (string, error) {
sID, err := m.GenerateCode()
if err != nil {
return "", err
@ -62,6 +62,7 @@ func (m *SessionManager) NewSession(connectorID, clientID, clientState string, r
RedirectURL: redirectURL,
Register: register,
Nonce: nonce,
Scope: scope,
}
err = m.sessions.Create(s)

10
session/manager_test.go

@ -16,7 +16,7 @@ func staticGenerateCodeFunc(code string) GenerateCodeFunc {
func TestSessionManagerNewSession(t *testing.T) {
sm := NewSessionManager(NewSessionRepo(), NewSessionKeyRepo())
sm.GenerateCode = staticGenerateCodeFunc("boo")
got, err := sm.NewSession("bogus_idpc", "XXX", "bogus", url.URL{}, "", false)
got, err := sm.NewSession("bogus_idpc", "XXX", "bogus", url.URL{}, "", false, nil)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -27,7 +27,7 @@ func TestSessionManagerNewSession(t *testing.T) {
func TestSessionAttachRemoteIdentityTwice(t *testing.T) {
sm := NewSessionManager(NewSessionRepo(), NewSessionKeyRepo())
sessionID, err := sm.NewSession("bogus_idpc", "XXX", "bogus", url.URL{}, "", false)
sessionID, err := sm.NewSession("bogus_idpc", "XXX", "bogus", url.URL{}, "", false, nil)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -44,7 +44,7 @@ func TestSessionAttachRemoteIdentityTwice(t *testing.T) {
func TestSessionManagerExchangeKey(t *testing.T) {
sm := NewSessionManager(NewSessionRepo(), NewSessionKeyRepo())
sessionID, err := sm.NewSession("connector_id", "XXX", "bogus", url.URL{}, "", false)
sessionID, err := sm.NewSession("connector_id", "XXX", "bogus", url.URL{}, "", false, nil)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -80,7 +80,7 @@ func TestSessionManagerGetSessionInStateNoExist(t *testing.T) {
func TestSessionManagerGetSessionInStateWrongState(t *testing.T) {
sm := NewSessionManager(NewSessionRepo(), NewSessionKeyRepo())
sessionID, err := sm.NewSession("connector_id", "XXX", "bogus", url.URL{}, "", false)
sessionID, err := sm.NewSession("connector_id", "XXX", "bogus", url.URL{}, "", false, nil)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
@ -95,7 +95,7 @@ func TestSessionManagerGetSessionInStateWrongState(t *testing.T) {
func TestSessionManagerKill(t *testing.T) {
sm := NewSessionManager(NewSessionRepo(), NewSessionKeyRepo())
sessionID, err := sm.NewSession("connector_id", "XXX", "bogus", url.URL{}, "", false)
sessionID, err := sm.NewSession("connector_id", "XXX", "bogus", url.URL{}, "", false, nil)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}

3
session/session.go

@ -48,6 +48,9 @@ type Session struct {
// Nonce is optionally provided in the initial authorization request, and propogated in such cases to the generated claims.
Nonce string
// Scope is the 'scope' field in the authentication request. Example scopes are 'openid', 'email', 'offline', etc.
Scope []string
}
// Claims returns a new set of Claims for the current session.

Loading…
Cancel
Save