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/01/17 23:40:37 UTC
[35/50] [abbrv] Merge branch 'master' into rbac.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/929fbaba/services/iam/plugin/test/org/apache/cloudstack/acl/AclApiServiceTest.java
----------------------------------------------------------------------
diff --cc services/iam/plugin/test/org/apache/cloudstack/acl/AclApiServiceTest.java
index 3a38ce7,0000000..676c0ab
mode 100644,000000..100644
--- a/services/iam/plugin/test/org/apache/cloudstack/acl/AclApiServiceTest.java
+++ b/services/iam/plugin/test/org/apache/cloudstack/acl/AclApiServiceTest.java
@@@ -1,350 -1,0 +1,350 @@@
+package org.apache.cloudstack.acl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.ComponentScan.Filter;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.FilterType;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.core.type.filter.TypeFilter;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.acl.api.AclApiService;
+import org.apache.cloudstack.acl.api.AclApiServiceImpl;
+import org.apache.cloudstack.acl.api.response.AclGroupResponse;
+import org.apache.cloudstack.acl.api.response.AclPermissionResponse;
+import org.apache.cloudstack.acl.api.response.AclPolicyResponse;
+import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.iam.api.AclGroup;
+import org.apache.cloudstack.iam.api.AclPolicy;
+import org.apache.cloudstack.iam.api.AclPolicyPermission;
+import org.apache.cloudstack.iam.api.AclPolicyPermission.Permission;
+import org.apache.cloudstack.iam.api.IAMService;
+import org.apache.cloudstack.iam.server.AclGroupVO;
+import org.apache.cloudstack.iam.server.AclPolicyPermissionVO;
+import org.apache.cloudstack.iam.server.AclPolicyVO;
+import org.apache.cloudstack.test.utils.SpringUtils;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import com.cloud.api.ApiServerService;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
+import com.cloud.user.UserVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.ComponentContext;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
+public class AclApiServiceTest {
+
+ @Inject
+ IAMService _iamSrv;
+
+ @Inject
+ DomainDao _domainDao;
+
+ @Inject
+ AclApiService _aclSrv;
+
+ @Inject
+ AccountManager _accountMgr;
+
+ @Inject
+ AccountDao _accountDao;
+
+ @Inject
+ ApiServerService _apiServer;
+
+ private static Account caller;
+ private static Long callerId;
+ private static String callerAccountName = "tester";
+ private static Long callerDomainId = 3L;
+ private static String callerDomainPath = "/root/testdomain";
+ private static DomainVO callerDomain;
+
+ @BeforeClass
+ public static void setUpClass() throws ConfigurationException {
+ }
+
+ @Before
+ public void setUp() {
+ ComponentContext.initComponentsLifeCycle();
+ caller = new AccountVO(callerAccountName, callerDomainId, null, Account.ACCOUNT_TYPE_ADMIN, UUID.randomUUID().toString());
+ callerId = caller.getId();
+ callerDomain = new DomainVO();
+ callerDomain.setPath(callerDomainPath);
+ UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString());
+ CallContext.register(user, caller);
+
+ when(_domainDao.findById(callerDomainId)).thenReturn(callerDomain);
+ doNothing().when(_accountMgr).checkAccess(caller, callerDomain);
+ }
+
+ @Test
+ public void createAclGroupTest() {
+ AclGroup group = new AclGroupVO("group1", "tester group1");
+ List<AclGroup> groups = new ArrayList<AclGroup>();
+ groups.add(group);
+ Pair<List<AclGroup>, Integer> grpList = new Pair<List<AclGroup>, Integer>(groups, 1);
+ when(_iamSrv.createAclGroup("group1", "tester group1", callerDomainPath)).thenReturn(group);
+ when(_iamSrv.listAclGroups(null, null, callerDomainPath, 0L, 20L)).thenReturn(grpList);
+
+ AclGroup createdGrp = _aclSrv.createAclGroup(caller, "group1", "tester group1");
+ assertNotNull("Acl group 'group1' failed to create ", createdGrp);
+ ListResponse<AclGroupResponse> grpResp = _aclSrv.listAclGroups(null, null, callerDomainId, 0L, 20L);
+ assertTrue("No. of response items should be one", grpResp.getCount() == 1);
+ AclGroupResponse resp = grpResp.getResponses().get(0);
+ assertEquals("Error in created group name", "group1", resp.getName());
+ }
+
+ @Test
+ public void deleteAclGroupTest() {
+ when(_iamSrv.deleteAclGroup(1L)).thenReturn(true);
+ assertTrue("failed to delete acl group 1", _aclSrv.deleteAclGroup(1L));
+ }
+
+ @Test
+ public void listAclGroupTest() {
+ AclGroup group = new AclGroupVO("group1", "tester group1");
+ List<AclGroup> groups = new ArrayList<AclGroup>();
+ groups.add(group);
+ when(_iamSrv.listAclGroups(callerId)).thenReturn(groups);
+ List<AclGroup> grps = _aclSrv.listAclGroups(callerId);
+ assertTrue(grps != null && grps.size() == 1);
+ AclGroup grp = grps.get(0);
+ assertEquals("Error to retrieve group", "group1", grp.getName());
+ }
+
+ @Test
+ public void addRemoveAccountToGroupTest() {
+ AclGroup group = new AclGroupVO("group1", "tester group1");
+ List<AclGroup> groups = new ArrayList<AclGroup>();
+ groups.add(group);
+ Long groupId = group.getId();
+ List<Long> acctIds = new ArrayList<Long>();
+ AccountVO acct1 = new AccountVO(100L);
+ acct1.setAccountName("account1");
+ AccountVO acct2 = new AccountVO(200L);
+ acct2.setAccountName("account2");
+ acctIds.add(acct1.getId());
+ acctIds.add(acct2.getId());
+ when(_accountDao.findById(acct1.getId())).thenReturn(acct1);
+ when(_accountDao.findById(acct2.getId())).thenReturn(acct2);
+ when(_iamSrv.addAccountsToGroup(acctIds, groupId)).thenReturn(group);
+ when(_iamSrv.listAccountsByGroup(groupId)).thenReturn(acctIds);
+ Pair<List<AclGroup>, Integer> grpList = new Pair<List<AclGroup>, Integer>(groups, 1);
+ when(_iamSrv.listAclGroups(null, "group1", callerDomainPath, 0L, 20L)).thenReturn(grpList);
+ _aclSrv.addAccountsToGroup(acctIds, groupId);
+ ListResponse<AclGroupResponse> grpResp = _aclSrv.listAclGroups(null, "group1", callerDomainId, 0L, 20L);
+ assertTrue("No. of response items should be one", grpResp.getCount() == 1);
+ AclGroupResponse resp = grpResp.getResponses().get(0);
+ Set<String> acctNames = resp.getAccountNameList();
+ assertEquals("There should be 2 accounts in the group", 2, acctNames.size());
+ assertTrue("account1 should be assigned to the group", acctNames.contains("account1"));
+ assertTrue("account2 should be assigned to the group", acctNames.contains("account2"));
+ // remove "account2" from group1
+ acctIds.remove(1);
+ List<Long> rmAccts = new ArrayList<Long>();
+ rmAccts.add(acct2.getId());
+ when(_iamSrv.removeAccountsFromGroup(rmAccts, groupId)).thenReturn(group);
+ _aclSrv.removeAccountsFromGroup(acctIds, groupId);
+ grpResp = _aclSrv.listAclGroups(null, "group1", callerDomainId, 0L, 20L);
+ assertTrue("No. of response items should be one", grpResp.getCount() == 1);
+ resp = grpResp.getResponses().get(0);
+ acctNames = resp.getAccountNameList();
+ assertEquals("There should be 1 accounts in the group", 1, acctNames.size());
+ assertFalse("account2 should not belong to the group anymore", acctNames.contains("account2"));
+ }
+
+ @Test
+ public void createAclPolicyTest() {
+ AclPolicy policy = new AclPolicyVO("policy1", "tester policy1");
+ List<AclPolicy> policies = new ArrayList<AclPolicy>();
+ policies.add(policy);
+ Pair<List<AclPolicy>, Integer> policyList = new Pair<List<AclPolicy>, Integer>(policies, 1);
+ when(_iamSrv.createAclPolicy("policy1", "tester policy1", null)).thenReturn(policy);
+ when(_iamSrv.listAclPolicies(null, null, callerDomainPath, 0L, 20L)).thenReturn(policyList);
+
+ AclPolicy createdPolicy = _aclSrv.createAclPolicy(caller, "policy1", "tester policy1", null);
+ assertNotNull("Acl policy 'policy1' failed to create ", createdPolicy);
+ ListResponse<AclPolicyResponse> policyResp = _aclSrv.listAclPolicies(null, null, callerDomainId, 0L, 20L);
+ assertTrue("No. of response items should be one", policyResp.getCount() == 1);
+ AclPolicyResponse resp = policyResp.getResponses().get(0);
+ assertEquals("Error in created group name", "policy1", resp.getName());
+ }
+
+ @Test
+ public void deleteAclPolicyTest() {
+ when(_iamSrv.deleteAclPolicy(1L)).thenReturn(true);
+ assertTrue("failed to delete acl policy 1", _aclSrv.deleteAclPolicy(1L));
+ }
+
+ @Test
+ public void listAclPolicyTest() {
+ AclPolicy policy = new AclPolicyVO("policy1", "tester policy1");
+ List<AclPolicy> policies = new ArrayList<AclPolicy>();
+ policies.add(policy);
+ when(_iamSrv.listAclPolicies(callerId)).thenReturn(policies);
+ List<AclPolicy> polys = _aclSrv.listAclPolicies(callerId);
+ assertTrue(polys != null && polys.size() == 1);
+ AclPolicy p = polys.get(0);
+ assertEquals("Error to retrieve group", "policy1", p.getName());
+ }
+
+ @Test
+ public void addRemovePolicyToGroupTest() {
+ AclGroup group = new AclGroupVO("group1", "tester group1");
+ List<AclGroup> groups = new ArrayList<AclGroup>();
+ groups.add(group);
+ Long groupId = group.getId();
+ List<Long> policyIds = new ArrayList<Long>();
+ policyIds.add(100L);
+ policyIds.add(200L);
+ AclPolicy policy1 = new AclPolicyVO("policy1", "my first policy");
+ AclPolicy policy2 = new AclPolicyVO("policy2", "my second policy");
+ List<AclPolicy> policies = new ArrayList<AclPolicy>();
+ policies.add(policy1);
+ policies.add(policy2);
+ when(_iamSrv.attachAclPoliciesToGroup(policyIds, groupId)).thenReturn(group);
+ when(_iamSrv.listAclPoliciesByGroup(groupId)).thenReturn(policies);
+ Pair<List<AclGroup>, Integer> grpList = new Pair<List<AclGroup>, Integer>(groups, 1);
+ when(_iamSrv.listAclGroups(null, "group1", callerDomainPath, 0L, 20L)).thenReturn(grpList);
+ _aclSrv.attachAclPoliciesToGroup(policyIds, groupId);
+ ListResponse<AclGroupResponse> grpResp = _aclSrv.listAclGroups(null, "group1", callerDomainId, 0L, 20L);
+ assertTrue("No. of response items should be one", grpResp.getCount() == 1);
+ AclGroupResponse resp = grpResp.getResponses().get(0);
+ Set<String> policyNames = resp.getPolicyList();
+ assertEquals("There should be 2 policies in the group", 2, policyNames.size());
+ assertTrue("policy1 should be assigned to the group", policyNames.contains("policy1"));
+ assertTrue("policy2 should be assigned to the group", policyNames.contains("policy2"));
+ // remove "policy2" from group1
+ policyIds.remove(1);
+ policies.remove(policy2);
+ when(_iamSrv.removeAclPoliciesFromGroup(policyIds, groupId)).thenReturn(group);
+ _aclSrv.removeAclPoliciesFromGroup(policyIds, groupId);
+ grpResp = _aclSrv.listAclGroups(null, "group1", callerDomainId, 0L, 20L);
+ assertTrue("No. of response items should be one", grpResp.getCount() == 1);
+ resp = grpResp.getResponses().get(0);
+ policyNames = resp.getPolicyList();
+ assertEquals("There should be 1 policy attached to the group", 1, policyNames.size());
+ assertFalse("policy2 should not belong to the group anymore", policyNames.contains("policy2"));
+ }
+
+ @Test
+ public void addRemovePermissionToPolicyTest() {
+ AclPolicy policy = new AclPolicyVO("policy1", "tester policy1");
+ List<AclPolicy> policies = new ArrayList<AclPolicy>();
+ policies.add(policy);
+ Long policyId = policy.getId();
+ Long resId = 200L;
+ Class clz = ListVMsCmd.class;
+ when(_apiServer.getCmdClass("listVirtualMachines")).thenReturn(clz);
+ when(
+ _iamSrv.addAclPermissionToAclPolicy(policyId, AclEntityType.VirtualMachine.toString(), PermissionScope.RESOURCE.toString(), resId, "listVirtualMachines",
+ AccessType.ListEntry.toString(), Permission.Allow)).thenReturn(policy);
+ _aclSrv.addAclPermissionToAclPolicy(policyId, AclEntityType.VirtualMachine.toString(), PermissionScope.RESOURCE, resId, "listVirtualMachines", Permission.Allow);
+ Pair<List<AclPolicy>, Integer> policyList = new Pair<List<AclPolicy>, Integer>(policies, 1);
+ List<AclPolicyPermission> policyPerms = new ArrayList<AclPolicyPermission>();
+ AclPolicyPermission perm = new AclPolicyPermissionVO(policyId, "listVirtualMachines", AclEntityType.VirtualMachine.toString(), AccessType.ListEntry.toString(),
+ PermissionScope.RESOURCE.toString(),
+ resId, Permission.Allow);
+ policyPerms.add(perm);
+ when(_iamSrv.listAclPolicies(null, "policy1", callerDomainPath, 0L, 20L)).thenReturn(policyList);
+ when(_iamSrv.listPolicyPermissions(policyId)).thenReturn(policyPerms);
+ ListResponse<AclPolicyResponse> policyResp = _aclSrv.listAclPolicies(null, "policy1", callerDomainId, 0L, 20L);
+ assertTrue("No. of response items should be one", policyResp.getCount() == 1);
+ AclPolicyResponse resp = policyResp.getResponses().get(0);
+ Set<AclPermissionResponse> permList = resp.getPermissionList();
+ assertTrue("Permission list should not be empty", permList != null && permList.size() > 0);
+ AclPermissionResponse permResp = permList.iterator().next();
+ assertEquals("There should be one permission for listVirtualMachines", "listVirtualMachines", permResp.getAction());
+
+ //remove permission from policy
+ policyPerms.remove(perm);
+ _aclSrv.removeAclPermissionFromAclPolicy(policyId, AclEntityType.VirtualMachine.toString(), PermissionScope.RESOURCE, resId, "listVirtualMachines");
+ policyResp = _aclSrv.listAclPolicies(null, "policy1", callerDomainId, 0L, 20L);
+ assertTrue("No. of response items should be one", policyResp.getCount() == 1);
+ resp = policyResp.getResponses().get(0);
+ permList = resp.getPermissionList();
+ assertTrue("Permission list should be empty", permList != null && permList.size() == 0);
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ @Configuration
+ @ComponentScan(basePackageClasses = {AclApiServiceImpl.class}, includeFilters = {@Filter(value = TestConfiguration.Library.class, type = FilterType.CUSTOM)}, useDefaultFilters = false)
+ public static class TestConfiguration extends SpringUtils.CloudStackTestConfiguration {
+
+ @Bean
+ public DomainDao domainDao() {
+ return Mockito.mock(DomainDao.class);
+ }
+
+ @Bean
+ public IAMService iamService() {
+ return Mockito.mock(IAMService.class);
+ }
+
+ @Bean
+ public AccountDao accountDao() {
+ return Mockito.mock(AccountDao.class);
+ }
+
+ @Bean
+ public AccountManager accountManager() {
+ return Mockito.mock(AccountManager.class);
+ }
-
++
+ @Bean
+ public MessageBus messageBus() {
+ return Mockito.mock(MessageBus.class);
+ }
+
+ @Bean
+ public ApiServerService apiServerService() {
+ return Mockito.mock(ApiServerService.class);
+ }
+
+ public static class Library implements TypeFilter {
+
+ @Override
+ public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
+ ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class);
+ return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/929fbaba/services/iam/pom.xml
----------------------------------------------------------------------
diff --cc services/iam/pom.xml
index 72353e0,0000000..d4bf3e7
mode 100644,000000..100644
--- a/services/iam/pom.xml
+++ b/services/iam/pom.xml
@@@ -1,59 -1,0 +1,59 @@@
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>cloudstack-service-iam</artifactId>
+ <name>Apache CloudStack IAM Service</name>
+ <packaging>pom</packaging>
+ <parent>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloudstack-services</artifactId>
- <version>4.3.0-SNAPSHOT</version>
++ <version>4.4.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <build>
+ <defaultGoal>install</defaultGoal>
+ </build>
+ <modules>
+ <module>plugin</module>
+ <module>server</module>
+ </modules>
+ <!--
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-utils</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-api</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ -->
+
+</project>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/929fbaba/services/iam/server/pom.xml
----------------------------------------------------------------------
diff --cc services/iam/server/pom.xml
index f5e5ae0,0000000..bed8811
mode 100644,000000..100644
--- a/services/iam/server/pom.xml
+++ b/services/iam/server/pom.xml
@@@ -1,52 -1,0 +1,52 @@@
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>cloud-iam</artifactId>
+ <name>Apache CloudStack IAM - Server</name>
+ <parent>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloudstack-service-iam</artifactId>
- <version>4.3.0-SNAPSHOT</version>
++ <version>4.4.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <dependencies>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-utils</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-api</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/929fbaba/services/iam/server/src/org/apache/cloudstack/iam/server/AclGroupVO.java
----------------------------------------------------------------------
diff --cc services/iam/server/src/org/apache/cloudstack/iam/server/AclGroupVO.java
index 69d20d2,0000000..bdb85e8
mode 100644,000000..100644
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/AclGroupVO.java
+++ b/services/iam/server/src/org/apache/cloudstack/iam/server/AclGroupVO.java
@@@ -1,122 -1,0 +1,122 @@@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.iam.server;
+
+import java.util.Date;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.apache.cloudstack.iam.api.AclGroup;
+
+import com.cloud.utils.db.GenericDao;
+
+@Entity
+@Table(name = ("acl_group"))
+public class AclGroupVO implements AclGroup {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "id")
+ private long id;
+
+ @Column(name = "name")
+ private String name;
+
+ @Column(name = "description")
+ private String description;
+
+ @Column(name = "uuid")
+ private String uuid;
+
+ @Column(name = "path")
+ private String path;
+
+ @Column(name = "account_id")
+ private long accountId;
+
+ @Column(name = GenericDao.REMOVED_COLUMN)
+ private Date removed;
+
+ @Column(name = GenericDao.CREATED_COLUMN)
+ private Date created;
+
+ public AclGroupVO() {
- uuid = UUID.randomUUID().toString();
++ uuid = UUID.randomUUID().toString();
+ }
+
+ public AclGroupVO(String name, String description) {
+ this.name = name;
+ this.description = description;
- uuid = UUID.randomUUID().toString();
++ uuid = UUID.randomUUID().toString();
+ path = "/";
+ }
+
+ @Override
+ public long getId() {
+ return id;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+
+ @Override
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ @Override
+ public long getAccountId() {
+ return accountId;
+ }
+
+ public void setAccountId(long acctId) {
+ accountId = acctId;
+ }
+
+ @Override
+ public String getUuid() {
- return uuid;
++ return uuid;
+ }
+
+ public void setUuid(String uuid) {
- this.uuid = uuid;
++ this.uuid = uuid;
+ }
+
+ public Date getRemoved() {
+ return removed;
+ }
+
+ public Date getCreated() {
+ return created;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/929fbaba/services/iam/server/src/org/apache/cloudstack/iam/server/AclPolicyVO.java
----------------------------------------------------------------------
diff --cc services/iam/server/src/org/apache/cloudstack/iam/server/AclPolicyVO.java
index f3ceb04,0000000..16fbf80
mode 100644,000000..100644
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/AclPolicyVO.java
+++ b/services/iam/server/src/org/apache/cloudstack/iam/server/AclPolicyVO.java
@@@ -1,138 -1,0 +1,138 @@@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.iam.server;
+
+import java.util.Date;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.apache.cloudstack.iam.api.AclPolicy;
+
+import com.cloud.utils.db.GenericDao;
+
+@Entity
+@Table(name = ("acl_policy"))
+public class AclPolicyVO implements AclPolicy {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "id")
+ private long id;
+
+ @Column(name = "name")
+ private String name;
+
+ @Column(name = "description")
+ private String description;
+
+ @Column(name = "uuid")
+ private String uuid;
+
+ @Column(name = "path")
+ private String path;
+
+ @Column(name = "account_id")
+ private long accountId;
+
+ @Column(name = GenericDao.REMOVED_COLUMN)
+ private Date removed;
+
+ @Column(name = GenericDao.CREATED_COLUMN)
+ private Date created;
+
+ @Column(name = "policy_type")
+ @Enumerated(value = EnumType.STRING)
+ private AclPolicy.PolicyType policyType;
+
+ public AclPolicyVO() {
- uuid = UUID.randomUUID().toString();
++ uuid = UUID.randomUUID().toString();
+ }
+
+ public AclPolicyVO(String name, String description) {
+ this.name = name;
+ this.description = description;
- uuid = UUID.randomUUID().toString();
++ uuid = UUID.randomUUID().toString();
+ policyType = AclPolicy.PolicyType.Static;
+ }
+
+ @Override
+ public long getId() {
+ return id;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+
+
+ @Override
+ public String getUuid() {
- return uuid;
++ return uuid;
+ }
+
+ public void setUuid(String uuid) {
- this.uuid = uuid;
++ this.uuid = uuid;
+ }
+
+ public Date getRemoved() {
+ return removed;
+ }
+
+ public Date getCreated() {
+ return created;
+ }
+
+ @Override
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ @Override
+ public long getAccountId() {
+ return accountId;
+ }
+
+ public void setAccountId(long accountId) {
+ this.accountId = accountId;
+ }
+
+ public AclPolicy.PolicyType getPolicyType() {
+ return policyType;
+ }
+
+ public void setPolicyType(AclPolicy.PolicyType policyType) {
+ this.policyType = policyType;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/929fbaba/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java
----------------------------------------------------------------------
diff --cc services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java
index 9390b77,0000000..6eb3223
mode 100644,000000..100644
--- a/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java
+++ b/services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java
@@@ -1,694 -1,0 +1,692 @@@
+// 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 javax.ejb.Local;
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
- import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.iam.api.AclGroup;
+import org.apache.cloudstack.iam.api.AclPolicy;
+import org.apache.cloudstack.iam.api.AclPolicyPermission;
+import org.apache.cloudstack.iam.api.AclPolicyPermission.Permission;
+import org.apache.cloudstack.iam.api.IAMService;
+import org.apache.cloudstack.iam.server.dao.AclGroupAccountMapDao;
+import org.apache.cloudstack.iam.server.dao.AclGroupDao;
+import org.apache.cloudstack.iam.server.dao.AclGroupPolicyMapDao;
+import org.apache.cloudstack.iam.server.dao.AclPolicyDao;
+import org.apache.cloudstack.iam.server.dao.AclPolicyPermissionDao;
+
+import com.cloud.exception.InvalidParameterValueException;
- import com.cloud.user.Account;
+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.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;
+
+@Local(value = {IAMService.class})
+public class IAMServiceImpl extends ManagerBase implements IAMService, Manager {
+
+ public static final Logger s_logger = Logger.getLogger(IAMServiceImpl.class);
+ private String _name;
+
+ @Inject
+ AclPolicyDao _aclPolicyDao;
+
+ @Inject
+ AclGroupDao _aclGroupDao;
+
+ @Inject
+ EntityManager _entityMgr;
+
+ @Inject
+ AclGroupPolicyMapDao _aclGroupPolicyMapDao;
+
+ @Inject
+ AclGroupAccountMapDao _aclGroupAccountMapDao;
+
+ @Inject
+ AclPolicyPermissionDao _policyPermissionDao;
+
+ @DB
+ @Override
+ public AclGroup createAclGroup(String aclGroupName, String description, String path) {
+ // check if the group is already existing
+ AclGroup grp = _aclGroupDao.findByName(path, aclGroupName);
+ if (grp != null) {
+ throw new InvalidParameterValueException(
+ "Unable to create acl group with name " + aclGroupName
+ + " already exisits for path " + path);
+ }
+ AclGroupVO rvo = new AclGroupVO(aclGroupName, description);
+ rvo.setPath(path);
+
+ return _aclGroupDao.persist(rvo);
+ }
+
+ @DB
+ @Override
+ public boolean deleteAclGroup(final Long aclGroupId) {
+ // get the Acl Group entity
+ final AclGroup grp = _aclGroupDao.findById(aclGroupId);
+ if (grp == null) {
+ throw new InvalidParameterValueException("Unable to find acl group: " + aclGroupId
+ + "; failed to delete acl group.");
+ }
+
+ Transaction.execute(new TransactionCallbackNoReturn() {
+ @Override
+ public void doInTransactionWithoutResult(TransactionStatus status) {
+ // remove this group related entry in acl_group_role_map
+ List<AclGroupPolicyMapVO> groupPolicyMap = _aclGroupPolicyMapDao.listByGroupId(grp.getId());
+ if (groupPolicyMap != null) {
+ for (AclGroupPolicyMapVO gr : groupPolicyMap) {
+ _aclGroupPolicyMapDao.remove(gr.getId());
+ }
+ }
+
+ // remove this group related entry in acl_group_account table
+ List<AclGroupAccountMapVO> groupAcctMap = _aclGroupAccountMapDao.listByGroupId(grp.getId());
+ if (groupAcctMap != null) {
+ for (AclGroupAccountMapVO grpAcct : groupAcctMap) {
+ _aclGroupAccountMapDao.remove(grpAcct.getId());
+ }
+ }
+
+ // remove this group from acl_group table
+ _aclGroupDao.remove(aclGroupId);
+ }
+ });
+
+ return true;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<AclGroup> listAclGroups(long accountId) {
+
+ GenericSearchBuilder<AclGroupAccountMapVO, Long> groupSB = _aclGroupAccountMapDao.createSearchBuilder(Long.class);
+ groupSB.selectFields(groupSB.entity().getAclGroupId());
+ groupSB.and("account", groupSB.entity().getAccountId(), Op.EQ);
+ SearchCriteria<Long> groupSc = groupSB.create();
+
+ List<Long> groupIds = _aclGroupAccountMapDao.customSearch(groupSc, null);
+
+ SearchBuilder<AclGroupVO> sb = _aclGroupDao.createSearchBuilder();
+ sb.and("ids", sb.entity().getId(), Op.IN);
+ SearchCriteria<AclGroupVO> 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 AclGroup addAccountsToGroup(final List<Long> acctIds, final Long groupId) {
+ // get the Acl Group entity
+ AclGroup 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
+ AclGroupAccountMapVO grMap = _aclGroupAccountMapDao.findByGroupAndAccount(groupId, acctId);
+ if (grMap == null) {
+ // not there already
+ grMap = new AclGroupAccountMapVO(groupId, acctId);
+ _aclGroupAccountMapDao.persist(grMap);
+ }
+ }
+ }
+ });
+ return group;
+ }
+
+ @DB
+ @Override
+ public AclGroup removeAccountsFromGroup(final List<Long> acctIds, final Long groupId) {
+ // get the Acl Group entity
+ AclGroup 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) {
+ AclGroupAccountMapVO grMap = _aclGroupAccountMapDao.findByGroupAndAccount(groupId, acctId);
+ if (grMap != null) {
+ // not removed yet
+ _aclGroupAccountMapDao.remove(grMap.getId());
+ }
+ }
+ }
+ });
+ return group;
+ }
+
+ @Override
+ public List<Long> listAccountsByGroup(long groupId) {
+ List<AclGroupAccountMapVO> grpAcctMap = _aclGroupAccountMapDao.listByGroupId(groupId);
+ if (grpAcctMap == null || grpAcctMap.size() == 0) {
+ return new ArrayList<Long>();
+ }
+
+ List<Long> accts = new ArrayList<Long>();
+ for (AclGroupAccountMapVO grpAcct : grpAcctMap) {
+ accts.add(grpAcct.getAccountId());
+ }
+ return accts;
+ }
+
+ @Override
+ public Pair<List<AclGroup>, Integer> listAclGroups(Long aclGroupId, String aclGroupName, String path, Long startIndex, Long pageSize) {
+ if (aclGroupId != null) {
+ AclGroup group = _aclGroupDao.findById(aclGroupId);
+ if (group == null) {
+ throw new InvalidParameterValueException("Unable to find acl group by id " + aclGroupId);
+ }
+ }
+
+ Filter searchFilter = new Filter(AclGroupVO.class, "id", true, startIndex, pageSize);
+
+ SearchBuilder<AclGroupVO> 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<AclGroupVO> sc = sb.create();
+
+ if (aclGroupName != null) {
+ sc.setParameters("name", aclGroupName);
+ }
+
+ if (aclGroupId != null) {
+ sc.setParameters("id", aclGroupId);
+ }
+
+ sc.setParameters("path", path + "%");
+
+ Pair<List<AclGroupVO>, Integer> groups = _aclGroupDao.searchAndCount(sc, searchFilter);
+ return new Pair<List<AclGroup>, Integer>(new ArrayList<AclGroup>(groups.first()), groups.second());
+ }
+
+ @DB
+ @Override
+ public AclPolicy createAclPolicy(final String aclPolicyName, final String description, final Long parentPolicyId) {
+
+ // check if the policy is already existing
+ AclPolicy ro = _aclPolicyDao.findByName(aclPolicyName);
+ if (ro != null) {
+ throw new InvalidParameterValueException(
+ "Unable to create acl policy with name " + aclPolicyName
+ + " already exisits");
+ }
+
+ AclPolicy role = Transaction.execute(new TransactionCallback<AclPolicy>() {
+ @Override
+ public AclPolicy doInTransaction(TransactionStatus status) {
+ AclPolicyVO rvo = new AclPolicyVO(aclPolicyName, description);
+
+ AclPolicy role = _aclPolicyDao.persist(rvo);
+ if (parentPolicyId != null) {
+ // copy parent role permissions
+ List<AclPolicyPermissionVO> perms = _policyPermissionDao.listByPolicy(parentPolicyId);
+ if (perms != null) {
+ for (AclPolicyPermissionVO perm : perms) {
+ perm.setAclPolicyId(role.getId());
+ _policyPermissionDao.persist(perm);
+ }
+ }
+ }
+ return role;
+ }
+ });
-
++
+
+ return role;
+ }
+
+ @DB
+ @Override
+ public boolean deleteAclPolicy(final long aclPolicyId) {
+ // get the Acl Policy entity
+ final AclPolicy policy = _aclPolicyDao.findById(aclPolicyId);
+ if (policy == null) {
+ throw new InvalidParameterValueException("Unable to find acl policy: " + aclPolicyId
+ + "; failed to delete acl policy.");
+ }
+
+ Transaction.execute(new TransactionCallbackNoReturn() {
+ @Override
+ public void doInTransactionWithoutResult(TransactionStatus status) {
+ // remove this role related entry in acl_group_role_map
+ List<AclGroupPolicyMapVO> groupPolicyMap = _aclGroupPolicyMapDao.listByPolicyId(policy.getId());
+ if (groupPolicyMap != null) {
+ for (AclGroupPolicyMapVO gr : groupPolicyMap) {
+ _aclGroupPolicyMapDao.remove(gr.getId());
+ }
+ }
+
+ // remove this policy related entry in acl_policy_permission table
+ List<AclPolicyPermissionVO> policyPermMap = _policyPermissionDao.listByPolicy(policy.getId());
+ if (policyPermMap != null) {
+ for (AclPolicyPermissionVO policyPerm : policyPermMap) {
+ _policyPermissionDao.remove(policyPerm.getId());
+ }
+ }
+
+ // remove this role from acl_role table
+ _aclPolicyDao.remove(aclPolicyId);
+ }
+ });
+
+ return true;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<AclPolicy> listAclPolicies(long accountId) {
+
+ // static policies of the account
+ SearchBuilder<AclGroupAccountMapVO> groupSB = _aclGroupAccountMapDao.createSearchBuilder();
+ groupSB.and("account", groupSB.entity().getAccountId(), Op.EQ);
+
+ GenericSearchBuilder<AclGroupPolicyMapVO, 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);
+
+ SearchBuilder<AclPolicyVO> sb = _aclPolicyDao.createSearchBuilder();
+ sb.and("ids", sb.entity().getId(), Op.IN);
+ SearchCriteria<AclPolicyVO> 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<AclPolicy> listAclPoliciesByGroup(long groupId) {
+ List<AclGroupPolicyMapVO> policyGrpMap = _aclGroupPolicyMapDao.listByGroupId(groupId);
+ if (policyGrpMap == null || policyGrpMap.size() == 0) {
+ return new ArrayList<AclPolicy>();
+ }
+
+ List<Long> policyIds = new ArrayList<Long>();
+ for (AclGroupPolicyMapVO pg : policyGrpMap) {
+ policyIds.add(pg.getAclPolicyId());
+ }
+
+ SearchBuilder<AclPolicyVO> sb = _aclPolicyDao.createSearchBuilder();
+ sb.and("ids", sb.entity().getId(), Op.IN);
+ SearchCriteria<AclPolicyVO> 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 Pair<List<AclPolicy>, Integer> listAclPolicies(Long aclPolicyId, String aclPolicyName, String path, Long startIndex, Long pageSize) {
+
+ if (aclPolicyId != null) {
+ AclPolicy policy = _aclPolicyDao.findById(aclPolicyId);
+ if (policy == null) {
+ throw new InvalidParameterValueException("Unable to find acl policy by id " + aclPolicyId);
+ }
+ }
+
+ Filter searchFilter = new Filter(AclPolicyVO.class, "id", true, startIndex, pageSize);
+
+ SearchBuilder<AclPolicyVO> 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<AclPolicyVO> sc = sb.create();
+
+ if (aclPolicyName != null) {
+ sc.setParameters("name", aclPolicyName);
+ }
+
+ if (aclPolicyId != null) {
+ sc.setParameters("id", aclPolicyId);
+ }
+
+ sc.setParameters("path", path + "%");
+
+ Pair<List<AclPolicyVO>, Integer> policies = _aclPolicyDao.searchAndCount(sc, searchFilter);
+ @SuppressWarnings("rawtypes")
+ List policyList = policies.first();
+ return new Pair<List<AclPolicy>, Integer>(policyList, policies.second());
+ }
+
+ @DB
+ @Override
+ public AclGroup attachAclPoliciesToGroup(final List<Long> policyIds, final Long groupId) {
+ // get the Acl Group entity
+ AclGroup 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) {
+ AclPolicy policy = _aclPolicyDao.findById(policyId);
+ if (policy == null) {
+ throw new InvalidParameterValueException("Unable to find acl policy: " + policyId
+ + "; failed to add policies to acl group.");
+ }
+
+ AclGroupPolicyMapVO grMap = _aclGroupPolicyMapDao.findByGroupAndPolicy(groupId, policyId);
+ if (grMap == null) {
+ // not there already
+ grMap = new AclGroupPolicyMapVO(groupId, policyId);
+ _aclGroupPolicyMapDao.persist(grMap);
+ }
+ }
+ }
+ });
+
+ return group;
+ }
+
+ @DB
+ @Override
+ public AclGroup removeAclPoliciesFromGroup(final List<Long> policyIds, final Long groupId) {
+ // get the Acl Group entity
+ AclGroup 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) {
+ AclPolicy policy = _aclPolicyDao.findById(policyId);
+ if (policy == null) {
+ throw new InvalidParameterValueException("Unable to find acl policy: " + policyId
+ + "; failed to add policies to acl group.");
+ }
+
+ AclGroupPolicyMapVO grMap = _aclGroupPolicyMapDao.findByGroupAndPolicy(groupId, policyId);
+ if (grMap != null) {
+ // not removed yet
+ _aclGroupPolicyMapDao.remove(grMap.getId());
+ }
+ }
+ }
+ });
+ return group;
+ }
+
+ /*
+ @DB
+ @Override
+ @ActionEvent(eventType = EventTypes.EVENT_ACL_POLICY_GRANT, eventDescription = "Granting permission to Acl Role")
+ public AclP addAclPermissionToAclPolicy(final long aclRoleId, final List<String> apiNames) {
+ Account caller = CallContext.current().getCallingAccount();
+ // get the Acl Role entity
+ AclRole role = _aclPolicyDao.findById(aclRoleId);
+ if (role == null) {
+ throw new InvalidParameterValueException("Unable to find acl role: " + aclRoleId
+ + "; failed to grant permission to role.");
+ }
+ // check permissions
+ _accountMgr.checkAccess(caller, null, true, role);
+
+ Transaction.execute(new TransactionCallbackNoReturn() {
+ @Override
+ public void doInTransactionWithoutResult(TransactionStatus status) {
+ // add entries in acl_api_permission table
+ for (String api : apiNames) {
+ AclApiPermissionVO perm = _apiPermissionDao.findByRoleAndApi(aclRoleId, api);
+ if (perm == null) {
+ // not there already
+ perm = new AclApiPermissionVO(aclRoleId, api);
+ _apiPermissionDao.persist(perm);
+ }
+ }
+ }
+ });
-
++
+ return role;
+
+ }
+
+ @DB
+ @Override
+ @ActionEvent(eventType = EventTypes.EVENT_ACL_POLICY_REVOKE, eventDescription = "Revoking permission from Acl Role")
+ public AclRole revokeApiPermissionFromAclRole(final long aclRoleId, final List<String> apiNames) {
+ Account caller = CallContext.current().getCallingAccount();
+ // get the Acl Role entity
+ AclRole role = _aclPolicyDao.findById(aclRoleId);
+ if (role == null) {
+ throw new InvalidParameterValueException("Unable to find acl role: " + aclRoleId
+ + "; failed to revoke permission from role.");
+ }
+ // check permissions
+ _accountMgr.checkAccess(caller, null, true, role);
+
+ Transaction.execute(new TransactionCallbackNoReturn() {
+ @Override
+ public void doInTransactionWithoutResult(TransactionStatus status) {
+ // remove entries from acl_api_permission table
+ for (String api : apiNames) {
+ AclApiPermissionVO perm = _apiPermissionDao.findByRoleAndApi(aclRoleId, api);
+ if (perm != null) {
+ // not removed yet
+ _apiPermissionDao.remove(perm.getId());
+ }
+ }
+ }
+ });
+ return role;
+ }
+ */
+
+ @DB
+ @Override
+ public AclPolicy addAclPermissionToAclPolicy(long aclPolicyId, String entityType, String scope, Long scopeId,
+ String action, String accessType, Permission perm) {
+ // get the Acl Policy entity
+ AclPolicy policy = _aclPolicyDao.findById(aclPolicyId);
+ if (policy == null) {
+ throw new InvalidParameterValueException("Unable to find acl policy: " + aclPolicyId
+ + "; failed to add permission to policy.");
+ }
+
+ // add entry in acl_policy_permission table
+ AclPolicyPermissionVO permit = _policyPermissionDao.findByPolicyAndEntity(aclPolicyId, entityType, scope, scopeId, action, perm);
+ if (permit == null) {
+ // not there already
+ permit = new AclPolicyPermissionVO(aclPolicyId, action, entityType, accessType, scope, scopeId, perm);
+ _policyPermissionDao.persist(permit);
+ }
+ return policy;
+
+ }
+
+ @DB
+ @Override
+ public AclPolicy removeAclPermissionFromAclPolicy(long aclPolicyId, String entityType, String scope, Long scopeId,
+ String action) {
+ // get the Acl Policy entity
+ AclPolicy policy = _aclPolicyDao.findById(aclPolicyId);
+ if (policy == null) {
+ throw new InvalidParameterValueException("Unable to find acl policy: " + aclPolicyId
+ + "; failed to revoke permission from policy.");
+ }
+ // remove entry from acl_entity_permission table
+ AclPolicyPermissionVO permit = _policyPermissionDao.findByPolicyAndEntity(aclPolicyId, entityType, scope, scopeId, action, null);
+ if (permit != null) {
+ // not removed yet
+ _policyPermissionDao.remove(permit.getId());
+ }
+ return policy;
+ }
+
+
+ @DB
+ @Override
+ public AclPolicy resetAclPolicy(long aclPolicyId) {
+ // get the Acl Policy entity
+ AclPolicy policy = _aclPolicyDao.findById(aclPolicyId);
+ if (policy == null) {
+ throw new InvalidParameterValueException("Unable to find acl policy: " + aclPolicyId
+ + "; failed to reset the policy.");
+ }
+
+ SearchBuilder<AclPolicyPermissionVO> sb = _policyPermissionDao.createSearchBuilder();
+ sb.and("policyId", sb.entity().getAclPolicyId(), SearchCriteria.Op.EQ);
+ sb.and("scope", sb.entity().getScope(), SearchCriteria.Op.EQ);
+ sb.done();
+ SearchCriteria<AclPolicyPermissionVO> permissionSC = sb.create();
+ permissionSC.setParameters("policyId", aclPolicyId);
+ _policyPermissionDao.expunge(permissionSC);
+
+ return policy;
+ }
+
+ @Override
+ public boolean isActionAllowedForPolicies(String action, List<AclPolicy> policies) {
+
+ boolean allowed = false;
+
+ List<Long> policyIds = new ArrayList<Long>();
+ for (AclPolicy policy : policies) {
+ policyIds.add(policy.getId());
+ }
+
+ SearchBuilder<AclPolicyPermissionVO> sb = _policyPermissionDao.createSearchBuilder();
+ sb.and("action", sb.entity().getAction(), Op.EQ);
+ sb.and("policyId", sb.entity().getAclPolicyId(), Op.IN);
+
+ SearchCriteria<AclPolicyPermissionVO> sc = sb.create();
+ sc.setParameters("policyId", policyIds.toArray(new Object[policyIds.size()]));
+ sc.setParameters("action", action);
+
+ List<AclPolicyPermissionVO> 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<AclPolicy> policies = listAclPolicies(accountId);
+ // for each policy, find granted permission within the given scope
+ List<Long> entityIds = new ArrayList<Long>();
+ for (AclPolicy policy : policies) {
+ List<AclPolicyPermissionVO> pp = _policyPermissionDao.listGrantedByActionAndScope(policy.getId(), action,
+ scope);
+ if (pp != null) {
+ for (AclPolicyPermissionVO p : pp) {
+ if (p.getScopeId() != null) {
+ entityIds.add(p.getScopeId());
+ }
+ }
+ }
+ }
+ return entityIds;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public List<AclPolicyPermission> listPolicyPermissions(long policyId) {
+ @SuppressWarnings("rawtypes")
+ List pp = _policyPermissionDao.listByPolicy(policyId);
+ return pp;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<AclPolicyPermission> listPolicyPermissionsByScope(long policyId, String action, String scope) {
+ @SuppressWarnings("rawtypes")
+ List pp = _policyPermissionDao.listGrantedByActionAndScope(policyId, action, scope);
+ return pp;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<AclPolicyPermission> listPolicyPermissionByEntityType(long policyId, String action, String entityType) {
+ @SuppressWarnings("rawtypes")
+ List pp = _policyPermissionDao.listByPolicyActionAndEntity(policyId, action, entityType);
+ return pp;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<AclPolicyPermission> listPolicyPermissionByAccessType(long policyId, String accessType, String entityType, String action) {
+ @SuppressWarnings("rawtypes")
+ List pp = _policyPermissionDao.listByPolicyAccessAndEntity(policyId, accessType, entityType, action);
+ return pp;
+ }
-
++
+ @Override
+ public AclPolicy getResourceOwnerPolicy() {
+ return _aclPolicyDao.findByName("RESOURCE_OWNER");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/929fbaba/services/iam/server/test/org/apache/cloudstack/iam/IAMServiceUnitTest.java
----------------------------------------------------------------------
diff --cc services/iam/server/test/org/apache/cloudstack/iam/IAMServiceUnitTest.java
index 437b0ea,0000000..5b1e57b
mode 100644,000000..100644
--- a/services/iam/server/test/org/apache/cloudstack/iam/IAMServiceUnitTest.java
+++ b/services/iam/server/test/org/apache/cloudstack/iam/IAMServiceUnitTest.java
@@@ -1,209 -1,0 +1,205 @@@
+// 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 static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.junit.After;
- import org.apache.cloudstack.test.utils.SpringUtils;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.ComponentScan.Filter;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.FilterType;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.core.type.filter.TypeFilter;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
- import com.cloud.exception.InvalidParameterValueException;
-
+import org.apache.cloudstack.iam.api.AclGroup;
+import org.apache.cloudstack.iam.api.AclPolicy;
+import org.apache.cloudstack.iam.api.IAMService;
- import org.apache.cloudstack.iam.server.AclGroupAccountMapVO;
+import org.apache.cloudstack.iam.server.AclGroupVO;
+import org.apache.cloudstack.iam.server.AclPolicyVO;
+import org.apache.cloudstack.iam.server.IAMServiceImpl;
+import org.apache.cloudstack.iam.server.dao.AclGroupAccountMapDao;
+import org.apache.cloudstack.iam.server.dao.AclGroupDao;
+import org.apache.cloudstack.iam.server.dao.AclGroupPolicyMapDao;
+import org.apache.cloudstack.iam.server.dao.AclPolicyDao;
+import org.apache.cloudstack.iam.server.dao.AclPolicyPermissionDao;
++import org.apache.cloudstack.test.utils.SpringUtils;
++
++import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.db.EntityManager;
- import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
- import com.cloud.utils.db.SearchCriteria.Op;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
+public class IAMServiceUnitTest {
+
+ @Inject
+ IAMService _iamService;
+
+ @Inject
+ AclPolicyDao _aclPolicyDao;
+
+ @Inject
+ AclGroupDao _aclGroupDao;
+
+ @Inject
+ EntityManager _entityMgr;
+
+ @Inject
+ AclGroupPolicyMapDao _aclGroupPolicyMapDao;
+
+ @Inject
+ AclGroupAccountMapDao _aclGroupAccountMapDao;
+
+ @Inject
- AclPolicyPermissionDao _policyPermissionDao;
-
-
++ AclPolicyPermissionDao _policyPermissionDao;
++
+ @BeforeClass
+ public static void setUpClass() throws ConfigurationException {
+ }
+
+ @Before
+ public void setUp() {
+ ComponentContext.initComponentsLifeCycle();
+ AclGroupVO group = new AclGroupVO("group1", "my first group");
+ Mockito.when(_aclGroupDao.persist(Mockito.any(AclGroupVO.class))).thenReturn(group);
+ List<AclGroupVO> groups = new ArrayList<AclGroupVO>();
+ groups.add(group);
+ when(_aclGroupDao.search(Mockito.any(SearchCriteria.class), Mockito.any(com.cloud.utils.db.Filter.class)))
+ .thenReturn(groups);
+
+ AclPolicyVO policy = new AclPolicyVO("policy1", "my first policy");
+ Mockito.when(_aclPolicyDao.persist(Mockito.any(AclPolicyVO.class))).thenReturn(policy);
+
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ @Test(expected = InvalidParameterValueException.class)
+ public void createAclGroupTest() {
+ AclGroup group = _iamService.createAclGroup("group1", "my first group", "/root/mydomain");
+ assertNotNull("Acl group 'group1' failed to create ", group);
+
+ AclGroupVO group2 = new AclGroupVO("group1", "my second group");
+ when(_aclGroupDao.findByName(eq("/root/mydomain"), eq("group1"))).thenReturn(group2);
+
+ AclGroup group3 = _iamService.createAclGroup("group1", "my first group", "/root/mydomain");
+ }
+
+ @Test(expected = InvalidParameterValueException.class)
- public void deleteAclGroupInvalidIdTest(){
++ public void deleteAclGroupInvalidIdTest() {
+ when(_aclGroupDao.findById(20L)).thenReturn(null);
+ _iamService.deleteAclGroup(20L);
+ }
+
+ @Test
+ public void accountGroupMaptest() {
+ // create group
+ AclGroupVO group = new AclGroupVO("group1", "my first group");
+
+ // add account to group
+ List<Long> accountIds = new ArrayList<Long>();
+ accountIds.add(100L);
+ when(_aclGroupDao.findById(20L)).thenReturn(group);
+ _iamService.addAccountsToGroup(accountIds, 20L);
+
+ _iamService.removeAccountsFromGroup(accountIds, 20L);
+ }
+
+ @Test(expected = InvalidParameterValueException.class)
+ public void createAclPolicyTest() {
+ AclPolicy policy = _iamService.createAclPolicy("policy1", "my first policy", null);
+ assertNotNull("Acl policy 'policy1' failed to create ", policy);
+
+ AclPolicyVO rvo = new AclPolicyVO("policy2", "second policy");
+ when(_aclPolicyDao.findByName(eq("policy2"))).thenReturn(rvo);
+
+ _iamService.createAclPolicy("policy2", "second policy", null);
+ }
+
+ @Test(expected = InvalidParameterValueException.class)
+ public void deleteAclPolicyInvalidIdTest() {
+ when(_aclPolicyDao.findById(34L)).thenReturn(null);
+ _iamService.deleteAclPolicy(34L);
+ }
+
+ @Configuration
- @ComponentScan(basePackageClasses = { IAMServiceImpl.class }, includeFilters = { @Filter(value = TestConfiguration.Library.class, type = FilterType.CUSTOM) }, useDefaultFilters = false)
++ @ComponentScan(basePackageClasses = {IAMServiceImpl.class}, includeFilters = {@Filter(value = TestConfiguration.Library.class, type = FilterType.CUSTOM)}, useDefaultFilters = false)
+ public static class TestConfiguration extends SpringUtils.CloudStackTestConfiguration {
+
+ @Bean
+ public AclPolicyDao aclPolicyDao() {
+ return Mockito.mock(AclPolicyDao.class);
+ }
+
+ @Bean
+ public AclGroupDao aclGroupDao() {
+ return Mockito.mock(AclGroupDao.class);
+ }
+
+ @Bean
+ public EntityManager entityManager() {
+ return Mockito.mock(EntityManager.class);
+ }
+
+ @Bean
+ public AclGroupPolicyMapDao aclGroupPolicyMapDao() {
+ return Mockito.mock(AclGroupPolicyMapDao.class);
+ }
+
+ @Bean
+ public AclGroupAccountMapDao aclGroupAccountMapDao() {
+ return Mockito.mock(AclGroupAccountMapDao.class);
+ }
+
+ @Bean
- public AclPolicyPermissionDao aclPolicyPermissionDao() {
- return Mockito.mock(AclPolicyPermissionDao.class);
- }
-
++ public AclPolicyPermissionDao aclPolicyPermissionDao() {
++ return Mockito.mock(AclPolicyPermissionDao.class);
++ }
++
+ public static class Library implements TypeFilter {
+
+ @Override
+ public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
+ ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class);
+ return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/929fbaba/services/pom.xml
----------------------------------------------------------------------
diff --cc services/pom.xml
index fb6d71d,0e61a61..24b8e62
--- a/services/pom.xml
+++ b/services/pom.xml
@@@ -24,12 -24,15 +24,13 @@@
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack</artifactId>
- <version>4.3.0-SNAPSHOT</version>
+ <version>4.4.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <build>
- <defaultGoal>install</defaultGoal>
- </build>
<modules>
<module>console-proxy</module>
+ <module>console-proxy-rdp/rdpconsole</module>
<module>secondary-storage</module>
+ <module>iam</module>
</modules>
</project>