Search in sources :

Example 1 with TenantOrgList

use of com.emc.storageos.model.tenant.TenantOrgList in project coprhd-controller by CoprHD.

the class TenantsService method listSubTenants.

/**
 * List subtenants
 *
 * @param id the URN of a ViPR Tenant
 * @prereq none
 * @brief List subtenants
 * @return List of subtenants
 */
@GET
@Path("/{id}/subtenants")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public TenantOrgList listSubTenants(@PathParam("id") URI id) {
    StorageOSUser user = getUserFromContext();
    TenantOrg tenant = getTenantById(id, false);
    TenantOrgList list = new TenantOrgList();
    if (!TenantOrg.isRootTenant(tenant)) {
        // no subtenants if not root tenant
        throw APIException.methodNotAllowed.notSupportedForSubtenants();
    }
    NamedElementQueryResultList subtenants = new NamedElementQueryResultList();
    if (_permissionsHelper.userHasGivenRole(user, tenant.getId(), Role.SYSTEM_MONITOR, Role.TENANT_ADMIN, Role.SECURITY_ADMIN, Role.SYSTEM_ADMIN)) {
        _dbClient.queryByConstraint(ContainmentConstraint.Factory.getTenantOrgSubTenantConstraint(tenant.getId()), subtenants);
    } else {
        // we will most likely not need indexing for tenants
        // given the number of tenants is not going to be that many
        Set<String> roles = new HashSet<String>();
        roles.add(Role.TENANT_ADMIN.toString());
        Map<URI, Set<String>> allTenantPermissions = _permissionsHelper.getAllPermissionsForUser(user, tenant.getId(), roles, true);
        if (!allTenantPermissions.keySet().isEmpty()) {
            List<TenantOrg> tenants = _dbClient.queryObjectField(TenantOrg.class, "label", new ArrayList<URI>(allTenantPermissions.keySet()));
            List<NamedElementQueryResultList.NamedElement> elements = new ArrayList<NamedElementQueryResultList.NamedElement>(tenants.size());
            for (TenantOrg t : tenants) {
                elements.add(NamedElementQueryResultList.NamedElement.createElement(t.getId(), t.getLabel()));
            }
            subtenants.setResult(elements.iterator());
        } else {
            throw APIException.forbidden.insufficientPermissionsForUser(user.getName());
        }
    }
    for (NamedElementQueryResultList.NamedElement el : subtenants) {
        list.getSubtenants().add(toNamedRelatedResource(ResourceTypeEnum.TENANT, el.getId(), el.getName()));
    }
    return list;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) AbstractChangeTrackingSet(com.emc.storageos.db.client.model.AbstractChangeTrackingSet) StringSet(com.emc.storageos.db.client.model.StringSet) ArrayList(java.util.ArrayList) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) StorageOSUser(com.emc.storageos.security.authentication.StorageOSUser) TenantOrg(com.emc.storageos.db.client.model.TenantOrg) TenantOrgList(com.emc.storageos.model.tenant.TenantOrgList) NamedElementQueryResultList(com.emc.storageos.db.client.constraint.NamedElementQueryResultList) HashSet(java.util.HashSet) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET)

Example 2 with TenantOrgList

use of com.emc.storageos.model.tenant.TenantOrgList in project coprhd-controller by CoprHD.

the class ResourceService method checkForDuplicateNamespace.

/**
 * Check if a tenant with the same namespace exists
 * @param namespace     namespace of the tenant
 */
public void checkForDuplicateNamespace(String namespace) {
    TenantOrgList list = new TenantOrgList();
    // Verify with root tenant if current is not root
    TenantOrg rootTenant = _permissionsHelper.getRootTenant();
    if (rootTenant.getNamespace() != null && rootTenant.getNamespace().equalsIgnoreCase(namespace)) {
        throw APIException.badRequests.duplicateNamespace(namespace);
    }
    NamedElementQueryResultList subtenants = new NamedElementQueryResultList();
    _dbClient.queryByConstraint(ContainmentConstraint.Factory.getTenantOrgSubTenantConstraint(rootTenant.getId()), subtenants);
    for (NamedElementQueryResultList.NamedElement el : subtenants) {
        TenantOrg currTenant = _dbClient.queryObject(TenantOrg.class, el.getId());
        if (currTenant.getNamespace() != null && currTenant.getNamespace().equalsIgnoreCase(namespace)) {
            throw APIException.badRequests.duplicateNamespace(namespace);
        }
    }
}
Also used : TenantOrg(com.emc.storageos.db.client.model.TenantOrg) TenantOrgList(com.emc.storageos.model.tenant.TenantOrgList) NamedElementQueryResultList(com.emc.storageos.db.client.constraint.NamedElementQueryResultList)

Example 3 with TenantOrgList

use of com.emc.storageos.model.tenant.TenantOrgList in project coprhd-controller by CoprHD.

the class ApiTest method usageAclTests.

/**
 * Cos and VirtualArray acls tests
 */
