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;
}
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);
}
}
}
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);
}
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());
}
Aggregations