Skip to content

Commit

Permalink
UI/OIDC provider fix (#12871)
Browse files Browse the repository at this point in the history
* Add cluster name to oidc-provider path

* Move oidc-provider route up on router

* Return base url for changelog if no version

* OIDC Provider check on targetRouteName instead of transitionToTargetRoute

* restore dynamic provider segment on route

* Fix redirect after auth issue

* handle permission denied
  • Loading branch information
hashishaw committed Oct 20, 2021
1 parent 51f167c commit 180a24a
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 20 deletions.
6 changes: 3 additions & 3 deletions ui/app/mixins/cluster-route.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ export default Mixin.create({

transitionToTargetRoute(transition = {}) {
const targetRoute = this.targetRouteName(transition);
if (OIDC_PROVIDER === this.router.currentRouteName || OIDC_PROVIDER === transition?.to?.name) {
return RSVP.resolve();
}
if (
targetRoute &&
targetRoute !== this.routeName &&
Expand Down Expand Up @@ -83,6 +80,9 @@ export default Mixin.create({

return DR_REPLICATION_SECONDARY;
}
if ((transition && transition.targetName === OIDC_PROVIDER) || this.routeName === OIDC_PROVIDER) {
return OIDC_PROVIDER;
}
if (!isAuthed) {
if ((transition && transition.targetName === OIDC_CALLBACK) || this.routeName === OIDC_CALLBACK) {
return OIDC_CALLBACK;
Expand Down
7 changes: 3 additions & 4 deletions ui/app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export default class Router extends EmberRouter {
Router.map(function() {
this.route('vault', { path: '/' }, function() {
this.route('cluster', { path: '/:cluster_name' }, function() {
this.route('identity', function() {
this.route('oidc-provider', { path: '/oidc/provider/:provider_name/authorize' });
});
this.route('oidc-callback', { path: '/auth/*auth_path/oidc/callback' });
this.route('auth');
this.route('init');
Expand Down Expand Up @@ -139,10 +142,6 @@ Router.map(function() {
}

this.route('not-found', { path: '/*path' });

this.route('identity', function() {
this.route('oidc-provider', { path: '/oidc/provider/:oidc_name/authorize' });
});
});
this.route('not-found', { path: '/*path' });
});
Expand Down
32 changes: 20 additions & 12 deletions ui/app/routes/vault/cluster/identity/oidc-provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export default class VaultClusterIdentityOidcProviderRoute extends Route {
}

_redirect(url, params) {
if (!url) return;
let redir = this._buildUrl(url, params);
this.win.location.replace(redir);
}
Expand All @@ -27,23 +28,27 @@ export default class VaultClusterIdentityOidcProviderRoute extends Route {
error: 'login_required',
});
} else if (!currentToken || 'login' === qp.prompt?.toLowerCase()) {
let shouldLogout = !!currentToken;
if ('login' === qp.prompt?.toLowerCase()) {
this.auth.deleteCurrentToken();
// need to remove before redirect to avoid infinite loop
qp.prompt = null;
}
let { cluster_name } = this.paramsFor('vault.cluster');
let url = this.router.urlFor(transition.to.name, transition.to.params, { queryParams: qp });
return this.transitionTo(AUTH, cluster_name, { queryParams: { redirect_to: url } });
return this._redirectToAuth(transition.to.params?.provider_name, qp, shouldLogout);
}
}

_redirectToAuth(oidcName, queryParams, logout = false) {
_redirectToAuth(provider_name, queryParams, logout = false) {
let { cluster_name } = this.paramsFor('vault.cluster');
let currentRoute = this.router.urlFor(PROVIDER, oidcName, { queryParams });
let url = this.router.urlFor(PROVIDER, cluster_name, provider_name, { queryParams });
// This is terrible, I'm sorry
// Need to do this because transitionTo (as used in auth-form) expects url without
// rootURL /ui/ at the beginning, but urlFor builds it in. We can't use currentRoute
// because it hasn't transitioned yet
url = url.replace(/^(\/?ui)/, '');
if (logout) {
this.auth.deleteCurrentToken();
}
return this.transitionTo(AUTH, cluster_name, { queryParams: { redirect_to: currentRoute } });
return this.transitionTo(AUTH, cluster_name, { queryParams: { redirect_to: url } });
}

_buildUrl(urlString, params) {
Expand Down Expand Up @@ -72,11 +77,14 @@ export default class VaultClusterIdentityOidcProviderRoute extends Route {
}

async model(params) {
let { oidc_name, ...qp } = params;
let { provider_name, ...qp } = params;
let decodedRedirect = decodeURI(qp.redirect_uri);
let url = this._buildUrl(`${this.win.origin}/v1/identity/oidc/provider/${oidc_name}/authorize`, qp);
let endpoint = this._buildUrl(
`${this.win.origin}/v1/identity/oidc/provider/${provider_name}/authorize`,
qp
);
try {
const response = await this.auth.ajax(url, 'GET', {});
const response = await this.auth.ajax(endpoint, 'GET', {});
if ('consent' === qp.prompt?.toLowerCase()) {
return {
consent: {
Expand All @@ -90,8 +98,8 @@ export default class VaultClusterIdentityOidcProviderRoute extends Route {
} catch (errorRes) {
let resp = await errorRes.json();
let code = resp.error;
if (code === 'max_age_violation') {
this._redirectToAuth(oidc_name, qp, true);
if (code === 'max_age_violation' || resp?.errors?.includes('permission denied')) {
this._redirectToAuth(provider_name, qp, true);
} else if (code === 'invalid_redirect_uri') {
return {
error: {
Expand Down
2 changes: 1 addition & 1 deletion ui/lib/core/addon/helpers/changelog-url-for.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ etc.

export function changelogUrlFor([version]) {
let url = 'https://www.github.com/hashicorp/vault/blob/main/CHANGELOG.md#';

if (!version) return url;
try {
// strip the '+prem' from enterprise versions and remove periods
let versionNumber = version
Expand Down

0 comments on commit 180a24a

Please sign in to comment.