ui/app/admin-tab/auth/github/controller.js

326 lines
8.9 KiB
JavaScript

import Ember from 'ember';
import C from 'ui/utils/constants';
import { denormalizeName } from 'ui/services/settings';
export default Ember.Controller.extend({
github : Ember.inject.service(),
endpoint : Ember.inject.service(),
access : Ember.inject.service(),
settings : Ember.inject.service(),
confirmDisable : false,
errors : null,
testing : false,
saving : false,
saved : true,
error : null,
originalModel : null,
organizations : null,
addUserInput : '',
addOrgInput : '',
useNonSecure : false,
scheme : Ember.computed.alias('model.scheme'),
saveDisabled : Ember.computed.or('saving','saved'),
isRestricted : Ember.computed.equal('model.accessMode','restricted'),
wasRestricted : Ember.computed.equal('originalModel.accessMode','restricted'),
useSSL: Ember.observer('useNonSecure', function(){
if (this.get('useNonSecure')) {
this.set('scheme', 'http://');
} else {
this.set('scheme', 'https://');
}
}),
createDisabled: function() {
if ( this.get('isEnterprise') && !this.get('model.hostname') )
{
return true;
}
if ( this.get('testing') )
{
return true;
}
}.property('model.{clientId,clientSecret,hostname}','testing','isEnterprise'),
wasRestrictedMsg: function() {
let users = this.get('originalModel.allowedIdentities').filterBy('externalIdType',C.PROJECT.TYPE_GITHUB_USER).get('length');
let orgs = this.get('originalModel.allowedIdentities').filterBy('externalIdType',C.PROJECT.TYPE_GITHUB_ORG).get('length');
let enterprise = !!this.get('originalModel.hostname');
let github = 'GitHub' + ( enterprise ? ' Enterprise' : '');
let str = 'project members';
if ( users )
{
str += (orgs ? ', ' : ' and ') + users + ' ' + github + ' user' + (users === 1 ? '' : 's');
}
if ( orgs )
{
str += ' and ' + orgs + (users ? '' : ' ' + github) + ' organization' + ( orgs === 1 ? '' : 's');
}
return str;
}.property('originalModel.allowedIdentities.[]','wasRestricted'),
allowedActualIdentities: Ember.computed.alias('model.allowedIdentities'),
wasShowing: false,
showingAccessControl: function() {
let show = this.get('wasShowing');
let restricted = this.get('isRestricted');
if ( restricted )
{
if ( this.get('allowedActualIdentities.length') > 1 )
{
show = true;
}
else if ( this.get('allowedActualIdentities.firstObject.id') !== this.get('access.identity.id') )
{
show = true;
}
}
else
{
show = true;
}
this.set('wasShowing', show);
return show;
}.property('allowedActualIdentities.@each.id','isRestricted','wasShowing'),
destinationUrl: function() {
return window.location.origin+'/';
}.property(),
accessModeChanged: function() {
this.set('saved',false);
}.observes('model.accessMode'),
isEnterprise: false,
enterpriseDidChange: function() {
if ( !this.get('isEnterprise') ) {
this.set('hostname', null);
} else {
if (this.get('model.scheme') === 'http://') {
this.set('useNonSecure', true);
}
}
}.observes('isEnterprise'),
protocolChoices: [
{label: 'https:// -- Requires a cert from a public CA', value: 'https://'},
{label: 'http://', value: 'http://'},
],
hostnameDidChange: function() {
let cur = this.get('model.hostname')||'';
let neu = cur.replace(/^https?:\/\//ig,'').replace(/\/.*$/,'');
if ( cur !== neu )
{
this.set('hostname', neu);
}
}.observes('hostname'),
actions: {
test: function() {
this.send('clearError');
this.set('testing', true);
let model = this.get('model');
model.setProperties({
'clientId': (model.get('clientId')||'').trim(),
'clientSecret': (model.get('clientSecret')||'').trim(),
'enabled': false, // It should already be, but just in case..
'accessMode': 'unrestricted',
'allowedIdentities': [],
});
// Send authenticate immediately so that the popup isn't blocked,
// even though the config isn't necessarily saved yet...
this.set('github.hostname', model.get('hostname'));
this.set('github.clientId', model.get('clientId'));
this.send('authenticate');
model.save().catch(err => {
this.set('testing', false);
this.send('gotError', err);
});
},
authenticate: function() {
this.send('clearError');
this.get('github').authorizeTest((err,code) => {
if ( err )
{
this.send('gotError', err);
}
else
{
this.send('gotCode', code);
}
});
},
gotCode: function(code) {
this.get('access').login(code).then(res => {
let auth = JSON.parse(res.xhr.responseText);
this.send('authenticationSucceeded', auth);
}).catch(res => {
// Github auth succeeded but didn't get back a token
let err = JSON.parse(res.xhr.responseText);
this.send('gotError', err);
});
},
authenticationSucceeded: function(auth) {
this.send('clearError');
this.set('organizations', auth.orgs);
let model = this.get('model').clone();
model.setProperties({
'enabled': true,
'accessMode': 'restricted',
'allowedIdentities': [auth.userIdentity],
});
let url = window.location.href;
model.save().then(() => {
// Set this to true so the token will be sent with the request
this.set('access.enabled', true);
return this.get('store').find('setting', denormalizeName(C.SETTING.API_HOST)).then((setting) => {
if ( setting.get('value') )
{
this.send('waitAndRefresh', url);
}
else
{
// Default the api.host so the user won't have to set it in most cases
setting.set('value', this.get('endpoint.host'));
return setting.save().then(() => {
this.send('waitAndRefresh', url);
});
}
});
}).catch((err) => {
this.set('access.enabled', false);
this.send('gotError', err);
});
},
waitAndRefresh: function(url) {
$('#loading-underlay, #loading-overlay').removeClass('hide').show();
setTimeout(function() {
window.location.href = url || window.location.href;
}, 1000);
},
addAuthorized: function(data) {
this.send('clearError');
this.set('saved', false);
this.get('model.allowedIdentities').pushObject(data);
},
githubNotFound: function(login) {
this.send('showError',"User '"+ login + "' not found");
this.send('removeUser',login);
},
removeIdentity: function(ident) {
this.set('saved', false);
this.get('model.allowedIdentities').removeObject(ident);
},
saveAuthorization: function() {
this.send('clearError');
if ( this.get('isRestricted') && !this.get('model.allowedIdentities.length') )
{
this.send('showError','Add at least one authorized user or organization');
return;
}
this.set('saving', true);
this.set('saved', false);
let model = this.get('model');
model.save().then(() => {
this.get('originalModel').replaceWith(model);
this.set('originalModel.allowedIdentities', this.get('model.allowedIdentities').slice());
this.set('saved', true);
}).catch((err) => {
this.send('gotError', err);
}).finally(() => {
this.set('saving', false);
});
},
promptDisable: function() {
this.set('confirmDisable', true);
Ember.run.later(this, function() {
this.set('confirmDisable', false);
}, 10000);
},
gotError: function(err) {
if ( err.message )
{
this.send('showError', err.message + (err.detail? '('+err.detail+')' : ''));
}
else
{
this.send('showError', 'Error ('+err.status + ' - ' + err.code+')');
}
this.set('testing', false);
this.set('saving', false);
},
showError: function(msg) {
this.set('errors', [msg]);
window.scrollY = 0;
},
clearError: function() {
this.set('errors', null);
},
disable: function() {
this.send('clearError');
let model = this.get('model').clone();
model.setProperties({
'allowedIdentities': [],
'accessMode': 'unrestricted',
'enabled': false,
'hostname': null,
'clientSecret': '',
});
model.save().then(() => {
this.get('access').clearSessionKeys();
this.set('access.enabled',false);
this.send('waitAndRefresh');
}).catch((err) => {
this.send('gotError', err);
}).finally(() => {
this.set('confirmDisable', false);
});
},
showAccessControl: function() {
this.set('wasShowing',true);
},
},
});