conjur-asset-ui-beta 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/TODO.md +0 -23
  3. data/app/build/js/app.js +72652 -50337
  4. data/app/package.json +2 -0
  5. data/app/src/actions.js +56 -3
  6. data/app/src/app.js +7 -3
  7. data/app/src/clients/graph.js +24 -0
  8. data/app/src/clients/members.js +3 -3
  9. data/app/src/components/audit/table.js +9 -0
  10. data/app/src/components/custom/view.js +26 -14
  11. data/app/src/components/dashboard/activity.js +24 -4
  12. data/app/src/components/generic/foldable_audit_section.js +17 -0
  13. data/app/src/components/generic/role_link.js +2 -1
  14. data/app/src/components/graph/graph.js +421 -0
  15. data/app/src/components/graph/graph.less +39 -0
  16. data/app/src/components/group/view.js +31 -14
  17. data/app/src/components/host/activity.js +24 -4
  18. data/app/src/components/host/executors.js +83 -0
  19. data/app/src/components/host/updaters.js +83 -0
  20. data/app/src/components/host/view.js +46 -14
  21. data/app/src/components/layer/view.js +30 -13
  22. data/app/src/components/policy/view.js +23 -14
  23. data/app/src/components/search/search.js +21 -7
  24. data/app/src/components/user/activity.js +25 -4
  25. data/app/src/components/user/view.js +30 -13
  26. data/app/src/components/variable/activity.js +25 -4
  27. data/app/src/components/variable/fetchers.js +1 -1
  28. data/app/src/components/variable/updaters.js +1 -1
  29. data/app/src/components/variable/view.js +24 -13
  30. data/app/src/constants.js +4 -2
  31. data/app/src/stores/graph_store.js +55 -0
  32. data/app/src/stores/host_store.js +12 -1
  33. data/app/src/stores/route_store.js +7 -5
  34. data/app/src/stores/search_store.js +11 -6
  35. data/conjur-asset-ui.gemspec +1 -1
  36. data/lib/conjur-asset-ui-version.rb +1 -1
  37. metadata +9 -3
data/app/package.json CHANGED
@@ -16,6 +16,8 @@
16
16
  "bootstrap": "^3.3.2",
17
17
  "collections": "^1.2.2",
18
18
  "d3": "^3.5.3",
19
+ "dagre": "^0.7.1",
20
+ "dagre-d3": "^0.4.2",
19
21
  "event-source-polyfill": "0.0.1",
20
22
  "fluxxor": "^1.5.2",
21
23
  "lodash": "^3.6.0",
data/app/src/actions.js CHANGED
@@ -5,7 +5,8 @@ var ClientAudit = require('./clients/audit'),
5
5
  ClientList = require('./clients/list'),
6
6
  ClientSearch = require('./clients/search'),
7
7
  ClientMembers = require('./clients/members'),
8
- ClientLayerMembers = require('./clients/layer_members');
8
+ ClientLayerMembers = require('./clients/layer_members'),
9
+ ClientGraph = require('./clients/graph');
9
10
 
10
11
  var constants = require('./constants');
11
12
 
@@ -15,8 +16,8 @@ module.exports = {
15
16
  },
16
17
 
17
18
  routes: {
18
- transition(path, params) {
19
- this.dispatch(constants.ROUTES.TRANSITION, {path: path, params: params});
19
+ transition(params) {
20
+ this.dispatch(constants.ROUTES.TRANSITION, {params: params});
20
21
  }
21
22
  },
22
23
 
@@ -154,6 +155,33 @@ module.exports = {
154
155
  }
155
156
  },
156
157
 
