Allow users to update images created from other projects
Currently on the angular images panel, edit image/update metadata/delete image actions are only available for images created from the current logged in project. This patch removed that restriction and added the policy check for the actions. Change-Id: I17761e27f0659799d5e55e24a6106c3c7a3e5459 Closes-bug: #1698963
This commit is contained in:
parent
19414ccb48
commit
d8dea730d9
@ -22,7 +22,6 @@
|
||||
deleteImageService.$inject = [
|
||||
'$q',
|
||||
'horizon.app.core.openstack-service-api.glance',
|
||||
'horizon.app.core.openstack-service-api.userSession',
|
||||
'horizon.app.core.openstack-service-api.policy',
|
||||
'horizon.framework.util.actions.action-result.service',
|
||||
'horizon.framework.util.i18n.gettext',
|
||||
@ -45,7 +44,6 @@
|
||||
function deleteImageService(
|
||||
$q,
|
||||
glance,
|
||||
userSessionService,
|
||||
policy,
|
||||
actionResultService,
|
||||
gettext,
|
||||
@ -87,7 +85,7 @@
|
||||
return $q.all([
|
||||
notProtected(image),
|
||||
deleteImagePromise,
|
||||
userSessionService.isCurrentProject(image.owner),
|
||||
policy.ifAllowed({ rules: [['image', 'delete_image']] }),
|
||||
notDeleted(image)
|
||||
]);
|
||||
} else {
|
||||
|
@ -43,14 +43,7 @@
|
||||
}
|
||||
};
|
||||
|
||||
var userSession = {
|
||||
isCurrentProject: function() {
|
||||
deferred.resolve();
|
||||
return deferred.promise;
|
||||
}
|
||||
};
|
||||
|
||||
var deferred, service, $scope, deferredModal;
|
||||
var service, $scope, deferredModal;
|
||||
|
||||
///////////////////////
|
||||
|
||||
@ -65,15 +58,12 @@
|
||||
beforeEach(module('horizon.app.core.openstack-service-api', function($provide) {
|
||||
$provide.value('horizon.app.core.openstack-service-api.glance', glanceAPI);
|
||||
$provide.value('horizon.app.core.openstack-service-api.policy', policyAPI);
|
||||
$provide.value('horizon.app.core.openstack-service-api.userSession', userSession);
|
||||
spyOn(policyAPI, 'ifAllowed').and.callThrough();
|
||||
spyOn(userSession, 'isCurrentProject').and.callThrough();
|
||||
}));
|
||||
|
||||
beforeEach(inject(function($injector, _$rootScope_, $q) {
|
||||
$scope = _$rootScope_.$new();
|
||||
service = $injector.get('horizon.app.core.images.actions.delete-image.service');
|
||||
deferred = $q.defer();
|
||||
deferredModal = $q.defer();
|
||||
}));
|
||||
|
||||
@ -121,7 +111,6 @@
|
||||
it('should open the delete modal and show correct labels', testpluralLabels);
|
||||
it('should open the delete modal with correct entities', testEntities);
|
||||
it('should only delete images that are valid', testValids);
|
||||
it('should fail if this project is not owner', testOwner);
|
||||
it('should fail if images is protected', testProtected);
|
||||
it('should fail if status is deleted', testStatus);
|
||||
it('should pass in a function that deletes an image', testGlance);
|
||||
@ -188,15 +177,6 @@
|
||||
expect(entities[1].name).toEqual('image2');
|
||||
}
|
||||
|
||||
function testOwner() {
|
||||
var images = generateImage(1);
|
||||
deferred.reject();
|
||||
service.perform(images);
|
||||
$scope.$apply();
|
||||
|
||||
expect(deleteModalService.open).not.toHaveBeenCalled();
|
||||
}
|
||||
|
||||
function testProtected() {
|
||||
var images = generateImage(1);
|
||||
images[0].protected = true;
|
||||
@ -249,7 +229,6 @@
|
||||
it('should use default policy if batch action', testBatch);
|
||||
it('allows delete if image can be deleted', testValid);
|
||||
it('disallows delete if image is protected', testProtected);
|
||||
it('disallows delete if image is not owned by user', testOwner);
|
||||
it('disallows delete if image status is deleted', testStatus);
|
||||
|
||||
////////////
|
||||
@ -277,14 +256,6 @@
|
||||
expect(resolver.error).toHaveBeenCalled();
|
||||
}
|
||||
|
||||
function testOwner() {
|
||||
var image = generateImage(1)[0];
|
||||
deferred.reject();
|
||||
service.allowed(image).then(resolver.success, resolver.error);
|
||||
$scope.$apply();
|
||||
expect(resolver.error).toHaveBeenCalled();
|
||||
}
|
||||
|
||||
function testStatus() {
|
||||
var image = generateImage(1)[0];
|
||||
image.status = 'deleted';
|
||||
|
@ -29,7 +29,6 @@
|
||||
'horizon.app.core.metadata.service',
|
||||
'horizon.app.core.openstack-service-api.glance',
|
||||
'horizon.app.core.openstack-service-api.policy',
|
||||
'horizon.app.core.openstack-service-api.userSession',
|
||||
'horizon.framework.util.actions.action-result.service',
|
||||
'horizon.framework.util.q.extensions',
|
||||
'horizon.framework.widgets.modal.wizard-modal.service',
|
||||
@ -49,7 +48,6 @@
|
||||
metadataService,
|
||||
glance,
|
||||
policy,
|
||||
userSessionService,
|
||||
actionResultService,
|
||||
$qExtensions,
|
||||
wizardModalService,
|
||||
@ -84,7 +82,6 @@
|
||||
function allowed(image) {
|
||||
return $q.all([
|
||||
modifyImagePolicyCheck,
|
||||
userSessionService.isCurrentProject(image.owner),
|
||||
isActive(image)
|
||||
]);
|
||||
}
|
||||
|
@ -114,14 +114,6 @@
|
||||
expect(modalArgs.workflow).toBeDefined();
|
||||
});
|
||||
|
||||
it('should not allow edit if image is not owned by user', function() {
|
||||
deferred.reject();
|
||||
var image = {owner: 'doesnt_matter', status: 'active'};
|
||||
var allowed = service.allowed(image);
|
||||
permissionShouldFail(allowed);
|
||||
$scope.$apply();
|
||||
});
|
||||
|
||||
it('should not allow edit if image status is not active', function() {
|
||||
var image = {owner: 'project', status: 'not_active'};
|
||||
var allowed = service.allowed(image);
|
||||
|
@ -23,7 +23,7 @@
|
||||
updateMetadataService.$inject = [
|
||||
'$q',
|
||||
'horizon.app.core.metadata.modal.service',
|
||||
'horizon.app.core.openstack-service-api.userSession',
|
||||
'horizon.app.core.openstack-service-api.policy',
|
||||
'horizon.framework.util.actions.action-result.service',
|
||||
'horizon.framework.util.q.extensions',
|
||||
'horizon.app.core.images.resourceType'
|
||||
@ -35,7 +35,7 @@
|
||||
*
|
||||
* @param {Object} $q
|
||||
* @param {Object} metadataModalService
|
||||
* @param {Object} userSessionService
|
||||
* @param {Object} policy
|
||||
* @param {Object} $qExtensions
|
||||
* @Description
|
||||
* Brings up the Update Metadata for image modal.
|
||||
@ -47,7 +47,7 @@
|
||||
function updateMetadataService(
|
||||
$q,
|
||||
metadataModalService,
|
||||
userSessionService,
|
||||
policy,
|
||||
actionResultService,
|
||||
$qExtensions,
|
||||
imageResourceType
|
||||
@ -77,7 +77,10 @@
|
||||
}
|
||||
|
||||
function allowed(image) {
|
||||
return $q.all([userSessionService.isCurrentProject(image.owner), isActive(image)]);
|
||||
return $q.all([
|
||||
policy.ifAllowed({rules: [['image', 'modify_metadef_object']]}),
|
||||
isActive(image)
|
||||
]);
|
||||
}
|
||||
|
||||
function isActive(image) {
|
||||
|
@ -17,19 +17,22 @@
|
||||
'use strict';
|
||||
|
||||
describe('horizon.app.core.images.actions.update-metadata.service', function() {
|
||||
var deferred, service, $scope;
|
||||
|
||||
var userSession = {
|
||||
isCurrentProject: function() {
|
||||
deferred.resolve();
|
||||
return deferred.promise;
|
||||
}
|
||||
};
|
||||
var service, $scope;
|
||||
|
||||
var metadataModalMock = {
|
||||
open: function () {}
|
||||
};
|
||||
|
||||
var policyAPI = {
|
||||
ifAllowed: function() {
|
||||
return {
|
||||
success: function(callback) {
|
||||
callback({allowed: false});
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////
|
||||
|
||||
beforeEach(module('horizon.framework'));
|
||||
@ -38,14 +41,9 @@
|
||||
$provide.value('horizon.app.core.metadata.modal.service', metadataModalMock);
|
||||
}));
|
||||
|
||||
beforeEach(module('horizon.app.core.openstack-service-api', function($provide) {
|
||||
$provide.value('horizon.app.core.openstack-service-api.userSession', userSession);
|
||||
}));
|
||||
|
||||
beforeEach(inject(function($injector, _$rootScope_, $q) {
|
||||
beforeEach(inject(function($injector, _$rootScope_) {
|
||||
$scope = _$rootScope_.$new();
|
||||
service = $injector.get('horizon.app.core.images.actions.update-metadata.service');
|
||||
deferred = $q.defer();
|
||||
}));
|
||||
|
||||
it('should open the modal with correct message', function() {
|
||||
@ -66,19 +64,25 @@
|
||||
});
|
||||
|
||||
describe('Update Metadata', function() {
|
||||
function policyIfAllowed() {
|
||||
return {
|
||||
then: function(callback) {
|
||||
callback({allowed: true});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
beforeEach(inject(function ($injector) {
|
||||
policyAPI = $injector.get('horizon.app.core.openstack-service-api.policy');
|
||||
spyOn(policyAPI, 'ifAllowed').and.callFake(policyIfAllowed);
|
||||
}));
|
||||
|
||||
it('should allow Update Metadata if image can be deleted', function() {
|
||||
var image = {owner: 'project', status: 'active'};
|
||||
permissionShouldPass(service.allowed(image));
|
||||
$scope.$apply();
|
||||
});
|
||||
|
||||
it('should not allow Update Metadata if service call is rejected', function() {
|
||||
var image = {owner: 'doesnt_matter', status: 'active'};
|
||||
deferred.reject();
|
||||
permissionShouldFail(service.allowed(image));
|
||||
$scope.$apply();
|
||||
});
|
||||
|
||||
it('should not allow Update Metadata if image status is not active', function() {
|
||||
var image = {owner: 'project', status: 'not_active'};
|
||||
permissionShouldFail(service.allowed(image));
|
||||
|
Loading…
x
Reference in New Issue
Block a user