mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
New Feature: Enable/Disable Roles (#9549)
* New feature: Enable/Disable Roles * Fixes * Fix unit tests
This commit is contained in:
parent
d7ca05e5ba
commit
d32ace6731
@ -242,6 +242,8 @@ public class EventTypes {
|
||||
public static final String EVENT_ROLE_UPDATE = "ROLE.UPDATE";
|
||||
public static final String EVENT_ROLE_DELETE = "ROLE.DELETE";
|
||||
public static final String EVENT_ROLE_IMPORT = "ROLE.IMPORT";
|
||||
public static final String EVENT_ROLE_ENABLE = "ROLE.ENABLE";
|
||||
public static final String EVENT_ROLE_DISABLE = "ROLE.DISABLE";
|
||||
public static final String EVENT_ROLE_PERMISSION_CREATE = "ROLE.PERMISSION.CREATE";
|
||||
public static final String EVENT_ROLE_PERMISSION_UPDATE = "ROLE.PERMISSION.UPDATE";
|
||||
public static final String EVENT_ROLE_PERMISSION_DELETE = "ROLE.PERMISSION.DELETE";
|
||||
@ -842,6 +844,8 @@ public class EventTypes {
|
||||
entityEventDetails.put(EVENT_ROLE_UPDATE, Role.class);
|
||||
entityEventDetails.put(EVENT_ROLE_DELETE, Role.class);
|
||||
entityEventDetails.put(EVENT_ROLE_IMPORT, Role.class);
|
||||
entityEventDetails.put(EVENT_ROLE_ENABLE, Role.class);
|
||||
entityEventDetails.put(EVENT_ROLE_DISABLE, Role.class);
|
||||
entityEventDetails.put(EVENT_ROLE_PERMISSION_CREATE, RolePermission.class);
|
||||
entityEventDetails.put(EVENT_ROLE_PERMISSION_UPDATE, RolePermission.class);
|
||||
entityEventDetails.put(EVENT_ROLE_PERMISSION_DELETE, RolePermission.class);
|
||||
|
||||
@ -21,7 +21,18 @@ import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
public interface Role extends RoleEntity, InternalIdentity, Identity {
|
||||
|
||||
enum State {
|
||||
ENABLED, DISABLED;
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return super.toString().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
RoleType getRoleType();
|
||||
boolean isDefault();
|
||||
boolean isPublicRole();
|
||||
State getState();
|
||||
}
|
||||
|
||||
@ -54,6 +54,10 @@ public interface RoleService {
|
||||
|
||||
boolean deleteRole(Role role);
|
||||
|
||||
boolean enableRole(Role role);
|
||||
|
||||
boolean disableRole(Role role);
|
||||
|
||||
RolePermission findRolePermission(Long id);
|
||||
|
||||
RolePermission findRolePermissionByRoleIdAndRule(Long roleId, String rule);
|
||||
@ -76,7 +80,7 @@ public interface RoleService {
|
||||
*/
|
||||
List<Role> listRoles();
|
||||
|
||||
Pair<List<Role>, Integer> listRoles(Long startIndex, Long limit);
|
||||
Pair<List<Role>, Integer> listRoles(String state, Long startIndex, Long limit);
|
||||
|
||||
/**
|
||||
* Find all roles that have the giving {@link String} as part of their name.
|
||||
@ -84,14 +88,14 @@ public interface RoleService {
|
||||
*/
|
||||
List<Role> findRolesByName(String name);
|
||||
|
||||
Pair<List<Role>, Integer> findRolesByName(String name, String keyword, Long startIndex, Long limit);
|
||||
Pair<List<Role>, Integer> findRolesByName(String name, String keyword, String state, Long startIndex, Long limit);
|
||||
|
||||
/**
|
||||
* Find all roles by {@link RoleType}. If the role type is {@link RoleType#Admin}, the calling account must be a root admin, otherwise we return an empty list.
|
||||
*/
|
||||
List<Role> findRolesByType(RoleType roleType);
|
||||
|
||||
Pair<List<Role>, Integer> findRolesByType(RoleType roleType, Long startIndex, Long limit);
|
||||
Pair<List<Role>, Integer> findRolesByType(RoleType roleType, String state, Long startIndex, Long limit);
|
||||
|
||||
List<RolePermission> findAllPermissionsBy(Long roleId);
|
||||
|
||||
|
||||
@ -0,0 +1,69 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you 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
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.admin.acl;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.user.Account;
|
||||
import org.apache.cloudstack.acl.Role;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.RoleResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
@APICommand(name = "disableRole", description = "Disables a role", responseObject = SuccessResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
|
||||
since = "4.20.0",
|
||||
authorized = {RoleType.Admin})
|
||||
public class DisableRoleCmd extends BaseCmd {
|
||||
|
||||
@Parameter(name = ApiConstants.ID, type = BaseCmd.CommandType.UUID, required = true, entityType = RoleResponse.class,
|
||||
description = "ID of the role", validations = {ApiArgValidator.PositiveNumber})
|
||||
private Long roleId;
|
||||
|
||||
public Long getRoleId() {
|
||||
return roleId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
Role role = roleService.findRole(getRoleId());
|
||||
if (role == null) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Cannot find the role with provided id");
|
||||
}
|
||||
CallContext.current().setEventDetails("Role id: " + role.getId());
|
||||
boolean result = roleService.disableRole(role);
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
response.setSuccess(result);
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you 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
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.admin.acl;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.user.Account;
|
||||
import org.apache.cloudstack.acl.Role;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.RoleResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
@APICommand(name = "enableRole", description = "Enables a role", responseObject = SuccessResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
|
||||
since = "4.20.0",
|
||||
authorized = {RoleType.Admin})
|
||||
public class EnableRoleCmd extends BaseCmd {
|
||||
|
||||
@Parameter(name = ApiConstants.ID, type = BaseCmd.CommandType.UUID, required = true, entityType = RoleResponse.class,
|
||||
description = "ID of the role", validations = {ApiArgValidator.PositiveNumber})
|
||||
private Long roleId;
|
||||
|
||||
public Long getRoleId() {
|
||||
return roleId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||
Role role = roleService.findRole(getRoleId());
|
||||
if (role == null) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Cannot find the role with provided id");
|
||||
}
|
||||
CallContext.current().setEventDetails("Role id: " + role.getId());
|
||||
boolean result = roleService.enableRole(role);
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
response.setSuccess(result);
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
}
|
||||
@ -21,6 +21,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import org.apache.cloudstack.acl.Role;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
@ -51,6 +52,9 @@ public class ListRolesCmd extends BaseListCmd {
|
||||
@Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "List role by role type, valid options are: Admin, ResourceAdmin, DomainAdmin, User.")
|
||||
private String roleType;
|
||||
|
||||
@Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "List role by role type status, valid options are: enabled, disabled")
|
||||
private String roleState;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -70,6 +74,17 @@ public class ListRolesCmd extends BaseListCmd {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Role.State getRoleState() {
|
||||
if (roleState == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Role.State.valueOf(roleState.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new InvalidParameterValueException("Unrecognized role state value");
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -93,6 +108,7 @@ public class ListRolesCmd extends BaseListCmd {
|
||||
roleResponse.setDescription(role.getDescription());
|
||||
roleResponse.setIsDefault(role.isDefault());
|
||||
roleResponse.setPublicRole(role.isPublicRole());
|
||||
roleResponse.setState(role.getState().toString());
|
||||
roleResponse.setObjectName("role");
|
||||
roleResponses.add(roleResponse);
|
||||
}
|
||||
@ -104,14 +120,16 @@ public class ListRolesCmd extends BaseListCmd {
|
||||
@Override
|
||||
public void execute() {
|
||||
Pair<List<Role>, Integer> roles;
|
||||
Role.State state = getRoleState();
|
||||
String roleStateStr = state != null ? state.toString() : null;
|
||||
if (getId() != null && getId() > 0L) {
|
||||
roles = new Pair<>(Collections.singletonList(roleService.findRole(getId(), true)), 1);
|
||||
} else if (StringUtils.isNotBlank(getName()) || StringUtils.isNotBlank(getKeyword())) {
|
||||
roles = roleService.findRolesByName(getName(), getKeyword(), getStartIndex(), getPageSizeVal());
|
||||
roles = roleService.findRolesByName(getName(), getKeyword(), roleStateStr, getStartIndex(), getPageSizeVal());
|
||||
} else if (getRoleType() != null) {
|
||||
roles = roleService.findRolesByType(getRoleType(), getStartIndex(), getPageSizeVal());
|
||||
roles = roleService.findRolesByType(getRoleType(), roleStateStr, getStartIndex(), getPageSizeVal());
|
||||
} else {
|
||||
roles = roleService.listRoles(getStartIndex(), getPageSizeVal());
|
||||
roles = roleService.listRoles(roleStateStr, getStartIndex(), getPageSizeVal());
|
||||
}
|
||||
setupResponse(roles);
|
||||
}
|
||||
|
||||
@ -59,6 +59,7 @@ public abstract class RoleCmd extends BaseCmd {
|
||||
response.setRoleType(role.getRoleType());
|
||||
response.setDescription(role.getDescription());
|
||||
response.setPublicRole(role.isPublicRole());
|
||||
response.setState(role.getState().toString());
|
||||
response.setResponseName(getCommandName());
|
||||
response.setObjectName("role");
|
||||
setResponseObject(response);
|
||||
|
||||
@ -36,6 +36,10 @@ public class RoleResponse extends BaseRoleResponse {
|
||||
@Param(description = "true if role is default, false otherwise")
|
||||
private Boolean isDefault;
|
||||
|
||||
@SerializedName(ApiConstants.STATE)
|
||||
@Param(description = "the state of the role")
|
||||
private String state;
|
||||
|
||||
public void setRoleType(RoleType roleType) {
|
||||
if (roleType != null) {
|
||||
this.roleType = roleType.name();
|
||||
@ -45,4 +49,8 @@ public class RoleResponse extends BaseRoleResponse {
|
||||
public void setIsDefault(Boolean isDefault) {
|
||||
this.isDefault = isDefault;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,6 +54,7 @@ public class CreateRoleCmdTest {
|
||||
when(role.getDescription()).thenReturn("User test");
|
||||
when(role.getName()).thenReturn("testuser");
|
||||
when(role.getRoleType()).thenReturn(RoleType.User);
|
||||
when(role.getState()).thenReturn(Role.State.ENABLED);
|
||||
when(roleService.createRole(createRoleCmd.getRoleName(), createRoleCmd.getRoleType(), createRoleCmd.getRoleDescription(), true)).thenReturn(role);
|
||||
createRoleCmd.execute();
|
||||
RoleResponse response = (RoleResponse) createRoleCmd.getResponseObject();
|
||||
@ -71,6 +72,7 @@ public class CreateRoleCmdTest {
|
||||
when(newRole.getDescription()).thenReturn("User test");
|
||||
when(newRole.getName()).thenReturn("testuser");
|
||||
when(newRole.getRoleType()).thenReturn(RoleType.User);
|
||||
when(newRole.getState()).thenReturn(Role.State.ENABLED);
|
||||
when(roleService.createRole(createRoleCmd.getRoleName(), role, createRoleCmd.getRoleDescription(), true)).thenReturn(newRole);
|
||||
createRoleCmd.execute();
|
||||
RoleResponse response = (RoleResponse) createRoleCmd.getResponseObject();
|
||||
|
||||
@ -87,6 +87,7 @@ public class ImportRoleCmdTest {
|
||||
when(role.getDescription()).thenReturn("test user imported");
|
||||
when(role.getName()).thenReturn("Test User");
|
||||
when(role.getRoleType()).thenReturn(RoleType.User);
|
||||
when(role.getState()).thenReturn(Role.State.ENABLED);
|
||||
when(roleService.importRole(anyString(), any(), anyString(), any(), anyBoolean(), anyBoolean())).thenReturn(role);
|
||||
|
||||
importRoleCmd.execute();
|
||||
|
||||
@ -62,6 +62,7 @@ public class UpdateRoleCmdTest extends TestCase{
|
||||
when(role.getId()).thenReturn(1L);
|
||||
when(role.getDescription()).thenReturn("Description Initial");
|
||||
when(role.getName()).thenReturn("User");
|
||||
when(role.getState()).thenReturn(Role.State.ENABLED);
|
||||
updateRoleCmd.execute();
|
||||
RoleResponse response = (RoleResponse) updateRoleCmd.getResponseObject();
|
||||
assertEquals((String)ReflectionTestUtils.getField(response, "roleName"),role.getName());
|
||||
|
||||
@ -58,11 +58,16 @@ public class RoleVO implements Role {
|
||||
@Column(name = "public_role")
|
||||
private boolean publicRole = true;
|
||||
|
||||
@Column(name = "state")
|
||||
@Enumerated(value = EnumType.STRING)
|
||||
private State state;
|
||||
|
||||
@Column(name = GenericDao.REMOVED_COLUMN)
|
||||
private Date removed;
|
||||
|
||||
public RoleVO() {
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
this.state = State.ENABLED;
|
||||
}
|
||||
|
||||
public RoleVO(final String name, final RoleType roleType, final String description) {
|
||||
@ -131,4 +136,12 @@ public class RoleVO implements Role {
|
||||
public void setPublicRole(boolean publicRole) {
|
||||
this.publicRole = publicRole;
|
||||
}
|
||||
|
||||
public State getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(State state) {
|
||||
this.state = state;
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,15 +28,15 @@ import java.util.List;
|
||||
public interface RoleDao extends GenericDao<RoleVO, Long> {
|
||||
List<RoleVO> findAllByName(String roleName, boolean showPrivateRole);
|
||||
|
||||
Pair<List<RoleVO>, Integer> findAllByName(final String roleName, String keyword, Long offset, Long limit, boolean showPrivateRole);
|
||||
Pair<List<RoleVO>, Integer> findAllByName(final String roleName, String keyword, String state, Long offset, Long limit, boolean showPrivateRole);
|
||||
|
||||
List<RoleVO> findAllByRoleType(RoleType type, boolean showPrivateRole);
|
||||
List<RoleVO> findByName(String roleName, boolean showPrivateRole);
|
||||
RoleVO findByNameAndType(String roleName, RoleType type, boolean showPrivateRole);
|
||||
|
||||
Pair<List<RoleVO>, Integer> findAllByRoleType(RoleType type, Long offset, Long limit, boolean showPrivateRole);
|
||||
Pair<List<RoleVO>, Integer> findAllByRoleType(RoleType type, String state, Long offset, Long limit, boolean showPrivateRole);
|
||||
|
||||
Pair<List<RoleVO>, Integer> listAllRoles(Long startIndex, Long limit, boolean showPrivateRole);
|
||||
Pair<List<RoleVO>, Integer> listAllRoles(String state, Long startIndex, Long limit, boolean showPrivateRole);
|
||||
|
||||
List<RoleVO> searchByIds(Long... ids);
|
||||
}
|
||||
|
||||
@ -50,11 +50,13 @@ public class RoleDaoImpl extends GenericDaoBase<RoleVO, Long> implements RoleDao
|
||||
RoleByNameSearch = createSearchBuilder();
|
||||
RoleByNameSearch.and("roleName", RoleByNameSearch.entity().getName(), SearchCriteria.Op.LIKE);
|
||||
RoleByNameSearch.and("isPublicRole", RoleByNameSearch.entity().isPublicRole(), SearchCriteria.Op.EQ);
|
||||
RoleByNameSearch.and("state", RoleByNameSearch.entity().getState(), SearchCriteria.Op.EQ);
|
||||
RoleByNameSearch.done();
|
||||
|
||||
RoleByTypeSearch = createSearchBuilder();
|
||||
RoleByTypeSearch.and("roleType", RoleByTypeSearch.entity().getRoleType(), SearchCriteria.Op.EQ);
|
||||
RoleByTypeSearch.and("isPublicRole", RoleByTypeSearch.entity().isPublicRole(), SearchCriteria.Op.EQ);
|
||||
RoleByTypeSearch.and("state", RoleByTypeSearch.entity().getState(), SearchCriteria.Op.EQ);
|
||||
RoleByTypeSearch.done();
|
||||
|
||||
RoleByNameAndTypeSearch = createSearchBuilder();
|
||||
@ -65,16 +67,17 @@ public class RoleDaoImpl extends GenericDaoBase<RoleVO, Long> implements RoleDao
|
||||
|
||||
RoleByIsPublicSearch = createSearchBuilder();
|
||||
RoleByIsPublicSearch.and("isPublicRole", RoleByIsPublicSearch.entity().isPublicRole(), SearchCriteria.Op.EQ);
|
||||
RoleByIsPublicSearch.and("state", RoleByIsPublicSearch.entity().getState(), SearchCriteria.Op.EQ);
|
||||
RoleByIsPublicSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RoleVO> findAllByName(final String roleName, boolean showPrivateRole) {
|
||||
return findAllByName(roleName, null, null, null, showPrivateRole).first();
|
||||
return findAllByName(roleName, null, null, null, null, showPrivateRole).first();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<List<RoleVO>, Integer> findAllByName(final String roleName, String keyword, Long offset, Long limit, boolean showPrivateRole) {
|
||||
public Pair<List<RoleVO>, Integer> findAllByName(final String roleName, String keyword, String state, Long offset, Long limit, boolean showPrivateRole) {
|
||||
SearchCriteria<RoleVO> sc = RoleByNameSearch.create();
|
||||
filterPrivateRolesIfNeeded(sc, showPrivateRole);
|
||||
if (StringUtils.isNotEmpty(roleName)) {
|
||||
@ -83,19 +86,25 @@ public class RoleDaoImpl extends GenericDaoBase<RoleVO, Long> implements RoleDao
|
||||
if (StringUtils.isNotEmpty(keyword)) {
|
||||
sc.setParameters("roleName", "%" + keyword + "%");
|
||||
}
|
||||
if (StringUtils.isNotEmpty(state)) {
|
||||
sc.setParameters("state", state);
|
||||
}
|
||||
|
||||
return searchAndCount(sc, new Filter(RoleVO.class, "id", true, offset, limit));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RoleVO> findAllByRoleType(final RoleType type, boolean showPrivateRole) {
|
||||
return findAllByRoleType(type, null, null, showPrivateRole).first();
|
||||
return findAllByRoleType(type, null, null, null, showPrivateRole).first();
|
||||
}
|
||||
|
||||
public Pair<List<RoleVO>, Integer> findAllByRoleType(final RoleType type, Long offset, Long limit, boolean showPrivateRole) {
|
||||
public Pair<List<RoleVO>, Integer> findAllByRoleType(final RoleType type, String state, Long offset, Long limit, boolean showPrivateRole) {
|
||||
SearchCriteria<RoleVO> sc = RoleByTypeSearch.create();
|
||||
filterPrivateRolesIfNeeded(sc, showPrivateRole);
|
||||
sc.setParameters("roleType", type);
|
||||
if (StringUtils.isNotEmpty(state)) {
|
||||
sc.setParameters("state", state);
|
||||
}
|
||||
return searchAndCount(sc, new Filter(RoleVO.class, "id", true, offset, limit));
|
||||
}
|
||||
|
||||
@ -117,8 +126,11 @@ public class RoleDaoImpl extends GenericDaoBase<RoleVO, Long> implements RoleDao
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<List<RoleVO>, Integer> listAllRoles(Long startIndex, Long limit, boolean showPrivateRole) {
|
||||
public Pair<List<RoleVO>, Integer> listAllRoles(String state, Long startIndex, Long limit, boolean showPrivateRole) {
|
||||
SearchCriteria<RoleVO> sc = RoleByIsPublicSearch.create();
|
||||
if (StringUtils.isNotEmpty(state)) {
|
||||
sc.setParameters("state", state);
|
||||
}
|
||||
filterPrivateRolesIfNeeded(sc, showPrivateRole);
|
||||
return searchAndCount(sc, new Filter(RoleVO.class, "id", true, startIndex, limit));
|
||||
}
|
||||
|
||||
@ -231,3 +231,5 @@ CALL `cloud`.`IDEMPOTENT_MODIFY_COLUMN_CHAR_SET`('vpc', 'display_text', 'VARCHAR
|
||||
CALL `cloud`.`IDEMPOTENT_MODIFY_COLUMN_CHAR_SET`('vpc_offerings', 'name', 'VARCHAR(255)', 'DEFAULT NULL COMMENT \'vpc offering name\'');
|
||||
CALL `cloud`.`IDEMPOTENT_MODIFY_COLUMN_CHAR_SET`('vpc_offerings', 'unique_name', 'VARCHAR(64)', 'DEFAULT NULL COMMENT \'unique name of the vpc offering\'');
|
||||
CALL `cloud`.`IDEMPOTENT_MODIFY_COLUMN_CHAR_SET`('vpc_offerings', 'display_text', 'VARCHAR(255)', 'DEFAULT NULL COMMENT \'display text\'');
|
||||
|
||||
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.roles','state', 'varchar(10) NOT NULL default "enabled" COMMENT "role state"');
|
||||
|
||||
@ -36,6 +36,8 @@ import org.apache.cloudstack.api.command.admin.acl.CreateRoleCmd;
|
||||
import org.apache.cloudstack.api.command.admin.acl.CreateRolePermissionCmd;
|
||||
import org.apache.cloudstack.api.command.admin.acl.DeleteRoleCmd;
|
||||
import org.apache.cloudstack.api.command.admin.acl.DeleteRolePermissionCmd;
|
||||
import org.apache.cloudstack.api.command.admin.acl.DisableRoleCmd;
|
||||
import org.apache.cloudstack.api.command.admin.acl.EnableRoleCmd;
|
||||
import org.apache.cloudstack.api.command.admin.acl.ImportRoleCmd;
|
||||
import org.apache.cloudstack.api.command.admin.acl.ListRolePermissionsCmd;
|
||||
import org.apache.cloudstack.api.command.admin.acl.ListRolesCmd;
|
||||
@ -349,6 +351,36 @@ public class RoleManagerImpl extends ManagerBase implements RoleService, Configu
|
||||
throw new PermissionDeniedException("Found accounts that have role in use, won't allow to delete role");
|
||||
}
|
||||
|
||||
protected boolean updateRoleState(Role role, Role.State state) {
|
||||
checkCallerAccess();
|
||||
if (role == null) {
|
||||
return false;
|
||||
}
|
||||
if (role.getState().equals(state)) {
|
||||
throw new PermissionDeniedException(String.format("Role is already %s", state));
|
||||
}
|
||||
return Transaction.execute(new TransactionCallback<Boolean>() {
|
||||
@Override
|
||||
public Boolean doInTransaction(TransactionStatus status) {
|
||||
RoleVO roleVO = roleDao.findById(role.getId());
|
||||
roleVO.setState(state);
|
||||
return roleDao.update(role.getId(), roleVO);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_ROLE_ENABLE, eventDescription = "enabling Role")
|
||||
public boolean enableRole(Role role) {
|
||||
return updateRoleState(role, Role.State.ENABLED);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_ROLE_DISABLE, eventDescription = "disabling Role")
|
||||
public boolean disableRole(Role role) {
|
||||
return updateRoleState(role, Role.State.DISABLED);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_ROLE_PERMISSION_CREATE, eventDescription = "creating Role Permission")
|
||||
public RolePermission createRolePermission(final Role role, final Rule rule, final Permission permission, final String description) {
|
||||
@ -401,13 +433,13 @@ public class RoleManagerImpl extends ManagerBase implements RoleService, Configu
|
||||
|
||||
@Override
|
||||
public List<Role> findRolesByName(String name) {
|
||||
return findRolesByName(name, null, null, null).first();
|
||||
return findRolesByName(name, null, null, null, null).first();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<List<Role>, Integer> findRolesByName(String name, String keyword, Long startIndex, Long limit) {
|
||||
public Pair<List<Role>, Integer> findRolesByName(String name, String keyword, String state, Long startIndex, Long limit) {
|
||||
if (StringUtils.isNotBlank(name) || StringUtils.isNotBlank(keyword)) {
|
||||
Pair<List<RoleVO>, Integer> data = roleDao.findAllByName(name, keyword, startIndex, limit, isCallerRootAdmin());
|
||||
Pair<List<RoleVO>, Integer> data = roleDao.findAllByName(name, keyword, state, startIndex, limit, isCallerRootAdmin());
|
||||
int removed = removeRolesIfNeeded(data.first());
|
||||
return new Pair<List<Role>,Integer>(ListUtils.toListOfInterface(data.first()), Integer.valueOf(data.second() - removed));
|
||||
}
|
||||
@ -504,15 +536,15 @@ public class RoleManagerImpl extends ManagerBase implements RoleService, Configu
|
||||
|
||||
@Override
|
||||
public List<Role> findRolesByType(RoleType roleType) {
|
||||
return findRolesByType(roleType, null, null).first();
|
||||
return findRolesByType(roleType, null, null, null).first();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<List<Role>, Integer> findRolesByType(RoleType roleType, Long startIndex, Long limit) {
|
||||
public Pair<List<Role>, Integer> findRolesByType(RoleType roleType, String state, Long startIndex, Long limit) {
|
||||
if (roleType == null || RoleType.Admin == roleType && !isCallerRootAdmin()) {
|
||||
return new Pair<List<Role>, Integer>(Collections.emptyList(), 0);
|
||||
}
|
||||
Pair<List<RoleVO>, Integer> data = roleDao.findAllByRoleType(roleType, startIndex, limit, isCallerRootAdmin());
|
||||
Pair<List<RoleVO>, Integer> data = roleDao.findAllByRoleType(roleType, state, startIndex, limit, isCallerRootAdmin());
|
||||
return new Pair<List<Role>,Integer>(ListUtils.toListOfInterface(data.first()), Integer.valueOf(data.second()));
|
||||
}
|
||||
|
||||
@ -524,8 +556,8 @@ public class RoleManagerImpl extends ManagerBase implements RoleService, Configu
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<List<Role>, Integer> listRoles(Long startIndex, Long limit) {
|
||||
Pair<List<RoleVO>, Integer> data = roleDao.listAllRoles(startIndex, limit, isCallerRootAdmin());
|
||||
public Pair<List<Role>, Integer> listRoles(String state, Long startIndex, Long limit) {
|
||||
Pair<List<RoleVO>, Integer> data = roleDao.listAllRoles(state, startIndex, limit, isCallerRootAdmin());
|
||||
int removed = removeRolesIfNeeded(data.first());
|
||||
return new Pair<List<Role>,Integer>(ListUtils.toListOfInterface(data.first()), Integer.valueOf(data.second() - removed));
|
||||
}
|
||||
@ -577,6 +609,8 @@ public class RoleManagerImpl extends ManagerBase implements RoleService, Configu
|
||||
cmdList.add(ListRolePermissionsCmd.class);
|
||||
cmdList.add(UpdateRolePermissionCmd.class);
|
||||
cmdList.add(DeleteRolePermissionCmd.class);
|
||||
cmdList.add(EnableRoleCmd.class);
|
||||
cmdList.add(DisableRoleCmd.class);
|
||||
return cmdList;
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,7 +214,7 @@ public class RoleManagerImplTest {
|
||||
String roleName = "roleName";
|
||||
List<Role> roles = new ArrayList<>();
|
||||
Pair<ArrayList<RoleVO>, Integer> toBeReturned = new Pair(roles, 0);
|
||||
Mockito.doReturn(toBeReturned).when(roleDaoMock).findAllByName(roleName, null, null, null, false);
|
||||
Mockito.doReturn(toBeReturned).when(roleDaoMock).findAllByName(roleName, null, null, null, null, false);
|
||||
|
||||
roleManagerImpl.findRolesByName(roleName);
|
||||
Mockito.verify(roleManagerImpl).removeRolesIfNeeded(roles);
|
||||
@ -345,7 +345,7 @@ public class RoleManagerImplTest {
|
||||
List<Role> roles = new ArrayList<>();
|
||||
roles.add(Mockito.mock(Role.class));
|
||||
Pair<ArrayList<RoleVO>, Integer> toBeReturned = new Pair(roles, 1);
|
||||
Mockito.doReturn(toBeReturned).when(roleDaoMock).findAllByRoleType(RoleType.Admin, null, null, true);
|
||||
Mockito.doReturn(toBeReturned).when(roleDaoMock).findAllByRoleType(RoleType.Admin, null, null, null, true);
|
||||
List<Role> returnedRoles = roleManagerImpl.findRolesByType(RoleType.Admin);
|
||||
|
||||
Assert.assertEquals(1, returnedRoles.size());
|
||||
@ -360,7 +360,7 @@ public class RoleManagerImplTest {
|
||||
List<Role> roles = new ArrayList<>();
|
||||
roles.add(Mockito.mock(Role.class));
|
||||
Pair<ArrayList<RoleVO>, Integer> toBeReturned = new Pair(roles, 1);
|
||||
Mockito.doReturn(toBeReturned).when(roleDaoMock).findAllByRoleType(RoleType.User, null, null, true);
|
||||
Mockito.doReturn(toBeReturned).when(roleDaoMock).findAllByRoleType(RoleType.User, null, null, null, true);
|
||||
List<Role> returnedRoles = roleManagerImpl.findRolesByType(RoleType.User);
|
||||
|
||||
Assert.assertEquals(1, returnedRoles.size());
|
||||
|
||||
@ -109,6 +109,7 @@
|
||||
"label.action.disable.disk.offering": "Disable disk offering",
|
||||
"label.action.disable.physical.network": "Disable physical Network",
|
||||
"label.action.disable.pod": "Disable pod",
|
||||
"label.action.disable.role": "Disable Role",
|
||||
"label.action.disable.static.nat": "Disable static NAT",
|
||||
"label.action.disable.service.offering": "Disable service offering",
|
||||
"label.action.disable.system.service.offering": "Disable system service offering",
|
||||
@ -133,6 +134,7 @@
|
||||
"label.action.enable.maintenance.mode": "Enable maintenance mode",
|
||||
"label.action.enable.physical.network": "Enable physical Network",
|
||||
"label.action.enable.pod": "Enable pod",
|
||||
"label.action.enable.role": "Enable Role",
|
||||
"label.action.enable.service.offering": "Enable service offering",
|
||||
"label.action.enable.system.service.offering": "Enable system service offering",
|
||||
"label.action.enable.static.nat": "Enable static NAT",
|
||||
@ -2884,6 +2886,7 @@
|
||||
"message.detach.disk": "Are you sure you want to detach this disk?",
|
||||
"message.detach.iso.confirm": "Please confirm that you want to detach the ISO from this virtual Instance.",
|
||||
"message.disable.account": "Please confirm that you want to disable this Account. By disabling the Account, all Users for this Account will no longer have access to their cloud resources. All running Instances will be immediately shut down.",
|
||||
"message.disable.role": "Please confirm that you would like to disable this Role",
|
||||
"message.disable.user": "Please confirm that you would like to disable this User.",
|
||||
"message.disable.vpn": "Are you sure you want to disable VPN?",
|
||||
"message.disable.vpn.failed": "Failed to disable VPN.",
|
||||
@ -2905,6 +2908,7 @@
|
||||
"message.egress.rules.info.for.network": "The default egress policy of this Network is %x. <br> Outgoing traffic matching the following egress rules will be %y",
|
||||
"message.enable.account": "Please confirm that you want to enable this Account.",
|
||||
"message.enable.netsacler.provider.failed": "failed to enable Netscaler provider",
|
||||
"message.enable.role": "Please confirm that you want to enable this Role",
|
||||
"message.enable.securitygroup.provider.failed": "failed to enable security group provider",
|
||||
"message.enable.user": "Please confirm that you would like to enable this User.",
|
||||
"message.enable.vpn": "Please confirm that you want remote access VPN enabled for this IP address.",
|
||||
|
||||
@ -25,7 +25,7 @@ export default {
|
||||
docHelp: 'adminguide/accounts.html#roles',
|
||||
permission: ['listRoles', 'listRolePermissions'],
|
||||
searchFilters: ['name', 'type'],
|
||||
columns: ['name', 'type', 'description'],
|
||||
columns: ['name', 'type', 'description', 'state'],
|
||||
details: ['name', 'id', 'type', 'description', 'ispublic'],
|
||||
tabs: [{
|
||||
name: 'details',
|
||||
@ -56,6 +56,38 @@ export default {
|
||||
popup: true,
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/views/iam/ImportRole.vue')))
|
||||
},
|
||||
{
|
||||
api: 'enableRole',
|
||||
icon: 'play-circle-outlined',
|
||||
label: 'label.action.enable.role',
|
||||
message: 'message.enable.role',
|
||||
dataView: true,
|
||||
show: (record, store) => {
|
||||
return record.state === 'disabled'
|
||||
},
|
||||
mapping: {
|
||||
id: {
|
||||
value: (record) => { return record.id }
|
||||
}
|
||||
},
|
||||
popup: true
|
||||
},
|
||||
{
|
||||
api: 'disableRole',
|
||||
icon: 'pause-circle-outlined',
|
||||
label: 'label.action.disable.role',
|
||||
message: 'message.disable.role',
|
||||
dataView: true,
|
||||
show: (record, store) => {
|
||||
return record.state === 'enabled'
|
||||
},
|
||||
mapping: {
|
||||
id: {
|
||||
value: (record) => { return record.id }
|
||||
}
|
||||
},
|
||||
popup: true
|
||||
},
|
||||
{
|
||||
api: 'updateRole',
|
||||
icon: 'edit-outlined',
|
||||
|
||||
@ -307,7 +307,9 @@ export default {
|
||||
},
|
||||
fetchRoles () {
|
||||
this.roleLoading = true
|
||||
api('listRoles').then(response => {
|
||||
const params = {}
|
||||
params.state = 'enabled'
|
||||
api('listRoles', params).then(response => {
|
||||
this.roles = response.listrolesresponse.role || []
|
||||
this.form.roleid = this.roles[0].id
|
||||
if (this.isDomainAdmin()) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user