You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mc...@apache.org on 2014/03/06 23:07:22 UTC

[39/50] [abbrv] CLOUDSTACK-5920: IAM service plugin.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c28450c1/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMPermissionResponse.java
----------------------------------------------------------------------
diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMPermissionResponse.java b/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMPermissionResponse.java
new file mode 100644
index 0000000..b7af4da
--- /dev/null
+++ b/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMPermissionResponse.java
@@ -0,0 +1,125 @@
+// 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.response.iam;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.apache.cloudstack.acl.IAMEntityType;
+import org.apache.cloudstack.acl.PermissionScope;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.iam.api.IAMPolicyPermission;
+
+import com.cloud.serializer.Param;
+
+public class IAMPermissionResponse extends BaseResponse {
+
+    @SerializedName(ApiConstants.IAM_ACTION)
+    @Param(description = "action of this permission")
+    private String action;
+
+    @SerializedName(ApiConstants.ENTITY_TYPE)
+    @Param(description = "the entity type of this permission")
+    private IAMEntityType entityType;
+
+    @SerializedName(ApiConstants.IAM_SCOPE)
+    @Param(description = "scope of this permission")
+    private PermissionScope scope;
+
+    @SerializedName(ApiConstants.IAM_SCOPE_ID)
+    @Param(description = "scope id of this permission")
+    private Long scopeId;
+
+    @SerializedName(ApiConstants.IAM_ALLOW_DENY)
+    @Param(description = "allow or deny of this permission")
+    private IAMPolicyPermission.Permission permission;
+
+    public IAMEntityType getEntityType() {
+        return entityType;
+    }
+
+    public void setEntityType(IAMEntityType entityType) {
+        this.entityType = entityType;
+    }
+
+    public String getAction() {
+        return action;
+    }
+
+    public void setAction(String action) {
+        this.action = action;
+    }
+
+    public PermissionScope getScope() {
+        return scope;
+    }
+
+    public void setScope(PermissionScope scope) {
+        this.scope = scope;
+    }
+
+    public Long getScopeId() {
+        return scopeId;
+    }
+
+    public void setScopeId(Long scopeId) {
+        this.scopeId = scopeId;
+    }
+
+    public IAMPolicyPermission.Permission getPermission() {
+        return permission;
+    }
+
+    public void setPermission(IAMPolicyPermission.Permission permission) {
+        this.permission = permission;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((action == null) ? 0 : action.hashCode());
+        result = prime * result + ((entityType == null) ? 0 : entityType.hashCode());
+        result = prime * result + ((scope == null) ? 0 : scope.hashCode());
+        result = prime * result + ((scopeId == null) ? 0 : scopeId.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        IAMPermissionResponse other = (IAMPermissionResponse) obj;
+        if ((entityType == null && other.entityType != null) || !entityType.equals(other.entityType)) {
+            return false;
+        } else if ((action == null && other.action != null) || !action.equals(other.action)) {
+            return false;
+        } else if ((scope == null && other.scope != null) || !scope.equals(other.scope)) {
+            return false;
+        } else if ((scopeId == null && other.scopeId != null) || !scopeId.equals(other.scopeId)) {
+            return false;
+        }
+        return true;
+    }
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c28450c1/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMPolicyResponse.java
----------------------------------------------------------------------
diff --git a/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMPolicyResponse.java b/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMPolicyResponse.java
new file mode 100644
index 0000000..dc29369
--- /dev/null
+++ b/services/iam/plugin/src/org/apache/cloudstack/api/response/iam/IAMPolicyResponse.java
@@ -0,0 +1,177 @@
+// 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.response.iam;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.EntityReference;
+import org.apache.cloudstack.api.response.ControlledViewEntityResponse;
+import org.apache.cloudstack.iam.api.IAMPolicy;
+
+import com.cloud.serializer.Param;
+
+@SuppressWarnings("unused")
+@EntityReference(value = IAMPolicy.class)
+public class IAMPolicyResponse extends BaseResponse implements ControlledViewEntityResponse {
+
+    @SerializedName(ApiConstants.ID)
+    @Param(description = "the ID of the iam policy")
+    private String id;
+
+    @SerializedName(ApiConstants.NAME)
+    @Param(description = "the name of the iam policy")
+    private String name;
+
+    @SerializedName(ApiConstants.DESCRIPTION)
+    @Param(description = "the description of the iam policy")
+    private String description;
+
+    @SerializedName(ApiConstants.DOMAIN_ID)
+    @Param(description = "the domain ID of the iam policy")
+    private String domainId;
+
+    @SerializedName(ApiConstants.DOMAIN)
+    @Param(description = "the domain name of the iam policy")
+    private String domainName;
+
+    @SerializedName(ApiConstants.ACCOUNT)
+    @Param(description = "the account owning the policy")
+    private String accountName;
+
+    @SerializedName(ApiConstants.IAM_PERMISSIONS)
+    @Param(description = "set of permissions for the iam policy")
+    private Set<IAMPermissionResponse> permissionList;
+
+    public IAMPolicyResponse() {
+        permissionList = new LinkedHashSet<IAMPermissionResponse>();
+    }
+
+    @Override
+    public String getObjectId() {
+        return getId();
+    }
+
+
+    public String getId() {
+        return id;
+     }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    @Override
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Override
+    public void setDomainName(String domainName) {
+        this.domainName = domainName;
+    }
+
+    public Set<IAMPermissionResponse> getPermissionList() {
+        return permissionList;
+    }
+
+    public void setPermissionList(Set<IAMPermissionResponse> perms) {
+        permissionList = perms;
+    }
+
+    public void addPermission(IAMPermissionResponse perm) {
+        permissionList.add(perm);
+    }
+
+    @Override
+    public void setAccountName(String accountName) {
+        this.accountName = accountName;
+    }
+
+    @Override
+    public void setProjectId(String projectId) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void setProjectName(String projectName) {
+        // TODO Auto-generated method stub
+
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public String getDomainName() {
+        return domainName;
+    }
+
+    public String getAccountName() {
+        return accountName;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((id == null) ? 0 : id.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        IAMPolicyResponse other = (IAMPolicyResponse) obj;
+        if (id == null) {
+            if (other.id != null)
+                return false;
+        } else if (!id.equals(other.id))
+            return false;
+        return true;
+    }
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c28450c1/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiService.java
----------------------------------------------------------------------
diff --git a/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiService.java b/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiService.java
new file mode 100644
index 0000000..bb8f03b
--- /dev/null
+++ b/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiService.java
@@ -0,0 +1,87 @@
+// 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;
+
+import java.util.List;
+
+import org.apache.cloudstack.acl.PermissionScope;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.iam.IAMGroupResponse;
+import org.apache.cloudstack.api.response.iam.IAMPolicyResponse;
+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 com.cloud.user.Account;
+import com.cloud.utils.component.PluggableService;
+
+public interface IAMApiService extends PluggableService {
+
+    /* ACL group related interfaces */
+    IAMGroup createIAMGroup(Account caller, String iamGroupName, String description);
+
+    boolean deleteIAMGroup(Long iamGroupId);
+
+    List<IAMGroup> listIAMGroups(long accountId);
+
+    IAMGroup addAccountsToGroup(List<Long> acctIds, Long groupId);
+
+    IAMGroup removeAccountsFromGroup(List<Long> acctIds, Long groupId);
+
+    /* IAM Policy related interfaces */
+    IAMPolicy createIAMPolicy(Account caller, String iamPolicyName, String description, Long parentPolicyId);
+
+    boolean deleteIAMPolicy(long iamPolicyId);
+
+    List<IAMPolicy> listIAMPolicies(long accountId);
+
+    IAMGroup attachIAMPoliciesToGroup(List<Long> policyIds, Long groupId);
+
+    IAMGroup removeIAMPoliciesFromGroup(List<Long> policyIds, Long groupId);
+
+    void attachIAMPolicyToAccounts(Long policyId, List<Long> accountIds);
+
+    void removeIAMPolicyFromAccounts(Long policyId, List<Long> accountIds);
+
+    IAMPolicy addIAMPermissionToIAMPolicy(long iamPolicyId, String entityType, PermissionScope scope, Long scopeId,
+            String action, Permission perm, Boolean recursive);
+
+    IAMPolicy removeIAMPermissionFromIAMPolicy(long iamPolicyId, String entityType, PermissionScope scope, Long scopeId, String action);
+
+    IAMPolicyPermission getIAMPolicyPermission(long accountId, String entityType, String action);
+
+    /* Utility routine to grant/revoke invidivual resource to list of accounts */
+    void grantEntityPermissioinToAccounts(String entityType, Long entityId, AccessType accessType, String action, List<Long> accountIds);
+
+    void revokeEntityPermissioinFromAccounts(String entityType, Long entityId, AccessType accessType, String action, List<Long> accountIds);
+
+    /* Response Generation */
+    IAMPolicyResponse createIAMPolicyResponse(IAMPolicy policy);
+
+    IAMGroupResponse createIAMGroupResponse(IAMGroup group);
+
+    ListResponse<IAMGroupResponse> listIAMGroups(Long iamGroupId, String iamGroupName,
+            Long domainId, Long startIndex, Long pageSize);
+
+    ListResponse<IAMPolicyResponse> listIAMPolicies(Long iamPolicyId, String iamPolicyName,
+            Long domainId, Long startIndex, Long pageSize);
+
+    // Convert passed scope uuid to internal scope long id
+    Long getPermissionScopeId(String scope, String entityType, String scopeId);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c28450c1/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiServiceImpl.java b/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiServiceImpl.java
new file mode 100644
index 0000000..97519f2
--- /dev/null
+++ b/services/iam/plugin/src/org/apache/cloudstack/iam/IAMApiServiceImpl.java
@@ -0,0 +1,800 @@
+// 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;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.IAMEntityType;
+import org.apache.cloudstack.acl.PermissionScope;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.affinity.AffinityGroupVO;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.InternalIdentity;
+import org.apache.cloudstack.api.command.iam.AddAccountToIAMGroupCmd;
+import org.apache.cloudstack.api.command.iam.AddIAMPermissionToIAMPolicyCmd;
+import org.apache.cloudstack.api.command.iam.AttachIAMPolicyToAccountCmd;
+import org.apache.cloudstack.api.command.iam.AttachIAMPolicyToIAMGroupCmd;
+import org.apache.cloudstack.api.command.iam.CreateIAMGroupCmd;
+import org.apache.cloudstack.api.command.iam.CreateIAMPolicyCmd;
+import org.apache.cloudstack.api.command.iam.DeleteIAMGroupCmd;
+import org.apache.cloudstack.api.command.iam.DeleteIAMPolicyCmd;
+import org.apache.cloudstack.api.command.iam.ListIAMGroupsCmd;
+import org.apache.cloudstack.api.command.iam.ListIAMPoliciesCmd;
+import org.apache.cloudstack.api.command.iam.RemoveAccountFromIAMGroupCmd;
+import org.apache.cloudstack.api.command.iam.RemoveIAMPermissionFromIAMPolicyCmd;
+import org.apache.cloudstack.api.command.iam.RemoveIAMPolicyFromAccountCmd;
+import org.apache.cloudstack.api.command.iam.RemoveIAMPolicyFromIAMGroupCmd;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.iam.IAMGroupResponse;
+import org.apache.cloudstack.api.response.iam.IAMPermissionResponse;
+import org.apache.cloudstack.api.response.iam.IAMPolicyResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.MessageSubscriber;
+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.IAMGroupVO;
+import org.apache.cloudstack.iam.server.IAMPolicyVO;
+import org.apache.cloudstack.region.gslb.GlobalLoadBalancerRuleVO;
+
+import com.cloud.api.ApiServerService;
+import com.cloud.domain.Domain;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.event.EventVO;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.UserIpv6AddressVO;
+import com.cloud.network.VpnUserVO;
+import com.cloud.network.as.AutoScalePolicyVO;
+import com.cloud.network.as.AutoScaleVmGroupVO;
+import com.cloud.network.as.AutoScaleVmProfileVO;
+import com.cloud.network.as.ConditionVO;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.MonitoringServiceVO;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.RemoteAccessVpnVO;
+import com.cloud.network.dao.Site2SiteCustomerGatewayVO;
+import com.cloud.network.dao.Site2SiteVpnConnectionVO;
+import com.cloud.network.dao.Site2SiteVpnGatewayVO;
+import com.cloud.network.dao.SslCertVO;
+import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.network.rules.PortForwardingRuleVO;
+import com.cloud.network.security.SecurityGroupVO;
+import com.cloud.network.vpc.StaticRouteVO;
+import com.cloud.network.vpc.VpcGatewayVO;
+import com.cloud.network.vpc.VpcVO;
+import com.cloud.projects.ProjectInvitationVO;
+import com.cloud.storage.SnapshotVO;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.VolumeVO;
+import com.cloud.tags.ResourceTagVO;
+import com.cloud.template.TemplateManager;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
+import com.cloud.user.DomainManager;
+import com.cloud.user.SSHKeyPairVO;
+import com.cloud.user.dao.AccountDao;
+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.vm.InstanceGroupVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.dao.NicIpAliasVO;
+import com.cloud.vm.dao.NicSecondaryIpVO;
+import com.cloud.vm.snapshot.VMSnapshotVO;
+
+@Local(value = {IAMApiService.class})
+public class IAMApiServiceImpl extends ManagerBase implements IAMApiService, Manager {
+
+    public static final Logger s_logger = Logger.getLogger(IAMApiServiceImpl.class);
+    private String _name;
+
+    @Inject
+    ApiServerService _apiServer;
+
+    @Inject
+    IAMService _iamSrv;
+
+    @Inject
+    DomainDao _domainDao;
+
+    @Inject
+    AccountDao _accountDao;
+
+    @Inject
+    AccountManager _accountMgr;
+
+    @Inject
+    MessageBus _messageBus;
+
+    @Inject
+    EntityManager _entityMgr;
+
+    private static final Map<IAMEntityType, Class<?>> s_typeMap = new HashMap<IAMEntityType, Class<?>>();
+    static {
+        s_typeMap.put(IAMEntityType.VirtualMachine, VMInstanceVO.class);
+        s_typeMap.put(IAMEntityType.Volume, VolumeVO.class);
+        s_typeMap.put(IAMEntityType.ResourceTag, ResourceTagVO.class);
+        s_typeMap.put(IAMEntityType.Account, AccountVO.class);
+        s_typeMap.put(IAMEntityType.AffinityGroup, AffinityGroupVO.class);
+        s_typeMap.put(IAMEntityType.AutoScalePolicy, AutoScalePolicyVO.class);
+        s_typeMap.put(IAMEntityType.AutoScaleVmProfile, AutoScaleVmProfileVO.class);
+        s_typeMap.put(IAMEntityType.AutoScaleVmGroup, AutoScaleVmGroupVO.class);
+        s_typeMap.put(IAMEntityType.Condition, ConditionVO.class);
+        s_typeMap.put(IAMEntityType.Vpc, VpcVO.class);
+        s_typeMap.put(IAMEntityType.VpcGateway, VpcGatewayVO.class);
+        s_typeMap.put(IAMEntityType.PrivateGateway, RemoteAccessVpnVO.class);
+        s_typeMap.put(IAMEntityType.VpnUser, VpnUserVO.class);
+        s_typeMap.put(IAMEntityType.VMSnapshot, VMSnapshotVO.class);
+        s_typeMap.put(IAMEntityType.VirtualMachineTemplate, VMTemplateVO.class);
+        s_typeMap.put(IAMEntityType.UserIpv6Address, UserIpv6AddressVO.class);
+        s_typeMap.put(IAMEntityType.StaticRoute, StaticRouteVO.class);
+        s_typeMap.put(IAMEntityType.SSHKeyPair, SSHKeyPairVO.class);
+        s_typeMap.put(IAMEntityType.Snapshot, SnapshotVO.class);
+        s_typeMap.put(IAMEntityType.Site2SiteVpnGateway, Site2SiteVpnGatewayVO.class);
+        s_typeMap.put(IAMEntityType.Site2SiteCustomerGateway, Site2SiteCustomerGatewayVO.class);
+        s_typeMap.put(IAMEntityType.Site2SiteVpnConnection, Site2SiteVpnConnectionVO.class);
+        s_typeMap.put(IAMEntityType.SecurityGroup, SecurityGroupVO.class);
+        s_typeMap.put(IAMEntityType.RemoteAccessVpn, RemoteAccessVpnVO.class);
+        s_typeMap.put(IAMEntityType.PublicIpAddress, IPAddressVO.class);
+        s_typeMap.put(IAMEntityType.ProjectInvitation, ProjectInvitationVO.class);
+        s_typeMap.put(IAMEntityType.NicSecondaryIp, NicSecondaryIpVO.class);
+        s_typeMap.put(IAMEntityType.NicIpAlias, NicIpAliasVO.class);
+        s_typeMap.put(IAMEntityType.Network, NetworkVO.class);
+        s_typeMap.put(IAMEntityType.IpAddress, IPAddressVO.class);
+        s_typeMap.put(IAMEntityType.InstanceGroup, InstanceGroupVO.class);
+        s_typeMap.put(IAMEntityType.GlobalLoadBalancerRule, GlobalLoadBalancerRuleVO.class);
+        s_typeMap.put(IAMEntityType.FirewallRule, FirewallRuleVO.class);
+        s_typeMap.put(IAMEntityType.PortForwardingRule, PortForwardingRuleVO.class);
+        s_typeMap.put(IAMEntityType.Event, EventVO.class);
+        s_typeMap.put(IAMEntityType.AsyncJob, AsyncJobVO.class);
+        s_typeMap.put(IAMEntityType.IAMGroup, IAMGroupVO.class);
+        s_typeMap.put(IAMEntityType.IAMPolicy, IAMPolicyVO.class);
+        s_typeMap.put(IAMEntityType.MonitorService, MonitoringServiceVO.class);
+        s_typeMap.put(IAMEntityType.SSLCert, SslCertVO.class);
+    }
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        _messageBus.subscribe(AccountManager.MESSAGE_ADD_ACCOUNT_EVENT, new MessageSubscriber() {
+            @Override
+            public void onPublishMessage(String senderAddress, String subject, Object obj) {
+                HashMap<Long, Long> acctGroupMap = (HashMap<Long, Long>) obj;
+                for (Long accountId : acctGroupMap.keySet()) {
+                    Long groupId = acctGroupMap.get(accountId);
+                    s_logger.debug("MessageBus message: new Account Added: " + accountId + ", adding it to groupId :"
+                            + groupId);
+                    addAccountToIAMGroup(accountId, groupId);
+                    // add it to domain group too
+                    AccountVO account = _accountDao.findById(accountId);
+                    Domain domain = _domainDao.findById(account.getDomainId());
+                    if (domain != null) {
+                        List<IAMGroup> domainGroups = listDomainGroup(domain);
+
+                        if (domainGroups != null) {
+                            for (IAMGroup group : domainGroups) {
+                                addAccountToIAMGroup(accountId, new Long(group.getId()));
+                            }
+                        }
+                    }
+                }
+            }
+        });
+
+        _messageBus.subscribe(AccountManager.MESSAGE_REMOVE_ACCOUNT_EVENT, new MessageSubscriber() {
+            @Override
+            public void onPublishMessage(String senderAddress, String subject, Object obj) {
+                Long accountId = ((Long) obj);
+                if (accountId != null) {
+                    s_logger.debug("MessageBus message: Account removed: " + accountId
+                            + ", releasing the group associations");
+                    removeAccountFromIAMGroups(accountId);
+                }
+            }
+        });
+
+        _messageBus.subscribe(DomainManager.MESSAGE_ADD_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: new Domain created: " + domainId + ", creating a new group");
+                    Domain domain = _domainDao.findById(domainId);
+                    _iamSrv.createIAMGroup("DomainGrp-" + domain.getUuid(), "Domain group", domain.getPath());
+                }
+            }
+        });
+
+        _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<IAMGroup> groups = listDomainGroup(domain);
+                    for (IAMGroup group : groups) {
+                        _iamSrv.deleteIAMGroup(group.getId());
+                    }
+                }
+            }
+        });
+
+        _messageBus.subscribe(TemplateManager.MESSAGE_REGISTER_PUBLIC_TEMPLATE_EVENT, new MessageSubscriber() {
+            @Override
+            public void onPublishMessage(String senderAddress, String subject, Object obj) {
+                Long templateId = (Long)obj;
+                if (templateId != null) {
+                    s_logger.debug("MessageBus message: new public template registered: " + templateId + ", grant permission to domain admin and normal user policies");
+                    _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), IAMEntityType.VirtualMachineTemplate.toString(),
+                            PermissionScope.RESOURCE.toString(), templateId, "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false);
+                    _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_NORMAL + 1), IAMEntityType.VirtualMachineTemplate.toString(),
+                            PermissionScope.RESOURCE.toString(), templateId, "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false);
+                }
+            }
+        });
+
+        _messageBus.subscribe(TemplateManager.MESSAGE_RESET_TEMPLATE_PERMISSION_EVENT, new MessageSubscriber() {
+            @Override
+            public void onPublishMessage(String senderAddress, String subject, Object obj) {
+                Long templateId = (Long)obj;
+                if (templateId != null) {
+                    s_logger.debug("MessageBus message: reset template permission: " + templateId);
+                    resetTemplatePermission(templateId);
+                }
+            }
+        });
+
+        _messageBus.subscribe(EntityManager.MESSAGE_REMOVE_ENTITY_EVENT, new MessageSubscriber() {
+            @Override
+            public void onPublishMessage(String senderAddress, String subject, Object obj) {
+                Pair<IAMEntityType, Long> entity = (Pair<IAMEntityType, Long>)obj;
+                if (entity != null) {
+                    String entityType = entity.first().toString();
+                    Long entityId = entity.second();
+                    s_logger.debug("MessageBus message: delete an entity: (" + entityType + "," + entityId + "), remove its related permission");
+                    _iamSrv.removeIAMPermissionForEntity(entityType, entityId);
+                }
+            }
+        });
+
+
+        _messageBus.subscribe(EntityManager.MESSAGE_GRANT_ENTITY_EVENT, new MessageSubscriber() {
+            @Override
+            public void onPublishMessage(String senderAddress, String subject, Object obj) {
+                Map<String, Object> permit = (Map<String, Object>)obj;
+                if (permit != null) {
+                    String entityType = (String)permit.get(ApiConstants.ENTITY_TYPE);
+                    Long entityId = (Long)permit.get(ApiConstants.ENTITY_ID);
+                    AccessType accessType = (AccessType)permit.get(ApiConstants.ACCESS_TYPE);
+                    String action = (String)permit.get(ApiConstants.IAM_ACTION);
+                    List<Long> acctIds = (List<Long>)permit.get(ApiConstants.ACCOUNTS);
+                    s_logger.debug("MessageBus message: grant accounts permission to an entity: (" + entityType + "," + entityId + ")");
+                    grantEntityPermissioinToAccounts(entityType, entityId, accessType, action, acctIds);
+                }
+            }
+        });
+
+        _messageBus.subscribe(EntityManager.MESSAGE_REVOKE_ENTITY_EVENT, new MessageSubscriber() {
+            @Override
+            public void onPublishMessage(String senderAddress, String subject, Object obj) {
+                Map<String, Object> permit = (Map<String, Object>)obj;
+                if (permit != null) {
+                    String entityType = (String)permit.get(ApiConstants.ENTITY_TYPE);
+                    Long entityId = (Long)permit.get(ApiConstants.ENTITY_ID);
+                    AccessType accessType = (AccessType)permit.get(ApiConstants.ACCESS_TYPE);
+                    String action = (String)permit.get(ApiConstants.IAM_ACTION);
+                    List<Long> acctIds = (List<Long>)permit.get(ApiConstants.ACCOUNTS);
+                    s_logger.debug("MessageBus message: revoke from accounts permission to an entity: (" + entityType + "," + entityId + ")");
+                    revokeEntityPermissioinFromAccounts(entityType, entityId, accessType, action, acctIds);
+                }
+            }
+        });
+
+        _messageBus.subscribe(EntityManager.MESSAGE_ADD_DOMAIN_WIDE_ENTITY_EVENT, new MessageSubscriber() {
+            @Override
+            public void onPublishMessage(String senderAddress, String subject, Object obj) {
+                Map<String, Object> params = (Map<String, Object>) obj;
+                if (params != null) {
+                    addDomainWideResourceAccess(params);
+                }
+            }
+        });
+
+        return super.configure(name, params);
+    }
+
+    private void addDomainWideResourceAccess(Map<String, Object> params) {
+
+        IAMEntityType entityType = (IAMEntityType)params.get(ApiConstants.ENTITY_TYPE);
+        Long entityId = (Long) params.get(ApiConstants.ENTITY_ID);
+        Long domainId = (Long) params.get(ApiConstants.DOMAIN_ID);
+        Boolean isRecursive = (Boolean) params.get(ApiConstants.SUBDOMAIN_ACCESS);
+
+        if (entityType == IAMEntityType.Network) {
+            createPolicyAndAddToDomainGroup("DomainWideNetwork-" + entityId, "domain wide network", entityType.toString(),
+                    entityId, "listNetworks", AccessType.UseEntry, domainId, isRecursive);
+        } else if (entityType == IAMEntityType.AffinityGroup) {
+            createPolicyAndAddToDomainGroup("DomainWideNetwork-" + entityId, "domain wide affinityGroup", entityType.toString(),
+                    entityId, "listAffinityGroups", AccessType.UseEntry, domainId, isRecursive);
+        }
+
+    }
+
+    private void createPolicyAndAddToDomainGroup(String policyName, String description, String entityType,
+            Long entityId, String action, AccessType accessType, Long domainId, Boolean recursive) {
+
+       Domain domain = _domainDao.findById(domainId);
+       if (domain != null) {
+            IAMPolicy policy = _iamSrv.createIAMPolicy(policyName, description, null, domain.getPath());
+            _iamSrv.addIAMPermissionToIAMPolicy(policy.getId(), entityType, PermissionScope.RESOURCE.toString(),
+                    entityId, action, accessType.toString(), Permission.Allow, recursive);
+            List<Long> policyList = new ArrayList<Long>();
+            policyList.add(new Long(policy.getId()));
+
+           List<IAMGroup> domainGroups = listDomainGroup(domain);
+           if (domainGroups != null) {
+               for (IAMGroup group : domainGroups) {
+                   _iamSrv.attachIAMPoliciesToGroup(policyList, group.getId());
+               }
+           }
+       }
+    }
+
+    @DB
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_IAM_GROUP_CREATE, eventDescription = "Creating Acl Group", create = true)
+    public IAMGroup createIAMGroup(Account caller, String iamGroupName, String description) {
+        Long domainId = caller.getDomainId();
+        Domain callerDomain = _domainDao.findById(domainId);
+        if (callerDomain == null) {
+            throw new InvalidParameterValueException("Caller does not have a domain");
+        }
+        return _iamSrv.createIAMGroup(iamGroupName, description, callerDomain.getPath());
+    }
+
+    @DB
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_IAM_GROUP_DELETE, eventDescription = "Deleting Acl Group")
+    public boolean deleteIAMGroup(final Long iamGroupId) {
+        return _iamSrv.deleteIAMGroup(iamGroupId);
+    }
+
+    @Override
+    public List<IAMGroup> listIAMGroups(long accountId) {
+        return _iamSrv.listIAMGroups(accountId);
+    }
+
+
+    @DB
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_IAM_GROUP_UPDATE, eventDescription = "Adding accounts to acl group")
+    public IAMGroup addAccountsToGroup(final List<Long> acctIds, final Long groupId) {
+        return _iamSrv.addAccountsToGroup(acctIds, groupId);
+    }
+
+
+    private void removeAccountFromIAMGroups(long accountId) {
+        List<IAMGroup> groups = listIAMGroups(accountId);
+        List<Long> accts = new ArrayList<Long>();
+        accts.add(accountId);
+        if (groups != null) {
+            for (IAMGroup grp : groups) {
+                removeAccountsFromGroup(accts, grp.getId());
+            }
+        }
+    }
+
+    private void addAccountToIAMGroup(long accountId, long groupId) {
+        List<Long> accts = new ArrayList<Long>();
+        accts.add(accountId);
+        addAccountsToGroup(accts, groupId);
+    }
+
+    @DB
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_IAM_GROUP_UPDATE, eventDescription = "Removing accounts from acl group")
+    public IAMGroup removeAccountsFromGroup(final List<Long> acctIds, final Long groupId) {
+        return _iamSrv.removeAccountsFromGroup(acctIds, groupId);
+    }
+
+    @DB
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_IAM_POLICY_CREATE, eventDescription = "Creating IAM Policy", create = true)
+    public IAMPolicy createIAMPolicy(Account caller, final String iamPolicyName, final String description, final Long parentPolicyId) {
+        Long domainId = caller.getDomainId();
+        Domain callerDomain = _domainDao.findById(domainId);
+        if (callerDomain == null) {
+            throw new InvalidParameterValueException("Caller does not have a domain");
+        }
+        return _iamSrv.createIAMPolicy(iamPolicyName, description, parentPolicyId, callerDomain.getPath());
+    }
+
+    @DB
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_IAM_POLICY_DELETE, eventDescription = "Deleting IAM Policy")
+    public boolean deleteIAMPolicy(final long iamPolicyId) {
+        return _iamSrv.deleteIAMPolicy(iamPolicyId);
+    }
+
+
+    @Override
+    public List<IAMPolicy> listIAMPolicies(long accountId) {
+        return _iamSrv.listIAMPolicies(accountId);
+    }
+
+    @DB
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_IAM_GROUP_UPDATE, eventDescription = "Attaching policy to acl group")
+    public IAMGroup attachIAMPoliciesToGroup(final List<Long> policyIds, final Long groupId) {
+        return _iamSrv.attachIAMPoliciesToGroup(policyIds, groupId);
+    }
+
+    @DB
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_IAM_GROUP_UPDATE, eventDescription = "Removing policies from acl group")
+    public IAMGroup removeIAMPoliciesFromGroup(final List<Long> policyIds, final Long groupId) {
+        return _iamSrv.removeIAMPoliciesFromGroup(policyIds, groupId);
+    }
+
+
+    @DB
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_IAM_ACCOUNT_POLICY_UPDATE, eventDescription = "Attaching policy to accounts")
+    public void attachIAMPolicyToAccounts(final Long policyId, final List<Long> accountIds) {
+        _iamSrv.attachIAMPolicyToAccounts(policyId, accountIds);
+    }
+
+    @DB
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_IAM_ACCOUNT_POLICY_UPDATE, eventDescription = "Removing policy from accounts")
+    public void removeIAMPolicyFromAccounts(final Long policyId, final List<Long> accountIds) {
+        _iamSrv.removeIAMPolicyFromAccounts(policyId, accountIds);
+    }
+
+    @DB
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_IAM_POLICY_GRANT, eventDescription = "Granting acl permission to IAM Policy")
+    public IAMPolicy addIAMPermissionToIAMPolicy(long iamPolicyId, String entityType, PermissionScope scope,
+            Long scopeId, String action, Permission perm, Boolean recursive) {
+        Class<?> cmdClass = _apiServer.getCmdClass(action);
+        AccessType accessType = null;
+        if (BaseListCmd.class.isAssignableFrom(cmdClass)) {
+            accessType = AccessType.UseEntry;
+        }
+        return _iamSrv.addIAMPermissionToIAMPolicy(iamPolicyId, entityType, scope.toString(), scopeId, action,
+                accessType.toString(), perm, recursive);
+    }
+
+    @DB
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_IAM_POLICY_REVOKE, eventDescription = "Revoking acl permission from IAM Policy")
+    public IAMPolicy removeIAMPermissionFromIAMPolicy(long iamPolicyId, String entityType, PermissionScope scope, Long scopeId, String action) {
+        return _iamSrv.removeIAMPermissionFromIAMPolicy(iamPolicyId, entityType, scope.toString(), scopeId, action);
+    }
+
+    @Override
+    public IAMPolicyPermission getIAMPolicyPermission(long accountId, String entityType, String action) {
+        List<IAMPolicy> policies = _iamSrv.listIAMPolicies(accountId);
+        IAMPolicyPermission curPerm = null;
+        for (IAMPolicy policy : policies) {
+            List<IAMPolicyPermission> perms = _iamSrv.listPolicyPermissionByActionAndEntity(policy.getId(), action,
+                    entityType);
+            if (perms == null || perms.size() == 0)
+                continue;
+            IAMPolicyPermission perm = perms.get(0); // just pick one
+            if (curPerm == null) {
+                curPerm = perm;
+            } else if (PermissionScope.valueOf(perm.getScope()).greaterThan(PermissionScope.valueOf(curPerm.getScope()))) {
+                // pick the more relaxed allowed permission
+                curPerm = perm;
+            }
+        }
+
+        return curPerm;
+    }
+
+
+    @Override
+    public IAMPolicyResponse createIAMPolicyResponse(IAMPolicy policy) {
+        IAMPolicyResponse response = new IAMPolicyResponse();
+        response.setId(policy.getUuid());
+        response.setName(policy.getName());
+        response.setDescription(policy.getDescription());
+        String domainPath = policy.getPath();
+        if (domainPath != null) {
+            DomainVO domain = _domainDao.findDomainByPath(domainPath);
+            if (domain != null) {
+                response.setDomainId(domain.getUuid());
+                response.setDomainName(domain.getName());
+            }
+        }
+        long accountId = policy.getAccountId();
+        AccountVO owner = _accountDao.findById(accountId);
+        if (owner != null) {
+            response.setAccountName(owner.getAccountName());
+        }
+        // find permissions associated with this policy
+        List<IAMPolicyPermission> permissions = _iamSrv.listPolicyPermissions(policy.getId());
+        if (permissions != null && permissions.size() > 0) {
+            for (IAMPolicyPermission permission : permissions) {
+                IAMPermissionResponse perm = new IAMPermissionResponse();
+                perm.setAction(permission.getAction());
+                if (permission.getEntityType() != null) {
+                    perm.setEntityType(IAMEntityType.valueOf(permission.getEntityType()));
+                }
+                if (permission.getScope() != null) {
+                    perm.setScope(PermissionScope.valueOf(permission.getScope()));
+                }
+                perm.setScopeId(permission.getScopeId());
+                perm.setPermission(permission.getPermission());
+                response.addPermission(perm);
+            }
+        }
+        response.setObjectName("aclpolicy");
+        return response;
+    }
+
+    @Override
+    public IAMGroupResponse createIAMGroupResponse(IAMGroup group) {
+        IAMGroupResponse response = new IAMGroupResponse();
+        response.setId(group.getUuid());
+        response.setName(group.getName());
+        response.setDescription(group.getDescription());
+        String domainPath = group.getPath();
+        if (domainPath != null) {
+            DomainVO domain = _domainDao.findDomainByPath(domainPath);
+            if (domain != null) {
+                response.setDomainId(domain.getUuid());
+                response.setDomainName(domain.getName());
+            }
+        }
+        long accountId = group.getAccountId();
+        AccountVO owner = _accountDao.findById(accountId);
+        if (owner != null) {
+            response.setAccountName(owner.getAccountName());
+        }
+        // find all the members in this group
+        List<Long> members = _iamSrv.listAccountsByGroup(group.getId());
+        if (members != null && members.size() > 0) {
+            for (Long member : members) {
+                AccountVO mem = _accountDao.findById(member);
+                if (mem != null) {
+                    response.addMemberAccount(mem.getAccountName());
+                }
+            }
+        }
+
+        // find all the policies attached to this group
+        List<IAMPolicy> policies = _iamSrv.listIAMPoliciesByGroup(group.getId());
+        if (policies != null && policies.size() > 0) {
+            for (IAMPolicy policy : policies) {
+                response.addPolicy(policy.getName());
+            }
+        }
+
+        response.setObjectName("aclgroup");
+        return response;
+
+    }
+
+    public List<IAMGroup> listDomainGroup(Domain domain) {
+
+        if (domain != null) {
+            String domainPath = domain.getPath();
+            // search for groups
+            Pair<List<IAMGroup>, Integer> result = _iamSrv.listIAMGroups(null, "DomainGrp-" + domain.getUuid(),
+                    domainPath, null, null);
+            return result.first();
+        }
+        return new ArrayList<IAMGroup>();
+
+    }
+
+    @Override
+    public ListResponse<IAMGroupResponse> listIAMGroups(Long iamGroupId, String iamGroupName, Long domainId, Long startIndex, Long pageSize) {
+        // acl check
+        Account caller = CallContext.current().getCallingAccount();
+
+        Domain domain = null;
+        if (domainId != null) {
+            domain = _domainDao.findById(domainId);
+            if (domain == null) {
+                throw new InvalidParameterValueException("Domain id=" + domainId + " doesn't exist");
+            }
+
+            _accountMgr.checkAccess(caller, domain);
+        } else {
+            domain = _domainDao.findById(caller.getDomainId());
+        }
+        String domainPath = domain.getPath();
+        // search for groups
+        Pair<List<IAMGroup>, Integer> result = _iamSrv.listIAMGroups(iamGroupId, iamGroupName, domainPath, startIndex, pageSize);
+        // generate group response
+        ListResponse<IAMGroupResponse> response = new ListResponse<IAMGroupResponse>();
+        List<IAMGroupResponse> groupResponses = new ArrayList<IAMGroupResponse>();
+        for (IAMGroup group : result.first()) {
+            IAMGroupResponse resp = createIAMGroupResponse(group);
+            groupResponses.add(resp);
+        }
+        response.setResponses(groupResponses, result.second());
+        return response;
+    }
+
+    @Override
+    public ListResponse<IAMPolicyResponse> listIAMPolicies(Long iamPolicyId, String iamPolicyName, Long domainId, Long startIndex,
+            Long pageSize) {
+        // acl check
+        Account caller = CallContext.current().getCallingAccount();
+
+        Domain domain = null;
+        if (domainId != null) {
+            domain = _domainDao.findById(domainId);
+            if (domain == null) {
+                throw new InvalidParameterValueException("Domain id=" + domainId + " doesn't exist");
+            }
+
+            _accountMgr.checkAccess(caller, domain);
+        } else {
+            domain = _domainDao.findById(caller.getDomainId());
+        }
+        String domainPath = domain.getPath();
+        // search for policies
+        Pair<List<IAMPolicy>, Integer> result = _iamSrv.listIAMPolicies(iamPolicyId, iamPolicyName, domainPath, startIndex, pageSize);
+        // generate policy response
+        ListResponse<IAMPolicyResponse> response = new ListResponse<IAMPolicyResponse>();
+        List<IAMPolicyResponse> policyResponses = new ArrayList<IAMPolicyResponse>();
+        for (IAMPolicy policy : result.first()) {
+            IAMPolicyResponse resp = createIAMPolicyResponse(policy);
+            policyResponses.add(resp);
+        }
+        response.setResponses(policyResponses, result.second());
+        return response;
+    }
+
+    @Override
+    public void grantEntityPermissioinToAccounts(String entityType, Long entityId, AccessType accessType, String action, List<Long> accountIds) {
+        // check if there is already a policy with only this permission added to it
+        IAMPolicy policy = _iamSrv.getResourceGrantPolicy(entityType, entityId, accessType.toString(), action);
+        if (policy == null) {
+            // not found, just create a policy with resource grant permission
+            Account caller = CallContext.current().getCallingAccount();
+            String aclPolicyName = "policyGrant" + entityType + entityId;
+            String description = "Policy to grant permission to " + entityType + entityId;
+            policy = createIAMPolicy(caller, aclPolicyName, description, null);
+            // add permission to this policy
+            addIAMPermissionToIAMPolicy(policy.getId(), entityType, PermissionScope.RESOURCE, entityId, action, Permission.Allow, false);
+        }
+        // attach this policy to list of accounts if not attached already
+        Long policyId = policy.getId();
+        for (Long acctId : accountIds) {
+            if (!isPolicyAttachedToAccount(policyId, acctId)) {
+                attachIAMPolicyToAccounts(policyId, Collections.singletonList(acctId));
+            }
+        }
+    }
+
+    @Override
+    public void revokeEntityPermissioinFromAccounts(String entityType, Long entityId, AccessType accessType, String action, List<Long> accountIds) {
+        // there should already a policy with only this permission added to it, this call is mainly used
+        IAMPolicy policy = _iamSrv.getResourceGrantPolicy(entityType, entityId, accessType.toString(), action);
+        if (policy == null) {
+            s_logger.warn("Cannot find a policy associated with this entity permissioin to be revoked, just return");
+            return;
+        }
+        // detach this policy from list of accounts if not detached already
+        Long policyId = policy.getId();
+        for (Long acctId : accountIds) {
+            if (isPolicyAttachedToAccount(policyId, acctId)) {
+                removeIAMPolicyFromAccounts(policyId, Collections.singletonList(acctId));
+            }
+        }
+
+    }
+
+    private boolean isPolicyAttachedToAccount(Long policyId, Long accountId) {
+        List<IAMPolicy> pList = listIAMPolicies(accountId);
+        for (IAMPolicy p : pList) {
+            if (p.getId() == policyId.longValue()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void resetTemplatePermission(Long templateId){
+        // reset template will change template to private, so we need to remove its permission for domain admin and normal user group
+        _iamSrv.removeIAMPermissionFromIAMPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), IAMEntityType.VirtualMachineTemplate.toString(),
+                PermissionScope.RESOURCE.toString(), templateId, "listTemplates");
+        _iamSrv.removeIAMPermissionFromIAMPolicy(new Long(Account.ACCOUNT_TYPE_NORMAL + 1), IAMEntityType.VirtualMachineTemplate.toString(),
+                PermissionScope.RESOURCE.toString(), templateId, "listTemplates");
+        // check if there is a policy with only UseEntry permission for this template added
+        IAMPolicy policy = _iamSrv.getResourceGrantPolicy(IAMEntityType.VirtualMachineTemplate.toString(), templateId, AccessType.UseEntry.toString(), "listTemplates");
+        if ( policy == null ){
+            s_logger.info("No policy found for this template grant: " + templateId + ", no detach to be done");
+            return;
+        }
+        // delete the policy, which should detach it from groups and accounts
+        _iamSrv.deleteIAMPolicy(policy.getId());
+
+    }
+
+    @Override
+    public Long getPermissionScopeId(String scope, String entityType, String scopeId) {
+        if (scopeId.equals("-1")) {
+            return -1L;
+        }
+        PermissionScope permScope = PermissionScope.valueOf(scope);
+        InternalIdentity entity = null;
+        switch (permScope) {
+        case DOMAIN:
+            entity = _domainDao.findByUuid(scopeId);
+            break;
+        case ACCOUNT:
+            entity = _accountDao.findByUuid(scopeId);
+            break;
+        case RESOURCE:
+            Class<?> clazz = s_typeMap.get(IAMEntityType.valueOf(entityType));
+            entity = (InternalIdentity)_entityMgr.findByUuid(clazz, scopeId);
+        }
+
+        if (entity != null) {
+            return entity.getId();
+        }
+        throw new InvalidParameterValueException("Unable to find scopeId " + scopeId + " with scope " + scope + " and type " + entityType);
+    }
+
+    @Override
+    public List<Class<?>> getCommands() {
+        List<Class<?>> cmdList = new ArrayList<Class<?>>();
+        cmdList.add(CreateIAMPolicyCmd.class);
+        cmdList.add(DeleteIAMPolicyCmd.class);
+        cmdList.add(ListIAMPoliciesCmd.class);
+        cmdList.add(AddIAMPermissionToIAMPolicyCmd.class);
+        cmdList.add(RemoveIAMPermissionFromIAMPolicyCmd.class);
+        cmdList.add(AttachIAMPolicyToIAMGroupCmd.class);
+        cmdList.add(RemoveIAMPolicyFromIAMGroupCmd.class);
+        cmdList.add(CreateIAMGroupCmd.class);
+        cmdList.add(DeleteIAMGroupCmd.class);
+        cmdList.add(ListIAMGroupsCmd.class);
+        cmdList.add(AddAccountToIAMGroupCmd.class);
+        cmdList.add(RemoveAccountFromIAMGroupCmd.class);
+        cmdList.add(AttachIAMPolicyToAccountCmd.class);
+        cmdList.add(RemoveIAMPolicyFromAccountCmd.class);
+        return cmdList;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c28450c1/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedAPIAccessChecker.java
----------------------------------------------------------------------
diff --git a/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedAPIAccessChecker.java b/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedAPIAccessChecker.java
new file mode 100644
index 0000000..fb75db3
--- /dev/null
+++ b/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedAPIAccessChecker.java
@@ -0,0 +1,273 @@
+// 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;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.APIChecker;
+import org.apache.cloudstack.acl.IAMEntityType;
+import org.apache.cloudstack.acl.PermissionScope;
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.BaseListCmd;
+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 com.cloud.api.ApiServerService;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountService;
+import com.cloud.user.User;
+import com.cloud.utils.PropertiesUtil;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.component.PluggableService;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+//This is the Role Based API access checker that grab's the  account's roles
+//based on the set of roles, access is granted if any of the role has access to the api
+@Local(value=APIChecker.class)
+public class RoleBasedAPIAccessChecker extends AdapterBase implements APIChecker {
+
+    protected static final Logger s_logger = Logger.getLogger(RoleBasedAPIAccessChecker.class);
+
+    @Inject
+    AccountService _accountService;
+    @Inject
+    ApiServerService _apiServer;
+    @Inject
+    IAMService _iamSrv;
+    @Inject
+    VMTemplateDao _templateDao;
+
+    Set<String> commandsPropertiesOverrides = new HashSet<String>();
+    Map<RoleType, Set<String>> commandsPropertiesRoleBasedApisMap = new HashMap<RoleType, Set<String>>();
+
+    List<PluggableService> _services;
+
+    protected RoleBasedAPIAccessChecker() {
+        super();
+        for (RoleType roleType : RoleType.values()) {
+            commandsPropertiesRoleBasedApisMap.put(roleType, new HashSet<String>());
+        }
+     }
+
+    @Override
+    public boolean checkAccess(User user, String commandName) throws PermissionDeniedException {
+        Account account = _accountService.getAccount(user.getAccountId());
+        if (account == null) {
+            throw new PermissionDeniedException("The account id=" + user.getAccountId() + "for user id=" + user.getId()
+                    + "is null");
+        }
+
+        List<IAMPolicy> policies = _iamSrv.listIAMPolicies(account.getAccountId());
+
+        boolean isAllowed = _iamSrv.isActionAllowedForPolicies(commandName, policies);
+        if (!isAllowed) {
+            throw new PermissionDeniedException("The API does not exist or is blacklisted. api: " + commandName);
+        }
+        return isAllowed;
+     }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        super.configure(name, params);
+
+        processMapping(PropertiesUtil.processConfigFile(new String[] { "commands.properties" }));
+        return true;
+     }
+
+    @Override
+    public boolean start() {
+
+        // drop all default policy api permissions - we reload them every time
+        // to include any changes done to the @APICommand or
+        // commands.properties.
+
+        for (RoleType role : RoleType.values()) {
+            Long policyId = getDefaultPolicyId(role);
+            if (policyId != null) {
+                _iamSrv.resetIAMPolicy(policyId);
+            }
+         }
+
+        // add the system-domain capability
+
+        _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_ADMIN + 1), null, null, null,
+                "SystemCapability", null, Permission.Allow, false);
+        _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), null, null, null,
+                "DomainCapability", null, Permission.Allow, false);
+        _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN + 1), null, null, null,
+                "DomainResourceCapability", null, Permission.Allow, false);
+
+        // add permissions for public templates
+        List<VMTemplateVO> pTmplts = _templateDao.listByPublic();
+        for (VMTemplateVO tmpl : pTmplts){
+            _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), IAMEntityType.VirtualMachineTemplate.toString(),
+                    PermissionScope.RESOURCE.toString(), tmpl.getId(), "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false);
+            _iamSrv.addIAMPermissionToIAMPolicy(new Long(Account.ACCOUNT_TYPE_NORMAL + 1), IAMEntityType.VirtualMachineTemplate.toString(),
+                    PermissionScope.RESOURCE.toString(), tmpl.getId(), "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false);
+        }
+
+        for (PluggableService service : _services) {
+            for (Class<?> cmdClass : service.getCommands()) {
+                APICommand command = cmdClass.getAnnotation(APICommand.class);
+                if (!commandsPropertiesOverrides.contains(command.name())) {
+                    for (RoleType role : command.authorized()) {
+                        addDefaultAclPolicyPermission(command.name(), cmdClass, role);
+                    }
+                 }
+             }
+         }
+
+        // read commands.properties and load api acl permissions -
+        // commands.properties overrides any @APICommand authorization
+
+        for (String apiName : commandsPropertiesOverrides) {
+            Class<?> cmdClass = _apiServer.getCmdClass(apiName);
+            for (RoleType role : RoleType.values()) {
+                if (commandsPropertiesRoleBasedApisMap.get(role).contains(apiName)) {
+                    // insert permission for this role for this api
+                    addDefaultAclPolicyPermission(apiName, cmdClass, role);
+                }
+             }
+         }
+
+        return super.start();
+     }
+
+    private Long getDefaultPolicyId(RoleType role) {
+        Long policyId = null;
+        switch (role) {
+        case User:
+            policyId = new Long(Account.ACCOUNT_TYPE_NORMAL + 1);
+            break;
+
+        case Admin:
+            policyId = new Long(Account.ACCOUNT_TYPE_ADMIN + 1);
+            break;
+
+        case DomainAdmin:
+            policyId = new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1);
+            break;
+
+        case ResourceAdmin:
+            policyId = new Long(Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN + 1);
+            break;
+        }
+
+        return policyId;
+    }
+
+    private void processMapping(Map<String, String> configMap) {
+        for (Map.Entry<String, String> entry : configMap.entrySet()) {
+            String apiName = entry.getKey();
+            String roleMask = entry.getValue();
+            commandsPropertiesOverrides.add(apiName);
+            try {
+                short cmdPermissions = Short.parseShort(roleMask);
+                for (RoleType roleType : RoleType.values()) {
+                    if ((cmdPermissions & roleType.getValue()) != 0)
+                        commandsPropertiesRoleBasedApisMap.get(roleType).add(apiName);
+                }
+            } catch (NumberFormatException nfe) {
+                s_logger.info("Malformed key=value pair for entry: " + entry.toString());
+             }
+         }
+     }
+
+    public List<PluggableService> getServices() {
+        return _services;
+     }
+
+    @Inject
+    public void setServices(List<PluggableService> services) {
+        _services = services;
+     }
+
+    private void addDefaultAclPolicyPermission(String apiName, Class<?> cmdClass, RoleType role) {
+
+        AccessType accessType = null;
+        IAMEntityType[] entityTypes = null;
+        if (cmdClass != null) {
+            BaseCmd cmdObj;
+            try {
+                cmdObj = (BaseCmd) cmdClass.newInstance();
+                if (cmdObj instanceof BaseListCmd) {
+                    accessType = AccessType.UseEntry;
+                } else if (!(cmdObj instanceof BaseAsyncCreateCmd)) {
+                    accessType = AccessType.OperateEntry;
+                }
+            } catch (Exception e) {
+                throw new CloudRuntimeException(String.format(
+                        "%s is claimed as an API command, but it cannot be instantiated", cmdClass.getName()));
+             }
+
+            APICommand at = cmdClass.getAnnotation(APICommand.class);
+            entityTypes = at.entityType();
+        }
+
+        PermissionScope permissionScope = PermissionScope.ACCOUNT;
+        Long policyId = getDefaultPolicyId(role);
+        switch (role) {
+        case User:
+            permissionScope = PermissionScope.ACCOUNT;
+            break;
+
+        case Admin:
+            permissionScope = PermissionScope.ALL;
+            break;
+
+        case DomainAdmin:
+            permissionScope = PermissionScope.DOMAIN;
+            break;
+
+        case ResourceAdmin:
+            permissionScope = PermissionScope.DOMAIN;
+            break;
+         }
+
+
+        if (entityTypes == null || entityTypes.length == 0) {
+            _iamSrv.addIAMPermissionToIAMPolicy(policyId, null, permissionScope.toString(), new Long(IAMPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER),
+                    apiName, (accessType == null) ? null : accessType.toString(), Permission.Allow, false);
+        } else {
+            for (IAMEntityType entityType : entityTypes) {
+                _iamSrv.addIAMPermissionToIAMPolicy(policyId, entityType.toString(), permissionScope.toString(), new Long(IAMPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER),
+                        apiName, (accessType == null) ? null : accessType.toString(), Permission.Allow, false);
+            }
+         }
+
+     }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c28450c1/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityAccessChecker.java
----------------------------------------------------------------------
diff --git a/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityAccessChecker.java b/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityAccessChecker.java
new file mode 100644
index 0000000..d0d9d88
--- /dev/null
+++ b/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityAccessChecker.java
@@ -0,0 +1,186 @@
+// 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;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.PermissionScope;
+import org.apache.cloudstack.acl.SecurityChecker;
+import org.apache.cloudstack.api.InternalIdentity;
+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.IAMService;
+
+import com.cloud.acl.DomainChecker;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.user.Account;
+import com.cloud.user.AccountService;
+
+public class RoleBasedEntityAccessChecker extends DomainChecker implements SecurityChecker {
+
+    private static final Logger s_logger = Logger.getLogger(RoleBasedEntityAccessChecker.class.getName());
+
+    @Inject
+    AccountService _accountService;
+
+    @Inject DomainDao _domainDao;
+
+    @Inject
+    IAMService _iamSrv;
+
+
+    @Override
+    public boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessType)
+            throws PermissionDeniedException {
+        return checkAccess(caller, entity, accessType, null);
+    }
+
+    @Override
+    public boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessType, String action)
+            throws PermissionDeniedException {
+
+        if (entity == null && action != null) {
+            // check if caller can do this action
+            List<IAMPolicy> policies = _iamSrv.listIAMPolicies(caller.getAccountId());
+
+            boolean isAllowed = _iamSrv.isActionAllowedForPolicies(action, policies);
+            if (!isAllowed) {
+                throw new PermissionDeniedException("The action '" + action + "' not allowed for account " + caller);
+            }
+            return true;
+        }
+
+        String entityType = entity.getEntityType().toString();
+
+        if (accessType == null) {
+            accessType = AccessType.UseEntry;
+        }
+
+        // get all Policies of this caller w.r.t the entity
+        List<IAMPolicy> policies = getEffectivePolicies(caller, entity);
+        HashMap<IAMPolicy, Boolean> policyPermissionMap = new HashMap<IAMPolicy, Boolean>();
+
+        for (IAMPolicy policy : policies) {
+            List<IAMPolicyPermission> permissions = new ArrayList<IAMPolicyPermission>();
+
+            if (action != null) {
+                permissions = _iamSrv.listPolicyPermissionByActionAndEntity(policy.getId(), action, entityType);
+                if (permissions.isEmpty()) {
+                    if (accessType != null) {
+                        permissions.addAll(_iamSrv.listPolicyPermissionByAccessAndEntity(policy.getId(),
+                                accessType.toString(), entityType));
+                    }
+                }
+            } else {
+                if (accessType != null) {
+                    permissions.addAll(_iamSrv.listPolicyPermissionByAccessAndEntity(policy.getId(),
+                            accessType.toString(), entityType));
+                }
+            }
+            for (IAMPolicyPermission permission : permissions) {
+                if (checkPermissionScope(caller, permission.getScope(), permission.getScopeId(), entity)) {
+                    if (permission.getEntityType().equals(entityType)) {
+                        policyPermissionMap.put(policy, permission.getPermission().isGranted());
+                        break;
+                    } else if (permission.getEntityType().equals("*")) {
+                        policyPermissionMap.put(policy, permission.getPermission().isGranted());
+                    }
+                }
+            }
+            if (policyPermissionMap.containsKey(policy) && policyPermissionMap.get(policy)) {
+                return true;
+            }
+        }
+
+        if (!policies.isEmpty()) { // Since we reach this point, none of the
+                                   // roles granted access
+            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);
+        }
+
+        return false;
+    }
+
+    private boolean checkPermissionScope(Account caller, String scope, Long scopeId, ControlledEntity entity) {
+
+        if(scopeId != null && !scopeId.equals(new Long(IAMPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER))){
+            //scopeId is set
+            if (scope.equals(PermissionScope.ACCOUNT.name())) {
+                if(scopeId == entity.getAccountId()){
+                    return true;
+                }
+            } else if (scope.equals(PermissionScope.DOMAIN.name())) {
+                if (_domainDao.isChildDomain(scopeId, entity.getDomainId())) {
+                    return true;
+                }
+            } else if (scope.equals(PermissionScope.RESOURCE.name())) {
+                if (entity instanceof InternalIdentity) {
+                    InternalIdentity entityWithId = (InternalIdentity) entity;
+                    if(scopeId.equals(entityWithId.getId())){
+                        return true;
+                    }
+                }
+            }
+        } else if (scopeId == null || scopeId.equals(new Long(IAMPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER))) {
+            if (scope.equals(PermissionScope.ACCOUNT.name())) {
+                if(caller.getAccountId() == entity.getAccountId()){
+                    return true;
+                }
+            } else if (scope.equals(PermissionScope.DOMAIN.name())) {
+                if (_domainDao.isChildDomain(caller.getDomainId(), entity.getDomainId())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private List<IAMPolicy> getEffectivePolicies(Account caller, ControlledEntity entity) {
+
+        // Get the static Policies of the Caller
+        List<IAMPolicy> policies = _iamSrv.listIAMPolicies(caller.getId());
+
+        // add any dynamic policies w.r.t the entity
+        if (caller.getId() == entity.getAccountId()) {
+            // The caller owns the entity
+            policies.add(_iamSrv.getResourceOwnerPolicy());
+        }
+
+        List<IAMGroup> groups = _iamSrv.listIAMGroups(caller.getId());
+        for (IAMGroup group : groups) {
+            // for each group find the grand parent groups.
+            List<IAMGroup> parentGroups = _iamSrv.listParentIAMGroups(group.getId());
+            for (IAMGroup parentGroup : parentGroups) {
+                policies.addAll(_iamSrv.listRecursiveIAMPoliciesByGroup(parentGroup.getId()));
+            }
+        }
+
+        return policies;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c28450c1/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityQuerySelector.java
----------------------------------------------------------------------
diff --git a/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityQuerySelector.java b/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityQuerySelector.java
new file mode 100644
index 0000000..23c57a1
--- /dev/null
+++ b/services/iam/plugin/src/org/apache/cloudstack/iam/RoleBasedEntityQuerySelector.java
@@ -0,0 +1,147 @@
+// 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;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.PermissionScope;
+import org.apache.cloudstack.acl.QuerySelector;
+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.IAMService;
+
+import com.cloud.user.Account;
+import com.cloud.utils.component.AdapterBase;
+
+public class RoleBasedEntityQuerySelector extends AdapterBase implements QuerySelector {
+
+    private static final Logger s_logger = Logger.getLogger(RoleBasedEntityQuerySelector.class.getName());
+
+    @Inject
+    IAMService _iamService;
+
+    @Override
+    public List<Long> getAuthorizedDomains(Account caller, String action) {
+        long accountId = caller.getAccountId();
+        // Get the static Policies of the Caller
+        List<IAMPolicy> policies = _iamService.listIAMPolicies(accountId);
+        // for each policy, find granted permission with Domain scope
+        List<Long> domainIds = new ArrayList<Long>();
+        for (IAMPolicy policy : policies) {
+            List<IAMPolicyPermission> pp = _iamService.listPolicyPermissionsByScope(policy.getId(), action, PermissionScope.DOMAIN.toString());
+            if (pp != null) {
+                for (IAMPolicyPermission p : pp) {
+                    if (p.getScopeId() != null) {
+                        if (p.getScopeId().longValue() == -1) {
+                            domainIds.add(caller.getDomainId());
+                        } else {
+                            domainIds.add(p.getScopeId());
+                        }
+                    }
+                }
+            }
+        }
+        return domainIds;
+    }
+
+    @Override
+    public List<Long> getAuthorizedAccounts(Account caller, String action) {
+        long accountId = caller.getAccountId();
+        // Get the static Policies of the Caller
+        List<IAMPolicy> policies = _iamService.listIAMPolicies(accountId);
+        // for each policy, find granted permission with Account scope
+        List<Long> accountIds = new ArrayList<Long>();
+        for (IAMPolicy policy : policies) {
+            List<IAMPolicyPermission> pp = _iamService.listPolicyPermissionsByScope(policy.getId(), action, PermissionScope.ACCOUNT.toString());
+            if (pp != null) {
+                for (IAMPolicyPermission p : pp) {
+                    if (p.getScopeId() != null) {
+                        if (p.getScopeId().longValue() == -1) {
+                            accountIds.add(caller.getId());
+                        } else {
+                            accountIds.add(p.getScopeId());
+                        }
+                    }
+                }
+            }
+        }
+        return accountIds;
+    }
+
+    @Override
+    public List<Long> getAuthorizedResources(Account caller, String action) {
+        long accountId = caller.getAccountId();
+        // Get the static Policies of the Caller
+        List<IAMPolicy> policies = _iamService.listIAMPolicies(accountId);
+
+        // add the policies that grant recursive access
+        List<IAMGroup> groups = _iamService.listIAMGroups(caller.getId());
+        for (IAMGroup group : groups) {
+            // for each group find the grand parent groups.
+            List<IAMGroup> parentGroups = _iamService.listParentIAMGroups(group.getId());
+            for (IAMGroup parentGroup : parentGroups) {
+                policies.addAll(_iamService.listRecursiveIAMPoliciesByGroup(parentGroup.getId()));
+            }
+        }
+
+        // for each policy, find granted permission with Resource scope
+        List<Long> entityIds = new ArrayList<Long>();
+        for (IAMPolicy policy : policies) {
+            List<IAMPolicyPermission> pp = _iamService.listPolicyPermissionsByScope(policy.getId(), action, PermissionScope.RESOURCE.toString());
+            if (pp != null) {
+                for (IAMPolicyPermission p : pp) {
+                    if (p.getScopeId() != null) {
+                        entityIds.add(p.getScopeId());
+                    }
+                }
+            }
+        }
+        return entityIds;
+    }
+
+    @Override
+    public boolean isGrantedAll(Account caller, String action) {
+        long accountId = caller.getAccountId();
+        // Get the static Policies of the Caller
+        List<IAMPolicy> policies = _iamService.listIAMPolicies(accountId);
+        // for each policy, find granted permission with ALL scope
+        for (IAMPolicy policy : policies) {
+            List<IAMPolicyPermission> pp = _iamService.listPolicyPermissionsByScope(policy.getId(), action, PermissionScope.ALL.toString());
+            if (pp != null && pp.size() > 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public List<String> listAclGroupsByAccount(long accountId) {
+        List<IAMGroup> groups = _iamService.listIAMGroups(accountId);
+        List<String> groupNames = new ArrayList<String>();
+        for (IAMGroup grp : groups) {
+            groupNames.add(grp.getName());
+        }
+        return groupNames;
+    }
+
+}