More logic to Role based checker

This commit is contained in:
Prachi Damle 2013-10-08 15:36:23 -07:00
parent 7ebb972885
commit 0b1aaf514f
6 changed files with 80 additions and 13 deletions

View File

@ -28,4 +28,8 @@ public interface AclRole extends PartOf, InternalIdentity, Identity {
String getDescription();
// Long getParentRoleId();
public enum RoleType {
Static, Dynamic
}
}

View File

@ -21,6 +21,7 @@ import java.util.List;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import com.cloud.utils.Pair;
import com.cloud.user.Account;
public interface AclService {
@ -86,4 +87,6 @@ public interface AclService {
boolean isAPIAccessibleForRoles(String apiName, List<AclRole> roles);
List<AclRole> getEffectiveRoles(Account caller, ControlledEntity entity);
}

View File

@ -21,6 +21,8 @@ import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@ -55,6 +57,10 @@ public class AclRoleVO implements AclRole {
@Column(name = GenericDao.CREATED_COLUMN)
private Date created;
@Column(name = "role_type")
@Enumerated(value = EnumType.STRING)
private AclRole.RoleType roleType;
public AclRoleVO() {
uuid = UUID.randomUUID().toString();
}
@ -63,6 +69,7 @@ public class AclRoleVO implements AclRole {
this.name = name;
this.description = description;
uuid = UUID.randomUUID().toString();
this.roleType = AclRole.RoleType.Static;
}
@Override
@ -107,4 +114,11 @@ public class AclRoleVO implements AclRole {
this.domainId = domainId;
}
public RoleType getRoleType() {
return roleType;
}
public void setRoleType(RoleType roleType) {
this.roleType = roleType;
}
}

View File

@ -21,8 +21,10 @@ import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.acl.AclEntityPermissionVO;
import org.apache.cloudstack.acl.AclEntityType;
import org.apache.cloudstack.acl.AclGroupAccountMapVO;
import org.apache.cloudstack.acl.AclRole;
import org.apache.cloudstack.acl.AclRolePermissionVO;
import org.apache.cloudstack.acl.AclService;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.SecurityChecker;
@ -30,6 +32,7 @@ import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.acl.dao.AclEntityPermissionDao;
import org.apache.cloudstack.acl.dao.AclGroupAccountMapDao;
import org.apache.cloudstack.acl.dao.AclGroupDao;
import org.apache.cloudstack.acl.dao.AclRolePermissionDao;
import org.apache.cloudstack.api.InternalIdentity;
import org.apache.log4j.Logger;
@ -55,11 +58,14 @@ public class RoleBasedEntityAccessChecker extends DomainChecker implements Secur
@Inject
AclEntityPermissionDao _entityPermissionDao;
@Inject
AclRolePermissionDao _rolePermissionDao;
@Override
public boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessType)
throws PermissionDeniedException {
String entityType = "";
String entityType = AclEntityType.VM.toString();
// check if explicit allow/deny is present for this entity in
// acl_entity_permission
@ -96,14 +102,35 @@ public class RoleBasedEntityAccessChecker extends DomainChecker implements Secur
if (caller.getId() == entity.getAccountId()) {
return true;
}
// Get the Roles of the Caller
List<AclRole> roles = _aclService.getAclRoles(caller.getId());
// Do you have DomainAdmin Role? If yes can access the entity in the
// domaintree
// get all Roles of this caller w.r.t the entity
List<AclRole> roles = _aclService.getEffectiveRoles(caller, entity);
// check the entity grant table
for (AclRole role : roles) {
AclRolePermissionVO permission = _rolePermissionDao.findByRoleAndEntity(role.getId(), entityType,
accessType);
boolean operationAllowedForAll = true;
if (permission.getEntityType().equals(entityType)) {
if (permission.isAllowed()) {
return true;
} else {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Account " + caller + " does not have permission to access resource " + entity
+ " for access type: " + accessType);
}
throw new PermissionDeniedException(caller + " does not have permission to access resource "
+ entity);
}
} else if (permission.getEntityType().equals("*")) {
if (permission.isAllowed()) {
operationAllowedForAll = true;
} else {
operationAllowedForAll = false;
}
}
}
return false;

View File