public void usageAclTests() {
    TenantResponse tenantResp = rSys.path("/tenant").get(TenantResponse.class);
    rootTenantId = tenantResp.getTenant();
    String subtenant_url = "/tenants/" + rootTenantId.toString() + "/subtenants";
    TenantOrgList list = rSys.path(subtenant_url).get(TenantOrgList.class);
    Assert.assertEquals(4, list.getSubtenants().size());
    NamedRelatedResourceRep st1 = list.getSubtenants().get(0);
    NamedRelatedResourceRep st2 = list.getSubtenants().get(1);
    // create neighborhoods for test
    VirtualArrayCreateParam neighborhoodParam = new VirtualArrayCreateParam();
    neighborhoodParam.setLabel("n1");
    VirtualArrayRestRep n1 = rSys.path("/vdc/varrays").post(VirtualArrayRestRep.class, neighborhoodParam);
    Assert.assertNotNull(n1.getId());
    neighborhoodParam.setLabel("n2");
    VirtualArrayRestRep n2 = rSys.path("/vdc/varrays").post(VirtualArrayRestRep.class, neighborhoodParam);
    Assert.assertNotNull(n2.getId());
    // test open to all by default
    ClientResponse resp = rSTAdmin1.path("/vdc/varrays/" + n1.getId().toString()).get(ClientResponse.class);
    Assert.assertEquals(200, resp.getStatus());
    resp = rSTAdmin2.path("/vdc/varrays/" + n1.getId().toString()).get(ClientResponse.class);
    Assert.assertEquals(200, resp.getStatus());
    // set usage acl for st1 on n1
    String neighborAclUrl = "/vdc/varrays/%s/acl";
    ACLAssignmentChanges changes = new ACLAssignmentChanges();
    ACLEntry entry1 = new ACLEntry();
    entry1.setTenant(st1.getId().toString());
    entry1.setAces(new ArrayList<String>());
    entry1.getAces().add("USE");
    changes.setAdd(new ArrayList<ACLEntry>());
    changes.getAdd().add(entry1);
    resp = rSys.path(String.format(neighborAclUrl, n1.getId().toString())).put(ClientResponse.class, changes);
    Assert.assertEquals(200, resp.getStatus());
    VirtualArrayRestRep nRead = rSTAdmin1.path("/vdc/varrays/" + n1.getId().toString()).get(VirtualArrayRestRep.class);
    Assert.assertEquals(nRead.getId(), n1.getId());
    Assert.assertEquals(nRead.getName(), n1.getName());
    resp = rSTAdmin2.path("/vdc/varrays/" + n1.getId().toString()).get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
    // set usage acl for st2 on n2
    changes = new ACLAssignmentChanges();
    ACLEntry entry2 = new ACLEntry();
    entry2.setTenant(st2.getId().toString());
    entry2.setAces(new ArrayList<String>());
    entry2.getAces().add("USE");
    changes.setAdd(new ArrayList<ACLEntry>());
    changes.getAdd().add(entry2);
    resp = rSys.path(String.format(neighborAclUrl, n2.getId().toString())).put(ClientResponse.class, changes);
    Assert.assertEquals(200, resp.getStatus());
    nRead = rSTAdmin2.path("/vdc/varrays/" + n2.getId().toString()).get(VirtualArrayRestRep.class);
    Assert.assertEquals(nRead.getId(), n2.getId());
    Assert.assertEquals(nRead.getName(), n2.getName());
    resp = rSTAdmin1.path("/vdc/varrays/" + n2.getId().toString()).get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
    // negative test - invalid tenant id
    changes = new ACLAssignmentChanges();
    entry2 = new ACLEntry();
    entry2.setTenant("invalid");
    entry2.setAces(new ArrayList<String>());
    entry2.getAces().add("USE");
    changes.setAdd(new ArrayList<ACLEntry>());
    changes.getAdd().add(entry2);
    resp = rSys.path(String.format(neighborAclUrl, n2.getId().toString())).put(ClientResponse.class, changes);
    Assert.assertEquals(400, resp.getStatus());
    // negative test - missing ace
    changes = new ACLAssignmentChanges();
    entry2 = new ACLEntry();
    entry2.setTenant(st2.getId().toString());
    entry2.setAces(new ArrayList<String>());
    changes.setAdd(new ArrayList<ACLEntry>());
    changes.getAdd().add(entry2);
    resp = rSys.path(String.format(neighborAclUrl, n2.getId().toString())).put(ClientResponse.class, changes);
    Assert.assertEquals(400, resp.getStatus());
    // negative test - choice of tenant/group/subject_id (multiple present)
    changes = new ACLAssignmentChanges();
    entry2 = new ACLEntry();
    entry2.setTenant(st2.getId().toString());
    entry2.setGroup("TEST");
    entry2.setAces(new ArrayList<String>());
    entry2.getAces().add("USE");
    changes.setAdd(new ArrayList<ACLEntry>());
    changes.getAdd().add(entry2);
    resp = rSys.path(String.format(neighborAclUrl, n2.getId().toString())).put(ClientResponse.class, changes);
    Assert.assertEquals(400, resp.getStatus());
    changes = new ACLAssignmentChanges();
    entry2 = new ACLEntry();
    entry2.setTenant(st2.getId().toString());
    entry2.setSubjectId("TEST");
    entry2.setAces(new ArrayList<String>());
    entry2.getAces().add("USE");
    changes.setAdd(new ArrayList<ACLEntry>());
    changes.getAdd().add(entry2);
    resp = rSys.path(String.format(neighborAclUrl, n2.getId().toString())).put(ClientResponse.class, changes);
    Assert.assertEquals(400, resp.getStatus());
    changes = new ACLAssignmentChanges();
    entry2 = new ACLEntry();
    entry2.setTenant(st2.getId().toString());
    entry2.setGroup("TEST");
    entry2.setSubjectId("TEST");
    entry2.setAces(new ArrayList<String>());
    entry2.getAces().add("USE");
    changes.setAdd(new ArrayList<ACLEntry>());
    changes.getAdd().add(entry2);
    resp = rSys.path(String.format(neighborAclUrl, n2.getId().toString())).put(ClientResponse.class, changes);
    Assert.assertEquals(400, resp.getStatus());
    // list neighborhoods
    VirtualArrayList nList = rSTAdminGr1.path("/vdc/varrays/").get(VirtualArrayList.class);
    Assert.assertEquals(1, nList.getVirtualArrays().size());
    Assert.assertEquals(n1.getId(), nList.getVirtualArrays().get(0).getId());
    // newly created varray, accessible for all
    neighborhoodParam = new VirtualArrayCreateParam();
    neighborhoodParam.setLabel("n3");
    VirtualArrayRestRep n3 = rSys.path("/vdc/varrays").post(VirtualArrayRestRep.class, neighborhoodParam);
    Assert.assertNotNull(n3.getId());
    nList = rSTAdminGr1.path("/vdc/varrays/").get(VirtualArrayList.class);
    Assert.assertEquals(2, nList.getVirtualArrays().size());
    Assert.assertTrue(nList.getVirtualArrays().get(0).getId().equals(n1.getId()) || nList.getVirtualArrays().get(1).getId().equals(n1.getId()));
    Assert.assertTrue(nList.getVirtualArrays().get(0).getId().equals(n3.getId()) || nList.getVirtualArrays().get(1).getId().equals(n3.getId()));
    // delete nh3
    rSys.path("/vdc/varrays/" + n3.getId().toString() + "/deactivate").post();
    // create vpool
    BlockVirtualPoolParam paramCosBlock = new BlockVirtualPoolParam();
    paramCosBlock.setName("foobar-block");
    paramCosBlock.setDescription("foobar-block description");
    paramCosBlock.setProtocols(new HashSet<String>());
    paramCosBlock.getProtocols().add(StorageProtocol.Block.FC.name());
    paramCosBlock.setMaxPaths(2);
    paramCosBlock.setProvisionType("Thick");
    BlockVirtualPoolRestRep cos1 = rZAdmin.path("/block/vpools").post(BlockVirtualPoolRestRep.class, paramCosBlock);
    Assert.assertNotNull(cos1.getId());
    resp = rZAdmin.path("/block/vpools").post(ClientResponse.class, paramCosBlock);
    Assert.assertEquals(400, resp.getStatus());
    resp = rSTAdmin1.path("/block/vpools/" + cos1.getId().toString()).get(ClientResponse.class);
    Assert.assertEquals(200, resp.getStatus());
    resp = rSTAdmin2.path("/block/vpools/" + cos1.getId().toString()).get(ClientResponse.class);
    Assert.assertEquals(200, resp.getStatus());
    // negative test: assign an empty storage pool
    VirtualPoolPoolUpdateParam paramPoolUpdate = new VirtualPoolPoolUpdateParam();
    paramPoolUpdate.setStoragePoolAssignmentChanges(new StoragePoolAssignmentChanges());
    paramPoolUpdate.getStoragePoolAssignmentChanges().setAdd(new StoragePoolAssignments());
    paramPoolUpdate.getStoragePoolAssignmentChanges().getAdd().setStoragePools(new HashSet<String>());
    paramPoolUpdate.getStoragePoolAssignmentChanges().getAdd().getStoragePools().add("");
    resp = rZAdmin.path("/block/vpools/" + cos1.getId().toString() + "/assign-matched-pools/").put(ClientResponse.class, paramPoolUpdate);
    Assert.assertEquals(400, resp.getStatus());
    // Set Cos acl
    changes = new ACLAssignmentChanges();
    changes.setAdd(new ArrayList<ACLEntry>());
    changes.getAdd().add(entry1);
    resp = rSys.path(String.format(_blockCosAclUrl, cos1.getId().toString())).put(ClientResponse.class, changes);
    Assert.assertEquals(200, resp.getStatus());
    resp = rSys.path(String.format(_fileCosAclUrl, cos1.getId().toString())).get(ClientResponse.class);
    Assert.assertEquals(400, resp.getStatus());
    BlockVirtualPoolRestRep cRead = rSTAdmin1.path("/block/vpools/" + cos1.getId().toString()).get(BlockVirtualPoolRestRep.class);
    Assert.assertEquals(cRead.getId(), cos1.getId());
    Assert.assertEquals(cRead.getName(), cos1.getName());
    resp = rSTAdmin2.path("/block/vpools/" + cos1.getId().toString()).get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
    // create second CoS
    paramCosBlock = new BlockVirtualPoolParam();
    paramCosBlock.setName("foobar-block2");
    paramCosBlock.setDescription("foobar-block2 description");
    paramCosBlock.setProtocols(new HashSet<String>());
    paramCosBlock.getProtocols().add(StorageProtocol.Block.FC.name());
    paramCosBlock.setProvisionType("Thick");
    BlockVirtualPoolRestRep cos2 = rZAdminGr.path("/block/vpools").post(BlockVirtualPoolRestRep.class, paramCosBlock);
    Assert.assertNotNull(cos2.getId());
    // list vpool
    VirtualPoolList cList = rSTAdminGr1.path("/block/vpools/").get(VirtualPoolList.class);
    Assert.assertEquals(2, cList.getVirtualPool().size());
    Assert.assertTrue(cList.getVirtualPool().get(0).getId().equals(cos1.getId()) || cList.getVirtualPool().get(1).getId().equals(cos1.getId()));
    Assert.assertTrue(cList.getVirtualPool().get(0).getId().equals(cos2.getId()) || cList.getVirtualPool().get(1).getId().equals(cos2.getId()));
    cList = rSTAdmin2.path("/block/vpools/").get(VirtualPoolList.class);
    Assert.assertEquals(1, cList.getVirtualPool().size());
    Assert.assertEquals(cos2.getId(), cList.getVirtualPool().get(0).getId());
    // test limits
    for (int i = 0; i < 100; i++) {
        changes = new ACLAssignmentChanges();
        entry1.setTenant(st2.getId().toString());
        changes.setAdd(new ArrayList<ACLEntry>());
        changes.getAdd().add(entry1);
        resp = rSys.path(String.format(_blockCosAclUrl, cos2.getId().toString())).put(ClientResponse.class, changes);
        Assert.assertEquals(200, resp.getStatus());
    }
    changes = new ACLAssignmentChanges();
    entry1.setTenant("tenant_invalid");
    changes.setAdd(new ArrayList<ACLEntry>());
    changes.getAdd().add(entry1);
    resp = rSys.path(String.format(_blockCosAclUrl, cos2.getId().toString())).put(ClientResponse.class, changes);
    Assert.assertEquals(400, resp.getStatus());
    // testing tags
    String cosTagUrl = "/block/vpools/%s/tags";
    TagAssignment tags = new TagAssignment();
    tags.setAdd(new StringSet());
    tags.getAdd().add("testtag1");
    resp = rSTAdmin2.path(String.format(cosTagUrl, cos1.getId())).put(ClientResponse.class, tags);
    Assert.assertEquals(403, resp.getStatus());
    Tags tagsResp = rSys.path(String.format(cosTagUrl, cos1.getId())).put(Tags.class, tags);
    Assert.assertTrue(tagsResp.getTag().equals(tags.getAdd()));
    tags.setRemove(new StringSet());
    tags.getRemove().addAll(new HashSet(tags.getAdd()));
    // invalid tag, too short
    tags.getAdd().add("t");
    resp = rSys.path(String.format(cosTagUrl, cos1.getId())).put(ClientResponse.class, tags);
    Assert.assertEquals(400, resp.getStatus());
    tags.getAdd().clear();
    // invalid tag, too long
    tags.getAdd().add("tag" + STR144);
    resp = rSys.path(String.format(cosTagUrl, cos1.getId())).put(ClientResponse.class, tags);
    Assert.assertEquals(400, resp.getStatus());
    tags.getAdd().clear();
    // tags should be trimmed
    tags.getAdd().add(" testtag  ");
    tagsResp = rSys.path(String.format(cosTagUrl, cos1.getId())).put(Tags.class, tags);
    Assert.assertTrue(tagsResp.getTag().equals(new StringSet() {

        {
            add("testtag");
        }
    }));
    resp = rSTAdmin2.path(String.format(cosTagUrl, cos1.getId())).get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
    resp = rSTAdmin1.path(String.format(cosTagUrl, cos1.getId())).get(ClientResponse.class);
    Assert.assertEquals(200, resp.getStatus());
    // Test bad parameter is returned if we add an invalid varray while creating the VirtualPool
    FileVirtualPoolParam paramFileCos = new FileVirtualPoolParam();
    paramFileCos.setName("Generic File VirtualPool");
    paramFileCos.setProtocols(new HashSet<String>());
    paramFileCos.getProtocols().add(StorageProtocol.File.NFS.name());
    paramFileCos.getProtocols().add(StorageProtocol.File.CIFS.name());
    paramFileCos.setVarrays(new HashSet<String>());
    paramFileCos.getVarrays().add("IDontExist");
    resp = rZAdmin.path("/file/vpools").post(ClientResponse.class, paramFileCos);
    Assert.assertEquals(400, resp.getStatus());
    // below is vpool restricted to tenant test
    /*
         * test setup:
         * create a varray and vpool and associate the vpool with the varray
         * restrict the vpool to the tenant
         */
    String vaLabel = "va-testTenantRestrictAccess-" + Calendar.getInstance().getTime().getTime();
    String vpLabel = "vp-testTenantRestrictAccess-" + Calendar.getInstance().getTime().getTime();
    // create a varray
    VirtualArrayCreateParam vaParam = new VirtualArrayCreateParam();
    vaParam.setLabel(vaLabel);
    BlockSettings bs = new BlockSettings();
    bs.setAutoSanZoning(true);
    vaParam.setBlockSettings(bs);
    VirtualArrayRestRep va1 = rSys.path("/vdc/varrays").post(VirtualArrayRestRep.class, vaParam);
    // create a vpool associated with the varray
    BlockVirtualPoolParam vpParam = new BlockVirtualPoolParam();
    vpParam.setName(vpLabel);
    vpParam.setDescription(vpLabel);
    Set<String> vas = new HashSet<String>();
    vas.add(va1.getId().toString());
    vpParam.setVarrays(vas);
    vpParam.setProvisionType("Thin");
    Set<String> protos = new HashSet();
    protos.add("FC");
    vpParam.setProtocols(protos);
    BlockVirtualPoolRestRep vp1 = rSys.path("/block/vpools").post(BlockVirtualPoolRestRep.class, vpParam);
    // restrict the vpool to a tenant
    ACLAssignmentChanges aclChange = new ACLAssignmentChanges();
    List<ACLEntry> acls = new ArrayList<>();
    ACLEntry acl = new ACLEntry();
    acl.setTenant(subtenant2Id.toString());
    acl.setAces(new ArrayList<String>(Arrays.asList("USE")));
    acls.add(acl);
    aclChange.setAdd(acls);
    String uri = String.format("/block/vpools/%s/acl", vp1.getId());
    ACLAssignments aclAssignments = rSys.path(uri).put(ACLAssignments.class, aclChange);
    // test1: sysadmin can see vpool
    // test2: sysmonitor can see vpool
    String vpUri = String.format("/vdc/varrays/%s/vpools", va1.getId().toString());
    VirtualPoolList vpoolList = rSys.path(vpUri).get(VirtualPoolList.class);
    List<NamedRelatedVirtualPoolRep> vpools = vpoolList.getVirtualPool();
    boolean foundVpool = false;
    for (NamedRelatedVirtualPoolRep vpool : vpools) {
        if (vpool.getId().equals(vp1.getId())) {
            foundVpool = true;
            _log.info("user root can see the vpool {}", vp1.getName());
        }
    }
    Assert.assertTrue(foundVpool);
    // test3: tenant user can see vpool
    VirtualPoolList vpoolList2 = rST2User.path(vpUri).get(VirtualPoolList.class);
    List<NamedRelatedVirtualPoolRep> vpools2 = vpoolList2.getVirtualPool();
    foundVpool = false;
    for (NamedRelatedVirtualPoolRep vpool : vpools2) {
        if (vpool.getId().equals(vp1.getId())) {
            foundVpool = true;
            _log.info("user st2user can see the vpool {}", vp1.getName());
        }
    }
    Assert.assertTrue(foundVpool);
}
Also used : ClientResponse(com.sun.jersey.api.client.ClientResponse) VirtualPoolPoolUpdateParam(com.emc.storageos.model.vpool.VirtualPoolPoolUpdateParam) VirtualArrayList(com.emc.storageos.model.varray.VirtualArrayList) ArrayList(java.util.ArrayList) VirtualPoolList(com.emc.storageos.model.vpool.VirtualPoolList) NamedRelatedVirtualPoolRep(com.emc.storageos.model.vpool.NamedRelatedVirtualPoolRep) VirtualArrayRestRep(com.emc.storageos.model.varray.VirtualArrayRestRep) StringSet(com.emc.storageos.db.client.model.StringSet) VirtualArrayList(com.emc.storageos.model.varray.VirtualArrayList) BlockVirtualPoolRestRep(com.emc.storageos.model.vpool.BlockVirtualPoolRestRep) Tags(com.emc.storageos.model.search.Tags) HashSet(java.util.HashSet) StoragePoolAssignments(com.emc.storageos.model.vpool.StoragePoolAssignments) StoragePoolAssignmentChanges(com.emc.storageos.model.vpool.StoragePoolAssignmentChanges) FileVirtualPoolParam(com.emc.storageos.model.vpool.FileVirtualPoolParam) ACLAssignmentChanges(com.emc.storageos.model.auth.ACLAssignmentChanges) VirtualArrayCreateParam(com.emc.storageos.model.varray.VirtualArrayCreateParam) TagAssignment(com.emc.storageos.model.TagAssignment) NamedRelatedResourceRep(com.emc.storageos.model.NamedRelatedResourceRep) BlockSettings(com.emc.storageos.model.varray.BlockSettings) ACLEntry(com.emc.storageos.model.auth.ACLEntry) TenantOrgList(com.emc.storageos.model.tenant.TenantOrgList) ACLAssignments(com.emc.storageos.model.auth.ACLAssignments) BlockVirtualPoolParam(com.emc.storageos.model.vpool.BlockVirtualPoolParam) TenantResponse(com.emc.storageos.model.tenant.TenantResponse)

Example 4 with TenantOrgList

use of com.emc.storageos.model.tenant.TenantOrgList in project coprhd-controller by CoprHD.

the class ApiTest method tenantTests.

/**
 * tenant api tests
 *
 * @throws Exception
 */
