use of com.emc.storageos.model.auth.AuthnUpdateParam in project coprhd-controller by CoprHD.
the class ApiTest method disabledAuthnProviderTest.
/**
* test tenantCreation will fail, if the authn provider is disabled
*
* @throws Exception
*/
public void disabledAuthnProviderTest() throws Exception {
// create a disabled authn provider
String domain = "secqe.com";
AuthnCreateParam param = new AuthnCreateParam();
param.setLabel("secqe.com");
param.setDescription("ad apitest disabled auth provider");
param.setDisable(true);
param.getDomains().add(domain);
param.setGroupAttribute("CN");
param.setManagerDn("CN=Administrator,CN=Users,DC=secqe,DC=com");
param.setManagerPassword(AD_PASS_WORD);
param.setSearchBase("CN=Users,DC=secqe,DC=com");
param.setSearchFilter("userPrincipalName=%u");
param.setServerUrls(new HashSet<String>());
param.getServerUrls().add("ldap:\\" + AD_SERVER2_IP);
param.setMode("ad");
AuthnProviderRestRep resp = rSys.path("/vdc/admin/authnproviders").post(AuthnProviderRestRep.class, param);
Assert.assertNotNull(resp.getId());
// create tenant against the disabled authn provider, should fail
String groupName = "e2egroup";
ClientResponse response = createTenant("disabled_tenant" + new Random().nextInt(), domain, groupName);
Assert.assertEquals(400, response.getStatus());
// enable the authn provider
AuthnUpdateParam updateParam = new AuthnUpdateParam();
updateParam.setDisable(false);
response = rSys.path("/vdc/admin/authnproviders/" + resp.getId()).put(ClientResponse.class, updateParam);
Assert.assertEquals(200, response.getStatus());
// create the tenant again, should success
response = createTenant("disabled_tenant" + new Random().nextInt(), domain, groupName);
Assert.assertEquals(200, response.getStatus());
}
use of com.emc.storageos.model.auth.AuthnUpdateParam 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());
}
use of com.emc.storageos.model.auth.AuthnUpdateParam in project coprhd-controller by CoprHD.
the class ApiTest method addBadADConfig.
// right now, this only test one particular bad parameter (search filter).
// We can enhance this to test out all the precheckConditions present in the AuthnConfigurationService
private void addBadADConfig() throws NoSuchAlgorithmException {
// Test that a config without a proper filter (key=%u) results in 400
AuthnCreateParam param = new AuthnCreateParam();
param.setLabel("ad apitest config bad");
param.setDescription("ad configuration created by ApiTest.java");
param.setDisable(false);
param.getDomains().add("sanity2.local");
param.setGroupAttribute("CN");
param.setGroupWhitelistValues(new HashSet<String>());
param.getGroupWhitelistValues().add("*Admins*");
param.getGroupWhitelistValues().add("*Test*");
param.getGroupWhitelistValues().add("*Users*");
param.setManagerDn("CN=Administrator,CN=Users,DC=sanity,DC=local");
param.setManagerPassword(AD_PASS_WORD);
param.setSearchBase("CN=Users,DC=sanity,DC=local");
// %u is there but not on the right side of the "=". Adding this config should fail
param.setSearchFilter("%u=userPrincipalName");
param.setServerUrls(new HashSet<String>());
param.getServerUrls().add("ldap:\\" + AD_SERVER1_IP);
param.setMode("ad");
ClientResponse resp = rSys.path("/vdc/admin/authnproviders").post(ClientResponse.class, param);
Assert.assertEquals(400, resp.getStatus());
// Test that adding two profiles with the same domain name results in 400
String label = "ad apitest config duplicate 1";
AuthnCreateParam duplicateConfig1 = new AuthnCreateParam();
duplicateConfig1.setLabel(label);
duplicateConfig1.setDescription("ad configuration created by ApiTest.java");
duplicateConfig1.setDisable(false);
duplicateConfig1.getDomains().add("mydomain.com");
duplicateConfig1.setGroupAttribute("CN");
duplicateConfig1.setGroupWhitelistValues(new HashSet<String>());
duplicateConfig1.getGroupWhitelistValues().add("*Admins*");
duplicateConfig1.setManagerDn("CN=Administrator,CN=Users,DC=sanity,DC=local");
duplicateConfig1.setManagerPassword(AD_PASS_WORD);
duplicateConfig1.setSearchBase("CN=Users,DC=sanity,DC=local");
duplicateConfig1.setSearchFilter("userPrincipalName=%u");
duplicateConfig1.setServerUrls(new HashSet<String>());
duplicateConfig1.getServerUrls().add("ldap:\\" + AD_SERVER1_IP);
duplicateConfig1.setMode("ad");
AuthnProviderRestRep authnResp = rSys.path("/vdc/admin/authnproviders").post(AuthnProviderRestRep.class, duplicateConfig1);
Assert.assertNotNull(authnResp);
URI firstCreatedConfig = authnResp.getId();
AuthnCreateParam duplicateConfig2 = new AuthnCreateParam();
duplicateConfig2.setLabel("ad apitest config duplicate 2");
duplicateConfig2.setDescription("ad configuration created by ApiTest.java");
duplicateConfig2.setDisable(false);
duplicateConfig2.getDomains().add("mydomain.com");
duplicateConfig2.setGroupAttribute("CN");
duplicateConfig2.setGroupWhitelistValues(new HashSet<String>());
duplicateConfig2.getGroupWhitelistValues().add("*Admins*");
duplicateConfig2.setManagerDn("CN=Administrator,CN=Users,DC=sanity,DC=local");
duplicateConfig2.setManagerPassword(AD_PASS_WORD);
duplicateConfig2.setSearchBase("CN=Users,DC=sanity,DC=local");
duplicateConfig2.setSearchFilter("userPrincipalName=%u");
duplicateConfig2.setServerUrls(new HashSet<String>());
duplicateConfig2.getServerUrls().add("ldap:\\" + AD_SERVER1_IP);
duplicateConfig2.setMode("ad");
resp = rSys.path("/vdc/admin/authnproviders").post(ClientResponse.class, duplicateConfig2);
Assert.assertEquals(400, resp.getStatus());
// Test for duplicate name check (post)
duplicateConfig2.setLabel(label);
duplicateConfig2.getDomains().add("mydomain2.com");
resp = rSys.path("/vdc/admin/authnproviders").post(ClientResponse.class, duplicateConfig2);
Assert.assertEquals(400, resp.getStatus());
// Test that you cannot update an existing with a domain name that exists somewhere else
AuthnUpdateParam updateParam = new AuthnUpdateParam();
updateParam.getDomainChanges().getAdd().add("sanity.local");
String myDomainComauthnProvidersUrlFormat = String.format("/vdc/admin/authnproviders/%s", firstCreatedConfig.toString());
resp = rSys.path(myDomainComauthnProvidersUrlFormat).put(ClientResponse.class, updateParam);
Assert.assertEquals(400, resp.getStatus());
// test that updating the config with the same name as itself is fine (no op)
AuthnUpdateParam updateParamSameName = new AuthnUpdateParam();
updateParamSameName.getDomainChanges().getAdd().add("mydomain.com");
resp = rSys.path(myDomainComauthnProvidersUrlFormat).put(ClientResponse.class, updateParamSameName);
Assert.assertEquals(200, resp.getStatus());
// test that trying to update a config with a name too short causes 400
AuthnUpdateParam updateParamNameTooShort = new AuthnUpdateParam();
updateParamNameTooShort.setLabel("a");
resp = rSys.path(myDomainComauthnProvidersUrlFormat).put(ClientResponse.class, updateParamNameTooShort);
Assert.assertEquals(400, resp.getStatus());
// test that trying to update a config with a name too long causes 400
AuthnUpdateParam updateParamNameTooLong = new AuthnUpdateParam();
updateParamNameTooLong.setLabel("authn" + STR144);
resp = rSys.path(myDomainComauthnProvidersUrlFormat).put(ClientResponse.class, updateParamNameTooLong);
Assert.assertEquals(400, resp.getStatus());
// test that trying to update a config with the same name doesn't cause an error
AuthnUpdateParam updateParam2 = new AuthnUpdateParam();
updateParam2.setLabel(label);
resp = rSys.path(myDomainComauthnProvidersUrlFormat).put(ClientResponse.class, updateParam2);
Assert.assertEquals(200, resp.getStatus());
// test that the String payload will be trimmed
updateParam2 = new AuthnUpdateParam();
updateParam2.setLabel(" " + label + " ");
authnResp = rSys.path(myDomainComauthnProvidersUrlFormat).put(AuthnProviderRestRep.class, updateParam2);
Assert.assertTrue(authnResp.getName().equals(label));
// Mark the mydomain.com provider as disabled. Try to add a conflicting domain provider.
// Should still fail. Because even though disabled the provider can eventually be renabled.
AuthnUpdateParam updateParam3 = new AuthnUpdateParam();
updateParam3.setDisable(true);
resp = rSys.path(myDomainComauthnProvidersUrlFormat).put(ClientResponse.class, updateParam3);
Assert.assertEquals(200, resp.getStatus());
resp = rSys.path(myDomainComauthnProvidersUrlFormat).put(ClientResponse.class, updateParam);
Assert.assertEquals(400, resp.getStatus());
// Now delete that mydomain.com provider and re-add it, see that
// it is now allowed because the conflicting provider has been deleted
resp = rSys.path(myDomainComauthnProvidersUrlFormat).delete(ClientResponse.class);
Assert.assertEquals(200, resp.getStatus());
authnResp = rSys.path("/vdc/admin/authnproviders").post(AuthnProviderRestRep.class, duplicateConfig1);
Assert.assertNotNull(authnResp);
// Test that updating a config with a MaxPageSize=0 fails
AuthnUpdateParam pageSizeUpdateParam = new AuthnUpdateParam();
pageSizeUpdateParam.setMaxPageSize(0);
resp = rSys.path(String.format("/vdc/admin/authnproviders/%s", authnResp.getId().toString())).put(ClientResponse.class, pageSizeUpdateParam);
Assert.assertEquals(400, resp.getStatus());
// Set the page size and verify that it is successful.
pageSizeUpdateParam.setMaxPageSize(500);
resp = rSys.path(String.format("/vdc/admin/authnproviders/%s", authnResp.getId().toString())).put(ClientResponse.class, pageSizeUpdateParam);
Assert.assertEquals(200, resp.getStatus());
// Get the provider and verify that it has the new page size
authnResp = rSys.path(String.format("/vdc/admin/authnproviders/%s", authnResp.getId().toString())).get(AuthnProviderRestRep.class);
Assert.assertEquals(pageSizeUpdateParam.getMaxPageSize().intValue(), authnResp.getMaxPageSize().intValue());
// Test that a bad search scope gets rejected.
// Missing scope is tested by all the other tests above which do not
// supply scope.
AuthnCreateParam badScopeParam = new AuthnCreateParam();
badScopeParam.setLabel("ad apitest config with bad scope");
badScopeParam.setDescription("ad configuration created by ApiTest.java");
badScopeParam.setDisable(false);
badScopeParam.getDomains().add("mydomain4.com");
badScopeParam.setGroupAttribute("CN");
badScopeParam.setGroupWhitelistValues(new HashSet<String>());
badScopeParam.getGroupWhitelistValues().add("*Admins*");
badScopeParam.setManagerDn("CN=Administrator,CN=Users,DC=sanity,DC=local");
badScopeParam.setManagerPassword(AD_PASS_WORD);
badScopeParam.setSearchBase("CN=Users,DC=sanity,DC=local");
badScopeParam.setSearchFilter("userPrincipalName=%u");
badScopeParam.setServerUrls(new HashSet<String>());
badScopeParam.getServerUrls().add("ldap:\\" + AD_SERVER1_IP);
// BAD SCOPE
badScopeParam.setSearchScope("bad scope");
badScopeParam.setMode("ad");
resp = rSys.path("/vdc/admin/authnproviders").post(ClientResponse.class, badScopeParam);
Assert.assertEquals(400, resp.getStatus());
// Test that a good search scope works
AuthnCreateParam goodScopeParam = new AuthnCreateParam();
String goodScopeName = "ad apitest config with good scope";
goodScopeParam.setLabel(goodScopeName);
goodScopeParam.setDescription("ad configuration created by ApiTest.java");
goodScopeParam.setDisable(false);
goodScopeParam.getDomains().add("mydomain5.com");
goodScopeParam.setGroupAttribute("CN");
goodScopeParam.setGroupWhitelistValues(new HashSet<String>());
goodScopeParam.getGroupWhitelistValues().add("*Admins*");
goodScopeParam.setManagerDn("CN=Administrator,CN=Users,DC=sanity,DC=local");
goodScopeParam.setManagerPassword(AD_PASS_WORD);
goodScopeParam.setSearchBase("CN=Users,DC=sanity,DC=local");
goodScopeParam.setSearchFilter("userPrincipalName=%u");
goodScopeParam.setServerUrls(new HashSet<String>());
goodScopeParam.getServerUrls().add("ldap:\\" + AD_SERVER1_IP);
goodScopeParam.setSearchScope(AuthnProvider.SearchScope.SUBTREE.toString());
goodScopeParam.setMode("ad");
resp = rSys.path("/vdc/admin/authnproviders").post(ClientResponse.class, goodScopeParam);
Assert.assertEquals(200, resp.getStatus());
// create a config, then try to modify its name to one that exists.
AuthnCreateParam randomConfig = new AuthnCreateParam();
randomConfig.setLabel("random");
randomConfig.setDescription("random provider");
randomConfig.setDisable(false);
randomConfig.getDomains().add("mydomain6.com");
randomConfig.setGroupAttribute("CN");
randomConfig.setGroupWhitelistValues(new HashSet<String>());
randomConfig.getGroupWhitelistValues().add("*Admins*");
randomConfig.setManagerDn("CN=Administrator,CN=Users,DC=sanity,DC=local");
randomConfig.setManagerPassword(AD_PASS_WORD);
randomConfig.setSearchBase("CN=Users,DC=sanity,DC=local");
randomConfig.setSearchFilter("userPrincipalName=%u");
randomConfig.setServerUrls(new HashSet<String>());
randomConfig.getServerUrls().add("ldap:\\" + AD_SERVER1_IP);
randomConfig.setSearchScope(AuthnProvider.SearchScope.SUBTREE.toString());
randomConfig.setMode("ad");
AuthnProviderRestRep authnResp2 = rSys.path("/vdc/admin/authnproviders").post(AuthnProviderRestRep.class, randomConfig);
Assert.assertNotNull(authnResp2);
AuthnUpdateParam updateParam4 = new AuthnUpdateParam();
updateParam4.setLabel(goodScopeName);
resp = rSys.path(String.format("/vdc/admin/authnproviders/%s", authnResp2.getId().toString())).put(ClientResponse.class, updateParam4);
Assert.assertEquals(400, resp.getStatus());
// attempt to delete the only url in the config. should fail with 400
AuthnUpdateParam lastUrl = new AuthnUpdateParam();
lastUrl.getServerUrlChanges().setRemove(new HashSet<String>());
lastUrl.getServerUrlChanges().getRemove().add("ldap:\\" + AD_SERVER1_IP);
resp = rSys.path(String.format("/vdc/admin/authnproviders/%s", _goodADConfig)).put(ClientResponse.class, lastUrl);
Assert.assertEquals(400, resp.getStatus());
// modify the main config with a bad group CN. Verify you get 400
AuthnUpdateParam badCN = new AuthnUpdateParam();
badCN.setGroupAttribute("garbage");
resp = rSys.path(String.format("/vdc/admin/authnproviders/%s", _goodADConfig)).queryParam("allow_group_attr_change", "true").put(ClientResponse.class, badCN);
String errorMessage = String.format("The authentication provider could not be added or modified because of the following error: The group attribute %s could not be found in AD schema at server [%s].", badCN.getGroupAttribute(), "ldap:\\" + AD_SERVER1_IP);
assertExpectedError(resp, 400, ServiceCode.API_PARAMETER_INVALID, errorMessage);
_savedTokens.remove(ROOTTENANTADMIN);
// put the config back.
AuthnUpdateParam goodCN = new AuthnUpdateParam();
goodCN.setGroupAttribute("CN");
resp = rSys.path(String.format("/vdc/admin/authnproviders/%s", _goodADConfig)).queryParam("allow_group_attr_change", "true").put(ClientResponse.class, goodCN);
Assert.assertEquals(200, resp.getStatus());
// modify the group attribute. Should fail.
AuthnUpdateParam changeCN = new AuthnUpdateParam();
changeCN.setGroupAttribute("objectSid");
resp = rSys.path(String.format("/vdc/admin/authnproviders/%s", _goodADConfig)).put(ClientResponse.class, changeCN);
Assert.assertEquals(400, resp.getStatus());
// modify the group attribute with force flag. Should succeed.
resp = rSys.path(String.format("/vdc/admin/authnproviders/%s", _goodADConfig)).queryParam("allow_group_attr_change", "true").put(ClientResponse.class, changeCN);
Assert.assertEquals(200, resp.getStatus());
// put the original group attribute back for the rest of the tests.
changeCN.setGroupAttribute("CN");
resp = rSys.path(String.format("/vdc/admin/authnproviders/%s", _goodADConfig)).queryParam("allow_group_attr_change", "true").put(ClientResponse.class, changeCN);
Assert.assertEquals(200, resp.getStatus());
}
use of com.emc.storageos.model.auth.AuthnUpdateParam in project coprhd-controller by CoprHD.
the class ApiTestAuthnProviders method testAuthnProviderEditByRemovingLDAPGroupProperties.
@Test
public void testAuthnProviderEditByRemovingLDAPGroupProperties() {
final String testName = "testAuthnProviderEditByRemovingLDAPGroupProperties - ";
AuthnCreateParam createParam = getDefaultAuthnCreateParam(testName + TRACE_AUTHN_PROVIDER_SUCCESSFUL);
AuthnProviderRestRep createResp = rSys.path(getTestApi()).post(AuthnProviderRestRep.class, createParam);
validateAuthProviderCreateSuccess(createParam, createResp);
// Now edit the created authn provider.
final String editAPI = getTestEditApi(createResp.getId());
AuthnUpdateParam editParam = getAuthnUpdateParamFromAuthnProviderRestResp(createResp);
Set<String> addedGroupObjectClasses = new LinkedHashSet<String>();
addedGroupObjectClasses.addAll(editParam.getGroupObjectClassChanges().getAdd());
Set<String> addedGroupMemberAttributes = new LinkedHashSet<String>();
addedGroupMemberAttributes.addAll(editParam.getGroupMemberAttributeChanges().getAdd());
// Remove everything from the add list
editParam.getGroupObjectClassChanges().getAdd().clear();
editParam.getGroupMemberAttributeChanges().getAdd().clear();
// Add everything to the remove list.
editParam.getGroupObjectClassChanges().getRemove().addAll(addedGroupObjectClasses);
editParam.getGroupMemberAttributeChanges().getRemove().addAll(addedGroupMemberAttributes);
editParam.setDescription(testName + "Edit by removing the ldap group properties");
// Now, Send the put request to edit the auth provider with duplicate ldap group properties.
// The request should be be successful and ldap group properties should not have any duplicates.
AuthnProviderRestRep editResp = rSys.path(editAPI).put(AuthnProviderRestRep.class, editParam);
validateAuthProviderEditSuccess(editParam, editResp);
editParam = getAuthnUpdateParamFromAuthnProviderRestResp(createResp);
editParam.setDescription(testName + "Edit after removing the ldap group properties to reset with default values");
// Now, Send the put request to edit the auth provider with duplicate ldap group properties.
// The request should be be successful and ldap group properties should not have any duplicates.
editResp = rSys.path(editAPI).put(AuthnProviderRestRep.class, editParam);
validateAuthProviderEditSuccess(editParam, editResp);
editParam.getGroupObjectClassChanges().getAdd().clear();
editParam.getGroupMemberAttributeChanges().getAdd().clear();
// Add only first two group object classes to the add list.
editParam.getGroupObjectClassChanges().getAdd().add(this.getGroupObjectClass(0));
editParam.getGroupObjectClassChanges().getAdd().add(this.getGroupObjectClass(1));
// Add only last two group object classes to the remove list.
editParam.getGroupObjectClassChanges().getRemove().add(this.getGroupObjectClass(2));
editParam.getGroupObjectClassChanges().getRemove().add(this.getGroupObjectClass(3));
// Add only first two group member attributes to the add list.
editParam.getGroupMemberAttributeChanges().getAdd().add(this.getGroupMemberAttribute(0));
editParam.getGroupMemberAttributeChanges().getAdd().add(this.getGroupMemberAttribute(1));
// Add only last two group member attributes to the remove list.
editParam.getGroupMemberAttributeChanges().getRemove().add(this.getGroupMemberAttribute(2));
editParam.getGroupMemberAttributeChanges().getRemove().add(this.getGroupMemberAttribute(3));
editParam.setDescription(testName + "Edit by removing and adding the ldap group properties in one update");
// Now, Send the put request to edit the auth provider with duplicate ldap group properties.
// The request should be be successful and ldap group properties should not have any duplicates.
editResp = rSys.path(editAPI).put(AuthnProviderRestRep.class, editParam);
validateAuthProviderEditSuccess(editParam, editResp);
editParam.getGroupObjectClassChanges().getAdd().clear();
editParam.getGroupMemberAttributeChanges().getAdd().clear();
editParam.getGroupObjectClassChanges().getRemove().clear();
editParam.getGroupMemberAttributeChanges().getRemove().clear();
editParam.getGroupObjectClassChanges().getRemove().add(this.getGroupObjectClass(0));
editParam.getGroupObjectClassChanges().getRemove().add(this.getGroupObjectClass(1));
editParam.setDescription(testName + "Edit by just removing all the group object classes only.");
// Now, Send the put request to edit the auth provider to remove all the object classes and keep
// member attributes.
// The request should fail as both group object classes and member attributes
// can be empty or both can have values. Just only one containing values is
// not allowed.
ClientResponse clientEditResp = rSys.path(editAPI).put(ClientResponse.class, editParam);
// Since the createParam does not contain group object classes, the request
// should fail with the below error.
String partialExpectedErrorMsg = AUTHN_PROVIDER_ADD_UPDATE_PARTIAL_ERROR + "modified because of the following error: Group object classes are not provided.";
validateAuthProviderBadRequest(HttpStatus.SC_BAD_REQUEST, partialExpectedErrorMsg, clientEditResp);
editParam.getGroupObjectClassChanges().getAdd().clear();
editParam.getGroupMemberAttributeChanges().getAdd().clear();
editParam.getGroupObjectClassChanges().getRemove().clear();
editParam.getGroupMemberAttributeChanges().getRemove().clear();
editParam.getGroupMemberAttributeChanges().getRemove().add(this.getGroupMemberAttribute(0));
editParam.getGroupMemberAttributeChanges().getRemove().add(this.getGroupMemberAttribute(1));
editParam.setDescription(testName + "Edit by just removing all the group member attributes only.");
// Now, Send the put request to edit the auth provider to remove all the member attributes and keep
// object classes.
// The request should fail as both group object classes and member attributes
// can be empty or both can have values. Just only one containing values is
// not allowed.
clientEditResp = rSys.path(editAPI).put(ClientResponse.class, editParam);
// Since the createParam does not contain group member attributes, the request
// should fail with the below error.
partialExpectedErrorMsg = AUTHN_PROVIDER_ADD_UPDATE_PARTIAL_ERROR + "modified because of the following error: Group member attributes are not provided.";
validateAuthProviderBadRequest(HttpStatus.SC_BAD_REQUEST, partialExpectedErrorMsg, clientEditResp);
}
use of com.emc.storageos.model.auth.AuthnUpdateParam in project coprhd-controller by CoprHD.
the class ApiTestAuthnProviders method testAuthnProviderEditWithLDAPGroupMemberAttributesOnly.
@Test
public void testAuthnProviderEditWithLDAPGroupMemberAttributesOnly() {
final String testName = "testAuthnProviderEditWithLDAPGroupMemberAttributesOnly - ";
AuthnCreateParam createParam = getDefaultAuthnCreateParam(testName + TRACE_AUTHN_PROVIDER_SUCCESSFUL);
AuthnProviderRestRep createResp = rSys.path(getTestApi()).post(AuthnProviderRestRep.class, createParam);
validateAuthProviderCreateSuccess(createParam, createResp);
// Now edit the created authn provider.
final String editAPI = getTestEditApi(createResp.getId());
AuthnUpdateParam editParam = getAuthnUpdateParamFromAuthnProviderRestResp(createResp);
// Remove the objectClasses from the editParam.
editParam.getGroupObjectClassChanges().getAdd().clear();
editParam.setDescription(testName + "Edit with only group memberAttributes");
// Now, Send the put request to edit the auth provider with duplicate ldap group properties.
// The reqeust should be be successful and ldap group properties should not have any duplicates.
AuthnProviderRestRep editResp = rSys.path(editAPI).put(AuthnProviderRestRep.class, editParam);
validateAuthProviderEditSuccessForGroupMemberAttributeOnly(editParam, editResp);
// Validate the counts separately to make sure that the counts are removed.
// GroupObjectClasses wont change here as the edit did not change
// the GroupObjectClasses
final int expected = 4;
Assert.assertEquals(expected, editResp.getGroupObjectClasses().size());
Assert.assertEquals(expected, editResp.getGroupMemberAttributes().size());
}
Aggregations