Skip to content

Commit 1c8ec30

Browse files
committed
Do not provision roles without applications
Some of the applications in the `crm_config.json` do not have applications and we don't want to add an user to those roles and we also don't want to send invitations
1 parent 814acbd commit 1c8ec30

File tree

3 files changed

+84
-12
lines changed

3 files changed

+84
-12
lines changed

server/src/main/java/invite/crm/CRMController.java

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ public CRMController(@Value("${crm.collab-person-prefix}") String collabPersonPr
102102
});
103103
this.crmConfig = crmConfigRaw.entrySet().stream()
104104
.map(entry -> new CrmConfigEntry(entry.getKey(), (String) entry.getValue().get("name"),
105-
((List<Map<String, String>>) entry.getValue().get("applications")).stream()
105+
((List<Map<String, String>>) entry.getValue().getOrDefault("applications", List.of()))
106+
.stream()
106107
.map(application -> new CrmManageIdentifier(
107108
EntityType.valueOf(application.get("manageType").toUpperCase()),
108109
application.get("manageEntityID"))).toList()))
@@ -123,7 +124,7 @@ public ResponseEntity<String> contact(@RequestBody CRMContact crmContact) {
123124

124125
if (crmContact.isSuppressInvitation() &&
125126
StringUtils.hasText(crmContact.getSchacHomeOrganisation()) && StringUtils.hasText(crmContact.getUid())) {
126-
created = provisionUser(crmContact);
127+
created = provisionUser(crmContact);
127128
} else {
128129
created = sendInvitation(crmContact);
129130
}
@@ -237,10 +238,11 @@ private boolean sendInvitation(CRMContact crmContact) {
237238
List<CRMRole> newCrmRoles = syncCrmRoles(crmContact, optionalUser.orElse(new User()));
238239
//Only save the user when the user already existed
239240
optionalUser.ifPresent(user -> userRepository.save(user));
241+
// Maps CRM roles to existing or new roles
242+
List<Role> roles = convertCrmRolesToInviteRoles(crmContact, newCrmRoles);
240243
//If there are no new roles, then we can't do anything
241-
if (!CollectionUtils.isEmpty(newCrmRoles)) {
242-
// Maps CRM roles to existing or new roles
243-
List<Role> roles = convertCrmRolesToInviteRoles(crmContact, newCrmRoles);
244+
if (!CollectionUtils.isEmpty(roles)) {
245+
//There are roles in CRM without applications, we need to ignore those
244246
List<GroupedProviders> groupedProviders = manage.getGroupedProviders(roles);
245247
Set<InvitationRole> invitationRoles = roles.stream()
246248
.map(role -> new InvitationRole(role))
@@ -263,16 +265,20 @@ private boolean sendInvitation(CRMContact crmContact) {
263265
private List<Role> convertCrmRolesToInviteRoles(CRMContact crmContact, List<CRMRole> newCrmRoles) {
264266
return newCrmRoles.stream()
265267
.map(crmRole -> roleRepository.findByCrmRoleIdAndCrmOrganisationId(
266-
crmRole.getRoleId(), crmContact.getOrganisation().getOrganisationId())
267-
.orElseGet(() -> this.createRole(crmContact.getOrganisation(), crmRole)))
268+
crmRole.getRoleId(), crmContact.getOrganisation().getOrganisationId())
269+
.or(() -> this.createRole(crmContact.getOrganisation(), crmRole)))
270+
.flatMap(Optional::stream)
268271
.toList();
269272
}
270273

271-
private Role createRole(CRMOrganisation crmOrganisation, CRMRole crmRole) {
274+
private Optional<Role> createRole(CRMOrganisation crmOrganisation, CRMRole crmRole) {
272275
CrmConfigEntry crmConfigEntry = this.crmConfig.get(crmRole.getSabCode());
273276
if (crmConfigEntry == null) {
274277
throw new InvalidInputException("CRM sabCode is not configured: " + crmRole.getSabCode());
275278
}
279+
if (crmConfigEntry.crmManageIdentifiers().isEmpty()) {
280+
return Optional.empty();
281+
}
276282
Set<ApplicationUsage> applicationUsages = crmConfigEntry.crmManageIdentifiers().stream()
277283
.map(crmManageIdentifier -> manage
278284
.providerByEntityID(crmManageIdentifier.manageType(), crmManageIdentifier.manageEntityID())
@@ -302,7 +308,7 @@ private Role createRole(CRMOrganisation crmOrganisation, CRMRole crmRole) {
302308

303309
Role role = roleRepository.save(unsavedRole);
304310
this.provisioningService.newGroupRequest(role);
305-
return role;
311+
return Optional.of(role);
306312
}
307313

308314
private Invitation createInvitation(CRMContact crmContact, Set<InvitationRole> invitationRoles) {

server/src/main/resources/crm/crm_config.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,10 @@
4646
"manageType": "oidc10_rp"
4747
}
4848
]
49+
},
50+
"EMPTY": {
51+
"name": "Deprecated",
52+
"roleId": "ea61793b-c4a9-47a0-9558-40e684ded3be",
53+
"applications": []
4954
}
5055
}

server/src/test/java/invite/crm/CRMControllerTest.java

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import io.restassured.http.ContentType;
1616
import jakarta.mail.Address;
1717
import org.junit.jupiter.api.Test;
18-
import org.springframework.http.HttpStatus;
1918

2019
import java.util.List;
2120
import java.util.Optional;
@@ -198,7 +197,8 @@ void contactInviteNewUserSuppressEmail() throws Exception {
198197
List<MimeMessageParser> allMailMessages = allMailMessages(0);
199198
assertEquals(0, allMailMessages.size());
200199
}
201-
@Test
200+
201+
@Test
202202
void contactProvisioningRemoveScimRole() throws JsonProcessingException {
203203
CRMRole crmRoleResearch = new CRMRole("5e17b508-08e4-e811-8100-005056956c1a", "CONBEH", "SURFconextbeheerder");
204204
CRMRole crmRoleCloud = new CRMRole("cf652619-08e4-e811-8100-005056956c1a", "CONVER", "SURFconextverantwoordelijke");
@@ -247,6 +247,67 @@ void contactProvisioningRemoveScimRole() throws JsonProcessingException {
247247
assertEquals(3, user.getUserRoles().size());
248248
}
249249

250+
@Test
251+
void contactProvisioningRoleEmptyApplications() {
252+
CRMRole crmRoleResearch = new CRMRole("ea61793b-c4a9-47a0-9558-40e684ded3be", "EMPTY", "Deprecated");
253+
String crmContactID = UUID.randomUUID().toString();
254+
String crmOrganisationID = UUID.randomUUID().toString();
255+
CRMContact crmContact = createCrmContact(crmContactID, crmOrganisationID, crmRoleResearch, "steven", "nope.com", true);
256+
String sub = "urn:collab:person:nope.com:steven";
257+
Optional<User> userOptional = userRepository.findBySubIgnoreCase(sub);
258+
assertTrue(userOptional.isEmpty());
259+
260+
String response = given()
261+
.when()
262+
.accept(ContentType.JSON)
263+
.header(API_KEY_HEADER, "secret")
264+
.contentType(ContentType.JSON)
265+
.body(crmContact)
266+
.post("/api/internal/v1/crm")
267+
.then()
268+
.extract()
269+
.asString();
270+
assertEquals("created", response);
271+
272+
userOptional = userRepository.findBySubIgnoreCase(sub);
273+
assertTrue(userOptional.isPresent());
274+
assertEquals(0, userOptional.get().getUserRoles().size());
275+
}
276+
277+
@Test
278+
void contactInviteNoInvitationWithNoRoles() throws Exception {
279+
CRMRole crmRoleResearch = new CRMRole("ea61793b-c4a9-47a0-9558-40e684ded3be", "EMPTY", "Deprecated");
280+
String crmContactID = UUID.randomUUID().toString();
281+
String crmOrganisationID = UUID.randomUUID().toString();
282+
CRMContact crmContact = createCrmContact(crmContactID, crmOrganisationID, crmRoleResearch, null, null, false);
283+
String sub = "urn:collab:person:nope.com:steven";
284+
Optional<User> userOptional = userRepository.findBySubIgnoreCase(sub);
285+
assertTrue(userOptional.isEmpty());
286+
287+
String response = given()
288+
.when()
289+
.accept(ContentType.JSON)
290+
.header(API_KEY_HEADER, "secret")
291+
.contentType(ContentType.JSON)
292+
.body(crmContact)
293+
.post("/api/internal/v1/crm")
294+
.then()
295+
.extract()
296+
.asString();
297+
assertEquals("created", response);
298+
299+
Optional<User> optionalUser = userRepository.findByCrmContactIdAndCrmOrganisationId(crmContactID,
300+
crmOrganisationID);
301+
assertTrue(optionalUser.isEmpty());
302+
303+
List<Invitation> invitations = invitationRepository.findByCrmContactIdAndCrmOrganisationId(
304+
crmContactID, crmOrganisationID);
305+
assertEquals(0, invitations.size());
306+
307+
List<MimeMessageParser> allMailMessages = allMailMessages(0);
308+
assertEquals(0, allMailMessages.size());
309+
}
310+
250311
@Test
251312
void deleteUser() throws JsonProcessingException {
252313
CRMContact crmContact = new CRMContact();
@@ -313,7 +374,7 @@ void scopeInviteRoleToUniqueCRMRoleIdAndOrganizationId() throws JsonProcessingEx
313374
assertEquals(1, user.getUserRoles().size());
314375
//Now post the same CRMContact for a different user, but the same role. Enusure the role is not re-used
315376
String newOrganisationID = UUID.randomUUID().toString();
316-
crmContact.setOrganisation(new CRMOrganisation(newOrganisationID,"abbrev","name"));
377+
crmContact.setOrganisation(new CRMOrganisation(newOrganisationID, "abbrev", "name"));
317378
crmContact.setUid("second_user");
318379
response = given()
319380
.when()

0 commit comments

Comments
 (0)