Merge "Adding ifAllowed method to policy service"

This commit is contained in:
Jenkins 2015-10-02 16:38:07 +00:00 committed by Gerrit Code Review
commit 3888f90e10
4 changed files with 120 additions and 34 deletions

View File

@ -52,18 +52,17 @@
// if user has permission
// fetch table data and populate it
var rules = [['identity', 'identity:list_users']];
policy.check({ rules: rules }).success(policySuccess);
policy.ifAllowed({ rules: rules }).then(policySuccess, policyFailed);
}
function policySuccess(response) {
if (response.allowed) {
function policySuccess() {
keystone.getUsers().success(getUsersSuccess);
keystone.getCurrentUserSession().success(getSessionSuccess);
}
else {
function policyFailed() {
var msg = gettext('Insufficient privilege level to view user information.');
toast.add('info', msg);
}
toast.add('warning', msg);
}
function getUsersSuccess(response) {

View File

@ -22,23 +22,14 @@
var policy = { allowed: true };
function fakePolicy() {
return {
success: function(callback) {
callback(policy);
then: function(successFn, errorFn) {
if (policy.allowed) { successFn(); }
else { errorFn(); }
}
};
}
function fakePromise() {
return {
success: function() {}
};
}
function fakeToast() {
return {
add: function(type, msg) {}
};
}
function fakePromise() { return { success: angular.noop }; }
function fakeToast() { return { add: angular.noop }; }
var controller, toastService, policyAPI, keystoneAPI;
@ -59,7 +50,7 @@
controller = $injector.get('$controller');
spyOn(toastService, 'add').and.callFake(fakeToast);
spyOn(policyAPI, 'check').and.callFake(fakePolicy);
spyOn(policyAPI, 'ifAllowed').and.callFake(fakePolicy);
spyOn(keystoneAPI, 'getUsers').and.callFake(fakePromise);
spyOn(keystoneAPI, 'getCurrentUserSession').and.callFake(fakePromise);
}));
@ -75,7 +66,7 @@
it('should invoke keystone apis if policy passes', function() {
policy.allowed = true;
createController();
expect(policyAPI.check).toHaveBeenCalled();
expect(policyAPI.ifAllowed).toHaveBeenCalled();
expect(keystoneAPI.getUsers).toHaveBeenCalled();
expect(keystoneAPI.getCurrentUserSession).toHaveBeenCalled();
});
@ -83,7 +74,7 @@
it('should not invoke keystone apis if policy fails', function() {
policy.allowed = false;
createController();
expect(policyAPI.check).toHaveBeenCalled();
expect(policyAPI.ifAllowed).toHaveBeenCalled();
expect(toastService.add).toHaveBeenCalled();
expect(keystoneAPI.getUsers).not.toHaveBeenCalled();
expect(keystoneAPI.getCurrentUserSession).not.toHaveBeenCalled();

View File

@ -1,5 +1,4 @@
/**
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@ -12,15 +11,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
'use strict';
angular
.module('horizon.app.core.openstack-service-api')
.factory('horizon.app.core.openstack-service-api.policy', PolicyService);
.service('horizon.app.core.openstack-service-api.policy', PolicyService);
PolicyService.$inject = ['horizon.framework.util.http.service',
'horizon.framework.widgets.toast.service'];
PolicyService.$inject = [
'$q',
'horizon.framework.util.http.service',
'horizon.framework.widgets.toast.service'
];
/**
* @ngdoc service
@ -28,13 +31,17 @@
* @description Provides a direct pass through to the policy engine in
* Horizon.
*/
function PolicyService(apiService, toastService) {
function PolicyService($q, apiService, toastService) {
var service = {
check: check
check: check,
ifAllowed: ifAllowed
};
return service;
//////////////
/**
* @name horizon.app.core.openstack-service-api.policy.check
* @description
@ -78,5 +85,32 @@
toastService.add('warning', gettext('Policy check failed.'));
});
}
/**
* @name ifAllowed
* @description
* Wrapper function for check that returns a deferred promise.
* Resolves if the response is allowed, rejects otherwise.
* The policyRules input is the same as the check function. Please
* refer to it for more information on the input.
*
* @example
* Assume if the users is not allowed to delete an object,
* you will delete the object, otherwise, you will do something else.
*
```js
policyService.ifAllowed(myRules).then(deleteObject, doSomethingElse);
```
*/
function ifAllowed(policyRules) {
var deferred = $q.defer();
service.check(policyRules).then(success);
return deferred.promise;
function success(response) {
if (response.data.allowed) { deferred.resolve(); }
else { deferred.reject(); }
}
}
}
}());

View File

@ -17,7 +17,7 @@
(function() {
'use strict';
describe('Policy API', function() {
describe('Policy API check', function() {
var testCall, service;
var apiService = {};
var toastService = {};
@ -60,6 +60,68 @@
testCall.apply(this, callParams);
});
});
});
describe("Policy API ifAllowed", function() {
var policy = { rules:[] };
var response = {
data: { allowed: true }
};
var deferred = {
then: function(callback) { callback(response); },
reject: angular.noop,
resolve: angular.noop
};
var service;
var q = { defer: function() { return deferred; }};
////////////////
beforeEach(module('horizon.framework.util.http'));
beforeEach(module('horizon.framework.widgets.toast'));
beforeEach(module('horizon.app.core.openstack-service-api'));
beforeEach(module(function($provide) {
$provide.value('$q', q);
}));
beforeEach(inject(['horizon.app.core.openstack-service-api.policy', function(policyAPI) {
service = policyAPI;
}]));
beforeEach(function() {
spyOn(service, 'check').and.returnValue(deferred);
spyOn(deferred, 'resolve');
spyOn(deferred, 'reject');
});
////////////////
it('should be defined', defined);
it("rejects if response allowed is false", rejects);
it("resolves if response allowed is true", resolves);
////////////////
function defined() {
expect(service.ifAllowed).toBeDefined();
}
function rejects() {
response.data.allowed = false;
service.ifAllowed(policy);
expect(service.check).toHaveBeenCalledWith(policy);
expect(deferred.reject).toHaveBeenCalled();
}
function resolves() {
response.data.allowed = true;
service.ifAllowed(policy);
expect(service.check).toHaveBeenCalledWith(policy);
expect(deferred.resolve).toHaveBeenCalled();
}
});