conjur-asset-ui 1.3.0 → 1.3.1

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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/.jshintrc +41 -0
  4. data/Gemfile +3 -1
  5. data/README.md +34 -0
  6. data/Rakefile +69 -1
  7. data/bower.json +93 -0
  8. data/conjur-asset-ui.gemspec +1 -1
  9. data/features/navigation_bar.feature +31 -0
  10. data/features/step_definitions/custom_step.rb +32 -0
  11. data/features/support/env.rb +38 -0
  12. data/features/support/hooks.rb +30 -0
  13. data/features/support/world.rb +17 -0
  14. data/gulpfile.js +140 -0
  15. data/lib/conjur/command/ui.rb +1 -1
  16. data/lib/conjur/webserver/server.rb +14 -9
  17. data/lib/conjur-asset-ui-version.rb +1 -1
  18. data/package.json +47 -0
  19. data/preprocessor.js +7 -0
  20. data/public/_client_libs.html +2 -15
  21. data/public/css/styles.less +170 -4
  22. data/public/index.html.erb +5 -7
  23. data/public/js/init.js +183 -97
  24. data/public/js/lib/sorted-set.no-require.js +3 -28
  25. data/public/js/models/groupRecord.js +12 -11
  26. data/public/js/models/hostRecord.js +6 -7
  27. data/public/js/models/layerRecord.js +12 -11
  28. data/public/js/models/namespace.js +2 -0
  29. data/public/js/models/policyList.js +3 -1
  30. data/public/js/models/policyRecord.js +6 -7
  31. data/public/js/models/record.js +24 -23
  32. data/public/js/models/resourceList.js +28 -10
  33. data/public/js/models/userList.js +7 -2
  34. data/public/js/models/userRecord.js +7 -8
  35. data/public/js/models/variableList.js +18 -7
  36. data/public/js/models/variableRecord.js +13 -12
  37. data/public/js/routers.js +72 -26
  38. data/public/js/views/annotations.js +38 -27
  39. data/public/js/views/audit.js +23 -17
  40. data/public/js/views/chart.js +471 -0
  41. data/public/js/views/dashboard.js +94 -58
  42. data/public/js/views/generic.js +16 -9
  43. data/public/js/views/group.js +94 -55
  44. data/public/js/views/groups.js +3 -7
  45. data/public/js/views/host.js +75 -44
  46. data/public/js/views/hosts.js +2 -6
  47. data/public/js/views/layer.js +127 -82
  48. data/public/js/views/layers.js +2 -6
  49. data/public/js/views/mixins/search.js +12 -5
  50. data/public/js/views/mixins/tabs.js +95 -55
  51. data/public/js/views/navSearch.js +16 -5
  52. data/public/js/views/owned.js +14 -8
  53. data/public/js/views/permissions.js +244 -178
  54. data/public/js/views/policies.js +2 -4
  55. data/public/js/views/policy.js +65 -38
  56. data/public/js/views/resource.js +49 -34
  57. data/public/js/views/role.js +52 -37
  58. data/public/js/views/searchResults.js +205 -138
  59. data/public/js/views/time.js +26 -13
  60. data/public/js/views/user.js +178 -55
  61. data/public/js/views/users.js +2 -7
  62. data/public/js/views/variable.js +226 -45
  63. data/public/js/views/variables.js +4 -8
  64. metadata +20 -20
  65. data/public/_client_code.html +0 -42
  66. data/public/css/bootstrap.css +0 -7
  67. data/public/fonts/glyphicons-halflings-regular.eot +0 -0
  68. data/public/fonts/glyphicons-halflings-regular.svg +0 -229
  69. data/public/fonts/glyphicons-halflings-regular.ttf +0 -0
  70. data/public/fonts/glyphicons-halflings-regular.woff +0 -0
  71. data/public/js/lib/JSXTransformer.js +0 -10862
  72. data/public/js/lib/async.js +0 -958
  73. data/public/js/lib/backbone.js +0 -2
  74. data/public/js/lib/bootstrap.js +0 -6
  75. data/public/js/lib/less.js +0 -16
  76. data/public/js/lib/moment.js +0 -7768
  77. data/public/js/lib/react-bootstrap.js +0 -5346
  78. data/public/js/lib/react-bootstrap.min.js +0 -4
  79. data/public/js/lib/underscore-min.js +0 -6
  80. data/public/js/lib/underscore.string.min.js +0 -1
  81. data/public/js/main.js +0 -57
