From 939b15169c512c2149d412204930c89976db2ba5 Mon Sep 17 00:00:00 2001 From: Prachi Damle Date: Mon, 3 Feb 2014 17:34:03 -0800 Subject: [PATCH] changes to support the domain wide resources for Network --- .../orchestration/NetworkOrchestrator.java | 4 ++ server/src/com/cloud/user/DomainManager.java | 1 + .../acl/RoleBasedEntityAccessChecker.java | 10 +++ .../cloudstack/acl/api/AclApiServiceImpl.java | 15 +++++ .../apache/cloudstack/iam/api/IAMService.java | 4 ++ .../cloudstack/iam/server/IAMServiceImpl.java | 65 +++++++++++++++++++ 6 files changed, 99 insertions(+) diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index 8857c001c8d..de22e9ddb5e 100755 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -2196,6 +2196,10 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra NetworkAccountVO networkAccount = _networkAccountDao.getAccountNetworkMapByNetworkId(networkFinal.getId()); if (networkAccount != null) _networkAccountDao.remove(networkAccount.getId()); + + // remove its related ACL permission + Pair networkMsg = new Pair(AclEntityType.Network, networkFinal.getId()); + _messageBus.publish(_name, EntityManager.MESSAGE_REMOVE_ENTITY_EVENT, PublishScope.LOCAL, networkMsg); } NetworkOffering ntwkOff = _entityMgr.findById(NetworkOffering.class, networkFinal.getNetworkOfferingId()); diff --git a/server/src/com/cloud/user/DomainManager.java b/server/src/com/cloud/user/DomainManager.java index 27c837d7961..592ab81a2a4 100644 --- a/server/src/com/cloud/user/DomainManager.java +++ b/server/src/com/cloud/user/DomainManager.java @@ -49,5 +49,6 @@ public interface DomainManager extends DomainService { Domain updateDomain(UpdateDomainCmd cmd); public static final String MESSAGE_ADD_DOMAIN_EVENT = "Message.AddDomain.Event"; + public static final String MESSAGE_REMOVE_DOMAIN_EVENT = "Message.RemoveDomain.Event"; } diff --git a/services/iam/plugin/src/org/apache/cloudstack/acl/RoleBasedEntityAccessChecker.java b/services/iam/plugin/src/org/apache/cloudstack/acl/RoleBasedEntityAccessChecker.java index acbf8d3eb27..1b915d5afe3 100644 --- a/services/iam/plugin/src/org/apache/cloudstack/acl/RoleBasedEntityAccessChecker.java +++ b/services/iam/plugin/src/org/apache/cloudstack/acl/RoleBasedEntityAccessChecker.java @@ -25,6 +25,7 @@ import javax.inject.Inject; import org.apache.log4j.Logger; import org.apache.cloudstack.api.InternalIdentity; +import org.apache.cloudstack.iam.api.AclGroup; import org.apache.cloudstack.iam.api.AclPolicy; import org.apache.cloudstack.iam.api.AclPolicyPermission; import org.apache.cloudstack.iam.api.IAMService; @@ -168,6 +169,15 @@ public class RoleBasedEntityAccessChecker extends DomainChecker implements Secur policies.add(_iamSrv.getResourceOwnerPolicy()); } + List groups = _iamSrv.listAclGroups(caller.getId()); + for (AclGroup group : groups) { + // for each group find the grand parent groups. + List parentGroups = _iamSrv.listParentAclGroupsOnPath(group.getPath()); + for (AclGroup parentGroup : parentGroups) { + policies.addAll(_iamSrv.listRecursiveAclPoliciesByGroup(parentGroup.getId())); + } + } + return policies; } } diff --git a/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java b/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java index 892a7bbb8e4..9b8e57f7456 100644 --- a/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java +++ b/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiServiceImpl.java @@ -159,6 +159,21 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man } }); + _messageBus.subscribe(DomainManager.MESSAGE_REMOVE_DOMAIN_EVENT, new MessageSubscriber() { + @Override + public void onPublishMessage(String senderAddress, String subject, Object obj) { + Long domainId = ((Long) obj); + if (domainId != null) { + s_logger.debug("MessageBus message: Domain removed: " + domainId + ", removing the domain group"); + Domain domain = _domainDao.findById(domainId); + List groups = listDomainGroup(domain); + for (AclGroup group : groups) { + _iamSrv.deleteAclGroup(group.getId()); + } + } + } + }); + _messageBus.subscribe(TemplateManager.MESSAGE_REGISTER_PUBLIC_TEMPLATE_EVENT, new MessageSubscriber() { @Override public void onPublishMessage(String senderAddress, String subject, Object obj) { diff --git a/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java b/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java index 694abd5282d..2679aaae48f 100644 --- a/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java +++ b/services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java @@ -85,4 +85,8 @@ public interface IAMService { List listPolicyPermissionByAccessAndEntity(long policyId, String accessType, String entityType); + List listParentAclGroupsOnPath(String path); + + List listRecursiveAclPoliciesByGroup(long groupId); + } diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java b/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java index 1dbfaef6764..d6cf8cdb377 100644 --- a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java +++ b/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java @@ -45,6 +45,7 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.EntityManager; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericSearchBuilder; +import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.JoinBuilder.JoinType; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -255,6 +256,33 @@ public class IAMServiceImpl extends ManagerBase implements IAMService, Manager { return new Pair, Integer>(new ArrayList(groups.first()), groups.second()); } + @Override + public List listParentAclGroupsOnPath(String path) { + + List pathList = new ArrayList(); + + String[] parts = path.split("/"); + + for (String part : parts) { + int start = path.indexOf(part); + if (start > 0) { + String subPath = path.substring(0, start); + pathList.add(subPath); + } + } + + SearchBuilder sb = _aclGroupDao.createSearchBuilder(); + sb.and("paths", sb.entity().getPath(), SearchCriteria.Op.IN); + + SearchCriteria sc = sb.create(); + sc.setParameters("paths", pathList.toArray()); + + List groups = _aclGroupDao.search(sc, null); + + return new ArrayList(groups); + + } + @DB @Override public AclPolicy createAclPolicy(final String aclPolicyName, final String description, final Long parentPolicyId) { @@ -388,6 +416,37 @@ public class IAMServiceImpl extends ManagerBase implements IAMService, Manager { return policies; } + @SuppressWarnings("unchecked") + @Override + public List listRecursiveAclPoliciesByGroup(long groupId) { + List policyGrpMap = _aclGroupPolicyMapDao.listByGroupId(groupId); + if (policyGrpMap == null || policyGrpMap.size() == 0) { + return new ArrayList(); + } + + List policyIds = new ArrayList(); + for (AclGroupPolicyMapVO pg : policyGrpMap) { + policyIds.add(pg.getAclPolicyId()); + } + + SearchBuilder permSb = _policyPermissionDao.createSearchBuilder(); + permSb.and("isRecursive", permSb.entity().isRecursive(), Op.EQ); + + SearchBuilder sb = _aclPolicyDao.createSearchBuilder(); + sb.and("ids", sb.entity().getId(), Op.IN); + sb.join("recursivePerm", permSb, sb.entity().getId(), permSb.entity().getAclPolicyId(), + JoinBuilder.JoinType.INNER); + + SearchCriteria sc = sb.create(); + sc.setParameters("ids", policyIds.toArray(new Object[policyIds.size()])); + sc.setJoinParameters("recursivePerm", "isRecursive", true); + + @SuppressWarnings("rawtypes") + List policies = _aclPolicyDao.customSearch(sc, null); + + return policies; + } + @SuppressWarnings("unchecked") @Override @@ -591,7 +650,13 @@ public class IAMServiceImpl extends ManagerBase implements IAMService, Manager { // remove entry from acl_entity_permission table List permitList = _policyPermissionDao.listByEntity(entityType, entityId); for (AclPolicyPermissionVO permit : permitList) { + long policyId = permit.getAclPolicyId(); _policyPermissionDao.remove(permit.getId()); + + // remove the policy of there are no other permissions + if ((_policyPermissionDao.listByPolicy(policyId)).isEmpty()) { + deleteAclPolicy(policyId); + } } } });