private void tenantTests() throws Exception {
    /*
         * GET MY TENANT ID
         */
    TenantResponse tenantResp = rSys.path("/tenant").get(TenantResponse.class);
    rootTenantId = tenantResp.getTenant();
    /*
         * GET root tenant info
         */
    ClientResponse resp = rUnAuth.path("/tenants/" + rootTenantId.toString()).get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
    TenantOrgRestRep tenant = rSys.path("/tenants/" + rootTenantId.toString()).get(TenantOrgRestRep.class);
    Assert.assertTrue(tenant != null);
    Assert.assertTrue(tenant.getId().equals(rootTenantId));
    Assert.assertFalse(tenant.getUserMappings().isEmpty());
    // ensure the tenent org name is the same name as the tenant and the tenant's link points to
    // the appropriate refs
    Assert.assertTrue(tenant.getName().equals(tenantResp.getName()));
    Assert.assertTrue(("/tenants/" + tenant.getId()).equals(tenantResp.getSelfLink().getLinkRef().toString()));
    // Remove the mapping and add a domain only mapping to make sure it works
    TenantUpdateParam tenantUpdate = new TenantUpdateParam();
    tenantUpdate.setUserMappingChanges(new UserMappingChanges());
    tenantUpdate.getUserMappingChanges().setRemove(tenant.getUserMappings());
    tenantUpdate.getUserMappingChanges().setAdd(new ArrayList<UserMappingParam>());
    UserMappingParam rootDomainMapping = new UserMappingParam();
    rootDomainMapping.setDomain("sanity.local");
    tenantUpdate.getUserMappingChanges().getAdd().add(rootDomainMapping);
    tenantUpdate.setLabel(ROOTTENANT_NAME);
    String rootTenantBaseUrl = "/tenants/" + rootTenantId.toString();
    resp = rSys.path(rootTenantBaseUrl).put(ClientResponse.class, tenantUpdate);
    Assert.assertEquals(200, resp.getStatus());
    tenant = rSys.path(rootTenantBaseUrl).get(TenantOrgRestRep.class);
    Assert.assertFalse(tenant.getUserMappings().isEmpty());
    // as sysmonitor, verify we can access tenant quota
    resp = rMon.path(rootTenantBaseUrl + "/quota").get(ClientResponse.class);
    Assert.assertEquals(200, resp.getStatus());
    // try to delete the auth provider that has the sanity.local domain.
    // should fail with 400.
    resp = rSys.path("/vdc/admin/authnproviders/" + _goodADConfig.toString()).delete(ClientResponse.class);
    Assert.assertEquals(400, resp.getStatus());
    // try to add another domain to that provider and remove the sanity.local domain which is used. Should fail.
    AuthnUpdateParam updateParam = new AuthnUpdateParam();
    updateParam.getDomainChanges().getAdd().add("someotherdomain2.com");
    updateParam.getDomainChanges().getRemove().add("sanity.local");
    resp = rSys.path("/vdc/admin/authnproviders/" + _goodADConfig.toString()).put(ClientResponse.class, updateParam);
    Assert.assertEquals(400, resp.getStatus());
    // Make sure that all mappings can be cleared from root
    tenantUpdate.setUserMappingChanges(new UserMappingChanges());
    tenantUpdate.getUserMappingChanges().setRemove(tenant.getUserMappings());
    resp = rSys.path(rootTenantBaseUrl).put(ClientResponse.class, tenantUpdate);
    Assert.assertEquals(200, resp.getStatus());
    tenant = rSys.path(rootTenantBaseUrl).get(TenantOrgRestRep.class);
    Assert.assertEquals(0, tenant.getUserMappings().size());
    // test that updating the tenant with its own name doesn't cause problems (no op)
    TenantUpdateParam tenantUpdateNameOnly = new TenantUpdateParam();
    tenantUpdateNameOnly.setLabel(tenant.getName());
    resp = rSys.path(rootTenantBaseUrl).put(ClientResponse.class, tenantUpdateNameOnly);
    Assert.assertEquals(200, resp.getStatus());
    // test adding attribute with a value, then modifying that value (add/remove in same call)
    // jira 4220 had a problem, this would return 400
    // start by adding an attribute
    tenantUpdate = new TenantUpdateParam();
    tenantUpdate.setUserMappingChanges(new UserMappingChanges());
    tenantUpdate.getUserMappingChanges().setAdd(new ArrayList<UserMappingParam>());
    rootDomainMapping = new UserMappingParam();
    rootDomainMapping.setDomain("sanity.local");
    UserMappingAttributeParam rootAttr = new UserMappingAttributeParam();
    rootAttr.setKey("ou");
    rootAttr.setValues(Collections.singletonList("attri1"));
    rootDomainMapping.setAttributes(Collections.singletonList(rootAttr));
    tenantUpdate.getUserMappingChanges().getAdd().add(rootDomainMapping);
    tenantUpdate.setLabel(ROOTTENANT_NAME);
    resp = rSys.path(rootTenantBaseUrl).put(ClientResponse.class, tenantUpdate);
    Assert.assertEquals(200, resp.getStatus());
    // now modify (add and remove) this attribute
    tenantUpdate = new TenantUpdateParam();
    tenantUpdate.setUserMappingChanges(new UserMappingChanges());
    tenantUpdate.getUserMappingChanges().setRemove(new ArrayList<UserMappingParam>());
    tenantUpdate.getUserMappingChanges().setAdd(new ArrayList<UserMappingParam>());
    rootDomainMapping = new UserMappingParam();
    rootDomainMapping.setDomain("sanity.local");
    rootAttr = new UserMappingAttributeParam();
    rootAttr.setKey("ou");
    rootAttr.setValues(Collections.singletonList("attri1"));
    rootDomainMapping.setAttributes(Collections.singletonList(rootAttr));
    tenantUpdate.getUserMappingChanges().getRemove().add(rootDomainMapping);
    UserMappingParam rootDomainMapping2 = new UserMappingParam();
    rootDomainMapping2.setDomain("sanity.local");
    rootAttr = new UserMappingAttributeParam();
    rootAttr.setKey("ou");
    rootAttr.setValues(Collections.singletonList("attri1b"));
    rootDomainMapping2.setAttributes(Collections.singletonList(rootAttr));
    tenantUpdate.getUserMappingChanges().getAdd().add(rootDomainMapping2);
    tenantUpdate.setLabel(ROOTTENANT_NAME);
    resp = rSys.path(rootTenantBaseUrl).put(ClientResponse.class, tenantUpdate);
    Assert.assertEquals(200, resp.getStatus());
    // remove what we did
    tenantUpdate = new TenantUpdateParam();
    tenantUpdate.setUserMappingChanges(new UserMappingChanges());
    tenantUpdate.getUserMappingChanges().setRemove(new ArrayList<UserMappingParam>());
    tenantUpdate.getUserMappingChanges().setAdd(new ArrayList<UserMappingParam>());
    rootDomainMapping = new UserMappingParam();
    rootDomainMapping.setDomain("sanity.local");
    rootAttr = new UserMappingAttributeParam();
    rootAttr.setKey("ou");
    rootAttr.setValues(Collections.singletonList("attri1b"));
    rootDomainMapping.setAttributes(Collections.singletonList(rootAttr));
    tenantUpdate.getUserMappingChanges().getRemove().add(rootDomainMapping);
    tenantUpdate.setLabel(ROOTTENANT_NAME);
    resp = rSys.path(rootTenantBaseUrl).put(ClientResponse.class, tenantUpdate);
    Assert.assertEquals(200, resp.getStatus());
    // put the mapping back
    updateRootTenantAttrs();
    /*
         * GET, PUT Zone Roles
         */
    RoleAssignments assignments = rSys.path("/vdc/role-assignments").get(RoleAssignments.class);
    Assert.assertTrue(assignments.getAssignments().isEmpty());
    // full update - bad role
    RoleAssignmentChanges changes = new RoleAssignmentChanges();
    RoleAssignmentEntry entry1 = new RoleAssignmentEntry();
    entry1.setSubjectId(ZONEADMIN);
    entry1.getRoles().add("SECURITY_ADMIN");
    changes.setAdd(new ArrayList<RoleAssignmentEntry>());
    changes.getAdd().add(entry1);
    RoleAssignmentEntry entry2 = new RoleAssignmentEntry();
    entry2.setSubjectId(ROOTUSER2);
    entry2.getRoles().add("SYSTEM_ADMIN");
    changes.getAdd().add(entry2);
    RoleAssignmentEntry entry_bad = new RoleAssignmentEntry();
    entry_bad.setSubjectId(ZONEADMIN);
    entry_bad.getRoles().add("INVALID_ROLE");
    changes.getAdd().add(entry_bad);
    resp = rSys.path("/vdc/role-assignments").put(ClientResponse.class, changes);
    Assert.assertEquals(400, resp.getStatus());
    changes.getAdd().remove(2);
    entry_bad.setSubjectId("bad");
    entry_bad.getRoles().add("SECURITY_ADMIN");
    changes.getAdd().add(entry_bad);
    resp = rSys.path("/vdc/role-assignments").put(ClientResponse.class, changes);
    Assert.assertEquals(400, resp.getStatus());
    changes.getAdd().remove(2);
    // all good
    assignments = rSys.path("/vdc/role-assignments").put(RoleAssignments.class, changes);
    Assert.assertEquals(assignments.getAssignments().size(), 2);
    RoleAssignments readAssignments = rSys.path("/vdc/role-assignments").get(RoleAssignments.class);
    Assert.assertTrue(checkEqualsRoles(changes.getAdd(), readAssignments.getAssignments()));
    // check with whoami, that zadmin at this point, has security_admin
    userInfoCheckRoles(rZAdmin, new ArrayList<String>(Collections.singletonList("SECURITY_ADMIN")));
    RoleAssignmentEntry entry3 = new RoleAssignmentEntry();
    entry3.setSubjectId(ZONEADMIN);
    entry3.getRoles().add("SYSTEM_ADMIN");
    RoleAssignmentEntry entry4 = new RoleAssignmentEntry();
    entry4.setGroup(ZONEADMINS_GROUP);
    entry4.getRoles().add("SYSTEM_ADMIN");
    entry4.getRoles().add("TENANT_ADMIN");
    // partial update
    changes = new RoleAssignmentChanges();
    changes.setRemove(new ArrayList<RoleAssignmentEntry>());
    changes.getRemove().add(entry2);
    changes.setAdd(new ArrayList<RoleAssignmentEntry>());
    changes.getAdd().add(entry3);
    changes.getAdd().add(entry4);
    resp = rZAdmin.path("/vdc/role-assignments").put(ClientResponse.class, changes);
    Assert.assertEquals(400, resp.getStatus());
    changes.getAdd().remove(entry4);
    entry4.getRoles().remove("TENANT_ADMIN");
    changes.getAdd().add(entry4);
    readAssignments = rZAdmin.path("/vdc/role-assignments").put(RoleAssignments.class, changes);
    assignments = new RoleAssignments();
    entry3.getRoles().add("SECURITY_ADMIN");
    assignments.getAssignments().add(entry3);
    assignments.getAssignments().add(entry4);
    Assert.assertTrue(checkEqualsRoles(assignments.getAssignments(), readAssignments.getAssignments()));
    // try an update with missing role in the entry
    RoleAssignmentEntry entry4b = new RoleAssignmentEntry();
    entry4b.setGroup(ZONEADMINS_GROUP);
    changes.getAdd().add(entry4b);
    resp = rZAdmin.path("/vdc/role-assignments").put(ClientResponse.class, changes);
    Assert.assertEquals(400, resp.getStatus());
    // try to modify zone roles for local users, make sure that fails with 400
    RoleAssignmentChanges changes2 = new RoleAssignmentChanges();
    RoleAssignmentEntry rootTenantAdminUserEntry = new RoleAssignmentEntry();
    rootTenantAdminUserEntry.setSubjectId(SYSADMIN);
    rootTenantAdminUserEntry.getRoles().add("SECURITY_ADMIN");
    changes2.setAdd(new ArrayList<RoleAssignmentEntry>());
    changes2.getAdd().add(rootTenantAdminUserEntry);
    resp = rSys.path("/vdc/role-assignments").put(ClientResponse.class, changes2);
    Assert.assertEquals(400, resp.getStatus());
    changes2 = new RoleAssignmentChanges();
    changes2.setRemove(new ArrayList<RoleAssignmentEntry>());
    changes2.getRemove().add(rootTenantAdminUserEntry);
    resp = rSys.path("/vdc/role-assignments").put(ClientResponse.class, changes2);
    Assert.assertEquals(400, resp.getStatus());
    /*
         * GET/PUT/POST tenant roles
         */
    String roles_url_format = "/tenants/%s/role-assignments";
    assignments = rZAdmin.path(String.format(roles_url_format, rootTenantId.toString())).get(RoleAssignments.class);
    Assert.assertTrue(assignments.getAssignments().size() == 1);
    // - bad role
    entry1 = new RoleAssignmentEntry();
    entry1.setSubjectId(ROOTTENANTADMIN_FORASSIGNMENT);
    entry1.getRoles().add("TENANT_ADMIN");
    changes = new RoleAssignmentChanges();
    changes.setAdd(new ArrayList<RoleAssignmentEntry>());
    changes.getAdd().add(entry1);
    entry2 = new RoleAssignmentEntry();
    entry2.setSubjectId(ROOTUSER2);
    entry2.getRoles().add("TENANT_ADMIN");
    changes.getAdd().add(entry2);
    entry_bad = new RoleAssignmentEntry();
    entry_bad.setSubjectId("bad");
    entry_bad.getRoles().add("INVALID_ROLE");
    changes.getAdd().add(entry_bad);
    resp = rSys.path(String.format(roles_url_format, rootTenantId.toString())).put(ClientResponse.class, assignments);
    Assert.assertEquals(400, resp.getStatus());
    changes.getAdd().remove(2);
    // zone system admin can not do tenant admin stuff
    resp = rZAdminGr.path(String.format(roles_url_format, rootTenantId.toString())).put(ClientResponse.class, changes);
    Assert.assertEquals(403, resp.getStatus());
    // - all good
    // this will remove sysadmin's tenant_admin role on root
    rootTenantAdminUserEntry = new RoleAssignmentEntry();
    rootTenantAdminUserEntry.setSubjectId(SYSADMIN);
    rootTenantAdminUserEntry.getRoles().add("TENANT_ADMIN");
    changes.setRemove(new ArrayList<RoleAssignmentEntry>());
    changes.getRemove().add(rootTenantAdminUserEntry);
    readAssignments = rZAdmin.path(String.format(roles_url_format, rootTenantId.toString())).put(RoleAssignments.class, changes);
    Assert.assertTrue(checkEqualsRoles(changes.getAdd(), readAssignments.getAssignments()));
    // check with whoami, that root user2 at this point, has tenant_admin
    userInfoCheckRoles(rRootUser2, new ArrayList<String>(Collections.singletonList("TENANT_ADMIN")));
    // partial update
    resp = rTAdmin.path("/tenant").get(ClientResponse.class);
    Assert.assertEquals(200, resp.getStatus());
    RoleAssignmentEntry entry3t = new RoleAssignmentEntry();
    entry3t.setSubjectId(ROOTTENANTADMIN_FORASSIGNMENT);
    entry3t.getRoles().add("PROJECT_ADMIN");
    RoleAssignmentEntry entry4t = new RoleAssignmentEntry();
    entry4t.setGroup(TENANT_ADMINS_GROUP);
    entry4t.getRoles().add("TENANT_ADMIN");
    changes = new RoleAssignmentChanges();
    changes.setRemove(new ArrayList<RoleAssignmentEntry>());
    changes.getRemove().add(entry2);
    changes.setAdd(new ArrayList<RoleAssignmentEntry>());
    changes.getAdd().add(entry3t);
    changes.getAdd().add(entry4t);
    readAssignments = rTAdmin.path(String.format(roles_url_format, rootTenantId.toString())).put(RoleAssignments.class, changes);
    assignments = new RoleAssignments();
    entry3t.getRoles().add("TENANT_ADMIN");
    assignments.getAssignments().add(entry3t);
    assignments.getAssignments().add(entry4t);
    Assert.assertTrue(checkEqualsRoles(assignments.getAssignments(), readAssignments.getAssignments()));
    // verify Tenant Admin permission for admins on root tenant
    readAssignments = rTAdminGr.path(String.format(roles_url_format, rootTenantId.toString())).get(RoleAssignments.class);
    Assert.assertTrue(checkEqualsRoles(assignments.getAssignments(), readAssignments.getAssignments()));
    RoleAssignments vdcReadAssignments = rZAdmin.path("/vdc/role-assignments").get(RoleAssignments.class);
    // try to add more than 100 roles - this should fail (quickly, because
    // it's not validating)
    changes = new RoleAssignmentChanges();
    changes.setAdd(new ArrayList<RoleAssignmentEntry>());
    // since 2.0, should exclude the vdc roles here since they are in NOT in tenant db.
    int currRolesCount = readAssignments.getAssignments().size();
    int rolesToAdd = _maxRoleAclEntries + 1 - currRolesCount;
    for (int i = 0; i < rolesToAdd; i++) {
        entry_bad = new RoleAssignmentEntry();
        entry_bad.setRoles(new ArrayList<String>());
        entry_bad.getRoles().add(Role.TENANT_ADMIN.toString());
        entry_bad.setSubjectId("invalidUser" + i + "@invalidDomain.com");
        changes.getAdd().add(entry_bad);
    }
    resp = rTAdminGr.path(String.format(roles_url_format, rootTenantId.toString())).put(ClientResponse.class, changes);
    final String message = String.format("Exceeding limit of %d role assignments with %d", _maxRoleAclEntries, _maxRoleAclEntries + 1);
    assertExpectedError(resp, 400, ServiceCode.API_EXCEEDING_ASSIGNMENT_LIMIT, message);
    // verify zone roles here, to test out role filtering code
    assignments = new RoleAssignments();
    assignments.getAssignments().add(entry3);
    assignments.getAssignments().add(entry4);
    readAssignments = rZAdmin.path("/vdc/role-assignments").get(RoleAssignments.class);
    Assert.assertTrue(checkEqualsRoles(assignments.getAssignments(), readAssignments.getAssignments()));
    /*
         * Before creating subtenant try to log in
         * as subtenant user and verify that it fails with
         * 403 because the user does not map to a tenant
         */
    resp = rSTAdmin1.path("/login").get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
    /*
         * CREATE subtenants
         */
    String subtenant_url = rootTenantBaseUrl + "/subtenants";
    TenantCreateParam tenantParam = new TenantCreateParam();
    String subtenant1_label = "subtenant1";
    tenantParam.setLabel(subtenant1_label);
    tenantParam.setDescription("first subtenant");
    tenantParam.setUserMappings(new ArrayList<UserMappingParam>());
    UserMappingParam tenantMapping1 = new UserMappingParam();
    tenantMapping1.setDomain("bad_domain.com");
    // add user mapping with domain only. Should fail because it conflicts with an existing mapping
    resp = rTAdminGr.path(subtenant_url).post(ClientResponse.class, tenantParam);
    Assert.assertEquals(400, resp.getStatus());
    tenantMapping1.setDomain("sanity.LOCAL");
    // add user mapping with domain only. Should fail because it conflicts with an existing mapping
    resp = rTAdminGr.path(subtenant_url).post(ClientResponse.class, tenantParam);
    Assert.assertEquals(400, resp.getStatus());
    // Add an attribute scope to the mapping
    UserMappingAttributeParam tenantAttr = new UserMappingAttributeParam();
    tenantAttr.setKey("departMent");
    tenantAttr.setValues(Collections.singletonList(SUBTENANT1_ATTR));
    tenantMapping1.setAttributes(Collections.singletonList(tenantAttr));
    // create a second mapping with no domain
    // should fail to add it
    UserMappingAttributeParam tenantAttr2 = new UserMappingAttributeParam();
    tenantAttr2.setKey("Company");
    tenantAttr2.setValues(Collections.singletonList(SUBTENANT1_ATTR));
    UserMappingParam tenantMapping2 = new UserMappingParam();
    tenantMapping2.setAttributes(Collections.singletonList(tenantAttr2));
    tenantParam.getUserMappings().add(tenantMapping1);
    tenantParam.getUserMappings().add(tenantMapping2);
    resp = rTAdminGr.path(subtenant_url).post(ClientResponse.class, tenantParam);
    Assert.assertEquals(400, resp.getStatus());
    // Add the domain to the second mapping
    tenantMapping2.setDomain("Sanity.Local");
    // Should fail with 403
    resp = rSys.path(subtenant_url).post(ClientResponse.class, tenantParam);
    Assert.assertEquals(403, resp.getStatus());
    // Add the mappings
    TenantOrgRestRep subtenant1 = rTAdminGr.path(subtenant_url).post(TenantOrgRestRep.class, tenantParam);
    Assert.assertTrue(subtenant1.getName().equals(subtenant1_label));
    Assert.assertEquals(2, subtenant1.getUserMappings().size());
    for (UserMappingParam mapping : subtenant1.getUserMappings()) {
        Assert.assertEquals(1, mapping.getAttributes().size());
        UserMappingAttributeParam attribute = mapping.getAttributes().get(0);
        if (attribute.getKey().equalsIgnoreCase("department") || attribute.getKey().equalsIgnoreCase("company")) {
            Assert.assertEquals(1, attribute.getValues().size());
            Assert.assertEquals(SUBTENANT1_ATTR, attribute.getValues().get(0));
        } else {
            Assert.fail("Attribute key unexpected " + attribute.getKey());
        }
    }
    subtenant1Id = subtenant1.getId();
    // Try to remove all of the mappings
    // should fail for non-root tenant
    tenantUpdate = new TenantUpdateParam();
    tenantUpdate.setUserMappingChanges(new UserMappingChanges());
    tenantUpdate.getUserMappingChanges().setRemove(new ArrayList<UserMappingParam>());
    tenantUpdate.getUserMappingChanges().getRemove().add(tenantMapping1);
    tenantUpdate.getUserMappingChanges().getRemove().add(tenantMapping2);
    resp = rTAdminGr.path("/tenants/" + subtenant1Id.toString()).put(ClientResponse.class, tenantUpdate);
    Assert.assertEquals(400, resp.getStatus());
    subtenant1 = rTAdminGr.path("/tenants/" + subtenant1Id.toString()).get(TenantOrgRestRep.class);
    Assert.assertTrue(subtenant1.getId().equals(subtenant1Id));
    Assert.assertTrue(subtenant1.getName().equals(subtenant1_label));
    Assert.assertEquals(2, subtenant1.getUserMappings().size());
    for (UserMappingParam mapping : subtenant1.getUserMappings()) {
        Assert.assertEquals(1, mapping.getAttributes().size());
        UserMappingAttributeParam attribute = mapping.getAttributes().get(0);
        if (attribute.getKey().equalsIgnoreCase("department") || attribute.getKey().equalsIgnoreCase("company")) {
            Assert.assertEquals(1, attribute.getValues().size());
            Assert.assertEquals(SUBTENANT1_ATTR, attribute.getValues().get(0));
        } else {
            Assert.fail("Attribute key unexpected " + attribute.getKey());
        }
    }
    // Add a zone role for the subtenant1 admins group
    // verify that a subtenant user in that group does not get the zone role
    changes = new RoleAssignmentChanges();
    changes.setAdd(new ArrayList<RoleAssignmentEntry>());
    RoleAssignmentEntry entry_subtenant = new RoleAssignmentEntry();
    entry_subtenant.setGroup(SUBTENANT1_ADMINS_GROUP);
    entry_subtenant.getRoles().add("SECURITY_ADMIN");
    changes.getAdd().add(entry_subtenant);
    assignments = rSys.path("/vdc/role-assignments").put(RoleAssignments.class, changes);
    Assert.assertEquals(3, assignments.getAssignments().size());
    resp = rSTAdminGr1.path("/vdc/role-assignments").get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
    String subtenant2_label = "subtenant2";
    tenantParam.setLabel(subtenant2_label);
    tenantParam.setDescription("second subtenant");
    tenantParam.setUserMappings(new ArrayList<UserMappingParam>());
    UserMappingParam tenant2UserMapping = new UserMappingParam();
    tenant2UserMapping.setDomain("sanity.local");
    UserMappingAttributeParam tenant2Attr = new UserMappingAttributeParam();
    tenant2Attr.setKey("COMPANY");
    tenant2Attr.setValues(Collections.singletonList(SUBTENANT1_ATTR.toLowerCase()));
    tenant2UserMapping.setAttributes(Collections.singletonList(tenant2Attr));
    tenantParam.getUserMappings().add(tenant2UserMapping);
    // duplicate attribute - should fail
    resp = rTAdmin.path(subtenant_url).post(ClientResponse.class, tenantParam);
    Assert.assertEquals(400, resp.getStatus());
    // create second subtenant
    tenant2Attr.setValues(Collections.singletonList(SUBTENANT2_ATTR));
    UserMappingAttributeParam tenant2Attr2 = new UserMappingAttributeParam();
    tenant2Attr2.setKey("department");
    tenant2Attr2.setValues(Collections.singletonList(SUBTENANT2_ATTR.toLowerCase()));
    List<UserMappingAttributeParam> attributes = new ArrayList<UserMappingAttributeParam>();
    attributes.add(tenant2Attr);
    attributes.add(tenant2Attr2);
    tenant2UserMapping.setAttributes(attributes);
    // duplicate name check for tenants
    tenantParam.setLabel(subtenant1_label);
    resp = rTAdmin.path(subtenant_url).post(ClientResponse.class, tenantParam);
    Assert.assertEquals(400, resp.getStatus());
    tenantParam.setLabel(subtenant2_label);
    TenantOrgRestRep subtenant2 = rTAdmin.path(subtenant_url).post(TenantOrgRestRep.class, tenantParam);
    subtenant2Id = subtenant2.getId();
    // Add a mapping with less scope then remove the mapping
    // with more scope to verify that it works.
    UserMappingParam tenant2UserMapping2 = new UserMappingParam();
    tenant2UserMapping2.setDomain("sanity.local");
    UserMappingAttributeParam tenant2Attr3 = new UserMappingAttributeParam();
    tenant2Attr3.setKey("company");
    tenant2Attr3.setValues(Collections.singletonList(SUBTENANT2_ATTR));
    tenant2UserMapping2.setAttributes(Collections.singletonList(tenant2Attr3));
    tenantUpdate = new TenantUpdateParam();
    tenantUpdate.setUserMappingChanges(new UserMappingChanges());
    tenantUpdate.getUserMappingChanges().setAdd(new ArrayList<UserMappingParam>());
    // Create a third mapping equal to the first mapping
    // with differences in case and order of attributes
    UserMappingParam tenant2UserMapping3 = new UserMappingParam();
    tenantUpdate.setLabel(subtenant2_label);
    tenant2UserMapping3.setDomain("Sanity.Local");
    List<UserMappingAttributeParam> attributes2 = new ArrayList<UserMappingAttributeParam>();
    attributes2.add(tenant2Attr3);
    attributes2.add(tenant2Attr2);
    tenant2UserMapping3.setAttributes(attributes2);
    tenantUpdate.setLabel(subtenant2_label);
    tenantUpdate.getUserMappingChanges().getAdd().add(tenant2UserMapping2);
    resp = rTAdmin.path("/tenants/" + subtenant2Id.toString()).put(ClientResponse.class, tenantUpdate);
    Assert.assertEquals(200, resp.getStatus());
    tenantUpdate.getUserMappingChanges().setAdd(new ArrayList<UserMappingParam>());
    tenantUpdate.getUserMappingChanges().setRemove(new ArrayList<UserMappingParam>());
    tenantUpdate.getUserMappingChanges().getRemove().add(tenant2UserMapping3);
    resp = rTAdmin.path("/tenants/" + subtenant2Id.toString()).put(ClientResponse.class, tenantUpdate);
    Assert.assertEquals(200, resp.getStatus());
    subtenant2 = rTAdmin.path("/tenants/" + subtenant2Id.toString()).get(TenantOrgRestRep.class);
    Assert.assertTrue(subtenant2.getId().equals(subtenant2Id));
    Assert.assertTrue(subtenant2.getName().equals(subtenant2_label));
    Assert.assertEquals(1, subtenant2.getUserMappings().size());
    for (UserMappingParam mapping : subtenant2.getUserMappings()) {
        Assert.assertEquals(1, mapping.getAttributes().size());
        UserMappingAttributeParam attribute = mapping.getAttributes().get(0);
        if (attribute.getKey().equalsIgnoreCase("company")) {
            Assert.assertEquals(1, attribute.getValues().size());
            Assert.assertEquals(SUBTENANT2_ATTR, attribute.getValues().get(0));
        } else {
            Assert.fail("Attribute key unexpected " + attribute.getKey());
        }
    }
    // test that updating this tenant with the second tenant's name
    tenantUpdateNameOnly = new TenantUpdateParam();
    tenantUpdateNameOnly.setLabel(subtenant2_label);
    resp = rTAdminGr.path("/tenants/" + subtenant1Id.toString()).put(ClientResponse.class, tenantUpdateNameOnly);
    Assert.assertEquals(400, resp.getStatus());
    // as sysmonitor, verify we can access sub tenant quota
    resp = rMon.path("/tenants/" + subtenant2Id.toString() + "/quota").get(ClientResponse.class);
    Assert.assertEquals(200, resp.getStatus());
    // create second level tenant - should fail
    tenantParam.setLabel("bad");
    tenantParam.setDescription("bad subtenant");
    tenantParam.setUserMappings(new ArrayList<UserMappingParam>());
    UserMappingAttributeParam tenantAttrBad = new UserMappingAttributeParam();
    tenantAttrBad.setKey("company");
    tenantAttrBad.setValues(Collections.singletonList("subtenant_bad"));
    UserMappingParam tenantMappingBad = new UserMappingParam();
    tenantMappingBad.setAttributes(Collections.singletonList(tenantAttrBad));
    tenantParam.getUserMappings().add(tenantMappingBad);
    resp = rTAdminGr.path("/tenants/" + subtenant2Id.toString() + "/subtenants").post(ClientResponse.class, tenantParam);
    Assert.assertEquals(403, resp.getStatus());
    resp = rTAdmin.path("/tenants/" + subtenant2Id.toString() + "/subtenants").post(ClientResponse.class, tenantParam);
    Assert.assertEquals(400, resp.getStatus());
    // TODO - Refactor these tests to meet one of the good code property "one method is responsible for one work"
    // TODO - and make each tests as individual and simple unittests as possible that just runs in very few milliseconds.
    // But, still the process of understanding the whole test architecture, hence adding
    // my new test also here for now.
    // Create subtenants with duplicate groups. But API should
    // be able to find the duplicate groups and remove them
    // and create only the distinct groups to the userMappings.
    String dupGroupSubtenant_url = rootTenantBaseUrl + "/subtenants";
    String dupTenantParam_label = "DupGroupSubTenant";
    TenantCreateParam dupTenantParam = new TenantCreateParam();
    dupTenantParam.setLabel(dupTenantParam_label);
    dupTenantParam.setDescription("first subtenant with duplicate groups in the user mapping.");
    dupTenantParam.setUserMappings(new ArrayList<UserMappingParam>());
    String key1 = "Attr1";
    String key2 = "Attr2";
    String key3 = "Attr3";
    List<String> values1 = new ArrayList<String>();
    values1.add("one");
    values1.add("two");
    values1.add("three");
    values1.add("four");
    // Duplicate one, so should be removed in the expected list.
    values1.add("two");
    // Duplicate one, so should be removed in the expected list.
    values1.add("three");
    List<String> expectedValues1 = new ArrayList<String>();
    expectedValues1.add("one");
    expectedValues1.add("two");
    expectedValues1.add("three");
    expectedValues1.add("four");
    List<String> values2 = new ArrayList<String>();
    values2.add("one");
    values2.add("two");
    values2.add("three");
    values2.add("four");
    // Duplicate one, so should be removed in the expected list.
    values2.add("two");
    // Duplicate one, so should be removed in the expected list.
    values2.add("three");
    // One additional value that is not there in value1. So, not a duplicate.
    values2.add("five");
    List<String> expectedValues2 = new ArrayList<String>();
    expectedValues2.add("one");
    expectedValues2.add("two");
    expectedValues2.add("three");
    expectedValues2.add("four");
    expectedValues2.add("five");
    // Validating the duplicate removal code added in the UserMappingAttributeParam() constructor.
    UserMappingAttributeParam userMappingAttributeParam1 = new UserMappingAttributeParam(key1, values1);
    // Duplicate Attribute.
    UserMappingAttributeParam userMappingAttributeParam2 = new UserMappingAttributeParam(key1, values1);
    UserMappingAttributeParam userMappingAttributeParam3 = new UserMappingAttributeParam(key1, values2);
    UserMappingAttributeParam userMappingAttributeParam4 = new UserMappingAttributeParam(key2, values2);
    UserMappingAttributeParam userMappingAttributeParam5 = new UserMappingAttributeParam(key3, values2);
    Assert.assertArrayEquals(expectedValues1.toArray(), userMappingAttributeParam1.getValues().toArray());
    Assert.assertArrayEquals(expectedValues1.toArray(), userMappingAttributeParam2.getValues().toArray());
    Assert.assertArrayEquals(expectedValues2.toArray(), userMappingAttributeParam3.getValues().toArray());
    Assert.assertArrayEquals(expectedValues2.toArray(), userMappingAttributeParam4.getValues().toArray());
    Assert.assertArrayEquals(expectedValues2.toArray(), userMappingAttributeParam5.getValues().toArray());
    // Validating the duplicate removal code added in the UserMappingAttributeParam.setValues() method.
    userMappingAttributeParam1.setValues(values1);
    userMappingAttributeParam2.setValues(values1);
    userMappingAttributeParam3.setValues(values2);
    userMappingAttributeParam4.setValues(values2);
    userMappingAttributeParam5.setValues(values2);
    Assert.assertArrayEquals(expectedValues1.toArray(), userMappingAttributeParam1.getValues().toArray());
    Assert.assertArrayEquals(expectedValues1.toArray(), userMappingAttributeParam2.getValues().toArray());
    Assert.assertArrayEquals(expectedValues2.toArray(), userMappingAttributeParam3.getValues().toArray());
    Assert.assertArrayEquals(expectedValues2.toArray(), userMappingAttributeParam4.getValues().toArray());
    Assert.assertArrayEquals(expectedValues2.toArray(), userMappingAttributeParam5.getValues().toArray());
    List<UserMappingAttributeParam> attributeList = new ArrayList<UserMappingAttributeParam>();
    attributeList.add(userMappingAttributeParam1);
    // Duplicate one, so should be removed in the expected list.
    attributeList.add(userMappingAttributeParam2);
    attributeList.add(userMappingAttributeParam3);
    attributeList.add(userMappingAttributeParam4);
    List<UserMappingAttributeParam> expectedAttributeList = new ArrayList<UserMappingAttributeParam>();
    expectedAttributeList.add(userMappingAttributeParam1);
    expectedAttributeList.add(userMappingAttributeParam3);
    expectedAttributeList.add(userMappingAttributeParam4);
    List<UserMappingAttributeParam> additionalAttributeList = new ArrayList<UserMappingAttributeParam>();
    additionalAttributeList.add(userMappingAttributeParam1);
    // Duplicate one, so should be removed in the expected list.
    additionalAttributeList.add(userMappingAttributeParam2);
    additionalAttributeList.add(userMappingAttributeParam5);
    additionalAttributeList.add(userMappingAttributeParam3);
    additionalAttributeList.add(userMappingAttributeParam4);
    List<UserMappingAttributeParam> expectedAdditionalAttributeList = new ArrayList<UserMappingAttributeParam>();
    expectedAdditionalAttributeList.add(userMappingAttributeParam1);
    expectedAdditionalAttributeList.add(userMappingAttributeParam5);
    expectedAdditionalAttributeList.add(userMappingAttributeParam3);
    expectedAdditionalAttributeList.add(userMappingAttributeParam4);
    List<String> groups = new ArrayList<String>();
    groups.add(ZONEADMINS_GROUP);
    groups.add(TENANT_ADMINS_GROUP);
    groups.add(SUBTENANT1_ADMINS_GROUP);
    groups.add(SUBTENANT1_USERS_GROUP);
    // Duplicate one, so should be removed in the expected list.
    groups.add(ZONEADMINS_GROUP);
    // Duplicate one, so should be removed in the expected list.
    groups.add(TENANT_ADMINS_GROUP);
    // Duplicate one, so should be removed in the expected list.
    groups.add(SUBTENANT1_USERS_GROUP);
    List<String> expectedGroups = new ArrayList<String>();
    expectedGroups.add(ZONEADMINS_GROUP);
    expectedGroups.add(TENANT_ADMINS_GROUP);
    expectedGroups.add(SUBTENANT1_ADMINS_GROUP);
    expectedGroups.add(SUBTENANT1_USERS_GROUP);
    List<String> additionalGroups = new ArrayList<String>();
    additionalGroups.add(ZONEADMINS_GROUP);
    additionalGroups.add(TENANT_ADMINS_GROUP);
    additionalGroups.add(SUBTENANT2_ADMINS_GROUP);
    additionalGroups.add(ASUBSETOFUSERS_GROUP);
    additionalGroups.add(SUBTENANT1_ADMINS_GROUP);
    additionalGroups.add(SUBTENANT1_USERS_GROUP);
    // Duplicate one, so should be removed in the expected list.
    additionalGroups.add(ZONEADMINS_GROUP);
    // Duplicate one, so should be removed in the expected list.
    additionalGroups.add(TENANT_ADMINS_GROUP);
    // Duplicate one, so should be removed in the expected list.
    additionalGroups.add(SUBTENANT1_USERS_GROUP);
    List<String> expectedAdditionalGroups = new ArrayList<String>();
    expectedAdditionalGroups.add(ZONEADMINS_GROUP);
    expectedAdditionalGroups.add(TENANT_ADMINS_GROUP);
    expectedAdditionalGroups.add(SUBTENANT2_ADMINS_GROUP);
    expectedAdditionalGroups.add(ASUBSETOFUSERS_GROUP);
    expectedAdditionalGroups.add(SUBTENANT1_ADMINS_GROUP);
    expectedAdditionalGroups.add(SUBTENANT1_USERS_GROUP);
    UserMappingParam dupTenantMapping1 = new UserMappingParam("sanity.LOCAL", attributeList, groups);
    UserMappingParam dupTenantMapping2 = new UserMappingParam("sanity.LOCAL", attributeList, groups);
    // Validate against the expected list. This is to validate the new code added to remove the
    // duplicates in the UserMappingParam() constructor. For UserMappingParam1.
    List<UserMappingAttributeParam> retAttributeList = dupTenantMapping1.getAttributes();
    List<String> retGroups = dupTenantMapping1.getGroups();
    Assert.assertArrayEquals(expectedAttributeList.toArray(), retAttributeList.toArray());
    Assert.assertArrayEquals(expectedGroups.toArray(), retGroups.toArray());
    // For UserMappingParam2.
    retAttributeList = dupTenantMapping2.getAttributes();
    retGroups = dupTenantMapping2.getGroups();
    Assert.assertArrayEquals(expectedAttributeList.toArray(), retAttributeList.toArray());
    Assert.assertArrayEquals(expectedGroups.toArray(), retGroups.toArray());
    // Validate against the expected list. This is to validate the new code added to remove the
    // duplicates in the UserMappingParam.setAttributes() and UserMappingParam.setGroups().
    // For UserMappingParam1.
    dupTenantMapping1.setGroups(additionalGroups);
    dupTenantMapping1.setAttributes(additionalAttributeList);
    retAttributeList = dupTenantMapping1.getAttributes();
    retGroups = dupTenantMapping1.getGroups();
    Assert.assertArrayEquals(expectedAdditionalAttributeList.toArray(), retAttributeList.toArray());
    Assert.assertArrayEquals(expectedAdditionalGroups.toArray(), retGroups.toArray());
    // For UserMappingParam2.
    dupTenantMapping2.setGroups(additionalGroups);
    dupTenantMapping2.setAttributes(additionalAttributeList);
    retAttributeList = dupTenantMapping2.getAttributes();
    retGroups = dupTenantMapping2.getGroups();
    Assert.assertArrayEquals(expectedAdditionalAttributeList.toArray(), retAttributeList.toArray());
    Assert.assertArrayEquals(expectedAdditionalGroups.toArray(), retGroups.toArray());
    List<UserMappingParam> dupUserMappings = new ArrayList<UserMappingParam>();
    dupUserMappings.add(dupTenantMapping1);
    // Adding the same userMapping here, just make sure the duplicate will be removed..
    dupUserMappings.add(dupTenantMapping2);
    // Execute the API /tenants/{id}/subtenants with duplicate entries in the payload
    // and validate the response to make sure no duplicates are actually added to the resource.
    dupTenantParam.setUserMappings(dupUserMappings);
    TenantOrgRestRep dupTenantResp = rTAdminGr.path(dupGroupSubtenant_url).post(TenantOrgRestRep.class, dupTenantParam);
    Assert.assertTrue(dupTenantResp.getName().equals(dupTenantParam_label));
    Assert.assertEquals(1, dupTenantResp.getUserMappings().size());
    // same expected values.
    for (UserMappingParam retUserMapping : dupTenantResp.getUserMappings()) {
        // Unique groups are only ZONEADMINS_GROUP, TENANT_ADMINS_GROUP, SUBTENANT1_ADMINS_GROUP, SUBTENANT1_USERS_GROUP,
        // SUBTENANT2_ADMINS_GROUP, ASUBSETOFUSERS_GROUP. So, count is 6.
        List<String> actualGroupsWithoutDomainUserMapping = new ArrayList<>(retUserMapping.getGroups());
        List<String> actualGroupsWithDomainUserMapping = new ArrayList<>();
        for (String group : actualGroupsWithoutDomainUserMapping) {
            String groupWithDomain = group + "@sanity.local";
            actualGroupsWithDomainUserMapping.add(groupWithDomain);
        }
        Assert.assertEquals(6, retUserMapping.getGroups().size());
        Assert.assertArrayEquals(expectedAdditionalGroups.toArray(), actualGroupsWithDomainUserMapping.toArray());
        // Unique attributes are only userMappingAttributeParam1, userMappingAttributeParam3, userMappingAttributeParam4,
        // userMappingAttributeParam5. So, count is 4.
        Assert.assertEquals(4, retUserMapping.getAttributes().size());
        Assert.assertArrayEquals(expectedAdditionalAttributeList.toArray(), retUserMapping.getAttributes().toArray());
    }
    // Delete the create the subtenant to avoid the confusions in the further test cases that runs after this.
    ClientResponse dupTenantDeleteResp = rTAdminGr.path("/tenants/" + dupTenantResp.getId().toString() + "/deactivate").post(ClientResponse.class);
    Assert.assertEquals(200, dupTenantDeleteResp.getStatus());
    /*
         * create subtenant unauthorized
         */
    // no perms
    resp = rUnAuth.path(subtenant_url).post(ClientResponse.class, tenantParam);
    Assert.assertEquals(403, resp.getStatus());
    // sysadmin
    resp = rSys.path(subtenant_url).post(ClientResponse.class, tenantParam);
    Assert.assertEquals(403, resp.getStatus());
    subtenant2Id = subtenant2.getId();
    subtenant2 = rTAdmin.path("/tenants/" + subtenant2Id.toString()).get(TenantOrgRestRep.class);
    Assert.assertTrue(subtenant2.getId().equals(subtenant2Id));
    Assert.assertTrue(subtenant2.getName().equals(subtenant2_label));
    Assert.assertEquals(1, subtenant2.getUserMappings().size());
    for (UserMappingParam mapping : subtenant2.getUserMappings()) {
        Assert.assertEquals(1, mapping.getAttributes().size());
        UserMappingAttributeParam attribute = mapping.getAttributes().get(0);
        if (attribute.getKey().equalsIgnoreCase("company")) {
            Assert.assertEquals(1, attribute.getValues().size());
            Assert.assertEquals(SUBTENANT2_ATTR, attribute.getValues().get(0));
        } else {
            Assert.fail("Attribute key unexpected " + attribute.getKey());
        }
    }
    // create third subtenant
    String subtenant3_label = "subtenant3";
    tenantParam.setLabel(subtenant3_label);
    tenantParam.setDescription("third subtenant");
    tenantParam.setUserMappings(new ArrayList<UserMappingParam>());
    UserMappingParam tenant3Mapping = new UserMappingParam();
    // Try a group without the domain. Expect 400
    tenant3Mapping.setGroups(Collections.singletonList("Test Group"));
    resp = rTAdmin.path(subtenant_url).post(ClientResponse.class, tenantParam);
    Assert.assertEquals(400, resp.getStatus());
    tenant3Mapping.setDomain("SANITY.local");
    // Set the group to a user and expect 400
    tenant3Mapping.setGroups(Collections.singletonList(SUBTENANT3_ADMIN));
    tenantParam.getUserMappings().add(tenant3Mapping);
    resp = rTAdmin.path(subtenant_url).post(ClientResponse.class, tenantParam);
    Assert.assertEquals(400, resp.getStatus());
    // Try a non-whitelist group expect 400
    tenant3Mapping.setGroups(Collections.singletonList("NotOnWhitelist"));
    resp = rTAdmin.path(subtenant_url).post(ClientResponse.class, tenantParam);
    Assert.assertEquals(400, resp.getStatus());
    // Finally attempt the successful case
    tenant3Mapping.setGroups(Collections.singletonList("Test Group"));
    TenantOrgRestRep subtenant3 = rTAdmin.path(subtenant_url).post(TenantOrgRestRep.class, tenantParam);
    Assert.assertTrue(subtenant3.getName().equals(subtenant3_label));
    Assert.assertEquals(1, subtenant3.getUserMappings().size());
    Assert.assertEquals(1, subtenant3.getUserMappings().get(0).getGroups().size());
    Assert.assertEquals("test group", subtenant3.getUserMappings().get(0).getGroups().get(0).toLowerCase());
    subtenant3Id = subtenant3.getId();
    // login in with a user that should map to more than one tenant and expect a 403
    _savedTokens.remove(SUBTENANT13_USER);
    resp = rST13User.path("/login").get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
    /*
         * list subtenants - sys monitor, tenant admin and group
         */
    TenantOrgList list = rSys.path(subtenant_url).get(TenantOrgList.class);
    Assert.assertEquals(3, list.getSubtenants().size());
    list = rTAdmin.path(subtenant_url).get(TenantOrgList.class);
    Assert.assertEquals(3, list.getSubtenants().size());
    list = rTAdminGr.path(subtenant_url).get(TenantOrgList.class);
    Assert.assertEquals(3, list.getSubtenants().size());
    // unauth
    resp = rUnAuth.path(subtenant_url).get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
    // system admin only user, verify it doesn't have permision to list subtenants
    String SYSTEM_ADMIN_ONLY = "sysadminonly@sanity.local";
    RoleAssignmentEntry roleAssignmentEntry = new RoleAssignmentEntry();
    roleAssignmentEntry.setSubjectId(SYSTEM_ADMIN_ONLY);
    roleAssignmentEntry.setRoles(new ArrayList<String>(Arrays.asList("SYSTEM_ADMIN")));
    List<RoleAssignmentEntry> add = new ArrayList<RoleAssignmentEntry>();
    add.add(roleAssignmentEntry);
    RoleAssignmentChanges roleAssignmentChanges = new RoleAssignmentChanges();
    roleAssignmentChanges.setAdd(add);
    resp = rSys.path("/vdc/role-assignments").put(ClientResponse.class, changes);
    Assert.assertEquals(200, resp.getStatus());
    BalancedWebResource rSysadminOnly = createHttpsClient(SYSTEM_ADMIN_ONLY, AD_PASS_WORD, baseUrls);
    resp = rSysadminOnly.path(subtenant_url).get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
    RoleAssignments previousAssignments = rZAdmin.path(String.format(roles_url_format, rootTenantId.toString())).get(RoleAssignments.class);
    // re-add the tenant admin role to root
    changes = new RoleAssignmentChanges();
    changes.setAdd(new ArrayList<RoleAssignmentEntry>());
    changes.getAdd().add(rootTenantAdminUserEntry);
    previousAssignments.getAssignments().add(rootTenantAdminUserEntry);
    readAssignments = rZAdmin.path(String.format(roles_url_format, rootTenantId.toString())).put(RoleAssignments.class, changes);
    Assert.assertTrue(checkEqualsRoles(previousAssignments.getAssignments(), readAssignments.getAssignments()));
    /*
         * ROLE ASSIGNMENT - subtenant
         */
    RoleAssignmentEntry entry5 = new RoleAssignmentEntry();
    entry5.setSubjectId(SUBTENANT1_ADMIN);
    entry5.getRoles().add("TENANT_ADMIN");
    entry5.getRoles().add("PROJECT_ADMIN");
    resp = rTAdmin.path(String.format(roles_url_format, subtenant1Id.toString())).get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
    readAssignments = rTAdminGr.path(String.format(roles_url_format, subtenant1Id.toString())).get(RoleAssignments.class);
    Assert.assertTrue(readAssignments.getAssignments().size() == 1);
    changes = new RoleAssignmentChanges();
    changes.setAdd(new ArrayList<RoleAssignmentEntry>());
    changes.getAdd().add(entry5);
    changes.setRemove(new ArrayList<RoleAssignmentEntry>());
    changes.getRemove().addAll(readAssignments.getAssignments());
    resp = rTAdminGr.path(String.format(roles_url_format, subtenant1Id.toString())).put(ClientResponse.class, changes);
    Assert.assertEquals(200, resp.getStatus());
    readAssignments = rSTAdmin1.path(String.format(roles_url_format, subtenant1Id.toString())).get(RoleAssignments.class);
    Assert.assertTrue(checkEqualsRoles(changes.getAdd(), readAssignments.getAssignments()));
    // batch role assignment changes
    RoleAssignments assignmentToHaveWhenImDone = readAssignments;
    changes = new RoleAssignmentChanges(new ArrayList<RoleAssignmentEntry>(), readAssignments.getAssignments());
    entry1 = new RoleAssignmentEntry();
    entry1.setSubjectId(ROOTUSER);
    entry1.getRoles().add("TENANT_ADMIN");
    changes.getAdd().add(entry1);
    entry2 = new RoleAssignmentEntry();
    entry2.setSubjectId(SUBTENANT1_ADMIN);
    entry2.getRoles().add("TENANT_ADMIN");
    entry2.getRoles().add("PROJECT_ADMIN");
    changes.getAdd().add(entry2);
    entry3 = new RoleAssignmentEntry();
    entry3.setSubjectId(SUBTENANT1_USER);
    entry3.getRoles().add("PROJECT_ADMIN");
    changes.getAdd().add(entry3);
    entry4 = new RoleAssignmentEntry();
    entry4.setSubjectId(SUBTENANT1_READER);
    entry4.getRoles().add("TENANT_APPROVER");
    changes.getAdd().add(entry4);
    entry5 = new RoleAssignmentEntry();
    entry5.setGroup(SUBTENANT1_ADMINS_GROUP);
    entry5.getRoles().add("TENANT_ADMIN");
    entry5.getRoles().add("PROJECT_ADMIN");
    changes.getAdd().add(entry5);
    RoleAssignmentEntry entry6 = new RoleAssignmentEntry();
    entry6.setGroup(SUBTENANT1_USERS_GROUP);
    entry6.getRoles().add("TENANT_APPROVER");
    changes.getAdd().add(entry6);
    resp = rSTAdmin1.path(String.format(roles_url_format, subtenant1Id.toString())).put(ClientResponse.class, changes);
    Assert.assertEquals(200, resp.getStatus());
    readAssignments = rSTAdmin1.path(String.format(roles_url_format, subtenant1Id.toString())).get(RoleAssignments.class);
    Assert.assertTrue(checkEqualsRoles(changes.getAdd(), readAssignments.getAssignments()));
    // reverting back to the way it was before the batch role assignment changes
    changes = new RoleAssignmentChanges(assignmentToHaveWhenImDone.getAssignments(), readAssignments.getAssignments());
    resp = rSTAdmin1.path(String.format(roles_url_format, subtenant1Id.toString())).put(ClientResponse.class, changes);
    Assert.assertEquals(200, resp.getStatus());
    readAssignments = rSTAdmin1.path(String.format(roles_url_format, subtenant1Id.toString())).get(RoleAssignments.class);
    Assert.assertTrue(checkEqualsRoles(changes.getAdd(), readAssignments.getAssignments()));
    // check with whoami, that SUBTENANT1_ADMIN at this point, has tenant_admin and project admin
    ArrayList<String> lookFor = new ArrayList<String>();
    Collections.addAll(lookFor, "TENANT_ADMIN", "PROJECT_ADMIN");
    userInfoCheckRoles(rSTAdmin1, lookFor);
    entry6 = new RoleAssignmentEntry();
    entry6.setGroup(SUBTENANT2_ADMINS_GROUP);
    entry6.getRoles().add("TENANT_ADMIN");
    RoleAssignmentEntry entry7 = new RoleAssignmentEntry();
    entry7.setSubjectId(SUBTENANT2_ADMIN);
    entry7.getRoles().add("TENANT_ADMIN");
    readAssignments = rTAdmin.path(String.format(roles_url_format, subtenant2Id.toString())).get(RoleAssignments.class);
    Assert.assertTrue(readAssignments.getAssignments().size() == 1);
    changes = new RoleAssignmentChanges();
    changes.setAdd(new ArrayList<RoleAssignmentEntry>());
    changes.getAdd().add(entry6);
    changes.getAdd().add(entry7);
    changes.setRemove(new ArrayList<RoleAssignmentEntry>());
    changes.getRemove().add(entry5);
    changes.getRemove().addAll(readAssignments.getAssignments());
    resp = rTAdmin.path(String.format(roles_url_format, subtenant2Id.toString())).put(ClientResponse.class, changes);
    Assert.assertEquals(200, resp.getStatus());
    readAssignments = rSTAdminGr2.path(String.format(roles_url_format, subtenant2Id.toString())).get(RoleAssignments.class);
    Assert.assertTrue(checkEqualsRoles(changes.getAdd(), readAssignments.getAssignments()));
    readAssignments = rSTAdmin2.path(String.format(roles_url_format, subtenant2Id.toString())).get(RoleAssignments.class);
    Assert.assertTrue(checkEqualsRoles(changes.getAdd(), readAssignments.getAssignments()));
    /*
         * LIST subtenants
         */
    // tenant admins on root gets the full list
    list = rTAdmin.path(subtenant_url).get(TenantOrgList.class);
    Assert.assertEquals(3, list.getSubtenants().size());
    // tenant admin on the child get only the child
    list = rSTAdmin1.path(subtenant_url).get(TenantOrgList.class);
    Assert.assertEquals(1, list.getSubtenants().size());
    Assert.assertEquals(subtenant1Id, list.getSubtenants().get(0).getId());
    list = rSTAdminGr2.path(subtenant_url).get(TenantOrgList.class);
    Assert.assertEquals(1, list.getSubtenants().size());
    Assert.assertEquals(subtenant2Id, list.getSubtenants().get(0).getId());
    list = rSTAdmin2.path(subtenant_url).get(TenantOrgList.class);
    Assert.assertEquals(1, list.getSubtenants().size());
    Assert.assertEquals(subtenant2Id, list.getSubtenants().get(0).getId());
    /*
         * Changing subtenant roles
         */
    RoleAssignmentEntry entry8 = new RoleAssignmentEntry();
    entry8.setGroup(SUBTENANT2_ADMINS_GROUP);
    entry8.getRoles().add("PROJECT_ADMIN");
    changes = new RoleAssignmentChanges();
    changes.setAdd(new ArrayList<RoleAssignmentEntry>());
    changes.getAdd().add(entry8);
    changes.setRemove(new ArrayList<RoleAssignmentEntry>());
    changes.getRemove().add(entry6);
    resp = rSTAdmin2.path(String.format(roles_url_format, subtenant2Id.toString())).put(ClientResponse.class, changes);
    Assert.assertEquals(200, resp.getStatus());
    changes.getAdd().add(entry7);
    readAssignments = rSTAdmin2.path(String.format(roles_url_format, subtenant2Id.toString())).get(RoleAssignments.class);
    Assert.assertTrue(checkEqualsRoles(changes.getAdd(), readAssignments.getAssignments()));
    resp = rSTAdminGr2.path(String.format(roles_url_format, subtenant2Id.toString())).get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
    RoleAssignmentEntry entry9 = new RoleAssignmentEntry();
    entry9.setGroup(SUBTENANT1_ADMINS_GROUP);
    entry9.getRoles().add("PROJECT_ADMIN");
    changes = new RoleAssignmentChanges();
    changes.setAdd(new ArrayList<RoleAssignmentEntry>());
    changes.getAdd().add(entry9);
    resp = rSTAdmin1.path(String.format(roles_url_format, subtenant1Id.toString())).put(ClientResponse.class, changes);
    Assert.assertEquals(200, resp.getStatus());
    resp = rSTAdminGr1.path(String.format(roles_url_format, subtenant1Id.toString())).get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
    resp = rSTAdminGr2.path(String.format(roles_url_format, subtenant1Id.toString())).get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
    // add a user from root tenant to be an TENANT_ADMIN in subtenant1
    entry_subtenant = new RoleAssignmentEntry();
    entry_subtenant.setSubjectId(ROOTUSER2);
    entry_subtenant.getRoles().add("TENANT_ADMIN");
    changes.getAdd().add(entry_subtenant);
    resp = rSTAdmin1.path(String.format(roles_url_format, subtenant1Id.toString())).put(ClientResponse.class, changes);
    Assert.assertEquals(200, resp.getStatus());
    // test out that rootuser2 is able to use his tenant admin in the subtenant even though that is not
    // his home tenant.
    resp = rRootUser2.path("/tenants/" + subtenant1Id.toString()).get(ClientResponse.class);
    Assert.assertEquals(200, resp.getStatus());
    changes = new RoleAssignmentChanges();
    changes.setAdd(new ArrayList<RoleAssignmentEntry>());
    changes.setRemove(new ArrayList<RoleAssignmentEntry>());
    // Assign a role to a recursive group
    RoleAssignmentEntry recursiveGroupEntry = new RoleAssignmentEntry();
    recursiveGroupEntry.setGroup("Domain Users@sanity.local");
    recursiveGroupEntry.getRoles().add("PROJECT_ADMIN");
    changes.getAdd().add(recursiveGroupEntry);
    // Try to assign a role to a group not on the whitelist
    RoleAssignmentEntry nonWhiteListGroupEntry = new RoleAssignmentEntry();
    nonWhiteListGroupEntry.setGroup("NotOnWhitelist@sanity.local");
    nonWhiteListGroupEntry.getRoles().add("PROJECT_ADMIN");
    changes.getAdd().add(nonWhiteListGroupEntry);
    // Assign a role to a user in this tenant
    RoleAssignmentEntry st3AdminEntry = new RoleAssignmentEntry();
    st3AdminEntry.setSubjectId(SUBTENANT3_ADMIN);
    st3AdminEntry.getRoles().add("TENANT_ADMIN");
    changes.getAdd().add(st3AdminEntry);
    resp = rTAdmin.path(String.format(roles_url_format, subtenant3Id.toString())).put(ClientResponse.class, changes);
    // Should fail with a 400 due to the non-whitelist group
    Assert.assertEquals(400, resp.getStatus());
    changes.getAdd().remove(nonWhiteListGroupEntry);
    // Adding this to the remove list should have no effect
    changes.getRemove().add(nonWhiteListGroupEntry);
    resp = rTAdmin.path(String.format(roles_url_format, subtenant3Id.toString())).put(ClientResponse.class, changes);
    // Should succeed now
    Assert.assertEquals(200, resp.getStatus());
    changes = new RoleAssignmentChanges();
    changes.setAdd(new ArrayList<RoleAssignmentEntry>());
    changes.setRemove(new ArrayList<RoleAssignmentEntry>());
    // STAdmin3 should be able to read roles now
    readAssignments = rSTAdmin3.path(String.format(roles_url_format, subtenant3Id.toString())).get(RoleAssignments.class);
    // Try to assign a role to a user in a different tenant
    RoleAssignmentEntry st2AdminEntry = new RoleAssignmentEntry();
    st2AdminEntry.setSubjectId(SUBTENANT2_ADMIN);
    st2AdminEntry.getRoles().add("TENANT_ADMIN");
    changes.getAdd().add(st2AdminEntry);
    resp = rSTAdmin3.path(String.format(roles_url_format, subtenant3Id.toString())).put(ClientResponse.class, changes);
    // Should fail with a 400 due to user in wrong tenant
    Assert.assertEquals(400, resp.getStatus());
    // Try to assign a role with the valid group as username
    RoleAssignmentEntry groupAsSidEntry = new RoleAssignmentEntry();
    groupAsSidEntry.setSubjectId("Domain Users");
    groupAsSidEntry.getRoles().add("TENANT_ADMIN");
    changes.getAdd().remove(0);
    changes.getAdd().add(groupAsSidEntry);
    resp = rSTAdmin3.path(String.format(roles_url_format, subtenant3Id.toString())).put(ClientResponse.class, changes);
    // Should fail with a 400 due to user with that name not existing
    Assert.assertEquals(400, resp.getStatus());
    // Try to assign a role with a valid username as the group
    RoleAssignmentEntry sidAsGroupEntry = new RoleAssignmentEntry();
    sidAsGroupEntry.setGroup(SUBTENANT3_ADMIN);
    sidAsGroupEntry.getRoles().add("TENANT_ADMIN");
    changes.getAdd().remove(0);
    changes.getAdd().add(sidAsGroupEntry);
    resp = rSTAdmin3.path(String.format(roles_url_format, subtenant3Id.toString())).put(ClientResponse.class, changes);
    // Should fail with a 400 due to group with that name not existing
    Assert.assertEquals(400, resp.getStatus());
    /*
         * Test the user tenant troubleshooting API
         */
    String userTenantURL = "/user/tenant";
    resp = rUnAuth.path(userTenantURL).queryParam("username", "sanity_user@sanity.local").get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
    resp = rZAdmin.path(userTenantURL).queryParam("username", "sanity_user@baddomain.com").get(ClientResponse.class);
    Assert.assertEquals(400, resp.getStatus());
    resp = rZAdmin.path(userTenantURL).queryParam("username", "sanity_user").get(ClientResponse.class);
    Assert.assertEquals(400, resp.getStatus());
    resp = rZAdmin.path(userTenantURL).queryParam("username", "nouser@sanity.local").get(ClientResponse.class);
    Assert.assertEquals(400, resp.getStatus());
    resp = rZAdmin.path(userTenantURL).get(ClientResponse.class);
    Assert.assertEquals(400, resp.getStatus());
    UserTenantList userTenants = rZAdmin.path(userTenantURL).queryParam("username", "sanity_user@sanity.local").get(UserTenantList.class);
    Assert.assertEquals(userTenants._userTenantList.size(), 1);
    UserTenant userTenant = userTenants._userTenantList.get(0);
    Assert.assertEquals(rootTenantId, userTenant._id);
    Assert.assertEquals("sanity.local", userTenant._userMapping.getDomain());
    Assert.assertEquals(1, userTenant._userMapping.getAttributes().size());
    Assert.assertEquals("ou", userTenant._userMapping.getAttributes().get(0).getKey());
    Assert.assertArrayEquals(new String[] { ROOTTENANT_ATTR }, userTenant._userMapping.getAttributes().get(0).getValues().toArray(new String[0]));
    userTenants = rZAdmin.path(userTenantURL).queryParam("username", SUBTENANT13_USER).get(UserTenantList.class);
    Assert.assertEquals(userTenants._userTenantList.size(), 2);
    for (UserTenant userTenantEntry : userTenants._userTenantList) {
        if (userTenantEntry._id.equals(subtenant1Id)) {
            Assert.assertEquals(1, userTenantEntry._userMapping.getAttributes().size());
            Assert.assertEquals("company", userTenantEntry._userMapping.getAttributes().get(0).getKey().toLowerCase());
            Assert.assertArrayEquals(new String[] { SUBTENANT1_ATTR }, userTenantEntry._userMapping.getAttributes().get(0).getValues().toArray(new String[0]));
        } else if (userTenantEntry._id.equals(subtenant3Id)) {
            Assert.assertEquals(1, userTenantEntry._userMapping.getGroups().size());
            Assert.assertArrayEquals(new String[] { SUBTENANT3_ATTR }, userTenantEntry._userMapping.getGroups().toArray(new String[0]));
        } else {
            Assert.fail("Unexpected tenant ID: " + userTenantEntry._id);
        }
    }
    /*
         * CREATE, LIST projects
         */
    // as zone sysadmin
    expectedProjListResults.put("root", new ArrayList<ProjectEntry>());
    expectedProjListResults.put("st1", new ArrayList<ProjectEntry>());
    expectedProjListResults.put("st2", new ArrayList<ProjectEntry>());
    ProjectParam paramProj = new ProjectParam();
    resp = rZAdminGr.path(String.format(_projectsUrlFormat, rootTenantId.toString())).post(ClientResponse.class, paramProj);
    Assert.assertEquals(403, resp.getStatus());
    // as tenant admin of root
    paramProj = new ProjectParam("root project1");
    ProjectEntry createResp = rTAdmin.path(String.format(_projectsUrlFormat, rootTenantId.toString())).post(ProjectEntry.class, paramProj);
    Assert.assertTrue(createResp.name.equals(paramProj.getName()));
    Assert.assertTrue(createResp.id != null);
    ProjectEntry projEl = new ProjectEntry(createResp);
    expectedProjListResults.get("root").add(projEl);
    // as subtenant admins and project admins
    paramProj = new ProjectParam("subtenant1 project1");
    createResp = rSTAdmin1.path(String.format(_projectsUrlFormat, subtenant1Id.toString())).post(ProjectEntry.class, paramProj);
    Assert.assertTrue(createResp.name.equals(paramProj.getName()));
    Assert.assertTrue(createResp.id != null);
    expectedProjListResults.get("st1").add(new ProjectEntry(createResp));
    paramProj.setName("subtenant1 project2");
    createResp = rSTAdminGr1.path(String.format(_projectsUrlFormat, subtenant1Id.toString())).post(ProjectEntry.class, paramProj);
    Assert.assertTrue(createResp.name.equals(paramProj.getName()));
    Assert.assertTrue(createResp.id != null);
    expectedProjListResults.get("st1").add(new ProjectEntry(createResp));
    paramProj.setName("subtenant2 project1");
    createResp = rSTAdmin2.path(String.format(_projectsUrlFormat, subtenant2Id.toString())).post(ProjectEntry.class, paramProj);
    Assert.assertTrue(createResp.name.equals(paramProj.getName()));
    Assert.assertTrue(createResp.id != null);
    expectedProjListResults.get("st2").add(new ProjectEntry(createResp));
    paramProj.setName("subtenant2 project2");
    createResp = rSTAdminGr2.path(String.format(_projectsUrlFormat, subtenant2Id.toString())).post(ProjectEntry.class, paramProj);
    Assert.assertTrue(createResp.name.equals(paramProj.getName()));
    Assert.assertTrue(createResp.id != null);
    expectedProjListResults.get("st2").add(new ProjectEntry(createResp));
    // negative - create
    paramProj = new ProjectParam("bad");
    // tenant admin on root, can not create projects on subtenants
    resp = rTAdmin.path(String.format(_projectsUrlFormat, subtenant1Id.toString())).post(ClientResponse.class, paramProj);
    Assert.assertEquals(403, resp.getStatus());
    // tenant admin at subtenant level can not create project on root tenant
    resp = rSTAdmin1.path(String.format(_projectsUrlFormat, rootTenantId.toString())).post(ClientResponse.class, paramProj);
    Assert.assertEquals(403, resp.getStatus());
    // tenant admin at subtenant2 can not create project on subtenant1
    resp = rSTAdmin2.path(String.format(_projectsUrlFormat, subtenant1Id.toString())).post(ClientResponse.class, paramProj);
    Assert.assertEquals(403, resp.getStatus());
    // project admin at subtenant1 can not create project on subtenant2
    resp = rSTAdminGr1.path(String.format(_projectsUrlFormat, subtenant2Id.toString())).post(ClientResponse.class, paramProj);
    Assert.assertEquals(403, resp.getStatus());
    // create project on deleted tenant
    tenantParam.setLabel("toremove");
    tenantParam.setDescription("toremove subtenant");
    tenantParam.setUserMappings(new ArrayList<UserMappingParam>());
    UserMappingParam tenantMappingToRemove = new UserMappingParam();
    tenantMappingToRemove.setDomain("sanity.local");
    UserMappingAttributeParam tenantAttr3 = new UserMappingAttributeParam();
    tenantAttr3.setKey("company");
    tenantAttr3.setValues(Collections.singletonList("toremove"));
    tenantMappingToRemove.setAttributes(Collections.singletonList(tenantAttr3));
    tenantParam.getUserMappings().add(tenantMappingToRemove);
    TenantOrgRestRep stDeleted = rTAdminGr.path(subtenant_url).post(TenantOrgRestRep.class, tenantParam);
    rTAdminGr.path("/tenants/" + stDeleted.getId() + "/deactivate").post();
    resp = rTAdminGr.path(String.format(_projectsUrlFormat, stDeleted.getId())).post(ClientResponse.class, paramProj);
    Assert.assertEquals(404, resp.getStatus());
    // list and compare
    ProjectList projList = rSys.path(String.format(_projectsUrlFormat, rootTenantId.toString())).get(ProjectList.class);
    Assert.assertTrue(checkEqualsList(projList._projects, expectedProjListResults.get("root")));
    projList = rTAdmin.path(String.format(_projectsUrlFormat, rootTenantId.toString())).get(ProjectList.class);
    Assert.assertTrue(checkEqualsList(projList._projects, expectedProjListResults.get("root")));
    projList = rSys.path(String.format(_projectsUrlFormat, subtenant1Id.toString())).get(ProjectList.class);
    Assert.assertTrue(checkEqualsList(projList._projects, expectedProjListResults.get("st1")));
    projList = rSTAdmin1.path(String.format(_projectsUrlFormat, subtenant1Id.toString())).get(ProjectList.class);
    Assert.assertTrue(checkEqualsList(projList._projects, expectedProjListResults.get("st1")));
    projList = rSTAdmin2.path(String.format(_projectsUrlFormat, subtenant2Id.toString())).get(ProjectList.class);
    Assert.assertTrue(checkEqualsList(projList._projects, expectedProjListResults.get("st2")));
    projList = rSTAdminGr1.path(String.format(_projectsUrlFormat, subtenant1Id.toString())).get(ProjectList.class);
    Assert.assertEquals(1, projList._projects.size());
    Assert.assertTrue(projList._projects.get(0).name.equals("subtenant1 project2"));
    resp = rSTAdmin1.path(String.format(_projectsUrlFormat, rootTenantId.toString())).get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
    resp = rSTAdmin1.path(String.format(_projectsUrlFormat, subtenant2Id.toString())).get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
    // negative test:
    // 1. with TENANT_ADMIN user from root tenant, create subtenant
    // 2. with same user, create project in subtenant
    // 3. with same user, remove TENANT_ADMIN on himself in subtenant
    // 4. with same user, do get /projects/id/acl so show his project ownership
    // is still honored. (cq605248)
    String crossUserSubtenantUrl = rootTenantBaseUrl + "/subtenants";
    TenantCreateParam tenantParam2 = new TenantCreateParam();
    tenantParam2.setLabel("subtenantwithuserfromroottenant");
    tenantParam2.setDescription("subtenant where user from root tenant owns projects");
    tenantParam2.setUserMappings(new ArrayList<UserMappingParam>());
    UserMappingParam tenantMapping3 = new UserMappingParam();
    tenantMapping3.setDomain("sanity.local");
    UserMappingAttributeParam crossTenantAttr = new UserMappingAttributeParam();
    crossTenantAttr.setKey("COMPANY");
    crossTenantAttr.setValues(Collections.singletonList("crosstenant"));
    tenantMapping3.setAttributes(Collections.singletonList(crossTenantAttr));
    tenantParam2.getUserMappings().add(tenantMapping3);
    TenantOrgRestRep crossUserSubtenant = rTAdmin.path(crossUserSubtenantUrl).post(TenantOrgRestRep.class, tenantParam2);
    Assert.assertNotNull(crossUserSubtenant);
    paramProj = new ProjectParam();
    paramProj.setName("crosstenantuserproject");
    ProjectEntry project = rTAdmin.path(String.format(_projectsUrlFormat, crossUserSubtenant.getId().toString())).post(ProjectEntry.class, paramProj);
    Assert.assertNotNull(project);
    RoleAssignmentEntry rtTenantAdminUserEntry = new RoleAssignmentEntry();
    rtTenantAdminUserEntry.setSubjectId(ROOTTENANTADMIN);
    rtTenantAdminUserEntry.getRoles().add("TENANT_ADMIN");
    changes = new RoleAssignmentChanges();
    changes.setRemove(new ArrayList<RoleAssignmentEntry>());
    changes.getRemove().add(rtTenantAdminUserEntry);
    resp = rTAdmin.path(String.format(roles_url_format, crossUserSubtenant.getId().toString())).put(ClientResponse.class, changes);
    Assert.assertEquals(200, resp.getStatus());
    resp = rTAdmin.path(String.format(_projectAclUrl, project.id.toString())).get(ClientResponse.class);
    Assert.assertEquals(200, resp.getStatus());
    // negative test:
    // 1. assign TENANT_ADMIN to a group called ASubSetOfUsers in the root tenant
    // 2. Login with cross1@sanity.local. That user is part of the group above however is mapped
    // to the crosssubtenant by his attribute company=crosstenant. Therefore he should not be allowed
    // to perform a TENANT_ADMIN call in the root tenant.
    entry1 = new RoleAssignmentEntry();
    entry1.setGroup(ASUBSETOFUSERS_GROUP);
    entry1.getRoles().add("TENANT_ADMIN");
    changes = new RoleAssignmentChanges();
    changes.setAdd(new ArrayList<RoleAssignmentEntry>());
    changes.getAdd().add(entry1);
    resp = rSys.path(String.format(roles_url_format, rootTenantId.toString())).put(ClientResponse.class, changes);
    Assert.assertEquals(200, resp.getStatus());
    resp = rSTCross.path("/tenants/" + rootTenantId.toString()).get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
    // list auth providers tests (CTRL-4314)
    // SECURITY_ADMIN can access auth providers
    resp = rZAdmin.path("/vdc/admin/authnproviders").get(ClientResponse.class);
    Assert.assertEquals(200, resp.getStatus());
    // root tenant TENANT_ADMIN can access auth providers
    resp = rTAdmin.path("/vdc/admin/authnproviders").get(ClientResponse.class);
    Assert.assertEquals(200, resp.getStatus());
    // subtenant TENANT_ADMIN can access auth providers
    resp = rSTAdmin2.path("/vdc/admin/authnproviders").get(ClientResponse.class);
    Assert.assertEquals(200, resp.getStatus());
    // regular user can't access auth providers
    resp = rUnAuth.path("/vdc/admin/authnproviders").get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
    // make the user the admin of a subtenant (not their home tenant)
    assignTenantRole(subtenant3Id.toString(), ROOTUSER, "TENANT_ADMIN");
    // subtenant TENANT_ADMIN can access auth providers, even if they aren't admin of their home tenant
    resp = rUnAuth.path("/vdc/admin/authnproviders").get(ClientResponse.class);
    Assert.assertEquals(200, resp.getStatus());
    // cleanup
    removeTenantRole(subtenant3Id.toString(), ROOTUSER, "TENANT_ADMIN");
    // verify the role was removed
    resp = rUnAuth.path("/vdc/admin/authnproviders").get(ClientResponse.class);
    Assert.assertEquals(403, resp.getStatus());
}
Also used : ClientResponse(com.sun.jersey.api.client.ClientResponse) AuthnUpdateParam(com.emc.storageos.model.auth.AuthnUpdateParam) UserMappingParam(com.emc.storageos.model.tenant.UserMappingParam) VirtualArrayList(com.emc.storageos.model.varray.VirtualArrayList) ArrayList(java.util.ArrayList) TenantCreateParam(com.emc.storageos.model.tenant.TenantCreateParam) TenantUpdateParam(com.emc.storageos.model.tenant.TenantUpdateParam) UserTenant(com.emc.storageos.security.resource.UserInfoPage.UserTenant) UserMappingAttributeParam(com.emc.storageos.model.tenant.UserMappingAttributeParam) RoleAssignmentChanges(com.emc.storageos.model.auth.RoleAssignmentChanges) ProjectParam(com.emc.storageos.model.project.ProjectParam) UserMappingChanges(com.emc.storageos.model.tenant.UserMappingChanges) RoleAssignmentEntry(com.emc.storageos.model.auth.RoleAssignmentEntry) RoleAssignments(com.emc.storageos.model.auth.RoleAssignments) UserTenantList(com.emc.storageos.security.resource.UserInfoPage.UserTenantList) TenantOrgList(com.emc.storageos.model.tenant.TenantOrgList) TenantOrgRestRep(com.emc.storageos.model.tenant.TenantOrgRestRep) TenantResponse(com.emc.storageos.model.tenant.TenantResponse)

