Skip to content

Commit

Permalink
Merge pull request #2813 from bpetetot/add-scope-in-restore-of-oauth2…
Browse files Browse the repository at this point in the history
…-password-grant-authenticator

feat: Add scope in restore for OAuth2PasswordGrant
  • Loading branch information
BobrImperator authored Sep 9, 2024
2 parents 1404c50 + c34b039 commit c118fab
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,18 @@ export default BaseAuthenticator.extend({
*/
refreshAccessTokens: true,

/**
Sets whether the authenticator use the scope when refreshing access tokens
if the server supports it.
@memberof OAuth2PasswordGrantAuthenticator
@property refreshAccessTokensWithScope
@type Boolean
@default false
@public
*/
refreshAccessTokensWithScope: false,

/**
The offset time in milliseconds to refresh the access token. This must
return a random number. This randomization is needed because in case of
Expand Down Expand Up @@ -139,7 +151,10 @@ export default BaseAuthenticator.extend({
const refreshAccessTokens = this.get('refreshAccessTokens');
if (!isEmpty(data['expires_at']) && data['expires_at'] < now) {
if (refreshAccessTokens) {
this._refreshAccessToken(data['expires_in'], data['refresh_token']).then(resolve, reject);
this._refreshAccessToken(data['expires_in'], data['refresh_token'], data['scope']).then(
resolve,
reject
);
} else {
reject();
}
Expand Down Expand Up @@ -373,21 +388,30 @@ export default BaseAuthenticator.extend({
}
},

_refreshAccessToken(expiresIn, refreshToken) {
_refreshAccessToken(expiresIn, refreshToken, scope) {
const data = { grant_type: 'refresh_token', refresh_token: refreshToken };
const refreshAccessTokensWithScope = this.get('refreshAccessTokensWithScope');
if (refreshAccessTokensWithScope && !isEmpty(scope)) {
data.scope = scope;
}

const serverTokenEndpoint = this.get('serverTokenEndpoint');
return new RSVP.Promise((resolve, reject) => {
this.makeRequest(serverTokenEndpoint, data).then(
response => {
run(() => {
expiresIn = response['expires_in'] || expiresIn;
refreshToken = response['refresh_token'] || refreshToken;
scope = response['scope'] || scope;
const expiresAt = this._absolutizeExpirationTime(expiresIn);
const data = Object.assign(response, {
expires_in: expiresIn,
expires_at: expiresAt,
refresh_token: refreshToken,
});
if (refreshAccessTokensWithScope && !isEmpty(scope)) {
data.scope = scope;
}
this._scheduleAccessTokenRefresh(expiresIn, null, refreshToken);
this.trigger('sessionDataUpdated', data);
resolve(data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,28 @@ module('OAuth2PasswordGrantAuthenticator', function (hooks) {
});
});
});

module('when refresh access tokens with scope is enabled', function (hooks) {
hooks.beforeEach(function () {
authenticator.set('refreshAccessTokensWithScope', true);
});

test('resolves with the correct data with a scope', async function (assert) {
let data = await authenticator.restore({
access_token: 'secret token!',
expires_in: 12345,
refresh_token: 'refresh token!',
scope: 'scope!',
});

assert.deepEqual(data, {
access_token: 'secret token!',
expires_in: 12345,
refresh_token: 'refresh token!',
scope: 'scope!',
});
});
});
});

module('#authenticate', function () {
Expand Down Expand Up @@ -512,6 +534,49 @@ module('OAuth2PasswordGrantAuthenticator', function (hooks) {
});
});
});

module('when refresh access tokens with scope is enabled', function (hooks) {
hooks.beforeEach(function () {
authenticator.set('refreshAccessTokensWithScope', true);
});

test('sends the scope to the token endpoint', async function (assert) {
assert.expect(1);
server.post('/token', request => {
let { requestBody } = request;
let body = parsePostData(requestBody);

assert.deepEqual(body, {
grant_type: 'refresh_token',
refresh_token: 'refresh token!',
scope: 'scope!',
});

return [200, { 'Content-Type': 'application/json' }, '{}'];
});

await authenticator._refreshAccessToken(12345, 'refresh token!', 'scope!');
});

test('triggers the "sessionDataUpdated" event with the scope', async function (assert) {
assert.expect(1);
server.post('/token', () => [
200,
{ 'Content-Type': 'application/json' },
'{ "access_token": "secret token 2!", "expires_in": 67890, "refresh_token": "refresh token 2!", "scope": "scope!" }',
]);

await new Promise(resolve => {
authenticator.one('sessionDataUpdated', data => {
assert.equal(data.scope, 'scope!');

resolve();
});

authenticator._refreshAccessToken(12345, 'refresh token!', 'scope!');
});
});
});
});
});
});

0 comments on commit c118fab

Please sign in to comment.