158
+ graph: {
159
+ load(kind, id) {
160
+ this.dispatch(constants.GRAPH.LOAD);
161
+
162
+ // this.dispatch(constants.GRAPH.LOAD_SUCCESS,
163
+ // {kind: kind, id: id,
164
+ // res: {body: {"graph":[{"parent":"conjur:group:foods","child":"conjur:host:ldap1"},{"parent":"conjur:group:vegetables","child":"conjur:host:ldap1"},{"parent":"conjur:user:foo","child":"conjur:host:ldap1"},{"parent":"conjur:user:bar","child":"conjur:host:ldap1"},{"parent":"conjur:group:foods","child":"conjur:group:vegetables"},{"parent":"conjur:host:ldap1","child":"conjur:user:admin"}]}}});
165
+
166
+ ClientGraph(
167
+ kind,
168
+ id,
169
+ (res) => {
170
+ var payload = {kind: kind, id: id, res: res};
171
+
172
+ this.dispatch(
173
+ constants.GRAPH.LOAD_SUCCESS,
174
+ payload
175
+ );
176
+ },
177
+ (res) => {
178
+ this.dispatch(constants.GRAPH.LOAD_FAIL, {id: id});
179
+ // this.flux.actions.flashMessage(res.error.message);
180
+ }
181
+ );
182
+ }
183
+ },
184
+
157
185
  user: {
158
186
  load(id) {
159
187
  this.dispatch(constants.USER.LOAD, {id: id});
@@ -299,6 +327,30 @@ module.exports = {
299
327
  });
300
328
  });
301
329
 
330
+ [
331
+ ClientMembers.c.MEMBERS_EXECUTE,
332
+ ClientMembers.c.MEMBERS_UPDATE
333
+ ].forEach((type) => {
334
+ this.dispatch(constants.HOST.LOAD, {id: id, type: type});
335
+
336
+ ClientMembers.fetch(
337
+ constants.HOST.ASSET_TYPE,
338
+ type,
339
+ id,
340
+ (res) => {
341
+ var payload = {id: id, type: type, res: res};
342
+
343
+ this.dispatch(
344
+ constants.HOST.LOAD_SUCCESS,
345
+ payload
346
+ );
347
+ },
348
+ (res) => {
349
+ this.dispatch(constants.HOST.LOAD_FAIL, {type: type});
350
+ this.flux.actions.flashMessage(res.error.message);
351
+ });
352
+ });
353
+
302
354
  this.dispatch(constants.HOST.LOAD, {id: id, type: 'RESOURCES'});
303
355
 
