100 lines
2.6 KiB
JavaScript
100 lines
2.6 KiB
JavaScript
import BaseAuthenticator from './base';
|
|
import { inject as service } from '@ember/service';
|
|
import { reject } from 'rsvp';
|
|
import fetch from 'fetch';
|
|
|
|
/**
|
|
*
|
|
*/
|
|
export default class OIDCAuthenticator extends BaseAuthenticator {
|
|
|
|
// =services
|
|
|
|
@service session;
|
|
|
|
// =methods
|
|
|
|
/**
|
|
* Generates an auth method URL with which to authenticate.
|
|
* @override
|
|
* @param {object} options
|
|
* @param {string} options.scope.scope_id
|
|
* @param {string} options.authMethod.id
|
|
* @return {string}
|
|
*/
|
|
buildAuthEndpointURL(/* {
|
|
scope: { id: scopeID },
|
|
authMethod: { id: authMethodID },
|
|
} */) { }
|
|
|
|
/**
|
|
* Generates an auth method URL with which to start authentication.
|
|
* @override
|
|
* @param {object} options
|
|
* @param {string} options.scope.scope_id
|
|
* @param {string} options.authMethod.id
|
|
* @return {string}
|
|
*/
|
|
buildStartAuthEndpointURL(/* {
|
|
scope: { id: scopeID },
|
|
authMethod: { id: authMethodID },
|
|
} */) { }
|
|
|
|
/**
|
|
* Kicks-off the OIDC flow: calls the `authenticate:start` action on the
|
|
* specified auth method, which returns some meta data along with an
|
|
* authorization request URL.
|
|
*
|
|
* @param {boolean} requestCookies request cookie tokens (default `true`)
|
|
* @param {object} options
|
|
* @return {Promise}
|
|
*/
|
|
async startAuthentication(requestCookies = true, options) {
|
|
const url = this.buildStartAuthEndpointURL(options);
|
|
const body = JSON.stringify({
|
|
token_type: requestCookies ? 'cookie' : null
|
|
});
|
|
const response = await fetch(url, { method: 'post', body });
|
|
const json = await response.json();
|
|
if (response.status < 400) {
|
|
// Store meta about the pending OIDC flow
|
|
this.session.set('data.pending', {
|
|
oidc: json
|
|
});
|
|
return json;
|
|
} else {
|
|
return reject();
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
async authenticate(json) {
|
|
console.info('Authenticated with OIDC provider');
|
|
return this.normalizeData(json);
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
async attemptOIDCAuthentication(options) {
|
|
const url = this.buildAuthEndpointURL(options);
|
|
const body = JSON.stringify({
|
|
state: this.session.get('data.pending.oidc.state'),
|
|
token_request_id: this.session.get('data.pending.oidc.token_request_id')
|
|
});
|
|
const response = await fetch(url, { method: 'post', body });
|
|
const json = await response.json();
|
|
if (response.status === 100) {
|
|
return false;
|
|
} else if (response.status < 400) {
|
|
// Authentication with OIDC is indirect...
|
|
await this.session.authenticate('authenticator:oidc', json);
|
|
return true;
|
|
} else {
|
|
return reject();
|
|
}
|
|
}
|
|
}
|