Skip to content

Commit c377e4f

Browse files
committed
what can user do
1 parent 2605c38 commit c377e4f

27 files changed

+264
-96
lines changed

app/index.html

+1
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ <h1>JavaScript Required</h1>
147147
<script src="scripts/services/userstore.js"></script>
148148
<script src="scripts/services/api.js"></script>
149149
<script src="scripts/services/auth.js"></script>
150+
<script src="scripts/services/authorization.js"></script>
150151
<script src="scripts/services/data.js"></script>
151152
<script src="scripts/services/discovery.js"></script>
152153
<script src="scripts/services/projects.js"></script>

app/scripts/controllers/deployment.js

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ angular.module('openshiftConsole')
3939
}
4040
];
4141

42+
$scope.isDeploymentConfig = ($routeParams.deploymentconfig) ? true : false;
4243
// if this is an RC it won't have deploymentconfig
4344
if ($routeParams.deploymentconfig){
4445
$scope.breadcrumbs.push({

app/scripts/controllers/otherResources.js

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ angular.module('openshiftConsole')
7070
if (!selected) {
7171
return;
7272
}
73+
$scope.selectedResource = APIService.kindToResource(selected.kind);
7374
// TODO - We can't watch because some of these resources do not support it (roles and rolebindings)
7475
DataService.list({
7576
group: selected.group,

app/scripts/directives/replicas.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ angular.module('openshiftConsole')
88
status: "=?",
99
spec: "=",
1010
disableScaling: "=?",
11-
scaleFn: "&?"
11+
scaleFn: "&?",
12+
isDc: "=?"
1213
},
1314
templateUrl: 'views/directives/replicas.html',
1415
link: function(scope) {

app/scripts/filters/resources.js

+51
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,57 @@ angular.module('openshiftConsole')
125125
return displayName;
126126
};
127127
})
128+
.filter('canI', function(AuthorizationService) {
129+
return function(resource, verb) {
130+
return AuthorizationService.canI(resource, verb);
131+
};
132+
})
133+
.filter('canIDoAny', function(canIFilter) {
134+
var resourceRulesMap = {
135+
"buildConfig": {"buildconfigs": ["delete", "update"], "buildconfigs/instantiate": ["create"]},
136+
"build": {"builds/clone": ["create"], "builds": ["create", "update"]},
137+
"deploymentConfig": {"horizontalpodautoscalers": ["create", "update"], "deploymentconfigs": ["create", "update"]},
138+
"deployment": {"replicationcontrollers": ["update", "delete"]},
139+
"imageStream": {"imagestreams": ["update", "delete"]},
140+
"persistentVolumeClaim": {"persistentvolumeclaims": ["update", "delete"]},
141+
"pod": {"pods": ["update", "delete"], "deploymentconfigs": ["update"]},
142+
"replicationController": {"horizontalpodautoscalers": ["create", "update"], "replicationcontrollers": ["create", "update"]},
143+
"route": {"routes": ["update", "delete"]},
144+
"service": {"services": ["update", "create", "delete"]},
145+
"project": {'projects': ['delete', 'update']},
146+
"configmaps": {"configmaps": ['delete', 'update']},
147+
"endpoints": {"endpoints": ['delete', 'update']},
148+
"horizontalpodautoscalers": {"horizontalpodautoscalers": ['delete', 'update']},
149+
"jobs": {"jobs": ['delete', 'update']}
150+
}
151+
return function(resource) {
152+
var canIDoAny = false;
153+
_.each(resourceRulesMap[resource], function(verbs, resource) {
154+
_.each(verbs, function(verb) {
155+
canIDoAny = canIFilter(resource,verb);
156+
});
157+
});
158+
return canIDoAny;
159+
};
160+
})
161+
.filter('canIScale', function(canIFilter) {
162+
return function(deploymentConfig) {
163+
var canIScale = false;
164+
if (deploymentConfig) {
165+
canIScale = canIFilter("deploymentconfigs/scale", "update");
166+
} else {
167+
canIScale = canIFilter("replicationcontrollers", "update");
168+
}
169+
return canIScale;
170+
};
171+
})
172+
// .filter('canInamespaced', function(AuthorizationService) {
173+
// var canI = false;
174+
175+
// return function(resource, verb, namespace) {
176+
// return AuthorizationService.canINamespaced(resource, verb, namespace);
177+
// };
178+
// })
128179
.filter('tags', function(annotationFilter) {
129180
return function(resource, /* optional */ annotationKey) {
130181
annotationKey = annotationKey || "tags";

app/scripts/services/authorization.js

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
'use strict';
2+
3+
angular.module("openshiftConsole")
4+
.factory("AuthorizationService", function($q, Logger, $interval, DataService, APIService){
5+
function AuthorizationService() {
6+
this.rules = null;
7+
this.intervalTimer = null;
8+
this.forceReload = false;
9+
this.canICreateSomeResource = false;
10+
this.projectNameRules = null;
11+
}
12+
13+
var normalizeRules = function(rules) {
14+
var normalizedRules = {};
15+
_.each(rules, function(rule) {
16+
_.each(rule.resources, function(resource) {
17+
normalizedRules[resource] = rule.verbs;
18+
});
19+
});
20+
return normalizedRules;
21+
};
22+
23+
AuthorizationService.prototype.getProjectRules = function(projectName) {
24+
var self = this;
25+
if (!self.rules || projectName !== self.projectNameRules) {
26+
// Making an API call to get the rules if:
27+
// - no rules are cached
28+
// - when need to force update the rules
29+
// - when switching between projects
30+
Logger.log("AuthorizationService, loading user rules");
31+
console.log("AuthorizationService, loading user rules");
32+
if (self.forceReload) {
33+
self.setForceReload(false);
34+
}
35+
if (!self.intervalTimer) {
36+
// Force rules reload every 3 minutes
37+
self.intervalTimer = $interval(function () {
38+
self.setForceReload(true);
39+
}, 180000);
40+
}
41+
self.projectNameRules = projectName;
42+
var object = {kind: "SelfSubjectRulesReview",
43+
apiVersion: "v1"
44+
};
45+
DataService.create('selfsubjectrulesreviews', null, object, {namespace: projectName}).then(
46+
function(data) {
47+
self.rules = normalizeRules(data.status.rules);
48+
}, function(data) {
49+
self.rules = null;
50+
});
51+
} else {
52+
// Using cached data.
53+
Logger.log("AuthorizationService, using cached rules");
54+
self.rules = self.getRules();
55+
}
56+
};
57+
58+
// Method to determine if user can perform specified action on a resource.
59+
// If resource is not specified, all resources will be checked if the action
60+
// can be performed.
61+
AuthorizationService.prototype.canI = function(resource, verb) {
62+
var rules = this.getRules();
63+
if (rules) {
64+
if (resource) {
65+
if (_.contains(rules[resource], verb)) {
66+
return true;
67+
} else {
68+
return false;
69+
}
70+
} else {
71+
var canIDoAction = false
72+
_.each(rules, function(verbs) {
73+
if (_.contains(verbs, verb)) {
74+
canIDoAction = true;
75+
return false;
76+
}
77+
});
78+
return canIDoAction;
79+
}
80+
} else {
81+
return false;
82+
}
83+
};
84+
85+
AuthorizationService.prototype.setForceReload = function(bool) {
86+
this.forceReload = bool;
87+
};
88+
89+
AuthorizationService.prototype.getRules = function() {
90+
return this.rules;
91+
};
92+
93+
return new AuthorizationService();
94+
});

app/scripts/services/projects.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
angular.module('openshiftConsole')
44
.factory('ProjectsService',
5-
function($location, $q, $routeParams, AuthService, DataService, annotationNameFilter) {
5+
function($location, $q, $routeParams, AuthService, DataService, annotationNameFilter, AuthorizationService) {
66

77

88
var cleanEditableAnnotations = function(resource) {
@@ -23,6 +23,7 @@ angular.module('openshiftConsole')
2323
return AuthService
2424
.withUser()
2525
.then(function() {
26+
AuthorizationService.getProjectRules(projectName);
2627
var context = {
2728
// TODO: swap $.Deferred() for $q.defer()
2829
projectPromise: $.Deferred(),
@@ -34,6 +35,7 @@ angular.module('openshiftConsole')
3435
.then(function(project) {
3536
context.project = project;
3637
context.projectPromise.resolve(project);
38+
3739
// TODO: fix need to return context & projectPromise
3840
return [project, context];
3941
}, function(e) {

app/views/browse/_deployment-details.html

+5-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<status-icon status="deployment | deploymentStatus"></status-icon>
1717
{{deployment | deploymentStatus}}
1818
<span style="margin-left: 7px;">
19-
<button ng-show="!rollBackCollapsed && (deployment | deploymentStatus) == 'Complete' && !(deployment | deploymentIsLatest : deploymentConfig) && !deployment.metadata.deletionTimestamp" ng-disabled="(deploymentConfigDeploymentsInProgress[deploymentConfigName] | hashSize) > 0" type="button" class="btn btn-default btn-xs" ng-click="rollBackCollapsed = !rollBackCollapsed">Roll Back</button>
19+
<button ng-if="'deploymentconfigrollbacks' | canI : 'create'" ng-show="!rollBackCollapsed && (deployment | deploymentStatus) == 'Complete' && !(deployment | deploymentIsLatest : deploymentConfig) && !deployment.metadata.deletionTimestamp" ng-disabled="(deploymentConfigDeploymentsInProgress[deploymentConfigName] | hashSize) > 0" type="button" class="btn btn-default btn-xs" ng-click="rollBackCollapsed = !rollBackCollapsed">Roll Back</button>
2020
<div ng-show="rollBackCollapsed" class="well well-sm">
2121
Use the following settings from {{deployment.metadata.name}} when rolling back:
2222
<div class="checkbox">
@@ -39,7 +39,7 @@
3939
<!-- disabled until we have an api endpoint for retry
4040
<button ng-show="(deployment | deploymentStatus) == 'Failed'" type="button" ng-click="retryFailedDeployment(deployment)" ng-disabled="(deploymentConfigDeploymentsInProgress[deploymentConfigName] | hashSize) > 0" class="btn btn-default btn-xs" ng-if="(deployment | deploymentIsLatest : deploymentConfig) && !deployment.metadata.deletionTimestamp">Retry</button>
4141
-->
42-
<button ng-show="(deployment | deploymentIsInProgress) && !deployment.metadata.deletionTimestamp" type="button" ng-click="cancelRunningDeployment(deployment)" class="btn btn-default btn-xs">Cancel</button>
42+
<button ng-if="'replicationcontrollers' | canI : 'update'" ng-show="(deployment | deploymentIsInProgress) && !deployment.metadata.deletionTimestamp" type="button" ng-click="cancelRunningDeployment(deployment)" class="btn btn-default btn-xs">Cancel</button>
4343
</span>
4444
</dd>
4545
<dt ng-if-start="deployment | isDeployment">Deployment config:</dt>
@@ -86,11 +86,12 @@ <h3>Template</h3>
8686
images-by-docker-reference="imagesByDockerReference"
8787
builds="builds"
8888
detailed="true"
89-
add-health-check-url="{{(!deploymentConfig || isActive) ? healthCheckURL : ''}}">
89+
add-health-check-url="{{((!deploymentConfig || isActive) && ('deploymentconfigs' | canI : 'update')) ? healthCheckURL : ''}}">
9090
</pod-template>
9191
<h4>Volumes</h4>
9292
<p ng-if="!deployment.spec.template.spec.volumes.length">
93-
<a ng-href="project/{{project.metadata.name}}/attach-pvc?deployment={{deployment.metadata.name}}">Attach storage</a>
93+
<a ng-if="'replicationcontrollers' | canI : 'update'" ng-href="project/{{project.metadata.name}}/attach-pvc?deployment={{deployment.metadata.name}}">Attach storage</a>
94+
<i ng-if="!('replicationcontrollers' | canI : 'update')">none</i>
9495
</p>
9596
<volumes volumes="deployment.spec.template.spec.volumes" namespace="project.metadata.name"></volumes>
9697
</div>

app/views/browse/_pod-details.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ <h4>Container {{containerStatus.name}}</h4>
6262
<dd>{{containerStatus.ready}}</dd>
6363
<dt>Restart Count:</dt>
6464
<dd>{{containerStatus.restartCount}}</dd>
65-
<div ng-if="(!containerStatus.state.running || !containerStatus.ready) && !(pod | debugLabel)" class="debug-pod-action">
65+
<div ng-if="(!containerStatus.state.running || !containerStatus.ready) && !(pod | debugLabel) && ('pods' | canI : 'create')" class="debug-pod-action">
6666
<a href="" ng-click="debugTerminal(containerStatus.name)" role="button">Debug in terminal</a>
6767
</div>
6868
</dl>

app/views/browse/build-config.html

+6-5
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ <h1>
1616
data-toggle="tooltip"
1717
data-original-title="Building from build configuration {{buildConfig.metadata.name}} has been paused.">
1818
</span>
19-
<div class="pull-right dropdown" ng-if="buildConfig">
19+
<div class="pull-right dropdown" ng-if="buildConfig" ng-hide="!('buildConfig' | canIDoAny)">
2020
<!-- Primary Actions -->
2121
<button
2222
class="btn btn-default hidden-xs"
23+
ng-if="'buildconfigs/instantiate' | canI : 'create'"
2324
ng-click="startBuild()">
2425
Start Build
2526
</button>
@@ -33,22 +34,22 @@ <h1>
3334
class="dropdown-toggle actions-dropdown-kebab visible-xs-inline"
3435
data-toggle="dropdown"><i class="fa fa-ellipsis-v"></i><span class="sr-only">Actions</span></a>
3536
<ul class="dropdown-menu actions action-button">
36-
<li class="visible-xs-inline">
37+
<li class="visible-xs-inline" ng-if="'buildconfigs/instantiate' | canI : 'create'">
3738
<a href=""
3839
role="button"
3940
ng-click="startBuild()">Start Build</a>
4041
</li>
41-
<li>
42+
<li ng-if="'buildconfigs' | canI : 'update'">
4243
<a ng-href="{{buildConfig | editResourceURL}}" role="button">Edit</a>
4344
</li>
44-
<li>
45+
<li ng-if="'buildconfigs' | canI : 'update'">
4546
<edit-link
4647
resource="buildConfig"
4748
kind="BuildConfig"
4849
alerts="alerts">
4950
</edit-link>
5051
</li>
51-
<li>
52+
<li ng-if="'buildconfigs' | canI : 'delete'">
5253
<delete-link
5354
kind="BuildConfig"
5455
resource-name="{{buildConfig.metadata.name}}"

app/views/browse/build.html

+9-9
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ <h1>
2020
data-original-title="Building from build configuration {{buildConfig.metadata.name}} has been paused.">
2121
</span>
2222
<small class="meta">created <relative-timestamp timestamp="build.metadata.creationTimestamp"></relative-timestamp></small>
23-
<div class="pull-right dropdown">
23+
<div class="pull-right dropdown" ng-hide="!('build' | canIDoAny)">
2424
<!-- Primary Actions -->
2525
<button class="btn btn-default hidden-xs"
2626
ng-click="cancelBuild()"
27-
ng-if="!build.metadata.deletionTimestamp && (build | isIncompleteBuild)">Cancel Build</button>
27+
ng-if="!build.metadata.deletionTimestamp && (build | isIncompleteBuild) && ('builds/clone' | canI : 'create')">Cancel Build</button>
2828
<button class="btn btn-default hidden-xs"
2929
ng-click="cloneBuild()"
30-
ng-hide="build.metadata.deletionTimestamp || (build | isIncompleteBuild)"
30+
ng-hide="build.metadata.deletionTimestamp || (build | isIncompleteBuild) || !('builds/clone' | canI : 'create')"
3131
ng-disabled="!canBuild">Rebuild</button>
3232

3333
<!-- Secondary Actions -->
@@ -39,29 +39,29 @@ <h1>
3939
class="dropdown-toggle actions-dropdown-kebab visible-xs-inline"
4040
data-toggle="dropdown"><i class="fa fa-ellipsis-v"></i><span class="sr-only">Actions</span></a>
4141
<ul class="dropdown-menu actions action-button">
42-
<li ng-if="!build.metadata.deletionTimestamp && (build | isIncompleteBuild)"
42+
<li ng-if="!build.metadata.deletionTimestamp && (build | isIncompleteBuild) && ('builds/clone' | canI : 'create')"
4343
class="visible-xs-inline">
4444
<a href=""
4545
role="button"
4646
ng-click="cancelBuild()">Cancel Build</a>
4747
</li>
4848
<li class="visible-xs-inline"
4949
ng-class="{ disabled: !canBuild }"
50-
ng-hide="build.metadata.deletionTimestamp || (build | isIncompleteBuild)">
50+
ng-hide="build.metadata.deletionTimestamp || (build | isIncompleteBuild) || !('builds/clone' | canI : 'create')">
5151
<a href=""
5252
role="button"
5353
ng-click="cloneBuild()"
5454
ng-attr-aria-disabled="{{canBuild ? undefined : 'true'}}"
5555
ng-class="{ 'disabled-link': !canBuild }">Rebuild</a>
5656
</li>
57-
<li>
57+
<li ng-if="('builds' | canI : 'update')">
5858
<edit-link
5959
resource="build"
6060
kind="Build"
6161
alerts="alerts">
6262
</edit-link>
6363
</li>
64-
<li>
64+
<li ng-if="('builds' | canI : 'delete')">
6565
<delete-link
6666
kind="Build"
6767
resource-name="{{build.metadata.name}}"
@@ -95,7 +95,7 @@ <h1>
9595
<em ng-if="!(build | buildStrategy).env">The build strategy had no environment variables defined.</em>
9696
</uib-tab>
9797

98-
<uib-tab active="selectedTab.logs" ng-if="!(build | isJenkinsPipelineStrategy)">
98+
<uib-tab active="selectedTab.logs" ng-if="!(build | isJenkinsPipelineStrategy) && ('builds/log' | canI : 'get')">
9999
<uib-tab-heading>Logs</uib-tab-heading>
100100
<log-viewer
101101
ng-if="selectedTab.logs"
@@ -121,7 +121,7 @@ <h1>
121121

122122
</log-viewer>
123123
</uib-tab>
124-
<uib-tab active="selectedTab.events">
124+
<uib-tab active="selectedTab.events" ng-if="('events' | canI : 'watch')">
125125
<uib-tab-heading>Events</uib-tab-heading>
126126
<events resource-kind="Pod" resource-name="{{build | annotation : 'buildPod'}}" project-context="projectContext" ng-if="selectedTab.events"></events>
127127
</uib-tab>

0 commit comments

Comments
 (0)