304
356
  ClientList.fetchResources(
@@ -425,6 +477,7 @@ module.exports = {
425
477
  this.dispatch(constants.VARIABLE.LOAD, {id: id, type: type});
426
478
 
427
479
  ClientMembers.fetch(
480
+ constants.VARIABLE.ASSET_TYPE,
428
481
  type,
429
482
  id,
430
483
  (res) => {
data/app/src/app.js CHANGED
@@ -25,7 +25,8 @@ var AppStore = require('./stores/app_store'),
25
25
  RouteStore = require('./stores/route_store'),
26
26
  SearchStore = require('./stores/search_store'),
27
27
  AuditStore = require('./stores/audit_store'),
28
- ResourcesStore = require('./stores/resources_store');
28
+ ResourcesStore = require('./stores/resources_store'),
29
+ GraphStore = require('./stores/graph_store');
29
30
 
30
31
  var UserStore = require('./stores/user_store'),
31
32
  GroupStore = require('./stores/group_store'),
@@ -38,10 +39,11 @@ var router = Router.create({routes: routes, location: Router.HistoryLocation});
38
39
 
39
40
  var stores = {
40
41
  AppStore: new AppStore(),
41
- RouteStore: new RouteStore({router: router}),
42
+ route: new RouteStore(),
42
43
  search: new SearchStore(),
43
44
  audit: new AuditStore(),
44
45
  resources: new ResourcesStore(),
46
+ graph: new GraphStore(),
45
47
  user: new UserStore(),
46
48
  group: new GroupStore(),
47
49
  host: new HostStore(),
@@ -67,7 +69,9 @@ Promise.all([
67
69
  }
68
70
  })
69
71
  ]).then(() => {
70
- router.run(function(Handler) {
72
+ router.run(function(Handler, state) {
73
+ flux.actions.routes.transition(state.params);
74
+
71
75
  React.render(
72
76
  <Handler flux={flux} />,
73
77
  document.getElementById('wrapper')
@@ -0,0 +1,24 @@
1
+ /* global conjur */
2
+
3
+ 'use strict';
4
+
5
+ var request = require('superagent');
6
+
7
+ module.exports = function(kind, id, callback, errCallback) {
8
+ var defaultCallback = function(res) {
9
+ if (res.error) {
10
+ errCallback(res);
11
+ } else {
12
+ callback(res);
13
+ }
14
+ };
15
+
16
+ request
17
+ .get('/api/authz/' +
18
+ window.encodeURIComponent(conjur.app.configuration.account) +
19
+ '/roles?' +
20
+ window.encodeURIComponent('roles[]') +
21
+ '=' +
22
+ window.encodeURIComponent(conjur.app.configuration.account + ':' + kind + ':' + id))
23
+ .end(defaultCallback);
24
+ };
@@ -9,7 +9,7 @@ var c = module.exports.c = {
9
9
  MEMBERS_UPDATE: 'MEMBERS_UPDATE'
10
10
  };
11
11
 
12
- module.exports.fetch = function(type, id, callback, errCallback) {
12
+ module.exports.fetch = function(asset_type, type, id, callback, errCallback) {
13
13
  var defaultCallback = function(res) {
14
14
  if (res.error) {
15
15
  errCallback(res);
@@ -30,8 +30,8 @@ module.exports.fetch = function(type, id, callback, errCallback) {
30
30
  .get('/api/authz/' +
31
31
  conjur.app.configuration.account +
32
32
  '/roles/allowed_to/' +
33
- privilege +
34
- '/variable/' +
33
+ privilege + '/' +
34
+ asset_type + '/' +
35
35
  window.encodeURIComponent(id))
36
36
  .end(defaultCallback);
37
37
  };
@@ -94,6 +94,15 @@ module.exports = React.createClass({
94
94
  }
95
95
  }
96
96
 
97
+ // hide new event role:index / all_roles , which is used by role graph only
98
+ if ((ev.kind === 'role') && (ev.action === 'index')) {
99
+ return false;
100
+ }
101
+
102
+ if ((ev.kind === 'role') && (ev.action === 'all_roles')) {
103
+ return false;
104
+ }
105
+
97
106
  return true;
98
107
  });
99
108
  }
@@ -3,8 +3,7 @@
3
3
  var React = require('react'),
4
4
  Fluxxor = require('fluxxor'),
5
5
  FluxMixin = Fluxxor.FluxMixin(React),
6
- StoreWatchMixin = Fluxxor.StoreWatchMixin,
7
- Router = require('react-router');
6
+ StoreWatchMixin = Fluxxor.StoreWatchMixin;
8
7
 
9
8
  var AuditTable = require('../audit/table'),
10
9
  Annotations = require('../generic/annotations'),
@@ -15,16 +14,38 @@ var AuditTable = require('../audit/table'),
15
14
  module.exports = React.createClass({
16
15
  displayName: 'CustomView',
17
16
 
18
- mixins: [FluxMixin, StoreWatchMixin('audit', 'resources'), Router.State],
17
+ mixins: [FluxMixin, StoreWatchMixin('audit', 'resources')],
18
+
19
+ askForNewData(state) {
20
+ var actions = this.getFlux().actions;
21
+
22
+ actions.audit.loadForResource(state.kind, state.id);
23
+ actions.resources.loadOne(state.kind, state.id);
24
+ },
25
+
26
+ componentDidMount() {
27
+ this.askForNewData(this.state);
28
+ },
29
+
30
+ componentWillUpdate(nextProps, nextState) {
31
+ if ((this.state.kind !== nextState.kind) ||
32
+ (this.state.id !== nextState.id)) {
33
+ this.askForNewData(nextState);
34
+ }
35
+
36
+ return true;
37
+ },
19
38
 
20
39
  getStateFromFlux() {
21
40
  var flux = this.getFlux(),
22
- kind = unescape(this.getParams().kind),
23
- id = unescape(this.getParams().id),
41
+ kind = flux.store('route').getParam('kind'),
42
+ id = flux.store('route').getParam('id'),
24
43
  audit = flux.store('audit').getEventFor(kind, id),
25
44
  resource = flux.store('resources').getResource(kind, id);
26
45
 
27
46
  return {
47
+ kind: kind,
48
+ id: id,
28
49
  loading: {
29
50
  audit: audit.loading,
30
51
  resource: resource.loading
@@ -58,14 +79,5 @@ module.exports = React.createClass({
58
79
  isLoading={this.state.loading.audit} />
59
80
  </div>
60
81
  );
61
- },
62
-
63
- componentDidMount() {
64
- var actions = this.getFlux().actions,
65
- kind = unescape(this.getParams().kind),
66
- id = unescape(this.getParams().id);
67
-
68
- actions.audit.loadForResource(kind, id);
69
- actions.resources.loadOne(kind, id);
70
82
  }
71
83
  });
@@ -97,16 +97,36 @@ module.exports = React.createClass({
97
97
  return null;
98
98
  },
99
99
 
100
+ getInitialState() {
101
+ return {showActivity: false};
102
+ },
103
+
104
+ toggleActivity(e) {
105
+ e.preventDefault();
106
+
107
+ this.setState({showActivity: !this.state.showActivity});
108
+ },
109
+
100
110
  render() {
101
111
  var data = this.getData(this.props.audit);
112
+ var activity_body = [];
113
+
114
+ var msg = this.state.showActivity ? 'Hide' : 'Show graph';
115
+
116
+ if (this.state.showActivity) {
117
+ activity_body.push(
118
+ <div className="b-dashboard-activity__graph">
119
+ <Chart options={this.props.options}
120
+ data={data} />
121
+ </div>
122
+ );
123
+ }
102
124
 
103
125
  return (
104
126
  <div className="b-dashboard-activity">
105
127
  <h2>Activity<Refresh show={this.props.isLoading} /></h2>
106
- <div className="b-dashboard-activity__graph">
107
- <Chart options={this.props.options}
108
- data={data} />
109
- </div>
128
+ <a href="#" onClick={this.toggleActivity}>{msg}</a>
129
+ {activity_body}
110
130
  </div>
111
131
  );
112
132
  }
@@ -58,6 +58,15 @@ var FoldableAuditSection = React.createClass({
58
58
  isLoading = isLoading || false;
59
59
 
60
60
  var filter = function(e) {
61
+ // hide new event role:index / all_roles , which is used by role graph only
62
+ if ((e.kind === 'role') && (e.action === 'index')) {
63
+ return false;
64
+ }
65
+
66
+ if ((e.kind === 'role') && (e.action === 'all_roles')) {
67
+ return false;
68
+ }
69
+
61
70
  return (
62
71
  e.hasOwnProperty('error') || e.allowed === false
63
72
  );
@@ -79,6 +88,14 @@ var FoldableAuditSection = React.createClass({
79
88
  isLoading = isLoading || false;
80
89
 
81
90
  var filter = function(e) {
91
+ // hide new event role:index / all_roles , which is used by role graph only
92
+ if ((e.kind === 'role') && (e.action === 'index')) {
93
+ return false;
94
+ }
95
+
96
+ if ((e.kind === 'role') && (e.action === 'all_roles')) {
97
+ return false;
98
+ }
82
99
 
83
100
  if (e.action === 'check') {
84
101
  return false;
@@ -1,7 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var React = require('react'),
4
- Link = require('react-router').Link,
4
+ Router = require('react-router'),
5
+ Link = Router.Link,
5
6
  includes = require('lodash/collection/includes');
6
7
 
7
8
  /** render a link to the role represented by this.props.id