diff --git a/cerberus-web/src/main/java/com/nike/cerberus/service/SafeDepositBoxService.java b/cerberus-web/src/main/java/com/nike/cerberus/service/SafeDepositBoxService.java index a2556265..40cfe433 100644 --- a/cerberus-web/src/main/java/com/nike/cerberus/service/SafeDepositBoxService.java +++ b/cerberus-web/src/main/java/com/nike/cerberus/service/SafeDepositBoxService.java @@ -621,6 +621,8 @@ protected void updateOwner( } if (!StringUtils.equals(userGroupOwnerRecords.get(0).getName(), newOwner)) { + userGroupPermissionService.ensureUserHasNoSdbPermissions(safeDepositBoxId, newOwner); + UserGroupPermission oldOwnerPermission = new UserGroupPermission(); oldOwnerPermission.setName(userGroupOwnerRecords.get(0).getName()); oldOwnerPermission.setRoleId(ownerRole.get().getId()); diff --git a/cerberus-web/src/main/java/com/nike/cerberus/service/UserGroupPermissionService.java b/cerberus-web/src/main/java/com/nike/cerberus/service/UserGroupPermissionService.java index 94242fa0..77e3c9da 100644 --- a/cerberus-web/src/main/java/com/nike/cerberus/service/UserGroupPermissionService.java +++ b/cerberus-web/src/main/java/com/nike/cerberus/service/UserGroupPermissionService.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @@ -182,6 +183,24 @@ public void updateUserGroupPermission( userGroupDao.updateUserGroupPermission(record); } + /** + * Revokes any user permission on the SDB for the user This is case-insensitive, so it will clean + * up weird cased duplicates too + * + * @param safeDepositBoxId The safe deposit box's name + * @param userGroupName Name of the user group + */ + public void ensureUserHasNoSdbPermissions(String safeDepositBoxId, String userGroupName) { + final String userGroupNameLowered = userGroupName.toLowerCase(); + final Set sdbUserGroupPermission = + getUserGroupPermissions(safeDepositBoxId); + final Set newOwnerExistingSdbPermissions = + sdbUserGroupPermission.stream() + .filter(perm -> perm.getName().toLowerCase().equals(userGroupNameLowered)) + .collect(Collectors.toSet()); + revokeUserGroupPermissions(safeDepositBoxId, newOwnerExistingSdbPermissions); + } + /** * Revokes a set of user group permissions. * diff --git a/cerberus-web/src/test/java/com/nike/cerberus/service/SafeDepositBoxServiceTest.java b/cerberus-web/src/test/java/com/nike/cerberus/service/SafeDepositBoxServiceTest.java index 5117cb0c..f6844de0 100644 --- a/cerberus-web/src/test/java/com/nike/cerberus/service/SafeDepositBoxServiceTest.java +++ b/cerberus-web/src/test/java/com/nike/cerberus/service/SafeDepositBoxServiceTest.java @@ -42,6 +42,7 @@ import com.nike.cerberus.domain.UserGroupPermission; import com.nike.cerberus.record.RoleRecord; import com.nike.cerberus.record.SafeDepositBoxRecord; +import com.nike.cerberus.record.UserGroupRecord; import com.nike.cerberus.security.CerberusPrincipal; import com.nike.cerberus.util.AwsIamRoleArnParser; import com.nike.cerberus.util.DateTimeSupplier; @@ -49,16 +50,20 @@ import com.nike.cerberus.util.UuidSupplier; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.time.OffsetDateTime; +import java.time.ZoneId; import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; import org.assertj.core.util.Lists; import org.assertj.core.util.Sets; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.InjectMocks; +import org.mockito.Matchers; import org.mockito.Mock; +import org.mockito.Mockito; public class SafeDepositBoxServiceTest { @@ -389,6 +394,62 @@ public void test_that_overrideSdbOwner_calls_update_owner() { .updateOwner(id, "new-owner", "admin-user", offsetDateTime); } + @Test + public void testEnsureUserHasNoSdbPermissionsWhenNoUserGroupPermissionRecordPresent() { + final OffsetDateTime now = OffsetDateTime.now(ZoneId.of("UTC")); + + UserGroupPermission notBuddy = + new UserGroupPermission().withName("notBuddy").withRoleId("read"); + + notBuddy.setCreatedBy("system"); + notBuddy.setLastUpdatedBy("system"); + notBuddy.setCreatedTs(now); + notBuddy.setLastUpdatedTs(now); + + final UserGroupRecord notBuddyUserGroupRecord = + new UserGroupRecord() + .setId("notBuddyId") + .setName("notBuddy") + .setCreatedBy("system") + .setLastUpdatedBy("system") + .setCreatedTs(now) + .setLastUpdatedTs(now); + + UserGroupPermission buddy = new UserGroupPermission().withName("buddy").withRoleId("read"); + + buddy.setCreatedBy("system"); + buddy.setLastUpdatedBy("system"); + buddy.setCreatedTs(now); + buddy.setLastUpdatedTs(now); + + UserGroupPermission buddyCaps = new UserGroupPermission().withName("Buddy").withRoleId("read"); + + buddyCaps.setCreatedBy("system"); + buddyCaps.setLastUpdatedBy("system"); + buddyCaps.setCreatedTs(now); + buddyCaps.setLastUpdatedTs(now); + + Set buddies = new HashSet<>(); + buddies.add(buddy); + buddies.add(buddyCaps); + + List ownerGroupRecords = List.of(notBuddyUserGroupRecord); + Mockito.when(userGroupDao.getUserGroupsByRole("safeBoxId", "ownerId")) + .thenReturn(ownerGroupRecords); + + Optional ownerRoleOptional = Optional.of(new Role().setName("owner").setId("ownerId")); + Mockito.when(roleService.getRoleByName(Matchers.anyString())).thenReturn(ownerRoleOptional); + + Mockito.when(userGroupPermissionService.getUserGroupPermissions("safeBoxId")) + .thenReturn(buddies); + Set userGroupPermissions = + userGroupPermissionService.getUserGroupPermissions("safeBoxId"); + Assert.assertFalse(userGroupPermissions.isEmpty()); + safeDepositBoxService.updateOwner("safeBoxId", "buddy", "system", OffsetDateTime.now()); + Mockito.verify(userGroupPermissionService, Mockito.atLeastOnce()) + .ensureUserHasNoSdbPermissions("safeBoxId", "buddy"); + } + @Test @SuppressFBWarnings public void test_that_getAssociatedSafeDepositBoxes_checks_assumed_role_and_its_base_iam_role() { diff --git a/cerberus-web/src/test/java/com/nike/cerberus/service/UserGroupPermissionServiceTest.java b/cerberus-web/src/test/java/com/nike/cerberus/service/UserGroupPermissionServiceTest.java index c29ac40c..0ba91bf5 100644 --- a/cerberus-web/src/test/java/com/nike/cerberus/service/UserGroupPermissionServiceTest.java +++ b/cerberus-web/src/test/java/com/nike/cerberus/service/UserGroupPermissionServiceTest.java @@ -14,6 +14,7 @@ import com.nike.cerberus.record.UserGroupRecord; import com.nike.cerberus.util.UuidSupplier; import java.time.OffsetDateTime; +import java.time.ZoneId; import java.util.*; import org.junit.Assert; import org.junit.Before; @@ -253,6 +254,72 @@ public void testGetUserGroupPermissionsForGivenSafeBoxIdWhenNoUserGroupPermissio Assert.assertTrue(userGroupPermissions.isEmpty()); } + @Test + public void testEnsureUserHasNoSdbPermissionsWhenNoUserGroupPermissionRecordPresent() { + final OffsetDateTime now = OffsetDateTime.now(ZoneId.of("UTC")); + + UserGroupPermissionRecord buddy = + new UserGroupPermissionRecord() + .setId("buddyId") + .setRoleId("read") + .setUserGroupId("buddy") + .setCreatedBy("system") + .setLastUpdatedBy("system") + .setCreatedTs(now) + .setLastUpdatedTs(now); + + final UserGroupRecord buddyUserGroupRecord = + new UserGroupRecord() + .setId("buddyId") + .setName("buddy") + .setCreatedBy("system") + .setLastUpdatedBy("system") + .setCreatedTs(now) + .setLastUpdatedTs(now); + + UserGroupPermissionRecord buddyCaps = + new UserGroupPermissionRecord() + .setUserGroupId("Buddy") + .setCreatedBy("system") + .setLastUpdatedBy("system") + .setCreatedTs(now) + .setLastUpdatedTs(now); + + final UserGroupRecord buddyCapsUserGroupRecord = + new UserGroupRecord() + .setId("buddyCapsId") + .setName("Buddy") + .setCreatedBy("system") + .setLastUpdatedBy("system") + .setCreatedTs(now) + .setLastUpdatedTs(now); + + List buddies = new ArrayList<>(); + buddies.add(buddy); + buddies.add(buddyCaps); + + Mockito.when(userGroupDao.getUserGroupPermissions("safeBoxId")).thenReturn(buddies); + + Optional optionalBuddyUgr = Optional.of(buddyUserGroupRecord); + Optional optionalBuddyCapsUgr = Optional.of(buddyCapsUserGroupRecord); + + Mockito.when(userGroupDao.getUserGroup("buddy")).thenReturn(optionalBuddyUgr); + Mockito.when(userGroupDao.getUserGroup("Buddy")).thenReturn(optionalBuddyCapsUgr); + + Mockito.when(userGroupDao.getUserGroupByName("buddy")).thenReturn(optionalBuddyUgr); + Mockito.when(userGroupDao.getUserGroupByName("Buddy")).thenReturn(optionalBuddyCapsUgr); + + Set userGroupPermissions = + userGroupPermissionService.getUserGroupPermissions("safeBoxId"); + Assert.assertFalse(userGroupPermissions.isEmpty()); + userGroupPermissionService.ensureUserHasNoSdbPermissions("safeBoxId", "buddy"); + + Mockito.verify(userGroupDao, Mockito.atLeastOnce()) + .deleteUserGroupPermission("safeBoxId", "buddyId"); + Mockito.verify(userGroupDao, Mockito.atLeastOnce()) + .deleteUserGroupPermission("safeBoxId", "buddyCapsId"); + } + @Test public void testGetUserGroupPermissionsForGivenSafeBoxIdWhenUserGroupPermissionRecordPresent() { UserGroupPermissionRecord userGroupPermissionRecord = getUserGroupPermissionRecord();