Aggregations

TenantOrgList (com.emc.storageos.model.tenant.TenantOrgList)4 ArrayList (java.util.ArrayList)3 NamedElementQueryResultList (com.emc.storageos.db.client.constraint.NamedElementQueryResultList)2 StringSet (com.emc.storageos.db.client.model.StringSet)2 TenantOrg (com.emc.storageos.db.client.model.TenantOrg)2 TenantResponse (com.emc.storageos.model.tenant.TenantResponse)2 VirtualArrayList (com.emc.storageos.model.varray.VirtualArrayList)2 ClientResponse (com.sun.jersey.api.client.ClientResponse)2 HashSet (java.util.HashSet)2 AbstractChangeTrackingSet (com.emc.storageos.db.client.model.AbstractChangeTrackingSet)1 NamedURI (com.emc.storageos.db.client.model.NamedURI)1 NamedRelatedResourceRep (com.emc.storageos.model.NamedRelatedResourceRep)1 TagAssignment (com.emc.storageos.model.TagAssignment)1 ACLAssignmentChanges (com.emc.storageos.model.auth.ACLAssignmentChanges)1 ACLAssignments (com.emc.storageos.model.auth.ACLAssignments)1 ACLEntry (com.emc.storageos.model.auth.ACLEntry)1 AuthnUpdateParam (com.emc.storageos.model.auth.AuthnUpdateParam)1 RoleAssignmentChanges (com.emc.storageos.model.auth.RoleAssignmentChanges)1 RoleAssignmentEntry (com.emc.storageos.model.auth.RoleAssignmentEntry)1 RoleAssignments (com.emc.storageos.model.auth.RoleAssignments)1