Skip to content

Commit

Permalink
test: add integration test
Browse files Browse the repository at this point in the history
  • Loading branch information
james-d-elliott authored and aeneasr committed Mar 6, 2023
1 parent c0b1a80 commit 3c8dd1b
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 9 deletions.
24 changes: 15 additions & 9 deletions integration/helper_endpoints_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,22 @@ func authEndpointHandler(t *testing.T, oauth2 fosite.OAuth2Provider, session fos
return
}

if ar.GetRequestedScopes().Has("fosite") {
ar.GrantScope("fosite")
}
if ar.GetClient().GetID() == "grant-all-requested-scopes-client" {
for _, scope := range ar.GetRequestedScopes() {
ar.GrantScope(scope)
}
} else {
if ar.GetRequestedScopes().Has("fosite") {
ar.GrantScope("fosite")
}

if ar.GetRequestedScopes().Has("offline") {
ar.GrantScope("offline")
}
if ar.GetRequestedScopes().Has("offline") {
ar.GrantScope("offline")
}

if ar.GetRequestedScopes().Has("openid") {
ar.GrantScope("openid")
if ar.GetRequestedScopes().Has("openid") {
ar.GrantScope("openid")
}
}

for _, a := range ar.GetRequestedAudience() {
Expand Down Expand Up @@ -134,7 +140,7 @@ func tokenEndpointHandler(t *testing.T, provider fosite.OAuth2Provider) func(rw

accessRequest, err := provider.NewAccessRequest(ctx, req, &oauth2.JWTSession{})
if err != nil {
t.Logf("Access request failed because: %+v", err)
t.Logf("Access request failed because: %+v", fosite.ErrorToRFC6749Error(err).WithExposeDebug(true).GetDescription())
t.Logf("Request: %+v", accessRequest)
provider.WriteAccessError(req.Context(), rw, accessRequest, err)
return
Expand Down
89 changes: 89 additions & 0 deletions integration/refresh_token_grant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,92 @@ func TestRefreshTokenFlow(t *testing.T) {
})
}
}

func TestRefreshTokenFlowScopeNarrowing(t *testing.T) {
session := &defaultSession{
DefaultSession: &openid.DefaultSession{
Claims: &jwt.IDTokenClaims{
Subject: "peter",
},
Headers: &jwt.Headers{},
Subject: "peter",
Username: "peteru",
},
}
fc := new(fosite.Config)
fc.RefreshTokenLifespan = -1
fc.GlobalSecret = []byte("some-secret-thats-random-some-secret-thats-random-")
f := compose.ComposeAllEnabled(fc, fositeStore, gen.MustRSAKey())
ts := mockServer(t, f, session)
defer ts.Close()

fc.ScopeStrategy = fosite.ExactScopeStrategy

oauthClient := newOAuth2Client(ts)
oauthClient.Scopes = []string{"openid", "offline", "offline_access", "foo", "bar"}
oauthClient.ClientID = "grant-all-requested-scopes-client"

state := "1234567890"

testRefreshingClient := &fosite.DefaultClient{
ID: "grant-all-requested-scopes-client",
Secret: []byte(`$2a$10$IxMdI6d.LIRZPpSfEwNoeu4rY3FhDREsxFJXikcgdRRAStxUlsuEO`), // = "foobar"
RedirectURIs: []string{ts.URL + "/callback"},
ResponseTypes: []string{"code"},
GrantTypes: []string{"implicit", "refresh_token", "authorization_code", "password", "client_credentials"},
Scopes: []string{"openid", "offline_access", "offline", "foo", "bar", "baz"},
Audience: []string{"https://www.ory.sh/api"},
}

fositeStore.Clients["grant-all-requested-scopes-client"] = testRefreshingClient

resp, err := http.Get(oauthClient.AuthCodeURL(state))
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode)

token, err := oauthClient.Exchange(oauth2.NoContext, resp.Request.URL.Query().Get("code"), oauth2.SetAuthURLParam("client_id", oauthClient.ClientID))
require.NoError(t, err)
require.NotEmpty(t, token.AccessToken)
require.NotEmpty(t, token.RefreshToken)

assert.Equal(t, "openid offline offline_access foo bar", token.Extra("scope"))

token1Refresh, err := doRefresh(oauthClient, token, nil)
require.NoError(t, err)
require.NotEmpty(t, token1Refresh.AccessToken)
require.NotEmpty(t, token1Refresh.RefreshToken)

assert.Equal(t, "openid offline offline_access foo bar", token1Refresh.Extra("scope"))

token2Refresh, err := doRefresh(oauthClient, token1Refresh, []string{"openid", "offline_access", "foo"})
require.NoError(t, err)
require.NotEmpty(t, token2Refresh.AccessToken)
require.NotEmpty(t, token2Refresh.RefreshToken)

assert.Equal(t, "openid offline_access foo", token2Refresh.Extra("scope"))

token3Refresh, err := doRefresh(oauthClient, token2Refresh, []string{"openid", "offline", "offline_access", "foo", "bar"})
require.NoError(t, err)
require.NotEmpty(t, token3Refresh.AccessToken)
require.NotEmpty(t, token3Refresh.RefreshToken)

assert.Equal(t, "openid offline offline_access foo bar", token3Refresh.Extra("scope"))

token4Refresh, err := doRefresh(oauthClient, token3Refresh, []string{"openid", "offline", "offline_access", "foo", "bar", "baz"})
require.Error(t, err)
require.Nil(t, token4Refresh)
require.Contains(t, err.Error(), "The requested scope is invalid, unknown, or malformed. The requested scope 'baz' was not originally granted by the resource owner.")
}

func doRefresh(client *oauth2.Config, t *oauth2.Token, scopes []string) (token *oauth2.Token, err error) {
opts := []oauth2.AuthCodeOption{
oauth2.SetAuthURLParam("refresh_token", t.RefreshToken),
oauth2.SetAuthURLParam("grant_type", "refresh_token"),
}

if len(scopes) != 0 {
opts = append(opts, oauth2.SetAuthURLParam("scope", strings.Join(scopes, " ")), oauth2.SetAuthURLParam("client_id", client.ClientID))
}

return client.Exchange(oauth2.NoContext, "", opts...)
}

0 comments on commit 3c8dd1b

Please sign in to comment.