func NewFirewall(issuer string, subject string, scopes fosite.Arguments, p ...ladon.Policy) (firewall.Firewall, *http.Client) { tokens := pkg.Tokens(1) fositeStore := pkg.FositeStore() ps := map[string]ladon.Policy{} for _, x := range p { ps[x.GetID()] = x } ladonWarden := pkg.LadonWarden(ps) ar := fosite.NewAccessRequest(&Session{Subject: subject}) ar.GrantedScopes = scopes fositeStore.CreateAccessTokenSession(nil, tokens[0][0], ar) conf := &oauth2.Config{Scopes: scopes, Endpoint: oauth2.Endpoint{}} return &warden.LocalWarden{ Warden: ladonWarden, TokenValidator: &core.CoreValidator{ AccessTokenStrategy: pkg.HMACStrategy, AccessTokenStorage: fositeStore, }, Issuer: issuer, }, conf.Client(oauth2.NoContext, &oauth2.Token{ AccessToken: tokens[0][1], Expiry: time.Now().Add(time.Hour), TokenType: "bearer", }) }
func TestResourceOwnerFlow_HandleTokenEndpointRequest(t *testing.T) { ctrl := gomock.NewController(t) store := internal.NewMockResourceOwnerPasswordCredentialsGrantStorage(ctrl) defer ctrl.Finish() areq := fosite.NewAccessRequest(nil) httpreq := &http.Request{PostForm: url.Values{}} h := ResourceOwnerPasswordCredentialsGrantHandler{ ResourceOwnerPasswordCredentialsGrantStorage: store, HandleHelper: &HandleHelper{ AccessTokenStorage: store, AccessTokenLifespan: time.Hour, }, ScopeStrategy: fosite.HierarchicScopeStrategy, } for k, c := range []struct { description string setup func() expectErr error }{ { description: "should fail because not responsible", expectErr: fosite.ErrUnknownRequest, setup: func() { areq.GrantTypes = fosite.Arguments{"123"} }, }, { description: "should fail because because invalid credentials", setup: func() { areq.GrantTypes = fosite.Arguments{"password"} areq.Client = &fosite.DefaultClient{GrantTypes: fosite.Arguments{"password"}} httpreq.PostForm.Set("username", "peter") httpreq.PostForm.Set("password", "pan") store.EXPECT().Authenticate(nil, "peter", "pan").Return(fosite.ErrNotFound) }, expectErr: fosite.ErrInvalidRequest, }, { description: "should fail because because error on lookup", setup: func() { store.EXPECT().Authenticate(nil, "peter", "pan").Return(errors.New("")) }, expectErr: fosite.ErrServerError, }, { description: "should pass", setup: func() { store.EXPECT().Authenticate(nil, "peter", "pan").Return(nil) }, }, } { c.setup() err := h.HandleTokenEndpointRequest(nil, httpreq, areq) assert.True(t, errors.Cause(err) == c.expectErr, "(%d) %s\n%s\n%s", k, c.description, err, c.expectErr) t.Logf("Passed test case %d", k) } }
func TestHandleTokenEndpointRequest(t *testing.T) { h := &OpenIDConnectExplicitHandler{} areq := fosite.NewAccessRequest(nil) areq.Client = &fosite.DefaultClient{ ResponseTypes: fosite.Arguments{"id_token"}, } assert.True(t, errors.Cause(h.HandleTokenEndpointRequest(nil, nil, areq)) == fosite.ErrUnknownRequest) }
func init() { wardens["local"] = &warden.LocalWarden{ Warden: ladonWarden, TokenValidator: &core.CoreValidator{ AccessTokenStrategy: pkg.HMACStrategy, AccessTokenStorage: fositeStore, }, Issuer: "tests", } r := httprouter.New() serv := &warden.WardenHandler{ Ladon: ladonWarden, H: &herodot.JSON{}, Warden: wardens["local"], } serv.SetRoutes(r) ts = httptest.NewServer(r) url, err := url.Parse(ts.URL + warden.AllowedHandlerPath) if err != nil { log.Fatalf("%s", err) } ar := fosite.NewAccessRequest(&oauth2.Session{Subject: "alice"}) ar.GrantedScopes = fosite.Arguments{"core"} fositeStore.CreateAccessTokenSession(nil, tokens[0][0], ar) ar = fosite.NewAccessRequest(&oauth2.Session{Subject: "siri"}) ar.GrantedScopes = fosite.Arguments{"hydra.warden"} fositeStore.CreateAccessTokenSession(nil, tokens[1][0], ar) conf := &coauth2.Config{ Scopes: []string{}, Endpoint: coauth2.Endpoint{}, } wardens["http"] = &warden.HTTPWarden{ Endpoint: url, Client: conf.Client(coauth2.NoContext, &coauth2.Token{ AccessToken: tokens[1][1], Expiry: time.Now().Add(time.Hour), TokenType: "bearer", }), } }
func TestIntrospectionResponse(t *testing.T) { r := &fosite.IntrospectionResponse{ AccessRequester: fosite.NewAccessRequest(nil), Active: true, } assert.Equal(t, r.AccessRequester, r.GetAccessRequester()) assert.Equal(t, r.Active, r.IsActive()) }
func (w *LocalWarden) ActionAllowed(ctx context.Context, token string, a *ladon.Request, scopes ...string) (*Context, error) { var session = new(oauth2.Session) var oauthRequest = fosite.NewAccessRequest(session) if err := w.TokenValidator.ValidateToken(ctx, oauthRequest, token); err != nil { return nil, err } return w.actionAllowed(ctx, a, scopes, oauthRequest, session) }
func TestGetExpiresIn(t *testing.T) { now := time.Now() r := fosite.NewAccessRequest(&fosite.DefaultSession{ ExpiresAt: map[fosite.TokenType]time.Time{ fosite.AccessToken: now.Add(time.Hour), }, }) assert.Equal(t, time.Hour, getExpiresIn(r, fosite.AccessToken, time.Millisecond, now)) }
func TestClientCredentials_PopulateTokenEndpointResponse(t *testing.T) { ctrl := gomock.NewController(t) store := internal.NewMockClientCredentialsGrantStorage(ctrl) chgen := internal.NewMockAccessTokenStrategy(ctrl) areq := fosite.NewAccessRequest(new(fosite.DefaultSession)) aresp := fosite.NewAccessResponse() defer ctrl.Finish() h := ClientCredentialsGrantHandler{ HandleHelper: &HandleHelper{ AccessTokenStorage: store, AccessTokenStrategy: chgen, AccessTokenLifespan: time.Hour, }, ScopeStrategy: fosite.HierarchicScopeStrategy, } for k, c := range []struct { description string mock func() req *http.Request expectErr error }{ { description: "should fail because not responsible", expectErr: fosite.ErrUnknownRequest, mock: func() { areq.GrantTypes = fosite.Arguments{""} }, }, { description: "should fail because client not allowed", expectErr: fosite.ErrInvalidGrant, mock: func() { areq.GrantTypes = fosite.Arguments{"client_credentials"} areq.Client = &fosite.DefaultClient{GrantTypes: fosite.Arguments{"foo"}} }, }, { description: "should pass", mock: func() { areq.GrantTypes = fosite.Arguments{"client_credentials"} areq.Session = &fosite.DefaultSession{} areq.Client = &fosite.DefaultClient{GrantTypes: fosite.Arguments{"client_credentials"}} chgen.EXPECT().GenerateAccessToken(nil, areq).Return("tokenfoo.bar", "bar", nil) store.EXPECT().CreateAccessTokenSession(nil, "bar", areq).Return(nil) }, }, } { c.mock() err := h.PopulateTokenEndpointResponse(nil, c.req, areq, aresp) assert.True(t, errors.Cause(err) == c.expectErr, "(%d) %s\n%s\n%s", k, c.description, err, c.expectErr) t.Logf("Passed test case %d", k) } }
func (w *LocalWarden) HTTPActionAllowed(ctx context.Context, r *http.Request, a *ladon.Request, scopes ...string) (*Context, error) { var session = new(oauth2.Session) var oauthRequest = fosite.NewAccessRequest(session) if err := w.TokenValidator.ValidateRequest(ctx, r, oauthRequest); errors.Is(err, fosite.ErrUnknownRequest) { return nil, pkg.ErrUnauthorized } else if err != nil { return nil, err } return w.actionAllowed(ctx, a, scopes, oauthRequest, session) }
func TestGenerateIDToken(t *testing.T) { ctrl := gomock.NewController(t) chgen := internal.NewMockOpenIDConnectTokenStrategy(ctrl) defer ctrl.Finish() httpreq := &http.Request{Form: url.Values{}} ar := fosite.NewAccessRequest(nil) sess := &DefaultSession{ Claims: &jwt.IDTokenClaims{ Subject: "peter", }, Headers: &jwt.Headers{}, } h := &IDTokenHandleHelper{IDTokenStrategy: chgen} for k, c := range []struct { description string setup func() expectErr error }{ { description: "should fail because generator failed", setup: func() { ar.Form.Set("nonce", "11111111111111111111111111111111111") ar.SetSession(sess) chgen.EXPECT().GenerateIDToken(nil, httpreq, ar).Return("", fooErr) }, expectErr: fooErr, }, { description: "should pass", setup: func() { chgen.EXPECT().GenerateIDToken(nil, httpreq, ar).AnyTimes().Return("asdf", nil) }, }, } { c.setup() token, err := h.generateIDToken(nil, httpreq, ar) assert.True(t, errors.Cause(err) == c.expectErr, "(%d) %s\n%s\n%s", k, c.description, err, c.expectErr) if err == nil { assert.NotEmpty(t, token, "(%d) %s", k, c.description) } t.Logf("Passed test case %d", k) } }
func (w *LocalWarden) Authorized(ctx context.Context, token string, scopes ...string) (*Context, error) { var session = new(oauth2.Session) var oauthRequest = fosite.NewAccessRequest(session) if err := w.TokenValidator.ValidateToken(ctx, oauthRequest, token); err != nil { return nil, err } session = oauthRequest.GetSession().(*oauth2.Session) if !matchScopes(oauthRequest.GetGrantedScopes(), scopes, session, oauthRequest.Client) { return nil, errors.New(herodot.ErrForbidden) } return &Context{ Subject: session.Subject, GrantedScopes: oauthRequest.GetGrantedScopes(), Issuer: w.Issuer, Audience: oauthRequest.GetClient().GetID(), IssuedAt: oauthRequest.GetRequestedAt(), }, nil }
func TestExplicit_PopulateTokenEndpointResponse(t *testing.T) { ctrl := gomock.NewController(t) store := internal.NewMockOpenIDConnectRequestStorage(ctrl) defer ctrl.Finish() session := &DefaultSession{ Claims: &jwt.IDTokenClaims{ Subject: "peter", }, Headers: &jwt.Headers{}, } aresp := fosite.NewAccessResponse() areq := fosite.NewAccessRequest(session) httpreq := &http.Request{PostForm: url.Values{}} h := &OpenIDConnectExplicitHandler{ OpenIDConnectRequestStorage: store, IDTokenHandleHelper: &IDTokenHandleHelper{ IDTokenStrategy: j, }, } for k, c := range []struct { description string setup func() expectErr error }{ { description: "should fail because invalid response type", setup: func() {}, expectErr: fosite.ErrUnknownRequest, }, { description: "should fail because lookup returns not found", setup: func() { areq.GrantTypes = fosite.Arguments{"authorization_code"} areq.Client = &fosite.DefaultClient{ GrantTypes: fosite.Arguments{"authorization_code"}, ResponseTypes: fosite.Arguments{"id_token"}, } areq.Form.Set("code", "foobar") store.EXPECT().GetOpenIDConnectSession(nil, "foobar", areq).Return(nil, ErrNoSessionFound) }, expectErr: fosite.ErrUnknownRequest, }, { description: "should fail because lookup fails", setup: func() { areq.GrantTypes = fosite.Arguments{"authorization_code"} store.EXPECT().GetOpenIDConnectSession(nil, "foobar", areq).Return(nil, errors.New("")) }, expectErr: fosite.ErrServerError, }, { description: "should fail because missing scope in original request", setup: func() { areq.GrantTypes = fosite.Arguments{"authorization_code"} store.EXPECT().GetOpenIDConnectSession(nil, "foobar", areq).Return(fosite.NewAuthorizeRequest(), nil) }, expectErr: fosite.ErrMisconfiguration, }, { description: "should pass", setup: func() { r := fosite.NewAuthorizeRequest() r.Session = areq.Session r.GrantedScopes = fosite.Arguments{"openid"} r.Form.Set("nonce", "1111111111111111") store.EXPECT().GetOpenIDConnectSession(nil, gomock.Any(), areq).AnyTimes().Return(r, nil) }, }, } { c.setup() err := h.PopulateTokenEndpointResponse(nil, httpreq, areq, aresp) assert.True(t, errors.Cause(err) == c.expectErr, "(%d) %s\n%s\n%s", k, c.description, err, c.expectErr) t.Logf("Passed test case %d", k) } }
func TestAuthorizeCode_PopulateTokenEndpointResponse(t *testing.T) { ctrl := gomock.NewController(t) store := internal.NewMockAuthorizeCodeGrantStorage(ctrl) ach := internal.NewMockAccessTokenStrategy(ctrl) rch := internal.NewMockRefreshTokenStrategy(ctrl) auch := internal.NewMockAuthorizeCodeStrategy(ctrl) aresp := internal.NewMockAccessResponder(ctrl) //mockcl := internal.NewMockClient(ctrl) defer ctrl.Finish() areq := fosite.NewAccessRequest(new(fosite.DefaultSession)) httpreq := &http.Request{PostForm: url.Values{}} authreq := fosite.NewAuthorizeRequest() areq.Session = new(fosite.DefaultSession) h := AuthorizeExplicitGrantHandler{ AuthorizeCodeGrantStorage: store, AuthorizeCodeStrategy: auch, AccessTokenStrategy: ach, RefreshTokenStrategy: rch, ScopeStrategy: fosite.HierarchicScopeStrategy, } for k, c := range []struct { description string setup func() expectErr error }{ { description: "should fail because not responsible", expectErr: fosite.ErrUnknownRequest, setup: func() { areq.GrantTypes = fosite.Arguments{"123"} }, }, { description: "should fail because authcode not found", setup: func() { areq.GrantTypes = fosite.Arguments{"authorization_code"} areq.Client = &fosite.DefaultClient{ GrantTypes: fosite.Arguments{"authorization_code"}, } httpreq.PostForm.Add("code", "authcode") auch.EXPECT().AuthorizeCodeSignature("authcode").AnyTimes().Return("authsig") store.EXPECT().GetAuthorizeCodeSession(nil, "authsig", gomock.Any()).Return(nil, fosite.ErrNotFound) }, expectErr: fosite.ErrServerError, }, { description: "should fail because validation failed", setup: func() { store.EXPECT().GetAuthorizeCodeSession(nil, "authsig", gomock.Any()).AnyTimes().Return(authreq, nil) auch.EXPECT().ValidateAuthorizeCode(nil, areq, "authcode").Return(errors.New("")) }, expectErr: fosite.ErrInvalidRequest, }, { description: "should fail because access token generation failed", setup: func() { authreq.GrantedScopes = []string{"offline"} auch.EXPECT().ValidateAuthorizeCode(nil, areq, "authcode").AnyTimes().Return(nil) ach.EXPECT().GenerateAccessToken(nil, areq).Return("", "", errors.New("error")) }, expectErr: fosite.ErrServerError, }, { description: "should fail because refresh token generation failed", setup: func() { ach.EXPECT().GenerateAccessToken(nil, areq).AnyTimes().Return("access.ats", "ats", nil) rch.EXPECT().GenerateRefreshToken(nil, areq).Return("", "", errors.New("error")) }, expectErr: fosite.ErrServerError, }, { description: "should fail because persisting failed", setup: func() { rch.EXPECT().GenerateRefreshToken(nil, areq).AnyTimes().Return("refresh.rts", "rts", nil) store.EXPECT().PersistAuthorizeCodeGrantSession(nil, "authsig", "ats", "rts", areq).Return(errors.New("")) }, expectErr: fosite.ErrServerError, }, { description: "should pass", setup: func() { areq.GrantedScopes = fosite.Arguments{"foo", "offline"} store.EXPECT().PersistAuthorizeCodeGrantSession(nil, "authsig", "ats", "rts", areq).Return(nil) aresp.EXPECT().SetAccessToken("access.ats") aresp.EXPECT().SetTokenType("bearer") aresp.EXPECT().SetExtra("refresh_token", "refresh.rts") aresp.EXPECT().SetExpiresIn(gomock.Any()) aresp.EXPECT().SetScopes(areq.GrantedScopes) }, }, } { c.setup() err := h.PopulateTokenEndpointResponse(nil, httpreq, areq, aresp) assert.True(t, errors.Cause(err) == c.expectErr, "(%d) %s\n%s\n%s", k, c.description, err, c.expectErr) t.Logf("Passed test case %d", k) } }
func TestAuthorizeCode_HandleTokenEndpointRequest(t *testing.T) { ctrl := gomock.NewController(t) store := internal.NewMockAuthorizeCodeGrantStorage(ctrl) ach := internal.NewMockAuthorizeCodeStrategy(ctrl) defer ctrl.Finish() authreq := fosite.NewAuthorizeRequest() areq := fosite.NewAccessRequest(nil) httpreq := &http.Request{PostForm: url.Values{}} areq.Session = new(fosite.DefaultSession) authreq.Session = new(fosite.DefaultSession) h := AuthorizeExplicitGrantHandler{ AuthorizeCodeGrantStorage: store, AuthorizeCodeStrategy: ach, ScopeStrategy: fosite.HierarchicScopeStrategy, } for k, c := range []struct { description string setup func() expectErr error }{ { description: "should fail because not responsible", expectErr: fosite.ErrUnknownRequest, setup: func() { areq.GrantTypes = fosite.Arguments{"12345678"} // grant_type REQUIRED. Value MUST be set to "authorization_code". }, }, { description: "should fail because authcode could not be retrieved (1)", setup: func() { areq.GrantTypes = fosite.Arguments{"authorization_code"} // grant_type REQUIRED. Value MUST be set to "authorization_code". httpreq.PostForm = url.Values{"code": {"foo.bar"}} ach.EXPECT().AuthorizeCodeSignature("foo.bar").AnyTimes().Return("bar") store.EXPECT().GetAuthorizeCodeSession(nil, "bar", gomock.Any()).Return(nil, fosite.ErrNotFound) }, expectErr: fosite.ErrInvalidRequest, }, { description: "should fail because authcode validation failed", setup: func() { store.EXPECT().GetAuthorizeCodeSession(nil, "bar", gomock.Any()).AnyTimes().Return(authreq, nil) ach.EXPECT().ValidateAuthorizeCode(nil, areq, "foo.bar").Return(errors.New("")) }, expectErr: fosite.ErrInvalidRequest, }, { description: "should fail because client mismatch", setup: func() { ach.EXPECT().ValidateAuthorizeCode(nil, areq, "foo.bar").AnyTimes().Return(nil) areq.Client = &fosite.DefaultClient{ID: "foo"} authreq.Scopes = fosite.Arguments{"a", "b"} authreq.Client = &fosite.DefaultClient{ID: "bar"} }, expectErr: fosite.ErrInvalidRequest, }, { description: "should fail because redirect uri not provided", setup: func() { authreq.Form.Add("redirect_uri", "request-redir") authreq.Client = &fosite.DefaultClient{ID: "foo"} }, expectErr: fosite.ErrInvalidRequest, }, { description: "should pass (2)", setup: func() { httpreq.PostForm = url.Values{"code": []string{"foo.bar"}} authreq.Form.Del("redirect_uri") authreq.RequestedAt = time.Now().Add(time.Hour) }, }, } { c.setup() err := h.HandleTokenEndpointRequest(nil, httpreq, areq) assert.True(t, errors.Cause(err) == c.expectErr, "(%d) %s\n%s\n%s", k, c.description, err, c.expectErr) t.Logf("Passed test case %d", k) } }
func TestIntrospectToken(t *testing.T) { ctrl := gomock.NewController(t) store := internal.NewMockCoreStorage(ctrl) chgen := internal.NewMockCoreStrategy(ctrl) areq := fosite.NewAccessRequest(nil) defer ctrl.Finish() v := &CoreValidator{ CoreStrategy: chgen, CoreStorage: store, } httpreq := &http.Request{Header: http.Header{}} for k, c := range []struct { description string setup func() expectErr error }{ { description: "should fail because no bearer token set", setup: func() { httpreq.Header.Set("Authorization", "bearer") chgen.EXPECT().AccessTokenSignature("").Return("") store.EXPECT().GetAccessTokenSession(nil, "", nil).Return(nil, errors.New("")) chgen.EXPECT().RefreshTokenSignature("").Return("") store.EXPECT().GetRefreshTokenSession(nil, "", nil).Return(nil, errors.New("")) chgen.EXPECT().AuthorizeCodeSignature("").Return("") store.EXPECT().GetAuthorizeCodeSession(nil, "", nil).Return(nil, errors.New("")) }, expectErr: fosite.ErrRequestUnauthorized, }, { description: "should fail because retrieval fails", setup: func() { httpreq.Header.Set("Authorization", "bearer 1234") chgen.EXPECT().AccessTokenSignature("1234").AnyTimes().Return("asdf") store.EXPECT().GetAccessTokenSession(nil, "asdf", nil).Return(nil, errors.New("")) chgen.EXPECT().RefreshTokenSignature("1234").Return("asdf") store.EXPECT().GetRefreshTokenSession(nil, "asdf", nil).Return(nil, errors.New("")) chgen.EXPECT().AuthorizeCodeSignature("1234").Return("asdf") store.EXPECT().GetAuthorizeCodeSession(nil, "asdf", nil).Return(nil, errors.New("")) }, expectErr: fosite.ErrRequestUnauthorized, }, { description: "should fail because validation fails", setup: func() { store.EXPECT().GetAccessTokenSession(nil, "asdf", nil).AnyTimes().Return(areq, nil) chgen.EXPECT().ValidateAccessToken(nil, areq, "1234").Return(errors.Wrap(fosite.ErrTokenExpired, "")) chgen.EXPECT().RefreshTokenSignature("1234").Return("asdf") store.EXPECT().GetRefreshTokenSession(nil, "asdf", nil).Return(nil, errors.New("")) chgen.EXPECT().AuthorizeCodeSignature("1234").Return("asdf") store.EXPECT().GetAuthorizeCodeSession(nil, "asdf", nil).Return(nil, errors.New("")) }, expectErr: fosite.ErrTokenExpired, }, { description: "should pass", setup: func() { chgen.EXPECT().ValidateAccessToken(nil, areq, "1234").Return(nil) }, }, } { c.setup() err := v.IntrospectToken(nil, fosite.AccessTokenFromRequest(httpreq), fosite.AccessToken, areq, []string{}) assert.True(t, errors.Cause(err) == c.expectErr, "(%d) %s\n%s\n%s", k, c.description, err, c.expectErr) t.Logf("Passed test case %d", k) } }
func TestRefreshFlow_PopulateTokenEndpointResponse(t *testing.T) { ctrl := gomock.NewController(t) store := internal.NewMockRefreshTokenGrantStorage(ctrl) rcts := internal.NewMockRefreshTokenStrategy(ctrl) acts := internal.NewMockAccessTokenStrategy(ctrl) areq := fosite.NewAccessRequest(nil) aresp := internal.NewMockAccessResponder(ctrl) httpreq := &http.Request{PostForm: url.Values{}} defer ctrl.Finish() areq.Client = &fosite.DefaultClient{} h := RefreshTokenGrantHandler{ RefreshTokenGrantStorage: store, RefreshTokenStrategy: rcts, AccessTokenStrategy: acts, AccessTokenLifespan: time.Hour, } for k, c := range []struct { description string setup func() expectErr error }{ { description: "should fail because not responsible", expectErr: fosite.ErrUnknownRequest, setup: func() { areq.GrantTypes = fosite.Arguments{"313"} }, }, { description: "should fail because access token generation fails", setup: func() { areq.GrantTypes = fosite.Arguments{"refresh_token"} httpreq.PostForm.Add("refresh_token", "foo.reftokensig") rcts.EXPECT().RefreshTokenSignature("foo.reftokensig").AnyTimes().Return("reftokensig") acts.EXPECT().GenerateAccessToken(nil, areq).Return("", "", errors.New("")) }, expectErr: fosite.ErrServerError, }, { description: "should fail because access token generation fails", setup: func() { acts.EXPECT().GenerateAccessToken(nil, areq).AnyTimes().Return("access.atsig", "atsig", nil) rcts.EXPECT().GenerateRefreshToken(nil, areq).Return("", "", errors.New("")) }, expectErr: fosite.ErrServerError, }, { description: "should fail because persisting fails", setup: func() { rcts.EXPECT().GenerateRefreshToken(nil, areq).AnyTimes().Return("refresh.resig", "resig", nil) store.EXPECT().PersistRefreshTokenGrantSession(nil, "reftokensig", "atsig", "resig", areq).Return(errors.New("")) }, expectErr: fosite.ErrServerError, }, { description: "should pass", setup: func() { areq.Session = &fosite.DefaultSession{} store.EXPECT().PersistRefreshTokenGrantSession(nil, "reftokensig", "atsig", "resig", areq).AnyTimes().Return(nil) aresp.EXPECT().SetAccessToken("access.atsig") aresp.EXPECT().SetTokenType("bearer") aresp.EXPECT().SetExpiresIn(gomock.Any()) aresp.EXPECT().SetScopes(gomock.Any()) aresp.EXPECT().SetExtra("refresh_token", "refresh.resig") }, }, } { c.setup() err := h.PopulateTokenEndpointResponse(nil, httpreq, areq, aresp) assert.True(t, errors.Cause(err) == c.expectErr, "(%d) %s\n%s\n%s", k, c.description, err, c.expectErr) t.Logf("Passed test case %d", k) } }
func TestResourceOwnerFlow_PopulateTokenEndpointResponse(t *testing.T) { ctrl := gomock.NewController(t) store := internal.NewMockResourceOwnerPasswordCredentialsGrantStorage(ctrl) chgen := internal.NewMockAccessTokenStrategy(ctrl) rtstr := internal.NewMockRefreshTokenStrategy(ctrl) aresp := fosite.NewAccessResponse() mockAT := "accesstoken.foo.bar" mockRT := "refreshtoken.bar.foo" defer ctrl.Finish() areq := fosite.NewAccessRequest(nil) httpreq := &http.Request{PostForm: url.Values{}} h := ResourceOwnerPasswordCredentialsGrantHandler{ ResourceOwnerPasswordCredentialsGrantStorage: store, HandleHelper: &HandleHelper{ AccessTokenStorage: store, AccessTokenStrategy: chgen, AccessTokenLifespan: time.Hour, }, RefreshTokenStrategy: rtstr, } for k, c := range []struct { description string setup func() expectErr error expect func() }{ { description: "should fail because not responsible", expectErr: fosite.ErrUnknownRequest, setup: func() { areq.GrantTypes = fosite.Arguments{""} }, }, { description: "should pass", setup: func() { areq.Session = &fosite.DefaultSession{} areq.GrantTypes = fosite.Arguments{"password"} chgen.EXPECT().GenerateAccessToken(nil, areq).Return(mockAT, "bar", nil) store.EXPECT().CreateAccessTokenSession(nil, "bar", areq).Return(nil) }, expect: func() { assert.Nil(t, aresp.GetExtra("refresh_token"), "unexpected refresh token") }, }, { description: "should pass - offline scope", setup: func() { areq.GrantTypes = fosite.Arguments{"password"} areq.GrantScope("offline") rtstr.EXPECT().GenerateRefreshToken(nil, areq).Return(mockRT, "bar", nil) store.EXPECT().CreateRefreshTokenSession(nil, "bar", areq).Return(nil) chgen.EXPECT().GenerateAccessToken(nil, areq).Return(mockAT, "bar", nil) store.EXPECT().CreateAccessTokenSession(nil, "bar", areq).Return(nil) }, expect: func() { assert.NotNil(t, aresp.GetExtra("refresh_token"), "expected refresh token") }, }, } { c.setup() err := h.PopulateTokenEndpointResponse(nil, httpreq, areq, aresp) assert.True(t, errors.Cause(err) == c.expectErr, "(%d) %s\n%s\n%s", k, c.description, err, c.expectErr) if c.expect != nil { c.expect() } t.Logf("Passed test case %d", k) } }
func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) { ctrl := gomock.NewController(t) store := internal.NewMockRefreshTokenGrantStorage(ctrl) chgen := internal.NewMockRefreshTokenStrategy(ctrl) defer ctrl.Finish() areq := fosite.NewAccessRequest(nil) sess := &fosite.DefaultSession{Subject: "othersub"} httpreq := &http.Request{PostForm: url.Values{}} h := RefreshTokenGrantHandler{ RefreshTokenGrantStorage: store, RefreshTokenStrategy: chgen, AccessTokenLifespan: time.Hour, } for k, c := range []struct { description string setup func() expectErr error expect func() }{ { description: "should fail because not responsible", expectErr: fosite.ErrUnknownRequest, setup: func() { areq.GrantTypes = fosite.Arguments{"123"} }, }, { description: "should fail because lookup failed", setup: func() { areq.GrantTypes = fosite.Arguments{"refresh_token"} areq.Client = &fosite.DefaultClient{GrantTypes: fosite.Arguments{"refresh_token"}} httpreq.PostForm.Add("refresh_token", "some.refreshtokensig") chgen.EXPECT().RefreshTokenSignature("some.refreshtokensig").AnyTimes().Return("refreshtokensig") store.EXPECT().GetRefreshTokenSession(nil, "refreshtokensig", nil).Return(nil, fosite.ErrNotFound) }, expectErr: fosite.ErrInvalidRequest, }, { description: "should fail because validation failed", setup: func() { store.EXPECT().GetRefreshTokenSession(nil, "refreshtokensig", nil).Return(&fosite.Request{ GrantedScopes: []string{"offline"}, }, nil) chgen.EXPECT().ValidateRefreshToken(nil, areq, "some.refreshtokensig").Return(errors.New("")) }, expectErr: fosite.ErrInvalidRequest, }, { description: "should fail because client mismatches", setup: func() { areq.Client = &fosite.DefaultClient{ ID: "foo", GrantTypes: fosite.Arguments{"refresh_token"}, } store.EXPECT().GetRefreshTokenSession(nil, "refreshtokensig", nil).Return(&fosite.Request{ Client: &fosite.DefaultClient{ID: ""}, GrantedScopes: []string{"offline"}, }, nil) chgen.EXPECT().ValidateRefreshToken(nil, areq, "some.refreshtokensig").AnyTimes().Return(nil) }, expectErr: fosite.ErrInvalidRequest, }, { description: "should pass", setup: func() { store.EXPECT().GetRefreshTokenSession(nil, "refreshtokensig", nil).Return(&fosite.Request{ Client: &fosite.DefaultClient{ID: "foo"}, GrantedScopes: fosite.Arguments{"foo", "offline"}, Scopes: fosite.Arguments{"foo", "bar"}, Session: sess, Form: url.Values{"foo": []string{"bar"}}, RequestedAt: time.Now().Add(-time.Hour).Round(time.Hour), }, nil) }, expect: func() { assert.Equal(t, sess, areq.Session) assert.NotEqual(t, time.Now().Add(-time.Hour).Round(time.Hour), areq.RequestedAt) assert.Equal(t, fosite.Arguments{"foo", "offline"}, areq.GrantedScopes) assert.Equal(t, fosite.Arguments{"foo", "bar"}, areq.Scopes) assert.NotEqual(t, url.Values{"foo": []string{"bar"}}, areq.Form) }, }, } { c.setup() err := h.HandleTokenEndpointRequest(nil, httpreq, areq) assert.True(t, errors.Cause(err) == c.expectErr, "(%d) %s\n%s\n%s", k, c.description, err, c.expectErr) if c.expect != nil { c.expect() } t.Logf("Passed test case %d", k) } }
func TestJWTStrategy_GenerateIDToken(t *testing.T) { var req *fosite.AccessRequest for k, c := range []struct { setup func() expectErr bool }{ { setup: func() { req = fosite.NewAccessRequest(&DefaultSession{ Claims: &jwt.IDTokenClaims{ Subject: "peter", }, Headers: &jwt.Headers{}, }) req.Form.Set("nonce", "some-secure-nonce-state") }, expectErr: false, }, { setup: func() { req = fosite.NewAccessRequest(&DefaultSession{ Claims: &jwt.IDTokenClaims{ Subject: "peter", AuthTime: time.Now(), }, Headers: &jwt.Headers{}, }) req.Form.Set("nonce", "some-secure-nonce-state") req.Form.Set("max_age", "1234") }, expectErr: false, }, { setup: func() { req = fosite.NewAccessRequest(&DefaultSession{ Claims: &jwt.IDTokenClaims{ Subject: "peter", ExpiresAt: time.Now().Add(-time.Hour), }, Headers: &jwt.Headers{}, }) req.Form.Set("nonce", "some-secure-nonce-state") }, expectErr: true, }, { setup: func() { req = fosite.NewAccessRequest(&DefaultSession{ Claims: &jwt.IDTokenClaims{ Subject: "peter", }, Headers: &jwt.Headers{}, }) req.Form.Set("nonce", "some-secure-nonce-state") req.Form.Set("max_age", "1234") }, expectErr: true, }, { setup: func() { req = fosite.NewAccessRequest(&DefaultSession{ Claims: &jwt.IDTokenClaims{}, Headers: &jwt.Headers{}, }) req.Form.Set("nonce", "some-secure-nonce-state") }, expectErr: true, }, { setup: func() { req = fosite.NewAccessRequest(&DefaultSession{ Claims: &jwt.IDTokenClaims{ Subject: "peter", }, Headers: &jwt.Headers{}, }) }, expectErr: true, }, } { c.setup() token, err := j.GenerateIDToken(nil, nil, req) assert.Equal(t, c.expectErr, err != nil, "%d: %s", k, err) if !c.expectErr { assert.NotEmpty(t, token) } } }
func TestNewAccessRequest(t *testing.T) { ctrl := gomock.NewController(t) store := internal.NewMockStorage(ctrl) client := internal.NewMockClient(ctrl) handler := internal.NewMockTokenEndpointHandler(ctrl) hasher := internal.NewMockHasher(ctrl) defer ctrl.Finish() fosite := &Fosite{Store: store, Hasher: hasher} for k, c := range []struct { header http.Header form url.Values mock func() method string expectErr error expect *AccessRequest handlers TokenEndpointHandlers }{ { header: http.Header{}, expectErr: ErrInvalidRequest, method: "POST", mock: func() {}, }, { header: http.Header{}, method: "POST", form: url.Values{ "grant_type": {"foo"}, }, mock: func() {}, expectErr: ErrInvalidRequest, }, { header: http.Header{}, method: "POST", form: url.Values{ "grant_type": {"foo"}, "client_id": {"foo"}, }, expectErr: ErrInvalidRequest, mock: func() {}, }, { header: http.Header{ "Authorization": {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ "grant_type": {"foo"}, }, expectErr: ErrInvalidClient, mock: func() { store.EXPECT().GetClient(gomock.Eq("foo")).Return(nil, errors.New("")) }, }, { header: http.Header{ "Authorization": {basicAuth("foo", "bar")}, }, method: "GET", form: url.Values{ "grant_type": {"foo"}, }, expectErr: ErrInvalidRequest, mock: func() {}, }, { header: http.Header{ "Authorization": {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ "grant_type": {"foo"}, }, expectErr: ErrInvalidClient, mock: func() { store.EXPECT().GetClient(gomock.Eq("foo")).Return(nil, errors.New("")) }, }, { header: http.Header{ "Authorization": {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ "grant_type": {"foo"}, }, expectErr: ErrInvalidClient, mock: func() { store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil) client.EXPECT().GetHashedSecret().Return([]byte("foo")) hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(errors.New("")) }, }, { header: http.Header{ "Authorization": {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ "grant_type": {"foo"}, }, expectErr: ErrServerError, mock: func() { store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil) client.EXPECT().GetHashedSecret().Return([]byte("foo")) hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil) handler.EXPECT().ValidateTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(ErrServerError) }, handlers: TokenEndpointHandlers{"a": handler}, }, { header: http.Header{ "Authorization": {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ "grant_type": {"foo"}, }, expectErr: ErrUnsupportedGrantType, mock: func() { store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil) client.EXPECT().GetHashedSecret().Return([]byte("foo")) hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil) handler.EXPECT().ValidateTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) }, handlers: TokenEndpointHandlers{"a": handler}, }, { header: http.Header{ "Authorization": {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ "grant_type": {"foo"}, }, expectErr: ErrUnsupportedGrantType, mock: func() { store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil) client.EXPECT().GetHashedSecret().Return([]byte("foo")) hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil) handler.EXPECT().ValidateTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ context.Context, _ *http.Request, a AccessRequester, _ interface{}) { a.SetGrantTypeHandled("bar") }).Return(nil) }, handlers: TokenEndpointHandlers{"a": handler}, }, { header: http.Header{ "Authorization": {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ "grant_type": {"foo"}, }, mock: func() { store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil) client.EXPECT().GetHashedSecret().Return([]byte("foo")) hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil) handler.EXPECT().ValidateTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ context.Context, _ *http.Request, a AccessRequester, _ interface{}) { a.SetGrantTypeHandled("foo") a.SetScopes([]string{"asdfasdf"}) }).Return(nil) }, handlers: TokenEndpointHandlers{"a": handler}, expectErr: ErrInvalidScope, }, { header: http.Header{ "Authorization": {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ "grant_type": {"foo"}, }, mock: func() { store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil) client.EXPECT().GetHashedSecret().Return([]byte("foo")) hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil) handler.EXPECT().ValidateTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Do(func(_ context.Context, _ *http.Request, a AccessRequester, _ interface{}) { a.SetGrantTypeHandled("foo") a.SetScopes([]string{DefaultRequiredScopeName}) }).Return(nil) }, handlers: TokenEndpointHandlers{"a": handler}, expect: &AccessRequest{ GrantType: "foo", HandledGrantType: []string{"foo"}, Client: client, }, }, } { r := &http.Request{ Header: c.header, PostForm: c.form, Form: c.form, Method: c.method, } c.mock() ctx := NewContext() fosite.TokenEndpointHandlers = c.handlers ar, err := fosite.NewAccessRequest(ctx, r, &struct{}{}) is := errors.Is(c.expectErr, err) assert.True(t, is, "%d\nwant: %s \ngot: %s", k, c.expectErr, err) if !is { t.Logf("Error occured: %s", err.(*errors.Error).ErrorStack()) } if err == nil { pkg.AssertObjectKeysEqual(t, c.expect, ar, "GrantType", "Client") assert.NotNil(t, ar.GetRequestedAt()) } t.Logf("Passed test case %d", k) } }
func TestNewAccessRequest(t *testing.T) { ctrl := gomock.NewController(t) store := internal.NewMockStorage(ctrl) client := internal.NewMockClient(ctrl) handler := internal.NewMockTokenEndpointHandler(ctrl) hasher := internal.NewMockHasher(ctrl) defer ctrl.Finish() fosite := &Fosite{Store: store, Hasher: hasher} for k, c := range []struct { header http.Header form url.Values mock func() method string expectErr error expect *AccessRequest handlers TokenEndpointHandlers }{ { header: http.Header{}, expectErr: ErrInvalidRequest, method: "POST", mock: func() {}, }, { header: http.Header{}, method: "POST", form: url.Values{ "grant_type": {"foo"}, }, mock: func() {}, expectErr: ErrInvalidRequest, }, { header: http.Header{}, method: "POST", form: url.Values{ "grant_type": {"foo"}, "client_id": {"foo"}, }, expectErr: ErrInvalidRequest, mock: func() {}, }, { header: http.Header{ "Authorization": {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ "grant_type": {"foo"}, }, expectErr: ErrInvalidClient, mock: func() { store.EXPECT().GetClient(gomock.Eq("foo")).Return(nil, errors.New("")) }, }, { header: http.Header{ "Authorization": {basicAuth("foo", "bar")}, }, method: "GET", form: url.Values{ "grant_type": {"foo"}, }, expectErr: ErrInvalidRequest, mock: func() {}, }, { header: http.Header{ "Authorization": {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ "grant_type": {"foo"}, }, expectErr: ErrInvalidClient, mock: func() { store.EXPECT().GetClient(gomock.Eq("foo")).Return(nil, errors.New("")) }, }, { header: http.Header{ "Authorization": {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ "grant_type": {"foo"}, }, expectErr: ErrInvalidClient, mock: func() { store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil) client.EXPECT().IsPublic().Return(false) client.EXPECT().GetHashedSecret().Return([]byte("foo")) hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(errors.New("")) }, }, { header: http.Header{ "Authorization": {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ "grant_type": {"foo"}, }, expectErr: ErrServerError, mock: func() { store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil) client.EXPECT().IsPublic().Return(false) client.EXPECT().GetHashedSecret().Return([]byte("foo")) hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil) handler.EXPECT().HandleTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return(ErrServerError) }, handlers: TokenEndpointHandlers{handler}, }, { header: http.Header{ "Authorization": {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ "grant_type": {"foo"}, }, mock: func() { store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil) client.EXPECT().IsPublic().Return(false) client.EXPECT().GetHashedSecret().Return([]byte("foo")) hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil) handler.EXPECT().HandleTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) }, handlers: TokenEndpointHandlers{handler}, expect: &AccessRequest{ GrantTypes: Arguments{"foo"}, Request: Request{ Client: client, }, }, }, { header: http.Header{ "Authorization": {basicAuth("foo", "bar")}, }, method: "POST", form: url.Values{ "grant_type": {"foo"}, }, mock: func() { store.EXPECT().GetClient(gomock.Eq("foo")).Return(client, nil) client.EXPECT().IsPublic().Return(true) handler.EXPECT().HandleTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) }, handlers: TokenEndpointHandlers{handler}, expect: &AccessRequest{ GrantTypes: Arguments{"foo"}, Request: Request{ Client: client, }, }, }, } { r := &http.Request{ Header: c.header, PostForm: c.form, Form: c.form, Method: c.method, } c.mock() ctx := NewContext() fosite.TokenEndpointHandlers = c.handlers ar, err := fosite.NewAccessRequest(ctx, r, new(DefaultSession)) assert.True(t, errors.Cause(err) == c.expectErr, "%d\nwant: %s \ngot: %s", k, c.expectErr, err) if err != nil { t.Logf("Error occured: %v", err) } else { pkg.AssertObjectKeysEqual(t, c.expect, ar, "GrantTypes", "Client") assert.NotNil(t, ar.GetRequestedAt()) } t.Logf("Passed test case %d", k) } }