Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ember-acmidm-login to v2 #471

Merged
merged 5 commits into from
May 31, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions app/components/acmidm-login-compact.hbs

This file was deleted.

23 changes: 12 additions & 11 deletions app/components/application-header.hbs
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
<AuMainHeader @brandLink="https://www.vlaanderen.be/nl" @homeRoute="index" @appTitle="Gelinkt Notuleren" @contactRoute="contact">
{{#if this.session.isAuthenticated}}
<AuDropdown @title="{{this.currentSession.user.voornaam}} {{this.currentSession.user.achternaam}} - {{this.currentSession.group.classificatie.label}} {{this.currentSession.group.naam}}" @buttonLabel="Account settings" @alignment="right">
<Acmidm::Switch as |acmidm|>
<AuButton @loading={{acmidm.isSwitching}} class="au-c-button au-c-button--tertiary" role="menuitem" {{on "click" acmidm.switch}}>
<AuIcon @icon="switch" @alignment="left" />{{t "application-header.switch-administrative-unit"}}
</AuButton>
</Acmidm::Switch>
<button type="button" class="au-c-button au-c-button--tertiary" role="menuitem" {{on "click" this.logout}}>
<AuIcon @icon="logout" @alignment="left" />{{t "application-header.logout"}}
</button>
<AuLink @route="authorization.switch" @icon="switch" role="menuitem">
{{t "auth.switch-administrative-unit"}}
</AuLink>
<AuLink @route="authorization.logout" @icon="logout" role="menuitem">
{{t "auth.logout"}}
</AuLink>
</AuDropdown>
{{else}}
<AcmidmLoginCompact @styles="au-c-button au-c-button--tertiary">
<AuIcon @icon="login" @alignment="left" />{{t "application-header.logout"}}
</AcmidmLoginCompact>
<AuLink
@route='authorization.login'
@icon="login"
>
{{t "auth.login"}}
</AuLink>
{{/if}}
</AuMainHeader>
1 change: 0 additions & 1 deletion app/components/application-header.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import Component from '@glimmer/component';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';

export default class ApplicationHeaderComponent extends Component {
@service currentSession;
@service session;
Expand Down
8 changes: 7 additions & 1 deletion app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ export default class Router extends EmberRouter {
}

Router.map(function () {
this.route('switch-login');
// this.route('switch-login');
this.route('authorization', function () {
this.route('callback');
this.route('login');
this.route('logout');
this.route('switch');
});
this.route('inbox', function () {
this.route('trash');
this.route('agendapoints', function () {
Expand Down
21 changes: 21 additions & 0 deletions app/routes/authorization/callback.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';

export default class AuthorizationCallbackRoute extends Route {
@service session;

queryParams = {
code: {
refreshModel: true,
},
};

beforeModel() {
// redirect to index if already authenticated
this.session.prohibitAuthentication('index');
}

async model(params) {
this.session.authenticate('authenticator:acm-idm', params.code);
}
}
19 changes: 19 additions & 0 deletions app/routes/authorization/login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import ENV from 'frontend-gelinkt-notuleren/config/environment';
import { buildLoginUrl, isValidAcmidmConfig } from '../../utils/acmidm';

export default class AuthorizationLoginRoute extends Route {
@service router;
@service session;

beforeModel() {
if (this.session.prohibitAuthentication('index')) {
if (isValidAcmidmConfig(ENV.acmidm)) {
window.location.replace(buildLoginUrl(ENV.acmidm));
} else {
this.router.replaceWith('mock-login');
}
}
}
}
29 changes: 29 additions & 0 deletions app/routes/authorization/logout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import ENV from 'frontend-gelinkt-notuleren/config/environment';

export default class AuthorizationLogoutRoute extends Route {
@service router;
@service session;

async beforeModel(transition) {
if (this.session.requireAuthentication(transition, 'login')) {
try {
let wasMockLoginSession = this.session.isMockLoginSession;
await this.session.invalidate();
let logoutUrl = wasMockLoginSession
? this.router.urlFor('mock-login')
: ENV.acmidm.logoutUrl;

window.location.replace(logoutUrl);
} catch (error) {
throw new Error(
'Something went wrong while trying to remove the session on the server',
{
cause: error,
}
);
}
}
}
}
30 changes: 30 additions & 0 deletions app/routes/authorization/switch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import ENV from 'frontend-gelinkt-notuleren/config/environment';
import { buildSwitchUrl } from '../../utils/acmidm';

export default class AuthorizationSwitchRoute extends Route {
@service router;
@service session;

async beforeModel(transition) {
this.session.requireAuthentication(transition, 'login');

try {
let wasMockLoginSession = this.session.isMockLoginSession;
await this.session.invalidate();
let logoutUrl = wasMockLoginSession
? this.router.urlFor('mock-login')
: buildSwitchUrl(ENV.acmidm);

window.location.replace(logoutUrl);
} catch (error) {
throw new Error(
'Something went wrong while trying to remove the session on the server',
{
cause: error,
}
);
}
}
}
15 changes: 4 additions & 11 deletions app/routes/switch-login.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';

//Switch login callback route
export default class SwitchLoginRoute extends Route {
@service session;
@service router;

beforeModel() {
this.session.prohibitAuthentication('index');
}

async model() {
try {
return await this.session.authenticate(
'authenticator:torii',
'acmidm-oauth2'
);
} catch (e) {
return 'Fout bij het aanmelden. Gelieve opnieuw te proberen.';
if (this.session.prohibitAuthentication('index')) {
this.router.replaceWith('authorization.login');
}
}
}
15 changes: 9 additions & 6 deletions app/services/session.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import { inject as service } from '@ember/service';
import BaseSessionService from 'ember-simple-auth/services/session';
import ENV from 'frontend-gelinkt-notuleren/config/environment';

export default class SessionService extends BaseSessionService {
@service currentSession;

handleAuthentication(routeAfterAuthentication) {
get isMockLoginSession() {
return this.isAuthenticated
? this.data.authenticated.authenticator.includes('mock-login')
: false;
}

async handleAuthentication(routeAfterAuthentication) {
await this.currentSession.load();
super.handleAuthentication(routeAfterAuthentication);
this.currentSession.load();
}

handleInvalidation() {
const logoutUrl = ENV['torii']['providers']['acmidm-oauth2']['logoutUrl'];
super.handleInvalidation(logoutUrl);
// We handle invalidation in the routes themselves dependent on whether its a normal, switch or mock-login logout
}
}
4 changes: 3 additions & 1 deletion app/templates/login.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
</AuContent>
</div>
<div class="au-o-grid__item au-u-1-4@small au-u-1-2@medium au-u-text-right@medium">
<AcmidmLogin />
<AuLink @route="authorization.login" @skin="button">
{{t "auth.login"}}
</AuLink>
</div>
</div>
</div>
Expand Down
10 changes: 2 additions & 8 deletions app/templates/meetings/publish.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,8 @@
</Group>
<Group>
<AuDropdown @title="{{this.currentSession.user.voornaam}} {{this.currentSession.user.achternaam}} - {{this.currentSession.group.classificatie.label}} {{this.currentSession.group.naam}}" @buttonLabel="Account settings" @alignment="right">
<Acmidm::Switch as |acmidm|>
<AuButton @loading={{acmidm.isSwitching}} class="au-c-button au-c-button--tertiary" role="menuitem" {{on "click" acmidm.switch}}>
<AuIcon @icon="switch" @alignment="left" />{{t "application-header.switch-administrative-unit"}}
</AuButton>
</Acmidm::Switch>
<button type="button" class="au-c-button au-c-button--tertiary" role="menuitem" {{on "click" this.logout}}>
<AuIcon @icon="logout" @alignment="left" />{{t "application-header.logout"}}
</button>
<AuLink @route="authorization.switch" @icon='switch' role="menuitem">{{t "auth.switch-administrative-unit"}}</AuLink>
<AuLink @route="authorization.logout" @icon='logout' role="menuitem">{{t "auth.logout"}}</AuLink>
</AuDropdown>
</Group>
</AuToolbar>
Expand Down
22 changes: 0 additions & 22 deletions app/templates/switch-login.hbs

This file was deleted.

27 changes: 27 additions & 0 deletions app/utils/acmidm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export function buildLoginUrl({ apiKey, baseUrl, scope, redirectUrl }) {
return (
`${baseUrl}?response_type=code&` +
`client_id=${apiKey}&` +
`redirect_uri=${encodeURIComponent(redirectUrl)}&` +
`scope=${scope}`
);
}

export function buildLogoutUrl({ logoutUrl }) {
return logoutUrl;
}

export function buildSwitchUrl({ apiKey, logoutUrl, switchRedirectUrl }) {
return `${logoutUrl}?switch=true&client_id=${apiKey}&post_logout_redirect_uri=${encodeURIComponent(
switchRedirectUrl
)}`;
}

export function isValidAcmidmConfig(acmidmConfig) {
return Object.values(acmidmConfig).every(
(value) =>
typeof value === 'string' &&
value.trim() !== '' &&
!value.startsWith('{{')
);
}
19 changes: 7 additions & 12 deletions config/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,13 @@ module.exports = function (environment) {
l: 'nl',
shift_page_down: false,
},
torii: {
disableRedirectInitializer: true,
providers: {
'acmidm-oauth2': {
apiKey: '{{OAUTH_API_KEY}}',
baseUrl: '{{OAUTH_BASE_URL}}',
scope: 'openid rrn vo profile abb_gelinktNotuleren',
redirectUri: '{{OAUTH_REDIRECT_URL}}',
logoutUrl: '{{OAUTH_LOGOUT_URL}}',
returnUrl: '{{OAUTH_SWITCH_URL}}',
},
},
acmidm: {
apiKey: '{{OAUTH_API_KEY}}',
baseUrl: '{{OAUTH_BASE_URL}}',
scope: 'openid rrn vo profile abb_gelinktNotuleren',
redirectUrl: '{{OAUTH_REDIRECT_URL}}',
logoutUrl: '{{OAUTH_LOGOUT_URL}}',
switchRedirectUrl: '{{OAUTH_SWITCH_URL}}',
},
environmentName: '{{ENVIRONMENT_NAME}}',
publication: {
Expand Down
Loading