From 2eed716ba418652f20e3fb095f5a825b7ec3facd Mon Sep 17 00:00:00 2001 From: Ofer Levi Date: Sun, 20 Feb 2022 15:05:33 +0200 Subject: [PATCH] Domain Dependency for Tenancy Signed-off-by: Ofer Levi --- .../java/com/yahoo/athenz/zms/DBService.java | 8 + .../java/com/yahoo/athenz/zms/ZMSImpl.java | 115 ++- .../athenz/zms/DomainDependencyTest.java | 22 +- .../com/yahoo/athenz/zms/ZMSImplTest.java | 713 ++++++++++++++++-- 4 files changed, 769 insertions(+), 89 deletions(-) diff --git a/servers/zms/src/main/java/com/yahoo/athenz/zms/DBService.java b/servers/zms/src/main/java/com/yahoo/athenz/zms/DBService.java index ce63b6f3502..6978e87ae40 100644 --- a/servers/zms/src/main/java/com/yahoo/athenz/zms/DBService.java +++ b/servers/zms/src/main/java/com/yahoo/athenz/zms/DBService.java @@ -4351,6 +4351,14 @@ void executePutTenantRoles(ResourceContext ctx, String provSvcDomain, String pro checkDomainAuditEnabled(con, provSvcDomain, auditRef, caller, principalName, AUDIT_TYPE_TENANCY); + // verify tenant domain exists + + Domain domain = con.getDomain(tenantDomain); + if (domain == null) { + con.rollbackChanges(); + throw ZMSUtils.notFoundError(caller + ": Unknown tenant domain: " + tenantDomain, caller); + } + String trustedRolePrefix = ZMSUtils.getTrustedResourceGroupRolePrefix(provSvcDomain, provSvcName, tenantDomain, resourceGroup); diff --git a/servers/zms/src/main/java/com/yahoo/athenz/zms/ZMSImpl.java b/servers/zms/src/main/java/com/yahoo/athenz/zms/ZMSImpl.java index 69f3a2e544f..7c3a4697d67 100644 --- a/servers/zms/src/main/java/com/yahoo/athenz/zms/ZMSImpl.java +++ b/servers/zms/src/main/java/com/yahoo/athenz/zms/ZMSImpl.java @@ -6726,6 +6726,49 @@ public void putTenancy(ResourceContext ctx, String tenantDomain, String provider if (authzServiceTokenOperation) { setupTenantAdminPolicyInProvider(ctx, provSvcDomain, provSvcName, tenantDomain, false, auditRef, caller); + + // If listed as service provider, register dependency between the provider service and the tenant domain (unless dependency exist + // following creation of a previous resource group) + + tenancyRegisterDomainDependency(ctx, tenantDomain, provider, true, auditRef, caller); + } + } + + private void tenancyRegisterDomainDependency(ResourceContext ctx, String tenantDomain, String provider, boolean authzServiceTokenOperation, String auditRef, String caller) { + String serviceToRegister = provider; + try { + serviceToRegister = getAuthorizedProviderService((RsrcCtxWrapper) ctx, serviceToRegister, authzServiceTokenOperation, caller); + if (serviceProviderManager.isServiceProvider(serviceToRegister)) { + + DomainList domainList = dbService.listDomainDependencies(serviceToRegister); + if (!domainList.getNames().contains(tenantDomain)) { + dbService.putDomainDependency(ctx, tenantDomain, serviceToRegister, auditRef, caller); + } + } + } catch (ResourceException ex) { + if (ex.getCode() == ResourceException.UNAUTHORIZED) { + LOG.warn("Not registering domain dependency: " + ex.getMessage()); + return; + } + throw ex; + } + } + + private void tenancyDeregisterDomainDependency(ResourceContext ctx, String tenantDomain, String provSvcDomain, String provSvcName, boolean authzServiceTokenOperation, String auditRef, String caller) { + String serviceToDeregister = provSvcDomain + "." + provSvcName; + try { + serviceToDeregister = getAuthorizedProviderService((RsrcCtxWrapper) ctx, serviceToDeregister, authzServiceTokenOperation, caller); + if (serviceProviderManager.isServiceProvider(serviceToDeregister)) { + boolean tenantDomainRolesExist = isTenantDomainRolesExist(tenantDomain, provSvcDomain, provSvcName); + if (!tenantDomainRolesExist) { + dbService.deleteDomainDependency(ctx, tenantDomain, serviceToDeregister, auditRef, caller); + } + } + } catch (ResourceException ex) { + if (ex.getCode() == ResourceException.UNAUTHORIZED) { + return; + } + throw ex; } } @@ -6776,6 +6819,10 @@ public void deleteTenancy(ResourceContext ctx, String tenantDomain, String provi if (authzServiceTokenOperation) { dbService.executeDeleteTenantRoles(ctx, provSvcDomain, provSvcName, tenantDomain, null, auditRef, caller); + + // If listed as service provider, check if there are remaining resource group roles. If not - de-register dependency between the provider service and the tenant domain + + tenancyDeregisterDomainDependency(ctx, tenantDomain, provSvcDomain, provSvcName, true, auditRef, caller); } // now clean-up local domain roles and policies for this tenant @@ -6834,6 +6881,11 @@ public void putTenant(ResourceContext ctx, String providerDomain, String provide setupTenantAdminPolicyInProvider(ctx, providerDomain, providerService, tenantDomain, false, auditRef, caller); + + // If listed as service provider, register dependency between the provider service and the tenant domain (unless dependency exist + // following creation of a previous resource group) + String provider = providerDomain + "." + providerService; + tenancyRegisterDomainDependency(ctx, tenantDomain, provider, false, auditRef, caller); } @Override @@ -6872,6 +6924,10 @@ public void deleteTenant(ResourceContext ctx, String providerDomain, String prov dbService.executeDeleteTenantRoles(ctx, providerDomain, providerService, tenantDomain, null, auditRef, caller); + + // If listed as service provider, check if there are remaining resource group roles. If not - de-register dependency between the provider service and the tenant domain + + tenancyDeregisterDomainDependency(ctx, tenantDomain, providerDomain, providerService, false, auditRef, caller); } boolean validateTenancyObject(Tenancy tenant, final String tenantDomain, final String providerService) { @@ -6991,6 +7047,13 @@ public TenantResourceGroupRoles putTenantResourceGroupRoles(ResourceContext ctx, dbService.executePutTenantRoles(ctx, provSvcDomain, provSvcName, tenantDomain, resourceGroup, detail.getRoles(), false, auditRef, caller); + + // If listed as service provider, register dependency between the provider service and the tenant domain (unless dependency exist + // following creation of a previous resource group) + + String provider = provSvcDomain + "." + provSvcName; + tenancyRegisterDomainDependency(ctx, tenantDomain, provider, false, auditRef, caller); + return detail; } @@ -7303,9 +7366,25 @@ public void deleteProviderResourceGroupRoles(ResourceContext ctx, String tenantD dbService.executeDeleteTenantRoles(ctx, provSvcDomain, provSvcName, tenantDomain, resourceGroup, auditRef, caller); + + // If listed as service provider, check if there are remaining resource group roles. If not - de-register dependency between the provider service and the tenant domain + + tenancyDeregisterDomainDependency(ctx, tenantDomain, provSvcDomain, provSvcName, true, auditRef, caller); } } + private boolean isTenantDomainRolesExist(String tenantDomain, String provSvcDomain, String provSvcName) { + final String rolePrefix = ZMSUtils.getTenantResourceGroupRolePrefix(provSvcName, tenantDomain, null); + // find roles matching the prefix + + List tenantDomainRoles = dbService.listRoles(provSvcDomain); + boolean tenantDomainRolesExist = tenantDomainRoles.stream() + .filter(role -> dbService.isTenantRolePrefixMatch(role, rolePrefix, null, tenantDomain)) + .findAny() + .isPresent(); + return tenantDomainRolesExist; + } + public ProviderResourceGroupRoles getProviderResourceGroupRoles(ResourceContext ctx, String tenantDomain, String provSvcDomain, String provSvcName, String resourceGroup) { @@ -7492,6 +7571,11 @@ public ProviderResourceGroupRoles putProviderResourceGroupRoles(ResourceContext dbService.executePutTenantRoles(ctx, provSvcDomain, provSvcName, tenantDomain, resourceGroup, roleActions, false, auditRef, caller); + + // If listed as service provider, register dependency between the provider service and the tenant domain (unless dependency exist + // following creation of a previous resource group) + + tenancyRegisterDomainDependency(ctx, tenantDomain, authorizedService, true, auditRef, caller); } return detail; @@ -7630,6 +7714,10 @@ public void deleteTenantResourceGroupRoles(ResourceContext ctx, String provSvcDo dbService.executeDeleteTenantRoles(ctx, provSvcDomain, provSvcName, tenantDomain, resourceGroup, auditRef, caller); + + // If listed as service provider, check if there are remaining resource group roles. If not - de-register dependency between the provider service and the tenant domain + + tenancyDeregisterDomainDependency(ctx, tenantDomain, provSvcDomain, provSvcName, false, auditRef, caller); } void validateRequest(HttpServletRequest request, String caller) { @@ -10206,7 +10294,7 @@ public void putDomainDependency(ResourceContext ctx, String domainName, String a } String service = (dependentService != null) ? dependentService.getService() : null; - service = getAuthorizedProviderService((RsrcCtxWrapper) ctx, service, caller); + service = getAuthorizedProviderService((RsrcCtxWrapper) ctx, service, false, caller); validateRequest(ctx.request(), caller); @@ -10233,7 +10321,7 @@ public void deleteDomainDependency(ResourceContext ctx, String domainName, Strin throw ZMSUtils.requestError(SERVER_READ_ONLY_MESSAGE, caller); } - service = getAuthorizedProviderService((RsrcCtxWrapper) ctx, service, caller); + service = getAuthorizedProviderService((RsrcCtxWrapper) ctx, service, false, caller); validateRequest(ctx.request(), caller); @@ -10251,18 +10339,21 @@ public void deleteDomainDependency(ResourceContext ctx, String domainName, Strin dbService.deleteDomainDependency(ctx, domainName, service, auditRef, caller); } - String getAuthorizedProviderService(RsrcCtxWrapper ctx, String service, String caller) { - // If system administrator - service is mandatory - // Otherwise ignore it and use the principal as dependent service + String getAuthorizedProviderService(RsrcCtxWrapper ctx, String service, boolean authzServiceTokenOperation, String caller) { + + if (!authzServiceTokenOperation) { + // If system administrator - service is mandatory + // Otherwise ignore it and use the principal as dependent service - Principal principal = ctx.principal(); - boolean isSysAdminUser = isSysAdminUser(principal, false); - if (isSysAdminUser) { - if (StringUtil.isEmpty(service)) { - throw ZMSUtils.requestError("service is mandatory", caller); + Principal principal = ctx.principal(); + boolean isSysAdminUser = isSysAdminUser(principal, false); + if (isSysAdminUser) { + if (StringUtil.isEmpty(service)) { + throw ZMSUtils.requestError("service is mandatory", caller); + } + } else { + service = principal.getFullName(); } - } else { - service = principal.getFullName(); } service = service.toLowerCase(); diff --git a/servers/zms/src/test/java/com/yahoo/athenz/zms/DomainDependencyTest.java b/servers/zms/src/test/java/com/yahoo/athenz/zms/DomainDependencyTest.java index 2d446767e06..6fe9808a06a 100644 --- a/servers/zms/src/test/java/com/yahoo/athenz/zms/DomainDependencyTest.java +++ b/servers/zms/src/test/java/com/yahoo/athenz/zms/DomainDependencyTest.java @@ -456,7 +456,7 @@ public void testGetAuthorizedProviderService() { // Throw failure for service which is not a service provider try { - zmsImpl.getAuthorizedProviderService(regularUserCtx, null, caller); + zmsImpl.getAuthorizedProviderService(regularUserCtx, null, false, caller); } catch (ResourceException ex) { assertEquals(ex.getMessage(), "ResourceException (401): {code: 401, message: \"user.user1 is not an authorized service provider\"}"); } @@ -465,7 +465,7 @@ public void testGetAuthorizedProviderService() { RsrcCtxWrapper sysAdminCtx = zmsTestInitializer.contextWithMockPrincipal(caller); try { - zmsImpl.getAuthorizedProviderService(sysAdminCtx, null, caller); + zmsImpl.getAuthorizedProviderService(sysAdminCtx, null, false, caller); } catch (ResourceException ex) { assertEquals(ex.getMessage(), "ResourceException (400): {code: 400, message: \"service is mandatory\"}"); } @@ -473,7 +473,7 @@ public void testGetAuthorizedProviderService() { // Throw failure for system administrator that specified a non service-provider service try { - zmsImpl.getAuthorizedProviderService(sysAdminCtx, "not.service.provider", caller); + zmsImpl.getAuthorizedProviderService(sysAdminCtx, "not.service.provider", false, caller); } catch (ResourceException ex) { assertEquals(ex.getMessage(), "ResourceException (401): {code: 401, message: \"not.service.provider is not an authorized service provider\"}"); } @@ -485,23 +485,29 @@ public void testGetAuthorizedProviderService() { // For non system administrators - trying to specify the service provider isn't enough, principal must be the service provider try { - zmsImpl.getAuthorizedProviderService(regularUserCtx, "service.provider", caller); + zmsImpl.getAuthorizedProviderService(regularUserCtx, "service.provider", false, caller); } catch (ResourceException ex) { assertEquals(ex.getMessage(), "ResourceException (401): {code: 401, message: \"user.user1 is not an authorized service provider\"}"); } // Successful for system administrator or the service provider itself - String authorizedProviderService = zmsImpl.getAuthorizedProviderService(sysAdminCtx, "service.provider", caller); + String authorizedProviderService = zmsImpl.getAuthorizedProviderService(sysAdminCtx, "service.provider", false, caller); assertEquals(authorizedProviderService, "service.provider"); RsrcCtxWrapper serviceProviderCtx = zmsTestInitializer.contextWithMockPrincipal(caller, "service", "provider"); - authorizedProviderService = zmsImpl.getAuthorizedProviderService(serviceProviderCtx, "service.provider", caller); + authorizedProviderService = zmsImpl.getAuthorizedProviderService(serviceProviderCtx, "service.provider", false, caller); assertEquals(authorizedProviderService, "service.provider"); - // Also Successful for system administrator that isn't human + // Successful for system administrator that isn't human RsrcCtxWrapper serviceSysAdminCtx = zmsTestInitializer.generateServiceSysAdmin(caller, "admindomain", "serviceprincipal"); - authorizedProviderService = zmsImpl.getAuthorizedProviderService(serviceSysAdminCtx, "service.provider", caller); + authorizedProviderService = zmsImpl.getAuthorizedProviderService(serviceSysAdminCtx, "service.provider", false, caller); + assertEquals(authorizedProviderService, "service.provider"); + + // Successful for request with authorized service token + + RsrcCtxWrapper nonServiceProviderCtx = zmsTestInitializer.contextWithMockPrincipal(caller, "service", "not-provider"); + authorizedProviderService = zmsImpl.getAuthorizedProviderService(nonServiceProviderCtx, "service.provider", true, caller); assertEquals(authorizedProviderService, "service.provider"); } } diff --git a/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSImplTest.java b/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSImplTest.java index 844ef045942..af09fb28871 100644 --- a/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSImplTest.java +++ b/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSImplTest.java @@ -6540,13 +6540,18 @@ public void testGetTenantResourceGroupRoles() { dom.setAuditEnabled(true); zmsTestInitializer.getZms().postTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), zmsTestInitializer.getAuditRef(), dom); + String tenantDomain = "tenantTestDeleteTenantRoles"; + TopLevelDomain tenantDom = zmsTestInitializer.createTopLevelDomainObject( + tenantDomain, "Tenant Domain", "testOrg", zmsTestInitializer.getAdminUser()); + tenantDom.setAuditEnabled(true); + zmsTestInitializer.getZms().postTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), zmsTestInitializer.getAuditRef(), tenantDom); + List roleActions = new ArrayList<>(); for (Struct.Field f : ZMSTestInitializer.TABLE_PROVIDER_ROLE_ACTIONS) { roleActions.add(new TenantRoleAction().setRole(f.name()).setAction( (String) f.value())); } String serviceName = "storage"; - String tenantDomain = "tenantTestDeleteTenantRoles"; String resourceGroup = "Group1"; TenantResourceGroupRoles tenantRoles = new TenantResourceGroupRoles().setDomain(domain) @@ -6564,7 +6569,134 @@ public void testGetTenantResourceGroupRoles() { assertEquals(resourceGroup.toLowerCase(), tRoles.getResourceGroup()); assertEquals(ZMSTestInitializer.TABLE_PROVIDER_ROLE_ACTIONS.size(), tRoles.getRoles().size()); + // Verify domain dependency wasn't created as the provider isn't listed in the "sys.auth:role.service_providers role + + try { + zmsTestInitializer.getZms().getDependentDomainList(zmsTestInitializer.getMockDomRsrcCtx(), domain + "." + serviceName); + fail(); + } catch (ResourceException ex) { + assertEquals(ex.getMessage(), "ResourceException (400): {code: 400, message: \"testgettenantresourcegrouproles.storage is not a registered service provider\"}"); + } + zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), domain, zmsTestInitializer.getAuditRef()); + zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, zmsTestInitializer.getAuditRef()); + } + + public void makeServiceProviders(ZMSImpl zmsImpl, RsrcCtxWrapper ctx, List providerNames) { + // Create Service Provider + + final String sysAdminDomainName = "sys.auth"; + final String serviceProvidersRoleName = "service_providers"; + List roleMembers = providerNames.stream().map(provider -> { + RoleMember authorizedServiceRoleMember = new RoleMember(); + authorizedServiceRoleMember.setMemberName(provider.toLowerCase()); + return authorizedServiceRoleMember; + }).collect(Collectors.toList()); + Role role = new Role(); + role.setName(serviceProvidersRoleName); + role.setRoleMembers(roleMembers); + + zmsImpl.putRole(ctx, sysAdminDomainName, serviceProvidersRoleName, zmsTestInitializer.getAuditRef(), role); + + // Wait for cache to be ServiceProviderManager cache to refresh + + ZMSTestUtils.sleep((1000 * fetchDomainDependencyFrequency) + 50); + } + + @Test + public void testGetTenantResourceGroupRolesDomainDependency() { + + ZMSImpl zmsImpl = zmsTestInitializer.zmsInit(); + + String domain = "testGetTenantResourceGroupRolesDomainDependency"; + TopLevelDomain dom = zmsTestInitializer.createTopLevelDomainObject( + domain, "Test Domain1", "testOrg", zmsTestInitializer.getAdminUser()); + dom.setAuditEnabled(true); + zmsImpl.postTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), zmsTestInitializer.getAuditRef(), dom); + + String tenantDomain = "tenantTestGetTenantResourceGroupRolesDomainDependency"; + TopLevelDomain tenantDom = zmsTestInitializer.createTopLevelDomainObject( + tenantDomain, "Tenant Domain", "testOrg", zmsTestInitializer.getAdminUser()); + tenantDom.setAuditEnabled(true); + zmsImpl.postTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), zmsTestInitializer.getAuditRef(), tenantDom); + + List roleActions = new ArrayList<>(); + for (Struct.Field f : ZMSTestInitializer.TABLE_PROVIDER_ROLE_ACTIONS) { + roleActions.add(new TenantRoleAction().setRole(f.name()).setAction( + (String) f.value())); + } + String serviceName = "storage"; + String resourceGroup = "Group1"; + + makeServiceProviders(zmsImpl, zmsTestInitializer.getMockDomRsrcCtx(), Collections.singletonList(domain + "." + serviceName)); + TenantResourceGroupRoles tenantRoles = new TenantResourceGroupRoles().setDomain(domain) + .setService(serviceName).setTenant(tenantDomain) + .setRoles(roleActions).setResourceGroup(resourceGroup); + RsrcCtxWrapper serviceProviderCtx = zmsTestInitializer.contextWithMockPrincipal("putTenantResourceGroupRoles", domain, serviceName); + zmsImpl.putTenantResourceGroupRoles(serviceProviderCtx, domain, serviceName, tenantDomain, resourceGroup, + zmsTestInitializer.getAuditRef(), tenantRoles); + + TenantResourceGroupRoles tRoles = zmsImpl.getTenantResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), domain, serviceName, + tenantDomain, resourceGroup); + assertNotNull(tRoles); + assertEquals(domain.toLowerCase(), tRoles.getDomain()); + assertEquals(serviceName.toLowerCase(), tRoles.getService()); + assertEquals(tenantDomain.toLowerCase(), tRoles.getTenant()); + assertEquals(resourceGroup.toLowerCase(), tRoles.getResourceGroup()); + assertEquals(ZMSTestInitializer.TABLE_PROVIDER_ROLE_ACTIONS.size(), tRoles.getRoles().size()); + + // Verify dependency + + DomainList dependentDomainList = zmsImpl.getDependentDomainList(zmsTestInitializer.getMockDomRsrcCtx(), domain + "." + serviceName); + assertEquals(dependentDomainList.getNames().size(), 1); + assertEquals(dependentDomainList.getNames().get(0), tenantDomain.toLowerCase()); + + // Now add another resource group + + String resourceGroup2 = "Group2"; + tenantRoles = new TenantResourceGroupRoles().setDomain(domain) + .setService(serviceName).setTenant(tenantDomain) + .setRoles(roleActions).setResourceGroup(resourceGroup2); + zmsImpl.putTenantResourceGroupRoles(serviceProviderCtx, domain, serviceName, tenantDomain, resourceGroup2, + zmsTestInitializer.getAuditRef(), tenantRoles); + + tRoles = zmsImpl.getTenantResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), domain, serviceName, + tenantDomain, resourceGroup2); + assertNotNull(tRoles); + assertEquals(domain.toLowerCase(), tRoles.getDomain()); + assertEquals(serviceName.toLowerCase(), tRoles.getService()); + assertEquals(tenantDomain.toLowerCase(), tRoles.getTenant()); + assertEquals(resourceGroup2.toLowerCase(), tRoles.getResourceGroup()); + assertEquals(ZMSTestInitializer.TABLE_PROVIDER_ROLE_ACTIONS.size(), tRoles.getRoles().size()); + + // Now remove the first resource group and verify dependency remains until the second resource group and admin role is removed + + zmsImpl.deleteTenantResourceGroupRoles(serviceProviderCtx, domain, serviceName, tenantDomain, resourceGroup, zmsTestInitializer.getAuditRef()); + dependentDomainList = zmsImpl.getDependentDomainList(zmsTestInitializer.getMockDomRsrcCtx(), domain + "." + serviceName); + assertEquals(dependentDomainList.getNames().size(), 1); + assertEquals(dependentDomainList.getNames().get(0), tenantDomain.toLowerCase()); + + // Now delete the second resouce group and verify dependency still remains until the admin role is removed + + zmsImpl.deleteTenantResourceGroupRoles(serviceProviderCtx, domain, serviceName, tenantDomain, resourceGroup2, zmsTestInitializer.getAuditRef()); + dependentDomainList = zmsImpl.getDependentDomainList(zmsTestInitializer.getMockDomRsrcCtx(), domain + "." + serviceName); + assertEquals(dependentDomainList.getNames().size(), 1); + assertEquals(dependentDomainList.getNames().get(0), tenantDomain.toLowerCase()); + + // Finally, remove all resource groups related to the tenant domain (which will remove the admin role) + + ServiceIdentity serviceProvider = zmsTestInitializer.createServiceObject(domain, + serviceName, "http://localhost", "/usr/bin/java", "root", + "users", "host1"); + + zmsImpl.putServiceIdentity(zmsTestInitializer.getMockDomRsrcCtx(), domain, serviceName, zmsTestInitializer.getAuditRef(), serviceProvider); + + zmsImpl.deleteTenant(serviceProviderCtx, domain, serviceName, tenantDomain, zmsTestInitializer.getAuditRef()); + dependentDomainList = zmsImpl.getDependentDomainList(zmsTestInitializer.getMockDomRsrcCtx(), domain + "." + serviceName); + assertEquals(dependentDomainList.getNames().size(), 0); + + zmsImpl.deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), domain, zmsTestInitializer.getAuditRef()); + zmsImpl.deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, zmsTestInitializer.getAuditRef()); } @Test @@ -6588,13 +6720,18 @@ public void testDeleteTenantResourceGroupRoles() { dom.setAuditEnabled(true); zmsTestInitializer.getZms().postTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), zmsTestInitializer.getAuditRef(), dom); + String tenantDomain = "tenantTestDeleteTenantRoles"; + TopLevelDomain tenantDom = zmsTestInitializer.createTopLevelDomainObject( + tenantDomain, "Tenant Domain", "testOrg", zmsTestInitializer.getAdminUser()); + tenantDom.setAuditEnabled(true); + zmsTestInitializer.getZms().postTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), zmsTestInitializer.getAuditRef(), tenantDom); + List roleActions = new ArrayList<>(); for (Struct.Field f : ZMSTestInitializer.TABLE_PROVIDER_ROLE_ACTIONS) { roleActions.add(new TenantRoleAction().setRole(f.name()).setAction( (String) f.value())); } String serviceName = "storage"; - String tenantDomain = "tenantTestDeleteTenantRoles"; String resourceGroup = "Group1"; TenantResourceGroupRoles tenantRoles = new TenantResourceGroupRoles().setDomain(domain) @@ -6607,6 +6744,10 @@ public void testDeleteTenantResourceGroupRoles() { tenantDomain, resourceGroup); assertNotNull(tRoles); + // Delete the tenant domain. Then make sure we can still delete resource groups in provider + + zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, zmsTestInitializer.getAuditRef()); + zmsTestInitializer.getZms().deleteTenantResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), domain, serviceName, tenantDomain, resourceGroup, zmsTestInitializer.getAuditRef()); tRoles = zmsTestInitializer.getZms().getTenantResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), domain, serviceName, tenantDomain, resourceGroup); @@ -9436,6 +9577,66 @@ public void testPutTenancy() { zmsTestInitializer.getZms().putProviderResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), "AddTenancyDom1", "coretech", "storage", "set1", zmsTestInitializer.getAuditRef(), providerRoles); + assertPutTenancyTest(); + + // Verify domain dependency wasn't created as the provider isn't listed in the "sys.auth:role.service_providers role + + try { + zmsTestInitializer.getZms().getDependentDomainList(zmsTestInitializer.getMockDomRsrcCtx(), "coretech.storage"); + fail(); + } catch (ResourceException ex) { + assertEquals(ex.getMessage(), "ResourceException (400): {code: 400, message: \"coretech.storage is not a registered service provider\"}"); + } + + zmsTestInitializer.getZms().deleteTenancy(zmsTestInitializer.getMockDomRsrcCtx(), "AddTenancyDom1", "coretech.storage", zmsTestInitializer.getAuditRef()); + + zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), "AddTenancyDom1", zmsTestInitializer.getAuditRef()); + zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), "coretech", zmsTestInitializer.getAuditRef()); + } + + @Test + public void testPutTenancyNoAuthorizedServiceDomainDependency() { + + ZMSImpl zmsImpl = zmsTestInitializer.zmsInit(); + + zmsTestInitializer.setupTenantDomainProviderService(zmsImpl, "AddTenancyDom1", "coretech", "storage", + "http://localhost:8090/provider"); + + makeServiceProviders(zmsImpl, zmsTestInitializer.getMockDomRsrcCtx(), Collections.singletonList("coretech.storage")); + + Tenancy tenant = zmsTestInitializer.createTenantObject("AddTenancyDom1", "coretech.storage"); + zmsImpl.putTenancy(zmsTestInitializer.getMockDomRsrcCtx(), "AddTenancyDom1", "coretech.storage", zmsTestInitializer.getAuditRef(), tenant); + + // now set up the tenant for the sub domain provider + + List roleActions = new ArrayList<>(); + for (Struct.Field f : ZMSTestInitializer.TABLE_PROVIDER_ROLE_ACTIONS) { + roleActions.add(new TenantRoleAction().setRole(f.name()).setAction( + (String) f.value())); + } + + ProviderResourceGroupRoles providerRoles = new ProviderResourceGroupRoles() + .setDomain("coretech").setService("storage") + .setTenant("AddTenancyDom1").setRoles(roleActions) + .setResourceGroup("set1"); + zmsImpl.putProviderResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), "AddTenancyDom1", "coretech", + "storage", "set1", zmsTestInitializer.getAuditRef(), providerRoles); + + assertPutTenancyTest(); + + // Verify domain dependency wasn't created as no service token was passed + + DomainList dependentDomainList = zmsImpl.getDependentDomainList(zmsTestInitializer.getMockDomRsrcCtx(), "coretech.storage"); + assertEquals(dependentDomainList.getNames().size(), 0); + + zmsImpl.deleteTenancy(zmsTestInitializer.getMockDomRsrcCtx(), "AddTenancyDom1", "coretech.storage", zmsTestInitializer.getAuditRef()); + + zmsImpl.deleteRole(zmsTestInitializer.getMockDomRsrcCtx(), "sys.auth", "service_providers", zmsTestInitializer.getAuditRef()); + zmsImpl.deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), "AddTenancyDom1", zmsTestInitializer.getAuditRef()); + zmsImpl.deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), "coretech", zmsTestInitializer.getAuditRef()); + } + + private void assertPutTenancyTest() { // make sure our roles have been created Role role = zmsTestInitializer.getZms().getRole(zmsTestInitializer.getMockDomRsrcCtx(), "AddTenancyDom1", "tenancy.coretech.storage.admin", false, false, false); @@ -9494,11 +9695,6 @@ public void testPutTenancy() { assertList = policy.getAssertions(); assertEquals(assertList.size(), 1); assertEquals(assertList.get(0).getRole(), "addtenancydom1:role.coretech.storage.res_group.set1.writer"); - - zmsTestInitializer.getZms().deleteTenancy(zmsTestInitializer.getMockDomRsrcCtx(), "AddTenancyDom1", "coretech.storage", zmsTestInitializer.getAuditRef()); - - zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), "AddTenancyDom1", zmsTestInitializer.getAuditRef()); - zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), "coretech", zmsTestInitializer.getAuditRef()); } @Test @@ -9611,9 +9807,127 @@ public void testPutTenancyWithAuthorizedService() { Tenancy tenant = zmsTestInitializer.createTenantObject(tenantDomain, provider); zmsTestInitializer.getZms().putTenancy(ctx, tenantDomain, provider, zmsTestInitializer.getAuditRef(), tenant); + String tenantRoleInProviderDomain = assertPolicyForTenancyTests(zmsTestInitializer.getZms(), tenantDomain, providerService, provider); + + // Verify domain dependency wasn't created as the provider isn't listed in the "sys.auth:role.service_providers role + + try { + zmsTestInitializer.getZms().getDependentDomainList(zmsTestInitializer.getMockDomRsrcCtx(), provider); + fail(); + } catch (ResourceException ex) { + assertEquals(ex.getMessage(), "ResourceException (400): {code: 400, message: \"coretech.storage is not a registered service provider\"}"); + } + + // now let's call delete tenancy support with the same authorized service token + + zmsTestInitializer.getZms().deleteTenancy(ctx, tenantDomain, provider, zmsTestInitializer.getAuditRef()); + + // verify that all roles and policies have been deleted + + try { + zmsTestInitializer.getZms().getPolicy(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, "tenancy." + provider + ".admin"); + fail(); + } catch (ResourceException ex) { + assertEquals(ex.getCode(), 404); + } + + try { + zmsTestInitializer.getZms().getRole(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, tenantRoleInProviderDomain, false, false, false); + fail(); + } catch (ResourceException ex) { + assertEquals(ex.getCode(), 404); + } + + // clean up our domains + + zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, zmsTestInitializer.getAuditRef()); + zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, zmsTestInitializer.getAuditRef()); + } + + @Test + public void testPutTenancyWithAuthorizedServiceDomainDependency() { + + String tenantDomain = "puttenancyauthorizedservice"; + String providerService = "storage"; + String providerDomain = "coretech"; + String provider = providerDomain + "." + providerService; + + ZMSImpl zmsImpl = zmsTestInitializer.zmsInit(); + zmsTestInitializer.setupTenantDomainProviderService(zmsImpl, tenantDomain, providerDomain, providerService, null); + makeServiceProviders(zmsImpl, zmsTestInitializer.getMockDomRsrcCtx(), Collections.singletonList("coretech.storage")); + + // tenant is setup so let's setup up policy to authorize access to tenants + // without this role/policy we won't be authorized to add tenant roles + // to the provider domain even with authorized service details + + Role role = zmsTestInitializer.createRoleObject(providerDomain, "self_serve", null, + providerDomain + "." + providerService, null); + zmsImpl.putRole(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, "self_serve", zmsTestInitializer.getAuditRef(), role); + + Policy policy = zmsTestInitializer.createPolicyObject(providerDomain, "self_serve", + "self_serve", "update", providerDomain + ":tenant.*", AssertionEffect.ALLOW); + zmsImpl.putPolicy(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, "self_serve", zmsTestInitializer.getAuditRef(), policy); + + // we are going to create a principal object with authorized service + // set to coretech.storage + + Authority principalAuthority = new com.yahoo.athenz.common.server.debug.DebugPrincipalAuthority(); + String userId = "user1"; + String unsignedCreds = "v=U1;d=user;u=" + userId; + Principal principal = SimplePrincipal.create("user", userId, unsignedCreds + ";s=signature", 0, principalAuthority); + assertNotNull(principal); + ((SimplePrincipal) principal).setUnsignedCreds(unsignedCreds); + ((SimplePrincipal) principal).setAuthorizedService(provider); + ResourceContext ctx = zmsTestInitializer.createResourceContext(principal, "puttenancy"); + + // after this call we should have admin roles set for both provider and tenant + + Tenancy tenant = zmsTestInitializer.createTenantObject(tenantDomain, provider); + zmsImpl.putTenancy(ctx, tenantDomain, provider, zmsTestInitializer.getAuditRef(), tenant); + + String tenantRoleInProviderDomain = assertPolicyForTenancyTests(zmsImpl, tenantDomain, providerService, provider); + + // Verify domain dependency was created + + DomainList dependentDomainList = zmsImpl.getDependentDomainList(zmsTestInitializer.getMockDomRsrcCtx(), provider); + assertEquals(dependentDomainList.getNames().size(), 1); + assertEquals(dependentDomainList.getNames().get(0), "puttenancyauthorizedservice"); + + // now let's call delete tenancy support with the same authorized service token + + zmsImpl.deleteTenancy(ctx, tenantDomain, provider, zmsTestInitializer.getAuditRef()); + + // Verify domain dependency was removed + dependentDomainList = zmsImpl.getDependentDomainList(zmsTestInitializer.getMockDomRsrcCtx(), provider); + assertEquals(dependentDomainList.getNames().size(), 0); + + // verify that all roles and policies have been deleted + + try { + zmsImpl.getPolicy(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, "tenancy." + provider + ".admin"); + fail(); + } catch (ResourceException ex) { + assertEquals(ex.getCode(), 404); + } + + try { + zmsImpl.getRole(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, tenantRoleInProviderDomain, false, false, false); + fail(); + } catch (ResourceException ex) { + assertEquals(ex.getCode(), 404); + } + + // clean up our domains + + zmsImpl.deleteRole(zmsTestInitializer.getMockDomRsrcCtx(), "sys.auth", "service_providers", zmsTestInitializer.getAuditRef()); + zmsImpl.deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, zmsTestInitializer.getAuditRef()); + zmsImpl.deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, zmsTestInitializer.getAuditRef()); + } + + private String assertPolicyForTenancyTests(ZMSImpl zms, String tenantDomain, String providerService, String provider) { // make sure our policy has been created - policy = zmsTestInitializer.getZms().getPolicy(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, "tenancy." + provider + ".admin"); + Policy policy = zms.getPolicy(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, "tenancy." + provider + ".admin"); assertNotNull(policy); String tenantRoleInProviderDomain = providerService + ".tenant." + tenantDomain + ".admin"; @@ -9642,30 +9956,7 @@ public void testPutTenancyWithAuthorizedService() { assertTrue(domainAdminRoleCheck); assertTrue(tenantAdminRoleCheck); assertTrue(tenantUpdateCheck); - - // now let's call delete tenancy support with the same authorized service token - - zmsTestInitializer.getZms().deleteTenancy(ctx, tenantDomain, provider, zmsTestInitializer.getAuditRef()); - - // verify that all roles and policies have been deleted - - try { - zmsTestInitializer.getZms().getPolicy(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, "tenancy." + provider + ".admin"); - fail(); - } catch (ResourceException ex) { - assertEquals(ex.getCode(), 404); - } - - try { - zmsTestInitializer.getZms().getRole(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, tenantRoleInProviderDomain, false, false, false); - } catch (ResourceException ex) { - assertEquals(ex.getCode(), 404); - } - - // clean up our domains - - zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, zmsTestInitializer.getAuditRef()); - zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, zmsTestInitializer.getAuditRef()); + return tenantRoleInProviderDomain; } @Test @@ -10019,13 +10310,18 @@ public void testPutTenantRolesWithResourceGroup() { dom.setAuditEnabled(true); zmsTestInitializer.getZms().postTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), zmsTestInitializer.getAuditRef(), dom); + String tenantDomain = "tenantTestPutTenantRoles"; + TopLevelDomain tenantDom = zmsTestInitializer.createTopLevelDomainObject( + tenantDomain, "Tenant Domain", "testOrg", zmsTestInitializer.getAdminUser()); + tenantDom.setAuditEnabled(true); + zmsTestInitializer.getZms().postTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), zmsTestInitializer.getAuditRef(), tenantDom); + List roleActions = new ArrayList<>(); for (Struct.Field f : ZMSTestInitializer.TABLE_PROVIDER_ROLE_ACTIONS) { roleActions.add(new TenantRoleAction().setRole(f.name()).setAction( (String) f.value())); } String serviceName = "storage"; - String tenantDomain = "tenantTestPutTenantRoles"; String resourceGroup = "Group1"; TenantResourceGroupRoles tenantRoles = new TenantResourceGroupRoles().setDomain(domain) @@ -10043,6 +10339,40 @@ public void testPutTenantRolesWithResourceGroup() { assertEquals(resourceGroup.toLowerCase(), tRoles.getResourceGroup()); assertEquals(ZMSTestInitializer.TABLE_PROVIDER_ROLE_ACTIONS.size(), tRoles.getRoles().size()); + zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), domain, zmsTestInitializer.getAuditRef()); + zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, zmsTestInitializer.getAuditRef()); + } + + @Test + public void testPutTenantRolesWithResourceGroupInvalidTenant() { + + String domain = "testPutTenantRoles"; + TopLevelDomain dom = zmsTestInitializer.createTopLevelDomainObject( + domain, "Test Domain1", "testOrg", zmsTestInitializer.getAdminUser()); + dom.setAuditEnabled(true); + zmsTestInitializer.getZms().postTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), zmsTestInitializer.getAuditRef(), dom); + + String tenantDomain = "tenantTestPutTenantRoles"; + + List roleActions = new ArrayList<>(); + for (Struct.Field f : ZMSTestInitializer.TABLE_PROVIDER_ROLE_ACTIONS) { + roleActions.add(new TenantRoleAction().setRole(f.name()).setAction( + (String) f.value())); + } + String serviceName = "storage"; + String resourceGroup = "Group1"; + + TenantResourceGroupRoles tenantRoles = new TenantResourceGroupRoles().setDomain(domain) + .setService(serviceName).setTenant(tenantDomain) + .setRoles(roleActions).setResourceGroup(resourceGroup); + try { + zmsTestInitializer.getZms().putTenantResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), domain, serviceName, tenantDomain, resourceGroup, + zmsTestInitializer.getAuditRef(), tenantRoles); + fail(); + } catch (ResourceException ex) { + assertEquals(ex.getMessage(), "ResourceException (404): {code: 404, message: \"someApiMethod: Unknown tenant domain: tenanttestputtenantroles\"}"); + } + zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), domain, zmsTestInitializer.getAuditRef()); } @@ -13666,52 +13996,145 @@ public void testPutProviderResourceGroupRolesWithAuthorizedService() { zmsTestInitializer.getZms().putProviderResourceGroupRoles(ctx, tenantDomain, providerDomain, providerService, resourceGroup, zmsTestInitializer.getAuditRef(), providerRoles); - ProviderResourceGroupRoles pRoles = zmsTestInitializer.getZms().getProviderResourceGroupRoles(ctx, + assertPutProviderResourceGroupRolesWithAuthorizedService(zmsTestInitializer.getZms(), tenantDomain, providerService, providerDomain, resourceGroup, ctx); + + // Verify domain dependency wasn't created as the provider isn't listed in the "sys.auth:role.service_providers role + + try { + zmsTestInitializer.getZms().getDependentDomainList(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain + "." + providerService); + fail(); + } catch (ResourceException ex) { + assertEquals(ex.getMessage(), "ResourceException (400): {code: 400, message: \"" + providerDomain + "." + providerService + " is not a registered service provider\"}"); + } + + // now we're going to delete the provider roles using the standard + // resource object without the authorized service. in this case + // the provider roles are going to be deleted but not the tenant + // roles from the provider domain + + zmsTestInitializer.getZms().deleteProviderResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, providerDomain, + providerService, resourceGroup, zmsTestInitializer.getAuditRef()); + + // so for tenant we're going to 0 provider roles + + ProviderResourceGroupRoles pRoles = zmsTestInitializer.getZms().getProviderResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, providerDomain, providerService, resourceGroup); assertNotNull(pRoles); - assertEquals(providerDomain.toLowerCase(), pRoles.getDomain()); - assertEquals(providerService.toLowerCase(), pRoles.getService()); - assertEquals(tenantDomain.toLowerCase(), pRoles.getTenant()); - assertEquals(resourceGroup.toLowerCase(), pRoles.getResourceGroup()); - assertEquals(ZMSTestInitializer.RESOURCE_PROVIDER_ROLE_ACTIONS.size(), pRoles.getRoles().size()); - List traList = pRoles.getRoles(); - List roles = new ArrayList<>(); - for (TenantRoleAction ra : traList) { - roles.add(ra.getRole()); - } - assertTrue(roles.contains("reader")); - assertTrue(roles.contains("writer")); + assertEquals(0, pRoles.getRoles().size()); - // now get the tenant roles for the provider + // but for provider we're still going to get full set of roles TenantResourceGroupRoles tRoles = zmsTestInitializer.getZms().getTenantResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, providerService, tenantDomain, resourceGroup); assertNotNull(tRoles); - assertEquals(tRoles.getDomain(), providerDomain); - assertEquals(tRoles.getService(), providerService); - assertEquals(tRoles.getTenant(), tenantDomain); - assertEquals(tRoles.getResourceGroup(), resourceGroup); - assertEquals(ZMSTestInitializer.RESOURCE_PROVIDER_ROLE_ACTIONS.size(), tRoles.getRoles().size()); - traList = pRoles.getRoles(); - roles = new ArrayList<>(); - for (TenantRoleAction ra : traList) { - roles.add(ra.getRole()); + assertEquals(2, tRoles.getRoles().size()); + + // now this time we're going to delete with the principal with the + // authorized service token + + zmsTestInitializer.getZms().deleteProviderResourceGroupRoles(ctx, tenantDomain, providerDomain, + providerService, resourceGroup, zmsTestInitializer.getAuditRef()); + + // so for tenant we're still going to 0 provider roles + + pRoles = zmsTestInitializer.getZms().getProviderResourceGroupRoles(ctx, + tenantDomain, providerDomain, providerService, resourceGroup); + + assertNotNull(pRoles); + assertEquals(0, pRoles.getRoles().size()); + + // and for provider we're now going to get 0 tenant roles as well + + tRoles = zmsTestInitializer.getZms().getTenantResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, + providerService, tenantDomain, resourceGroup); + assertNotNull(tRoles); + assertEquals(0, tRoles.getRoles().size()); + + // clean up our domains + + zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, zmsTestInitializer.getAuditRef()); + zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, zmsTestInitializer.getAuditRef()); + } + + @Test + public void testPutProviderResourceGroupRolesWithAuthorizedServiceDomainDependency() { + + String tenantDomain = "providerresourcegrouprolesauthorizedservice"; + String providerService = "storage"; + String providerDomain = "coretech"; + String resourceGroup = "hockey"; + + ZMSImpl zms = zmsTestInitializer.zmsInit(); + + zmsTestInitializer.setupTenantDomainProviderService(zms, tenantDomain, providerDomain, providerService, + "http://localhost:8090/tableprovider"); + + makeServiceProviders(zms, zmsTestInitializer.getMockDomRsrcCtx(), Collections.singletonList("coretech.storage")); + + // tenant is setup so let's setup up policy to authorize access to tenants + // without this role/policy we won't be authorized to add tenant roles + // to the provider domain even with authorized service details + + Role role = zmsTestInitializer.createRoleObject(providerDomain, "self_serve", null, + providerDomain + "." + providerService, null); + zms.putRole(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, "self_serve", zmsTestInitializer.getAuditRef(), role); + + Policy policy = zmsTestInitializer.createPolicyObject(providerDomain, "self_serve", + "self_serve", "update", providerDomain + ":tenant.*", AssertionEffect.ALLOW); + zms.putPolicy(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, "self_serve", zmsTestInitializer.getAuditRef(), policy); + + // now we're going to setup our provider role call + + List roleActions = new ArrayList<>(); + for (Struct.Field f : ZMSTestInitializer.RESOURCE_PROVIDER_ROLE_ACTIONS) { + roleActions.add(new TenantRoleAction().setRole(f.name()).setAction( + (String) f.value())); } - assertTrue(roles.contains("reader")); - assertTrue(roles.contains("writer")); + + ProviderResourceGroupRoles providerRoles = new ProviderResourceGroupRoles() + .setDomain(providerDomain).setService(providerService) + .setTenant(tenantDomain).setRoles(roleActions) + .setResourceGroup(resourceGroup); + + // we are going to create a principal object with authorized service + // set to coretech.storage + + String userId = "user1"; + Authority principalAuthority = new com.yahoo.athenz.common.server.debug.DebugPrincipalAuthority(); + String unsignedCreds = "v=U1;d=user;n=" + userId; + Principal principal = SimplePrincipal.create("user", userId, unsignedCreds + ";s=signature", + 0, principalAuthority); + assertNotNull(principal); + ((SimplePrincipal) principal).setUnsignedCreds(unsignedCreds); + ((SimplePrincipal) principal).setUnsignedCreds(unsignedCreds); + ((SimplePrincipal) principal).setAuthorizedService("coretech.storage"); + ResourceContext ctx = zmsTestInitializer.createResourceContext(principal, "putproviderresourcegrouproles"); + + // after this call we should have roles set for both provider and tenant + + zms.putProviderResourceGroupRoles(ctx, tenantDomain, providerDomain, providerService, + resourceGroup, zmsTestInitializer.getAuditRef(), providerRoles); + + assertPutProviderResourceGroupRolesWithAuthorizedService(zms, tenantDomain, providerService, providerDomain, resourceGroup, ctx); + + // Verify domain dependency was created + + DomainList dependentDomainList = zms.getDependentDomainList(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain + "." + providerService); + assertEquals(dependentDomainList.getNames().size(), 1); + assertEquals(dependentDomainList.getNames().get(0), "providerresourcegrouprolesauthorizedservice"); // now we're going to delete the provider roles using the standard // resource object without the authorized service. in this case // the provider roles are going to be deleted but not the tenant // roles from the provider domain - zmsTestInitializer.getZms().deleteProviderResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, providerDomain, + zms.deleteProviderResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, providerDomain, providerService, resourceGroup, zmsTestInitializer.getAuditRef()); // so for tenant we're going to 0 provider roles - pRoles = zmsTestInitializer.getZms().getProviderResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), + ProviderResourceGroupRoles pRoles = zms.getProviderResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, providerDomain, providerService, resourceGroup); assertNotNull(pRoles); @@ -13719,15 +14142,21 @@ public void testPutProviderResourceGroupRolesWithAuthorizedService() { // but for provider we're still going to get full set of roles - tRoles = zmsTestInitializer.getZms().getTenantResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, + TenantResourceGroupRoles tRoles = zms.getTenantResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, providerService, tenantDomain, resourceGroup); assertNotNull(tRoles); assertEquals(2, tRoles.getRoles().size()); + // Also, domain dependency remains until the resources are removed from the provider + + dependentDomainList = zms.getDependentDomainList(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain + "." + providerService); + assertEquals(dependentDomainList.getNames().size(), 1); + assertEquals(dependentDomainList.getNames().get(0), "providerresourcegrouprolesauthorizedservice"); + // now this time we're going to delete with the principal with the // authorized service token - zmsTestInitializer.getZms().deleteProviderResourceGroupRoles(ctx, tenantDomain, providerDomain, + zms.deleteProviderResourceGroupRoles(ctx, tenantDomain, providerDomain, providerService, resourceGroup, zmsTestInitializer.getAuditRef()); // so for tenant we're still going to 0 provider roles @@ -13740,15 +14169,65 @@ public void testPutProviderResourceGroupRolesWithAuthorizedService() { // and for provider we're now going to get 0 tenant roles as well - tRoles = zmsTestInitializer.getZms().getTenantResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, + tRoles = zms.getTenantResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, providerService, tenantDomain, resourceGroup); assertNotNull(tRoles); assertEquals(0, tRoles.getRoles().size()); + // Domain dependency still remains as the admin role wasn't removed (storage.tenant.providerresourcegrouprolesauthorizedservice.admin) + + dependentDomainList = zms.getDependentDomainList(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain + "." + providerService); + assertEquals(dependentDomainList.getNames().size(), 1); + assertEquals(dependentDomainList.getNames().get(0), "providerresourcegrouprolesauthorizedservice"); + + // Finally, remove the admin role by deleting the tenant + RsrcCtxWrapper serviceProviderCtx = zmsTestInitializer.contextWithMockPrincipal("deleteTenant", providerDomain, providerService); + zms.deleteTenant(serviceProviderCtx, providerDomain, providerService, tenantDomain, zmsTestInitializer.getAuditRef()); + dependentDomainList = zms.getDependentDomainList(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain + "." + providerService); + assertEquals(dependentDomainList.getNames().size(), 0); + // clean up our domains - zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, zmsTestInitializer.getAuditRef()); - zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, zmsTestInitializer.getAuditRef()); + zms.deleteRole(zmsTestInitializer.getMockDomRsrcCtx(), "sys.auth", "service_providers", zmsTestInitializer.getAuditRef()); + zms.deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), tenantDomain, zmsTestInitializer.getAuditRef()); + zms.deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, zmsTestInitializer.getAuditRef()); + } + + private void assertPutProviderResourceGroupRolesWithAuthorizedService(ZMSImpl zms, String tenantDomain, String providerService, String providerDomain, String resourceGroup, ResourceContext ctx) { + ProviderResourceGroupRoles pRoles = zms.getProviderResourceGroupRoles(ctx, + tenantDomain, providerDomain, providerService, resourceGroup); + + assertNotNull(pRoles); + assertEquals(providerDomain.toLowerCase(), pRoles.getDomain()); + assertEquals(providerService.toLowerCase(), pRoles.getService()); + assertEquals(tenantDomain.toLowerCase(), pRoles.getTenant()); + assertEquals(resourceGroup.toLowerCase(), pRoles.getResourceGroup()); + assertEquals(ZMSTestInitializer.RESOURCE_PROVIDER_ROLE_ACTIONS.size(), pRoles.getRoles().size()); + List traList = pRoles.getRoles(); + List roles = new ArrayList<>(); + for (TenantRoleAction ra : traList) { + roles.add(ra.getRole()); + } + assertTrue(roles.contains("reader")); + assertTrue(roles.contains("writer")); + + // now get the tenant roles for the provider + + TenantResourceGroupRoles tRoles = zms.getTenantResourceGroupRoles(zmsTestInitializer.getMockDomRsrcCtx(), providerDomain, + providerService, tenantDomain, resourceGroup); + assertNotNull(tRoles); + assertEquals(tRoles.getDomain(), providerDomain); + assertEquals(tRoles.getService(), providerService); + assertEquals(tRoles.getTenant(), tenantDomain); + assertEquals(tRoles.getResourceGroup(), resourceGroup); + assertEquals(ZMSTestInitializer.RESOURCE_PROVIDER_ROLE_ACTIONS.size(), tRoles.getRoles().size()); + traList = pRoles.getRoles(); + roles = new ArrayList<>(); + for (TenantRoleAction ra : traList) { + roles.add(ra.getRole()); + } + assertTrue(roles.contains("reader")); + assertTrue(roles.contains("writer")); } @Test @@ -19246,6 +19725,10 @@ public void testPutTenant() { "Test Domain1", "testOrg", zmsTestInitializer.getAdminUser()); zmsTestInitializer.getZms().postTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), zmsTestInitializer.getAuditRef(), dom1); + TopLevelDomain sportsDomain = zmsTestInitializer.createTopLevelDomainObject("sports", + "Sports Domain", "testOrg", zmsTestInitializer.getAdminUser()); + zmsTestInitializer.getZms().postTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), zmsTestInitializer.getAuditRef(), sportsDomain); + ServiceIdentity service = new ServiceIdentity(); service.setName(ResourceUtils.serviceResourceName("providerdomain", "api")); zmsTestInitializer.getZms().putServiceIdentity(zmsTestInitializer.getMockDomRsrcCtx(), "providerdomain", "api", zmsTestInitializer.getAuditRef(), service); @@ -19253,19 +19736,106 @@ public void testPutTenant() { Tenancy tenant = new Tenancy().setDomain("sports").setService("providerdomain.api"); zmsTestInitializer.getZms().putTenant(zmsTestInitializer.getMockDomRsrcCtx(), "providerdomain", "api", "sports", zmsTestInitializer.getAuditRef(), tenant); - Role role = zmsTestInitializer.getZms().getRole(zmsTestInitializer.getMockDomRsrcCtx(), "providerdomain", "api.tenant.sports.admin", false, false, false); + assertPutTenantTests(zmsTestInitializer.getZms()); + + // Verify domain dependency wasn't created as the provider isn't listed in the "sys.auth:role.service_providers role + + try { + zmsTestInitializer.getZms().getDependentDomainList(zmsTestInitializer.getMockDomRsrcCtx(), "providerdomain.api"); + fail(); + } catch (ResourceException ex) { + assertEquals(ex.getMessage(), "ResourceException (400): {code: 400, message: \"providerdomain.api is not a registered service provider\"}"); + } + + zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), "providerdomain", zmsTestInitializer.getAuditRef()); + zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), "sports", zmsTestInitializer.getAuditRef()); + } + + @Test + public void testPutTenantNotServiceProviderCtx() { + ZMSImpl zms = zmsTestInitializer.zmsInit(); + TopLevelDomain dom1 = zmsTestInitializer.createTopLevelDomainObject("providerdomain", + "Test Domain1", "testOrg", zmsTestInitializer.getAdminUser()); + zms.postTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), zmsTestInitializer.getAuditRef(), dom1); + + TopLevelDomain sportsDomain = zmsTestInitializer.createTopLevelDomainObject("sports", + "Sports Domain", "testOrg", zmsTestInitializer.getAdminUser()); + zms.postTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), zmsTestInitializer.getAuditRef(), sportsDomain); + + ServiceIdentity service = new ServiceIdentity(); + service.setName(ResourceUtils.serviceResourceName("providerdomain", "api")); + zms.putServiceIdentity(zmsTestInitializer.getMockDomRsrcCtx(), "providerdomain", "api", zmsTestInitializer.getAuditRef(), service); + + makeServiceProviders(zms, zmsTestInitializer.getMockDomRsrcCtx(), Collections.singletonList("providerdomain.api")); + + Tenancy tenant = new Tenancy().setDomain("sports").setService("providerdomain.api"); + zms.putTenant(zmsTestInitializer.getMockDomRsrcCtx(), "providerdomain", "api", "sports", zmsTestInitializer.getAuditRef(), tenant); + + assertPutTenantTests(zms); + + // Verify domain dependency wasn't created as the putTenant request wasn't made with the service provider context + + DomainList dependentDomainList = zms.getDependentDomainList(zmsTestInitializer.getMockDomRsrcCtx(), "providerdomain.api"); + assertEquals(dependentDomainList.getNames().size(), 0); + + zms.deleteRole(zmsTestInitializer.getMockDomRsrcCtx(), "sys.auth", "service_providers", zmsTestInitializer.getAuditRef()); + zms.deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), "providerdomain", zmsTestInitializer.getAuditRef()); + zms.deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), "sports", zmsTestInitializer.getAuditRef()); + } + + @Test + public void testPutTenantDomainDependency() { + ZMSImpl zms = zmsTestInitializer.zmsInit(); + TopLevelDomain dom1 = zmsTestInitializer.createTopLevelDomainObject("providerdomain", + "Test Domain1", "testOrg", zmsTestInitializer.getAdminUser()); + zms.postTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), zmsTestInitializer.getAuditRef(), dom1); + + TopLevelDomain sportsDomain = zmsTestInitializer.createTopLevelDomainObject("sports", + "Sports Domain", "testOrg", zmsTestInitializer.getAdminUser()); + zms.postTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), zmsTestInitializer.getAuditRef(), sportsDomain); + + ServiceIdentity service = new ServiceIdentity(); + service.setName(ResourceUtils.serviceResourceName("providerdomain", "api")); + zms.putServiceIdentity(zmsTestInitializer.getMockDomRsrcCtx(), "providerdomain", "api", zmsTestInitializer.getAuditRef(), service); + + makeServiceProviders(zms, zmsTestInitializer.getMockDomRsrcCtx(), Collections.singletonList("providerdomain.api")); + // Swith to service provider context + RsrcCtxWrapper serviceProviderCtx = zmsTestInitializer.contextWithMockPrincipal("putTenant", "providerdomain", "api"); + + Tenancy tenant = new Tenancy().setDomain("sports").setService("providerdomain.api"); + zms.putTenant(serviceProviderCtx, "providerdomain", "api", "sports", zmsTestInitializer.getAuditRef(), tenant); + + assertPutTenantTests(zms); + + // Verify domain dependency was created + + DomainList dependentDomainList = zms.getDependentDomainList(zmsTestInitializer.getMockDomRsrcCtx(), "providerdomain.api"); + assertEquals(dependentDomainList.getNames().size(), 1); + assertEquals(dependentDomainList.getNames().get(0), "sports"); + + // Delete tenant, verify domain dependency was removed + + zms.deleteTenant(serviceProviderCtx, "providerdomain", "api", "sports", zmsTestInitializer.getAuditRef()); + dependentDomainList = zms.getDependentDomainList(zmsTestInitializer.getMockDomRsrcCtx(), "providerdomain.api"); + assertEquals(dependentDomainList.getNames().size(), 0); + + zms.deleteRole(zmsTestInitializer.getMockDomRsrcCtx(), "sys.auth", "service_providers", zmsTestInitializer.getAuditRef()); + zms.deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), "providerdomain", zmsTestInitializer.getAuditRef()); + zms.deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), "sports", zmsTestInitializer.getAuditRef()); + } + + private void assertPutTenantTests(ZMSImpl zms) { + Role role = zms.getRole(zmsTestInitializer.getMockDomRsrcCtx(), "providerdomain", "api.tenant.sports.admin", false, false, false); assertNotNull(role); assertEquals(role.getTrust(), "sports"); - Policy policy = zmsTestInitializer.getZms().getPolicy(zmsTestInitializer.getMockDomRsrcCtx(), "providerdomain", "api.tenant.sports.admin"); + Policy policy = zms.getPolicy(zmsTestInitializer.getMockDomRsrcCtx(), "providerdomain", "api.tenant.sports.admin"); assertNotNull(policy); assertEquals(policy.getAssertions().size(), 1); Assertion assertion = policy.getAssertions().get(0); assertEquals(assertion.getAction(), "*"); assertEquals(assertion.getRole(), "providerdomain:role.api.tenant.sports.admin"); assertEquals(assertion.getResource(), "providerdomain:service.api.tenant.sports.*"); - - zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), "providerdomain", zmsTestInitializer.getAuditRef()); } @Test @@ -19275,6 +19845,10 @@ public void testDeleteTenant() { "Test Domain1", "testOrg", zmsTestInitializer.getAdminUser()); zmsTestInitializer.getZms().postTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), zmsTestInitializer.getAuditRef(), dom1); + TopLevelDomain sportsDomain = zmsTestInitializer.createTopLevelDomainObject("sports", + "sports domain", "testOrg", zmsTestInitializer.getAdminUser()); + zmsTestInitializer.getZms().postTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), zmsTestInitializer.getAuditRef(), sportsDomain); + ServiceIdentity service = new ServiceIdentity(); service.setName(ResourceUtils.serviceResourceName("providerdomaindelete", "api")); zmsTestInitializer.getZms().putServiceIdentity(zmsTestInitializer.getMockDomRsrcCtx(), "providerdomaindelete", "api", zmsTestInitializer.getAuditRef(), service); @@ -19305,6 +19879,7 @@ public void testDeleteTenant() { } zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), "providerdomaindelete", zmsTestInitializer.getAuditRef()); + zmsTestInitializer.getZms().deleteTopLevelDomain(zmsTestInitializer.getMockDomRsrcCtx(), "sports", zmsTestInitializer.getAuditRef()); } @Test