conjur-asset-ui 1.4.2 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +8 -3
  3. data/CHANGELOG.md +10 -0
  4. data/Makefile +19 -0
  5. data/README.md +0 -3
  6. data/Rakefile +22 -17
  7. data/TODO.md +0 -23
  8. data/app/.csscomb.json +304 -0
  9. data/app/.eslintignore +3 -0
  10. data/app/.eslintrc +265 -0
  11. data/app/config/preprocessor.js +19 -0
  12. data/app/config/webpack.js +124 -0
  13. data/app/gulpfile.js +96 -0
  14. data/app/package.json +86 -0
  15. data/app/src/actions.js +550 -0
  16. data/app/src/app.js +83 -0
  17. data/app/src/clients/audit.js +34 -0
  18. data/app/src/clients/auth.js +24 -0
  19. data/app/src/clients/generic.js +52 -0
  20. data/app/src/clients/graph.js +7 -0
  21. data/app/src/clients/layer_members.js +18 -0
  22. data/app/src/clients/list.js +31 -0
  23. data/app/src/clients/members.js +20 -0
  24. data/app/src/clients/request.js +531 -0
  25. data/app/src/clients/search.js +5 -0
  26. data/app/src/components/app/__tests__/app-test.js +22 -0
  27. data/app/src/components/app/app.js +36 -0
  28. data/app/src/components/app/wrapper.js +17 -0
  29. data/app/src/components/audit/__tests__/table_header-test.js +22 -0
  30. data/app/src/components/audit/box.js +9 -0
  31. data/app/src/components/audit/constants.js +5 -0
  32. data/app/src/components/audit/entry.js +105 -0
  33. data/app/src/components/audit/fields_mixin.js +11 -0
  34. data/app/src/components/audit/humanize_event.js +213 -0
  35. data/app/src/components/audit/table.js +64 -0
  36. data/app/src/components/audit/table_header.js +37 -0
  37. data/app/src/components/audit/timestamp.js +28 -0
  38. data/app/src/components/auth/login.js +177 -0
  39. data/app/src/components/auth/login.less +71 -0
  40. data/app/src/components/auth/logout.js +42 -0
  41. data/app/src/components/auth/logout.less +21 -0
  42. data/app/src/components/chart/chart.js +540 -0
  43. data/app/src/components/chart/chart_helper_mixin.js +78 -0
  44. data/app/src/components/custom/list.js +3 -0
  45. data/app/src/components/custom/view.js +81 -0
  46. data/app/src/components/dashboard/activity.js +144 -0
  47. data/app/src/components/dashboard/dashboard.js +46 -0
  48. data/app/src/components/flash/flash.js +98 -0
  49. data/app/src/components/flash/flash.less +3 -0
  50. data/app/src/components/generic/__tests__/time-test.js +42 -0
  51. data/app/src/components/generic/annotations.js +39 -0
  52. data/app/src/components/generic/breadcrumbs.js +57 -0
  53. data/app/src/components/generic/foldable_audit_section.js +204 -0
  54. data/app/src/components/generic/list.js +141 -0
  55. data/app/src/components/generic/list_factory.js +41 -0
  56. data/app/src/components/generic/resource_link.js +64 -0
  57. data/app/src/components/generic/role_link.js +66 -0
  58. data/app/src/components/generic/tab_mixin.js +146 -0
  59. data/app/src/components/generic/time.js +32 -0
  60. data/app/src/components/graph/__tests__/collapse-test.js +133 -0
  61. data/app/src/components/graph/__tests__/edges-from-vertices-test.js +48 -0
  62. data/app/src/components/graph/__tests__/new-vertex-set-test.js +16 -0
  63. data/app/src/components/graph/__tests__/next-id-test.js +27 -0
  64. data/app/src/components/graph/__tests__/role-kind-from-id-test.js +24 -0
  65. data/app/src/components/graph/__tests__/vertices-from-edges-test.js +72 -0
  66. data/app/src/components/graph/graph.js +449 -0
  67. data/app/src/components/graph/graph.less +39 -0
  68. data/app/src/components/graph/helpers.js +368 -0
  69. data/app/src/components/group/list.js +3 -0
  70. data/app/src/components/group/view.js +153 -0
  71. data/app/src/components/host/activity.js +111 -0
  72. data/app/src/components/host/details.js +28 -0
  73. data/app/src/components/host/executors.js +77 -0
  74. data/app/src/components/host/host_link.js +18 -0
  75. data/app/src/components/host/list.js +3 -0
  76. data/app/src/components/host/updaters.js +77 -0
  77. data/app/src/components/host/view.js +145 -0
  78. data/app/src/components/layer/list.js +3 -0
  79. data/app/src/components/layer/view.js +197 -0
  80. data/app/src/components/navbar/__tests__/navbar-test.js +21 -0
  81. data/app/src/components/navbar/nav_search_form.js +40 -0
  82. data/app/src/components/navbar/navbar.js +96 -0
  83. data/app/src/components/notfound/notfound.js +35 -0
  84. data/app/src/components/notfound/notfound.less +21 -0
  85. data/app/src/components/owned_resources/owned_resources.js +84 -0
  86. data/app/src/components/owned_resources/owned_resources_box.js +101 -0
  87. data/app/src/components/permissions/permissions.js +138 -0
  88. data/app/src/components/permissions/permissions_table.js +101 -0
  89. data/app/src/components/policy/list.js +3 -0
  90. data/app/src/components/policy/view.js +107 -0
  91. data/app/src/components/refresh/refresh.js +29 -0
  92. data/app/src/components/refresh/refresh.less +15 -0
  93. data/app/src/components/search/group.js +43 -0
  94. data/app/src/components/search/group_heading.js +50 -0
  95. data/app/src/components/search/group_title.js +37 -0
  96. data/app/src/components/search/result_item.js +55 -0
  97. data/app/src/components/search/search.js +118 -0
  98. data/app/src/components/user/activity.js +112 -0
  99. data/app/src/components/user/details.js +30 -0
  100. data/app/src/components/user/list.js +3 -0
  101. data/app/src/components/user/pubkeys.js +118 -0
  102. data/app/src/components/user/pubkeys.less +56 -0
  103. data/app/src/components/user/view.js +143 -0
  104. data/app/src/components/variable/activity.js +101 -0
  105. data/app/src/components/variable/details.js +46 -0
  106. data/app/src/components/variable/fetchers.js +77 -0
  107. data/app/src/components/variable/list.js +3 -0
  108. data/app/src/components/variable/updaters.js +77 -0
  109. data/app/src/components/variable/view.js +115 -0
  110. data/app/src/constants.js +36 -0
  111. data/{public → app/src}/images/conjur-logo.svg +0 -0
  112. data/{public → app/src}/images/icon-client-pc.svg +0 -0
  113. data/{public → app/src}/images/icon-environment.png +0 -0
  114. data/{public → app/src}/images/icon-person.svg +0 -0
  115. data/{public → app/src}/images/icon-policy.png +0 -0
  116. data/{public → app/src}/images/icon-resource.png +0 -0
  117. data/{public → app/src}/images/icon-service-dots.svg +0 -0
  118. data/{public → app/src}/images/icon-variable.png +0 -0
  119. data/app/src/pages/index.html +27 -0
  120. data/app/src/routes.js +64 -0
  121. data/app/src/stores/app_store.js +35 -0
  122. data/app/src/stores/audit_store.js +143 -0
  123. data/app/src/stores/graph_store.js +51 -0
  124. data/app/src/stores/group_store.js +104 -0
  125. data/app/src/stores/host_store.js +111 -0
  126. data/app/src/stores/layer_store.js +115 -0
  127. data/app/src/stores/policy_store.js +88 -0
  128. data/app/src/stores/resources_store.js +115 -0
  129. data/app/src/stores/route_store.js +21 -0
  130. data/app/src/stores/search_store.js +77 -0
  131. data/app/src/stores/user_store.js +109 -0
  132. data/app/src/stores/variable_store.js +93 -0
  133. data/app/src/styles/bootstrap.less +54 -0
  134. data/{public/css → app/src/styles}/styles.less +26 -82
  135. data/app/src/utils.js +38 -0
  136. data/app/src/vendor/pace.js +2 -0
  137. data/conjur-asset-ui.gemspec +3 -4
  138. data/docker/assets-build/Dockerfile +12 -0
  139. data/docker/conjur-ui/Dockerfile +33 -0
  140. data/docker/conjur-ui/README.md +38 -0
  141. data/docker/conjur-ui/mime.types +90 -0
  142. data/docker/conjur-ui/nginx.conf +110 -0
  143. data/docker/conjur-ui/start.py +72 -0
  144. data/docker/conjur-ui/start.sh +18 -0
  145. data/docker/conjur-ui/test.env +8 -0
  146. data/lib/conjur-asset-ui-version.rb +1 -1
  147. data/lib/conjur/command/ui.rb +10 -2
  148. data/lib/conjur/webserver/home.rb +3 -3
  149. data/lib/conjur/webserver/login.rb +1 -1
  150. data/lib/conjur/webserver/server.rb +16 -4
  151. data/public/js/views/roleGraph.js +91 -0
  152. metadata +167 -105
  153. data/.jshintrc +0 -41
  154. data/bower.json +0 -98
  155. data/gulpfile.js +0 -139
  156. data/package.json +0 -47
  157. data/preprocessor.js +0 -7
  158. data/public/_client_libs.html +0 -9
  159. data/public/index.html.erb +0 -63
  160. data/public/js/init.js +0 -196
  161. data/public/js/lib/pace.js +0 -2
  162. data/public/js/lib/sorted-set.no-require.js +0 -1145
  163. data/public/js/lib/sorted-set.no-require.js.txt +0 -6
  164. data/public/js/models/groupRecord.js +0 -72
  165. data/public/js/models/hostRecord.js +0 -60
  166. data/public/js/models/layerRecord.js +0 -79
  167. data/public/js/models/namespace.js +0 -12
  168. data/public/js/models/policyList.js +0 -16
  169. data/public/js/models/policyRecord.js +0 -54
  170. data/public/js/models/record.js +0 -117
  171. data/public/js/models/resourceList.js +0 -87
  172. data/public/js/models/userList.js +0 -25
  173. data/public/js/models/userRecord.js +0 -75
  174. data/public/js/models/variableList.js +0 -27
  175. data/public/js/models/variableRecord.js +0 -77
  176. data/public/js/routers.js +0 -242
  177. data/public/js/views/annotations.js +0 -47
  178. data/public/js/views/audit.js +0 -369
  179. data/public/js/views/breadcrumbs.js +0 -62
  180. data/public/js/views/chart.js +0 -617
  181. data/public/js/views/dashboard.js +0 -146
  182. data/public/js/views/generic.js +0 -122
  183. data/public/js/views/group.js +0 -109
  184. data/public/js/views/groups.js +0 -26
  185. data/public/js/views/host.js +0 -200
  186. data/public/js/views/hosts.js +0 -26
  187. data/public/js/views/layer.js +0 -146
  188. data/public/js/views/layers.js +0 -26
  189. data/public/js/views/mixins/search.js +0 -22
  190. data/public/js/views/mixins/tabs.js +0 -154
  191. data/public/js/views/namespaces.js +0 -40
  192. data/public/js/views/navSearch.js +0 -36
  193. data/public/js/views/owned.js +0 -184
  194. data/public/js/views/permissions.js +0 -254
  195. data/public/js/views/policies.js +0 -26
  196. data/public/js/views/policy.js +0 -70
  197. data/public/js/views/resource.js +0 -59
  198. data/public/js/views/role.js +0 -63
  199. data/public/js/views/searchResults.js +0 -212
  200. data/public/js/views/sections.js +0 -226
  201. data/public/js/views/time.js +0 -39
  202. data/public/js/views/user.js +0 -297
  203. data/public/js/views/users.js +0 -26
  204. data/public/js/views/variable.js +0 -310
  205. data/public/js/views/variables.js +0 -26
  206. data/spec/javascripts/helpers/.gitkeep +0 -0
  207. data/spec/javascripts/support/jasmine.yml +0 -112
  208. data/spec/javascripts/support/jasmine_helper.rb +0 -22
  209. data/spec/javascripts/support/run.html.erb +0 -23
  210. data/spec/javascripts/views/AuditSpec.js +0 -22
  211. data/spec/javascripts/views/AuditSpec.ls +0 -18
