conjur-asset-ui-api 1.1.1 → 1.2.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.
- checksums.yaml +4 -4
- data/Rakefile +2 -0
- data/compile_ls +5 -1
- data/conjur-asset-ui.gemspec +1 -0
- data/lib/conjur-asset-ui-version.rb +1 -1
- data/lib/conjur/webserver/home.rb +19 -13
- data/lib/conjur/webserver/login.rb +7 -0
- data/lib/conjur/webserver/renderer.rb +34 -0
- data/livescript/views/audit.ls +31 -19
- data/public/_client_code.html +37 -0
- data/public/_client_libs.html +21 -0
- data/public/css/styles.less +23 -10
- data/public/index.html.erb +71 -0
- data/public/js/main.js +33 -70
- data/public/js/models/groupRecord.js +35 -0
- data/public/js/models/hostRecord.js +26 -0
- data/public/js/models/layerRecord.js +38 -0
- data/public/js/models/record.js +36 -23
- data/public/js/models/userRecord.js +26 -0
- data/public/js/models/variableRecord.js +39 -0
- data/public/js/views/audit.js +53 -33
- data/public/js/views/dashboard.js +32 -5
- data/public/js/views/group.js +2 -1
- data/public/js/views/host.js +3 -2
- data/public/js/views/layer.js +3 -3
- data/public/js/views/owned.js +77 -0
- data/public/js/views/permissions.js +98 -36
- data/public/js/views/resource.js +3 -0
- data/public/js/views/user.js +3 -4
- data/spec/javascripts/helpers/.gitkeep +0 -0
- data/spec/javascripts/support/jasmine.yml +112 -0
- data/spec/javascripts/support/jasmine_helper.rb +22 -0
- data/spec/javascripts/support/run.html.erb +23 -0
- data/spec/javascripts/views/AuditSpec.js +22 -0
- data/spec/javascripts/views/AuditSpec.ls +18 -0
- metadata +39 -4
- data/public/index.html +0 -121
@@ -3,9 +3,9 @@
|
|
3
3
|
var DashboardSearchForm = React.createClass({
|
4
4
|
mixins: [ SearchMixin ],
|
5
5
|
|
6
|
-
render: function(){
|
6
|
+
render: function() {
|
7
7
|
return (
|
8
|
-
<form className="form-inline search" role="search" onSubmit={this.handleSubmit}>
|
8
|
+
<form id="dashboard-search" className="form-inline search" role="search" onSubmit={this.handleSubmit}>
|
9
9
|
<div className="form-group">
|
10
10
|
<input ref="input" type="text" className="form-control" placeholder="Search Conjur" value={this.props.searchText}>
|
11
11
|
</input>
|
@@ -16,6 +16,31 @@ var DashboardSearchForm = React.createClass({
|
|
16
16
|
}
|
17
17
|
});
|
18
18
|
|
19
|
+
var DashboardFrequent = React.createClass({
|
20
|
+
getInitialState: function() {
|
21
|
+
return {resources: [], loaded: false}
|
22
|
+
},
|
23
|
+
|
24
|
+
componentWillMount: function() {
|
25
|
+
$.get("/api/authz/" + conjurConfiguration.account + "/resources?owner=" + encodeURIComponent(userId), function(data) {
|
26
|
+
this.setState({resources: data, loaded: true});
|
27
|
+
}.bind(this));
|
28
|
+
},
|
29
|
+
|
30
|
+
render: function() {
|
31
|
+
var content;
|
32
|
+
if (this.state.loaded)
|
33
|
+
content = <OwnedResourcesBox resources={this.state.resources} />
|
34
|
+
else
|
35
|
+
content = <span>Loading...</span>
|
36
|
+
|
37
|
+
return <section>
|
38
|
+
<h3>Owned assets</h3>
|
39
|
+
{content}
|
40
|
+
</section>;
|
41
|
+
}
|
42
|
+
});
|
43
|
+
|
19
44
|
var Dashboard = React.createClass({
|
20
45
|
render: function(){
|
21
46
|
return (
|
@@ -23,10 +48,12 @@ var Dashboard = React.createClass({
|
|
23
48
|
<div className="row">
|
24
49
|
<DashboardSearchForm />
|
25
50
|
</div>
|
26
|
-
<div className="summary">
|
27
|
-
<div className="
|
51
|
+
<div className="row summary">
|
52
|
+
<div className="col-xs-6">
|
53
|
+
<DashboardFrequent />
|
28
54
|
</div>
|
29
|
-
<div className="
|
55
|
+
<div className="col-xs-6 audit">
|
56
|
+
<AuditTable src={'/api/audit/all'} caption={'Recent activity'} compact={true}/>
|
30
57
|
</div>
|
31
58
|
</div>
|
32
59
|
</div>
|
data/public/js/views/group.js
CHANGED
@@ -22,7 +22,8 @@ var Group = React.createClass({
|
|
22
22
|
</ul>
|
23
23
|
</dd>
|
24
24
|
</dl>
|
25
|
-
<
|
25
|
+
<OwnedResources owned={this.props.data.owned} />
|
26
|
+
<Permissions owned={this.props.data.owned} role={group.roleid}/>
|
26
27
|
<div className="audit auditGroup">
|
27
28
|
<AuditBox roles={[resourceId]} resources={[resourceId]}/>
|
28
29
|
</div>
|
data/public/js/views/host.js
CHANGED
@@ -20,7 +20,7 @@ var HostLink = React.createClass({
|
|
20
20
|
|
21
21
|
var Host = React.createClass({
|
22
22
|
render: function(){
|
23
|
-
var host = this.props.data;
|
23
|
+
var host = this.props.data.host;
|
24
24
|
return (
|
25
25
|
<div className="host">
|
26
26
|
<h2> Host {host.id} </h2>
|
@@ -30,7 +30,8 @@ var Host = React.createClass({
|
|
30
30
|
<dt> Created At </dt>
|
31
31
|
<dd> <Time timestamp={host.created_at}/> </dd>
|
32
32
|
</dl>
|
33
|
-
<
|
33
|
+
<OwnedResources owned={this.props.data.owned} />
|
34
|
+
<Permissions owned={this.props.data.owned} role={host.roleid}/>
|
34
35
|
<div className="audit auditHost">
|
35
36
|
<AuditBox roles={[host.roleid]} resources={[host.resource_identifier]}/>
|
36
37
|
</div>
|
data/public/js/views/layer.js
CHANGED
@@ -13,8 +13,7 @@ var Layer = React.createClass({
|
|
13
13
|
}
|
14
14
|
|
15
15
|
var layer = this.props.data.layer;
|
16
|
-
|
17
|
-
|
16
|
+
|
18
17
|
var hosts = layer.hosts.map(function (host) {
|
19
18
|
return <li>
|
20
19
|
<HostLink data={host} />
|
@@ -53,7 +52,8 @@ var Layer = React.createClass({
|
|
53
52
|
</ul>
|
54
53
|
</dd>
|
55
54
|
</dl>
|
56
|
-
<
|
55
|
+
<OwnedResources owned={this.props.data.owned} />
|
56
|
+
<Permissions owned={this.props.data.owned} role={layer.roleid}/>
|
57
57
|
<div className="audit auditLayer">
|
58
58
|
<AuditBox roles={[layer.roleid]} resources={[layer.resource_identifier]}/>
|
59
59
|
</div>
|
@@ -0,0 +1,77 @@
|
|
1
|
+
/** @jsx React.DOM */
|
2
|
+
|
3
|
+
var OwnedResourcesBox = React.createClass({
|
4
|
+
render: function() {
|
5
|
+
var items = this.props.resources.map(function(resource) {
|
6
|
+
return <li>
|
7
|
+
<ResourceLink data={resource} />
|
8
|
+
</li>
|
9
|
+
});
|
10
|
+
|
11
|
+
return <div className="owned">
|
12
|
+
<div className="hide-all">
|
13
|
+
<a onClick={this.props.hideHandler}>Hide all «</a>
|
14
|
+
</div>
|
15
|
+
<ul>
|
16
|
+
{items}
|
17
|
+
</ul>
|
18
|
+
</div>
|
19
|
+
}
|
20
|
+
});
|
21
|
+
|
22
|
+
var OwnedResourcesSummary = React.createClass({
|
23
|
+
render: function() {
|
24
|
+
var expand = "";
|
25
|
+
if ( this.props.length > 0 )
|
26
|
+
expand = <span>
|
27
|
+
<br/>
|
28
|
+
<span>
|
29
|
+
<a onClick={this.props.expandHandler}>Show all »</a>
|
30
|
+
</span>
|
31
|
+
</span>;
|
32
|
+
|
33
|
+
var message = "";
|
34
|
+
if ( this.props.length === 0 )
|
35
|
+
message = "none";
|
36
|
+
else
|
37
|
+
message = "" + this.props.length + " things";
|
38
|
+
|
39
|
+
return <div>
|
40
|
+
<span>
|
41
|
+
{message}
|
42
|
+
</span>
|
43
|
+
{expand}
|
44
|
+
</div>
|
45
|
+
}
|
46
|
+
});
|
47
|
+
|
48
|
+
var OwnedResources = React.createClass({
|
49
|
+
getInitialState: function() {
|
50
|
+
return { expand: false }
|
51
|
+
},
|
52
|
+
|
53
|
+
expand: function(event) {
|
54
|
+
this.setState({expand: true})
|
55
|
+
},
|
56
|
+
|
57
|
+
collapse: function(event) {
|
58
|
+
this.setState({expand: false})
|
59
|
+
},
|
60
|
+
|
61
|
+
render: function() {
|
62
|
+
var owned = this.props.owned;
|
63
|
+
|
64
|
+
var content = null;
|
65
|
+
if ( this.state.expand )
|
66
|
+
content = <OwnedResourcesBox resources={owned} hideHandler={this.collapse} />
|
67
|
+
else
|
68
|
+
content = <OwnedResourcesSummary length={owned.length} expandHandler={this.expand} />
|
69
|
+
|
70
|
+
return <section className="owned">
|
71
|
+
<h3>Owned assets</h3>
|
72
|
+
<div id="ownedDetails">
|
73
|
+
{content}
|
74
|
+
</div>
|
75
|
+
</section>;
|
76
|
+
}
|
77
|
+
});
|
@@ -1,33 +1,9 @@
|
|
1
1
|
/** @jsx React.DOM */
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
render: function(){
|
6
|
-
var p = this.props.data;
|
7
|
-
return (<tr>
|
8
|
-
<td> { p.privilege } </td>
|
9
|
-
<td> { p.grant_option ? "yes" : "no" }</td>
|
10
|
-
<td> <RoleLink id={p.grantor}/> </td>
|
11
|
-
</tr>);
|
12
|
-
}
|
13
|
-
})
|
14
|
-
|
15
|
-
|
16
|
-
var Permissions = React.createClass({
|
17
|
-
getInitialState: function(){
|
18
|
-
return {resources: [], loaded: false}
|
19
|
-
},
|
20
|
-
|
21
|
-
componentWillMount: function(){
|
22
|
-
$.get(this.url(), function(data){
|
23
|
-
this.setState({resources: data, loaded: true});
|
24
|
-
}.bind(this));
|
25
|
-
},
|
26
|
-
|
27
|
-
render: function(){
|
28
|
-
|
3
|
+
var PermissionsTable = React.createClass({
|
4
|
+
render: function() {
|
29
5
|
var rows = [];
|
30
|
-
var resources = _.sortBy(this.
|
6
|
+
var resources = _.sortBy(this.props.resources, function(r){
|
31
7
|
return r.id.split(':')[2];
|
32
8
|
});
|
33
9
|
resources.forEach(function(r){
|
@@ -56,11 +32,11 @@ var Permissions = React.createClass({
|
|
56
32
|
});
|
57
33
|
rows = _.flatten(rows);
|
58
34
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
35
|
+
return <div>
|
36
|
+
<div>
|
37
|
+
<a onClick={this.props.hideHandler}>Hide all «</a>
|
38
|
+
</div>
|
39
|
+
<table>
|
64
40
|
<thead>
|
65
41
|
<tr>
|
66
42
|
<th> Resource </th>
|
@@ -71,17 +47,103 @@ var Permissions = React.createClass({
|
|
71
47
|
</tr>
|
72
48
|
</thead>
|
73
49
|
<tbody> {rows} </tbody>
|
74
|
-
</table>
|
75
|
-
|
50
|
+
</table>
|
51
|
+
</div>
|
52
|
+
}
|
53
|
+
});
|
54
|
+
|
55
|
+
|
56
|
+
// Renders a permission as a tr
|
57
|
+
var PermissionRow = React.createClass({
|
58
|
+
render: function(){
|
59
|
+
var p = this.props.data;
|
60
|
+
return <tr>
|
61
|
+
<td> { p.privilege } </td>
|
62
|
+
<td> { p.grant_option ? "yes" : "no" }</td>
|
63
|
+
<td> <RoleLink id={p.grantor}/> </td>
|
64
|
+
</tr>;
|
65
|
+
}
|
66
|
+
});
|
67
|
+
|
68
|
+
var PermissionsSummary = React.createClass({
|
69
|
+
render: function() {
|
70
|
+
var expand = "";
|
71
|
+
if ( this.props.length > 0 )
|
72
|
+
expand = <span>
|
73
|
+
<br/>
|
74
|
+
<span>
|
75
|
+
<a onClick={this.props.expandHandler}>Show all »</a>
|
76
|
+
</span>
|
77
|
+
</span>;
|
78
|
+
|
79
|
+
return <div>
|
80
|
+
<span>
|
81
|
+
{this.props.length} permissions
|
82
|
+
</span>
|
83
|
+
{expand}
|
84
|
+
</div>
|
85
|
+
}
|
86
|
+
});
|
76
87
|
|
88
|
+
var Permissions = React.createClass({
|
89
|
+
getInitialState: function() {
|
90
|
+
return {resources: [], loaded: false, expand: false}
|
91
|
+
},
|
92
|
+
|
93
|
+
expand: function(event) {
|
94
|
+
this.setState({expand: true})
|
95
|
+
},
|
96
|
+
|
97
|
+
collapse: function(event) {
|
98
|
+
this.setState({expand: false})
|
99
|
+
},
|
100
|
+
|
101
|
+
componentWillMount: function() {
|
102
|
+
$.get(this.url(), function(data){
|
103
|
+
this.setPermissions(data);
|
104
|
+
}.bind(this));
|
105
|
+
},
|
106
|
+
|
107
|
+
setPermissions: function(_resources) {
|
108
|
+
/**
|
109
|
+
* Filter out owned resources
|
110
|
+
*/
|
111
|
+
var resources;
|
112
|
+
|
113
|
+
if ( this.props.owned ) {
|
114
|
+
var ownedIds = _.pluck(this.props.owned, 'id');
|
115
|
+
resources = _resources.filter(function(r) {
|
116
|
+
return !_.contains(ownedIds, r.id);
|
117
|
+
});
|
118
|
+
}
|
119
|
+
else
|
120
|
+
resources = _resources;
|
121
|
+
|
122
|
+
this.setState({resources: resources, loaded: true});
|
123
|
+
},
|
124
|
+
|
125
|
+
render: function(){
|
126
|
+
var content;
|
127
|
+
if (this.state.loaded) {
|
128
|
+
if ( this.state.expand )
|
129
|
+
content = <PermissionsTable resources={this.state.resources} hideHandler={this.collapse} />
|
130
|
+
else
|
131
|
+
content = <PermissionsSummary length={this.state.resources.length} expandHandler={this.expand} />
|
132
|
+
}
|
133
|
+
else {
|
134
|
+
content = <span>Loading...</span>
|
135
|
+
}
|
136
|
+
|
77
137
|
var cx = React.addons.classSet;
|
78
138
|
var classes = cx({
|
79
139
|
permissions: true,
|
80
140
|
loading: !this.state.loaded
|
81
141
|
});
|
82
142
|
return <section className={classes}>
|
83
|
-
<h3>Permissions held
|
84
|
-
|
143
|
+
<h3>Permissions held</h3>
|
144
|
+
<div id="permissionDetails">
|
145
|
+
{content}
|
146
|
+
</div>
|
85
147
|
</section>;
|
86
148
|
},
|
87
149
|
|
data/public/js/views/resource.js
CHANGED
@@ -9,6 +9,9 @@
|
|
9
9
|
var ResourceLink = React.createClass({
|
10
10
|
render: function(){
|
11
11
|
var resourceId = this.props.data;
|
12
|
+
if ( resourceId.id )
|
13
|
+
resourceId = resourceId.id;
|
14
|
+
|
12
15
|
var tokens = resourceId.split(':');
|
13
16
|
var kind = tokens[1];
|
14
17
|
var id = tokens[tokens.length - 1];
|
data/public/js/views/user.js
CHANGED
@@ -2,8 +2,7 @@
|
|
2
2
|
|
3
3
|
var User = React.createClass({
|
4
4
|
render: function(){
|
5
|
-
var user = this.props.data;
|
6
|
-
console.log("render User data=", user);
|
5
|
+
var user = this.props.data.user;
|
7
6
|
return (
|
8
7
|
<div className="user">
|
9
8
|
<h2> User {user.login} </h2>
|
@@ -11,12 +10,12 @@ var User = React.createClass({
|
|
11
10
|
<dt> Owner </dt>
|
12
11
|
<dd><RoleLink id={user.ownerid}/></dd>
|
13
12
|
</dl>
|
14
|
-
<
|
13
|
+
<OwnedResources owned={this.props.data.owned} />
|
14
|
+
<Permissions owned={this.props.data.owned} role={user.roleid}/>
|
15
15
|
<div className="audit auditGroup">
|
16
16
|
<AuditBox roles={[user.roleid]} resources={[user.resource_identifier]}/>
|
17
17
|
</div>
|
18
18
|
</div>
|
19
|
-
|
20
19
|
);
|
21
20
|
}
|
22
21
|
});
|
File without changes
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# src_files
|
2
|
+
#
|
3
|
+
# Return an array of filepaths relative to src_dir to include before jasmine specs.
|
4
|
+
# Default: []
|
5
|
+
#
|
6
|
+
# EXAMPLE:
|
7
|
+
#
|
8
|
+
# src_files:
|
9
|
+
# - lib/source1.js
|
10
|
+
# - lib/source2.js
|
11
|
+
# - dist/**/*.js
|
12
|
+
#
|
13
|
+
src_files:
|
14
|
+
- public/js/**/*.js
|
15
|
+
|
16
|
+
# stylesheets
|
17
|
+
#
|
18
|
+
# Return an array of stylesheet filepaths relative to src_dir to include before jasmine specs.
|
19
|
+
# Default: []
|
20
|
+
#
|
21
|
+
# EXAMPLE:
|
22
|
+
#
|
23
|
+
# stylesheets:
|
24
|
+
# - css/style.css
|
25
|
+
# - stylesheets/*.css
|
26
|
+
#
|
27
|
+
stylesheets:
|
28
|
+
- stylesheets/**/*.css
|
29
|
+
|
30
|
+
# helpers
|
31
|
+
#
|
32
|
+
# Return an array of filepaths relative to spec_dir to include before jasmine specs.
|
33
|
+
# Default: ["helpers/**/*.js"]
|
34
|
+
#
|
35
|
+
# EXAMPLE:
|
36
|
+
#
|
37
|
+
# helpers:
|
38
|
+
# - helpers/**/*.js
|
39
|
+
#
|
40
|
+
helpers:
|
41
|
+
- 'helpers/**/*.js'
|
42
|
+
|
43
|
+
# spec_files
|
44
|
+
#
|
45
|
+
# Return an array of filepaths relative to spec_dir to include.
|
46
|
+
# Default: ["**/*[sS]pec.js"]
|
47
|
+
#
|
48
|
+
# EXAMPLE:
|
49
|
+
#
|
50
|
+
# spec_files:
|
51
|
+
# - **/*[sS]pec.js
|
52
|
+
#
|
53
|
+
spec_files:
|
54
|
+
- '**/*[sS]pec.js'
|
55
|
+
|
56
|
+
# src_dir
|
57
|
+
#
|
58
|
+
# Source directory path. Your src_files must be returned relative to this path. Will use root if left blank.
|
59
|
+
# Default: project root
|
60
|
+
#
|
61
|
+
# EXAMPLE:
|
62
|
+
#
|
63
|
+
# src_dir: public
|
64
|
+
#
|
65
|
+
src_dir: public
|
66
|
+
|
67
|
+
# spec_dir
|
68
|
+
#
|
69
|
+
# Spec directory path. Your spec_files must be returned relative to this path.
|
70
|
+
# Default: spec/javascripts
|
71
|
+
#
|
72
|
+
# EXAMPLE:
|
73
|
+
#
|
74
|
+
# spec_dir: spec/javascripts
|
75
|
+
#
|
76
|
+
spec_dir:
|
77
|
+
|
78
|
+
# spec_helper
|
79
|
+
#
|
80
|
+
# Ruby file that Jasmine server will require before starting.
|
81
|
+
# Returned relative to your root path
|
82
|
+
# Default spec/javascripts/support/jasmine_helper.rb
|
83
|
+
#
|
84
|
+
# EXAMPLE:
|
85
|
+
#
|
86
|
+
# spec_helper: spec/javascripts/support/jasmine_helper.rb
|
87
|
+
#
|
88
|
+
spec_helper: spec/javascripts/support/jasmine_helper.rb
|
89
|
+
|
90
|
+
# boot_dir
|
91
|
+
#
|
92
|
+
# Boot directory path. Your boot_files must be returned relative to this path.
|
93
|
+
# Default: Built in boot file
|
94
|
+
#
|
95
|
+
# EXAMPLE:
|
96
|
+
#
|
97
|
+
# boot_dir: spec/javascripts/support/boot
|
98
|
+
#
|
99
|
+
boot_dir:
|
100
|
+
|
101
|
+
# boot_files
|
102
|
+
#
|
103
|
+
# Return an array of filepaths relative to boot_dir to include in order to boot Jasmine
|
104
|
+
# Default: Built in boot file
|
105
|
+
#
|
106
|
+
# EXAMPLE
|
107
|
+
#
|
108
|
+
# boot_files:
|
109
|
+
# - '**/*.js'
|
110
|
+
#
|
111
|
+
boot_files:
|
112
|
+
|