func TestOpenIDConnectExplicitFlow(t *testing.T) { session := &defaultSession{ DefaultSession: &openid.DefaultSession{ Claims: &jwt.IDTokenClaims{ Subject: "peter", }, Headers: &jwt.Headers{}, }, } f := compose.ComposeAllEnabled(new(compose.Config), fositeStore, []byte("some-secret-thats-random"), internal.MustRSAKey()) ts := mockServer(t, f, session) defer ts.Close() oauthClient := newOAuth2Client(ts) fositeStore.Clients["my-client"].RedirectURIs[0] = ts.URL + "/callback" var state string for k, c := range []struct { description string setup func() authStatusCode int }{ { description: "should pass", setup: func() { state = "12345678901234567890" oauthClient.Scopes = []string{"openid"} }, authStatusCode: http.StatusOK, }, } { c.setup() resp, err := http.Get(oauthClient.AuthCodeURL(state) + "&nonce=1234567890") require.Nil(t, err) require.Equal(t, c.authStatusCode, resp.StatusCode, "(%d) %s", k, c.description) if resp.StatusCode == http.StatusOK { token, err := oauthClient.Exchange(oauth2.NoContext, resp.Request.URL.Query().Get("code")) fmt.Printf("after exchange: %s\n\n", fositeStore.AuthorizeCodes) require.Nil(t, err, "(%d) %s", k, c.description) require.NotEmpty(t, token.AccessToken, "(%d) %s", k, c.description) require.NotEmpty(t, token.Extra("id_token"), "(%d) %s", k, c.description) } t.Logf("Passed test case (%d) %s", k, c.description) } }
func TestOIDCImplicitFlow(t *testing.T) { session := &defaultSession{ DefaultSession: &openid.DefaultSession{ Claims: &jwt.IDTokenClaims{ Subject: "peter", }, Headers: &jwt.Headers{}, }, } f := compose.ComposeAllEnabled(new(compose.Config), fositeStore, []byte("some-secret-thats-random"), internal.MustRSAKey()) ts := mockServer(t, f, session) defer ts.Close() oauthClient := newOAuth2Client(ts) fositeStore.Clients["my-client"].RedirectURIs[0] = ts.URL + "/callback" var state = "12345678901234567890" for k, c := range []struct { responseType string description string nonce string setup func() hasToken bool hasCode bool }{ { description: "should pass without id token", responseType: "token", setup: func() { oauthClient.Scopes = []string{"fosite"} }, }, { responseType: "id_token%20token", nonce: "1111111111111111", description: "should pass id token (id_token token)", setup: func() { oauthClient.Scopes = []string{"fosite", "openid"} }, hasToken: true, }, { responseType: "token%20id_token%20code", nonce: "1111111111111111", description: "should pass id token (id_token token)", setup: func() {}, hasToken: true, hasCode: true, }, } { c.setup() var callbackURL *url.URL authURL := strings.Replace(oauthClient.AuthCodeURL(state), "response_type=code", "response_type="+c.responseType, -1) + "&nonce=" + c.nonce client := &http.Client{ CheckRedirect: func(req *http.Request, via []*http.Request) error { callbackURL = req.URL return errors.New("Dont follow redirects") }, } resp, err := client.Get(authURL) require.NotNil(t, err, "(%d) %s", k, c.description) t.Logf("Response: %s", callbackURL.String()) fragment, err := url.ParseQuery(callbackURL.Fragment) require.Nil(t, err, "(%d) %s", k, c.description) expires, err := strconv.Atoi(fragment.Get("expires_in")) require.Nil(t, err, "(%d) %s", k, c.description) token := &oauth2.Token{ AccessToken: fragment.Get("access_token"), TokenType: fragment.Get("token_type"), RefreshToken: fragment.Get("refresh_token"), Expiry: time.Now().Add(time.Duration(expires) * time.Second), } if c.hasToken { assert.NotEmpty(t, fragment.Get("id_token"), "(%d) %s", k, c.description) } else { assert.Empty(t, fragment.Get("id_token"), "(%d) %s", k, c.description) } if c.hasCode { assert.NotEmpty(t, fragment.Get("code"), "(%d) %s", k, c.description) } else { assert.Empty(t, fragment.Get("code"), "(%d) %s", k, c.description) } httpClient := oauthClient.Client(oauth2.NoContext, token) resp, err = httpClient.Get(ts.URL + "/info") require.Nil(t, err, "(%d) %s", k, c.description) assert.Equal(t, http.StatusNoContent, resp.StatusCode, "(%d) %s", k, c.description) t.Logf("Passed test case (%d) %s", k, c.description) } }
func TestNewIntrospectionRequest(t *testing.T) { ctrl := gomock.NewController(t) validator := internal.NewMockTokenIntrospector(ctrl) defer ctrl.Finish() f := compose.ComposeAllEnabled(new(compose.Config), storage.NewMemoryStore(), []byte{}, nil).(*Fosite) httpreq := &http.Request{ Method: "POST", Header: http.Header{}, Form: url.Values{}, } for k, c := range []struct { description string setup func() expectErr error isActive bool }{ { description: "should fail", setup: func() { }, expectErr: ErrInvalidRequest, }, { description: "should pass", setup: func() { f.TokenIntrospectionHandlers = TokenIntrospectionHandlers{validator} httpreq = &http.Request{ Method: "POST", Header: http.Header{ "Authorization": []string{"bearer some-token"}, }, PostForm: url.Values{ "token": []string{"introspect-token"}, }, } validator.EXPECT().IntrospectToken(nil, "some-token", gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) validator.EXPECT().IntrospectToken(nil, "introspect-token", gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("")) }, isActive: false, }, { description: "should pass", setup: func() { f.TokenIntrospectionHandlers = TokenIntrospectionHandlers{validator} httpreq = &http.Request{ Method: "POST", Header: http.Header{ "Authorization": []string{"bearer some-token"}, }, PostForm: url.Values{ "token": []string{"introspect-token"}, }, } validator.EXPECT().IntrospectToken(nil, "some-token", gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) validator.EXPECT().IntrospectToken(nil, "introspect-token", gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) }, isActive: true, }, } { c.setup() res, err := f.NewIntrospectionRequest(nil, httpreq, nil) assert.True(t, errors.Cause(err) == c.expectErr, "(%d) %s\n%s\n%s", k, c.description, err, c.expectErr) if res != nil { assert.Equal(t, c.isActive, res.IsActive()) } t.Logf("Passed test case %d", k) } }
func TestIntrospect(t *testing.T) { ctrl := gomock.NewController(t) validator := internal.NewMockTokenIntrospector(ctrl) defer ctrl.Finish() f := compose.ComposeAllEnabled(new(compose.Config), storage.NewMemoryStore(), []byte{}, nil).(*Fosite) httpreq := &http.Request{ Header: http.Header{ "Authorization": []string{"bearer some-token"}, }, Form: url.Values{}, } for k, c := range []struct { description string scopes []string setup func() expectErr error }{ { description: "should fail", scopes: []string{}, setup: func() { }, expectErr: ErrRequestUnauthorized, }, { description: "should fail", scopes: []string{"foo"}, setup: func() { f.TokenIntrospectionHandlers = TokenIntrospectionHandlers{validator} validator.EXPECT().IntrospectToken(nil, "some-token", gomock.Any(), gomock.Any(), gomock.Any()).Return(ErrUnknownRequest) }, expectErr: ErrRequestUnauthorized, }, { description: "should fail", scopes: []string{"foo"}, setup: func() { validator.EXPECT().IntrospectToken(nil, "some-token", gomock.Any(), gomock.Any(), gomock.Any()).Return(ErrInvalidClient) }, expectErr: ErrInvalidClient, }, { description: "should pass", setup: func() { validator.EXPECT().IntrospectToken(nil, "some-token", gomock.Any(), gomock.Any(), gomock.Any()).Do(func(ctx context.Context, _ string, _ TokenType, accessRequest AccessRequester, _ []string) { accessRequest.(*AccessRequest).GrantedScopes = []string{"bar"} }).Return(nil) }, }, { description: "should pass", scopes: []string{"bar"}, setup: func() { validator.EXPECT().IntrospectToken(nil, "some-token", gomock.Any(), gomock.Any(), gomock.Any()).Do(func(ctx context.Context, _ string, _ TokenType, accessRequest AccessRequester, _ []string) { accessRequest.(*AccessRequest).GrantedScopes = []string{"bar"} }).Return(nil) }, }, } { c.setup() _, err := f.IntrospectToken(nil, AccessTokenFromRequest(httpreq), AccessToken, nil, c.scopes...) 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) } }