From b2e916acd09165d288affa256d66b97496870fa0 Mon Sep 17 00:00:00 2001 From: Sanjay Dalal Date: Fri, 11 Jun 2010 19:09:27 +0000 Subject: [PATCH] CSPACE-595 added a test for multi-tenancy. it uses two pre-configured users in ROLE_TEANAT_ADMINISTRATOR to create an account, a role and a permission for a service for each tenant. It then creates (potentially concurrently) dimension object as the newly created user for a tenant, tries to update the other tenant's object and fails successfully, tries to delete the other tenant's object and fails successfully. test: MultiTenancyTest, all service tests M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleJpaFilter.java M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionJpaFilter.java M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/AuthorizationDelegate.java M services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleDocumentHandler.java M services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageUtils.java M services/common/src/main/java/org/collectionspace/services/common/security/SecurityUtils.java M services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountDocumentHandler.java M services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountJpaFilter.java A services/security/client/src/test/java/org/collectionspace/services/security/client/test/MultiTenancyTest.java --- .../storage/AccountDocumentHandler.java | 5 +- .../account/storage/AccountJpaFilter.java | 29 +- .../storage/AuthorizationDelegate.java | 35 +- .../storage/PermissionDocumentHandler.java | 5 +- .../storage/PermissionJpaFilter.java | 12 +- .../storage/PermissionRoleUtil.java | 25 +- .../storage/RoleDocumentHandler.java | 6 +- .../authorization/storage/RoleJpaFilter.java | 12 +- .../common/security/SecurityUtils.java | 19 + .../common/storage/jpa/JpaStorageUtils.java | 13 +- .../client/test/MultiTenancyTest.java | 891 ++++++++++++++++++ 11 files changed, 1027 insertions(+), 25 deletions(-) create mode 100644 services/security/client/src/test/java/org/collectionspace/services/security/client/test/MultiTenancyTest.java diff --git a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountDocumentHandler.java b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountDocumentHandler.java index 7fcc775af..454f19c49 100644 --- a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountDocumentHandler.java +++ b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountDocumentHandler.java @@ -37,6 +37,7 @@ import org.collectionspace.services.common.document.AbstractDocumentHandlerImpl; import org.collectionspace.services.common.document.DocumentFilter; import org.collectionspace.services.common.document.DocumentWrapper; import org.collectionspace.services.common.document.JaxbUtils; +import org.collectionspace.services.common.security.SecurityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -212,7 +213,9 @@ public class AccountDocumentHandler */ private void sanitize(AccountsCommon account) { account.setPassword(null); - account.setTenants(new ArrayList(0)); + if (!SecurityUtils.isCSpaceAdmin()) { + account.setTenants(new ArrayList(0)); + } } /* (non-Javadoc) diff --git a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountJpaFilter.java b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountJpaFilter.java index eaa84856f..8cae96383 100644 --- a/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountJpaFilter.java +++ b/services/account/service/src/main/java/org/collectionspace/services/account/storage/AccountJpaFilter.java @@ -28,6 +28,7 @@ import java.util.ArrayList; import java.util.List; import org.collectionspace.services.common.storage.jpa.JpaDocumentFilter; import org.collectionspace.services.common.context.ServiceContext; +import org.collectionspace.services.common.security.SecurityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,9 +53,16 @@ public class AccountJpaFilter extends JpaDocumentFilter { if (null != snvals && snvals.size() > 0) { screenName = snvals.get(0); } - queryStrBldr.append(addTenant(false, paramList)); + boolean csAdmin = SecurityUtils.isCSpaceAdmin(); + if (!csAdmin) { + queryStrBldr.append(addTenant(false, paramList)); + } if (null != screenName && !screenName.isEmpty()) { - queryStrBldr.append(" AND"); + if (!csAdmin) { + queryStrBldr.append(" AND"); + } else { + queryStrBldr.append(" WHERE"); + } queryStrBldr.append(" UPPER(a." + AccountStorageConstants.SCREEN_NAME + ")"); queryStrBldr.append(" LIKE"); queryStrBldr.append(" :" + AccountStorageConstants.Q_SCREEN_NAME); @@ -68,7 +76,11 @@ public class AccountJpaFilter extends JpaDocumentFilter { uid = uidvals.get(0); } if (null != uid && !uid.isEmpty()) { - queryStrBldr.append(" AND"); + if (!csAdmin) { + queryStrBldr.append(" AND"); + } else { + queryStrBldr.append(" WHERE"); + } queryStrBldr.append(" UPPER(a." + AccountStorageConstants.USER_ID + ")"); queryStrBldr.append(" LIKE"); queryStrBldr.append(" :" + AccountStorageConstants.Q_USER_ID); @@ -83,14 +95,18 @@ public class AccountJpaFilter extends JpaDocumentFilter { } if (null != email && !email.isEmpty()) { - queryStrBldr.append(" AND"); + if (!csAdmin) { + queryStrBldr.append(" AND"); + } else { + queryStrBldr.append(" WHERE"); + } queryStrBldr.append(" UPPER(a." + AccountStorageConstants.EMAIL + ")"); queryStrBldr.append(" LIKE"); queryStrBldr.append(" :" + AccountStorageConstants.Q_EMAIL); paramList.add(new ParamBinding(AccountStorageConstants.Q_EMAIL, "%" + email.toUpperCase() + "%")); } - + if (logger.isDebugEnabled()) { String query = queryStrBldr.toString(); logger.debug("query=" + query); @@ -106,8 +122,9 @@ public class AccountJpaFilter extends JpaDocumentFilter { @Override protected String addTenant(boolean append, List paramList) { + String tenantId = getTenantId(); String whereClause = " JOIN a.tenants as at WHERE at.tenantId = :tenantId"; - paramList.add(new ParamBinding("tenantId", getTenantId())); + paramList.add(new ParamBinding("tenantId", tenantId)); return whereClause; } } diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/AuthorizationDelegate.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/AuthorizationDelegate.java index b103b552a..0b02e44db 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/AuthorizationDelegate.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/AuthorizationDelegate.java @@ -35,6 +35,7 @@ import org.collectionspace.services.authorization.PermissionAction; import org.collectionspace.services.authorization.PermissionException; import org.collectionspace.services.authorization.PermissionRole; import org.collectionspace.services.authorization.PermissionValue; +import org.collectionspace.services.authorization.Role; import org.collectionspace.services.authorization.RoleValue; import org.collectionspace.services.authorization.SubjectType; import org.collectionspace.services.authorization.URIResourceImpl; @@ -80,12 +81,19 @@ public class AuthorizationDelegate { } } else if (SubjectType.PERMISSION.equals(subject)) { RoleValue rv = pr.getRoles().get(0); + Role r = getRole(rv.getRoleId()); + if (r == null) { + String msg = "addPermissions: No role found for id=" + rv.getRoleId(); + logger.error(msg); + throw new DocumentNotFoundException(msg); + } String[] roles = {rv.getRoleName()}; for (PermissionValue pv : pr.getPermissions()) { Permission p = getPermission(pv.getPermissionId()); if (p == null) { String msg = "addPermissions: No permission found for id=" + pv.getPermissionId(); logger.error(msg); + //TODO: would be nice contiue to still send 400 back continue; } CSpaceResource[] resources = getResources(p); @@ -155,10 +163,14 @@ public class AuthorizationDelegate { private static String[] getRoles(List rvl) { List rvls = new ArrayList(); for (RoleValue rv : rvl) { - //assumption: rolename is relationship metadata is mandatory - if (rv.getRoleName() != null) { - rvls.add(rv.getRoleName()); + Role r = getRole(rv.getRoleId()); + if (r == null) { + String msg = "getRoles: No role found for id=" + rv.getRoleId(); + logger.error(msg); + //TODO: would be nice contiue to still send 400 back + continue; } + rvls.add(r.getRoleName()); } return rvls.toArray(new String[0]); } @@ -174,9 +186,14 @@ public class AuthorizationDelegate { List rl = new ArrayList(); for (PermissionAction pa : p.getActions()) { - - CSpaceResource res = new URIResourceImpl(p.getResourceName(), - getAction(pa.getName())); + CSpaceResource res = null; + if (p.getTenantId() == null) { + res = new URIResourceImpl(p.getResourceName(), + getAction(pa.getName())); + } else { + res = new URIResourceImpl(p.getTenantId(), p.getResourceName(), + getAction(pa.getName())); + } rl.add(res); } return rl.toArray(new CSpaceResource[0]); @@ -188,6 +205,12 @@ public class AuthorizationDelegate { return p; } + private static Role getRole(String roleCsid) { + Role r = (Role) JpaStorageUtils.getEntity(roleCsid, + Role.class); + return r; + } + /** * getAction is a convenience method to get corresponding action for * given ActionType diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java index d2b16e465..025294873 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionDocumentHandler.java @@ -36,6 +36,7 @@ import org.collectionspace.services.common.document.BadRequestException; import org.collectionspace.services.common.document.DocumentFilter; import org.collectionspace.services.common.document.DocumentWrapper; import org.collectionspace.services.common.document.JaxbUtils; +import org.collectionspace.services.common.security.SecurityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -197,7 +198,9 @@ public class PermissionDocumentHandler * @param permission */ private void sanitize(Permission permission) { - permission.setTenantId(null); + if (!SecurityUtils.isCSpaceAdmin()) { + permission.setTenantId(null); + } } private void setTenant(Permission permission) { diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionJpaFilter.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionJpaFilter.java index cfe69cf12..8a57775b1 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionJpaFilter.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionJpaFilter.java @@ -27,6 +27,7 @@ package org.collectionspace.services.authorization.storage; import java.util.ArrayList; import java.util.List; import org.collectionspace.services.common.context.ServiceContext; +import org.collectionspace.services.common.security.SecurityUtils; import org.collectionspace.services.common.storage.jpa.JpaDocumentFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,9 +59,16 @@ public class PermissionJpaFilter extends JpaDocumentFilter { if (null != rn && rn.size() > 0) { resName = rn.get(0); } - queryStrBldr.append(addTenant(false, paramList)); + boolean csAdmin = SecurityUtils.isCSpaceAdmin(); + if (!csAdmin) { + queryStrBldr.append(addTenant(false, paramList)); + } if (null != resName && !resName.isEmpty()) { - queryStrBldr.append(" AND"); + if (!csAdmin) { + queryStrBldr.append(" AND"); + } else { + queryStrBldr.append(" WHERE"); + } queryStrBldr.append(" UPPER(a." + PermissionStorageConstants.RESOURCE_NAME + ")"); queryStrBldr.append(" LIKE"); queryStrBldr.append(" :" + PermissionStorageConstants.Q_RESOURCE_NAME); diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java index 6af23e53c..4a3da1578 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/PermissionRoleUtil.java @@ -23,6 +23,7 @@ */ package org.collectionspace.services.authorization.storage; +import java.util.HashMap; import java.util.List; import org.collectionspace.services.authorization.PermissionRole; import org.collectionspace.services.authorization.PermissionRoleRel; @@ -31,6 +32,7 @@ import org.collectionspace.services.authorization.RoleValue; import org.collectionspace.services.authorization.SubjectType; import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.common.context.ServiceContextProperties; +import org.collectionspace.services.common.storage.jpa.JpaStorageUtils; /** * @@ -82,7 +84,7 @@ public class PermissionRoleUtil { } } } - + static private PermissionRoleRel buildPermissonRoleRel(PermissionValue pv, RoleValue rv) { PermissionRoleRel prr = new PermissionRoleRel(); prr.setPermissionId(pv.getPermissionId()); @@ -91,4 +93,25 @@ public class PermissionRoleUtil { prr.setRoleName(rv.getRoleName()); return prr; } + + static boolean isInvalidTenant(String tenantId, StringBuilder msgBldr) { + boolean invalid = false; + + if (tenantId == null || tenantId.isEmpty()) { + invalid = true; + msgBldr.append("\n tenant : tenantId is missing"); + } + String whereClause = "where id = :id"; + HashMap params = new HashMap(); + params.put("id", tenantId); + + Object tenantFound = JpaStorageUtils.getEntity( + "org.collectionspace.services.account.Tenant", whereClause, params); + if (tenantFound == null) { + invalid = true; + msgBldr.append("\n tenant : tenantId=" + tenantId + + " not found"); + } + return invalid; + } } diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleDocumentHandler.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleDocumentHandler.java index 0171d0325..7be60a26c 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleDocumentHandler.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleDocumentHandler.java @@ -24,7 +24,6 @@ package org.collectionspace.services.authorization.storage; import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.UUID; @@ -36,6 +35,7 @@ import org.collectionspace.services.common.document.BadRequestException; import org.collectionspace.services.common.document.DocumentFilter; import org.collectionspace.services.common.document.DocumentWrapper; import org.collectionspace.services.common.document.JaxbUtils; +import org.collectionspace.services.common.security.SecurityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -180,7 +180,9 @@ public class RoleDocumentHandler * @param roleFound */ private void sanitize(Role role) { - role.setTenantId(null); + if (!SecurityUtils.isCSpaceAdmin()) { + role.setTenantId(null); + } } private String fixRoleName(String role) { diff --git a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleJpaFilter.java b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleJpaFilter.java index 35751bb44..483baa9a3 100644 --- a/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleJpaFilter.java +++ b/services/authorization-mgt/service/src/main/java/org/collectionspace/services/authorization/storage/RoleJpaFilter.java @@ -27,6 +27,7 @@ import java.util.ArrayList; import java.util.List; import org.collectionspace.services.common.storage.jpa.JpaDocumentFilter; import org.collectionspace.services.common.context.ServiceContext; +import org.collectionspace.services.common.security.SecurityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,9 +52,16 @@ public class RoleJpaFilter extends JpaDocumentFilter { if (null != rn && rn.size() > 0) { roleName = rn.get(0); } - queryStrBldr.append(addTenant(false, paramList)); + boolean csAdmin = SecurityUtils.isCSpaceAdmin(); + if (!csAdmin) { + queryStrBldr.append(addTenant(false, paramList)); + } if (null != roleName && !roleName.isEmpty()) { - queryStrBldr.append(" AND"); + if (!csAdmin) { + queryStrBldr.append(" AND"); + } else { + queryStrBldr.append(" WHERE"); + } queryStrBldr.append(" UPPER(a." + RoleStorageConstants.ROLE_NAME + ")"); queryStrBldr.append(" LIKE"); queryStrBldr.append(" :" + RoleStorageConstants.Q_ROLE_NAME); diff --git a/services/common/src/main/java/org/collectionspace/services/common/security/SecurityUtils.java b/services/common/src/main/java/org/collectionspace/services/common/security/SecurityUtils.java index c7e8d46db..de57be1ad 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/security/SecurityUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/common/security/SecurityUtils.java @@ -22,6 +22,7 @@ */ package org.collectionspace.services.common.security; +import org.collectionspace.authentication.AuthN; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -66,4 +67,22 @@ public class SecurityUtils { throw new IllegalArgumentException(msg); } } + + /** + * isCSpaceAdmin check if authenticated user is a CSpace administrator + * @param tenantId + * @return + */ + public static boolean isCSpaceAdmin() { + String tenantId = AuthN.get().getCurrentTenantId(); + if (tenantId != null) { + if (!"0".equals(tenantId)) { + return false; + } else { + return true; + } + } else { + return false; + } + } } diff --git a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageUtils.java b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageUtils.java index e387baa85..dac25d852 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageUtils.java @@ -24,13 +24,12 @@ package org.collectionspace.services.common.storage.jpa; import java.util.HashMap; -import java.util.List; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.NoResultException; import javax.persistence.Persistence; import javax.persistence.Query; -import org.collectionspace.services.common.document.DocumentFilter; +import org.collectionspace.services.common.security.SecurityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -110,13 +109,19 @@ public class JpaStorageUtils { StringBuilder queryStrBldr = new StringBuilder("SELECT a FROM "); queryStrBldr.append(entityName); queryStrBldr.append(" a"); - queryStrBldr.append(" WHERE csid = :csid AND tenantId = :tenantId"); + queryStrBldr.append(" WHERE csid = :csid"); + boolean csAdmin = SecurityUtils.isCSpaceAdmin(); + if (!csAdmin) { + queryStrBldr.append(" AND tenantId = :tenantId"); + } emf = getEntityManagerFactory(); em = emf.createEntityManager(); String queryStr = queryStrBldr.toString(); //for debugging Query q = em.createQuery(queryStr); q.setParameter("csid", id); - q.setParameter("tenantId", tenantId); + if (!csAdmin) { + q.setParameter("tenantId", tenantId); + } o = q.getSingleResult(); } catch (NoResultException nre) { if (em != null && em.getTransaction().isActive()) { diff --git a/services/security/client/src/test/java/org/collectionspace/services/security/client/test/MultiTenancyTest.java b/services/security/client/src/test/java/org/collectionspace/services/security/client/test/MultiTenancyTest.java new file mode 100644 index 000000000..75075ecbf --- /dev/null +++ b/services/security/client/src/test/java/org/collectionspace/services/security/client/test/MultiTenancyTest.java @@ -0,0 +1,891 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + + * http://www.collectionspace.org + * http://wiki.collectionspace.org + + * Copyright 2010 University of California at Berkeley + + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + + * You may obtain a copy of the ECL 2.0 License at + + * https://source.collectionspace.org/collection-space/LICENSE.txt + + * 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. + */ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.collectionspace.services.security.client.test; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Hashtable; +import java.util.List; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.collectionspace.services.account.AccountsCommon; +import org.collectionspace.services.authorization.AccountRole; +import org.collectionspace.services.authorization.AccountValue; +import org.collectionspace.services.authorization.ActionType; +import org.collectionspace.services.authorization.EffectType; + +import org.collectionspace.services.authorization.Permission; +import org.collectionspace.services.authorization.PermissionAction; +import org.collectionspace.services.authorization.PermissionRole; +import org.collectionspace.services.authorization.PermissionValue; +import org.collectionspace.services.authorization.Role; +import org.collectionspace.services.authorization.RoleValue; +import org.collectionspace.services.client.AccountClient; +import org.collectionspace.services.client.AccountFactory; +import org.collectionspace.services.client.AccountRoleClient; +import org.collectionspace.services.client.AccountRoleFactory; +import org.collectionspace.services.client.CollectionSpaceClient; +import org.collectionspace.services.client.DimensionClient; +import org.collectionspace.services.client.DimensionFactory; +import org.collectionspace.services.client.PermissionClient; +import org.collectionspace.services.client.PermissionFactory; +import org.collectionspace.services.client.PermissionRoleClient; +import org.collectionspace.services.client.PermissionRoleFactory; +import org.collectionspace.services.client.RoleClient; +import org.collectionspace.services.client.RoleFactory; +import org.collectionspace.services.client.test.AbstractServiceTestImpl; +import org.collectionspace.services.dimension.DimensionsCommon; +import org.collectionspace.services.jaxb.AbstractCommonList; +import org.jboss.resteasy.client.ClientResponse; +import org.jboss.resteasy.plugins.providers.multipart.MultipartInput; +import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput; +import org.jboss.resteasy.plugins.providers.multipart.OutputPart; + +import org.testng.Assert; +import org.testng.annotations.Test; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; + +/** + * AuthorizationServiceTest, carries out tests against a + * deployed and running Permission, Role, AccountRole, PermissionRole and + * CollectionObject Services. + * + * Pre-requisite : authorization-mgt/client tests seed some permissions used + * by this test + * + * $LastChangedRevision: 917 $ + * $LastChangedDate: 2009-11-06 12:20:28 -0800 (Fri, 06 Nov 2009) $ + */ +public class MultiTenancyTest extends AbstractServiceTestImpl { + + private final String CLASS_NAME = MultiTenancyTest.class.getName(); + private final Logger logger = LoggerFactory.getLogger(CLASS_NAME); + private final static String TENANT_1_ADMIN_USER = "test"; + private final static String TENANT_2_ADMIN_USER = "test-pahma"; + private final static String TENANT_1_USER = "user1@museum1.org"; + private final static String TENANT_2_USER = "user2@museum2.org"; + private final static String TENANT_1 = "1"; + private final static String TENANT_2 = "2"; + private final static String TEST_ROLE_NAME = "ROLE_TEST_REGISTRAR"; + private final static String TEST_SERVICE_A = "dimensions"; + + private static class UserInfo { + + String userName; + String password; + + UserInfo(String u, String p) { + userName = u; + password = p; + } + } + // Instance variables specific to this test. + private String TENANT_RESOURCE_1 = null; + private String TENANT_RESOURCE_2 = null; + private List allResourceIdsCreated = new ArrayList(); + //key for userAccounts is userId + private Hashtable userAccounts = new Hashtable(); + //key for permValues is id as there could be several perms for the same resource + private Hashtable permValues = new Hashtable(); + //key for all tenantXXX tables is tenant id, expecting only one entity per tenant for this test + private Hashtable tenantAdminUsers = new Hashtable(); + private Hashtable tenantAccounts = new Hashtable(); + private Hashtable tenantRoles = new Hashtable(); + private Hashtable tenantAdminRoles = new Hashtable(); + private Hashtable tenantPermissions = new Hashtable(); + +// private String permId1; +// private String permId2; + + /* + * This method is called only by the parent class, AbstractServiceTestImpl + */ + @Override + protected String getServicePathComponent() { + return null; + } + + @BeforeClass(alwaysRun = true) + public void seedData() { + if (logger.isDebugEnabled()) { + testBanner("seedData", CLASS_NAME); + } + + //tenant admin users are used to create accounts, roles and permissions and relationships + //assumption : two tenant admin users exist before running this test + tenantAdminUsers.put(TENANT_1, new UserInfo(TENANT_1_ADMIN_USER, "test")); + tenantAdminUsers.put(TENANT_2, new UserInfo(TENANT_2_ADMIN_USER, "test")); + + seedAccounts(); + seedPermissions(); + seedRoles(); + seedAccountRoles(); + seedPermissionRoles(); + } + + private void seedAccounts() { + seedAccount(TENANT_1, TENANT_1_USER); + seedAccount(TENANT_2, TENANT_2_USER); + } + + private void seedAccount(String tenantId, String userId) { + //create account using default user in admin role but assign tenant id + //create username, email and password same for simplicity + String accId = createAccount(tenantId, userId, userId); + AccountValue ava = new AccountValue(); + ava.setScreenName(userId); + ava.setUserId(userId); + ava.setAccountId(accId); + userAccounts.put(ava.getUserId(), ava); + tenantAccounts.put(tenantId, ava); + if (logger.isDebugEnabled()) { + logger.debug("seedAccount tenantId=" + tenantId + " userId=" + userId); + } + } + + private void seedPermissions() { + String resource = TEST_SERVICE_A; + + PermissionAction pac = new PermissionAction(); + pac.setName(ActionType.CREATE); + PermissionAction par = new PermissionAction(); + par.setName(ActionType.READ); + PermissionAction pau = new PermissionAction(); + pau.setName(ActionType.UPDATE); + PermissionAction pad = new PermissionAction(); + pad.setName(ActionType.DELETE); + + //both users can create, read and update and delete + List testActions = new ArrayList(); + testActions.add(pac); + testActions.add(par); + testActions.add(pau); + testActions.add(pad); + + seedPermission(TENANT_1, resource, testActions, EffectType.PERMIT); + seedPermission(TENANT_2, resource, testActions, EffectType.PERMIT); + } + + private void seedPermission(String tenantId, + String resource, List testActions, EffectType effect) { + //create permission using default user in admin role but assign tenant id + String id = createPermission(tenantId, resource, testActions, effect); + PermissionValue pv = new PermissionValue(); + pv.setResourceName(resource); + pv.setPermissionId(id); + permValues.put(pv.getPermissionId(), pv); + tenantPermissions.put(tenantId, pv); + if (logger.isDebugEnabled()) { + logger.debug("seedPermission tenantId=" + tenantId + + " permId=" + id + " resource=" + resource); + } + } + + private void seedRoles() { + //create role using default user in admin role but assign tenant id + //use the same role name to check constraints + seedRole(TENANT_1, TEST_ROLE_NAME); + seedRole(TENANT_2, TEST_ROLE_NAME); + } + + private void seedRole(String tenantId, String roleName) { + String rid = createRole(tenantId, roleName); + RoleValue rv = new RoleValue(); + rv.setRoleId(rid); + rv.setRoleName(roleName); + tenantRoles.put(tenantId, rv); + if (logger.isDebugEnabled()) { + logger.debug("seedRole tenantId=" + tenantId + " roleName=" + roleName); + } + } + + private void seedAccountRoles() { + + for (String tenantId : tenantAccounts.keySet()) { + AccountValue av = (AccountValue) tenantAccounts.get(tenantId); + seedAccountRole(tenantId, av.getUserId()); + } + } + + private void seedAccountRole(String tenantId, String userId) { + List tenantRoleValues = new ArrayList(); + tenantRoleValues.add(tenantRoles.get(tenantId)); + createAccountRole(tenantId, userAccounts.get(userId), tenantRoleValues); + if (logger.isDebugEnabled()) { + logger.debug("seedAccountRole tenantId=" + tenantId + " userId=" + userId); + } + } + + private void seedPermissionRoles() { + + for (String tenantId : tenantPermissions.keySet()) { + PermissionValue pv = tenantPermissions.get(tenantId); + seedPermissionRole(tenantId, pv.getPermissionId()); + } + } + + private void seedPermissionRole(String tenantId, String permId) { + List tenantRoleValues = new ArrayList(); + tenantRoleValues.add(tenantRoles.get(tenantId)); + PermissionValue pv = permValues.get(permId); + createPermissionRole(tenantId, permValues.get(permId), tenantRoleValues); + if (logger.isDebugEnabled()) { + logger.debug("seedPermissionRole tenantId=" + tenantId + + " permId=" + permId + " resource=" + pv.getResourceName()); + } + } + + + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance() + */ + @Override + protected CollectionSpaceClient getClientInstance() { + return null; + } + + /* (non-Javadoc) + * @see org.collectionspace.services.client.test.BaseServiceTest#getAbstractCommonList(org.jboss.resteasy.client.ClientResponse) + */ + @Override + protected AbstractCommonList getAbstractCommonList( + ClientResponse response) { + //FIXME: http://issues.collectionspace.org/browse/CSPACE-1697 + throw new UnsupportedOperationException(); + } + + @Test(dataProvider = "testName") + @Override + public void readPaginatedList(String testName) throws Exception { + //FIXME: http://issues.collectionspace.org/browse/CSPACE-1697 + } + // --------------------------------------------------------------- + // CRUD tests : CREATE tests + // --------------------------------------------------------------- + // Success outcomes + + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class) + public void create(String testName) throws Exception { + if (logger.isDebugEnabled()) { + logger.debug(testBanner(testName, CLASS_NAME)); + } + + ClientResponse res = create(testName, TENANT_1_USER, TENANT_1); + + TENANT_RESOURCE_1 = extractId(res); + + if (logger.isDebugEnabled()) { + logger.debug(testName + ": tenantId= " + TENANT_1 + + " userId=" + TENANT_1_USER + + " TENANT_RESOURCE_1 id=" + TENANT_RESOURCE_1); + } + } + + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class) + public void create2(String testName) throws Exception { + if (logger.isDebugEnabled()) { + logger.debug(testBanner(testName, CLASS_NAME)); + } + + ClientResponse res = create(testName, TENANT_2_USER, TENANT_2); + + TENANT_RESOURCE_2 = extractId(res); + if (logger.isDebugEnabled()) { + logger.debug(testName + ": tenantId= " + TENANT_2 + + " userId=" + TENANT_2_USER + + " TENANT_RESOURCE_2 id=" + TENANT_RESOURCE_2); + } + } + + private ClientResponse create(String testName, String userName, String tenatnId) { + setupCreate(); + // Submit the request to the service and store the response. + DimensionClient client = new DimensionClient(); + client.setAuth(true, userName, true, userName, true); + String identifier = createIdentifier(); + DimensionsCommon dimension = new DimensionsCommon(); + dimension.setDimension("dimensionType"); + dimension.setValue("value-" + identifier); + dimension.setValueDate(new Date().toString()); + MultipartOutput multipart = DimensionFactory.createDimensionInstance(client.getCommonPartName(), + dimension); + ClientResponse res = client.create(multipart); + int statusCode = res.getStatus(); + + if (logger.isDebugEnabled()) { + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, Response.Status.CREATED.getStatusCode()); + return res; + + } + + //to not cause uniqueness violation for permRole, createList is removed + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"create"}) + public void createList(String testName) throws Exception { + } + + // Failure outcomes + // Placeholders until the three tests below can be uncommented. + // See Issue CSPACE-401. + @Override + public void createWithEmptyEntityBody(String testName) throws Exception { + } + + @Override + public void createWithMalformedXml(String testName) throws Exception { + } + + @Override + public void createWithWrongXmlSchema(String testName) throws Exception { + } + + // --------------------------------------------------------------- + // CRUD tests : READ tests + // --------------------------------------------------------------- + // Success outcomes + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"create"}) + public void read(String testName) throws Exception { + + if (logger.isDebugEnabled()) { + logger.debug(testBanner(testName, CLASS_NAME)); + } + DimensionsCommon dimension = read(testName, TENANT_RESOURCE_1, TENANT_1_USER); + Assert.assertNotNull(dimension); + if (logger.isDebugEnabled()) { + logger.debug(testName + ": tenantId= " + TENANT_1 + + " userId=" + TENANT_1_USER + + " TENANT_RESOURCE_1 retrieved id=" + dimension.getCsid()); + } + } + + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"create2"}) + public void read2(String testName) throws Exception { + + if (logger.isDebugEnabled()) { + logger.debug(testBanner(testName, CLASS_NAME)); + } + DimensionsCommon dimension = read(testName, TENANT_RESOURCE_2, TENANT_2_USER); + Assert.assertNotNull(dimension); + if (logger.isDebugEnabled()) { + logger.debug(testName + ": tenantId= " + TENANT_2 + + " userId=" + TENANT_2_USER + + " TENANT_RESOURCE_1 retrieved id=" + dimension.getCsid()); + } + } + + private DimensionsCommon read(String testName, String id, String userName) throws Exception { + setupRead(); + // Submit the request to the service and store the response. + DimensionClient client = new DimensionClient(); + client.setAuth(true, userName, true, userName, true); + ClientResponse res = client.read(id); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if (logger.isDebugEnabled()) { + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + + MultipartInput input = (MultipartInput) res.getEntity(); + return (DimensionsCommon) extractPart(input, + client.getCommonPartName(), DimensionsCommon.class); + } + // Failure outcomes + + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class) + public void readNonExistent(String testName) throws Exception { + + // Perform setup. + setupReadNonExistent(); + } + + // --------------------------------------------------------------- + // CRUD tests : READ_LIST tests + // --------------------------------------------------------------- + // Success outcomes + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"createList", "read"}) + public void readList(String testName) throws Exception { + setupReadList(); + } + + // Failure outcomes + // None at present. + // --------------------------------------------------------------- + // CRUD tests : UPDATE tests + // --------------------------------------------------------------- + // Success outcomes + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"read", "readList", "readNonExistent"}) + public void update(String testName) throws Exception { + setupUpdate(); + + } + + // Failure outcomes + // Placeholders until the three tests below can be uncommented. + // See Issue CSPACE-401. + @Override + public void updateWithEmptyEntityBody(String testName) throws Exception { + } + + @Override + public void updateWithMalformedXml(String testName) throws Exception { + } + + @Override + public void updateWithWrongXmlSchema(String testName) throws Exception { + } + + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"read2", "readNonExistent", "testSubmitRequest"}) + public void updateNonExistent(String testName) throws Exception { + + DimensionClient client = new DimensionClient(); + //TENANT_1_USER is not allowed to update the resource of TENANT_2 + client.setAuth(true, TENANT_1_USER, true, TENANT_1_USER, true); + + DimensionsCommon dimension = new DimensionsCommon(); + dimension.setDimension("dimensionType"); + // Update the content of this resource. + dimension.setValue("updated-" + dimension.getValue()); + dimension.setValueDate("updated-" + dimension.getValueDate()); + // Submit the request to the service and store the response. + MultipartOutput output = new MultipartOutput(); + OutputPart commonPart = output.addPart(dimension, MediaType.APPLICATION_XML_TYPE); + commonPart.getHeaders().add("label", client.getCommonPartName()); + + ClientResponse res = client.update(TENANT_RESOURCE_2, output); + int statusCode = res.getStatus(); + // Check the status code of the response: does it match the expected response(s)? + if (logger.isDebugEnabled()) { + logger.debug(testName + " resource = " + TENANT_RESOURCE_2 + + " status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + //going to incorrect Nuxeo domain would give DocumentNotFoundException + //instead of giving FORBIDDEN + Assert.assertEquals(statusCode, Response.Status.NOT_FOUND.getStatusCode()); + } + + // --------------------------------------------------------------- + // CRUD tests : DELETE tests + // --------------------------------------------------------------- + // Success outcomes + + + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"deleteNonExistent"}) + public void delete(String testName) throws Exception { + + if (logger.isDebugEnabled()) { + logger.debug(testBanner(testName, CLASS_NAME)); + } + + int statusCode = delete(testName, TENANT_RESOURCE_1, TENANT_1_USER); + } + + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"updateNonExistent"}) + public void delete2(String testName) throws Exception { + + if (logger.isDebugEnabled()) { + logger.debug(testBanner(testName, CLASS_NAME)); + } + int statusCode = delete(testName, TENANT_RESOURCE_2, TENANT_2_USER); + + } + + private int delete(String testName, String id, String userName) throws Exception { + // Perform setup. + setupDelete(); + // Submit the request to the service and store the response. + DimensionClient client = new DimensionClient(); + client.setAuth(true, userName, true, userName, true); + ClientResponse res = client.delete(id); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if (logger.isDebugEnabled()) { + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + return statusCode; + } + + // Failure outcomes + @Override + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"read"}) + public void deleteNonExistent(String testName) throws Exception { + //ignoring this test as the service side returns 200 now even if it does + //not find a record in the db + + if (logger.isDebugEnabled()) { + logger.debug(testBanner(testName, CLASS_NAME)); + } + // Perform setup. + setupDelete(); + + // Submit the request to the service and store the response. + DimensionClient client = new DimensionClient(); + //TENANT_2_USER of TENANT_2 is not allowed to delete the resource of TENANT_1 + client.setAuth(true, TENANT_2_USER, true, TENANT_2_USER, true); + ClientResponse res = client.delete(TENANT_RESOURCE_1); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if (logger.isDebugEnabled()) { + logger.debug(testName + ": status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + //going to incorrect Nuxeo domain would give DocumentNotFoundException + //instead of giving FORBIDDEN + Assert.assertEquals(statusCode, Response.Status.NOT_FOUND.getStatusCode()); + } + + // --------------------------------------------------------------- + // Utility tests : tests of code used in tests above + // --------------------------------------------------------------- + /** + * Tests the code for manually submitting data that is used by several + * of the methods above. + */ + @Test(dependsOnMethods = {"create"}) + public void testSubmitRequest() throws Exception { + } + + // --------------------------------------------------------------- + // Utility methods used by tests above + // --------------------------------------------------------------- + @AfterClass(alwaysRun = true) + public void cleanUp() { + if (logger.isDebugEnabled()) { + testBanner("cleanUp", CLASS_NAME); + } + setupDelete(); + String noTest = System.getProperty("noTestCleanup"); + if (Boolean.TRUE.toString().equalsIgnoreCase(noTest)) { + if (logger.isDebugEnabled()) { + logger.debug("Skipping Cleanup phase ..."); + } + return; + } + if (logger.isDebugEnabled()) { + logger.debug("Cleaning up temporary resources created for testing ..."); + } + + //tenant admin users are used to create accounts, roles and permissions and relationships + //assumption : two tenant admin users exist before running this test + + //FIXME delete on permission role deletes all roles associated with the permission + //this would delete association with ROLE_ADMINISTRATION too + //deletePermissionRoles(); + deleteAccountRoles(); + //FIXME delete on permission role deletes all roles associated with the permission + //this would delete association with ROLE_ADMINISTRATION too + //deletePermissions(); + deleteRoles(); + deleteAccounts(); + } + + private void deletePermissionRoles() { + + //first delete relationships between the entities + for (String tenantId : tenantPermissions.keySet()) { + PermissionValue pv = tenantPermissions.get(tenantId); + deletePermissionRole(tenantId, pv.getPermissionId()); + } + } + + private void deleteAccountRoles() { + for (String tenantId : tenantAccounts.keySet()) { + AccountValue av = tenantAccounts.get(tenantId); + deleteAccountRole(tenantId, av.getAccountId()); + } + } + + private void deletePermissions() { + for (String tenantId : tenantPermissions.keySet()) { + PermissionValue pv = tenantPermissions.get(tenantId); + deletePermission(tenantId, pv.getPermissionId()); + } + } + + private void deleteRoles() { + for (String tenantId : tenantRoles.keySet()) { + RoleValue rv = tenantRoles.get(tenantId); + deleteRole(tenantId, rv.getRoleId()); + } + } + + private void deleteAccounts() { + + for (String tenantId : tenantAccounts.keySet()) { + AccountValue av = tenantAccounts.get(tenantId); + deleteAccount(tenantId, av.getAccountId()); + } + } + + private String createPermission(String tenantId, String resName, + List actions, EffectType effect) { + setupCreate(); + PermissionClient permClient = new PermissionClient(); + UserInfo ui = tenantAdminUsers.get(tenantId); + permClient.setAuth(true, ui.userName, true, ui.password, true); + Permission permission = PermissionFactory.createPermissionInstance(resName, + "default permissions for " + resName, + actions, effect, true, true, true); + permission.setTenantId(tenantId); + ClientResponse res = permClient.create(permission); + int statusCode = res.getStatus(); + if (logger.isDebugEnabled()) { + logger.debug("createPermission: resName=" + resName + + " status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + res.releaseConnection(); + return extractId(res); + } + + private void deletePermission(String tenantId, String permId) { + setupDelete(); + PermissionClient permClient = new PermissionClient(); + UserInfo ui = tenantAdminUsers.get(tenantId); + permClient.setAuth(true, ui.userName, true, ui.password, true); + ClientResponse res = permClient.delete(permId); + int statusCode = res.getStatus(); + if (logger.isDebugEnabled()) { + logger.debug("deletePermission: delete permission id=" + + permId + " status=" + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + res.releaseConnection(); + } + + private String createRole(String tenantId, String roleName) { + setupCreate(); + RoleClient roleClient = new RoleClient(); + UserInfo ui = tenantAdminUsers.get(tenantId); + roleClient.setAuth(true, ui.userName, true, ui.password, true); + Role role = RoleFactory.createRoleInstance(roleName, + "role for " + roleName, true); + role.setTenantId(tenantId); + ClientResponse res = roleClient.create(role); + int statusCode = res.getStatus(); + if (logger.isDebugEnabled()) { + logger.debug("createRole: name=" + roleName + + " status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + res.releaseConnection(); + return extractId(res); + } + + private void deleteRole(String tenantId, String roleId) { + setupDelete(); + RoleClient roleClient = new RoleClient(); + UserInfo ui = tenantAdminUsers.get(tenantId); + roleClient.setAuth(true, ui.userName, true, ui.password, true); + ClientResponse res = roleClient.delete(roleId); + int statusCode = res.getStatus(); + if (logger.isDebugEnabled()) { + logger.debug("deleteRole: delete role id=" + roleId + + " status=" + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + res.releaseConnection(); + } + + private String createAccount(String tenantId, String userName, String email) { + setupCreate(); + AccountClient accountClient = new AccountClient(); + UserInfo ui = tenantAdminUsers.get(tenantId); + accountClient.setAuth(true, ui.userName, true, ui.password, true); + AccountsCommon account = AccountFactory.createAccountInstance( + userName, userName, userName, email, tenantId, + true, false, true, true); + ClientResponse res = accountClient.create(account); + int statusCode = res.getStatus(); + if (logger.isDebugEnabled()) { + logger.debug("createAccount: tenantId=" + tenantId + " userName=" + userName + + " status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + res.releaseConnection(); + return extractId(res); + } + + private void deleteAccount(String tenantId, String accId) { + setupDelete(); + AccountClient accClient = new AccountClient(); + UserInfo ui = tenantAdminUsers.get(tenantId); + accClient.setAuth(true, ui.userName, true, ui.password, true); + ClientResponse res = accClient.delete(accId); + int statusCode = res.getStatus(); + if (logger.isDebugEnabled()) { + logger.debug("deleteAccount: delete account id=" + + accId + " status=" + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + res.releaseConnection(); + } + + private String createAccountRole(String tenantId, AccountValue av, + Collection rvs) { + setupCreate(); + + // Submit the request to the service and store the response. + AccountRole accRole = AccountRoleFactory.createAccountRoleInstance( + av, rvs, true, true); + AccountRoleClient client = new AccountRoleClient(); + UserInfo ui = tenantAdminUsers.get(tenantId); + client.setAuth(true, ui.userName, true, ui.password, true); + ClientResponse res = client.create(av.getAccountId(), accRole); + int statusCode = res.getStatus(); + + if (logger.isDebugEnabled()) { + logger.debug("createAccountRole: status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + res.releaseConnection(); + return extractId(res); + } + + private void deleteAccountRole(String tenantId, String accountId) { + // Perform setup. + setupDelete(); + + // Submit the request to the service and store the response. + AccountRoleClient client = new AccountRoleClient(); + UserInfo ui = tenantAdminUsers.get(tenantId); + client.setAuth(true, ui.userName, true, ui.password, true); + ClientResponse res = client.delete( + accountId, "123"); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if (logger.isDebugEnabled()) { + logger.debug("deleteAccountRole: status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + res.releaseConnection(); + } + + private String createPermissionRole(String tenantId, PermissionValue pv, + Collection rvs) { + setupCreate(); + List rvls = new ArrayList(); + rvls.addAll(rvs); + PermissionRole permRole = PermissionRoleFactory.createPermissionRoleInstance( + pv, rvls, true, true); + PermissionRoleClient client = new PermissionRoleClient(); + UserInfo ui = tenantAdminUsers.get(tenantId); + client.setAuth(true, ui.userName, true, ui.password, true); + ClientResponse res = client.create(pv.getPermissionId(), permRole); + int statusCode = res.getStatus(); + + if (logger.isDebugEnabled()) { + logger.debug("createPermissionRole: status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + res.releaseConnection(); + return extractId(res); + } + + private void deletePermissionRole(String tenantId, String permId) { + + // Perform setup. + setupDelete(); + + // Submit the request to the service and store the response. + PermissionRoleClient client = new PermissionRoleClient(); + UserInfo ui = tenantAdminUsers.get(tenantId); + client.setAuth(true, ui.userName, true, ui.password, true); + ClientResponse res = client.delete(permId, "123"); + int statusCode = res.getStatus(); + + // Check the status code of the response: does it match + // the expected response(s)? + if (logger.isDebugEnabled()) { + logger.debug("deletePermissionRole : status = " + statusCode); + } + Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode), + invalidStatusCodeMessage(REQUEST_TYPE, statusCode)); + Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE); + res.releaseConnection(); + } +} -- 2.47.3