From fdb2f06d8aa5231681603e11789f29c4ddb9eed7 Mon Sep 17 00:00:00 2001 From: Tak Date: Thu, 28 Nov 2024 09:40:18 +0900 Subject: [PATCH] If there is only one admin role member, the member cannot be deleted. (#2810) Signed-off-by: takumats --- .../java/com/yahoo/athenz/zms/ZMSImpl.java | 13 ++++++++ .../yahoo/athenz/zms/ZMSDeleteDomainTest.java | 33 +++++++++++++++++++ 2 files changed, 46 insertions(+) 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 8c122bf0183..59e170b8bbe 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 @@ -2201,6 +2201,19 @@ public void deleteDomainRoleMember(ResourceContext ctx, String domainName, Strin setRequestDomain(ctx, domainName); memberName = memberName.toLowerCase(); + // if this is the admin role then we need to make sure + // the admin is not himself who happens to be the last + // member in the role + AthenzDomain domain = getAthenzDomain(domainName, false); + Role adminRole = getRoleFromDomain(ZMSConsts.ADMIN_ROLE_NAME, domain); + if (adminRole == null) { + throw ZMSUtils.notFoundError("Invalid domain name specified", caller); + } + List members = adminRole.getRoleMembers(); + if (members.size() == 1 && members.get(0).getMemberName().equals(memberName)) { + throw ZMSUtils.forbiddenError("deleteDomainRoleMember: Cannot delete last member of 'admin' role", caller); + } + // verify that request is properly authenticated for this request verifyAuthorizedServiceOperation(((RsrcCtxWrapper) ctx).principal().getAuthorizedService(), caller); diff --git a/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSDeleteDomainTest.java b/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSDeleteDomainTest.java index ac3e7b3e49d..a3c72a09dee 100644 --- a/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSDeleteDomainTest.java +++ b/servers/zms/src/test/java/com/yahoo/athenz/zms/ZMSDeleteDomainTest.java @@ -860,6 +860,39 @@ public void testDeleteDomainRoleMember() { zmsImpl.deleteTopLevelDomain(ctx, domainName, auditRef, null); } + @Test + public void testDeleteDomainRoleMemberWhenSingleAdmin() { + + String domainName = "deletedomainrolemember3"; + ZMSImpl zmsImpl = zmsTestInitializer.getZms(); + RsrcCtxWrapper ctx = zmsTestInitializer.getMockDomRsrcCtx(); + final String auditRef = zmsTestInitializer.getAuditRef(); + + TopLevelDomain dom1 = zmsTestInitializer.createTopLevelDomainObject(domainName, + "Test Domain1", "testOrg", zmsTestInitializer.getAdminUser()); + zmsImpl.postTopLevelDomain(ctx, auditRef, null, dom1); + + Role adminRole = zmsTestInitializer.createRoleObject(domainName, "admin", null, + "user.jack", null); + zmsImpl.putRole(ctx, domainName, "admin", auditRef, false, null, adminRole); + + DomainRoleMembers domainRoleMembers = zmsImpl.getDomainRoleMembers(ctx, domainName); + assertEquals(domainName, domainRoleMembers.getDomainName()); + + List members = domainRoleMembers.getMembers(); + assertNotNull(members); + assertEquals(members.size(), 1); + ZMSTestUtils.verifyDomainRoleMember(members, "user.jack", "admin"); + + try { + zmsImpl.deleteDomainRoleMember(ctx, domainName, "user.jack", auditRef); + fail(); + } catch (ResourceException ex) { + assertEquals(ex.getCode(), ResourceException.FORBIDDEN); + } + zmsImpl.deleteTopLevelDomain(ctx, domainName, auditRef, null); + } + @Test public void testDeleteUserDomainNull() { Authority userAuthority = new com.yahoo.athenz.common.server.debug.DebugUserAuthority();