| // 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.ArrayList; |
| import java.util.List; |
| import java.util.Map; |
| |
| import javax.inject.Inject; |
| import javax.naming.ConfigurationException; |
| |
| import net.sf.ehcache.Cache; |
| import net.sf.ehcache.CacheManager; |
| import net.sf.ehcache.Element; |
| |
| import org.apache.log4j.Logger; |
| |
| import org.apache.cloudstack.acl.PermissionScope; |
| import org.apache.cloudstack.iam.api.IAMGroup; |
| import org.apache.cloudstack.iam.api.IAMPolicy; |
| import org.apache.cloudstack.iam.api.IAMPolicyPermission; |
| import org.apache.cloudstack.iam.api.IAMPolicyPermission.Permission; |
| import org.apache.cloudstack.iam.api.IAMService; |
| import org.apache.cloudstack.iam.server.dao.IAMAccountPolicyMapDao; |
| import org.apache.cloudstack.iam.server.dao.IAMGroupAccountMapDao; |
| import org.apache.cloudstack.iam.server.dao.IAMGroupDao; |
| import org.apache.cloudstack.iam.server.dao.IAMGroupPolicyMapDao; |
| import org.apache.cloudstack.iam.server.dao.IAMPolicyDao; |
| import org.apache.cloudstack.iam.server.dao.IAMPolicyPermissionDao; |
| |
| import com.cloud.exception.InvalidParameterValueException; |
| import com.cloud.utils.NumbersUtil; |
| import com.cloud.utils.Pair; |
| import com.cloud.utils.component.Manager; |
| import com.cloud.utils.component.ManagerBase; |
| 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; |
| import com.cloud.utils.db.SearchCriteria.Op; |
| import com.cloud.utils.db.Transaction; |
| import com.cloud.utils.db.TransactionCallback; |
| import com.cloud.utils.db.TransactionCallbackNoReturn; |
| import com.cloud.utils.db.TransactionStatus; |
| |
| public class IAMServiceImpl extends ManagerBase implements IAMService, Manager { |
| |
| public static final Logger s_logger = Logger.getLogger(IAMServiceImpl.class); |
| private String _name; |
| |
| @Inject |
| IAMPolicyDao _aclPolicyDao; |
| |
| @Inject |
| IAMGroupDao _aclGroupDao; |
| |
| @Inject |
| EntityManager _entityMgr; |
| |
| @Inject |
| IAMGroupPolicyMapDao _aclGroupPolicyMapDao; |
| |
| @Inject |
| IAMAccountPolicyMapDao _aclAccountPolicyMapDao; |
| |
| @Inject |
| IAMGroupAccountMapDao _aclGroupAccountMapDao; |
| |
| @Inject |
| IAMPolicyPermissionDao _policyPermissionDao; |
| |
| private Cache _iamCache; |
| |
| private void createIAMCache(final Map<String, ? extends Object> params) { |
| final String value = (String)params.get("cache.size"); |
| |
| if (value != null) { |
| final CacheManager cm = CacheManager.create(); |
| final int maxElements = NumbersUtil.parseInt(value, 0); |
| final int live = NumbersUtil.parseInt((String)params.get("cache.time.to.live"), 300); |
| final int idle = NumbersUtil.parseInt((String)params.get("cache.time.to.idle"), 300); |
| _iamCache = new Cache(getName(), maxElements, false, live == -1, live == -1 ? Integer.MAX_VALUE : live, idle); |
| cm.addCache(_iamCache); |
| s_logger.info("IAM Cache created: " + _iamCache.toString()); |
| } else { |
| _iamCache = null; |
| } |
| } |
| |
| @Override |
| public void addToIAMCache(Object accessKey, Object allowDeny) { |
| if (_iamCache != null) { |
| try { |
| s_logger.debug("Put IAM access check for " + accessKey + " in cache"); |
| _iamCache.put(new Element(accessKey, allowDeny)); |
| } catch (final Exception e) { |
| s_logger.debug("Can't put " + accessKey + " to IAM cache", e); |
| } |
| } |
| } |
| |
| @Override |
| public void invalidateIAMCache() { |
| //This may need to use event bus to publish to other MS, but event bus now is missing this functionality to handle PublishScope.GLOBAL |
| if (_iamCache != null) { |
| s_logger.debug("Invalidate IAM cache"); |
| _iamCache.removeAll(); |
| } |
| } |
| |
| @Override |
| public Object getFromIAMCache(Object accessKey) { |
| if (_iamCache != null) { |
| final Element element = _iamCache.get(accessKey); |
| return element == null ? null : element.getObjectValue(); |
| } |
| return null; |
| } |
| |
| @Override |
| public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException { |
| boolean result = super.configure(name, params); |
| // create IAM cache |
| createIAMCache(params); |
| return result; |
| } |
| |
| @DB |
| @Override |
| public IAMGroup createIAMGroup(String iamGroupName, String description, String path) { |
| // check if the group is already existing |
| IAMGroup grp = _aclGroupDao.findByName(path, iamGroupName); |
| if (grp != null) { |
| throw new InvalidParameterValueException( |
| "Unable to create acl group with name " + iamGroupName |
| + " already exists for path " + path); |
| } |
| IAMGroupVO rvo = new IAMGroupVO(iamGroupName, description); |
| rvo.setPath(path); |
| |
| return _aclGroupDao.persist(rvo); |
| } |
| |
| @DB |
| @Override |
| public boolean deleteIAMGroup(final Long iamGroupId) { |
| // get the Acl Group entity |
| final IAMGroup grp = _aclGroupDao.findById(iamGroupId); |
| if (grp == null) { |
| throw new InvalidParameterValueException("Unable to find acl group: " + iamGroupId |
| + "; failed to delete acl group."); |
| } |
| |
| Transaction.execute(new TransactionCallbackNoReturn() { |
| @Override |
| public void doInTransactionWithoutResult(TransactionStatus status) { |
| // remove this group related entry in acl_group_policy_map |
| List<IAMGroupPolicyMapVO> groupPolicyMap = _aclGroupPolicyMapDao.listByGroupId(grp.getId()); |
| if (groupPolicyMap != null) { |
| for (IAMGroupPolicyMapVO gr : groupPolicyMap) { |
| _aclGroupPolicyMapDao.remove(gr.getId()); |
| } |
| } |
| |
| // remove this group related entry in acl_group_account table |
| List<IAMGroupAccountMapVO> groupAcctMap = _aclGroupAccountMapDao.listByGroupId(grp.getId()); |
| if (groupAcctMap != null) { |
| for (IAMGroupAccountMapVO grpAcct : groupAcctMap) { |
| _aclGroupAccountMapDao.remove(grpAcct.getId()); |
| } |
| } |
| |
| // remove this group from acl_group table |
| _aclGroupDao.remove(iamGroupId); |
| } |
| }); |
| |
| invalidateIAMCache(); |
| return true; |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public List<IAMGroup> listIAMGroups(long accountId) { |
| |
| GenericSearchBuilder<IAMGroupAccountMapVO, Long> groupSB = _aclGroupAccountMapDao.createSearchBuilder(Long.class); |
| groupSB.selectFields(groupSB.entity().getAclGroupId()); |
| groupSB.and("account", groupSB.entity().getAccountId(), Op.EQ); |
| SearchCriteria<Long> groupSc = groupSB.create(); |
| groupSc.setParameters("account", accountId); |
| |
| List<Long> groupIds = _aclGroupAccountMapDao.customSearch(groupSc, null); |
| |
| if (groupIds == null || groupIds.isEmpty()) { |
| return new ArrayList<IAMGroup>(); |
| } |
| SearchBuilder<IAMGroupVO> sb = _aclGroupDao.createSearchBuilder(); |
| sb.and("ids", sb.entity().getId(), Op.IN); |
| SearchCriteria<IAMGroupVO> sc = sb.create(); |
| sc.setParameters("ids", groupIds.toArray(new Object[groupIds.size()])); |
| @SuppressWarnings("rawtypes") |
| List groups = _aclGroupDao.search(sc, null); |
| return groups; |
| } |
| |
| @DB |
| @Override |
| public IAMGroup addAccountsToGroup(final List<Long> acctIds, final Long groupId) { |
| // get the Acl Group entity |
| IAMGroup group = _aclGroupDao.findById(groupId); |
| if (group == null) { |
| throw new InvalidParameterValueException("Unable to find acl group: " + groupId |
| + "; failed to add accounts to acl group."); |
| } |
| |
| Transaction.execute(new TransactionCallbackNoReturn() { |
| @Override |
| public void doInTransactionWithoutResult(TransactionStatus status) { |
| // add entries in acl_group_account_map table |
| for (Long acctId : acctIds) { |
| // check account permissions |
| IAMGroupAccountMapVO grMap = _aclGroupAccountMapDao.findByGroupAndAccount(groupId, acctId); |
| if (grMap == null) { |
| // not there already |
| grMap = new IAMGroupAccountMapVO(groupId, acctId); |
| _aclGroupAccountMapDao.persist(grMap); |
| } |
| } |
| } |
| }); |
| |
| invalidateIAMCache(); |
| return group; |
| } |
| |
| @DB |
| @Override |
| public IAMGroup removeAccountsFromGroup(final List<Long> acctIds, final Long groupId) { |
| // get the Acl Group entity |
| IAMGroup group = _aclGroupDao.findById(groupId); |
| if (group == null) { |
| throw new InvalidParameterValueException("Unable to find acl group: " + groupId |
| + "; failed to remove accounts from acl group."); |
| } |
| |
| Transaction.execute(new TransactionCallbackNoReturn() { |
| @Override |
| public void doInTransactionWithoutResult(TransactionStatus status) { |
| // remove entries from acl_group_account_map table |
| for (Long acctId : acctIds) { |
| IAMGroupAccountMapVO grMap = _aclGroupAccountMapDao.findByGroupAndAccount(groupId, acctId); |
| if (grMap != null) { |
| // not removed yet |
| _aclGroupAccountMapDao.remove(grMap.getId()); |
| } |
| } |
| } |
| }); |
| |
| invalidateIAMCache(); |
| return group; |
| } |
| |
| @Override |
| public List<Long> listAccountsByGroup(long groupId) { |
| List<IAMGroupAccountMapVO> grpAcctMap = _aclGroupAccountMapDao.listByGroupId(groupId); |
| if (grpAcctMap == null || grpAcctMap.size() == 0) { |
| return new ArrayList<Long>(); |
| } |
| |
| List<Long> accts = new ArrayList<Long>(); |
| for (IAMGroupAccountMapVO grpAcct : grpAcctMap) { |
| accts.add(grpAcct.getAccountId()); |
| } |
| return accts; |
| } |
| |
| @Override |
| public Pair<List<IAMGroup>, Integer> listIAMGroups(Long iamGroupId, String iamGroupName, String path, Long startIndex, Long pageSize) { |
| if (iamGroupId != null) { |
| IAMGroup group = _aclGroupDao.findById(iamGroupId); |
| if (group == null) { |
| throw new InvalidParameterValueException("Unable to find acl group by id " + iamGroupId); |
| } |
| } |
| |
| Filter searchFilter = new Filter(IAMGroupVO.class, "id", true, startIndex, pageSize); |
| |
| SearchBuilder<IAMGroupVO> sb = _aclGroupDao.createSearchBuilder(); |
| sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); |
| sb.and("path", sb.entity().getPath(), SearchCriteria.Op.LIKE); |
| sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); |
| |
| SearchCriteria<IAMGroupVO> sc = sb.create(); |
| |
| if (iamGroupName != null) { |
| sc.setParameters("name", iamGroupName); |
| } |
| |
| if (iamGroupId != null) { |
| sc.setParameters("id", iamGroupId); |
| } |
| |
| sc.setParameters("path", path + "%"); |
| |
| Pair<List<IAMGroupVO>, Integer> groups = _aclGroupDao.searchAndCount(sc, searchFilter); |
| return new Pair<List<IAMGroup>, Integer>(new ArrayList<IAMGroup>(groups.first()), groups.second()); |
| } |
| |
| @Override |
| public List<IAMGroup> listParentIAMGroups(long groupId) { |
| IAMGroup group = _aclGroupDao.findById(groupId); |
| if (group == null) { |
| throw new InvalidParameterValueException("Unable to find acl group by id " + groupId); |
| } |
| |
| String path = group.getPath(); |
| List<String> pathList = new ArrayList<String>(); |
| |
| 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); |
| } |
| } |
| |
| if (pathList.isEmpty()) { |
| return new ArrayList<IAMGroup>(); |
| } |
| |
| SearchBuilder<IAMGroupVO> sb = _aclGroupDao.createSearchBuilder(); |
| sb.and("paths", sb.entity().getPath(), SearchCriteria.Op.IN); |
| |
| SearchCriteria<IAMGroupVO> sc = sb.create(); |
| sc.setParameters("paths", pathList.toArray()); |
| |
| List<IAMGroupVO> groups = _aclGroupDao.search(sc, null); |
| |
| return new ArrayList<IAMGroup>(groups); |
| |
| } |
| |
| @DB |
| @Override |
| public IAMPolicy createIAMPolicy(final String iamPolicyName, final String description, final Long parentPolicyId, final String path) { |
| |
| // check if the policy is already existing |
| IAMPolicy ro = _aclPolicyDao.findByName(iamPolicyName); |
| if (ro != null) { |
| throw new InvalidParameterValueException( |
| "Unable to create acl policy with name " + iamPolicyName |
| + " already exists"); |
| } |
| |
| IAMPolicy role = Transaction.execute(new TransactionCallback<IAMPolicy>() { |
| @Override |
| public IAMPolicy doInTransaction(TransactionStatus status) { |
| IAMPolicyVO rvo = new IAMPolicyVO(iamPolicyName, description); |
| rvo.setPath(path); |
| |
| IAMPolicy role = _aclPolicyDao.persist(rvo); |
| if (parentPolicyId != null) { |
| // copy parent role permissions |
| List<IAMPolicyPermissionVO> perms = _policyPermissionDao.listByPolicy(parentPolicyId); |
| if (perms != null) { |
| for (IAMPolicyPermissionVO perm : perms) { |
| perm.setAclPolicyId(role.getId()); |
| _policyPermissionDao.persist(perm); |
| } |
| } |
| } |
| return role; |
| } |
| }); |
| |
| |
| return role; |
| } |
| |
| @DB |
| @Override |
| public boolean deleteIAMPolicy(final long iamPolicyId) { |
| // get the Acl Policy entity |
| final IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId); |
| if (policy == null) { |
| throw new InvalidParameterValueException("Unable to find acl policy: " + iamPolicyId |
| + "; failed to delete acl policy."); |
| } |
| |
| Transaction.execute(new TransactionCallbackNoReturn() { |
| @Override |
| public void doInTransactionWithoutResult(TransactionStatus status) { |
| // remove this policy related entry in acl_group_policy_map |
| List<IAMGroupPolicyMapVO> groupPolicyMap = _aclGroupPolicyMapDao.listByPolicyId(policy.getId()); |
| if (groupPolicyMap != null) { |
| for (IAMGroupPolicyMapVO gr : groupPolicyMap) { |
| _aclGroupPolicyMapDao.remove(gr.getId()); |
| } |
| } |
| |
| // remove this policy related entry in acl_account_policy_map table |
| List<IAMAccountPolicyMapVO> policyAcctMap = _aclAccountPolicyMapDao.listByPolicyId(policy.getId()); |
| if (policyAcctMap != null) { |
| for (IAMAccountPolicyMapVO policyAcct : policyAcctMap) { |
| _aclAccountPolicyMapDao.remove(policyAcct.getId()); |
| } |
| } |
| |
| // remove this policy related entry in acl_policy_permission table |
| List<IAMPolicyPermissionVO> policyPermMap = _policyPermissionDao.listByPolicy(policy.getId()); |
| if (policyPermMap != null) { |
| for (IAMPolicyPermissionVO policyPerm : policyPermMap) { |
| _policyPermissionDao.remove(policyPerm.getId()); |
| } |
| } |
| |
| // remove this role from acl_role table |
| _aclPolicyDao.remove(iamPolicyId); |
| } |
| }); |
| |
| invalidateIAMCache(); |
| |
| return true; |
| } |
| |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public List<IAMPolicy> listIAMPolicies(long accountId) { |
| |
| // static policies of the account |
| SearchBuilder<IAMGroupAccountMapVO> groupSB = _aclGroupAccountMapDao.createSearchBuilder(); |
| groupSB.and("account", groupSB.entity().getAccountId(), Op.EQ); |
| |
| GenericSearchBuilder<IAMGroupPolicyMapVO, Long> policySB = _aclGroupPolicyMapDao.createSearchBuilder(Long.class); |
| policySB.selectFields(policySB.entity().getAclPolicyId()); |
| policySB.join("accountgroupjoin", groupSB, groupSB.entity().getAclGroupId(), policySB.entity().getAclGroupId(), |
| JoinType.INNER); |
| policySB.done(); |
| SearchCriteria<Long> policySc = policySB.create(); |
| policySc.setJoinParameters("accountgroupjoin", "account", accountId); |
| |
| List<Long> policyIds = _aclGroupPolicyMapDao.customSearch(policySc, null); |
| // add policies directly attached to the account |
| List<IAMAccountPolicyMapVO> acctPolicies = _aclAccountPolicyMapDao.listByAccountId(accountId); |
| for (IAMAccountPolicyMapVO p : acctPolicies) { |
| policyIds.add(p.getIamPolicyId()); |
| } |
| if (policyIds.size() == 0) { |
| return new ArrayList<IAMPolicy>(); |
| } |
| SearchBuilder<IAMPolicyVO> sb = _aclPolicyDao.createSearchBuilder(); |
| sb.and("ids", sb.entity().getId(), Op.IN); |
| SearchCriteria<IAMPolicyVO> sc = sb.create(); |
| sc.setParameters("ids", policyIds.toArray(new Object[policyIds.size()])); |
| @SuppressWarnings("rawtypes") |
| List policies = _aclPolicyDao.customSearch(sc, null); |
| |
| return policies; |
| |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public List<IAMPolicy> listIAMPoliciesByGroup(long groupId) { |
| List<IAMGroupPolicyMapVO> policyGrpMap = _aclGroupPolicyMapDao.listByGroupId(groupId); |
| if (policyGrpMap == null || policyGrpMap.size() == 0) { |
| return new ArrayList<IAMPolicy>(); |
| } |
| |
| List<Long> policyIds = new ArrayList<Long>(); |
| for (IAMGroupPolicyMapVO pg : policyGrpMap) { |
| policyIds.add(pg.getAclPolicyId()); |
| } |
| |
| SearchBuilder<IAMPolicyVO> sb = _aclPolicyDao.createSearchBuilder(); |
| sb.and("ids", sb.entity().getId(), Op.IN); |
| SearchCriteria<IAMPolicyVO> sc = sb.create(); |
| sc.setParameters("ids", policyIds.toArray(new Object[policyIds.size()])); |
| @SuppressWarnings("rawtypes") |
| List policies = _aclPolicyDao.customSearch(sc, null); |
| |
| return policies; |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public List<IAMPolicy> listRecursiveIAMPoliciesByGroup(long groupId) { |
| List<IAMGroupPolicyMapVO> policyGrpMap = _aclGroupPolicyMapDao.listByGroupId(groupId); |
| if (policyGrpMap == null || policyGrpMap.size() == 0) { |
| return new ArrayList<IAMPolicy>(); |
| } |
| |
| List<Long> policyIds = new ArrayList<Long>(); |
| for (IAMGroupPolicyMapVO pg : policyGrpMap) { |
| policyIds.add(pg.getAclPolicyId()); |
| } |
| |
| SearchBuilder<IAMPolicyPermissionVO> permSb = _policyPermissionDao.createSearchBuilder(); |
| permSb.and("isRecursive", permSb.entity().isRecursive(), Op.EQ); |
| |
| SearchBuilder<IAMPolicyVO> 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<IAMPolicyVO> 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 |
| public Pair<List<IAMPolicy>, Integer> listIAMPolicies(Long iamPolicyId, String iamPolicyName, String path, Long startIndex, Long pageSize) { |
| |
| if (iamPolicyId != null) { |
| IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId); |
| if (policy == null) { |
| throw new InvalidParameterValueException("Unable to find acl policy by id " + iamPolicyId); |
| } |
| } |
| |
| Filter searchFilter = new Filter(IAMPolicyVO.class, "id", true, startIndex, pageSize); |
| |
| SearchBuilder<IAMPolicyVO> sb = _aclPolicyDao.createSearchBuilder(); |
| sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); |
| sb.and("path", sb.entity().getPath(), SearchCriteria.Op.LIKE); |
| sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); |
| |
| SearchCriteria<IAMPolicyVO> sc = sb.create(); |
| |
| if (iamPolicyName != null) { |
| sc.setParameters("name", iamPolicyName); |
| } |
| |
| if (iamPolicyId != null) { |
| sc.setParameters("id", iamPolicyId); |
| } |
| |
| sc.setParameters("path", path + "%"); |
| |
| Pair<List<IAMPolicyVO>, Integer> policies = _aclPolicyDao.searchAndCount(sc, searchFilter); |
| @SuppressWarnings("rawtypes") |
| List policyList = policies.first(); |
| return new Pair<List<IAMPolicy>, Integer>(policyList, policies.second()); |
| } |
| |
| @DB |
| @Override |
| public IAMGroup attachIAMPoliciesToGroup(final List<Long> policyIds, final Long groupId) { |
| // get the Acl Group entity |
| IAMGroup group = _aclGroupDao.findById(groupId); |
| if (group == null) { |
| throw new InvalidParameterValueException("Unable to find acl group: " + groupId |
| + "; failed to add roles to acl group."); |
| } |
| |
| Transaction.execute(new TransactionCallbackNoReturn() { |
| @Override |
| public void doInTransactionWithoutResult(TransactionStatus status) { |
| // add entries in acl_group_policy_map table |
| for (Long policyId : policyIds) { |
| IAMPolicy policy = _aclPolicyDao.findById(policyId); |
| if (policy == null) { |
| throw new InvalidParameterValueException("Unable to find acl policy: " + policyId |
| + "; failed to add policies to acl group."); |
| } |
| |
| IAMGroupPolicyMapVO grMap = _aclGroupPolicyMapDao.findByGroupAndPolicy(groupId, policyId); |
| if (grMap == null) { |
| // not there already |
| grMap = new IAMGroupPolicyMapVO(groupId, policyId); |
| _aclGroupPolicyMapDao.persist(grMap); |
| } |
| } |
| } |
| }); |
| |
| invalidateIAMCache(); |
| return group; |
| } |
| |
| @DB |
| @Override |
| public IAMGroup removeIAMPoliciesFromGroup(final List<Long> policyIds, final Long groupId) { |
| // get the Acl Group entity |
| IAMGroup group = _aclGroupDao.findById(groupId); |
| if (group == null) { |
| throw new InvalidParameterValueException("Unable to find acl group: " + groupId |
| + "; failed to remove roles from acl group."); |
| } |
| |
| Transaction.execute(new TransactionCallbackNoReturn() { |
| @Override |
| public void doInTransactionWithoutResult(TransactionStatus status) { |
| // add entries in acl_group_role_map table |
| for (Long policyId : policyIds) { |
| IAMPolicy policy = _aclPolicyDao.findById(policyId); |
| if (policy == null) { |
| throw new InvalidParameterValueException("Unable to find acl policy: " + policyId |
| + "; failed to add policies to acl group."); |
| } |
| |
| IAMGroupPolicyMapVO grMap = _aclGroupPolicyMapDao.findByGroupAndPolicy(groupId, policyId); |
| if (grMap != null) { |
| // not removed yet |
| _aclGroupPolicyMapDao.remove(grMap.getId()); |
| } |
| } |
| } |
| }); |
| |
| invalidateIAMCache(); |
| return group; |
| } |
| |
| |
| @Override |
| public void attachIAMPolicyToAccounts(final Long policyId, final List<Long> acctIds) { |
| IAMPolicy policy = _aclPolicyDao.findById(policyId); |
| if (policy == null) { |
| throw new InvalidParameterValueException("Unable to find acl policy: " + policyId |
| + "; failed to add policy to account."); |
| } |
| |
| Transaction.execute(new TransactionCallbackNoReturn() { |
| @Override |
| public void doInTransactionWithoutResult(TransactionStatus status) { |
| // add entries in acl_group_policy_map table |
| for (Long acctId : acctIds) { |
| IAMAccountPolicyMapVO acctMap = _aclAccountPolicyMapDao.findByAccountAndPolicy(acctId, policyId); |
| if (acctMap == null) { |
| // not there already |
| acctMap = new IAMAccountPolicyMapVO(acctId, policyId); |
| _aclAccountPolicyMapDao.persist(acctMap); |
| } |
| } |
| } |
| }); |
| |
| invalidateIAMCache(); |
| } |
| |
| @Override |
| public void removeIAMPolicyFromAccounts(final Long policyId, final List<Long> acctIds) { |
| IAMPolicy policy = _aclPolicyDao.findById(policyId); |
| if (policy == null) { |
| throw new InvalidParameterValueException("Unable to find acl policy: " + policyId |
| + "; failed to add policy to account."); |
| } |
| |
| Transaction.execute(new TransactionCallbackNoReturn() { |
| @Override |
| public void doInTransactionWithoutResult(TransactionStatus status) { |
| // add entries in acl_group_policy_map table |
| for (Long acctId : acctIds) { |
| IAMAccountPolicyMapVO acctMap = _aclAccountPolicyMapDao.findByAccountAndPolicy(acctId, policyId); |
| if (acctMap != null) { |
| // exists |
| _aclAccountPolicyMapDao.remove(acctMap.getId()); |
| } |
| } |
| } |
| }); |
| |
| invalidateIAMCache(); |
| } |
| |
| @DB |
| @Override |
| public IAMPolicy addIAMPermissionToIAMPolicy(long iamPolicyId, String entityType, String scope, Long scopeId, |
| String action, String accessType, Permission perm, Boolean recursive) { |
| // get the Acl Policy entity |
| IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId); |
| if (policy == null) { |
| throw new InvalidParameterValueException("Unable to find acl policy: " + iamPolicyId |
| + "; failed to add permission to policy."); |
| } |
| |
| // add entry in acl_policy_permission table |
| IAMPolicyPermissionVO permit = _policyPermissionDao.findByPolicyAndEntity(iamPolicyId, entityType, scope, |
| scopeId, action, perm, accessType); |
| if (permit == null) { |
| // not there already |
| permit = new IAMPolicyPermissionVO(iamPolicyId, action, entityType, accessType, scope, scopeId, perm, |
| recursive); |
| _policyPermissionDao.persist(permit); |
| } |
| |
| invalidateIAMCache(); |
| return policy; |
| |
| } |
| |
| @DB |
| @Override |
| public IAMPolicy removeIAMPermissionFromIAMPolicy(long iamPolicyId, String entityType, String scope, Long scopeId, |
| String action) { |
| // get the Acl Policy entity |
| IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId); |
| if (policy == null) { |
| throw new InvalidParameterValueException("Unable to find acl policy: " + iamPolicyId |
| + "; failed to revoke permission from policy."); |
| } |
| // remove entry from acl_entity_permission table |
| IAMPolicyPermissionVO permit = _policyPermissionDao.findByPolicyAndEntity(iamPolicyId, entityType, scope, |
| scopeId, action, Permission.Allow, null); |
| if (permit != null) { |
| // not removed yet |
| _policyPermissionDao.remove(permit.getId()); |
| } |
| |
| invalidateIAMCache(); |
| return policy; |
| } |
| |
| @DB |
| @Override |
| public void removeIAMPermissionForEntity(final String entityType, final Long entityId) { |
| Transaction.execute(new TransactionCallbackNoReturn() { |
| @Override |
| public void doInTransactionWithoutResult(TransactionStatus status) { |
| // remove entry from acl_entity_permission table |
| List<IAMPolicyPermissionVO> permitList = _policyPermissionDao.listByEntity(entityType, entityId); |
| for (IAMPolicyPermissionVO permit : permitList) { |
| long policyId = permit.getAclPolicyId(); |
| _policyPermissionDao.remove(permit.getId()); |
| |
| // remove the policy if there are no other permissions |
| if ((_policyPermissionDao.listByPolicy(policyId)).isEmpty()) { |
| deleteIAMPolicy(policyId); |
| } |
| } |
| } |
| }); |
| |
| invalidateIAMCache(); |
| } |
| |
| @DB |
| @Override |
| public IAMPolicy resetIAMPolicy(long iamPolicyId) { |
| // get the Acl Policy entity |
| IAMPolicy policy = _aclPolicyDao.findById(iamPolicyId); |
| if (policy == null) { |
| throw new InvalidParameterValueException("Unable to find acl policy: " + iamPolicyId |
| + "; failed to reset the policy."); |
| } |
| |
| SearchBuilder<IAMPolicyPermissionVO> sb = _policyPermissionDao.createSearchBuilder(); |
| sb.and("policyId", sb.entity().getAclPolicyId(), SearchCriteria.Op.EQ); |
| sb.and("scope", sb.entity().getScope(), SearchCriteria.Op.EQ); |
| sb.done(); |
| SearchCriteria<IAMPolicyPermissionVO> permissionSC = sb.create(); |
| permissionSC.setParameters("policyId", iamPolicyId); |
| _policyPermissionDao.expunge(permissionSC); |
| |
| invalidateIAMCache(); |
| return policy; |
| } |
| |
| @Override |
| public boolean isActionAllowedForPolicies(String action, List<IAMPolicy> policies) { |
| |
| boolean allowed = false; |
| |
| if (policies == null || policies.size() == 0) { |
| return allowed; |
| } |
| |
| List<Long> policyIds = new ArrayList<Long>(); |
| for (IAMPolicy policy : policies) { |
| policyIds.add(policy.getId()); |
| } |
| |
| SearchBuilder<IAMPolicyPermissionVO> sb = _policyPermissionDao.createSearchBuilder(); |
| sb.and("action", sb.entity().getAction(), Op.EQ); |
| sb.and("policyId", sb.entity().getAclPolicyId(), Op.IN); |
| |
| SearchCriteria<IAMPolicyPermissionVO> sc = sb.create(); |
| sc.setParameters("policyId", policyIds.toArray(new Object[policyIds.size()])); |
| sc.setParameters("action", action); |
| |
| List<IAMPolicyPermissionVO> permissions = _policyPermissionDao.customSearch(sc, null); |
| |
| if (permissions != null && !permissions.isEmpty()) { |
| allowed = true; |
| } |
| |
| return allowed; |
| } |
| |
| |
| @Override |
| public List<Long> getGrantedEntities(long accountId, String action, String scope) { |
| // Get the static Policies of the Caller |
| List<IAMPolicy> policies = listIAMPolicies(accountId); |
| // for each policy, find granted permission within the given scope |
| List<Long> entityIds = new ArrayList<Long>(); |
| for (IAMPolicy policy : policies) { |
| List<IAMPolicyPermissionVO> pp = _policyPermissionDao.listByPolicyActionAndScope(policy.getId(), action, |
| scope, null); |
| if (pp != null) { |
| for (IAMPolicyPermissionVO p : pp) { |
| if (p.getScopeId() != null) { |
| entityIds.add(p.getScopeId()); |
| } |
| } |
| } |
| } |
| return entityIds; |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public List<IAMPolicyPermission> listPolicyPermissions(long policyId) { |
| @SuppressWarnings("rawtypes") |
| List pp = _policyPermissionDao.listByPolicy(policyId); |
| return pp; |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public List<IAMPolicyPermission> listPolicyPermissionsByScope(long policyId, String action, String scope, |
| String accessType) { |
| @SuppressWarnings("rawtypes") |
| List pp = _policyPermissionDao.listByPolicyActionAndScope(policyId, action, scope, accessType); |
| return pp; |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public List<IAMPolicyPermission> listPolicyPermissionByActionAndEntity(long policyId, String action, |
| String entityType) { |
| @SuppressWarnings("rawtypes") |
| List pp = _policyPermissionDao.listByPolicyActionAndEntity(policyId, action, entityType); |
| return pp; |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public List<IAMPolicyPermission> listPolicyPermissionByAccessAndEntity(long policyId, String accessType, |
| String entityType) { |
| @SuppressWarnings("rawtypes") |
| List pp = _policyPermissionDao.listByPolicyAccessAndEntity(policyId, accessType, entityType); |
| return pp; |
| } |
| |
| @Override |
| public IAMPolicy getResourceOwnerPolicy() { |
| return _aclPolicyDao.findByName("RESOURCE_OWNER"); |
| } |
| |
| // search for policy with only one resource grant permission |
| @Override |
| public IAMPolicy getResourceGrantPolicy(String entityType, Long entityId, String accessType, String action) { |
| List<IAMPolicyVO> policyList = _aclPolicyDao.listAll(); |
| for (IAMPolicyVO policy : policyList) { |
| List<IAMPolicyPermission> pp = listPolicyPermissions(policy.getId()); |
| if (pp != null && pp.size() == 1) { |
| // resource grant policy should only have one ACL permission assigned |
| IAMPolicyPermission permit = pp.get(0); |
| if (permit.getEntityType().equals(entityType) && permit.getScope().equals(PermissionScope.RESOURCE.toString()) |
| && permit.getScopeId().longValue() == entityId.longValue()) { |
| if (accessType != null && permit.getAccessType().equals(accessType)) { |
| return policy; |
| } else if (action != null && permit.getAction().equals(action)) { |
| return policy; |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| } |