From b56801d413f5a26eb95f69337c61b1279ae991f0 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 6 Dec 2022 10:07:06 -0700 Subject: [PATCH 1/4] Disabled group change on dynamic reg when enabled --- .../dynamic-registration/component/DynamicRegistrationList.js | 2 +- .../app/dynamic-registration/view/DynamicRegistrationDetail.js | 2 +- .../app/store/dynamic-registration/DynamicRegistrationSlice.js | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ui/src/app/dynamic-registration/component/DynamicRegistrationList.js b/ui/src/app/dynamic-registration/component/DynamicRegistrationList.js index 5788018b0..39e0a9866 100644 --- a/ui/src/app/dynamic-registration/component/DynamicRegistrationList.js +++ b/ui/src/app/dynamic-registration/component/DynamicRegistrationList.js @@ -103,7 +103,7 @@ export function DynamicRegistrationList ({entities, children, onChangeGroup, onD className="form-control" onChange={(event) => onChangeGroup(reg, event.target.value)} value={reg.idOfOwner ? reg.idOfOwner : ''} - disabled={loadingGroups} + disabled={loadingGroups || reg.enabled} disablevalidation="true"> {groups.map((g, ridx) => ( diff --git a/ui/src/app/dynamic-registration/view/DynamicRegistrationDetail.js b/ui/src/app/dynamic-registration/view/DynamicRegistrationDetail.js index ca6c93cbd..7d5d800ea 100644 --- a/ui/src/app/dynamic-registration/view/DynamicRegistrationDetail.js +++ b/ui/src/app/dynamic-registration/view/DynamicRegistrationDetail.js @@ -86,7 +86,7 @@ export function DynamicRegistrationDetail () { className="form-control form-control-sm" onChange={({target: {value}}) => changeGroup({ registration: detail, group: value })} value={detail.idOfOwner} - disabled={loadingGroups} + disabled={loadingGroups || detail.enabled} disablevalidation="true"> {groups.map((g, ridx) => ( diff --git a/ui/src/app/store/dynamic-registration/DynamicRegistrationSlice.js b/ui/src/app/store/dynamic-registration/DynamicRegistrationSlice.js index e39700294..eec39b071 100644 --- a/ui/src/app/store/dynamic-registration/DynamicRegistrationSlice.js +++ b/ui/src/app/store/dynamic-registration/DynamicRegistrationSlice.js @@ -13,12 +13,14 @@ export const DynamicRegistrationApi = createApi({ url: `/DynamicRegistrations` }), providesTags: ['DynamicRegistration'], + // transformResponse: (registrations) => [...registrations.map(r => ({...r, enabled: true}))] }), selectDynamicRegistration: builder.query({ query: ({id}) => ({ url: `/DynamicRegistration/${id}` }), providesTags: ['DynamicRegistration'], + // transformResponse: (reg) => ({...reg, enabled: true}) }), getDisabledRegistrations: builder.query({ query: () => ({ From 3915e8694c9d8637942fafee45bf4a9d6def7f4e Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 6 Dec 2022 10:16:16 -0700 Subject: [PATCH 2/4] SHIBUI-2393/2492 fixed when activating - set approved to true --- .../admin/ui/service/JPADynamicRegistrationServiceImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPADynamicRegistrationServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPADynamicRegistrationServiceImpl.java index 3ac846b39..7f47d8086 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPADynamicRegistrationServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPADynamicRegistrationServiceImpl.java @@ -146,6 +146,7 @@ public HttpStatus enableDynamicRegistration(String resourceId) throws Persistent HttpStatus status = shibRestTemplateDelegate.sendRequest(existingDri); if (status == HttpStatus.CREATED || status == HttpStatus.OK) { existingDri.setEnabled(true); + existingDri.setApproved(true); repository.save(existingDri); } return status; From d7cd6fbe66f5b755dce61ee559cf1ba2990bfc3c Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 6 Dec 2022 11:04:12 -0700 Subject: [PATCH 3/4] SHIBUI-2393/2493 fixed issue when changing dynamic registration group --- .../ui/security/controller/GroupController.java | 5 +++++ .../DynamicRegistrationInfoRepository.java | 3 +++ .../ui/service/DynamicRegistrationService.java | 3 +++ .../JPADynamicRegistrationServiceImpl.java | 15 +++++++++++++++ 4 files changed, 26 insertions(+) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupController.java index 6352e01ca..2b4b2e9c8 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupController.java @@ -6,6 +6,7 @@ import edu.internet2.tier.shibboleth.admin.ui.security.exception.InvalidGroupRegexException; import edu.internet2.tier.shibboleth.admin.ui.security.model.Group; import edu.internet2.tier.shibboleth.admin.ui.security.service.IGroupService; +import edu.internet2.tier.shibboleth.admin.ui.service.DynamicRegistrationService; import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorService; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tags; @@ -33,6 +34,9 @@ public class GroupController { @Autowired private EntityDescriptorService entityDescriptorService; + @Autowired + private DynamicRegistrationService dynamicRegistrationService; + @Secured("ROLE_ADMIN") @PostMapping @Transactional @@ -71,6 +75,7 @@ public ResponseEntity getOne(@PathVariable String resourceId) throws Persiste public ResponseEntity update(@RequestBody Group group) throws PersistentEntityNotFound, InvalidGroupRegexException { Group result = groupService.updateGroup(group); entityDescriptorService.checkApprovalStatusOfEntitiesForGroup(result); + dynamicRegistrationService.checkApprovalStatusOfEntitiesForGroup(result); return ResponseEntity.ok(result); } } \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/repository/DynamicRegistrationInfoRepository.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/repository/DynamicRegistrationInfoRepository.java index 21f95be6c..8caa871d1 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/repository/DynamicRegistrationInfoRepository.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/repository/DynamicRegistrationInfoRepository.java @@ -11,6 +11,9 @@ public interface DynamicRegistrationInfoRepository extends JpaRepository { List findAllByIdOfOwner(String idOfOwner); + @Query(value="SELECT dri.resourceId FROM DynamicRegistrationInfo dri WHERE dri.idOfOwner = :groupId AND dri.enabled = false") + List findAllResourceIdsByIdOfOwnerAndNotEnabled(@Param("groupId") String groupId); + DynamicRegistrationInfo findByResourceId(String id); @Query(value = "SELECT dri FROM DynamicRegistrationInfo dri " + diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/DynamicRegistrationService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/DynamicRegistrationService.java index 5fca6eda5..e9df64a85 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/DynamicRegistrationService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/DynamicRegistrationService.java @@ -6,6 +6,7 @@ import edu.internet2.tier.shibboleth.admin.ui.exception.ObjectIdExistsException; import edu.internet2.tier.shibboleth.admin.ui.exception.PersistentEntityNotFound; import edu.internet2.tier.shibboleth.admin.ui.exception.UnsupportedShibUiOperationException; +import edu.internet2.tier.shibboleth.admin.ui.security.model.Group; import org.springframework.http.HttpStatus; import java.util.List; @@ -14,6 +15,8 @@ public interface DynamicRegistrationService { DynamicRegistrationRepresentation approveDynamicRegistration(String resourceId, boolean status) throws PersistentEntityNotFound, ForbiddenException; + void checkApprovalStatusOfEntitiesForGroup(Group result); + DynamicRegistrationRepresentation createNew(DynamicRegistrationRepresentation dynRegRepresentation) throws ObjectIdExistsException, MissingRequiredFieldsException; diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPADynamicRegistrationServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPADynamicRegistrationServiceImpl.java index 7f47d8086..d0b7d2e47 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPADynamicRegistrationServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPADynamicRegistrationServiceImpl.java @@ -1,5 +1,6 @@ package edu.internet2.tier.shibboleth.admin.ui.service; +import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor; import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.DynamicRegistrationRepresentation; import edu.internet2.tier.shibboleth.admin.ui.domain.oidc.DynamicRegistrationInfo; import edu.internet2.tier.shibboleth.admin.ui.exception.ForbiddenException; @@ -237,4 +238,18 @@ public DynamicRegistrationRepresentation updateGroupForDynamicRegistration(Strin DynamicRegistrationInfo savedEntity = repository.save(existingDri); return new DynamicRegistrationRepresentation(savedEntity); } + + /** + * Update the approval status of entities that were in some approval state but the group approvers were added/removed. + */ + @Override + public void checkApprovalStatusOfEntitiesForGroup(Group group) { + repository.findAllResourceIdsByIdOfOwnerAndNotEnabled(group.getResourceId()).forEach(id -> { + DynamicRegistrationInfo dri = repository.findByResourceId(id); + int approvedCount = dri.approvedCount(); // total number of approvals so far + List theApprovers = groupService.find(dri.getIdOfOwner()).getApproversList(); + dri.setApproved(approvedCount >= theApprovers.size()); + dri = repository.save(dri); + }); + } } \ No newline at end of file From 988ac5d5f725bee378e152aec822573a3031692b Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 6 Dec 2022 13:06:21 -0700 Subject: [PATCH 4/4] SHIBUI-2393/2493 fixed issue when changing dynamic registration group --- .../permission/ShibUiPermissionDelegate.java | 16 +++++----------- .../GroupsControllerIntegrationTests.groovy | 5 +++++ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/permission/ShibUiPermissionDelegate.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/permission/ShibUiPermissionDelegate.java index e9a05a432..20662b366 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/permission/ShibUiPermissionDelegate.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/permission/ShibUiPermissionDelegate.java @@ -59,7 +59,11 @@ public Collection getPersistentEntities(Authentication ignored, ShibUiPermissibl case approve: return getAllDynamicRegistrationInfoObjectsNeedingApprovalBasedOnUserAccess(); case enable: - return getAllDynamicRegistrationNeedingEnabledByUserAccess(); + // This particular list is used for an admin function, so the user must be an ADMIN + if (!hasPermission(ignored, null, PermissionType.admin)) { + throw new ForbiddenException(); + } + dynamicRegistrationInfoRepository.getDynamicRegistrationsNeedingEnabling(); case fetch: return getAllDynamicRegistrationInfoObjectsBasedOnUserAccess(); } @@ -67,16 +71,6 @@ public Collection getPersistentEntities(Authentication ignored, ShibUiPermissibl return null; } - private Collection getAllDynamicRegistrationNeedingEnabledByUserAccess() throws ForbiddenException { - if (userService.currentUserIsAdmin()) { - return dynamicRegistrationInfoRepository.getDynamicRegistrationsNeedingEnabling(); - } else if (userService.currentUserCanEnable()) { - return dynamicRegistrationInfoRepository.getDynamicRegistrationsNeedingEnabling(userService.getCurrentUser().getGroupId()); - } - throw new ForbiddenException("User has no access rights to enable"); - - } - private List getAllDynamicRegistrationInfoObjectsNeedingApprovalBasedOnUserAccess() { List groupsToApprove = userService.getGroupsCurrentUserCanApprove(); return dynamicRegistrationInfoRepository.getAllNeedingApproval(groupsToApprove); diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupsControllerIntegrationTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupsControllerIntegrationTests.groovy index fcfa882c4..387236094 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupsControllerIntegrationTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/controller/GroupsControllerIntegrationTests.groovy @@ -9,6 +9,7 @@ import edu.internet2.tier.shibboleth.admin.ui.security.model.Group import edu.internet2.tier.shibboleth.admin.ui.security.model.Role import edu.internet2.tier.shibboleth.admin.ui.security.model.User import edu.internet2.tier.shibboleth.admin.ui.security.repository.GroupsRepository +import edu.internet2.tier.shibboleth.admin.ui.service.DynamicRegistrationService import edu.internet2.tier.shibboleth.admin.ui.service.JPAEntityDescriptorServiceImpl import edu.internet2.tier.shibboleth.admin.ui.util.WithMockAdmin import groovy.json.JsonOutput @@ -32,6 +33,9 @@ class GroupsControllerIntegrationTests extends AbstractBaseDataJpaTest { @Autowired GroupsRepository groupsRepository + @Autowired + private DynamicRegistrationService dynamicRegistrationService + @Autowired JPAEntityDescriptorServiceImpl service @@ -44,6 +48,7 @@ class GroupsControllerIntegrationTests extends AbstractBaseDataJpaTest { GroupController groupController = new GroupController().with ({ it.groupService = this.groupService it.entityDescriptorService = this.service + it.dynamicRegistrationService = this.dynamicRegistrationService it }) mockMvc = MockMvcBuilders.standaloneSetup(groupController).build()