@@ -1,70 +0,0 @@
1
- /** @jsx React.DOM */
2
- /* global conjur, React, ReactBootstrap, _ */
3
-
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={this.props.data.owner}/></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">
38
- <div className="audit auditGroup">
39
- <AuditBox roles={[policy.id]} tabview={true} />
40
- </div>
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,59 +0,0 @@
1
- /** @jsx React.DOM */
2
- /* global conjur, React, _ */
3
-
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
- // guard against misuse such as https://github.com/conjurinc/conjur-asset-ui/issues/78
18
- if (resourceId === undefined) {
19
- return React.DOM.em({}, 'undefined');
20
- }
21
-
22
- var tokens = resourceId.split(':'),
23
- kind = tokens[1],
24
- id = tokens[tokens.length - 1],
25
- text = this.props.text || id;
26
-
27
- var knownTypes = ['user', 'group', 'layer', 'host', 'variable', 'policy'],
28
- resourceIsKnown = _.contains(knownTypes, kind);
29
-
30
- // we shouldn't build links to for unsupported resources
31
- var href = '/ui/' + conjur.utils.pluralize(kind) + '/' + window.encodeURIComponent(id);
32
- var classes = ['resource-link'];
33
-
34
- if (!this.props.noIcon) {
35
- if (resourceIsKnown) {
36
- classes.push(kind);
37
- } else {
38
- classes.push('abstract');
39
-
40
- if (text === id) {
41
- text = [kind, text].join(':'); // prepend kind to id
42
- }
43
- }
44
- } else if (text === id) {
45
- text = [kind, text].join(':'); // prepend kind to id
46
- }
47
-
48
- return (
49
- <a className={classes.join(' ')} href={href}>{text}</a>
50
- );
51
- }
52
- });
53
-
54
- }).bind(conjur.views)
55
- (
56
- conjur,
57
- React,
58
- _
59
- );
@@ -1,63 +0,0 @@
1
- /** @jsx React.DOM */
2
- /* global conjur, React, _ */
3
-
4
- (function(conjur, React, _) {
5
- 'use strict';
6
-
7
- /** render a link to the role represented by this.props.id
8
- Example: <RoleLink id='ci:user:jon'/>
9
- */
10
- this.RoleLink = React.createClass({
11
- render: function() {
12
- // guard against misuse such as https://github.com/conjurinc/conjur-asset-ui/issues/78
13
- if (this.props.id === undefined) {
14
- return React.DOM.em({}, 'undefined');
15
- }
16
-
17
- var tokens = this.props.id.split(':'),
18
- kind = tokens[1],
19
- id = tokens[tokens.length-1],
20
- href,
21
- classes = ['role-link'],
22
- knownTypes = ['user', 'group', 'layer', 'host', 'policy'],
23
- kindIsKnown,
24
- text;
25
-
26
- if (tokens.length === 1) { // just username
27
- kind = 'user';
28
- id = tokens[0];
29
- }
30
-
31
- // TODO: shouldn't point to unknown types
32
- href = '/ui/' + conjur.utils.pluralize(kind) + '/' + window.encodeURIComponent(id);
33
- kindIsKnown = _.contains(knownTypes, kind);
34
- text = id;
35
-
36
- if (!this.props.noIcon) {
37
- if (kindIsKnown) {
38
- classes.push(kind);
39
- } else {
40
- classes.push('abstract'); // we have no picture for abstract role yet
41
-
42
- if (text === id) {
43
- text = [kind, text].join(':'); // prepend kind to id
44
- }
45
- }
46
- } else if (text === id) {
47
- text = [kind, text].join(':'); // prepend kind to id
48
- }
49
-
50
- return (
51
- <a className={classes.join(' ')} href={href}>
52
- {text}
53
- </a>
54
- );
55
- }
56
- });
57
-
58
- }).bind(conjur.views)
59
- (
60
- conjur,
61
- React,
62
- _
63
- );
@@ -1,212 +0,0 @@
1
- /**@jsx React.DOM*/
2
- /* global conjur, React, jQuery, _ */
3
-
4
-
5
- (function(conjur, React, $, _) {
6
- 'use strict';
7
-
8
- var ResourceLink = conjur.views.ResourceLink,
9
- RoleLink = conjur.views.RoleLink;
10
-
11
- var SearchGroupTitle = React.createClass({
12
- render: function() {
13
- return (
14
- <span>{this.title()}</span>
15
- );
16
- },
17
-
18
- title: function() {
19
- var words = this.props.data.kind.replace(/[-_]/, ' ').split(' ');
20
-
21
- words[words.length - 1] = conjur.utils.pluralize(words[words.length - 1]);
22
-
23
- return (
24
- words.map(_.str.capitalize).join(' ') + ' (' + this.props.data.items.length + ')'
25
- );
26
- }
27
- });
28
-
29
- var SearchGroupHeading = React.createClass({
30
- render: function() {
31
- var targetId = '#search-collapse-' + this.props.data.kind;
32
-
33
- return (
34
- <div className="panel-heading">
35
- <h4 className="panel-title">
36
- <a data-toggle="collapse"
37
- data-target={targetId}
38
- className={'group-heading' + this.props.data.kind}>
39
- <SearchGroupTitle data={this.props.data} />
40
- </a>
41
- </h4>
42
- </div>
43
- );
44
- },
45
-
46
- title: function() {
47
- var words = this.props.data.kind.replace(/[-_]/, ' ').split(' ');
48
-
49
- words[words.length - 1] = conjur.utils.pluralize(words[words.length - 1]);
50
-
51
- return (
52
- words.map(_.str.capitalize).join(' ') + ' (' + this.props.data.items.length + ')'
53
- );
54
- }
55
- });
56
-
57
- var SearchResultItem = React.createClass({
58
- render: function() {
59
- return (
60
- <div className="item">
61
- <h4>{this.titleLink()}</h4>
62
- <div className="details">
63
- <strong> ID: </strong> <ResourceLink data={this.props.data.id}
64
- noIcon="true" />
65
- <strong> Owner: </strong> <RoleLink id={this.props.data.owner}
66
- noIcon="true" />
67
- </div>
68
- <div className="comment">
69
- {this.commentText()}
70
- </div>
71
- </div>
72
- );
73
- },
74
-
75
- commentText: function() {
76
- var annots = this.annotationsMap();
77
-
78
- return annots.description || '';
79
- },
80
-
81
- titleLink: function(){
82
- var annots = this.annotationsMap();
83
-
84
- return (
85
- <ResourceLink data={this.props.data.id} text={annots.name} />
86
- );
87
- },
88
-
89
- annotationsMap: function(){
90
- if (this._annotationsMap) {
91
- return this._annotationsMap;
92
- }
93
-
94
- var map = this._annotationsMap = {};
95
-
96
- (this.props.data.annotations || []).forEach(function(a) {
97
- map[a.name] = a.value;
98
- });
99
-
100
- return map;
101
- }
102
- });
103
-
104
- // accepts props like data: { kind:"", items:[] }
105
- var SearchGroup = React.createClass({
106
- render: function() {
107
- var id = 'search-group-' + this.props.data.kind;
108
-
109
- var items = this.props.data.items.map(function(r) {
110
- return (
111
- <SearchResultItem data={r}/>
112
- );
113
- });
114
-
115
- return (
116
- <div id={id} className="panel panel-default search-group">
117
- <SearchGroupHeading data={this.props.data}/>
118
- <div id={'search-collapse-' + this.props.data.kind}
119
- className="panel-collapse collapse in">
120
- <div className="panel-body">
121
- {items}
122
- </div>
123
- </div>
124
- </div>
125
- );
126
- }
127
- });
128
-
129
- var SearchResults = this.SearchResults = React.createClass({
130
- render: function() {
131
- var results = this.props.data.results;
132
-
133
- var grouped = _.groupBy(results, function(r) {
134
- return r.id.split(':')[1];
135
- });
136
-
137
- // Don't care about these
138
- delete grouped['environment-variables'];
139
- delete grouped.notification;
140
- delete grouped.queue;
141
-
142
- var groups = _.map(grouped, function(items, key) {
143
- var data = {items: items, kind: key}; // - prevent editor barfing
144
- return <SearchGroup data={data}/>;
145
- });
146
-
147
- var scores = {
148
- 'policy': 1,
149
- 'layer': 2,
150
- 'group': 3,
151
- 'host': 4,
152
- 'user': 5,
153
- 'variable': 6,
154
- 'key_pair': 7
155
- };
156
-
157
- groups.sort(function(a, b) {
158
- return (
159
- (scores[a.props.data.kind] || 100) -
160
- (scores[b.props.data.kind] || 100)
161
- );
162
- });
163
-
164
- var toc = groups.map(function(g) {
165
- var gid = '#search-group-' + g.props.data.kind;
166
-
167
- return (
168
- <div className="toc-item">
169
- <a href={gid}><SearchGroupTitle data={g.props.data} /></a>
170
- </div>
171
- );
172
- });
173
-
174
- var heading = 'Found ' + this.props.data.results.length +
175
- ' resources matching "' + this.props.data.search + '"';
176
-
177
- return (
178
- <div id="searchResults">
179
- <div className="searchResults">
180
- <h3> { heading } </h3>
181
- <div className="search-results-toc">
182
- {toc}
183
- </div>
184
- <div className="search-results">
185
- {groups}
186
- </div>
187
- </div>
188
- </div>
189
- );
190
- }
191
- });
192
-
193
- SearchResults.search = function(search, container) {
194
- container = container || document.getElementById('content');
195
-
196
- $.get(
197
- conjur.app.endpoints.authz('resources', {search: search.replace('-',' ')}),
198
- function(results) {
199
- var data = {search: search, results: results};
200
- React.renderComponent(<SearchResults data={data}/>, container);
201
- }
202
- );
203
- };
204
-
205
-
206
- }).bind(conjur.views)
207
- (
208
- conjur,
209
- React,
210
- jQuery,
211
- _
212
- );
@@ -1,226 +0,0 @@
1
- /** @jsx React.DOM */
2
- /* global conjur, _, React */
3
-
4
- (function(conjur, _, React) {
5
- 'use strict';
6
-
7
- var defaultNumberOfElements = 3;
8
-
9
- // TODO: refactor to avoid this copypaste from audit.js
10
- var known_rolsource_types = [ 'user','group','host','layer','policy'];
11
-
12
- var ResourceLink = conjur.views.ResourceLink,
13
- Time = conjur.views.Time;
14
-
15
- var FoldableAuditSection = React.createClass({
16
- statics: {
17
- updates: function(audit) {
18
- var filter = function(e) {
19
- return (
20
- e.action === 'check' && e.privilege === 'update' &&
21
- !(e.hasOwnProperty('error') ||
22
- e.allowed === false)
23
- );
24
- };
25
-
26
- var getItem = function(e) {
27
- var user = [
28
- (<Time timestamp={e.timestamp} relative="time from now" />),
29
- (<ResourceLink id={e.user} />)
30
- ];
31
-
32
- if (e.user !== e.acting_as) {
33
- user.push(' acting as ');
34
- user.push(<ResourceLink id={e.acting_as} />);
35
- }
36
-
37
- return user;
38
- };
39
-
40
- return (
41
- <FoldableAuditSection audit={audit} title="Updates"
42
- filter={filter} getItem={getItem} />
43
- );
44
- },
45
-
46
- warnings: function(audit) {
47
- var filter = function(e) {
48
- return (
49
- e.hasOwnProperty('error') || e.allowed === false
50
- );
51
- };
52
-
53
- var getItem = function(e) {
54
- return window.AuditEntry(e);
55
- };
56
-
57
- return (
58
- <FoldableAuditSection audit={audit} title="Warnings"
59
- filter={filter} getItem={getItem} />
60
- );
61
- },
62
-
63
- changes: function(audit) {
64
- var filter = function(e) {
65
-
66
- if (e.action === 'check') {
67
- return false;
68
- }
69
- if (e.kind === 'audit' || e.kind === 'annotation') {
70
- return false;
71
- }
72
-
73
- // TODO: refactor code to avoid copypaste from audit.js
74
- // remove internal resources creation
75
- if ((e.role!=null) && (e.role.split(':')[1] == '@')) {
76
- return false;
77
- }
78
- if ((e.resource!=null) && (e.resource.split(':')[1] == '@')) {
79
- return false;
80
- }
81
- if ((e.resource!=null) && (e.resource.split(':')[1] == 'secret')) {
82
- return false;
83
- }
84
- if ((e.grantee!=null) && (e.grantee.split(':')[1] == '@')) {
85
- return false;
86
- }
87
- // hide automated creation of roles corresponding to resources of known type
88
- if ((e.kind=="role") && (e.action=="create")) {
89
- var rolekind = e.role.split(':')[1];
90
- if (_.contains(known_rolsource_types, rolekind)) {
91
- return false;
92
- }
93
- }
94
-
95
- // anything else is permission change
96
- return true;
97
- };
98
-
99
- var getItem = function(e) {
100
- return window.AuditEntry(e);
101
- };
102
-
103
- return (
104
- <FoldableAuditSection audit={audit} title="Recent permission model changes"
105
- filter={filter} getItem={getItem} />
106
- );
107
- }
108
- },
109
-
110
- propTypes: {
111
- audit: React.PropTypes.arrayOf(React.PropTypes.object),
112
- filter: React.PropTypes.func,
113
- getItem: React.PropTypes.func,
114
- howMuch: React.PropTypes.number,
115
- title: React.PropTypes.string
116
- },
117
-
118
- defaultFilter: function(e) {
119
- return typeof e === 'object';
120
- },
121
-
122
- defaultGetItem: function(e) {
123
- return e.id;
124
- },
125
-
126
- getDefaultProps: function() {
127
- return {
128
- audit: [],
129
- filter: this.defaultFilter,
130
- getItem: this.defaultGetItem,
131
- howMuch: defaultNumberOfElements,
132
- title: 'Audit Section'
133
- };
134
- },
135
-
136
- getInitialState: function() {
137
- return {showAll: false};
138
- },
139
-
140
- handleClick: function(e) {
141
- e.preventDefault();
142
-
143
- this.setState({showAll: !this.state.showAll});
144
- },
145
-
146
- reverseChronology: function(a, b) {
147
- if (a.timestamp < b.timestamp) {
148
- return 1;
149
- } else if (a.timestamp > b.timestamp) {
150
- return -1;
151
- } else {
152
- return 0;
153
- }
154
- },
155
-
156
- getItems: function() {
157
- var items = _.filter(this.props.audit,
158
- this.props.filter)
159
- .sort(this.reverseChronology),
160
- className = [
161
- 'b-audit-section__item',
162
- 'list-group-item',
163
- 'list-group-item-noborder'
164
- ].join(' ');
165
-
166
- if (!this.state.showAll) {
167
- items = _.first(items, this.props.howMuch);
168
- }
169
-
170
- return _.map(items, function(e) {
171
- return (
172
- <li className={className}
173
- key={'audit-entry-' + e.id}>
174
- {this.props.getItem(e)}
175
- </li>
176
- );
177
- }.bind(this));
178
- },
179
-
180
- render: function() {
181
- var items = this.getItems(),
182
- msg = this.state.showAll ?
183
- 'Show only top ' + (this.props.howMuch) :
184
- 'See full history',
185
- empty = items.length === 0,
186
- lessThan = items.length < (this.props.howMuch),
187
- body = [(<h2 key="title">{this.props.title}</h2>)];
188
-
189
- if (!empty) {
190
- body.push(
191
- <ul className="b-audit-section__list list-unstyled list-group"
192
- key="list">
193
- {items}
194
- </ul>
195
- );
196
- } else {
197
- body.push(
198
- <p key="info">There is no history records available</p>
199
- );
200
- }
201
-
202
- if (!lessThan) {
203
- body.push(
204
- <div className="b-audit-section__toggle"
205
- key="toggle">
206
- <a href="#" onClick={this.handleClick}>{msg}</a>
207
- </div>
208
- );
209
- }
210
-
211
- return (
212
- <div className="b-audit-section">
213
- {body}
214
- </div>
215
- );
216
- }
217
- });
218
-
219
- this.FoldableAuditSection = FoldableAuditSection;
220
-
221
- }).bind(conjur.views)
222
- (
223
- conjur,
224
- _,
225
- React
226
- );