ui: Improve dev-time SSO/OIDC visibility (#11248)
This commit tries to make the development experience of working on our OIDC support a little more realistic, essentially by creating our own OIDC provider in our application (only during development builds). You can still provide a real OIDC provider to work with via our dev time environment/cookie variables as before, just now we default to the behaviour in this commit. Overall this makes it much easier to verify our OIDC support in the UI, and also opens up avenues for us to be able to test more scenarios that we couldn't before (for example not only successful logins, but also erroneous, potentially with multiple error reasons).
This commit is contained in:
parent
c059e57f33
commit
569c92c10c
|
@ -19,7 +19,7 @@
|
||||||
{{~/if~}}
|
{{~/if~}}
|
||||||
{{~else~}}
|
{{~else~}}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type={{or @type 'button'}}
|
||||||
{{on 'click' (optional @onclick)}}
|
{{on 'click' (optional @onclick)}}
|
||||||
tabindex={{@tabindex}}
|
tabindex={{@tabindex}}
|
||||||
...attributes
|
...attributes
|
||||||
|
|
|
@ -27,7 +27,7 @@ export default class Outlet extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
setAppRoute(name) {
|
setAppRoute(name) {
|
||||||
if (name !== 'loading') {
|
if (name !== 'loading' || name === 'oidc-provider-debug') {
|
||||||
const doc = this.element.ownerDocument.documentElement;
|
const doc = this.element.ownerDocument.documentElement;
|
||||||
if (doc.classList.contains('ember-loading')) {
|
if (doc.classList.contains('ember-loading')) {
|
||||||
doc.classList.remove('ember-loading');
|
doc.classList.remove('ember-loading');
|
||||||
|
|
|
@ -26,7 +26,7 @@ export default class BaseRoute extends Route {
|
||||||
this.templateName = template;
|
this.templateName = template;
|
||||||
}
|
}
|
||||||
const queryParams = get(routes, `${routeName}._options.queryParams`);
|
const queryParams = get(routes, `${routeName}._options.queryParams`);
|
||||||
if(queryParams && this.routeName === 'dc.partitions.index') {
|
if(queryParams && (this.routeName === 'dc.partitions.index' || this.routeName === 'oauth-provider-debug')) {
|
||||||
this.queryParams = queryParams;
|
this.queryParams = queryParams;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import OAuth2CodeProvider from 'torii/providers/oauth2-code';
|
import OAuth2CodeProvider from 'torii/providers/oauth2-code';
|
||||||
|
import { runInDebug } from '@ember/debug';
|
||||||
|
|
||||||
export default class OAuth2CodeWithURLProvider extends OAuth2CodeProvider {
|
export default class OAuth2CodeWithURLProvider extends OAuth2CodeProvider {
|
||||||
|
|
||||||
name = 'oidc-with-url';
|
name = 'oidc-with-url';
|
||||||
|
@ -16,11 +18,13 @@ export default class OAuth2CodeWithURLProvider extends OAuth2CodeProvider {
|
||||||
.open(url, responseParams, options)
|
.open(url, responseParams, options)
|
||||||
.then(function(authData) {
|
.then(function(authData) {
|
||||||
// the same as the parent class but with an authorizationState added
|
// the same as the parent class but with an authorizationState added
|
||||||
return {
|
const creds = {
|
||||||
authorizationState: authData.state,
|
authorizationState: authData.state,
|
||||||
authorizationCode: decodeURIComponent(authData[responseType]),
|
authorizationCode: decodeURIComponent(authData[responseType]),
|
||||||
provider: name,
|
provider: name,
|
||||||
};
|
};
|
||||||
|
runInDebug(_ => console.log('Retrieved the following creds from the OAuth Provider', creds))
|
||||||
|
return creds;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,8 @@ as |source|>
|
||||||
/>
|
/>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (not-eq route.currentName 'oauth-provider-debug')}}
|
||||||
|
|
||||||
{{! redirect if we aren't on a URL with dc information }}
|
{{! redirect if we aren't on a URL with dc information }}
|
||||||
{{#if (eq route.currentName 'index')}}
|
{{#if (eq route.currentName 'index')}}
|
||||||
{{did-insert (route-action 'replaceWith' 'dc.services.index'
|
{{did-insert (route-action 'replaceWith' 'dc.services.index'
|
||||||
|
@ -156,4 +158,17 @@ as |dc dcs|}}
|
||||||
</DataSource>
|
</DataSource>
|
||||||
{{/let}}
|
{{/let}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
{{else}}
|
||||||
|
{{! Routes with no main navigation }}
|
||||||
|
<Outlet
|
||||||
|
@name="application"
|
||||||
|
@model={{hash
|
||||||
|
user=(hash
|
||||||
|
token=token
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
as |o|>
|
||||||
|
{{outlet}}
|
||||||
|
</Outlet>
|
||||||
|
{{/if}}
|
||||||
</Route>
|
</Route>
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
<Route
|
||||||
|
@name={{routeName}}
|
||||||
|
as |route|>
|
||||||
|
<div
|
||||||
|
style="width: 50%;margin: 0 auto;"
|
||||||
|
>
|
||||||
|
<h1><route.Title @title="Mock OAuth Provider" /></h1>
|
||||||
|
<main>
|
||||||
|
<form
|
||||||
|
method="GET"
|
||||||
|
action={{redirect_uri}}
|
||||||
|
>
|
||||||
|
{{#let (hash
|
||||||
|
state="state-123456789/abcdefghijklmnopqrstuvwxyz"
|
||||||
|
code="code-abcdefghijklmnopqrstuvwxyz/123456789"
|
||||||
|
) as |item|}}
|
||||||
|
<TextInput
|
||||||
|
@name="state"
|
||||||
|
@label="State"
|
||||||
|
@item={{item}}
|
||||||
|
@help="The OIDC state value that will get passed through to Consul"
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
@name="code"
|
||||||
|
@label="Code"
|
||||||
|
@item={{item}}
|
||||||
|
@help="The OIDC code value that will get passed through to Consul"
|
||||||
|
/>
|
||||||
|
{{/let}}
|
||||||
|
<Action
|
||||||
|
@type="submit"
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</Action>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</Route>
|
|
@ -13,6 +13,8 @@ const repositorySHA = utils.repositorySHA;
|
||||||
const binaryVersion = utils.binaryVersion(repositoryRoot);
|
const binaryVersion = utils.binaryVersion(repositoryRoot);
|
||||||
|
|
||||||
module.exports = function(environment, $ = process.env) {
|
module.exports = function(environment, $ = process.env) {
|
||||||
|
// available environments
|
||||||
|
// ['production', 'development', 'staging', 'test'];
|
||||||
const env = utils.env($);
|
const env = utils.env($);
|
||||||
// basic 'get env var with fallback' accessor
|
// basic 'get env var with fallback' accessor
|
||||||
|
|
||||||
|
@ -23,10 +25,9 @@ module.exports = function(environment, $ = process.env) {
|
||||||
locationType: 'fsm-with-optional',
|
locationType: 'fsm-with-optional',
|
||||||
historySupportMiddleware: true,
|
historySupportMiddleware: true,
|
||||||
|
|
||||||
// We use a complete dynamically (from Consul) configured torii provider.
|
torii: {
|
||||||
// We provide this object here to prevent ember from giving a log message
|
disableRedirectInitializer: false
|
||||||
// when starting ember up
|
},
|
||||||
torii: {},
|
|
||||||
|
|
||||||
EmberENV: {
|
EmberENV: {
|
||||||
FEATURES: {
|
FEATURES: {
|
||||||
|
@ -128,8 +129,18 @@ module.exports = function(environment, $ = process.env) {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case environment === 'development':
|
||||||
|
ENV = Object.assign({}, ENV, {
|
||||||
|
torii: {
|
||||||
|
disableRedirectInitializer: true
|
||||||
|
},
|
||||||
|
});
|
||||||
|
break;
|
||||||
case environment === 'staging':
|
case environment === 'staging':
|
||||||
ENV = Object.assign({}, ENV, {
|
ENV = Object.assign({}, ENV, {
|
||||||
|
torii: {
|
||||||
|
disableRedirectInitializer: true
|
||||||
|
},
|
||||||
// On staging sites everything defaults to being turned on by
|
// On staging sites everything defaults to being turned on by
|
||||||
// different staging sites can be built with certain features disabled
|
// different staging sites can be built with certain features disabled
|
||||||
// by setting an environment variable to 0 during building (e.g.
|
// by setting an environment variable to 0 during building (e.g.
|
||||||
|
|
|
@ -149,10 +149,15 @@ module.exports = function(defaults, $ = process.env) {
|
||||||
outputFile: `assets/${item.name}/routes.js`,
|
outputFile: `assets/${item.name}/routes.js`,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
['consul-ui/services'].concat(devlike ? ['consul-ui/services-debug'] : []).forEach(item => {
|
[
|
||||||
app.import(`vendor/${item}.js`, {
|
'consul-ui/services'
|
||||||
outputFile: `assets/${item}.js`,
|
].concat(devlike ? [
|
||||||
});
|
'consul-ui/services-debug',
|
||||||
|
'consul-ui/routes-debug'
|
||||||
|
] : []).forEach(item => {
|
||||||
|
app.import(`vendor/${item}.js`, {
|
||||||
|
outputFile: `assets/${item}.js`,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
// Use `app.import` to add additional libraries to the generated
|
// Use `app.import` to add additional libraries to the generated
|
||||||
// output files.
|
// output files.
|
||||||
|
|
|
@ -46,6 +46,7 @@ ${
|
||||||
environment === 'development' || environment === 'staging'
|
environment === 'development' || environment === 'staging'
|
||||||
? `
|
? `
|
||||||
<script data-app-name="${appName}" data-${appName}-services src="${rootURL}assets/consul-ui/services-debug.js"></script>
|
<script data-app-name="${appName}" data-${appName}-services src="${rootURL}assets/consul-ui/services-debug.js"></script>
|
||||||
|
<script data-app-name="${appName}" data-${appName}-routing src="${rootURL}assets/consul-ui/routes-debug.js"></script>
|
||||||
` : ``}
|
` : ``}
|
||||||
${
|
${
|
||||||
environment === 'production'
|
environment === 'production'
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
{
|
{
|
||||||
"AuthURL": "${env('CONSUL_OIDC_PROVIDER_URL')}&redirect_uri=${encodeURIComponent(http.body.RedirectURI)}&response_type=code&scope=openid"
|
"AuthURL": "${env('CONSUL_OIDC_PROVIDER_URL', 'http://localhost:4200/ui/oauth-provider-debug?client_id=oauth-double&nonce=1&state=123456789abc')}&redirect_uri=${encodeURIComponent(http.body.RedirectURI)}&response_type=code&scope=openid"
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
typeof http.body.Namespace !== 'undefined' ? http.body.Namespace : 'default'
|
typeof http.body.Namespace !== 'undefined' ? http.body.Namespace : 'default'
|
||||||
}",
|
}",
|
||||||
"Local": false,
|
"Local": false,
|
||||||
"Description": "${fake.lorem.sentence()}",
|
"Description": "AuthMethod: ${http.body.AuthMethod}; Code: ${http.body.Code}; State: ${http.body.State}; - ${fake.lorem.sentence()}",
|
||||||
"Policies": [
|
"Policies": [
|
||||||
${
|
${
|
||||||
range(env('CONSUL_POLICY_COUNT', 3)).map(
|
range(env('CONSUL_POLICY_COUNT', 3)).map(
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
(routes => routes({
|
||||||
|
['oauth-provider-debug']: {
|
||||||
|
_options: {
|
||||||
|
path: '/oauth-provider-debug',
|
||||||
|
queryParams: {
|
||||||
|
redirect_uri: 'redirect_uri',
|
||||||
|
response_type: 'response_type',
|
||||||
|
scope: 'scope',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}))(
|
||||||
|
(json, data = document.currentScript.dataset) => {
|
||||||
|
const appNameJS = data.appName.split('-')
|
||||||
|
.map((item, i) => i ? `${item.substr(0, 1).toUpperCase()}${item.substr(1)}` : item)
|
||||||
|
.join('');
|
||||||
|
data[`${appNameJS}Routes`] = JSON.stringify(json);
|
||||||
|
}
|
||||||
|
);
|
Loading…
Reference in New Issue