Fixes requests from review

This commit is contained in:
Eric Tokatlian 2019-07-03 13:34:58 -07:00
parent dfac8fb538
commit 0670441dbc
15 changed files with 239 additions and 155 deletions

View File

@ -79,10 +79,10 @@ const App = Application.extend({
'digitalOcean', 'digitalOcean',
'endpoint', 'endpoint',
'github', 'github',
'google',
'globalStore', 'globalStore',
'intl', 'intl',
'modal', 'modal',
'oauth',
'resource-actions', 'resource-actions',
'router', 'router',
'scope', 'scope',

View File

@ -11,8 +11,7 @@ const samlProviders = ['ping', 'adfs', 'keycloak', 'okta'];
const allowedForwards = ['localhost']; const allowedForwards = ['localhost'];
export default Route.extend(VerifyAuth, { export default Route.extend(VerifyAuth, {
github: service(), oauth: service(),
google: service(),
intl: service(), intl: service(),
language: service('user-language'), language: service('user-language'),
@ -23,8 +22,7 @@ export default Route.extend(VerifyAuth, {
}, },
model(params/* , transition */) { model(params/* , transition */) {
const github = get(this, 'github'); const oauth = get(this, 'oauth');
const google = get(this, 'google');
const code = get(params, 'code'); const code = get(params, 'code');
const forward = get(params, 'forward'); const forward = get(params, 'forward');
@ -41,7 +39,7 @@ export default Route.extend(VerifyAuth, {
code code
}); });
} else { } else {
github.login(forward); oauth.login(forward);
} }
} else { } else {
return reject(new Error('Invalid forward url')); return reject(new Error('Invalid forward url'));
@ -51,28 +49,21 @@ export default Route.extend(VerifyAuth, {
} }
if ( window.opener && !get(params, 'login') && !get(params, 'errorCode') ) { if ( window.opener && !get(params, 'login') && !get(params, 'errorCode') ) {
let openersGithub = window.opener.ls('github'); let openersOauth = window.opener.ls('oauth');
let openersGoogle = window.opener.ls('google');
let openerStore = window.opener.ls('globalStore'); let openerStore = window.opener.ls('globalStore');
let qp = get(params, 'config') || get(params, 'authProvider'); let qp = get(params, 'config') || get(params, 'authProvider');
let type = `${ qp }Config`; let type = `${ qp }Config`;
let config = openerStore.getById(type, qp); let config = openerStore.getById(type, qp);
let gh = get(this, 'github');
let go = get(this, 'google');
let stateMsg = 'Authorization state did not match, please try again.'; let stateMsg = 'Authorization state did not match, please try again.';
let isGithub = get(params, 'config') === 'github'
let isGoogle = get(params, 'config') === 'googleoauth'
if ( get(params, 'config') === 'github' ) { if ( isGithub || isGoogle ) {
return gh.testConfig(config).then((resp) => { return oauth.testConfig(config).then((resp) => {
gh.authorize(resp, openersGithub.get('state')); oauth.authorize(resp, openersOauth.get('state'));
}).catch((err) => { }).catch((err) => {
this.send('gotError', err); this.send('gotError', err);
}); });
} else if ( get(params, 'config') === 'googleoauth') {
return go.testConfig(config).then((resp) => {
go.authorize(resp, openersGoogle.get('state'));
}).catch((err) => {
this.send('gotError', err)
})
} else if ( samlProviders.includes(get(params, 'config')) ) { } else if ( samlProviders.includes(get(params, 'config')) ) {
if ( window.opener.window.onAuthTest ) { if ( window.opener.window.onAuthTest ) {
reply(null, config); reply(null, config);
@ -82,9 +73,7 @@ export default Route.extend(VerifyAuth, {
} }
if ( get(params, 'code') ) { if ( get(params, 'code') ) {
const currentOpener = openersGithub.state ? openersGithub : openersGoogle; if ( openersOauth.stateMatches(get(params, 'state')) ) {
if ( currentOpener.stateMatches(get(params, 'state')) ) {
reply(params.error_description, params.code); reply(params.error_description, params.code);
} else { } else {
reply(stateMsg); reply(stateMsg);
@ -99,11 +88,11 @@ export default Route.extend(VerifyAuth, {
} }
} }
if ( code && get(params, 'login') || get(params, 'state').includes('login') ) { if ( code && get(params, 'state').includes('login') ) {
let currentProvider = github.stateMatches(get(params, 'state')) ? 'github' : 'googleoauth' const providerType = get(params, 'state').includes('github') ? 'github' : 'googleoauth'
if ( github.stateMatches(get(params, 'state')) || google.stateMatches(get(params, 'state')) ) { if ( oauth.stateMatches(get(params, 'state')) ) {
currentProvider = get(this, 'access.providers').findBy('id', currentProvider); const currentProvider = get(this, 'access.providers').findBy('id', providerType);
return currentProvider.doAction('login', { return currentProvider.doAction('login', {
code, code,

View File

@ -18,10 +18,10 @@ const Eng = Engine.extend({
'digitalOcean', 'digitalOcean',
'endpoint', 'endpoint',
'github', 'github',
'google',
'globalStore', 'globalStore',
'intl', 'intl',
'modal', 'modal',
'oauth',
'resource-actions', 'resource-actions',
'router', 'router',
'scope', 'scope',

View File

@ -9,7 +9,7 @@ import C from 'ui/utils/constants';
import AuthMixin from 'global-admin/mixins/authentication'; import AuthMixin from 'global-admin/mixins/authentication';
export default Controller.extend(AuthMixin, { export default Controller.extend(AuthMixin, {
github: service(), oauth: service(),
endpoint: service(), endpoint: service(),
access: service(), access: service(),
settings: service(), settings: service(),
@ -58,7 +58,7 @@ export default Controller.extend(AuthMixin, {
'allowedPrincipalIds': [], 'allowedPrincipalIds': [],
}); });
setProperties(get(this, 'github'), { setProperties(get(this, 'oauth'), {
hostname: authConfig.get('hostname'), hostname: authConfig.get('hostname'),
scheme: authConfig.get('scheme'), scheme: authConfig.get('scheme'),
clientId: authConfig.get('clientId') clientId: authConfig.get('clientId')
@ -66,7 +66,7 @@ export default Controller.extend(AuthMixin, {
set(this, '_boundSucceed', this.authenticationApplied.bind(this)); set(this, '_boundSucceed', this.authenticationApplied.bind(this));
get(this, 'github').test(authConfig, get(this, '_boundSucceed')); get(this, 'oauth').test(authConfig, get(this, '_boundSucceed'));
}, },
}, },
enterpriseDidChange: observer('isEnterprise', 'authConfig.hostname', 'secure', function() { enterpriseDidChange: observer('isEnterprise', 'authConfig.hostname', 'secure', function() {

View File

@ -5,7 +5,7 @@ import Controller from '@ember/controller';
import AuthMixin from 'global-admin/mixins/authentication'; import AuthMixin from 'global-admin/mixins/authentication';
export default Controller.extend(AuthMixin, { export default Controller.extend(AuthMixin, {
google: service(), oauth: service(),
endpoint: service(), endpoint: service(),
access: service(), access: service(),
settings: service(), settings: service(),
@ -44,7 +44,7 @@ export default Controller.extend(AuthMixin, {
}); });
set(this, '_boundSucceed', this.authenticationApplied.bind(this)); set(this, '_boundSucceed', this.authenticationApplied.bind(this));
get(this, 'google').test(authConfig, get(this, '_boundSucceed')); get(this, 'oauth').test(authConfig, get(this, '_boundSucceed'));
}, },
}, },

View File

@ -1,11 +1,10 @@
<section> <section>
{{#unless isEnabled}} {{#unless isEnabled}}
<div class="banner bg-warning"> <BannerMessage
<div class="banner-icon"><span class="icon icon-alert"></span></div> @color='bg-warning'
<div class="banner-message"> @icon='icon-alert'
<p>{{t 'authPage.google.header.disabled.label'}}</p> @message={{t 'authPage.google.header.disabled.label'}}
</div> />
</div>
{{/unless}} {{/unless}}
{{top-errors errors=errors}} {{top-errors errors=errors}}
</section> </section>
@ -21,21 +20,21 @@
showExpand=false showExpand=false
title=(t 'authPage.google.authenticated.header.text') title=(t 'authPage.google.authenticated.header.text')
}} }}
<section class=""> <section class=''>
<div class="clearfix"> <div class='clearfix'>
<div class="pull-right"> <div class='pull-right'>
<button class="btn btn-sm right-divider-btn bg-error" {{action "disable"}}> <button class='btn btn-sm right-divider-btn bg-error' {{action 'disable'}}>
{{t 'authPage.google.authenticated.disableAccess.disable'}} {{t 'authPage.google.authenticated.disableAccess.disable'}}
</button> </button>
</div> </div>
</div> </div>
<hr /> <hr />
<div><b>{{t 'authPage.google.authenticated.header.adminEmail.text'}} </b> <span class="text-muted">{{authConfig.adminEmail}}</span></div> <div><b>{{t 'authPage.google.authenticated.header.adminEmail.text'}} </b> <span class='text-muted'>{{authConfig.adminEmail}}</span></div>
</section> </section>
{{/accordion-list-item}} {{/accordion-list-item}}
{{#accordion-list-item {{#accordion-list-item
classNames="mt-30" classNames='mt-30'
detail=(t 'siteAccess.helpText' appName=settings.appName htmlSafe=true) detail=(t 'siteAccess.helpText' appName=settings.appName htmlSafe=true)
expand=(action expandFn) expand=(action expandFn)
expandAll=al.expandAll expandAll=al.expandAll
@ -61,9 +60,9 @@
showExpand=false showExpand=false
title=(t 'authPage.google.notAuthenticated.header') title=(t 'authPage.google.notAuthenticated.header')
}} }}
<section class=""> <section class=''>
<p> <p>
<ol class="alphalist ml-40"> <ol class='alphalist ml-40'>
<li> <li>
{{t 'authPage.google.notAuthenticated.ul.li1.text' htmlSafe=true}} {{t 'authPage.google.notAuthenticated.ul.li1.text' htmlSafe=true}}
<ul> <ul>
@ -74,10 +73,25 @@
{{t 'authPage.google.notAuthenticated.ul.li2.text'}} {{t 'authPage.google.notAuthenticated.ul.li2.text'}}
<ul> <ul>
<li>{{t 'authPage.google.notAuthenticated.ul.li2.ul.li1' appName=settings.appName htmlSafe=true}} <li>{{t 'authPage.google.notAuthenticated.ul.li2.ul.li1' appName=settings.appName htmlSafe=true}}
<span>{{destinationDomain}}{{copy-to-clipboard size='small' clipboardText=destinationUrl htmlSafe=true}}</span> <span>
{{destinationDomain}}
{{copy-to-clipboard
size='small'
clipboardText=destinationUrl
htmlSafe=true
}}
</span>
</li> </li>
<li> <li>
<b>{{t 'authPage.google.notAuthenticated.ul.li2.ul.li2' htmlSafe=true}}</b> <span>{{destinationUrl}}{{copy-to-clipboard size='small' clipboardText=destinationUrl htmlSafe=true}}</span> <b>{{t 'authPage.google.notAuthenticated.ul.li2.ul.li2' htmlSafe=true}}</b>
<span>
{{destinationUrl}}
{{copy-to-clipboard
size='small'
clipboardText=destinationUrl
htmlSafe=true
}}
</span>
</li> </li>
<li>{{t 'authPage.google.notAuthenticated.ul.li2.ul.li3'}}</li> <li>{{t 'authPage.google.notAuthenticated.ul.li2.ul.li3'}}</li>
</ul> </ul>
@ -88,10 +102,25 @@
<li>{{t 'authPage.google.notAuthenticated.ul.li3.ul.li1'}} <li>{{t 'authPage.google.notAuthenticated.ul.li3.ul.li1'}}
</li> </li>
<li> <li>
<b>{{t 'authPage.google.notAuthenticated.ul.li3.ul.li2' htmlSafe=true}}</b> <span>{{destinationUrl}}{{copy-to-clipboard size='small' clipboardText=destinationUrl htmlSafe=true}}</span> <b>{{t 'authPage.google.notAuthenticated.ul.li3.ul.li2' htmlSafe=true}}</b>
<span>
{{destinationUrl}}
{{copy-to-clipboard
size='small'
clipboardText=destinationUrl
htmlSafe=true
}}
</span>
</li> </li>
<li>{{t 'authPage.google.notAuthenticated.ul.li3.ul.li3' htmlSafe=true}} <li>{{t 'authPage.google.notAuthenticated.ul.li3.ul.li3' htmlSafe=true}}
<span>{{redirectURI}}{{copy-to-clipboard size='small' clipboardText=destinationUrl htmlSafe=true}}</span> <span>
{{redirectURI}}
{{copy-to-clipboard
size='small'
clipboardText=destinationUrl
htmlSafe=true
}}
</span>
</li> </li>
<li>{{t 'authPage.google.notAuthenticated.ul.li3.ul.li4'}}</li> <li>{{t 'authPage.google.notAuthenticated.ul.li3.ul.li4'}}</li>
</ul> </ul>
@ -118,44 +147,53 @@
showExpand=false showExpand=false
title=(t 'authPage.google.notAuthenticated.form.header' appName=settings.appName) title=(t 'authPage.google.notAuthenticated.form.header' appName=settings.appName)
}} }}
<form autcomplete="on"> <form autcomplete='on'>
<section class=""> <section class=''>
<div class="row"> <div class='row'>
<div class="col span-6"> <div class='col span-6'>
<div class="inline-form"> <div class='inline-form'>
<label class="acc-label pb-5">{{t 'authPage.google.notAuthenticated.form.adminEmail.labelText'}}{{field-required}}</label> <label class='acc-label pb-5'>{{t 'authPage.google.notAuthenticated.form.adminEmail.labelText'}}{{field-required}}</label>
{{input type="text" name="username" value=authConfig.adminEmail classNames="form-control"}} {{input
<p class="help-block">{{t 'authPage.google.notAuthenticated.form.adminEmail.helperText'}}</p> type='text'
name='username'
value=authConfig.adminEmail
classNames='form-control'
}}
<p class='help-block'>{{t 'authPage.google.notAuthenticated.form.adminEmail.helperText'}}</p>
</div> </div>
</div> </div>
<div class="col span-6"> <div class='col span-6'>
<div class="inline-form"> <div class='inline-form'>
<label class="acc-label pb-5">{{t 'authPage.google.notAuthenticated.form.hostname.labelText'}}{{field-required}}</label> <label class='acc-label pb-5'>{{t 'authPage.google.notAuthenticated.form.hostname.labelText'}}{{field-required}}</label>
{{input type="text" value=authConfig.hostname classNames="form-control"}} {{input
<p class="help-block">{{t 'authPage.google.notAuthenticated.form.hostname.helperText'}}</p> type='text'
value=authConfig.hostname
classNames='form-control'
}}
<p class='help-block'>{{t 'authPage.google.notAuthenticated.form.hostname.helperText'}}</p>
</div> </div>
</div> </div>
</div> </div>
<div class="row"> <div class='row'>
<div class="col span-12"> <div class='col span-12'>
{{#input-text-file {{#input-text-file
classNames="box" classNames='box'
label="authPage.google.notAuthenticated.form.oauthCredential.labelText" label='authPage.google.notAuthenticated.form.oauthCredential.labelText'
value=authConfig.oauthCredential value=authConfig.oauthCredential
accept="text/*, .json" accept='text/*, .json'
minHeight=60 minHeight=60
canChangeName=false canChangeName=false
nameRequired=true nameRequired=true
placeholder="authPage.google.notAuthenticated.form.oauthCredential.labelText" placeholder='authPage.google.notAuthenticated.form.oauthCredential.labelText'
concealValue=true concealValue=true
as |section| as |section|
}} }}
{{#if (eq section "description")}} {{#if (eq section 'description')}}
<div class="row help"> <div class='row help'>
<div class="col span-12 help-block wrap mb-0"> <div class='col span-12 help-block wrap mb-0'>
{{t "authPage.google.notAuthenticated.form.oauthCredential.helperText" htmlSafe=true}} {{t 'authPage.google.notAuthenticated.form.oauthCredential.helperText' htmlSafe=true}}
</div> </div>
</div> </div>
{{/if}} {{/if}}
@ -163,24 +201,24 @@
</div> </div>
</div> </div>
<div class="row"> <div class='row'>
<div class="col span-12"> <div class='col span-12'>
{{#input-text-file {{#input-text-file
classNames="box" classNames='box'
label="authPage.google.notAuthenticated.form.serviceAccountCredential.labelText" label='authPage.google.notAuthenticated.form.serviceAccountCredential.labelText'
value=authConfig.serviceAccountCredential value=authConfig.serviceAccountCredential
accept="text/*, .json" accept='text/*, .json'
minHeight=60 minHeight=60
canChangeName=false canChangeName=false
nameRequired=true nameRequired=true
placeholder="authPage.google.notAuthenticated.form.serviceAccountCredential.labelText" placeholder='authPage.google.notAuthenticated.form.serviceAccountCredential.labelText'
concealValue=true concealValue=true
as |section| as |section|
}} }}
{{#if (eq section "description")}} {{#if (eq section 'description')}}
<div class="row help"> <div class='row help'>
<div class="col span-12 help-block wrap mb-0"> <div class='col span-12 help-block wrap mb-0'>
{{t "authPage.google.notAuthenticated.form.serviceAccountCredential.helperText" htmlSafe=true}} {{t 'authPage.google.notAuthenticated.form.serviceAccountCredential.helperText' htmlSafe=true}}
</div> </div>
</div> </div>
{{/if}} {{/if}}
@ -188,18 +226,18 @@
</div> </div>
</div> </div>
<div class="row text-center"> <div class='row text-center'>
<div class="btn-group"> <div class='btn-group'>
<button class="btn bg-primary" {{action "save"}}> <button class='btn bg-primary' {{action 'save'}}>
{{#if saving}} {{#if saving}}
<i class="icon icon-spinner icon-spin"></i> {{t 'authPage.google.testAuth.buttonText.post'}} <i class='icon icon-spinner icon-spin'></i> {{t 'authPage.google.testAuth.buttonText.post'}}
{{else if doneSaving}} {{else if doneSaving}}
{{t 'generic.saved'}} {{t 'generic.saved'}}
{{else}} {{else}}
<i class="icon icon-github"></i> {{t 'authPage.google.testAuth.buttonText.pre'}} <i class='icon icon-google'></i> {{t 'authPage.google.testAuth.buttonText.pre'}}
{{/if}} {{/if}}
</button> </button>
<button {{action "cancel"}} class="btn bg-transparent">{{t 'saveCancel.cancel'}}</button> <button {{action 'cancel'}} class='btn bg-transparent'>{{t 'saveCancel.cancel'}}</button>
</div> </div>
</div> </div>

View File

@ -2,11 +2,11 @@ import { inject as service } from '@ember/service';
import Component from '@ember/component'; import Component from '@ember/component';
export default Component.extend({ export default Component.extend({
github: service(), oauth: service(),
actions: { actions: {
authenticate() { authenticate() {
this.get('github').login(); this.get('oauth').login('github');
} }
} }
}); });

View File

@ -2,11 +2,11 @@ import { inject as service } from '@ember/service';
import Component from '@ember/component'; import Component from '@ember/component';
export default Component.extend({ export default Component.extend({
google: service(), oauth: service(),
actions: { actions: {
authenticate() { authenticate() {
this.get('google').login(); this.get('oauth').login('googleoauth');
} }
} }
}); });

View File

@ -1,5 +1,5 @@
<form {{action "authenticate" on="submit"}} class="row pt-10 pb-10"> <form {{action "authenticate" on="submit"}} class="row pt-10 pb-10">
<button disabled={{waiting}} class="btn bg-primary" {{action "authenticate"}}> <button disabled={{waiting}} class="btn bg-primary" {{action "authenticate"}}>
<i class="icon icon-github"></i> {{t 'loginGoogle.buttonText'}} <i class="icon icon-google"></i> {{t 'loginGoogle.buttonText'}}
</button> </button>
</form> </form>

View File

@ -3,6 +3,9 @@ import { addQueryParam, addQueryParams, popupWindowOptions } from 'shared/utils/
import { get, set } from '@ember/object'; import { get, set } from '@ember/object';
import C from 'shared/utils/constants'; import C from 'shared/utils/constants';
const googleOauthScope = 'openid profile email https://www.googleapis.com/auth/admin.directory.user.readonly https://www.googleapis.com/auth/admin.directory.group.readonly';
const githubOauthScope = 'read:org';
export default Service.extend({ export default Service.extend({
access: service(), access: service(),
cookies: service(), cookies: service(),
@ -10,11 +13,16 @@ export default Service.extend({
globalStore: service(), globalStore: service(),
app: service(), app: service(),
intl: service(), intl: service(),
authType: '',
generateState() { generateState() {
return set(this, 'session.githubState', `${ Math.random() }`); return set(this, 'session.githubState', `${ Math.random() }`);
}, },
generateLoginStateKey(authType) {
return set(this, 'session.githubState', `${ Math.random() }login${ authType }`)
},
stateMatches(actual) { stateMatches(actual) {
return actual && get(this, 'session.githubState') === actual; return actual && get(this, 'session.githubState') === actual;
}, },
@ -28,31 +36,41 @@ export default Service.extend({
}, },
authorize(auth, state) { authorize(auth, state) {
const url = addQueryParams(get(auth, 'redirectUrl'), { const isGithub = auth.type.includes('github')
scope: 'read:org', let url = null;
redirect_uri: `${ window.location.origin }/verify-auth`,
authProvider: 'github',
state, if (isGithub) {
}); url = addQueryParams(get(auth, 'redirectUrl'), {
scope: githubOauthScope,
redirect_uri: `${ window.location.origin }/verify-auth`,
authProvider: 'github',
state,
});
} else {
url = addQueryParams(get(auth, 'redirectUrl'), {
scope: googleOauthScope,
redirect_uri: `${ window.location.origin }/verify-auth`,
state,
});
}
return window.location.href = url; return window.location.href = url;
}, },
login(forwardUrl) { login(authType, forwardUrl) {
const provider = get(this, 'access.providers').findBy('id', 'github'); const provider = get(this, 'access.providers').findBy('id', authType);
const authRedirect = get(provider, 'redirectUrl'); const authRedirect = get(provider, 'redirectUrl');
let redirect = addQueryParams(`${ window.location.origin }/verify-auth`, { let redirect = `${ window.location.origin }/verify-auth`;
login: true,
state: this.generateState(),
});
if ( forwardUrl ) { if ( forwardUrl ) {
redirect = addQueryParam(redirect, 'forward', forwardUrl); redirect = addQueryParam(redirect, 'forward', forwardUrl);
} }
const url = addQueryParams(authRedirect, { let url = addQueryParams(authRedirect, {
scope: 'read:org', scope: authType === 'github' ? githubOauthScope : googleOauthScope,
redirect_uri: redirect, state: this.generateLoginStateKey(authType),
redirect_uri: redirect,
}); });
window.location.href = url; window.location.href = url;
@ -60,6 +78,7 @@ export default Service.extend({
test(config, cb) { test(config, cb) {
let responded = false; let responded = false;
let configName = config.name;
window.onAuthTest = (err, code) => { window.onAuthTest = (err, code) => {
if ( !responded ) { if ( !responded ) {
@ -72,8 +91,7 @@ export default Service.extend({
}; };
set(this, 'state', this.generateState()); set(this, 'state', this.generateState());
let url = addQueryParams(`${ window.location.origin }/verify-auth`, { config: configName, });
let url = addQueryParams(`${ window.location.origin }/verify-auth`, { config: 'github', });
const popup = window.open(url, 'rancherAuth', popupWindowOptions()); const popup = window.open(url, 'rancherAuth', popupWindowOptions());
const intl = get(this, 'intl'); const intl = get(this, 'intl');
@ -105,17 +123,28 @@ export default Service.extend({
}, },
finishTest(config, code, cb) { finishTest(config, code, cb) {
const ghConfig = config; const currentConfig = config;
let out = null;
set(ghConfig, 'enabled', true); set(currentConfig, 'enabled', true);
let out = { if (config.id === 'googleoauth') {
code, out = {
enabled: true, code,
githubConfig: ghConfig, enabled: true,
description: C.SESSION.DESCRIPTION, googleOauthConfig: currentConfig,
ttl: C.SESSION.TTL, description: C.SESSION.DESCRIPTION,
}; ttl: C.SESSION.TTL,
};
} else {
out = {
code,
enabled: true,
githubConfig: currentConfig,
description: C.SESSION.DESCRIPTION,
ttl: C.SESSION.TTL,
};
}
const allowedPrincipalIds = get(config, 'allowedPrincipalIds') || []; const allowedPrincipalIds = get(config, 'allowedPrincipalIds') || [];
@ -133,7 +162,7 @@ export default Service.extend({
allowedPrincipalIds.pushObject(get(this, 'access.principal.id')); allowedPrincipalIds.pushObject(get(this, 'access.principal.id'));
} }
return ghConfig.save().then(() => { return currentConfig.save().then(() => {
window.location.href = window.location.href; window.location.href = window.location.href;
}); });
}) })

View File

@ -3,7 +3,8 @@ import { addQueryParam, addQueryParams, popupWindowOptions } from 'shared/utils/
import { get, set } from '@ember/object'; import { get, set } from '@ember/object';
import C from 'shared/utils/constants'; import C from 'shared/utils/constants';
const googleOauthScope = 'openid profile email https://www.googleapis.com/auth/admin.directory.user.readonly https://www.googleapis.com/auth/admin.directory.group.readonly' const googleOauthScope = 'openid profile email https://www.googleapis.com/auth/admin.directory.user.readonly https://www.googleapis.com/auth/admin.directory.group.readonly';
const githubOauthScope = 'read:org';
export default Service.extend({ export default Service.extend({
access: service(), access: service(),
@ -12,17 +13,18 @@ export default Service.extend({
globalStore: service(), globalStore: service(),
app: service(), app: service(),
intl: service(), intl: service(),
authType: '',
generateState() { generateState() {
return set(this, 'session.googleState', `${ Math.random() }`); return set(this, 'session.githubState', `${ Math.random() }`);
}, },
generateLoginStateKey() { generateLoginStateKey(authType) {
return set(this, 'session.googleState', `${ Math.random() }login`) return set(this, 'session.githubState', `${ Math.random() }login${ authType }`)
}, },
stateMatches(actual) { stateMatches(actual) {
return actual && get(this, 'session.googleState') === actual; return actual && get(this, 'session.githubState') === actual;
}, },
testConfig(config) { testConfig(config) {
@ -34,18 +36,30 @@ export default Service.extend({
}, },
authorize(auth, state) { authorize(auth, state) {
const url = addQueryParams(get(auth, 'redirectUrl'), { const isGithub = auth.type.includes('github')
scope: googleOauthScope, let url = null;
redirect_uri: `${ window.location.origin }/verify-auth`,
state,
});
if (isGithub) {
url = addQueryParams(get(auth, 'redirectUrl'), {
scope: githubOauthScope,
redirect_uri: `${ window.location.origin }/verify-auth`,
authProvider: 'github',
state,
});
} else {
url = addQueryParams(get(auth, 'redirectUrl'), {
scope: googleOauthScope,
redirect_uri: `${ window.location.origin }/verify-auth`,
state,
});
}
return window.location.href = url; return window.location.href = url;
}, },
login(forwardUrl) { login(authType, forwardUrl) {
const provider = get(this, 'access.providers').findBy('id', 'googleoauth'); const provider = get(this, 'access.providers').findBy('id', authType);
const authRedirect = get(provider, 'redirectUrl'); const authRedirect = get(provider, 'redirectUrl');
let redirect = `${ window.location.origin }/verify-auth`; let redirect = `${ window.location.origin }/verify-auth`;
@ -53,9 +67,9 @@ export default Service.extend({
redirect = addQueryParam(redirect, 'forward', forwardUrl); redirect = addQueryParam(redirect, 'forward', forwardUrl);
} }
const url = addQueryParams(authRedirect, { let url = addQueryParams(authRedirect, {
scope: googleOauthScope, scope: authType === 'github' ? githubOauthScope : googleOauthScope,
state: this.generateLoginStateKey(), state: this.generateLoginStateKey(authType),
redirect_uri: redirect, redirect_uri: redirect,
}); });
@ -64,20 +78,20 @@ export default Service.extend({
test(config, cb) { test(config, cb) {
let responded = false; let responded = false;
let configName = config.name;
window.onAuthTest = (err, code) => { window.onAuthTest = (err, code) => {
if ( !responded ) { if ( !responded ) {
let googleConfig = config; let ghConfig = config;
responded = true; responded = true;
this.finishTest(googleConfig, code, cb); this.finishTest(ghConfig, code, cb);
} }
}; };
set(this, 'state', this.generateState()); set(this, 'state', this.generateState());
let url = addQueryParams(`${ window.location.origin }/verify-auth`, { config: configName, });
let url = addQueryParams(`${ window.location.origin }/verify-auth`, { config: 'googleoauth', });
const popup = window.open(url, 'rancherAuth', popupWindowOptions()); const popup = window.open(url, 'rancherAuth', popupWindowOptions());
const intl = get(this, 'intl'); const intl = get(this, 'intl');
@ -90,7 +104,7 @@ export default Service.extend({
responded = true; responded = true;
cb({ cb({
type: 'error', type: 'error',
message: intl.t('authPage.google.testAuth.authError') message: intl.t('authPage.github.testAuth.authError')
}); });
} }
} else if (popup === null || typeof (popup) === 'undefined') { } else if (popup === null || typeof (popup) === 'undefined') {
@ -101,7 +115,7 @@ export default Service.extend({
cb({ cb({
type: 'error', type: 'error',
message: intl.t('authPage.google.testAuth.popupError') message: intl.t('authPage.github.testAuth.popupError')
}); });
} }
} }
@ -109,17 +123,28 @@ export default Service.extend({
}, },
finishTest(config, code, cb) { finishTest(config, code, cb) {
const goConfig = config; const currentConfig = config;
let out = null;
set(goConfig, 'enabled', true); set(currentConfig, 'enabled', true);
let out = { if (config.id === 'googleoauth') {
code, out = {
enabled: true, code,
googleOauthConfig: goConfig, enabled: true,
description: C.SESSION.DESCRIPTION, googleOauthConfig: currentConfig,
ttl: C.SESSION.TTL, description: C.SESSION.DESCRIPTION,
}; ttl: C.SESSION.TTL,
};
} else {
out = {
code,
enabled: true,
githubConfig: currentConfig,
description: C.SESSION.DESCRIPTION,
ttl: C.SESSION.TTL,
};
}
const allowedPrincipalIds = get(config, 'allowedPrincipalIds') || []; const allowedPrincipalIds = get(config, 'allowedPrincipalIds') || [];
@ -137,7 +162,7 @@ export default Service.extend({
allowedPrincipalIds.pushObject(get(this, 'access.principal.id')); allowedPrincipalIds.pushObject(get(this, 'access.principal.id'));
} }
return goConfig.save().then(() => { return currentConfig.save().then(() => {
window.location.href = window.location.href; window.location.href = window.location.href;
}); });
}) })
@ -145,4 +170,4 @@ export default Service.extend({
cb(err); cb(err);
}); });
}, },
}) });

View File

@ -220,6 +220,9 @@ var C = {
TYPE_OKTA_GROUP: 'okta_group', TYPE_OKTA_GROUP: 'okta_group',
TYPE_FREEIPA_USER: 'freeipa_user', TYPE_FREEIPA_USER: 'freeipa_user',
TYPE_FREEIPA_GROUP: 'freeipa_group', TYPE_FREEIPA_GROUP: 'freeipa_group',
TYPE_GOOGLE_USER: 'google_user',
TYPE_GOOGLE_TEAM: 'google_team',
TYPE_GOOGLE_ORG: 'google_org',
PERSON: 'person', PERSON: 'person',
TEAM: 'team', TEAM: 'team',

View File

@ -1 +0,0 @@
export { default } from 'shared/google/service';

View File

@ -0,0 +1 @@
export { default } from 'shared/oauth/service';

2
vendor/icons vendored

@ -1 +1 @@
Subproject commit dc7c438544167077ea087bd594921c0d12e7b182 Subproject commit 3781f899f1f430fa7af78642e89055d4da2695db