Skip to content

Commit

Permalink
handler/oauth2: resolve issues with refresh token flow (#110)
Browse files Browse the repository at this point in the history
* handler/oauth2/refresh: requestedAt time is not reset - closes #109
* handler/oauth2/refresh: session is not transported to new access token - closes #108
  • Loading branch information
arekkas authored Oct 6, 2016
1 parent 8c7c77e commit bef6197
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 10 deletions.
16 changes: 13 additions & 3 deletions handler/oauth2/flow_refresh.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,34 @@ func (c *RefreshTokenGrantHandler) HandleTokenEndpointRequest(ctx context.Contex

refresh := req.PostForm.Get("refresh_token")
signature := c.RefreshTokenStrategy.RefreshTokenSignature(refresh)
accessRequest, err := c.RefreshTokenGrantStorage.GetRefreshTokenSession(ctx, signature, nil)
originalRequest, err := c.RefreshTokenGrantStorage.GetRefreshTokenSession(ctx, signature, request.GetSession())
if errors.Cause(err) == fosite.ErrNotFound {
return errors.Wrap(fosite.ErrInvalidRequest, err.Error())
} else if err != nil {
return errors.Wrap(fosite.ErrServerError, err.Error())
}

if !originalRequest.GetGrantedScopes().Has("offline") {
return errors.Wrap(fosite.ErrScopeNotGranted, "The client is not allowed to use grant type refresh_token")

}

// The authorization server MUST ... validate the refresh token.
if err := c.RefreshTokenStrategy.ValidateRefreshToken(ctx, request, refresh); err != nil {
return errors.Wrap(fosite.ErrInvalidRequest, err.Error())
}

// The authorization server MUST ... and ensure that the refresh token was issued to the authenticated client
if accessRequest.GetClient().GetID() != request.GetClient().GetID() {
if originalRequest.GetClient().GetID() != request.GetClient().GetID() {
return errors.Wrap(fosite.ErrInvalidRequest, "Client ID mismatch")
}

request.Merge(accessRequest)
request.SetSession(originalRequest.GetSession())
request.SetRequestedScopes(originalRequest.GetRequestedScopes())
for _, scope := range originalRequest.GetGrantedScopes() {
request.GrantScope(scope)
}

return nil
}

Expand Down
19 changes: 12 additions & 7 deletions handler/oauth2/flow_refresh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) {
{
description: "should fail because validation failed",
setup: func() {
store.EXPECT().GetRefreshTokenSession(nil, "refreshtokensig", nil).Return(&fosite.Request{}, nil)
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,
Expand All @@ -67,7 +69,10 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) {
ID: "foo",
GrantTypes: fosite.Arguments{"refresh_token"},
}
store.EXPECT().GetRefreshTokenSession(nil, "refreshtokensig", nil).Return(&fosite.Request{Client: &fosite.DefaultClient{ID: ""}}, nil)
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,
Expand All @@ -77,19 +82,19 @@ func TestRefreshFlow_HandleTokenEndpointRequest(t *testing.T) {
setup: func() {
store.EXPECT().GetRefreshTokenSession(nil, "refreshtokensig", nil).Return(&fosite.Request{
Client: &fosite.DefaultClient{ID: "foo"},
GrantedScopes: fosite.Arguments{"foo"},
GrantedScopes: fosite.Arguments{"foo", "offline"},
Scopes: fosite.Arguments{"foo", "bar"},
Session: sess,
Form: url.Values{"foo": []string{"bar"}},
RequestedAt: time.Now().Round(time.Hour),
RequestedAt: time.Now().Add(-time.Hour).Round(time.Hour),
}, nil)
},
expect: func() {
assert.Equal(t, sess, areq.Session)
assert.Equal(t, time.Now().Round(time.Hour), areq.RequestedAt)
assert.Equal(t, fosite.Arguments{"foo"}, areq.GrantedScopes)
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.Equal(t, url.Values{"foo": []string{"bar"}}, areq.Form)
assert.NotEqual(t, url.Values{"foo": []string{"bar"}}, areq.Form)
},
},
} {
Expand Down

0 comments on commit bef6197

Please sign in to comment.