Skip to content

Commit

Permalink
Merge pull request #828 from gravitational/alexey/adding-acl
Browse files Browse the repository at this point in the history
Alexey/adding acl
  • Loading branch information
Alexey Kontsevoy authored Mar 11, 2017
2 parents e70b4b4 + 66d61c1 commit e710799
Show file tree
Hide file tree
Showing 15 changed files with 1,081 additions and 502 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ webpackJsonp([1],{
/***/ 0:
/***/ function(module, exports, __webpack_require__) {

module.exports = __webpack_require__(535);
module.exports = __webpack_require__(539);


/***/ },

/***/ 535:
/***/ 539:
/***/ function(module, exports) {

// removed by extract-text-webpack-plugin
Expand Down

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion web/dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
<body class="grv">
<div id="app"></div>
<div id="bearer_token" style="display: none;">{{.Session}}</div>
<script type="text/javascript" src="/web/app/vendor.be4d2d2826e88fc673d3.js"></script><script type="text/javascript" src="/web/app/styles.be4d2d2826e88fc673d3.js"></script><script type="text/javascript" src="/web/app/app.be4d2d2826e88fc673d3.js"></script></body>
<script type="text/javascript" src="/web/app/vendor.6a500c88f00b0a11eb77.js"></script><script type="text/javascript" src="/web/app/styles.6a500c88f00b0a11eb77.js"></script><script type="text/javascript" src="/web/app/app.6a500c88f00b0a11eb77.js"></script></body>
</html>
2 changes: 1 addition & 1 deletion web/src/app/__tests__/flux/userTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe('flux/user', function () {
});

it('should return "user"', function () {
var expected = {"name":"alex","logins":["admin","bob"], "shortDisplayName": "a"};
var expected = {"name":"alex", "shortDisplayName": "a"};
expect(reactor.evaluateToJS(getters.user)).toEqual(expected);
});
});
Expand Down
8 changes: 4 additions & 4 deletions web/src/app/components/nodes/main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ limitations under the License.

import React from 'react';
import reactor from 'app/reactor';
import userGetters from 'app/flux/user/getters';
import userAclGetters from 'app/flux/userAcl/getters';
import nodeGetters from 'app/flux/nodes/getters';
import NodeList from './nodeList.jsx';

Expand All @@ -27,13 +27,13 @@ const Nodes = React.createClass({
getDataBindings() {
return {
nodeRecords: nodeGetters.nodeListView,
user: userGetters.user
aclStore: userAclGetters.userAcl
}
},

render() {
let { nodeRecords, user, sites, siteId } = this.state;
let { logins } = user;
let { nodeRecords, aclStore, sites, siteId } = this.state;
let logins = aclStore.getSshLogins();
return (
<div className="grv-page">
<NodeList
Expand Down
1 change: 1 addition & 0 deletions web/src/app/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ let cfg = {
renewTokenPath:'/v1/webapi/sessions/renew',
sessionPath: '/v1/webapi/sessions',
userStatus: '/v1/webapi/user/status',
userAclPath: '/v1/webapi/user/acl',
invitePath: '/v1/webapi/users/invites/:inviteToken',
inviteWithOidcPath: '/v1/webapi/users/invites/oidc/validate?redirect_url=:redirect&connector_id=:provider&token=:inviteToken',
createUserPath: '/v1/webapi/users',
Expand Down
4 changes: 3 additions & 1 deletion web/src/app/flux/app/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ import api from 'app/services/api';
import cfg from 'app/config';
import restApiActions from 'app/flux/restApi/actions';
import { fetchNodes } from './../nodes/actions';
import { fetchAcl } from './../userAcl/actions'
import { fetchActiveSessions } from 'app/flux/sessions/actions';

import $ from 'jQuery';

const logger = require('app/lib/logger').create('flux/app');
Expand All @@ -40,7 +42,7 @@ const actions = {
restApiActions.start(TRYING_TO_INIT_APP);

// get the list of available clusters
return actions.fetchSites()
return $.when(actions.fetchSites(), fetchAcl())
.then(masterSiteId => {
siteId = siteId || masterSiteId;
reactor.dispatch(TLPT_APP_SET_SITE_ID, siteId);
Expand Down
8 changes: 5 additions & 3 deletions web/src/app/flux/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ limitations under the License.
import reactor from 'app/reactor';
import termStore from './terminal/store';
import playerStore from './player/store';
import userAcl from './userAcl/store';

reactor.registerStores({
'tlpt': require('./app/appStore'),
'tlpt_terminal': termStore,
'tlpt_player': playerStore,
'tlpt_user': require('./user/userStore'),
'tlpt_sites': require('./sites/siteStore'),
'tlpt_player': playerStore,
'tlpt_user': require('./user/userStore'),
'tlpt_user_invite': require('./user/userInviteStore'),
'tlpt_user_acl': userAcl,
'tlpt_sites': require('./sites/siteStore'),
'tlpt_nodes': require('./nodes/nodeStore'),
'tlpt_rest_api': require('./restApi/restApiStore'),
'tlpt_sessions_events': require('./sessions/eventStore'),
Expand Down
3 changes: 1 addition & 2 deletions web/src/app/flux/user/getters.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ const user = [ ['tlpt_user'], (currentUser) => {

return {
name,
shortDisplayName,
logins: currentUser.get('allowed_logins').toJS()
shortDisplayName
}
}
];
Expand Down
5 changes: 5 additions & 0 deletions web/src/app/flux/userAcl/actionTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import keyMirror from 'keymirror'

export default keyMirror({
USERACL_RECEIVE: null
})
13 changes: 13 additions & 0 deletions web/src/app/flux/userAcl/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import reactor from 'app/reactor';
import cfg from 'app/config';
import api from 'app/services/api';
import { USERACL_RECEIVE } from './actionTypes';

export default {
fetchAcl(){
return api.get(cfg.api.userAclPath)
.then(json => {
reactor.dispatch(USERACL_RECEIVE, json)
})
}
}
5 changes: 5 additions & 0 deletions web/src/app/flux/userAcl/getters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const userAcl = ['tlpt_user_acl'];

export default {
userAcl
}
52 changes: 52 additions & 0 deletions web/src/app/flux/userAcl/store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Store, toImmutable } from 'nuclear-js';
import { Record, Map, List } from 'immutable';
import { USERACL_RECEIVE } from './actionTypes';

class AccessRec extends Record({
admin: Map({
enabled: false
}),
ssh: Map({
enabled: false,
logins: List()
})
}){
constructor(params){
super(params);
}

isAdminEnabled() {
return this.getIn(['admin', 'enabled']);
}

isSshEnabled() {
let logins = this.getIn(['ssh', 'logins']);
return logins ? logins.size > 0 : false;
}

getSshLogins() {
let logins = this.getIn(['ssh', 'logins']);
if (!logins) {
return []
}

return logins.toJS();
}
}

export default Store({
getInitialState() {
return new AccessRec();
},

initialize() {
this.on(USERACL_RECEIVE, receiveAcl);
}
})

function receiveAcl(state, json) {
json = json || {};
return new AccessRec(toImmutable(json));
}


57 changes: 37 additions & 20 deletions web/src/app/services/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ limitations under the License.

var { browserHistory, createMemoryHistory } = require('react-router');
var $ = require('jQuery');

const EMPTY_TOKEN_CONTENT_LENGTH = 20;
const logger = require('app/lib/logger').create('services/sessions');
const AUTH_KEY_DATA = 'authData';

Expand Down Expand Up @@ -44,36 +44,53 @@ var session = {
},

getUserData(){
let userData = null;
try{
var item = localStorage.getItem(AUTH_KEY_DATA);
if(item){
return JSON.parse(item);
}
// first check if user data (with barer token) is embedded in HTML
userData = this._getUserDataFromHtml();

// for sso use-cases, try to grab the token from HTML
var hiddenDiv = document.getElementById("bearer_token");
if(hiddenDiv !== null ){
let json = window.atob(hiddenDiv.textContent);
let data = JSON.parse(json);
if(data.token){
// put it into the session
var userData = this.setUserData(data);
// remove the element
hiddenDiv.remove();
return userData;
}
// then lookup in the browser local storage
if(!userData){
userData = this._getUserDataFromLocalStorage();
}

}catch(err){
logger.error('error trying to read user auth data:', err);
logger.error('Cannot retrieve user data', err);
}

return {};
return userData || {};
},

clear(){
localStorage.clear()
}
},

_getUserDataFromHtml(){
let $el = $('#bearer_token');
let userData = null;
if($el.length !== 0){
let encodedToken = $el.text() || '';
if(encodedToken.length > EMPTY_TOKEN_CONTENT_LENGTH){
let decoded = window.atob(encodedToken);
let json = JSON.parse(decoded);
userData = this.setUserData(json);
}

// remove initial data from HTML as it will be renewed with a time
$el.remove();
}

return userData;
},

_getUserDataFromLocalStorage(){
let item = localStorage.getItem(AUTH_KEY_DATA);
if(item){
return JSON.parse(item);
}

return null;
}
}

module.exports = session;

0 comments on commit e710799

Please sign in to comment.