Skip to content

Commit ee82635

Browse files
authored
Merge pull request #4064 from sarkapalkovicova/approve_applications_bulk
feat(core): approve applications method
2 parents f75eff1 + 6fdaf33 commit ee82635

File tree

5 files changed

+78
-11
lines changed

5 files changed

+78
-11
lines changed

perun-openapi/openapi.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16354,6 +16354,22 @@ paths:
1635416354
default:
1635516355
$ref: '#/components/responses/ExceptionResponse'
1635616356

16357+
/urlinjsonout/registrarManager/approveApplications:
16358+
post:
16359+
tags:
16360+
- RegistrarManager
16361+
operationId: approveApplications
16362+
summary: Manually approves multiple applications at once.
16363+
description: |
16364+
Expected to be called as a result of direct VO administrator action in the web UI.
16365+
parameters:
16366+
- $ref: '#/components/parameters/ids'
16367+
responses:
16368+
'200':
16369+
$ref: '#/components/responses/VoidResponse'
16370+
default:
16371+
$ref: '#/components/responses/ExceptionResponse'
16372+
1635716373
/urlinjsonout/registrarManager/rejectApplication:
1635816374
post:
1635916375
tags:

perun-registrar-lib/src/main/java/cz/metacentrum/perun/registrar/RegistrarManager.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,15 @@ public interface RegistrarManager {
370370
*/
371371
Application approveApplication(PerunSession session, int appId) throws PerunException;
372372

373+
/**
374+
* Manually approves multiple applications at once. Expected to be called as a result of direct VO administrator action in the web UI.
375+
*
376+
* @param sess perun session
377+
* @param applicationIds list of application IDs
378+
* @throws PerunException
379+
*/
380+
void approveApplications(PerunSession sess, List<Integer> applicationIds) throws PerunException;
381+
373382
/**
374383
* Approves an application in one transaction.
375384
*

perun-registrar-lib/src/main/java/cz/metacentrum/perun/registrar/impl/RegistrarManagerImpl.java

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1753,7 +1753,7 @@ private void deleteApplicationReservedLogins(PerunSession sess, Application app)
17531753
public Application approveApplication(PerunSession sess, int appId) throws PerunException {
17541754
synchronized(runningApproveApplication) {
17551755
if (runningApproveApplication.contains(appId)) {
1756-
throw new AlreadyProcessingException("Application approval is already processing.");
1756+
throw new AlreadyProcessingException("Application " + appId + " approval is already processing.");
17571757
} else {
17581758
runningApproveApplication.add(appId);
17591759
}
@@ -1764,13 +1764,13 @@ public Application approveApplication(PerunSession sess, int appId) throws Perun
17641764
app = registrarManager.approveApplicationInternal(sess, appId);
17651765
} catch (AlreadyMemberException ex) {
17661766
// case when user joined identity after sending initial application and former user was already member of VO
1767-
throw new RegistrarException("User is already member (with ID: "+ex.getMember().getId()+") of your VO/group. (user joined his identities after sending new application). You can reject this application and re-validate old member to keep old data (e.g. login,email).", ex);
1767+
throw new RegistrarException("User is already member (with ID: "+ex.getMember().getId()+") of your VO/group. (user joined his identities after sending new application). You can reject this application " + appId + " and re-validate old member to keep old data (e.g. login,email).", ex);
17681768
} catch (MemberNotExistsException ex) {
1769-
throw new RegistrarException("To approve application user must already be member of VO.", ex);
1769+
throw new RegistrarException("To approve application " + appId + " user must already be member of VO.", ex);
17701770
} catch (NotGroupMemberException ex) {
1771-
throw new RegistrarException("To approve application user must already be member of Group.", ex);
1771+
throw new RegistrarException("To approve application " + appId + " user must already be member of Group.", ex);
17721772
} catch (UserNotExistsException | UserExtSourceNotExistsException | ExtSourceNotExistsException ex) {
1773-
throw new RegistrarException("User specified by the data in application was not found. If you tried to approve application for the Group, try to check, if user already has approved application in the VO. Application to the VO must be approved first.", ex);
1773+
throw new RegistrarException("User specified by the data in application " + appId + " was not found. If you tried to approve application for the Group, try to check, if user already has approved application in the VO. Application to the VO must be approved first.", ex);
17741774
} finally {
17751775
synchronized (runningApproveApplication) {
17761776
runningApproveApplication.remove(appId);
@@ -1821,6 +1821,13 @@ public Application approveApplication(PerunSession sess, int appId) throws Perun
18211821
return app;
18221822
}
18231823

1824+
@Override
1825+
public void approveApplications(PerunSession sess, List<Integer> applicationIds) throws PerunException {
1826+
for (Integer id : applicationIds) {
1827+
approveApplication(sess, id);
1828+
}
1829+
}
1830+
18241831
/**
18251832
* Returns list of all groups embedded to target vo/group of application
18261833
* @param sess
@@ -1941,7 +1948,7 @@ private void submitEmbeddedGroupApplications(PerunSession sess, List<Group> grou
19411948
public Application approveApplicationInternal(PerunSession sess, int appId) throws PerunException {
19421949

19431950
Application app = getApplicationById(appId);
1944-
if (app == null) throw new RegistrarException("Application with ID "+appId+" doesn't exists.");
1951+
if (app == null) throw new RegistrarException("Application with ID " + appId + " doesn't exists.");
19451952
Member member;
19461953

19471954
//Authorization
@@ -1957,9 +1964,9 @@ public Application approveApplicationInternal(PerunSession sess, int appId) thro
19571964

19581965
// only VERIFIED applications can be approved
19591966
if (!AppState.VERIFIED.equals(app.getState())) {
1960-
if (AppState.APPROVED.equals(app.getState())) throw new RegistrarException("Application is already approved. Try to refresh the view to see changes.");
1961-
if (AppState.REJECTED.equals(app.getState())) throw new RegistrarException("Rejected application cant' be approved. Try to refresh the view to see changes.");
1962-
throw new RegistrarException("User didn't verify his email address yet. Please wait until application will be in a 'Submitted' state. You can send mail verification notification to user again if you wish.");
1967+
if (AppState.APPROVED.equals(app.getState())) throw new RegistrarException("Application " + appId + " is already approved. Try to refresh the view to see changes.");
1968+
if (AppState.REJECTED.equals(app.getState())) throw new RegistrarException("Rejected application " + appId + " cant' be approved. Try to refresh the view to see changes.");
1969+
throw new RegistrarException("User didn't verify his email address yet. Please wait until application " + appId + " will be in a 'Submitted' state. You can send mail verification notification to user again if you wish.");
19631970
}
19641971

19651972
LinkedHashMap<String, String> additionalAttributes = BeansUtils.stringToMapOfAttributes(app.getFedInfo());
@@ -2028,7 +2035,7 @@ public Application approveApplicationInternal(PerunSession sess, int appId) thro
20282035
// and we don't want to validate expired, suspended or disabled users without VO admin owns action !!
20292036
// meaning, user should submit membership extension application first !!
20302037
if (!Arrays.asList(Status.VALID, Status.INVALID).contains(member.getStatus())) {
2031-
throw new CantBeApprovedException("Application of member with membership status: "+member.getStatus()+" can't be approved. Please wait until member extends/re-validate own membership in a VO.");
2038+
throw new CantBeApprovedException("Application " + appId + " of member with membership status: "+member.getStatus()+" can't be approved. Please wait until member extends/re-validate own membership in a VO.");
20322039
}
20332040

20342041
// store all attributes (but not logins)
@@ -2164,7 +2171,7 @@ public Application approveApplicationInternal(PerunSession sess, int appId) thro
21642171
// and we don't want to validate expired, suspended or disabled users without VO admin owns action !!
21652172
// meaning, user should submit membership extension application first !!
21662173
if (!Arrays.asList(Status.VALID, Status.INVALID).contains(member.getStatus())) {
2167-
throw new CantBeApprovedException("Application of member with membership status: "+member.getStatus()+" can't be approved. Please wait until member extends/re-validate own membership in a VO.");
2174+
throw new CantBeApprovedException("Application " + appId + " of member with membership status: "+member.getStatus()+" can't be approved. Please wait until member extends/re-validate own membership in a VO.");
21682175
}
21692176

21702177
// overwrite member with group context

perun-registrar-lib/src/test/java/cz/metacentrum/perun/registrar/RegistrarBaseIntegrationTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,24 @@ public void testEmbeddedGroupsSubmission() throws PerunException {
11201120
assertEquals(1, registrarManager.getApplicationsForGroup(session, group2, List.of("NEW", "VERIFIED")).size());
11211121
}
11221122

1123+
@Test
1124+
public void testApproveApplications() throws PerunException {
1125+
User user1 = new User(-1, "User1", "Test1", "", "", "");
1126+
User user2 = new User(-2, "User2", "Test2", "", "", "");
1127+
user1 = perun.getUsersManagerBl().createUser(session, user1);
1128+
user2 = perun.getUsersManagerBl().createUser(session, user2);
1129+
1130+
Application application1 = prepareApplicationToVo(user1);
1131+
Application application2 = prepareApplicationToVo(user2);
1132+
registrarManager.submitApplication(session, application1, new ArrayList<>());
1133+
registrarManager.submitApplication(session, application2, new ArrayList<>());
1134+
1135+
registrarManager.approveApplications(session, List.of(application1.getId(), application2.getId()));
1136+
1137+
List<Integer> approvedAppIds = registrarManager.getApplicationsForVo(session, vo, List.of("APPROVED"), false).stream().map(Application::getId).toList();
1138+
assertEquals(2, approvedAppIds.size());
1139+
assertThat(approvedAppIds).containsOnly(application1.getId(), application2.getId());
1140+
}
11231141

11241142
@Test
11251143
public void testEmbeddedGroupsSubmission_groupAutoApprove() throws PerunException {

perun-rpc/src/main/java/cz/metacentrum/perun/rpc/methods/RegistrarManagerMethod.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,23 @@ public Application call(ApiCaller ac, Deserializer parms) throws PerunException
859859

860860
},
861861

862+
/*#
863+
* Manually approve multiple applications at once.
864+
* Expected to be called as a result of direct VO administrator action in the web UI.
865+
*
866+
* @param ids int[] List of Application IDs
867+
*/
868+
approveApplications {
869+
870+
@Override
871+
public Void call(ApiCaller ac, Deserializer parms) throws PerunException {
872+
parms.stateChangingCheck();
873+
ac.getRegistrarManager().approveApplications(ac.getSession(), parms.readList("ids", Integer.class));
874+
return null;
875+
}
876+
877+
},
878+
862879
/*#
863880
* Check if application can be approved based on form module rules. Throws exception if not.
864881
* Expected to be called from Web UI before actual approving happens, so VO admin

0 commit comments

Comments
 (0)