ZMSImpl implements Authorizer, KeyStore, ZMSHandler { @Override public Response getSignedDomains(ResourceContext ctx, String domainName, String metaOnly, String metaAttr, Boolean master, String matchingTag) { final String caller = ctx.getApiName(); logPrincipal(ctx); validateRequest(ctx.request(), caller); if (domainName != null) { domainName = domainName.toLowerCase(); validate(domainName, TYPE_DOMAIN_NAME, caller); setRequestDomain(ctx, domainName); } if (metaAttr != null) { metaAttr = metaAttr.toLowerCase(); validate(metaAttr, TYPE_SIMPLE_NAME, caller); } boolean setMetaDataOnly = ZMSUtils.parseBoolean(metaOnly, false); long timestamp = getModTimestamp(matchingTag); Principal principal = ((RsrcCtxWrapper) ctx).principal(); boolean masterCopy = (useMasterCopyForSignedDomains || master == Boolean.TRUE) && principal.getFullName().startsWith("sys."); List<SignedDomain> sdList = new ArrayList<>(); Long youngestDomMod = -1L; if (domainName != null && !domainName.isEmpty()) { Domain domain = null; try { domain = dbService.getDomain(domainName, masterCopy); } catch (ResourceException ex) { if (ex.getCode() != ResourceException.NOT_FOUND) { throw ex; } } if (domain != null) { youngestDomMod = domain.getModified().millis(); if (timestamp != 0 && youngestDomMod <= timestamp) { EntityTag eTag = new EntityTag(domain.getModified().toString()); return Response.status(ResourceException.NOT_MODIFIED) .header("ETag", eTag.toString()).build(); } SignedDomain signedDomain = retrieveSignedDomain(domain, metaAttr, setMetaDataOnly, masterCopy); if (signedDomain != null) { sdList.add(signedDomain); } } else { youngestDomMod = System.currentTimeMillis(); } } else { if (!setMetaDataOnly && !masterCopy) { return Response.status(ResourceException.BAD_REQUEST).build(); } if (matchingTag == null) { EntityTag eTag = new EntityTag(Timestamp.fromMillis(0).toString()); matchingTag = eTag.toString(); } DomainMetaList dmlist = dbService.listModifiedDomains(timestamp); List<Domain> modlist = dmlist.getDomains(); if (modlist == null || modlist.size() == 0) { return Response.status(ResourceException.NOT_MODIFIED) .header("ETag", matchingTag).build(); } for (Domain dmod : modlist) { Long domModMillis = dmod.getModified().millis(); if (domModMillis.compareTo(youngestDomMod) > 0) { youngestDomMod = domModMillis; } SignedDomain signedDomain = retrieveSignedDomain(dmod, metaAttr, setMetaDataOnly, masterCopy); if (signedDomain == null) { continue; } sdList.add(signedDomain); } } SignedDomains sdoms = new SignedDomains(); sdoms.setDomains(sdList); Timestamp youngest = Timestamp.fromMillis(youngestDomMod); EntityTag eTag = new EntityTag(youngest.toString()); return Response.status(ResourceException.OK).entity(sdoms) .header("ETag", eTag.toString()).build(); } ZMSImpl(); Schema schema(); DomainList getDomainList(ResourceContext ctx, Integer limit, String skip, String prefix,
            Integer depth, String account, Integer productId, String roleMember, String roleName,
            String modifiedSince); Domain getDomain(ResourceContext ctx, String domainName); Domain postTopLevelDomain(ResourceContext ctx, String auditRef, TopLevelDomain detail); void deleteTopLevelDomain(ResourceContext ctx, String domainName, String auditRef); Domain postUserDomain(ResourceContext ctx, String name, String auditRef, UserDomain detail); Domain postSubDomain(ResourceContext ctx, String parent, String auditRef, SubDomain detail); void deleteSubDomain(ResourceContext ctx, String parent, String name, String auditRef); void deleteUserDomain(ResourceContext ctx, String name, String auditRef); UserList getUserList(ResourceContext ctx); @Override void deleteDomainRoleMember(ResourceContext ctx, String domainName, String memberName, String auditRef); @Override void deleteUser(ResourceContext ctx, String name, String auditRef); @Override void putDomainMeta(ResourceContext ctx, String domainName, String auditRef,
            DomainMeta meta); @Override void putDomainSystemMeta(ResourceContext ctx, String domainName, String attribute,
            String auditRef, DomainMeta meta); DomainTemplateList getDomainTemplateList(ResourceContext ctx, String domainName); @Override void putDomainTemplate(ResourceContext ctx, String domainName, String auditRef,
            DomainTemplate domainTemplate); @Override void putDomainTemplateExt(ResourceContext ctx, String domainName,
            String templateName, String auditRef, DomainTemplate domainTemplate); void deleteDomainTemplate(ResourceContext ctx, String domainName, String templateName, String auditRef); boolean access(String action, String resource, Principal principal, String trustDomain); Access getAccessExt(ResourceContext ctx, String action, String resource,
            String trustDomain, String checkPrincipal); Access getAccess(ResourceContext ctx, String action, String resource,
            String trustDomain, String checkPrincipal); @Override void putEntity(ResourceContext ctx, String domainName, String entityName, String auditRef, Entity resource); @Override EntityList getEntityList(ResourceContext ctx, String domainName); Entity getEntity(ResourceContext ctx, String domainName, String entityName); void deleteEntity(ResourceContext ctx, String domainName, String entityName, String auditRef); ServerTemplateList getServerTemplateList(ResourceContext ctx); Template getTemplate(ResourceContext ctx, String templateName); @Override DomainTemplateDetailsList getDomainTemplateDetailsList(ResourceContext ctx, String domainName); RoleList getRoleList(ResourceContext ctx, String domainName, Integer limit, String skip); Roles getRoles(ResourceContext ctx, String domainName, Boolean members); @Override DomainRoleMembers getDomainRoleMembers(ResourceContext ctx, String domainName); @Override DomainRoleMember getPrincipalRoles(ResourceContext context, String principal, String domainName); @Override Role getRole(ResourceContext ctx, String domainName, String roleName,
            Boolean auditLog, Boolean expand, Boolean pending); @Override void putRole(ResourceContext ctx, String domainName, String roleName, String auditRef, Role role); void deleteRole(ResourceContext ctx, String domainName, String roleName, String auditRef); @Override Membership getMembership(ResourceContext ctx, String domainName,
            String roleName, String memberName, String expiration); @Override DomainRoleMembers getOverdueReview(ResourceContext ctx, String domainName); @Override void putMembership(ResourceContext ctx, String domainName, String roleName,
            String memberName, String auditRef, Membership membership); void deletePendingMembership(ResourceContext ctx, String domainName, String roleName,
            String memberName, String auditRef); void deleteMembership(ResourceContext ctx, String domainName, String roleName,
            String memberName, String auditRef); Quota getQuota(ResourceContext ctx, String domainName); @Override void putQuota(ResourceContext ctx, String domainName, String auditRef, Quota quota); void deleteQuota(ResourceContext ctx, String domainName, String auditRef); PolicyList getPolicyList(ResourceContext ctx, String domainName, Integer limit, String skip); Policies getPolicies(ResourceContext ctx, String domainName, Boolean assertions); Policy getPolicy(ResourceContext ctx, String domainName, String policyName); Assertion getAssertion(ResourceContext ctx, String domainName, String policyName,
            Long assertionId); @Override Assertion putAssertion(ResourceContext ctx, String domainName, String policyName,
            String auditRef, Assertion assertion); void deleteAssertion(ResourceContext ctx, String domainName, String policyName,
            Long assertionId, String auditRef); @Override void putPolicy(ResourceContext ctx, String domainName, String policyName, String auditRef, Policy policy); void deletePolicy(ResourceContext ctx, String domainName, String policyName, String auditRef); boolean isValidServiceName(final String serviceName); @Override void putServiceIdentity(ResourceContext ctx, String domainName, String serviceName,
                                   String auditRef, ServiceIdentity service); @Override void putServiceIdentitySystemMeta(ResourceContext ctx, String domainName, String serviceName,
             String attribute, String auditRef, ServiceIdentitySystemMeta meta); ServiceIdentity getServiceIdentity(ResourceContext ctx, String domainName, String serviceName); void deleteServiceIdentity(ResourceContext ctx, String domainName,
            String serviceName, String auditRef); ServiceIdentities getServiceIdentities(ResourceContext ctx, String domainName,
            Boolean publicKeys, Boolean hosts); ServiceIdentityList getServiceIdentityList(ResourceContext ctx, String domainName,
            Integer limit, String skip); PublicKeyEntry getPublicKeyEntry(ResourceContext ctx, String domainName, String serviceName, String keyId); void deletePublicKeyEntry(ResourceContext ctx, String domainName, String serviceName,
            String keyId, String auditRef); @Override void putPublicKeyEntry(ResourceContext ctx, String domainName, String serviceName,
            String keyId, String auditRef, PublicKeyEntry keyEntry); @Override Response getSignedDomains(ResourceContext ctx, String domainName, String metaOnly,
            String metaAttr, Boolean master, String matchingTag); @Override JWSDomain getJWSDomain(ResourceContext ctx, String domainName); @Override UserToken getUserToken(ResourceContext ctx, String userName, String authorizedServices,
            Boolean header); UserToken optionsUserToken(ResourceContext ctx, String userName, String authorizedServices); @Override void putTenancy(ResourceContext ctx, String tenantDomain, String provider,
            String auditRef, Tenancy detail); @Override void deleteTenancy(ResourceContext ctx, String tenantDomain, String provider, String auditRef); @Override void putTenant(ResourceContext ctx, String providerDomain, String providerService,
           String tenantDomain, String auditRef, Tenancy detail); @Override void deleteTenant(ResourceContext ctx, String providerDomain, String providerService,
            String tenantDomain, String auditRef); @Override TenantResourceGroupRoles putTenantResourceGroupRoles(ResourceContext ctx, String provSvcDomain,
            String provSvcName, String tenantDomain, String resourceGroup, String auditRef,
            TenantResourceGroupRoles detail); DomainDataCheck getDomainDataCheck(ResourceContext ctx, String domainName); void deleteProviderResourceGroupRoles(ResourceContext ctx, String tenantDomain,
             String provSvcDomain, String provSvcName, String resourceGroup, String auditRef); ProviderResourceGroupRoles getProviderResourceGroupRoles(ResourceContext ctx, String tenantDomain,
            String provSvcDomain, String provSvcName, String resourceGroup); @Override ProviderResourceGroupRoles putProviderResourceGroupRoles(ResourceContext ctx, String tenantDomain,
             String provSvcDomain, String provSvcName, String resourceGroup, String auditRef,
             ProviderResourceGroupRoles detail); TenantResourceGroupRoles getTenantResourceGroupRoles(ResourceContext ctx, String provSvcDomain,
            String provSvcName, String tenantDomain, String resourceGroup); void deleteTenantResourceGroupRoles(ResourceContext ctx, String provSvcDomain,
            String provSvcName, String tenantDomain, String resourceGroup, String auditRef); @Override String getPublicKey(String domain, String service, String keyId); @Override void putDefaultAdmins(ResourceContext ctx, String domainName, String auditRef,
            DefaultAdmins defaultAdmins); ServicePrincipal getServicePrincipal(ResourceContext ctx); @Override ResourceAccessList getResourceAccessList(ResourceContext ctx, String principal,
            String action); @Override Status getStatus(ResourceContext ctx); ResourceContext newResourceContext(HttpServletRequest request,
                                              HttpServletResponse response,
                                              String apiName); @Override Schema getRdlSchema(ResourceContext context); static String getRootDir(); @Override void putRoleSystemMeta(ResourceContext ctx, String domainName, String roleName, String attribute,
            String auditRef, RoleSystemMeta meta); @Override void putRoleMeta(ResourceContext ctx, String domainName, String roleName, String auditRef, RoleMeta meta); @Override void putMembershipDecision(ResourceContext ctx, String domainName, String roleName,
            String memberName, String auditRef, Membership membership); @Override DomainRoleMembership getPendingDomainRoleMembersList(ResourceContext ctx, String principal); @Override void putRoleReview(ResourceContext ctx, String domainName, String roleName, String auditRef, Role role); @Override Groups getGroups(ResourceContext ctx, String domainName, Boolean members); @Override Group getGroup(ResourceContext ctx, String domainName, String groupName, Boolean auditLog, Boolean pending); @Override void putGroup(ResourceContext ctx, String domainName, String groupName, String auditRef, Group group); @Override void deleteGroup(ResourceContext ctx, String domainName, String groupName, String auditRef); @Override GroupMembership getGroupMembership(ResourceContext ctx, String domainName, String groupName, String memberName, String expiration); @Override void putGroupMembership(ResourceContext ctx, String domainName, String groupName, String memberName, String auditRef, GroupMembership membership); @Override void deleteGroupMembership(ResourceContext ctx, String domainName, String groupName, String memberName, String auditRef); @Override void deletePendingGroupMembership(ResourceContext ctx, String domainName, String groupName, String memberName, String auditRef); @Override DomainGroupMember getPrincipalGroups(ResourceContext ctx, String principal, String domainName); @Override void putGroupSystemMeta(ResourceContext ctx, String domainName, String groupName, String attribute,
                                   String auditRef, GroupSystemMeta meta); @Override void putGroupMeta(ResourceContext ctx, String domainName, String groupName, String auditRef, GroupMeta meta); @Override void putGroupMembershipDecision(ResourceContext ctx, String domainName, String groupName, String memberName,
                                           String auditRef, GroupMembership membership); @Override void putGroupReview(ResourceContext ctx, String domainName, String groupName, String auditRef, Group group); @Override DomainGroupMembership getPendingDomainGroupMembersList(ResourceContext ctx, String principal); void recordMetrics(ResourceContext ctx, int httpStatus); static Metric metric; static String serverHostName; }
