ZMSImpl implements Authorizer, KeyStore, ZMSHandler { @Override public void putMembership(ResourceContext ctx, String domainName, String roleName, String memberName, String auditRef, Membership membership) { final String caller = ctx.getApiName(); logPrincipal(ctx); if (readOnlyMode) { throw ZMSUtils.requestError(SERVER_READ_ONLY_MESSAGE, caller); } validateRequest(ctx.request(), caller); validate(domainName, TYPE_DOMAIN_NAME, caller); setRequestDomain(ctx, domainName); validate(roleName, TYPE_ENTITY_NAME, caller); validate(memberName, TYPE_MEMBER_NAME, caller); validate(membership, TYPE_MEMBERSHIP, caller); domainName = domainName.toLowerCase(); roleName = roleName.toLowerCase(); memberName = memberName.toLowerCase(); AthenzObject.MEMBERSHIP.convertToLowerCase(membership); final Principal principal = ((RsrcCtxWrapper) ctx).principal(); verifyAuthorizedServiceRoleOperation(principal.getAuthorizedService(), caller, roleName); if (!memberName.equals(membership.getMemberName())) { throw ZMSUtils.requestError("putMembership: Member name in URI and Membership object do not match", caller); } if (membership.getRoleName() != null && !roleName.equals(membership.getRoleName())) { throw ZMSUtils.requestError("putMembership: Role name in URI and Membership object do not match", caller); } AthenzDomain domain = getAthenzDomain(domainName, false); Role role = getRoleFromDomain(roleName, domain); if (role == null) { throw ZMSUtils.requestError("Invalid role name specified", caller); } RoleMember roleMember = new RoleMember(); roleMember.setMemberName(normalizeDomainAliasUser(memberName)); roleMember.setPrincipalType(principalType(roleMember.getMemberName())); setRoleMemberExpiration(domain, role, roleMember, membership, caller); setRoleMemberReview(role, roleMember, membership); final String userAuthorityFilter = enforcedUserAuthorityFilter(role.getUserAuthorityFilter(), domain.getDomain().getUserAuthorityFilter()); boolean disallowGroups = ADMIN_ROLE_NAME.equals(roleName); validateRoleMemberPrincipal(roleMember.getMemberName(), roleMember.getPrincipalType(), userAuthorityFilter, role.getUserAuthorityExpiration(), role.getAuditEnabled(), disallowGroups, caller); if (!isAllowedPutMembership(principal, domain, role, roleMember)) { throw ZMSUtils.forbiddenError("putMembership: principal is not authorized to add members", caller); } dbService.executePutMembership(ctx, domainName, roleName, roleMember, auditRef, caller); if (roleMember.getApproved() == Boolean.FALSE) { sendMembershipApprovalNotification(domainName, domain.getDomain().getOrg(), roleName, roleMember.getMemberName(), auditRef, principal.getFullName(), role); } } 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 testPutMembership() { TestAuditLogger alogger = new TestAuditLogger(); ZMSImpl zmsImpl = getZmsImpl(alogger); Mockito.when(mockDomRsrcCtx.getApiName()) .thenReturn("posttopleveldomain") .thenReturn("posttopleveldomain") .thenReturn("postsubdomain") .thenReturn("putrole") .thenReturn("putmembership"); TopLevelDomain dom1 = createTopLevelDomainObject("MbrAddDom1", "Test Domain1", "testOrg", "user.user1"); zmsImpl.postTopLevelDomain(mockDomRsrcCtx, auditRef, dom1); TopLevelDomain dom2 = createTopLevelDomainObject("coretech", "Test Domain2", "testOrg", adminUser); zmsImpl.postTopLevelDomain(mockDomRsrcCtx, auditRef, dom2); SubDomain subDom2 = createSubDomainObject("storage", "coretech", "Test Domain2", "testOrg", adminUser); zmsImpl.postSubDomain(mockDomRsrcCtx, "coretech", auditRef, subDom2); Role role1 = createRoleObject("MbrAddDom1", "Role1", null, "user.joe", "user.jane"); zmsImpl.putRole(mockDomRsrcCtx, "MbrAddDom1", "Role1", auditRef, role1); Membership mbr = generateMembership("Role1", "user.doe"); zmsImpl.putMembership(mockDomRsrcCtx, "MbrAddDom1", "Role1", "user.doe", auditRef, mbr); boolean foundError = false; List<String> aLogMsgs = alogger.getLogMsgList(); System.err.println("testPutMembership: Number of lines: " + aLogMsgs.size()); for (String msg: aLogMsgs) { if (!msg.contains("WHAT-api=(putmembership)")) { continue; } int index = msg.indexOf("WHAT-details=("); assertTrue(index != -1, msg); int index2 = msg.indexOf("{\"member\": \"user.doe\", \"approved\": true, \"system-disabled\": 0}"); assertTrue(index2 > index, msg); foundError = true; break; } assertTrue(foundError); aLogMsgs.clear(); mbr = generateMembership("Role1", "coretech.storage"); zmsImpl.putMembership(mockDomRsrcCtx, "MbrAddDom1", "Role1", "coretech.storage", auditRef, mbr); Role role = zmsImpl.getRole(mockDomRsrcCtx, "MbrAddDom1", "Role1", false, false, false); assertNotNull(role); List<RoleMember> members = role.getRoleMembers(); assertNotNull(members); assertEquals(members.size(), 4); List<String> checkList = new ArrayList<>(); checkList.add("user.joe"); checkList.add("user.jane"); checkList.add("user.doe"); checkList.add("coretech.storage"); checkRoleMember(checkList, members); foundError = false; System.err.println("testPutMembership: now Number of lines: " + aLogMsgs.size()); for (String msg: aLogMsgs) { if (!msg.contains("WHAT-api=(putmembership)")) { continue; } int index = msg.indexOf("WHAT-details=("); assertTrue(index != -1, msg); int index2 = msg.indexOf("{\"member\": \"coretech.storage\", \"approved\": true, \"system-disabled\": 0}"); assertTrue(index2 > index, msg); foundError = true; break; } assertTrue(foundError); zmsImpl.userAuthority = new TestUserPrincipalAuthority(); zmsImpl.validateUserRoleMembers = true; mbr = generateMembership("role1", "user.joe"); zmsImpl.putMembership(mockDomRsrcCtx, "MbrAddDom1", "role1", "user.joe", auditRef, mbr); mbr = generateMembership("role1", "user.john"); try { zmsImpl.putMembership(mockDomRsrcCtx, "MbrAddDom1", "role1", "user.john", auditRef, mbr); fail(); } catch (ResourceException ex) { assertEquals(ex.getCode(), ResourceException.BAD_REQUEST); } zmsImpl.deleteSubDomain(mockDomRsrcCtx, "coretech", "storage", auditRef); zmsImpl.deleteTopLevelDomain(mockDomRsrcCtx, "coretech", auditRef); zmsImpl.deleteTopLevelDomain(mockDomRsrcCtx,"MbrAddDom1", auditRef); }