@@ -1,188 +1,254 @@
1
1
  /** @jsx React.DOM */
2
-
3
- var PermissionsTable = React.createClass({
4
- render: function() {
5
- var rows = [];
6
- var resources = _.sortBy(this.props.resources, function(r){
7
- return r.id; // this way it will be sorting by (kind, id)
2
+ /* global conjur, React, jQuery, _ */
3
+
4
+ (function(conjur, React, $, _) {
5
+ 'use strict';
6
+
7
+ var ResourceLink = conjur.views.ResourceLink,
8
+ RoleLink = conjur.views.RoleLink;
9
+
10
+ var PermissionsTable = this.PermissionsTable = React.createClass({
11
+ render: function() {
12
+ var rows = [];
13
+
14
+ var resources = _.sortBy(this.props.resources, function(r) {
15
+ return r.id; // this way it will be sorting by (kind, id)
16
+ });
17
+
18
+ resources.forEach(function(r) {
19
+ var rowspan = r.permissions.length + 1,
20
+ parts = r.id.split(':'),
21
+ kind = parts[1]; // ignore env?
22
+
23
+ var cells = [
24
+ (<td rowSpan={rowspan}> <ResourceLink id={r.id}/> </td>),
25
+ (<td rowSpan={rowspan}> {kind} </td>)
26
+ ];
27
+
28
+ if (rowspan === 1) {
29
+ cells.push(<td colSpan="3"> full permissions </td>);
30
+ }
31
+
32
+ rows.push(
33
+ (<tr key={r.id}>{cells}</tr>)
34
+ );
35
+
36
+ if (rowspan > 1) {
37
+ rows.push(r.permissions.map(function(p) {
38
+ return (
39
+ <PermissionRow data={p}/>
40
+ );
41
+ }));
42
+ }
43
+
44
+ });
45
+
46
+ rows = _.flatten(rows);
47
+
48
+ var showhidelink = (
49
+ <div>
50
+ <a onClick={this.props.hideHandler}>Hide all &laquo;</a>
51
+ </div>
52
+ );
53
+
54
+ if (this.props.tabview) {
55
+ showhidelink = '';
56
+ }
57
+
58
+ if (rows.length === 0) {
59
+ return (
60
+ <span>None</span>
61
+ );
62
+ }
63
+
64
+ return (
65
+ <div>
66
+ {showhidelink}
67
+ <table>
68
+ <thead>
69
+ <tr>
70
+ <th> Resource </th>
71
+ <th> Kind </th>
72
+ <th> Privilege </th>
73
+ <th> Can Grant? </th>
74
+ <th> Granted By </th>
75
+ </tr>
76
+ </thead>
77
+ <tbody>
78
+ {rows}
79
+ </tbody>
80
+ </table>
81
+ </div>
82
+ );
83
+ }
8
84
  });
9
- resources.forEach(function(r){
10
- var rowspan = r.permissions.length + 1;
11
- var parts = r.id.split(":");
12
- var id = parts[2];
13
- var kind = parts[1]; // ignore env?
14
- var cells = [
15
- <td rowSpan={rowspan}> <ResourceLink id={r.id}/> </td>,
16
- <td rowSpan={rowspan}> {kind} </td>
17
- ];
18
- if(rowspan == 1){
19
- cells.push(<td colSpan="3"> full permissions </td>);
20
- }
21
-
22
- rows.push(
23
- <tr key={r.id}>{cells}</tr>
24
- );
25
-
26
- if(rowspan > 1){
27
- rows.push(r.permissions.map(function(p){
28
- return <PermissionRow data={p}/>
29
- }));
30
- }
31
85
 
32
- });
33
- rows = _.flatten(rows);
34
-
35
- var showhidelink = <div><a onClick={this.props.hideHandler}>Hide all &laquo;</a></div>;
36
-
37
- if (this.props.tabview) {
38
- showhidelink="";
39
- }
40
-
41
- if (rows.length==0) {
42
- return <span>None</span>;
43
- }
44
-
45
- return <div>
46
- {showhidelink}
47
- <table>
48
- <thead>
49
- <tr>
50
- <th> Resource </th>
51
- <th> Kind </th>
52
- <th> Privilege </th>
53
- <th> Can Grant? </th>
54
- <th> Granted By </th>
55
- </tr>
56
- </thead>
57
- <tbody> {rows} </tbody>
58
- </table>
59
- </div>
60
- }
61
- });
62
-
63
-
64
- // Renders a permission as a tr
65
- var PermissionRow = React.createClass({
66
- render: function(){
67
- var p = this.props.data;
68
- return <tr>
69
- <td> { p.privilege } </td>
70
- <td> { p.grant_option ? "yes" : "no" }</td>
71
- <td> <RoleLink id={p.grantor}/> </td>
72
- </tr>;
73
- }
74
- });
75
-
76
- var PermissionsSummary = React.createClass({
77
- render: function() {
78
- var expand = "";
79
- if ( this.props.length > 0 )
80
- expand = <span>
81
- <br/>
82
- <span>
83
- <a onClick={this.props.expandHandler}>Show all &raquo;</a>
84
- </span>
85
- </span>;
86
-
87
- return <div>
88
- <span>
89
- {this.props.length} permissions
90
- </span>
91
- {expand}
92
- </div>
93
- }
94
- });
95
-
96
- var Permissions = React.createClass({
97
- getInitialState: function() {
98
- return {resources: null, loaded: false, expand: false}
99
- },
100
-
101
- expand: function(event) {
102
- this.setState({expand: true})
103
- },
104
-
105
- collapse: function(event) {
106
- this.setState({expand: false})
107
- },
108
-
109
- componentWillMount: function() { // shouldn't it be done in model??? otherwise it will re-load stuff on each re-rendering of parent block
110
- if ( this.props.roles ) {
111
- $.get(this.url(), function(data){
112
- this.setPermissions(data);
113
- }.bind(this));
114
- }
115
- },
116
-
117
- setPermissions: function(_resources) {
118
- /**
119
- * Filter out owned resources.
120
- * Filter out permissions on resources which are not held by the current role.
121
- */
122
- var resources;
123
-
124
- if ( this.props.owned ) {
125
- var ownedIds = _.pluck(this.props.owned, 'id');
126
- resources = _resources.filter(function(r) {
127
- return !_.contains(ownedIds, r.id);
128
- });
129
- }
130
- else
131
- resources = _resources;
132
-
133
- var roleSet = {};
134
- this.props.roles.forEach(function(r) {
135
- roleSet[r] = r;
136
- });
137
86
 
138
- var cleanResources = resources.filter(function(item) {
139
- return item.id.split(':')[1] !== "secret"; // assets of 'secret' kind are internal
87
+ // Renders a permission as a tr
88
+ var PermissionRow = React.createClass({
89
+ render: function() {
90
+ var p = this.props.data;
91
+
92
+ return (
93
+ <tr>
94
+ <td>{p.privilege}</td>
95
+ <td>{p.grant_option ? 'yes' : 'no'}</td>
96
+ <td><RoleLink id={p.grantor}/></td>
97
+ </tr>
98
+ );
99
+ }
140
100
  });
141
101
 
142
- cleanResources.forEach(function(resource) {
143
- var permissions = resource.permissions;
144
- var hasPermissions = [];
145
- permissions.forEach(function(permission) {
146
- if ( roleSet.hasOwnProperty(permission['role']) )
147
- hasPermissions.push(permission);
148
- });
149
- resource.permissions = hasPermissions;
102
+ var PermissionsSummary = React.createClass({
103
+ render: function() {
104
+ var expand = '';
105
+
106
+ if (this.props.length > 0) {
107
+ expand = (
108
+ <span>
109
+ <br/>
110
+ <span>
111
+ <a onClick={this.props.expandHandler}>Show all &raquo;</a>
112
+ </span>
113
+ </span>
114
+ );
115
+ }
116
+
117
+ return (
118
+ <div>
119
+ <span>
120
+ {this.props.length} permissions
121
+ </span>
122
+ {expand}
123
+ </div>
124
+ );
125
+ }
150
126
  });
151
127
 
152
- this.setState({resources: cleanResources, loaded: true});
153
- },
154
-
155
- render: function(){
156
- var content;
157
- if (this.state.loaded) {
158
- if ( this.state.expand || this.props.tabview )
159
- content = <PermissionsTable resources={this.state.resources} hideHandler={this.collapse} tabview={this.props.tabview}/>
160
- else
161
- content = <PermissionsSummary length={this.state.resources.length} expandHandler={this.expand} />
162
- }
163
- else {
164
- if ( this.props.roles )
165
- content = <span>Loading...</span>
166
- else
167
- content = "You are not authorized to see these permissions";
168
- }
169
-
170
- var cx = React.addons.classSet;
171
- var classes = cx({
172
- permissions: true,
173
- loading: !this.state.loaded
128
+ this.Permissions = React.createClass({
129
+ getInitialState: function() {
130
+ return {resources: null, loaded: false, expand: false};
131
+ },
132
+
133
+ expand: function() {
134
+ this.setState({expand: true});
135
+ },
136
+
137
+ collapse: function() {
138
+ this.setState({expand: false});
139
+ },
140
+
141
+ componentWillMount: function() {
142
+ // shouldn't it be done in model??? otherwise it will
143
+ // re-load stuff on each re-rendering of parent block
144
+ if (this.props.roles) {
145
+ $.get(this.url(), function(data) {
146
+ this.setPermissions(data);
147
+ }.bind(this));
148
+ }
149
+ },
150
+
151
+ setPermissions: function(_resources) {
152
+ /**
153
+ * Filter out owned resources.
154
+ * Filter out permissions on resources which are not held by the current role.
155
+ */
156
+ var resources;
157
+
158
+ if (this.props.owned) {
159
+ var ownedIds = _.pluck(this.props.owned, 'id');
160
+
161
+ resources = _resources.filter(function(r) {
162
+ return !_.contains(ownedIds, r.id);
163
+ });
164
+ } else {
165
+ resources = _resources;
166
+ }
167
+
168
+ var roleSet = {};
169
+
170
+ this.props.roles.forEach(function(r) {
171
+ roleSet[r] = r;
172
+ });
173
+
174
+ var cleanResources = resources.filter(function(item) {
175
+ // assets of 'secret' kind are internal
176
+ return item.id.split(':')[1] !== 'secret';
177
+ });
178
+
179
+ cleanResources.forEach(function(resource) {
180
+ var permissions = resource.permissions,
181
+ hasPermissions = [];
182
+
183
+ permissions.forEach(function(permission) {
184
+ if (roleSet.hasOwnProperty(permission.role)) {
185
+ hasPermissions.push(permission);
186
+ }
187
+ });
188
+
189
+ resource.permissions = hasPermissions;
190
+ });
191
+
192
+ this.setState({resources: cleanResources, loaded: true});
193
+ },
194
+
195
+ render: function() {
196
+ var content;
197
+
198
+ if (this.state.loaded) {
199
+ if (this.state.expand || this.props.tabview) {
200
+ content = (
201
+ <PermissionsTable resources={this.state.resources}
202
+ hideHandler={this.collapse}
203
+ tabview={this.props.tabview} />
204
+ );
205
+ } else {
206
+ content = (
207
+ <PermissionsSummary length={this.state.resources.length}
208
+ expandHandler={this.expand} />
209
+ );
210
+ }
211
+ } else {
212
+ if (this.props.roles) {
213
+ content = (
214
+ <span>Loading...</span>
215
+ );
216
+ } else {
217
+ content = 'You are not authorized to see these permissions';
218
+ }
219
+ }
220
+
221
+ var cx = React.addons.classSet;
222
+
223
+ var classes = cx({
224
+ permissions: true,
225
+ loading: !this.state.loaded
226
+ });
227
+
228
+ var permissionsheader = this.props.tabview ? '' : (<h3>Permissions held</h3>);
229
+
230
+ return (
231
+ <section className={classes}>
232
+ {permissionsheader}
233
+ <div id="permissionDetails">
234
+ {content}
235
+ </div>
236
+ </section>
237
+ );
238
+ },
239
+
240
+ url: function() {
241
+ return '/api/authz/' +
242
+ conjur.app.configuration.account +
243
+ '/resources?acting_as=' +
244
+ this.props.role;
245
+ }
174
246
  });
175
247
 
176
- var permissionsheader = this.props.tabview ? "" : <h3>Permissions held</h3>;
177
- return <section className={classes}>
178
- {permissionsheader}
179
- <div id="permissionDetails">
180
- {content}
181
- </div>
182
- </section>;
183
- },
184
-
185
- url: function(){
186
- return "/api/authz/" + conjur.app.configuration.account + "/resources?acting_as=" + this.props.role;
187
- }
188
- })
248
+ }).bind(conjur.views)
249
+ (
250
+ conjur,
251
+ React,
252
+ jQuery,
253
+ _
254
+ );
@@ -1,14 +1,12 @@
1
1
  /** @jsx React.DOM */
2
+ /* global conjur, React */
2
3
 
3
4
  (function(conjur, React) {
4
5
  'use strict';
5
6
 
6
7
  var GenericList = conjur.views.GenericList;
7
8
 
8
- var PolicyBox = this.PolicyBox = React.createClass({
9
- /*getInitialState: function() {
10
- return { currentNamespace: "", members: [] };
11
- },*/
9
+ this.PolicyBox = React.createClass({
12
10
  render: function() {
13
11
  return (
14
12
  <div className="policyBox">
@@ -1,43 +1,70 @@
1
1
  /** @jsx React.DOM */
2
+ /* global conjur, React, ReactBootstrap, _ */
2
3
 
3
- var Policy = React.createClass({
4
- mixins: [conjur.views.mixins.Tab],
5
- render: function() {
6
- var policy = this.props.data.policy;
7
- var id = policy.id.split(':')[2];
8
-
9
- //TODO: policy loader
10
- //TODO in CLI: why not save text of policy as an annotation?
11
- var overview_tab =
12
- <TabPane key="overview" tab="Overview">
13
- <dl className="dl-horizontal">
14
- <dt>Owner</dt>
15
- <dd><RoleLink id={policy.id}/></dd>
16
- </dl>
17
- </TabPane>;
18
-
19
- var permissions_tab = this.permissions_tab(policy.id);
20
- var memberships_tab = this.memberships_tab(policy.id);
21
- var annotations_tab = this.annotations_tab();
22
- var owned_tab = this.owned_tab();
23
-
24
- var audit_tab =
25
- <TabPane key="audit" tab="Recent Activity">
4
+ (function(conjur, React, ReactBootstrap, _) {
5
+ 'use strict';
6
+
7
+ var TabbedArea = ReactBootstrap.TabbedArea,
8
+ TabPane = ReactBootstrap.TabPane,
9
+ Tab = conjur.views.mixins.Tab,
10
+ RoleLink = conjur.views.RoleLink,
11
+ AuditBox = window.AuditBox;
12
+
13
+ this.Policy = React.createClass({
14
+ mixins: [Tab],
15
+
16
+ render: function() {
17
+ var policy = this.props.data.policy,
18
+ id = policy.id.split(':')[2];
19
+
20
+ //TODO: policy loader
21
+ //TODO in CLI: why not save text of policy as an annotation?
22
+ var overviewTab = (
23
+ <TabPane key="overview" tab="Overview">
24
+ <dl className="dl-horizontal">
25
+ <dt>Owner</dt>
26
+ <dd><RoleLink id={policy.id}/></dd>
27
+ </dl>
28
+ </TabPane>
29
+ );
30
+
31
+ var permissionsTab = this.permissionsTab(policy.id),
32
+ membershipsTab = this.membershipsTab(policy.id),
33
+ annotationsTab = this.annotationsTab(),
34
+ ownedTab = this.ownedTab();
35
+
36
+ var auditTab = (
37
+ <TabPane key="audit" tab="Recent Activity">
26
38
  <div className="audit auditGroup">
27
39
  <AuditBox roles={[policy.id]} tabview={true} />
28
40
  </div>
29
- </TabPane>;
30
- var tabs = _.compact( [ overview_tab, owned_tab, memberships_tab, permissions_tab,
31
- annotations_tab, audit_tab
32
- ] );
33
-
34
- return (
35
- <div className="policy">
36
- <h2>Policy {id}</h2>
37
- <TabbedArea defaultActiveKey="overview">
38
- {tabs}
39
- </TabbedArea>
40
- </div>
41
- );
42
- }
43
- });
41
+ </TabPane>
42
+ );
43
+
44
+ var tabs = _.compact([
45
+ overviewTab,
46
+ ownedTab,
47
+ membershipsTab,
48
+ permissionsTab,
49
+ annotationsTab,
50
+ auditTab
51
+ ]);
52
+
53
+ return (
54
+ <div className="policy">
55
+ <h2>Policy {id}</h2>
56
+ <TabbedArea defaultActiveKey="overview">
57
+ {tabs}
58
+ </TabbedArea>
59
+ </div>
60
+ );
61
+ }
62
+ });
63
+
64
+ }).bind(conjur.views)
65
+ (
66
+ conjur,
67
+ React,
68
+ ReactBootstrap,
69
+ _
70
+ );
@@ -1,39 +1,54 @@
1
1
  /** @jsx React.DOM */
2
+ /* global conjur, React, _ */
2
3
 
3
- /**
4
- Renders a link to the resource with id given by this.props.data.
5
-
6
- Includes a slick little icon for the following kinds:
7
- TODO which kinds?
8
- **/
9
- var ResourceLink = React.createClass({
10
- render: function(){
11
- var resourceId = this.props.id || this.props.data.id || this.props.data;
12
-
13
- var tokens = resourceId.split(':');
14
- var kind = tokens[1];
15
- var id = tokens[tokens.length - 1];
16
- var text = this.props.text || id;
17
-
18
- var known_types=['user','group','layer','host','variable','policy'];
19
- var resource_is_known = _.contains(known_types, kind);
20
-
21
- // we shouldn't build links to for unsupported resources
22
- var href = "/ui/" + conjur.utils.pluralize(kind) + "/" + encodeURIComponent(id);
23
- var classes = [ 'resource-link' ];
24
- if( !this.props.noIcon ) {
25
- if (resource_is_known) {
26
- classes.push(kind);
27
- } else {
28
- classes.push('abstract');
29
- if (text==id) {
30
- text=[kind,text].join(":"); // prepend kind to id
4
+ (function(conjur, React, _) {
5
+ 'use strict';
6
+
7
+ /**
8
+ Renders a link to the resource with id given by this.props.data.
9
+
10
+ Includes a slick little icon for the following kinds:
11
+ TODO which kinds?
12
+ **/
13
+ this.ResourceLink = React.createClass({
14
+ render: function() {
15
+ var resourceId = this.props.id || this.props.data.id || this.props.data;
16
+
17
+ var tokens = resourceId.split(':'),
18
+ kind = tokens[1],
19
+ id = tokens[tokens.length - 1],
20
+ text = this.props.text || id;
21
+
22
+ var knownTypes = ['user', 'group', 'layer', 'host', 'variable', 'policy'],
23
+ resourceIsKnown = _.contains(knownTypes, kind);
24
+
25
+ // we shouldn't build links to for unsupported resources
26
+ var href = '/ui/' + conjur.utils.pluralize(kind) + '/' + window.encodeURIComponent(id);
27
+ var classes = ['resource-link'];
28
+
29
+ if (!this.props.noIcon) {
30
+ if (resourceIsKnown) {
31
+ classes.push(kind);
32
+ } else {
33
+ classes.push('abstract');
34
+
35
+ if (text === id) {
36
+ text = [kind, text].join(':'); // prepend kind to id
37
+ }
38
+ }
39
+ } else if (text === id) {
40
+ text = [kind, text].join(':'); // prepend kind to id
31
41
  }
42
+
43
+ return (
44
+ <a className={classes.join(' ')} href={href}>{text}</a>
45
+ );
32
46
  }
33
- } else if (text==id) {
34
- text=[kind,text].join(":"); // prepend kind to id
35
- }
47
+ });
36
48
 
37
- return <a className={classes.join(' ')} href={href}>{text}</a>
38
- }
39
- });
49
+ }).bind(conjur.views)
50
+ (
51
+ conjur,
52
+ React,
53
+ _
54
+ );