@Test public void testGetSignedDomains() { loadServerPublicKeys(zms); TopLevelDomain dom1 = createTopLevelDomainObject("SignedDom1", "Test Domain1", "testOrg", adminUser); zms.postTopLevelDomain(mockDomRsrcCtx, auditRef, dom1); Group group1 = createGroupObject("signeddom1", "group1", "user.user1", "user.user2"); zms.putGroup(mockDomRsrcCtx, "signeddom1", "group1", auditRef, group1); DomainMeta meta = createDomainMetaObject("Tenant Domain1", null, true, false, "12345", 0); zms.putDomainMeta(mockDomRsrcCtx, "signeddom1", auditRef, meta); meta = createDomainMetaObject("Tenant Domain1", null, true, false, "12345", 0); zms.putDomainSystemMeta(mockDomRsrcCtx, "signeddom1", "account", auditRef, meta); TopLevelDomain dom2 = createTopLevelDomainObject("SignedDom2", "Test Domain2", "testOrg", adminUser); zms.postTopLevelDomain(mockDomRsrcCtx, auditRef, dom2); meta = createDomainMetaObject("Tenant Domain2", null, false, false, "12346", null); zms.putDomainMeta(mockDomRsrcCtx, "signeddom2", auditRef, meta); meta = createDomainMetaObject("Tenant Domain2", null, false, false, "12346", null); zms.putDomainSystemMeta(mockDomRsrcCtx, "signeddom2", "account", auditRef, meta); DomainList domList = zms.getDomainList(mockDomRsrcCtx, null, null, null, null, null, null, null, null, null); List<String> domNames = domList.getNames(); int numDoms = domNames.size(); zms.privateKey = new ServerPrivateKey(Crypto.loadPrivateKey(Crypto.ybase64DecodeString(privKey)), "0"); Authority principalAuthority = new com.yahoo.athenz.common.server.debug.DebugPrincipalAuthority(); Principal sysPrincipal = principalAuthority.authenticate("v=U1;d=sys;n=zts;s=signature", "10.11.12.13", "GET", null); ResourceContext rsrcCtx = createResourceContext(sysPrincipal); Response response = zms.getSignedDomains(rsrcCtx, null, null, null, null, null); SignedDomains sdoms = (SignedDomains) response.getEntity(); assertNotNull(sdoms); List<SignedDomain> list = sdoms.getDomains(); assertNotNull(list); assertEquals(list.size(), numDoms); boolean dom1Found = false; boolean dom2Found = false; for (SignedDomain sDomain : list) { String signature = sDomain.getSignature(); String keyId = sDomain.getKeyId(); String publicKey = zms.getPublicKey("sys.auth", "zms", keyId); DomainData domainData = sDomain.getDomain(); if (domainData.getName().equals("signeddom1")) { assertEquals("12345", domainData.getAccount()); dom1Found = true; } else if (domainData.getName().equals("signeddom2")) { assertEquals("12346", domainData.getAccount()); dom2Found = true; } assertTrue(Crypto.verify(SignUtils.asCanonicalString(sDomain.getDomain()), Crypto.loadPublicKey(publicKey), signature)); } assertTrue(dom1Found); assertTrue(dom2Found); zms.privateKey = new ServerPrivateKey(Crypto.loadPrivateKey(Crypto.ybase64DecodeString(privKeyK1)), "1"); response = zms.getSignedDomains(rsrcCtx, null, null, "all", null, null); sdoms = (SignedDomains) response.getEntity(); assertNotNull(sdoms); list = sdoms.getDomains(); assertNotNull(list); assertEquals(list.size(), numDoms); for(SignedDomain sDomain : list) { String signature = sDomain.getSignature(); String keyId = sDomain.getKeyId(); String publicKey = zms.getPublicKey("sys.auth", "zms", keyId); assertTrue(Crypto.verify(SignUtils.asCanonicalString(sDomain.getDomain()), Crypto.loadPublicKey(publicKey), signature)); SignedPolicies signedPolicies = sDomain.getDomain().getPolicies(); signature = signedPolicies.getSignature(); assertTrue(Crypto.verify(SignUtils.asCanonicalString(signedPolicies.getContents()), Crypto.loadPublicKey(publicKey), signature)); } zms.privateKey = new ServerPrivateKey(Crypto.loadPrivateKey(Crypto.ybase64DecodeString(privKeyK2)), "2"); response = zms.getSignedDomains(rsrcCtx, null, null, null, Boolean.TRUE, null); sdoms = (SignedDomains) response.getEntity(); assertNotNull(sdoms); list = sdoms.getDomains(); assertNotNull(list); assertEquals(list.size(), numDoms); for(SignedDomain sDomain : list) { String signature = sDomain.getSignature(); String keyId = sDomain.getKeyId(); String publicKey = zms.getPublicKey("sys.auth", "zms", keyId); assertTrue(Crypto.verify(SignUtils.asCanonicalString(sDomain.getDomain()), Crypto.loadPublicKey(publicKey), signature)); } response = zms.getSignedDomains(rsrcCtx, null, "tRuE", null, Boolean.FALSE, null); sdoms = (SignedDomains) response.getEntity(); assertNotNull(sdoms); list = sdoms.getDomains(); assertNotNull(list); assertEquals(list.size(), numDoms); for (SignedDomain sDomain : list) { String signature = sDomain.getSignature(); assertTrue(signature == null || signature.isEmpty()); String keyId = sDomain.getKeyId(); assertTrue(keyId == null || keyId.isEmpty()); DomainData ddata = sDomain.getDomain(); assertNotNull(ddata); assertFalse(ddata.getName().isEmpty()); assertNotNull(ddata.getModified()); assertNull(ddata.getPolicies()); assertNull(ddata.getRoles()); assertNull(ddata.getServices()); } response = zms.getSignedDomains(rsrcCtx, null, "garbage", null, null, null); sdoms = (SignedDomains) response.getEntity(); assertNotNull(sdoms); list = sdoms.getDomains(); assertNotNull(list); assertEquals(list.size(), numDoms); for (SignedDomain sDomain : list) { String signature = sDomain.getSignature(); String keyId = sDomain.getKeyId(); String publicKey = zms.getPublicKey("sys.auth", "zms", keyId); assertTrue(Crypto.verify(SignUtils.asCanonicalString(sDomain.getDomain()), Crypto.loadPublicKey(publicKey), signature)); DomainData ddata = sDomain.getDomain(); assertNotNull(ddata.getPolicies()); assertTrue(ddata.getRoles() != null && ddata.getRoles().size() > 0); assertNotNull(ddata.getServices()); } response = zms.getSignedDomains(rsrcCtx, null, "fAlSe", null, null, null); sdoms = (SignedDomains) response.getEntity(); assertNotNull(sdoms); list = sdoms.getDomains(); assertNotNull(list); assertEquals(list.size(), numDoms); for (SignedDomain sDomain : list) { String signature = sDomain.getSignature(); String keyId = sDomain.getKeyId(); String publicKey = zms.getPublicKey("sys.auth", "zms", keyId); assertTrue(Crypto.verify(SignUtils.asCanonicalString(sDomain.getDomain()), Crypto.loadPublicKey(publicKey), signature)); DomainData ddata = sDomain.getDomain(); assertNotNull(ddata.getPolicies()); assertTrue(ddata.getRoles() != null && ddata.getRoles().size() > 0); assertNotNull(ddata.getServices()); } String eTag = "I am not good"; response = zms.getSignedDomains(rsrcCtx, null, null, null, Boolean.TRUE, eTag); sdoms = (SignedDomains) response.getEntity(); String eTag2 = response.getHeaderString("ETag"); assertNotNull(eTag2); assertNotEquals(eTag, eTag2); list = sdoms.getDomains(); assertNotNull(list); assertEquals(list.size(), numDoms); ZMSUtils.threadSleep(1000); Policy policy1 = createPolicyObject("SignedDom1", "Policy1"); zms.putPolicy(mockDomRsrcCtx, "SignedDom1", "Policy1", auditRef, policy1); response = zms.getSignedDomains(rsrcCtx, null, null, null, true, eTag2); sdoms = (SignedDomains) response.getEntity(); eTag = response.getHeaderString("ETag"); assertNotNull(eTag); assertNotEquals(eTag, eTag2); list = sdoms.getDomains(); assertNotNull(list); assertEquals(1, list.size()); response = zms.getSignedDomains(rsrcCtx, null, null, null, Boolean.TRUE, eTag); assertEquals(304, response.getStatus()); eTag2 = response.getHeaderString("ETag"); assertNotNull(eTag2); assertEquals(eTag, eTag2); zms.deleteTopLevelDomain(mockDomRsrcCtx, "SignedDom1", auditRef); zms.deleteTopLevelDomain(mockDomRsrcCtx, "SignedDom2", auditRef); }