Skip to content

Commit

Permalink
handler/openid: only refresh id token with id_token response type
Browse files Browse the repository at this point in the history
Closes #199
  • Loading branch information
arekkas authored and arekkas committed Jul 9, 2017
1 parent 63f329b commit dd2463a
Show file tree
Hide file tree
Showing 2 changed files with 182 additions and 1 deletion.
17 changes: 16 additions & 1 deletion handler/openid/flow_refresh_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package openid

import (
"context"

"time"

"github.com/ory/fosite"
Expand All @@ -22,6 +21,14 @@ func (c *OpenIDConnectRefreshHandler) HandleTokenEndpointRequest(ctx context.Con
return errors.WithStack(fosite.ErrUnknownRequest)
}

if !request.GetClient().GetGrantTypes().Has("refresh_token") {
return errors.Wrap(fosite.ErrInvalidGrant, "The client is not allowed to use the authorization_code grant type")
}

if !request.GetClient().GetResponseTypes().Has("id_token") {
return errors.Wrap(fosite.ErrUnknownRequest, "The client is not allowed to use response type id_token")
}

sess, ok := request.GetSession().(Session)
if !ok {
return errors.New("Failed to generate id token because session must be of type fosite/handler/openid.Session")
Expand All @@ -41,5 +48,13 @@ func (c *OpenIDConnectRefreshHandler) PopulateTokenEndpointResponse(ctx context.
return errors.WithStack(fosite.ErrUnknownRequest)
}

if !requester.GetClient().GetGrantTypes().Has("refresh_token") {
return errors.Wrap(fosite.ErrInvalidGrant, "The client is not allowed to use the authorization_code grant type")
}

if !requester.GetClient().GetResponseTypes().Has("id_token") {
return errors.Wrap(errors.WithStack(fosite.ErrUnknownRequest), "The client is not allowed to use response type id_token")
}

return c.IssueExplicitIDToken(ctx, requester, responder)
}
166 changes: 166 additions & 0 deletions handler/openid/flow_refresh_token_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package openid

import (
"testing"

"github.com/ory/fosite"
"github.com/ory/fosite/token/jwt"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestOpenIDConnectRefreshHandler_HandleTokenEndpointRequest(t *testing.T) {
h := &OpenIDConnectRefreshHandler{}
for _, c := range []struct {
areq *fosite.AccessRequest
expectedErr error
description string
}{
{
description: "should not pass because grant_type is wrong",
areq: &fosite.AccessRequest{
GrantTypes: []string{"foo"},
},
expectedErr: fosite.ErrUnknownRequest,
},
{
description: "should not pass because grant_type is right but scope is missing",
areq: &fosite.AccessRequest{
GrantTypes: []string{"refresh_token"},
Request: fosite.Request{
GrantedScopes: []string{"something"},
},
},
expectedErr: fosite.ErrUnknownRequest,
},
{
description: "should not pass because client may not execute this grant type",
areq: &fosite.AccessRequest{
GrantTypes: []string{"refresh_token"},
Request: fosite.Request{
GrantedScopes: []string{"openid"},
Client: &fosite.DefaultClient{},
},
},
expectedErr: fosite.ErrInvalidGrant,
},
{
description: "should not pass because client may not ask for id_token",
areq: &fosite.AccessRequest{
GrantTypes: []string{"refresh_token"},
Request: fosite.Request{
GrantedScopes: []string{"openid"},
Client: &fosite.DefaultClient{
GrantTypes: []string{"refresh_token"},
},
},
},
expectedErr: fosite.ErrUnknownRequest,
},
{
description: "should pass",
areq: &fosite.AccessRequest{
GrantTypes: []string{"refresh_token"},
Request: fosite.Request{
GrantedScopes: []string{"openid"},
Client: &fosite.DefaultClient{
GrantTypes: []string{"refresh_token"},
ResponseTypes: []string{"id_token"},
},
Session: &DefaultSession{},
},
},
},
} {
t.Run("case="+c.description, func(t *testing.T) {
err := h.HandleTokenEndpointRequest(nil, c.areq)
if c.expectedErr != nil {
require.EqualError(t, errors.Cause(err), c.expectedErr.Error(), "%v", err)
} else {
require.NoError(t, err)
}
})
}
}

func TestOpenIDConnectRefreshHandler_PopulateTokenEndpointResponse(t *testing.T) {
h := &OpenIDConnectRefreshHandler{
IDTokenHandleHelper: &IDTokenHandleHelper{
IDTokenStrategy: j,
},
}
for _, c := range []struct {
areq *fosite.AccessRequest
expectedErr error
check func(t *testing.T, aresp *fosite.AccessResponse)
description string
}{
{
description: "should not pass because grant_type is wrong",
areq: &fosite.AccessRequest{
GrantTypes: []string{"foo"},
},
expectedErr: fosite.ErrUnknownRequest,
},
{
description: "should not pass because grant_type is right but scope is missing",
areq: &fosite.AccessRequest{
GrantTypes: []string{"refresh_token"},
Request: fosite.Request{
GrantedScopes: []string{"something"},
},
},
expectedErr: fosite.ErrUnknownRequest,
},
{
description: "should not pass because client may not ask for id_token",
areq: &fosite.AccessRequest{
GrantTypes: []string{"refresh_token"},
Request: fosite.Request{
GrantedScopes: []string{"openid"},
Client: &fosite.DefaultClient{
GrantTypes: []string{"refresh_token"},
},
},
},
expectedErr: fosite.ErrUnknownRequest,
},
{
description: "should pass",
areq: &fosite.AccessRequest{
GrantTypes: []string{"refresh_token"},
Request: fosite.Request{
GrantedScopes: []string{"openid"},
Client: &fosite.DefaultClient{
GrantTypes: []string{"refresh_token"},
ResponseTypes: []string{"id_token"},
},
Session: &DefaultSession{
Subject: "foo",
Claims: &jwt.IDTokenClaims{
Subject: "foo",
},
},
},
},
check: func(t *testing.T, aresp *fosite.AccessResponse) {
assert.NotEmpty(t, aresp.GetExtra("id_token"))
},
},
} {
t.Run("case="+c.description, func(t *testing.T) {
aresp := fosite.NewAccessResponse()
err := h.PopulateTokenEndpointResponse(nil, c.areq, aresp)
if c.expectedErr != nil {
require.EqualError(t, errors.Cause(err), c.expectedErr.Error(), "%v", err)
} else {
require.NoError(t, err)
}

if c.check != nil {
c.check(t, aresp)
}
})
}
}

0 comments on commit dd2463a

Please sign in to comment.