Skip to content

Commit 473ca9a

Browse files
committed
Fixes #638
1 parent 9cbdfd6 commit 473ca9a

File tree

5 files changed

+88
-35
lines changed

5 files changed

+88
-35
lines changed

CHANGELOG.md

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1-
21
# Change Log
32

43
All notable changes to this project will be documented in this file.
54

65
The format is based on [Keep a Changelog](http://keepachangelog.com/)
76
and this project adheres to [Semantic Versioning](http://semver.org/).
87

9-
## Next (1.0.0)
8+
## Next (1.0.3)
9+
10+
- Fix: remove trailing slash in `scim_url`
11+
12+
## 1.0.2
13+
14+
- Fix: ensure that when a user is provisioned with eduID as the identifier, invite first calls the eduID
15+
provisioning service to obtain an institutional eduID, and then uses that eduID instead of the user’s original eduID
1016

1117
## 1.0.1
1218

@@ -157,10 +163,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
157163
- Add API endpoints for Openconext-spdashboard integration
158164
- Add API endpoints for Openconext-myconext integration
159165
- Fixes https://github.com/OpenConext/OpenConext-Invite/issues/307,
160-
https://github.com/OpenConext/OpenConext-Invite/issues/312,
161-
https://github.com/OpenConext/OpenConext-Invite/issues/320,
162-
https://github.com/OpenConext/OpenConext-Invite/issues/240,
163-
https://github.com/OpenConext/OpenConext-Invite/issues/310
166+
https://github.com/OpenConext/OpenConext-Invite/issues/312,
167+
https://github.com/OpenConext/OpenConext-Invite/issues/320,
168+
https://github.com/OpenConext/OpenConext-Invite/issues/240,
169+
https://github.com/OpenConext/OpenConext-Invite/issues/310
164170

165171
## 0.0.20 2024-09-13
166172

@@ -178,29 +184,29 @@ https://github.com/OpenConext/OpenConext-Invite/issues/310
178184
- Allow searching for specific role types in users
179185
- Show correct landingpage for roles in UI and API
180186
- Fixes issues https://github.com/OpenConext/OpenConext-Invite/issues/231,
181-
https://github.com/OpenConext/OpenConext-Invite/issues/302,
182-
https://github.com/OpenConext/OpenConext-Invite/issues/240,
183-
https://github.com/OpenConext/OpenConext-Invite/issues/298,
184-
https://github.com/OpenConext/OpenConext-Invite/issues/296,
185-
https://github.com/OpenConext/OpenConext-Invite/issues/295,
186-
https://github.com/OpenConext/OpenConext-Invite/issues/297,
187-
https://github.com/OpenConext/OpenConext-Invite/issues/239,
188-
https://github.com/OpenConext/OpenConext-Invite/issues/239,
189-
https://github.com/OpenConext/OpenConext-Invite/issues/241,
190-
https://github.com/OpenConext/OpenConext-Invite/issues/241,
191-
https://github.com/OpenConext/OpenConext-Invite/issues/293,
192-
https://github.com/OpenConext/OpenConext-Invite/issues/235,
193-
https://github.com/OpenConext/OpenConext-Invite/issues/235,
194-
https://github.com/OpenConext/OpenConext-Invite/issues/234,
195-
https://github.com/OpenConext/OpenConext-Invite/issues/232,
196-
https://github.com/OpenConext/OpenConext-Invite/issues/232,
197-
https://github.com/OpenConext/OpenConext-Invite/issues/233,
198-
https://github.com/OpenConext/OpenConext-Invite/issues/233,
199-
https://github.com/OpenConext/OpenConext-Invite/issues/231,
200-
https://github.com/OpenConext/OpenConext-Invite/issues/230,
201-
https://github.com/OpenConext/OpenConext-Invite/issues/227,
202-
https://github.com/OpenConext/OpenConext-Invite/issues/228,
203-
https://github.com/OpenConext/OpenConext-Invite/issues/291
187+
https://github.com/OpenConext/OpenConext-Invite/issues/302,
188+
https://github.com/OpenConext/OpenConext-Invite/issues/240,
189+
https://github.com/OpenConext/OpenConext-Invite/issues/298,
190+
https://github.com/OpenConext/OpenConext-Invite/issues/296,
191+
https://github.com/OpenConext/OpenConext-Invite/issues/295,
192+
https://github.com/OpenConext/OpenConext-Invite/issues/297,
193+
https://github.com/OpenConext/OpenConext-Invite/issues/239,
194+
https://github.com/OpenConext/OpenConext-Invite/issues/239,
195+
https://github.com/OpenConext/OpenConext-Invite/issues/241,
196+
https://github.com/OpenConext/OpenConext-Invite/issues/241,
197+
https://github.com/OpenConext/OpenConext-Invite/issues/293,
198+
https://github.com/OpenConext/OpenConext-Invite/issues/235,
199+
https://github.com/OpenConext/OpenConext-Invite/issues/235,
200+
https://github.com/OpenConext/OpenConext-Invite/issues/234,
201+
https://github.com/OpenConext/OpenConext-Invite/issues/232,
202+
https://github.com/OpenConext/OpenConext-Invite/issues/232,
203+
https://github.com/OpenConext/OpenConext-Invite/issues/233,
204+
https://github.com/OpenConext/OpenConext-Invite/issues/233,
205+
https://github.com/OpenConext/OpenConext-Invite/issues/231,
206+
https://github.com/OpenConext/OpenConext-Invite/issues/230,
207+
https://github.com/OpenConext/OpenConext-Invite/issues/227,
208+
https://github.com/OpenConext/OpenConext-Invite/issues/228,
209+
https://github.com/OpenConext/OpenConext-Invite/issues/291
204210

205211
## 0.0.19 2024-09-10
206212

@@ -254,7 +260,8 @@ https://github.com/OpenConext/OpenConext-Invite/issues/291
254260
- Fix styling of welcome deadend on medium screens
255261
- Make clear on welcome/profile which are your actual guest roles and for which you have a different authority
256262
- Fix wrong explanation with override invite settings option
257-
- Voot and invite-AA endpoints will only return roles the user is actually a guest in, not a different authority, just like provisioning already works
263+
- Voot and invite-AA endpoints will only return roles the user is actually a guest in, not a different authority, just
264+
like provisioning already works
258265
- Unbreak 'also invite as guest' when a user upgrades their own role
259266
- Support updating changed attributes in SCIM
260267
- Provisionings now show created date

server/src/main/java/invite/manage/Manage.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,15 @@
33
import invite.model.GroupedProviders;
44
import invite.model.Role;
55
import org.springframework.util.CollectionUtils;
6-
7-
import java.util.*;
6+
import org.springframework.util.StringUtils;
7+
8+
import java.util.ArrayList;
9+
import java.util.Collection;
10+
import java.util.HashMap;
11+
import java.util.List;
12+
import java.util.Map;
13+
import java.util.Optional;
14+
import java.util.UUID;
815
import java.util.stream.Collectors;
916

1017
import static invite.security.InstitutionAdmin.*;
@@ -82,6 +89,10 @@ default Map<String, Object> transformProvider(Map<String, Object> provider) {
8289
"user_wait_time"
8390
).forEach(attribute -> application.put(attribute, metaDataFields.get(attribute)));
8491
}
92+
String scimUrl = (String) application.get("scim_url");
93+
if (StringUtils.hasText(scimUrl) && scimUrl.endsWith("/")) {
94+
application.put("scim_url", scimUrl.substring(0, scimUrl.length() - 1));
95+
}
8596
application.put("type", provider.get("type"));
8697
application.put("applications", data.get("applications"));
8798
application.put("allowedEntities", data.get("allowedEntities"));

server/src/main/java/invite/provision/Provisioning.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class Provisioning {
1717
private final String id;
1818
private final String entityId;
1919
private final ProvisioningType provisioningType;
20-
private final String scimUrl;
20+
private String scimUrl;
2121
private final String scimUser;
2222
private final String scimPassword;
2323
private final String scimBearerToken;
@@ -41,6 +41,9 @@ public Provisioning(Map<String, Object> provider) {
4141

4242
this.provisioningType = ProvisioningType.valueOf((String) provider.get("provisioning_type"));
4343
this.scimUrl = (String) provider.get("scim_url");
44+
if (StringUtils.hasText(this.scimUrl) && this.scimUrl.endsWith("/")) {
45+
this.scimUrl = this.scimUrl.substring(0, this.scimUrl.length() - 1);
46+
}
4447
this.scimUser = (String) provider.get("scim_user");
4548
this.scimPassword = (String) provider.get("scim_password");
4649
this.scimBearerToken = (String) provider.get("scim_bearer_token");
@@ -73,8 +76,8 @@ private void invariant() {
7376
case scim -> {
7477
assert scimUrl != null : "scimUrl is null";
7578
if (scimBearerToken == null) {
76-
assert scimUser != null: "scimUser is null";
77-
assert scimPassword != null: "scimPassword or scimBearerToken is null";
79+
assert scimUser != null : "scimUser is null";
80+
assert scimPassword != null : "scimPassword or scimBearerToken is null";
7881
}
7982
}
8083
case graph -> {

server/src/test/java/invite/manage/LocalManageTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
import invite.AbstractTest;
44
import invite.model.Role;
5+
import invite.provision.ProvisioningType;
56
import org.junit.jupiter.api.Test;
67

78
import java.util.List;
9+
import java.util.Map;
810

911
import static org.junit.jupiter.api.Assertions.assertEquals;
1012
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -18,4 +20,22 @@ void deriveRemoteApplications() {
1820
localManage.addManageMetaData(roles);
1921
roles.forEach(role -> role.getApplicationMaps().forEach(map -> assertNotNull(map.get("id"))));
2022
}
23+
24+
@Test
25+
void provisioningScimTrailingSlash() {
26+
Map<String, Object> provider = Map.of(
27+
"type", EntityType.PROVISIONING.collectionName(),
28+
"_id", "12345678",
29+
"data", Map.of("metaDataFields", Map.of(
30+
"provisioning_type", ProvisioningType.scim.name(),
31+
"scim_url", "https://scum.url/",
32+
"scim_user", "user",
33+
"scim_password", "secret"
34+
))
35+
);
36+
Map<String, Object> application = localManage.transformProvider(provider);
37+
38+
assertEquals("12345678", application.get("id"));
39+
assertEquals("https://scum.url", application.get("scim_url"));
40+
}
2141
}

server/src/test/java/invite/provision/ProvisioningTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,18 @@ void provisioningGraph() {
3535
this.provisioningMap(ProvisioningType.graph, "graph_client_id", "graph_secret");
3636
}
3737

38+
@Test
39+
void provisioningScimTrailingSlash() {
40+
Map<String, Object> data = Map.of(
41+
"provisioning_type", ProvisioningType.scim.name(),
42+
"scim_url", "https://scum.url/",
43+
"scim_user","user",
44+
"scim_password", "secret"
45+
);
46+
Provisioning provisioning = new Provisioning(data);
47+
assertEquals("https://scum.url", provisioning.getScimUrl());
48+
}
49+
3850
private void assertInvariant(Map<String, Object> provider) {
3951
assertThrows(AssertionError.class, () -> new Provisioning(provider));
4052
}

0 commit comments

Comments
 (0)