Merge "Support can_edit_user and can_edit_role settings in Angularized panels"
This commit is contained in:
commit
1a312e86bd
@ -772,12 +772,18 @@ Default:
|
|||||||
'OPENSTACK_HYPERVISOR_FEATURES',
|
'OPENSTACK_HYPERVISOR_FEATURES',
|
||||||
'LAUNCH_INSTANCE_DEFAULTS',
|
'LAUNCH_INSTANCE_DEFAULTS',
|
||||||
'OPENSTACK_IMAGE_FORMATS',
|
'OPENSTACK_IMAGE_FORMATS',
|
||||||
'OPENSTACK_KEYSTONE_DEFAULT_DOMAIN'
|
'OPENSTACK_KEYSTONE_BACKEND',
|
||||||
|
'OPENSTACK_KEYSTONE_DEFAULT_DOMAIN',
|
||||||
|
'CREATE_IMAGE_DEFAULTS',
|
||||||
|
'ENFORCE_PASSWORD_CHECK'
|
||||||
]
|
]
|
||||||
|
|
||||||
This setting allows you to expose configuration values over Horizons internal
|
This setting allows you to expose configuration values over Horizons internal
|
||||||
REST API, so that the AngularJS panels can access them. Please be cautious
|
REST API, so that the AngularJS panels can access them. Please be cautious
|
||||||
about which values are listed here (and thus exposed on the frontend)
|
about which values are listed here (and thus exposed on the frontend).
|
||||||
|
For security purpose, this exposure of settings should be recognized explicitly
|
||||||
|
by operator. So ``REST_API_REQUIRED_SETTINGS`` is not set by default.
|
||||||
|
Please refer ``local_settings.py.example`` and confirm your ``local_settings.py``.
|
||||||
|
|
||||||
SELECTABLE_THEMES
|
SELECTABLE_THEMES
|
||||||
---------------------
|
---------------------
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
.factory('horizon.dashboard.identity.roles.actions.create.service', createService);
|
.factory('horizon.dashboard.identity.roles.actions.create.service', createService);
|
||||||
|
|
||||||
createService.$inject = [
|
createService.$inject = [
|
||||||
|
'$q',
|
||||||
'horizon.dashboard.identity.roles.resourceType',
|
'horizon.dashboard.identity.roles.resourceType',
|
||||||
'horizon.dashboard.identity.roles.role-schema',
|
'horizon.dashboard.identity.roles.role-schema',
|
||||||
'horizon.app.core.openstack-service-api.keystone',
|
'horizon.app.core.openstack-service-api.keystone',
|
||||||
@ -38,6 +39,7 @@
|
|||||||
* @Description A service to handle the Create Role modal.
|
* @Description A service to handle the Create Role modal.
|
||||||
*/
|
*/
|
||||||
function createService(
|
function createService(
|
||||||
|
$q,
|
||||||
resourceType,
|
resourceType,
|
||||||
schema,
|
schema,
|
||||||
keystoneAPI,
|
keystoneAPI,
|
||||||
@ -58,7 +60,10 @@
|
|||||||
//////////////
|
//////////////
|
||||||
|
|
||||||
function allowed() {
|
function allowed() {
|
||||||
return policy.ifAllowed({ rules: [['identity', 'identity:create_role']] });
|
return $q.all([
|
||||||
|
keystoneAPI.canEditIdentity('role'),
|
||||||
|
policy.ifAllowed({ rules: [['identity', 'identity:create_role']] })
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function perform() {
|
function perform() {
|
||||||
|
@ -38,23 +38,43 @@
|
|||||||
resType = $injector.get('horizon.dashboard.identity.roles.resourceType');
|
resType = $injector.get('horizon.dashboard.identity.roles.resourceType');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should check the policy if the user is allowed to create roles', function() {
|
it('should allow if can_edit_role is set True in OPENSTACK_KEYSTONE_BACKEND', function() {
|
||||||
var deferred = $q.defer();
|
//for canEditRole
|
||||||
spyOn(policyAPI, 'ifAllowed').and.returnValue(deferred.promise);
|
var deferredCanEditRole = $q.defer();
|
||||||
deferred.resolve({allowed: true});
|
deferredCanEditRole.resolve(true);
|
||||||
var handler = jasmine.createSpyObj('handler', ['success']);
|
spyOn(keystoneAPI, 'canEditIdentity').and.returnValue(deferredCanEditRole.promise);
|
||||||
|
|
||||||
service.allowed().then(handler.success);
|
//for ifAllowed
|
||||||
|
var deferredIfAllowed = $q.defer();
|
||||||
|
deferredIfAllowed.resolve(true);
|
||||||
|
spyOn(policyAPI, 'ifAllowed').and.returnValue(deferredIfAllowed.promise);
|
||||||
|
|
||||||
|
var allowed = service.allowed({id: '1234'});
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
|
|
||||||
expect(handler.success).toHaveBeenCalled();
|
|
||||||
var allowed = handler.success.calls.first().args[0];
|
|
||||||
|
|
||||||
expect(allowed).toBeTruthy();
|
expect(allowed).toBeTruthy();
|
||||||
expect(policyAPI.ifAllowed).toHaveBeenCalledWith(
|
expect(policyAPI.ifAllowed).toHaveBeenCalledWith(
|
||||||
{ rules: [['identity', 'identity:create_role']] });
|
{ rules: [['identity', 'identity:create_role']] });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should allow if can_edit_role is set True in OPENSTACK_KEYSTONE_BACKEND', function() {
|
||||||
|
//for canEditRole
|
||||||
|
var deferredCanEditRole = $q.defer();
|
||||||
|
deferredCanEditRole.resolve(false);
|
||||||
|
spyOn(keystoneAPI, 'canEditIdentity').and.returnValue(deferredCanEditRole.promise);
|
||||||
|
|
||||||
|
//for ifAllowed
|
||||||
|
var deferredIfAllowed = $q.defer();
|
||||||
|
deferredIfAllowed.resolve(true);
|
||||||
|
spyOn(policyAPI, 'ifAllowed').and.returnValue(deferredIfAllowed.promise);
|
||||||
|
|
||||||
|
var allowed = service.allowed({id: '1234'});
|
||||||
|
$scope.$apply();
|
||||||
|
|
||||||
|
// reject
|
||||||
|
expect(allowed.$$state.status).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
it('should open the modal with the correct parameters', function() {
|
it('should open the modal with the correct parameters', function() {
|
||||||
var deferred = $q.defer();
|
var deferred = $q.defer();
|
||||||
spyOn(modalFormService, 'open').and.returnValue(deferred.promise);
|
spyOn(modalFormService, 'open').and.returnValue(deferred.promise);
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
.factory('horizon.dashboard.identity.roles.actions.delete.service', deleteRoleService);
|
.factory('horizon.dashboard.identity.roles.actions.delete.service', deleteRoleService);
|
||||||
|
|
||||||
deleteRoleService.$inject = [
|
deleteRoleService.$inject = [
|
||||||
|
'$q',
|
||||||
'horizon.app.core.openstack-service-api.keystone',
|
'horizon.app.core.openstack-service-api.keystone',
|
||||||
'horizon.app.core.openstack-service-api.policy',
|
'horizon.app.core.openstack-service-api.policy',
|
||||||
'horizon.framework.util.actions.action-result.service',
|
'horizon.framework.util.actions.action-result.service',
|
||||||
@ -41,6 +42,7 @@
|
|||||||
* On cancel, do nothing.
|
* On cancel, do nothing.
|
||||||
*/
|
*/
|
||||||
function deleteRoleService(
|
function deleteRoleService(
|
||||||
|
$q,
|
||||||
keystone,
|
keystone,
|
||||||
policy,
|
policy,
|
||||||
actionResultService,
|
actionResultService,
|
||||||
@ -57,7 +59,10 @@
|
|||||||
//////////////
|
//////////////
|
||||||
|
|
||||||
function allowed() {
|
function allowed() {
|
||||||
return policy.ifAllowed({rules: [[ 'identity', 'identity:delete_role' ]]});
|
return $q.all([
|
||||||
|
keystone.canEditIdentity('role'),
|
||||||
|
policy.ifAllowed({ rules: [['identity', 'identity:delete_role']] })
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function perform(items, scope) {
|
function perform(items, scope) {
|
||||||
|
@ -20,9 +20,10 @@
|
|||||||
beforeEach(module('horizon.dashboard.identity.roles'));
|
beforeEach(module('horizon.dashboard.identity.roles'));
|
||||||
beforeEach(module('horizon.framework'));
|
beforeEach(module('horizon.framework'));
|
||||||
|
|
||||||
var deleteModalService, service, keystoneAPI, policyAPI;
|
var deleteModalService, $scope, service, keystoneAPI, policyAPI;
|
||||||
|
|
||||||
beforeEach(inject(function($injector) {
|
beforeEach(inject(function($injector, _$rootScope_) {
|
||||||
|
$scope = _$rootScope_.$new();
|
||||||
service = $injector.get('horizon.dashboard.identity.roles.actions.delete.service');
|
service = $injector.get('horizon.dashboard.identity.roles.actions.delete.service');
|
||||||
keystoneAPI = $injector.get('horizon.app.core.openstack-service-api.keystone');
|
keystoneAPI = $injector.get('horizon.app.core.openstack-service-api.keystone');
|
||||||
deleteModalService = $injector.get('horizon.framework.widgets.modal.deleteModalService');
|
deleteModalService = $injector.get('horizon.framework.widgets.modal.deleteModalService');
|
||||||
@ -72,8 +73,11 @@
|
|||||||
|
|
||||||
describe('allow method', function() {
|
describe('allow method', function() {
|
||||||
it('should use default policy if batch action', function test() {
|
it('should use default policy if batch action', function test() {
|
||||||
|
spyOn(keystoneAPI, 'canEditIdentity');
|
||||||
spyOn(policyAPI, 'ifAllowed');
|
spyOn(policyAPI, 'ifAllowed');
|
||||||
service.allowed();
|
service.allowed();
|
||||||
|
$scope.$apply();
|
||||||
|
expect(keystoneAPI.canEditIdentity).toHaveBeenCalled();
|
||||||
expect(policyAPI.ifAllowed).toHaveBeenCalled();
|
expect(policyAPI.ifAllowed).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}); // end of allowed
|
}); // end of allowed
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
.factory('horizon.dashboard.identity.roles.actions.edit.service', editService);
|
.factory('horizon.dashboard.identity.roles.actions.edit.service', editService);
|
||||||
|
|
||||||
editService.$inject = [
|
editService.$inject = [
|
||||||
|
'$q',
|
||||||
'horizon.dashboard.identity.roles.resourceType',
|
'horizon.dashboard.identity.roles.resourceType',
|
||||||
'horizon.dashboard.identity.roles.role-schema',
|
'horizon.dashboard.identity.roles.role-schema',
|
||||||
'horizon.app.core.openstack-service-api.keystone',
|
'horizon.app.core.openstack-service-api.keystone',
|
||||||
@ -37,6 +38,7 @@
|
|||||||
* @Description A service to handle the Edit Role modal.
|
* @Description A service to handle the Edit Role modal.
|
||||||
*/
|
*/
|
||||||
function editService(
|
function editService(
|
||||||
|
$q,
|
||||||
resourceType,
|
resourceType,
|
||||||
schema,
|
schema,
|
||||||
keystoneAPI,
|
keystoneAPI,
|
||||||
@ -58,7 +60,10 @@
|
|||||||
//////////////
|
//////////////
|
||||||
|
|
||||||
function allowed() {
|
function allowed() {
|
||||||
return policy.ifAllowed({ rules: [['identity', 'identity:update_role']] });
|
return $q.all([
|
||||||
|
keystoneAPI.canEditIdentity('role'),
|
||||||
|
policy.ifAllowed({ rules: [['identity', 'identity:update_role']] })
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function perform(role) {
|
function perform(role) {
|
||||||
|
@ -92,8 +92,10 @@
|
|||||||
|
|
||||||
describe('allow method', function() {
|
describe('allow method', function() {
|
||||||
it('should use default policy if batch action', function test() {
|
it('should use default policy if batch action', function test() {
|
||||||
|
spyOn(keystoneAPI, 'canEditIdentity');
|
||||||
spyOn(policyAPI, 'ifAllowed');
|
spyOn(policyAPI, 'ifAllowed');
|
||||||
service.allowed();
|
service.allowed();
|
||||||
|
expect(keystoneAPI.canEditIdentity).toHaveBeenCalled();
|
||||||
expect(policyAPI.ifAllowed).toHaveBeenCalled();
|
expect(policyAPI.ifAllowed).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
}); // end of allowed
|
}); // end of allowed
|
||||||
|
@ -62,7 +62,10 @@
|
|||||||
//////////////
|
//////////////
|
||||||
|
|
||||||
function allowed() {
|
function allowed() {
|
||||||
return policy.ifAllowed({ rules: [['identity', 'identity:create_user']] });
|
return $q.all([
|
||||||
|
keystone.canEditIdentity('user'),
|
||||||
|
policy.ifAllowed({ rules: [['identity', 'identity:create_user']] })
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function perform() {
|
function perform() {
|
||||||
|
@ -38,23 +38,43 @@
|
|||||||
resourceType = $injector.get('horizon.dashboard.identity.users.resourceType');
|
resourceType = $injector.get('horizon.dashboard.identity.users.resourceType');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should check the policy if the user is allowed to create user', function() {
|
it('should allow if can_edit_user is set True in OPENSTACK_KEYSTONE_BACKEND', function() {
|
||||||
var deferred = $q.defer();
|
//for canEditUser
|
||||||
spyOn(policy, 'ifAllowed').and.returnValue(deferred.promise);
|
var deferredCanEditUser = $q.defer();
|
||||||
deferred.resolve({allowed: true});
|
deferredCanEditUser.resolve(true);
|
||||||
var handler = jasmine.createSpyObj('handler', ['success']);
|
spyOn(keystone, 'canEditIdentity').and.returnValue(deferredCanEditUser.promise);
|
||||||
|
|
||||||
service.allowed().then(handler.success);
|
//for ifAllowed
|
||||||
|
var deferredIfAllowed = $q.defer();
|
||||||
|
deferredIfAllowed.resolve(true);
|
||||||
|
spyOn(policy, 'ifAllowed').and.returnValue(deferredIfAllowed.promise);
|
||||||
|
|
||||||
|
var allowed = service.allowed({id: '1234'});
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
|
|
||||||
expect(handler.success).toHaveBeenCalled();
|
|
||||||
var allowed = handler.success.calls.first().args[0];
|
|
||||||
|
|
||||||
expect(allowed).toBeTruthy();
|
expect(allowed).toBeTruthy();
|
||||||
expect(policy.ifAllowed).toHaveBeenCalledWith(
|
expect(policy.ifAllowed).toHaveBeenCalledWith(
|
||||||
{ rules: [['identity', 'identity:create_user']] });
|
{ rules: [['identity', 'identity:create_user']] });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should allow if can_edit_user is set True in OPENSTACK_KEYSTONE_BACKEND', function() {
|
||||||
|
//for canEditUser
|
||||||
|
var deferredCanEditUser = $q.defer();
|
||||||
|
deferredCanEditUser.resolve(false);
|
||||||
|
spyOn(keystone, 'canEditIdentity').and.returnValue(deferredCanEditUser.promise);
|
||||||
|
|
||||||
|
//for ifAllowed
|
||||||
|
var deferredIfAllowed = $q.defer();
|
||||||
|
deferredIfAllowed.resolve(true);
|
||||||
|
spyOn(policy, 'ifAllowed').and.returnValue(deferredIfAllowed.promise);
|
||||||
|
|
||||||
|
var allowed = service.allowed({id: '1234'});
|
||||||
|
$scope.$apply();
|
||||||
|
|
||||||
|
// reject
|
||||||
|
expect(allowed.$$state.status).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
it('should open the modal', function() {
|
it('should open the modal', function() {
|
||||||
spyOn(modal, 'open').and.returnValue($q.defer().promise);
|
spyOn(modal, 'open').and.returnValue($q.defer().promise);
|
||||||
spyOn(keystone, 'getVersion').and.returnValue($q.defer().promise);
|
spyOn(keystone, 'getVersion').and.returnValue($q.defer().promise);
|
||||||
|
@ -63,7 +63,10 @@
|
|||||||
//////////////
|
//////////////
|
||||||
|
|
||||||
function allowed() {
|
function allowed() {
|
||||||
return policy.ifAllowed({rules: [[ 'identity', 'identity:delete_user' ]]});
|
return $q.all([
|
||||||
|
keystone.canEditIdentity('user'),
|
||||||
|
policy.ifAllowed({ rules: [['identity', 'identity:delete_user']] })
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function perform(items, scope) {
|
function perform(items, scope) {
|
||||||
|
@ -37,6 +37,9 @@
|
|||||||
var keystoneAPI = {
|
var keystoneAPI = {
|
||||||
deleteUser: function() {
|
deleteUser: function() {
|
||||||
return;
|
return;
|
||||||
|
},
|
||||||
|
canEditIdentity: function() {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -75,6 +78,7 @@
|
|||||||
beforeEach(module('horizon.app.core.openstack-service-api', function($provide) {
|
beforeEach(module('horizon.app.core.openstack-service-api', function($provide) {
|
||||||
$provide.value('horizon.app.core.openstack-service-api.keystone', keystoneAPI);
|
$provide.value('horizon.app.core.openstack-service-api.keystone', keystoneAPI);
|
||||||
$provide.value('horizon.app.core.openstack-service-api.policy', policyAPI);
|
$provide.value('horizon.app.core.openstack-service-api.policy', policyAPI);
|
||||||
|
spyOn(keystoneAPI, 'canEditIdentity').and.callThrough();
|
||||||
spyOn(policyAPI, 'ifAllowed').and.callThrough();
|
spyOn(policyAPI, 'ifAllowed').and.callThrough();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -134,7 +138,7 @@
|
|||||||
it('should call policy check', function() {
|
it('should call policy check', function() {
|
||||||
service.allowed();
|
service.allowed();
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
|
expect(keystoneAPI.canEditIdentity).toHaveBeenCalled();
|
||||||
expect(policyAPI.ifAllowed).toHaveBeenCalled();
|
expect(policyAPI.ifAllowed).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
|
|
||||||
function allowed(selected) {
|
function allowed(selected) {
|
||||||
return $q.all([
|
return $q.all([
|
||||||
|
keystone.canEditIdentity('user'),
|
||||||
$qExtensions.booleanAsPromise(selected.enabled),
|
$qExtensions.booleanAsPromise(selected.enabled),
|
||||||
policy.ifAllowed({ rules: [['identity', 'identity:update_user']] })
|
policy.ifAllowed({ rules: [['identity', 'identity:update_user']] })
|
||||||
]);
|
]);
|
||||||
|
@ -35,6 +35,9 @@
|
|||||||
var deferred = $q.defer();
|
var deferred = $q.defer();
|
||||||
spyOn(keystone, 'editUser').and.returnValue(deferred.promise);
|
spyOn(keystone, 'editUser').and.returnValue(deferred.promise);
|
||||||
deferred.resolve({});
|
deferred.resolve({});
|
||||||
|
var deferredCanEdit = $q.defer();
|
||||||
|
spyOn(keystone, 'canEditIdentity').and.returnValue(deferredCanEdit.promise);
|
||||||
|
deferredCanEdit.resolve(true);
|
||||||
policy = $injector.get('horizon.app.core.openstack-service-api.policy');
|
policy = $injector.get('horizon.app.core.openstack-service-api.policy');
|
||||||
var allowedPromise = $q.defer();
|
var allowedPromise = $q.defer();
|
||||||
spyOn(policy, 'ifAllowed').and.returnValue(allowedPromise.promise);
|
spyOn(policy, 'ifAllowed').and.returnValue(allowedPromise.promise);
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
|
|
||||||
function allowed(selected) {
|
function allowed(selected) {
|
||||||
return $q.all([
|
return $q.all([
|
||||||
|
keystone.canEditIdentity('user'),
|
||||||
$qExtensions.booleanAsPromise(!selected.enabled),
|
$qExtensions.booleanAsPromise(!selected.enabled),
|
||||||
policy.ifAllowed({ rules: [['identity', 'identity:update_user']] })
|
policy.ifAllowed({ rules: [['identity', 'identity:update_user']] })
|
||||||
]);
|
]);
|
||||||
|
@ -35,6 +35,9 @@
|
|||||||
var deferred = $q.defer();
|
var deferred = $q.defer();
|
||||||
spyOn(keystone, 'editUser').and.returnValue(deferred.promise);
|
spyOn(keystone, 'editUser').and.returnValue(deferred.promise);
|
||||||
deferred.resolve({});
|
deferred.resolve({});
|
||||||
|
var deferredCanEdit = $q.defer();
|
||||||
|
spyOn(keystone, 'canEditIdentity').and.returnValue(deferredCanEdit.promise);
|
||||||
|
deferredCanEdit.resolve(true);
|
||||||
policy = $injector.get('horizon.app.core.openstack-service-api.policy');
|
policy = $injector.get('horizon.app.core.openstack-service-api.policy');
|
||||||
var allowedPromise = $q.defer();
|
var allowedPromise = $q.defer();
|
||||||
spyOn(policy, 'ifAllowed').and.returnValue(allowedPromise.promise);
|
spyOn(policy, 'ifAllowed').and.returnValue(allowedPromise.promise);
|
||||||
|
@ -62,7 +62,10 @@
|
|||||||
//////////////
|
//////////////
|
||||||
|
|
||||||
function allowed() {
|
function allowed() {
|
||||||
return policy.ifAllowed({ rules: [['identity', 'identity:update_user']] });
|
return $q.all([
|
||||||
|
keystone.canEditIdentity('user'),
|
||||||
|
policy.ifAllowed({ rules: [['identity', 'identity:update_user']] })
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
@ -40,6 +40,9 @@
|
|||||||
var deferred = $q.defer();
|
var deferred = $q.defer();
|
||||||
spyOn(policy, 'ifAllowed').and.returnValue(deferred.promise);
|
spyOn(policy, 'ifAllowed').and.returnValue(deferred.promise);
|
||||||
deferred.resolve({allowed: true});
|
deferred.resolve({allowed: true});
|
||||||
|
var deferredCanEdit = $q.defer();
|
||||||
|
spyOn(keystone, 'canEditIdentity').and.returnValue(deferredCanEdit.promise);
|
||||||
|
deferredCanEdit.resolve(true);
|
||||||
var handler = jasmine.createSpyObj('handler', ['success']);
|
var handler = jasmine.createSpyObj('handler', ['success']);
|
||||||
|
|
||||||
service.allowed().then(handler.success);
|
service.allowed().then(handler.success);
|
||||||
|
@ -60,7 +60,10 @@
|
|||||||
//////////////
|
//////////////
|
||||||
|
|
||||||
function allowed() {
|
function allowed() {
|
||||||
return policy.ifAllowed({ rules: [['identity', 'identity:update_user']] });
|
return $q.all([
|
||||||
|
keystone.canEditIdentity('user'),
|
||||||
|
policy.ifAllowed({ rules: [['identity', 'identity:update_user']] })
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function perform(selected) {
|
function perform(selected) {
|
||||||
|
@ -39,6 +39,9 @@
|
|||||||
var deferred = $q.defer();
|
var deferred = $q.defer();
|
||||||
spyOn(policy, 'ifAllowed').and.returnValue(deferred.promise);
|
spyOn(policy, 'ifAllowed').and.returnValue(deferred.promise);
|
||||||
deferred.resolve({allowed: true});
|
deferred.resolve({allowed: true});
|
||||||
|
var deferredCanEdit = $q.defer();
|
||||||
|
spyOn(keystone, 'canEditIdentity').and.returnValue(deferredCanEdit.promise);
|
||||||
|
deferredCanEdit.resolve(true);
|
||||||
var handler = jasmine.createSpyObj('handler', ['success']);
|
var handler = jasmine.createSpyObj('handler', ['success']);
|
||||||
|
|
||||||
service.allowed().then(handler.success);
|
service.allowed().then(handler.success);
|
||||||
|
@ -792,6 +792,7 @@ SECURITY_GROUP_RULES = {
|
|||||||
REST_API_REQUIRED_SETTINGS = ['OPENSTACK_HYPERVISOR_FEATURES',
|
REST_API_REQUIRED_SETTINGS = ['OPENSTACK_HYPERVISOR_FEATURES',
|
||||||
'LAUNCH_INSTANCE_DEFAULTS',
|
'LAUNCH_INSTANCE_DEFAULTS',
|
||||||
'OPENSTACK_IMAGE_FORMATS',
|
'OPENSTACK_IMAGE_FORMATS',
|
||||||
|
'OPENSTACK_KEYSTONE_BACKEND',
|
||||||
'OPENSTACK_KEYSTONE_DEFAULT_DOMAIN',
|
'OPENSTACK_KEYSTONE_DEFAULT_DOMAIN',
|
||||||
'CREATE_IMAGE_DEFAULTS',
|
'CREATE_IMAGE_DEFAULTS',
|
||||||
'ENFORCE_PASSWORD_CHECK']
|
'ENFORCE_PASSWORD_CHECK']
|
||||||
|
@ -22,11 +22,12 @@
|
|||||||
|
|
||||||
keystoneAPI.$inject = [
|
keystoneAPI.$inject = [
|
||||||
'$q',
|
'$q',
|
||||||
|
'horizon.app.core.openstack-service-api.settings',
|
||||||
'horizon.framework.util.http.service',
|
'horizon.framework.util.http.service',
|
||||||
'horizon.framework.widgets.toast.service'
|
'horizon.framework.widgets.toast.service'
|
||||||
];
|
];
|
||||||
|
|
||||||
function keystoneAPI($q, apiService, toastService) {
|
function keystoneAPI($q, settingAPI, apiService, toastService) {
|
||||||
var service = {
|
var service = {
|
||||||
getVersion: getVersion,
|
getVersion: getVersion,
|
||||||
getUsers: getUsers,
|
getUsers: getUsers,
|
||||||
@ -64,7 +65,8 @@
|
|||||||
getGroup: getGroup,
|
getGroup: getGroup,
|
||||||
editGroup: editGroup,
|
editGroup: editGroup,
|
||||||
deleteGroup: deleteGroup,
|
deleteGroup: deleteGroup,
|
||||||
deleteGroups: deleteGroups
|
deleteGroups: deleteGroups,
|
||||||
|
canEditIdentity: canEditIdentity
|
||||||
};
|
};
|
||||||
|
|
||||||
return service;
|
return service;
|
||||||
@ -385,6 +387,26 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name canEditIdentity
|
||||||
|
* @description
|
||||||
|
* Returns the promise for can_edit_* setting in OPENSTACK_KEYSTONE_BACKEND.
|
||||||
|
* @returns {object} Deferred promiss
|
||||||
|
*/
|
||||||
|
function canEditIdentity(type) {
|
||||||
|
var deferred = $q.defer();
|
||||||
|
settingAPI.getSetting('OPENSTACK_KEYSTONE_BACKEND', false).then(success);
|
||||||
|
return deferred.promise;
|
||||||
|
|
||||||
|
function success(response) {
|
||||||
|
if (response["can_edit_" + type]) {
|
||||||
|
deferred.resolve();
|
||||||
|
} else {
|
||||||
|
deferred.reject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name serviceCatalog
|
* @name serviceCatalog
|
||||||
* @description
|
* @description
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
describe('Keystone API', function() {
|
describe('Keystone API', function() {
|
||||||
var testCall, service;
|
var testCall, service, settings;
|
||||||
var apiService = {};
|
var apiService = {};
|
||||||
var toastService = {};
|
var toastService = {};
|
||||||
|
|
||||||
@ -31,9 +31,10 @@
|
|||||||
|
|
||||||
beforeEach(module('horizon.app.core.openstack-service-api'));
|
beforeEach(module('horizon.app.core.openstack-service-api'));
|
||||||
|
|
||||||
beforeEach(inject(['horizon.app.core.openstack-service-api.keystone', function(keystoneAPI) {
|
beforeEach(inject(function($injector) {
|
||||||
service = keystoneAPI;
|
service = $injector.get('horizon.app.core.openstack-service-api.keystone');
|
||||||
}]));
|
settings = $injector.get('horizon.app.core.openstack-service-api.settings');
|
||||||
|
}));
|
||||||
|
|
||||||
it('defines the service', function() {
|
it('defines the service', function() {
|
||||||
expect(service).toBeDefined();
|
expect(service).toBeDefined();
|
||||||
@ -508,6 +509,32 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('canEditIdentity', function () {
|
||||||
|
var deferred, $timeout;
|
||||||
|
|
||||||
|
beforeEach(inject(function (_$q_, _$timeout_) {
|
||||||
|
deferred = _$q_.defer();
|
||||||
|
$timeout = _$timeout_;
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should resolve true if can_edit_group is set True', function() {
|
||||||
|
deferred.resolve({can_edit_group: true});
|
||||||
|
spyOn(settings, 'getSettings').and.returnValue(deferred.promise);
|
||||||
|
var canEdit = service.canEditIdentity('group');
|
||||||
|
$timeout.flush();
|
||||||
|
expect(canEdit).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resolve false if can_edit_group is set False', function() {
|
||||||
|
deferred.resolve({can_edit_group: false});
|
||||||
|
spyOn(settings, 'getSettings').and.returnValue(deferred.promise);
|
||||||
|
var canEdit = service.canEditIdentity('group');
|
||||||
|
$timeout.flush();
|
||||||
|
// reject
|
||||||
|
expect(canEdit.$$state.status).toEqual(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
15
releasenotes/notes/bug-1779268-44848e4d2c69fddc.yaml
Normal file
15
releasenotes/notes/bug-1779268-44848e4d2c69fddc.yaml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- |
|
||||||
|
[:bug:`1779268`] Supported ``can_edit_*`` settings in Angularized identity
|
||||||
|
panels. To enable this settings in Angularized identity panels, add
|
||||||
|
``OPENSTACK_KEYSTONE_BACKEND`` into ``REST_API_REQUIRED_SETTINGS`` on
|
||||||
|
``local_settings.py``. For more detail, see
|
||||||
|
`REST_API_REQUIRED_SETTINGS <https://docs.openstack.org/horizon/latest/configuration/settings.html#rest-api-required-settings>`__
|
||||||
|
in horizon settings documentation.
|
||||||
|
upgrade:
|
||||||
|
- |
|
||||||
|
Add ``OPENSTACK_KEYSTONE_BACKEND`` manually into
|
||||||
|
``REST_API_REQUIRED_SETTINGS`` on ``local_settings.py``, if your deployment
|
||||||
|
uses Angularized identity panels and needs to enable ``can_edit_*``
|
||||||
|
settings in ``OPENSTACK_KEYSTONE_BACKEND``.
|
Loading…
x
Reference in New Issue
Block a user