mirror of https://github.com/rancher/dashboard.git
189 lines
4.7 KiB
Vue
189 lines
4.7 KiB
Vue
<script>
|
|
import {
|
|
GITHUB_CODE, GITHUB_NONCE, BACK_TO, IS_SLO, _FLAGGED
|
|
} from '@shell/config/query-params';
|
|
import { get } from '@shell/utils/object';
|
|
import { base64Decode } from '@shell/utils/crypto';
|
|
import loadPlugins from '@shell/plugins/plugin';
|
|
|
|
const samlProviders = ['ping', 'adfs', 'keycloak', 'okta', 'shibboleth'];
|
|
|
|
function reply(err, code) {
|
|
try {
|
|
window.opener.window.onAuthTest(err, code);
|
|
setTimeout(() => {
|
|
window.close();
|
|
}, 250);
|
|
} catch (e) {
|
|
window.close();
|
|
}
|
|
}
|
|
|
|
function isSaml($route) {
|
|
const { query } = $route;
|
|
const configQuery = get(query, 'config');
|
|
|
|
return samlProviders.includes(configQuery);
|
|
}
|
|
|
|
export default {
|
|
async fetch() {
|
|
const code = this.$route.query[GITHUB_CODE];
|
|
const stateStr = this.$route.query[GITHUB_NONCE];
|
|
const {
|
|
error, error_description: errorDescription, errorCode, errorMsg
|
|
} = this.$route.query;
|
|
|
|
if (error || errorDescription || errorCode || errorMsg) {
|
|
let out = errorDescription || error || errorCode;
|
|
|
|
if (this.isSlo) {
|
|
console.error('Failed to log out of auth provider', error, errorDescription, errorCode, errorMsg); // eslint-disable-line no-console
|
|
|
|
let out = this.$store.getters['i18n/withFallback'](`logout.specificError.unknown`);
|
|
|
|
if (errorCode) {
|
|
out = this.$store.getters['i18n/withFallback'](`logout.specificError.${ errorCode }`, null, out);
|
|
}
|
|
|
|
this.$router.replace(`/auth/login?${ IS_SLO }&err=${ escape(out) }`);
|
|
|
|
return;
|
|
} else {
|
|
if (errorMsg) {
|
|
out = this.$store.getters['i18n/withFallback'](`login.serverError.${ errorMsg }`, null, errorMsg);
|
|
}
|
|
|
|
this.$router.replace(`/auth/login?err=${ escape(out) }`);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
// check for existence of IS_SLO query param to differentiate between a login and a logout
|
|
if (this.isSlo) {
|
|
this.$store.dispatch('auth/uiLogout');
|
|
|
|
return;
|
|
}
|
|
|
|
let parsed;
|
|
|
|
try {
|
|
parsed = JSON.parse(base64Decode((stateStr)));
|
|
} catch (err) {
|
|
if (isSaml(this.$route)) {
|
|
// This is an ok failure. SAML has no state string so a failure is fine (see similar check in mounted).
|
|
// This whole file could be re-written with that in mind, but this change keeps things simple and fixes a breaking addition
|
|
return;
|
|
}
|
|
const out = this.$store.getters['i18n/t'](`login.error`);
|
|
|
|
console.error('Failed to parse nonce', stateStr, err); // eslint-disable-line no-console
|
|
|
|
this.$router.replace(`/auth/login?err=${ escape(out) }`);
|
|
|
|
return;
|
|
}
|
|
|
|
const { test, provider, nonce } = parsed;
|
|
|
|
if (test) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const res = await this.$store.dispatch('auth/verifyOAuth', {
|
|
code,
|
|
nonce,
|
|
provider
|
|
});
|
|
|
|
if ( res._status === 200) {
|
|
const backTo = this.$route.query[BACK_TO] || '/';
|
|
|
|
// Load plugins
|
|
await loadPlugins({
|
|
app: this.$store.app,
|
|
store: this.$store,
|
|
$plugin: this.$store.$plugin
|
|
});
|
|
|
|
this.$router.replace(backTo);
|
|
} else {
|
|
this.$router.replace(`/auth/login?err=${ escape(res) }`);
|
|
}
|
|
} catch (err) {
|
|
this.$router.replace(`/auth/login?err=${ escape(err) }`);
|
|
}
|
|
},
|
|
|
|
data() {
|
|
const stateJSON = this.$route.query[GITHUB_NONCE] || '';
|
|
|
|
let parsed = {};
|
|
|
|
try {
|
|
parsed = JSON.parse(base64Decode(stateJSON));
|
|
} catch {
|
|
}
|
|
|
|
const { test } = parsed;
|
|
|
|
// Is Single Log Out
|
|
const isSlo = this.$route.query[IS_SLO] === _FLAGGED;
|
|
|
|
return {
|
|
testing: test,
|
|
isSlo
|
|
};
|
|
},
|
|
|
|
mounted() {
|
|
if ( this.testing ) {
|
|
try {
|
|
const {
|
|
error: respError, error_description: respErrorDescription, [GITHUB_CODE]: code, errorMsg
|
|
} = this.$route.query;
|
|
|
|
let error = respErrorDescription || respError || (!code ? 'No code supplied by auth provider' : null);
|
|
|
|
if (errorMsg) {
|
|
error = this.$store.getters['i18n/withFallback'](`login.serverError.${ errorMsg }`, null, errorMsg);
|
|
}
|
|
|
|
reply(error, code );
|
|
} catch (e) {
|
|
window.close();
|
|
}
|
|
} else {
|
|
if ( window.opener ) {
|
|
if (isSaml(this.$route)) {
|
|
if ( window.opener.window.onAuthTest ) {
|
|
reply(null, null);
|
|
} else {
|
|
reply({ err: 'failure' });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<main class="main-layout">
|
|
<h1 class="text-center mt-50">
|
|
<span v-if="testing">
|
|
Testing Configuration…
|
|
</span>
|
|
<span v-else-if="isSlo">
|
|
Logging Out…
|
|
</span>
|
|
<span v-else>
|
|
Logging In…
|
|
</span>
|
|
</h1>
|
|
</main>
|
|
</template>
|