mirror of https://github.com/rancher/ui.git
Access Control config enhancements
- Check Github API and automatically remove users/orgs that don't exist - Saving/Saved state on the authorization save button to show state - Waiting state on test button to show state - Size GitHub popup window bigger to show content
This commit is contained in:
parent
1c0a29899b
commit
b4940855e8
|
|
@ -8,8 +8,8 @@ export function initialize(container, application) {
|
|||
|
||||
// Find out if auth is enabled
|
||||
store.rawRequest({
|
||||
url: 'token', // Base url, which will be /v1
|
||||
headers: { 'authorization': undefined }
|
||||
url: 'token',
|
||||
headers: { 'authorization': undefined } // Explicitly not send the auth token
|
||||
})
|
||||
.then(function(obj) {
|
||||
var body = JSON.parse(obj.xhr.responseText);
|
||||
|
|
|
|||
|
|
@ -5,21 +5,24 @@ export default Ember.Component.extend({
|
|||
login: null,
|
||||
|
||||
classNames: ['gh-avatar'],
|
||||
name: 'Loading...',
|
||||
name: 'Checking...',
|
||||
avatarUrl: null,
|
||||
|
||||
nameChanged: function() {
|
||||
var self = this;
|
||||
var url = 'https://api.github.com/' + this.get('type') + 's/' + this.get('login') + '?s=40';
|
||||
var login = this.get('login');
|
||||
var type = this.get('type');
|
||||
var url = 'https://api.github.com/' + type + 's/' + login;
|
||||
|
||||
Ember.$.ajax({url: url, dataType: 'json'}).then(function(body) {
|
||||
self.set('name', body.name);
|
||||
self.set('avatarUrl', body.avatar_url);
|
||||
}, function() {
|
||||
var type = self.get('type');
|
||||
type = type.substr(0,1).toUpperCase() + type.substr(1);
|
||||
|
||||
self.set('name', 'Warning: ' + type + ' not found');
|
||||
var avatarUrl = body.avatar_url;
|
||||
avatarUrl += (avatarUrl.indexOf('?') >= 0 ? '&' : '?') + 's=40';
|
||||
self.set('avatarUrl', avatarUrl);
|
||||
}, function() {
|
||||
self.set('name', '(Not found)');
|
||||
self.sendAction('notFound', login);
|
||||
});
|
||||
}.observes('login','type').on('init'),
|
||||
|
||||
|
|
|
|||
|
|
@ -12,5 +12,5 @@
|
|||
<div class="clip">
|
||||
<a {{bind-attr href=url}} target="_blank">{{login}}</a>
|
||||
</div>
|
||||
<div class="text-muted clip">{{name}}</div>
|
||||
<div class="text-muted clip">{{#if name}}{{name}}{{else}}<i>No name</i>{{/if}}</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,12 @@
|
|||
{{#if app.authenticationEnabled}}
|
||||
<div class="pull-right">
|
||||
<div class="dropdown">
|
||||
<span class="fa-stack fa-lg hand" id="user-dropdown" data-toggle="dropdown" aria-expanded="true">
|
||||
<i class="fa fa-circle-o fa-stack-2x"></i>
|
||||
<i class="fa fa-user fa-stack-1x"></i>
|
||||
<span class="hand" id="user-dropdown" data-toggle="dropdown" aria-expanded="true">
|
||||
<span class="fa-stack fa-lg">
|
||||
<i class="fa fa-circle-o fa-stack-2x"></i>
|
||||
<i class="fa fa-user fa-stack-1x"></i>
|
||||
</span>
|
||||
<i class="fa fa-chevron-down"></i>
|
||||
</span>
|
||||
<ul class="dropdown-menu dropdown-menu-right" role="menu" aria-labelledby="user-dropdown">
|
||||
<li role="presentation" class="disabled">
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ export default Ember.Controller.extend({
|
|||
self.set('timedOut', false);
|
||||
self.set('waiting', true);
|
||||
|
||||
self.get('torii').open('github-oauth2').then(function(github){
|
||||
self.get('torii').open('github-oauth2',{width: 1024, height: 500}).then(function(github){
|
||||
return self.get('store').rawRequest({
|
||||
url: 'token',
|
||||
method: 'POST',
|
||||
|
|
|
|||
|
|
@ -3,12 +3,17 @@ import Ember from 'ember';
|
|||
export default Ember.ObjectController.extend({
|
||||
confirmDisable: false,
|
||||
error: null,
|
||||
testing: false,
|
||||
saving: false,
|
||||
saved: true,
|
||||
|
||||
createIncomplete: function() {
|
||||
createDisabled: function() {
|
||||
var id = (this.get('clientId')||'').trim();
|
||||
var secret = (this.get('clientSecret')||'').trim();
|
||||
return id.length < 20 ||secret.length < 40;
|
||||
}.property('clientId','clientSecret'),
|
||||
return id.length < 20 ||secret.length < 40 || this.get('testing');
|
||||
}.property('clientId','clientSecret','testing'),
|
||||
|
||||
saveDisabled: Ember.computed.or('saving','saved'),
|
||||
|
||||
destinationUrl: function() {
|
||||
return window.location.origin+'/';
|
||||
|
|
@ -17,8 +22,10 @@ export default Ember.ObjectController.extend({
|
|||
actions: {
|
||||
test: function() {
|
||||
var self = this;
|
||||
self.send('clearError');
|
||||
self.set('testing',true);
|
||||
|
||||
var model = this.get('model');
|
||||
var model = self.get('model');
|
||||
model.set('clientId', model.get('clientId').trim());
|
||||
model.set('clientSecret', model.get('clientSecret').trim());
|
||||
model.set('enabled',false); // It should already be, but just in case..
|
||||
|
|
@ -34,7 +41,8 @@ export default Ember.ObjectController.extend({
|
|||
|
||||
authenticate: function() {
|
||||
var self = this;
|
||||
self.get('torii').open('github-oauth2').then(function(github){
|
||||
self.send('clearError');
|
||||
self.get('torii').open('github-oauth2',{width: 1024, height: 500}).then(function(github){
|
||||
return self.get('store').rawRequest({
|
||||
url: 'token',
|
||||
method: 'POST',
|
||||
|
|
@ -52,18 +60,21 @@ export default Ember.ObjectController.extend({
|
|||
.catch(function(err) {
|
||||
// Github auth failed.. try again
|
||||
self.send('gotError', err);
|
||||
})
|
||||
.finally(function() {
|
||||
self.set('testing',false);
|
||||
});
|
||||
},
|
||||
|
||||
authenticationSucceeded: function(auth) {
|
||||
console.log('Authentication succeeded');
|
||||
var self = this;
|
||||
var session = self.get('session');
|
||||
self.send('clearError');
|
||||
|
||||
var session = self.get('session');
|
||||
session.set('token', auth.jwt);
|
||||
session.set('isLoggedIn',1);
|
||||
|
||||
var model = this.get('model');
|
||||
var model = self.get('model');
|
||||
model.set('enabled',true);
|
||||
model.set('allowOrganizations', auth.orgs||[]);
|
||||
model.set('allowUsers', [auth.user]);
|
||||
|
|
@ -75,7 +86,6 @@ export default Ember.ObjectController.extend({
|
|||
},
|
||||
|
||||
waitAndRefresh: function(expect,limit) {
|
||||
console.log('Wait and refresh',expect,limit);
|
||||
var self = this;
|
||||
if ( limit === undefined )
|
||||
{
|
||||
|
|
@ -114,6 +124,9 @@ export default Ember.ObjectController.extend({
|
|||
},
|
||||
|
||||
addUser: function() {
|
||||
this.send('clearError');
|
||||
this.set('saved',false);
|
||||
|
||||
var str = (this.get('addUser')||'').trim();
|
||||
if ( str )
|
||||
{
|
||||
|
|
@ -122,11 +135,15 @@ export default Ember.ObjectController.extend({
|
|||
}
|
||||
},
|
||||
|
||||
removeUser: function(user) {
|
||||
this.get('allowUsers').removeObject(user);
|
||||
removeUser: function(login) {
|
||||
this.set('saved',false);
|
||||
this.get('allowUsers').removeObject(login);
|
||||
},
|
||||
|
||||
addOrg: function() {
|
||||
this.send('clearError');
|
||||
this.set('saved',false);
|
||||
|
||||
var str = (this.get('addOrg')||'').trim();
|
||||
if ( str )
|
||||
{
|
||||
|
|
@ -135,17 +152,34 @@ export default Ember.ObjectController.extend({
|
|||
}
|
||||
},
|
||||
|
||||
removeOrg: function(org) {
|
||||
this.get('allowOrganizations').removeObject(org);
|
||||
removeOrg: function(login) {
|
||||
this.set('saved',false);
|
||||
this.get('allowOrganizations').removeObject(login);
|
||||
},
|
||||
|
||||
userNotFound: function(login) {
|
||||
this.send('showError',"User '"+ login + "' not found");
|
||||
this.send('removeUser',login);
|
||||
},
|
||||
|
||||
orgNotFound: function(login) {
|
||||
this.send('showError',"Organization '"+ login + "' not found");
|
||||
this.send('removeOrg',login);
|
||||
},
|
||||
|
||||
saveAuthorization: function() {
|
||||
var self = this;
|
||||
self.send('clearError');
|
||||
self.set('saving',true);
|
||||
self.set('saved',false);
|
||||
|
||||
var model = self.get('model');
|
||||
model.save().then(function() {
|
||||
self.send('waitAndRefresh', true);
|
||||
self.set('saved',true);
|
||||
}).catch(function(err) {
|
||||
self.send('gotError', err);
|
||||
}).finally(function() {
|
||||
self.set('saving',false);
|
||||
});
|
||||
},
|
||||
|
||||
|
|
@ -154,12 +188,21 @@ export default Ember.ObjectController.extend({
|
|||
},
|
||||
|
||||
gotError: function(err) {
|
||||
this.set('error', err.message);
|
||||
this.send('showError', err.message);
|
||||
},
|
||||
|
||||
showError: function(msg) {
|
||||
this.set('error', msg);
|
||||
window.scrollY = 0;
|
||||
},
|
||||
|
||||
clearError: function() {
|
||||
this.set('error', '');
|
||||
},
|
||||
|
||||
disable: function() {
|
||||
var self = this;
|
||||
self.send('clearError');
|
||||
|
||||
var model = this.get('model');
|
||||
model.set('allowOrganizations',[]);
|
||||
|
|
|
|||
|
|
@ -11,5 +11,9 @@ export default Ember.Route.extend(AuthenticatedRouteMixin,{
|
|||
setupController: function(controller, model) {
|
||||
this._super(controller,model);
|
||||
controller.set('confirmDisable',false);
|
||||
controller.set('saving',false);
|
||||
controller.set('saved',true);
|
||||
controller.set('testing',false);
|
||||
controller.set('error',null);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,23 +1,29 @@
|
|||
<div style="padding: 20px 20px 0 20px;">
|
||||
<section>
|
||||
{{#if error}}
|
||||
<div class="alert alert-danger">
|
||||
<i style="float: left;" class="fa fa-lg fa-exclamation-circle"></i>
|
||||
<p style="margin-left: 50px">{{error}}</p>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="well">
|
||||
<h2>Access Control is {{#if app.authenticationEnabled}}<b>enabled</b>{{else}}<b class="text-warning">not configured</b>{{/if}}</h2>
|
||||
<p>
|
||||
<div>
|
||||
{{#if app.authenticationEnabled}}
|
||||
Rancher is configured to restrict access to the GitHub users and organization members below.
|
||||
{{else}}
|
||||
Rancher can be configured to restrict access to a set of GitHub users and organization members. This is not currently set up, so anybody that reach this page (or the API) has full control over the system.
|
||||
{{/if}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if error}}
|
||||
<div class="alert alert-danger">
|
||||
<i style="float: left;" class="fa fa-exclamation-circle"></i>
|
||||
<p style="margin-left: 50px">{{error}}</p>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if app.authenticationEnabled}}
|
||||
<div class="well">
|
||||
<h4>Authentication</h4>
|
||||
<hr/>
|
||||
<p>To change the configured GitHub application, disable access control below and then set it up again.</p>
|
||||
<div><b>Client ID: </b> <span class="text-muted">{{clientId}}</span></div>
|
||||
</div>
|
||||
|
||||
<div class="well">
|
||||
<h4>Configure Authorization</h4>
|
||||
|
|
@ -27,7 +33,7 @@
|
|||
<div class="col-sm-6">
|
||||
<label>Users</label>
|
||||
|
||||
<form {{action "addUser"}}>
|
||||
<form {{action "addUser" on="submit"}}>
|
||||
<div class="input-group">
|
||||
{{input type="text" value=addUser placeholder="Add GitHub username" class="form-control"}}
|
||||
<div class="input-group-btn">
|
||||
|
|
@ -41,7 +47,7 @@
|
|||
<ul class="list-unstyled gh-avatar-list">
|
||||
{{#each user in allowUsers}}
|
||||
<li>
|
||||
{{#github-avatar type="user" login=user}}
|
||||
{{#github-avatar type="user" login=user notFound="userNotFound"}}
|
||||
<button class="btn btn-danger btn-sm pull-right gh-action" {{action "removeUser" user}}>Remove</button>
|
||||
{{/github-avatar}}
|
||||
</li>
|
||||
|
|
@ -54,7 +60,7 @@
|
|||
<div class="col-sm-6">
|
||||
<label>Organizations</label>
|
||||
|
||||
<form {{action "addOrg"}}>
|
||||
<form {{action "addOrg" on="submit"}}>
|
||||
<div class="input-group">
|
||||
{{input type="text" value=addOrg placeholder="Add GitHub organization name" class="form-control"}}
|
||||
<div class="input-group-btn">
|
||||
|
|
@ -68,7 +74,7 @@
|
|||
<ul class="list-unstyled gh-avatar-list">
|
||||
{{#each org in allowOrganizations}}
|
||||
<li>
|
||||
{{#github-avatar type="org" login=org}}
|
||||
{{#github-avatar type="org" login=org notFound="orgNotFound"}}
|
||||
<button class="btn btn-danger btn-sm pull-right gh-action" {{action "removeOrg" org}}>Remove</button>
|
||||
{{/github-avatar}}
|
||||
</li>
|
||||
|
|
@ -81,8 +87,16 @@
|
|||
|
||||
<hr/>
|
||||
|
||||
<button class="btn btn-primary" {{action "saveAuthorization"}}>
|
||||
Save Authorization Configuration
|
||||
<button class="btn btn-primary" {{bind-attr disabled=saveDisabled}} {{action "saveAuthorization"}}>
|
||||
{{#if saved}}
|
||||
Saved
|
||||
{{else}}
|
||||
{{#if saving}}
|
||||
<i class="fa fa-spinner fa-spin"></i> Saving...</i>
|
||||
{{else}}
|
||||
Save authorization configuration
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
@ -96,11 +110,11 @@
|
|||
|
||||
{{#if confirmDisable}}
|
||||
<button class="btn btn-danger" {{action "disable"}}>
|
||||
<i class="fa fa-fire"></i> Are you sure? Click again to really disable Access Control
|
||||
<i class="fa fa-fire"></i> Are you sure? Click again to really disable access control
|
||||
</button>
|
||||
{{else}}
|
||||
<button class="btn btn-danger" {{action "promptDisable"}}>
|
||||
<i class="fa fa-fire"></i> Disable Access Control
|
||||
<i class="fa fa-fire"></i> Disable access control
|
||||
</button>
|
||||
{{/if}}
|
||||
|
||||
|
|
@ -160,11 +174,15 @@
|
|||
<p>Check that your application is configured correctly by testing authentication with it:</p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<button {{bind-attr disabled=createIncomplete}} class="btn btn-primary" {{action "test"}}>
|
||||
<i class="fa fa-github"></i> Authenticate with GitHub
|
||||
<button {{bind-attr disabled=createDisabled}} class="btn btn-primary" {{action "test"}}>
|
||||
{{#if testing}}
|
||||
<i class="fa fa-spinner fa-spin"></i> Waiting to hear back from GitHub
|
||||
{{else}}
|
||||
<i class="fa fa-github"></i> Authenticate with GitHub
|
||||
{{/if}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/unless}}
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Route.extend({
|
||||
enter: function() {
|
||||
this.send('setPageName','Settings');
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -116,13 +116,12 @@ HEADER {
|
|||
z-index: 2;
|
||||
margin-left: $nav_width;
|
||||
background-color: $header_bg;
|
||||
padding: 0;
|
||||
padding: 0 20px;
|
||||
|
||||
H2 {
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
line-height: $header_height;
|
||||
padding-left: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
"license": "Apache 2",
|
||||
"devDependencies": {
|
||||
"ember-api-store": "1.0.7",
|
||||
"rancher-torii": "^0.2.2",
|
||||
|
||||
"body-parser": "^1.2.0",
|
||||
"broccoli-asset-rev": "^1.0.0",
|
||||
|
|
@ -38,7 +39,6 @@
|
|||
"express": "^4.8.5",
|
||||
"forever-agent": "^0.5.2",
|
||||
"glob": "^4.0.5",
|
||||
"http-proxy": "^1.6.2",
|
||||
"torii": "^0.2.2"
|
||||
"http-proxy": "^1.6.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue