diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index fa4d342eb59..ef433f72f9c 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -459,6 +459,7 @@ public class EventTypes { public static final String EVENT_ACL_GROUP_DELETE = "ACLGROUP.DELETE"; public static final String EVENT_ACL_GROUP_GRANT = "ACLGROUP.GRANT"; public static final String EVENT_ACL_GROUP_REVOKE = "ACLGROUP.REVOKE"; + public static final String EVENT_ACL_ACCOUNT_POLICY_UPDATE = "ACLACCOUNTPOLICY.UPDATE"; // Object store migration public static final String EVENT_MIGRATE_PREPARE_SECONDARY_STORAGE = "MIGRATE.PREPARE.SS"; diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index e68b53a8eb9..29dfdadfd00 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -718,6 +718,8 @@ addAccountToAclGroup=1 removeAccountFromAclGroup=1 attachAclPolicyToAclGroup=1 removeAclPolicyFromAclGroup=1 +attachAclPolicyToAccount=1 +removeAclPolicyFromAccount=1 #### juniper-contrail commands createServiceInstance=1 diff --git a/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiService.java b/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiService.java index 98abd133a67..eb08de5b6f9 100644 --- a/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiService.java +++ b/services/iam/plugin/src/org/apache/cloudstack/acl/api/AclApiService.java @@ -50,9 +50,13 @@ public interface AclApiService extends PluggableService { List listAclPolicies(long accountId); - AclGroup attachAclPoliciesToGroup(List roleIds, Long groupId); + AclGroup attachAclPoliciesToGroup(List policyIds, Long groupId); - AclGroup removeAclPoliciesFromGroup(List roleIds, Long groupId); + AclGroup removeAclPoliciesFromGroup(List policyIds, Long groupId); + + void attachAclPolicyToAccounts(Long policyId, List accountIds); + + void removeAclPolicyFromAccounts(Long policyId, List accountIds); AclPolicy addAclPermissionToAclPolicy(long aclPolicyId, String entityType, PermissionScope scope, Long scopeId, String action, Permission perm); 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 12e37482309..d50f4f2aa11 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 @@ -32,6 +32,7 @@ import org.apache.cloudstack.acl.PermissionScope; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.acl.api.command.AddAccountToAclGroupCmd; import org.apache.cloudstack.acl.api.command.AddAclPermissionToAclPolicyCmd; +import org.apache.cloudstack.acl.api.command.AttachAclPolicyToAccountCmd; import org.apache.cloudstack.acl.api.command.AttachAclPolicyToAclGroupCmd; import org.apache.cloudstack.acl.api.command.CreateAclGroupCmd; import org.apache.cloudstack.acl.api.command.CreateAclPolicyCmd; @@ -41,6 +42,7 @@ import org.apache.cloudstack.acl.api.command.ListAclGroupsCmd; import org.apache.cloudstack.acl.api.command.ListAclPoliciesCmd; import org.apache.cloudstack.acl.api.command.RemoveAccountFromAclGroupCmd; import org.apache.cloudstack.acl.api.command.RemoveAclPermissionFromAclPolicyCmd; +import org.apache.cloudstack.acl.api.command.RemoveAclPolicyFromAccountCmd; import org.apache.cloudstack.acl.api.command.RemoveAclPolicyFromAclGroupCmd; import org.apache.cloudstack.acl.api.response.AclGroupResponse; import org.apache.cloudstack.acl.api.response.AclPermissionResponse; @@ -243,6 +245,20 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man } + @DB + @Override + @ActionEvent(eventType = EventTypes.EVENT_ACL_ACCOUNT_POLICY_UPDATE, eventDescription = "Attaching policy to accounts") + public void attachAclPolicyToAccounts(final Long policyId, final List accountIds) { + _iamSrv.attachAclPolicyToAccounts(policyId, accountIds); + } + + @DB + @Override + @ActionEvent(eventType = EventTypes.EVENT_ACL_ACCOUNT_POLICY_UPDATE, eventDescription = "Removing policy from accounts") + public void removeAclPolicyFromAccounts(final Long policyId, final List accountIds) { + _iamSrv.removeAclPolicyFromAccounts(policyId, accountIds); + } + @DB @Override @ActionEvent(eventType = EventTypes.EVENT_ACL_POLICY_GRANT, eventDescription = "Granting acl permission to Acl Policy") @@ -439,6 +455,8 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man cmdList.add(ListAclGroupsCmd.class); cmdList.add(AddAccountToAclGroupCmd.class); cmdList.add(RemoveAccountFromAclGroupCmd.class); + cmdList.add(AttachAclPolicyToAccountCmd.class); + cmdList.add(RemoveAclPolicyFromAccountCmd.class); return cmdList; } } diff --git a/services/iam/plugin/src/org/apache/cloudstack/acl/api/command/AttachAclPolicyToAccountCmd.java b/services/iam/plugin/src/org/apache/cloudstack/acl/api/command/AttachAclPolicyToAccountCmd.java new file mode 100644 index 00000000000..b88df2b3ea7 --- /dev/null +++ b/services/iam/plugin/src/org/apache/cloudstack/acl/api/command/AttachAclPolicyToAccountCmd.java @@ -0,0 +1,122 @@ +// 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.acl.api.command; + +import java.util.List; + +import javax.inject.Inject; + +import org.apache.log4j.Logger; + +import org.apache.cloudstack.acl.api.AclApiService; +import org.apache.cloudstack.acl.api.response.AclPolicyResponse; +import org.apache.cloudstack.api.ACL; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiCommandJobType; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.AccountResponse; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.context.CallContext; + +import com.cloud.event.EventTypes; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.user.Account; + + +@APICommand(name = "attachAclPolicyToAccount", description = "attach acl policy to accounts", responseObject = SuccessResponse.class) +public class AttachAclPolicyToAccountCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(AttachAclPolicyToAccountCmd.class.getName()); + private static final String s_name = "attachaclpolicytoaccountresponse"; + + @Inject + public AclApiService _aclApiSrv; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + + @ACL + @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = AclPolicyResponse.class, + required = true, description = "The ID of the acl policy") + private Long id; + + @ACL + @Parameter(name = ApiConstants.ACCOUNTS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = AccountResponse.class, description = "comma separated list of account id that the policy will attach to.") + private List accountIdList; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + + public Long getId() { + return id; + } + + + public List getAccountIdList() { + return accountIdList; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + + @Override + public String getCommandName() { + return s_name; + } + + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + + @Override + public void execute() throws ResourceUnavailableException, + InsufficientCapacityException, ServerApiException { + CallContext.current().setEventDetails("Acl policy Id: " + getId()); + _aclApiSrv.attachAclPolicyToAccounts(id, accountIdList); + SuccessResponse response = new SuccessResponse(); + response.setResponseName(getCommandName()); + setResponseObject(response); + } + + @Override + public String getEventType() { + return EventTypes.EVENT_ACL_ACCOUNT_POLICY_UPDATE; + } + + @Override + public String getEventDescription() { + return "adding acl policy to accounts"; + } + + @Override + public ApiCommandJobType getInstanceType() { + return ApiCommandJobType.Account; + } + +} diff --git a/services/iam/plugin/src/org/apache/cloudstack/acl/api/command/RemoveAclPolicyFromAccountCmd.java b/services/iam/plugin/src/org/apache/cloudstack/acl/api/command/RemoveAclPolicyFromAccountCmd.java new file mode 100644 index 00000000000..74b3092e74b --- /dev/null +++ b/services/iam/plugin/src/org/apache/cloudstack/acl/api/command/RemoveAclPolicyFromAccountCmd.java @@ -0,0 +1,122 @@ +// 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.acl.api.command; + +import java.util.List; + +import javax.inject.Inject; + +import org.apache.log4j.Logger; + +import org.apache.cloudstack.acl.api.AclApiService; +import org.apache.cloudstack.acl.api.response.AclGroupResponse; +import org.apache.cloudstack.acl.api.response.AclPolicyResponse; +import org.apache.cloudstack.api.ACL; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiCommandJobType; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.context.CallContext; + +import com.cloud.event.EventTypes; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.user.Account; + + +@APICommand(name = "removeAclPolicyFromAccount", description = "remove acl policy from accounts", responseObject = SuccessResponse.class) +public class RemoveAclPolicyFromAccountCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(RemoveAclPolicyFromAccountCmd.class.getName()); + private static final String s_name = "removeaclpolicyfromaccountresponse"; + + @Inject + public AclApiService _aclApiSrv; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + + @ACL + @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = AclGroupResponse.class, + required = true, description = "The ID of the acl group") + private Long id; + + @ACL + @Parameter(name = ApiConstants.ACCOUNTS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = AclPolicyResponse.class, description = "comma separated list of acl policy id that are going to be applied to the acl group.") + private List accountIdList; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + + public Long getId() { + return id; + } + + + public List getAccountIdList() { + return accountIdList; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + + @Override + public String getCommandName() { + return s_name; + } + + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + + @Override + public void execute() throws ResourceUnavailableException, + InsufficientCapacityException, ServerApiException { + CallContext.current().setEventDetails("Acl policy Id: " + getId()); + _aclApiSrv.removeAclPolicyFromAccounts(id, accountIdList); + SuccessResponse response = new SuccessResponse(); + response.setResponseName(getCommandName()); + setResponseObject(response); + } + + @Override + public String getEventType() { + return EventTypes.EVENT_ACL_ACCOUNT_POLICY_UPDATE; + } + + @Override + public String getEventDescription() { + return "removing acl policy from accounts"; + } + + @Override + public ApiCommandJobType getInstanceType() { + return ApiCommandJobType.Account; + } + +} diff --git a/services/iam/server/resources/META-INF/cloudstack/core/spring-iam-server-context.xml b/services/iam/server/resources/META-INF/cloudstack/core/spring-iam-server-context.xml index 16dfd4aa352..82faa70b6cf 100644 --- a/services/iam/server/resources/META-INF/cloudstack/core/spring-iam-server-context.xml +++ b/services/iam/server/resources/META-INF/cloudstack/core/spring-iam-server-context.xml @@ -32,6 +32,8 @@ + + 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 90dbb57d48d..aad982b50e8 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 @@ -54,6 +54,10 @@ public interface IAMService { AclGroup removeAclPoliciesFromGroup(List policyIds, Long groupId); + void attachAclPolicyToAccounts(Long policyId, List acctIds); + + void removeAclPolicyFromAccounts(Long policyId, List acctIds); + AclPolicy addAclPermissionToAclPolicy(long aclPolicyId, String entityType, String scope, Long scopeId, String action, String accessType, Permission perm); diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/AclAccountPolicyMapVO.java b/services/iam/server/src/org/apache/cloudstack/iam/server/AclAccountPolicyMapVO.java new file mode 100644 index 00000000000..b491e6e2628 --- /dev/null +++ b/services/iam/server/src/org/apache/cloudstack/iam/server/AclAccountPolicyMapVO.java @@ -0,0 +1,77 @@ +// 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.iam.server; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.cloud.utils.db.GenericDao; + +@Entity +@Table(name = ("acl_account_policy_map")) +public class AclAccountPolicyMapVO { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "account_id") + private long accountId; + + @Column(name = "policy_id") + private long aclPolicyId; + + @Column(name = GenericDao.REMOVED_COLUMN) + private Date removed; + + @Column(name = GenericDao.CREATED_COLUMN) + private Date created; + + public AclAccountPolicyMapVO() { + } + + public AclAccountPolicyMapVO(long accountId, long aclPolicyId) { + this.accountId = accountId; + this.aclPolicyId = aclPolicyId; + } + + public long getId() { + return id; + } + + public long getAccountId() { + return accountId; + } + + public long getAclPolicyId() { + return aclPolicyId; + } + + public Date getRemoved() { + return removed; + } + + public Date getCreated() { + return created; + } +} 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 d84dad4788d..0745e621e6c 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 @@ -29,6 +29,7 @@ import org.apache.cloudstack.iam.api.AclPolicy; import org.apache.cloudstack.iam.api.AclPolicyPermission; import org.apache.cloudstack.iam.api.AclPolicyPermission.Permission; import org.apache.cloudstack.iam.api.IAMService; +import org.apache.cloudstack.iam.server.dao.AclAccountPolicyMapDao; import org.apache.cloudstack.iam.server.dao.AclGroupAccountMapDao; import org.apache.cloudstack.iam.server.dao.AclGroupDao; import org.apache.cloudstack.iam.server.dao.AclGroupPolicyMapDao; @@ -70,6 +71,9 @@ public class IAMServiceImpl extends ManagerBase implements IAMService, Manager { @Inject AclGroupPolicyMapDao _aclGroupPolicyMapDao; + @Inject + AclAccountPolicyMapDao _aclAccountPolicyMapDao; + @Inject AclGroupAccountMapDao _aclGroupAccountMapDao; @@ -341,7 +345,12 @@ public class IAMServiceImpl extends ManagerBase implements IAMService, Manager { policySc.setJoinParameters("accountgroupjoin", "account", accountId); List policyIds = _aclGroupPolicyMapDao.customSearch(policySc, null); - if (policyIds == null || policyIds.size() == 0) { + // add policies directly attached to the account + List acctPolicies = _aclAccountPolicyMapDao.listByAccountId(accountId); + for (AclAccountPolicyMapVO p : acctPolicies) { + policyIds.add(p.getAclPolicyId()); + } + if (policyIds.size() == 0) { return new ArrayList(); } SearchBuilder sb = _aclPolicyDao.createSearchBuilder(); @@ -350,6 +359,7 @@ public class IAMServiceImpl extends ManagerBase implements IAMService, Manager { sc.setParameters("ids", policyIds.toArray(new Object[policyIds.size()])); @SuppressWarnings("rawtypes") List policies = _aclPolicyDao.customSearch(sc, null); + return policies; } @@ -479,70 +489,54 @@ public class IAMServiceImpl extends ManagerBase implements IAMService, Manager { return group; } - /* - @DB + @Override - @ActionEvent(eventType = EventTypes.EVENT_ACL_POLICY_GRANT, eventDescription = "Granting permission to Acl Role") - public AclP addAclPermissionToAclPolicy(final long aclRoleId, final List apiNames) { - Account caller = CallContext.current().getCallingAccount(); - // get the Acl Role entity - AclRole role = _aclPolicyDao.findById(aclRoleId); - if (role == null) { - throw new InvalidParameterValueException("Unable to find acl role: " + aclRoleId - + "; failed to grant permission to role."); + public void attachAclPolicyToAccounts(final Long policyId, final List acctIds) { + AclPolicy policy = _aclPolicyDao.findById(policyId); + if (policy == null) { + throw new InvalidParameterValueException("Unable to find acl policy: " + policyId + + "; failed to add policy to account."); } - // check permissions - _accountMgr.checkAccess(caller, null, true, role); Transaction.execute(new TransactionCallbackNoReturn() { @Override public void doInTransactionWithoutResult(TransactionStatus status) { - // add entries in acl_api_permission table - for (String api : apiNames) { - AclApiPermissionVO perm = _apiPermissionDao.findByRoleAndApi(aclRoleId, api); - if (perm == null) { + // add entries in acl_group_policy_map table + for (Long acctId : acctIds) { + AclAccountPolicyMapVO acctMap = _aclAccountPolicyMapDao.findByAccountAndPolicy(acctId, policyId); + if (acctMap == null) { // not there already - perm = new AclApiPermissionVO(aclRoleId, api); - _apiPermissionDao.persist(perm); + acctMap = new AclAccountPolicyMapVO(acctId, policyId); + _aclAccountPolicyMapDao.persist(acctMap); } } } }); - - return role; - } - @DB @Override - @ActionEvent(eventType = EventTypes.EVENT_ACL_POLICY_REVOKE, eventDescription = "Revoking permission from Acl Role") - public AclRole revokeApiPermissionFromAclRole(final long aclRoleId, final List apiNames) { - Account caller = CallContext.current().getCallingAccount(); - // get the Acl Role entity - AclRole role = _aclPolicyDao.findById(aclRoleId); - if (role == null) { - throw new InvalidParameterValueException("Unable to find acl role: " + aclRoleId - + "; failed to revoke permission from role."); + public void removeAclPolicyFromAccounts(final Long policyId, final List acctIds) { + AclPolicy policy = _aclPolicyDao.findById(policyId); + if (policy == null) { + throw new InvalidParameterValueException("Unable to find acl policy: " + policyId + + "; failed to add policy to account."); } - // check permissions - _accountMgr.checkAccess(caller, null, true, role); Transaction.execute(new TransactionCallbackNoReturn() { @Override public void doInTransactionWithoutResult(TransactionStatus status) { - // remove entries from acl_api_permission table - for (String api : apiNames) { - AclApiPermissionVO perm = _apiPermissionDao.findByRoleAndApi(aclRoleId, api); - if (perm != null) { - // not removed yet - _apiPermissionDao.remove(perm.getId()); + // add entries in acl_group_policy_map table + for (Long acctId : acctIds) { + AclAccountPolicyMapVO acctMap = _aclAccountPolicyMapDao.findByAccountAndPolicy(acctId, policyId); + if (acctMap == null) { + // not there already + acctMap = new AclAccountPolicyMapVO(acctId, policyId); + _aclAccountPolicyMapDao.remove(acctMap.getId()); } } } }); - return role; } - */ @DB @Override diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/AclAccountPolicyMapDao.java b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/AclAccountPolicyMapDao.java new file mode 100644 index 00000000000..83b814777b3 --- /dev/null +++ b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/AclAccountPolicyMapDao.java @@ -0,0 +1,17 @@ +package org.apache.cloudstack.iam.server.dao; + +import java.util.List; + +import org.apache.cloudstack.iam.server.AclAccountPolicyMapVO; + +import com.cloud.utils.db.GenericDao; + +public interface AclAccountPolicyMapDao extends GenericDao { + + List listByAccountId(long acctId); + + List listByPolicyId(long policyId); + + AclAccountPolicyMapVO findByAccountAndPolicy(long acctId, long policyId); + +} diff --git a/services/iam/server/src/org/apache/cloudstack/iam/server/dao/AclAccountPolicyMapDaoImpl.java b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/AclAccountPolicyMapDaoImpl.java new file mode 100644 index 00000000000..51091a6f880 --- /dev/null +++ b/services/iam/server/src/org/apache/cloudstack/iam/server/dao/AclAccountPolicyMapDaoImpl.java @@ -0,0 +1,61 @@ +package org.apache.cloudstack.iam.server.dao; + +import java.util.List; +import java.util.Map; + +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.iam.server.AclAccountPolicyMapVO; + +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + +public class AclAccountPolicyMapDaoImpl extends GenericDaoBase implements AclAccountPolicyMapDao { + + private SearchBuilder ListByAccountId; + private SearchBuilder ListByPolicyId; + private SearchBuilder findByPolicyAccountId; + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + super.configure(name, params); + + ListByAccountId = createSearchBuilder(); + ListByAccountId.and("accountId", ListByAccountId.entity().getAccountId(), SearchCriteria.Op.EQ); + ListByAccountId.done(); + + ListByPolicyId = createSearchBuilder(); + ListByPolicyId.and("policyId", ListByPolicyId.entity().getAclPolicyId(), SearchCriteria.Op.EQ); + ListByPolicyId.done(); + + findByPolicyAccountId = createSearchBuilder(); + findByPolicyAccountId.and("policyId", findByPolicyAccountId.entity().getAclPolicyId(), SearchCriteria.Op.EQ); + findByPolicyAccountId.and("accountId", findByPolicyAccountId.entity().getAccountId(), SearchCriteria.Op.EQ); + findByPolicyAccountId.done(); + + return true; + } + + @Override + public List listByAccountId(long acctId) { + SearchCriteria sc = ListByAccountId.create(); + sc.setParameters("accountId", acctId); + return listBy(sc); + } + + @Override + public List listByPolicyId(long policyId) { + SearchCriteria sc = ListByPolicyId.create(); + sc.setParameters("policyId", policyId); + return listBy(sc); + } + + @Override + public AclAccountPolicyMapVO findByAccountAndPolicy(long acctId, long policyId) { + SearchCriteria sc = findByPolicyAccountId.create(); + sc.setParameters("policyId", policyId); + sc.setParameters("accountId", acctId); + return findOneBy(sc); + } +} \ No newline at end of file diff --git a/services/iam/server/test/org/apache/cloudstack/iam/IAMServiceUnitTest.java b/services/iam/server/test/org/apache/cloudstack/iam/IAMServiceUnitTest.java index 5b1e57bd83b..03973e24542 100644 --- a/services/iam/server/test/org/apache/cloudstack/iam/IAMServiceUnitTest.java +++ b/services/iam/server/test/org/apache/cloudstack/iam/IAMServiceUnitTest.java @@ -51,6 +51,7 @@ import org.apache.cloudstack.iam.api.IAMService; import org.apache.cloudstack.iam.server.AclGroupVO; import org.apache.cloudstack.iam.server.AclPolicyVO; import org.apache.cloudstack.iam.server.IAMServiceImpl; +import org.apache.cloudstack.iam.server.dao.AclAccountPolicyMapDao; import org.apache.cloudstack.iam.server.dao.AclGroupAccountMapDao; import org.apache.cloudstack.iam.server.dao.AclGroupDao; import org.apache.cloudstack.iam.server.dao.AclGroupPolicyMapDao; @@ -188,6 +189,11 @@ public class IAMServiceUnitTest { return Mockito.mock(AclGroupAccountMapDao.class); } + @Bean + public AclAccountPolicyMapDao aclAccountPolicyMapDao() { + return Mockito.mock(AclAccountPolicyMapDao.class); + } + @Bean public AclPolicyPermissionDao aclPolicyPermissionDao() { return Mockito.mock(AclPolicyPermissionDao.class); diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql index 5cd54af2249..92957b2ebf5 100644 --- a/setup/db/db/schema-430to440.sql +++ b/setup/db/db/schema-430to440.sql @@ -471,7 +471,7 @@ CREATE TABLE `cloud`.`acl_group_account_map` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -CREATE TABLE `acl_policy` ( +CREATE TABLE `cloud`.`acl_policy` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `description` varchar(255) DEFAULT NULL, @@ -487,7 +487,7 @@ CREATE TABLE `acl_policy` ( KEY `i_acl_policy__removed` (`removed`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; -CREATE TABLE `acl_group_policy_map` ( +CREATE TABLE `cloud`.`acl_group_policy_map` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `group_id` bigint(20) unsigned NOT NULL, `policy_id` bigint(20) unsigned NOT NULL, @@ -500,7 +500,20 @@ CREATE TABLE `acl_group_policy_map` ( CONSTRAINT `fk_acl_group_policy_map__policy_id` FOREIGN KEY (`policy_id`) REFERENCES `acl_policy` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -CREATE TABLE `acl_policy_permission` ( +CREATE TABLE `cloud`.`acl_account_policy_map` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `account_id` bigint(20) unsigned NOT NULL, + `policy_id` bigint(20) unsigned NOT NULL, + `removed` datetime DEFAULT NULL COMMENT 'date the policy was revoked from the account', + `created` datetime DEFAULT NULL COMMENT 'date the policy was attached to the account', + PRIMARY KEY (`id`), + KEY `fk_acl_account_policy_map__account_id` (`account_id`), + KEY `fk_acl_account_policy_map__policy_id` (`policy_id`), + CONSTRAINT `fk_acl_account_policy_map__account_id` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_acl_account_policy_map__policy_id` FOREIGN KEY (`policy_id`) REFERENCES `acl_policy` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`acl_policy_permission` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `policy_id` bigint(20) unsigned NOT NULL, `action` varchar(100) NOT NULL,