@ -38,6 +38,7 @@ import org.apache.cloudstack.acl.dao.AclRolePermissionDao;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.context.CallContext;
import com.cloud.domain.Domain;
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
@ -534,6 +535,7 @@ public class AclServiceImpl extends ManagerBase implements AclService, Manager {
@Override
public List<AclRole> getAclRoles(long accountId) {
// static roles of the account
SearchBuilder<AclGroupAccountMapVO> groupSB = _aclGroupAccountMapDao.createSearchBuilder();
groupSB.and("account", groupSB.entity().getAccountId(), Op.EQ);
@ -643,4 +645,20 @@ public class AclServiceImpl extends ManagerBase implements AclService, Manager {
return accessible;
}
@Override
public List<AclRole> getEffectiveRoles(Account caller, ControlledEntity entity) {
// Get the static Roles of the Caller
List<AclRole> roles = getAclRoles(caller.getId());
// add any dynamic roles w.r.t the entity
if (caller.getId() == entity.getAccountId()) {
// The caller owns the entity
AclRole owner = _aclRoleDao.findByName(Domain.ROOT_DOMAIN, "RESOURCE_OWNER");
roles.add(owner);
}
return roles;
}
}

View File

@ -312,9 +312,10 @@ CREATE TABLE `cloud`.`acl_role` (
`name` varchar(255) NOT NULL,
`description` varchar(255) default NULL,
`uuid` varchar(40),
`domain_id` bigint unsigned NOT NULL,
`domain_id` bigint unsigned NOT NULL,
`removed` datetime COMMENT 'date the role was removed',
`created` datetime COMMENT 'date the role was created',
`role_type` varchar(64) DEFAULT 'Static' COMMENT 'Static or Dynamic',
PRIMARY KEY (`id`),
INDEX `i_acl_role__removed`(`removed`),
CONSTRAINT `uc_acl_role__uuid` UNIQUE (`uuid`)
@ -332,12 +333,12 @@ CREATE TABLE `cloud`.`acl_group_role_map` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT IGNORE INTO `cloud`.`acl_role` (id, name, description, uuid, domain_id, created) VALUES (1, 'NORMAL', 'Domain user role', UUID(), 1, Now());
INSERT IGNORE INTO `cloud`.`acl_role` (id, name, description, uuid, domain_id, created) VALUES (2, 'ADMIN', 'Root admin role', UUID(), 1, Now());
INSERT IGNORE INTO `cloud`.`acl_role` (id, name, description, uuid, domain_id, created) VALUES (3, 'DOMAIN_ADMIN', 'Domain admin role', UUID(), 1, Now());
INSERT IGNORE INTO `cloud`.`acl_role` (id, name, description, uuid, domain_id, created) VALUES (4, 'RESOURCE_DOMAIN_ADMIN', 'Resource domain admin role', UUID(), 1, Now());
INSERT IGNORE INTO `cloud`.`acl_role` (id, name, description, uuid, domain_id, created) VALUES (5, 'READ_ONLY_ADMIN', 'Read only admin role', UUID(), 1, Now());
INSERT IGNORE INTO `cloud`.`acl_role` (id, name, description, uuid, domain_id, created) VALUES (6, 'RESOURCE_OWNER', 'Resource owner role', UUID(), -1, Now());
INSERT IGNORE INTO `cloud`.`acl_role` (id, name, description, uuid, domain_id, created) VALUES (1, 'NORMAL', 'Domain user role', UUID(), 1, Now(), 'Static');
INSERT IGNORE INTO `cloud`.`acl_role` (id, name, description, uuid, domain_id, created) VALUES (2, 'ADMIN', 'Root admin role', UUID(), 1, Now(), 'Static');
INSERT IGNORE INTO `cloud`.`acl_role` (id, name, description, uuid, domain_id, created) VALUES (3, 'DOMAIN_ADMIN', 'Domain admin role', UUID(), 1, Now(), 'Static');
INSERT IGNORE INTO `cloud`.`acl_role` (id, name, description, uuid, domain_id, created) VALUES (4, 'RESOURCE_DOMAIN_ADMIN', 'Resource domain admin role', UUID(), 1, Now(), 'Static');
INSERT IGNORE INTO `cloud`.`acl_role` (id, name, description, uuid, domain_id, created) VALUES (5, 'READ_ONLY_ADMIN', 'Read only admin role', UUID(), 1, Now(), 'Static');
INSERT IGNORE INTO `cloud`.`acl_role` (id, name, description, uuid, domain_id, created) VALUES (6, 'RESOURCE_OWNER', 'Resource owner role', UUID(), 1, Now(), 'Dynamic');
INSERT IGNORE INTO `cloud`.`acl_group` (id, name, description, uuid, domain_id, created) VALUES (1, 'NORMAL', 'Domain user group', UUID(), 1, Now());
INSERT IGNORE INTO `cloud`.`acl_group` (id, name, description, uuid, domain_id, created) VALUES (2, 'ADMIN', 'Root admin group', UUID(), 1, Now());