Skip to content

Commit 12099b6

Browse files
committed
Merge branch 'feature/shedlock-locking' of github.com:OpenConext/OpenConext-Invite into feature/shedlock-locking
2 parents ac4eea6 + e14215f commit 12099b6

18 files changed

+87
-88
lines changed

.github/badges/branches.svg

Lines changed: 1 addition & 1 deletion
Loading

.github/badges/jacoco.svg

Lines changed: 1 addition & 1 deletion
Loading

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

8+
## 1.1.1
9+
10+
- Fix: eduID only invitations for managers and inviters
11+
- Feature: Display audit train for Institution Admins
12+
- Feature: Clean up expired invitations
13+
- Fix: Locking for cron jobs on multi-master databases
14+
815
## 1.1.0
916

1017
- Feature: Add CRM interface to directly create application-roles and invite users, triggers from an external CRM system
@@ -34,6 +41,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3441
- Improvement: cronjob database locks to work in clusterd enviroment
3542
- Fix: SCIM delete messageses were not always sent
3643
- Fix: Accepting invite in the same browser session that sent the invite
44+
- Change: SCIM Patch opeartions now follow rfc7644 and use `add`, `remove`, or `replace` (instead of `Add` and `Remove`)
3745

3846
## 1.0.2
3947

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,8 @@ cd client
209209
nvm use
210210
yarn outdated
211211
```
212+
213+
## CRM
214+
215+
CRM api calls have been added to enable migration from a legacy application called SAB (SURF Autorisatie Beheer).
216+
These api calls are actively used to integrate with the enterprise role administration system.

client/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"nth-check": "^2.1.1",
4646
"react-json-view-lite": "^2.4.2",
4747
"sass": "^1.90.0",
48-
"vite": "^7.2.2",
48+
"vite": "^7.3.2",
4949
"vite-plugin-svgr": "^4.5.0",
5050
"vitest": "^4.0.8"
5151
},

client/yarn.lock

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2660,9 +2660,9 @@ lodash.debounce@^4.0.8:
26602660
integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
26612661

26622662
lodash@*:
2663-
version "4.17.23"
2664-
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.23.tgz#f113b0378386103be4f6893388c73d0bde7f2c5a"
2665-
integrity sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==
2663+
version "4.18.1"
2664+
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.18.1.tgz#ff2b66c1f6326d59513de2407bf881439812771c"
2665+
integrity sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==
26662666

26672667
loose-envify@^1.4.0:
26682668
version "1.4.0"
@@ -3642,10 +3642,10 @@ vite-plugin-svgr@^4.5.0:
36423642
"@svgr/core" "^8.1.0"
36433643
"@svgr/plugin-jsx" "^8.1.0"
36443644

3645-
"vite@^6.0.0 || ^7.0.0", vite@^7.2.2:
3646-
version "7.3.1"
3647-
resolved "https://registry.yarnpkg.com/vite/-/vite-7.3.1.tgz#7f6cfe8fb9074138605e822a75d9d30b814d6507"
3648-
integrity sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==
3645+
"vite@^6.0.0 || ^7.0.0", vite@^7.3.2:
3646+
version "7.3.2"
3647+
resolved "https://registry.yarnpkg.com/vite/-/vite-7.3.2.tgz#cb041794d4c1395e28baea98198fd6e8f4b96b5c"
3648+
integrity sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==
36493649
dependencies:
36503650
esbuild "^0.27.0"
36513651
fdir "^6.5.0"
@@ -3797,9 +3797,9 @@ yallist@^3.0.2:
37973797
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
37983798

37993799
yaml@^1.10.0:
3800-
version "1.10.2"
3801-
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
3802-
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
3800+
version "1.10.3"
3801+
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.3.tgz#76e407ed95c42684fb8e14641e5de62fe65bbcb3"
3802+
integrity sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==
38033803

38043804
yocto-queue@^0.1.0:
38053805
version "0.1.0"

docs/SCIM/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ Content-Type: application/json
326326
"schemas" : [ "urn:ietf:params:scim:api:messages:2.0:PatchOp" ],
327327
"id" : "{GroupID at SP}",
328328
"Operations" : [ {
329-
"op" : "Add",
329+
"op" : "add",
330330
"path" : "members",
331331
"value" : [ {
332332
"value" : "{UserID at SP}"
@@ -346,7 +346,7 @@ Content-Type: application/json
346346
"schemas" : [ "urn:ietf:params:scim:api:messages:2.0:PatchOp" ],
347347
"id" : "{GroupID at SP}",
348348
"Operations" : [ {
349-
"op" : "Remove",
349+
"op" : "remove",
350350
"path" : "members",
351351
"value" : [ {
352352
"value" : "{UserID at SP}"

server/src/main/java/invite/api/APITokenController.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@
1818
import org.springframework.transaction.annotation.Transactional;
1919
import org.springframework.util.StringUtils;
2020
import org.springframework.validation.annotation.Validated;
21-
import org.springframework.web.bind.annotation.*;
21+
import org.springframework.web.bind.annotation.DeleteMapping;
22+
import org.springframework.web.bind.annotation.GetMapping;
23+
import org.springframework.web.bind.annotation.PathVariable;
24+
import org.springframework.web.bind.annotation.PostMapping;
25+
import org.springframework.web.bind.annotation.RequestBody;
26+
import org.springframework.web.bind.annotation.RequestMapping;
27+
import org.springframework.web.bind.annotation.RestController;
2228

2329
import java.util.List;
2430
import java.util.Map;
@@ -73,10 +79,10 @@ public ResponseEntity<APIToken> create(@Validated @RequestBody APIToken apiToken
7379
UserPermissions.assertAuthority(user, Authority.INVITER);
7480
String token = (String) request.getSession().getAttribute(TOKEN_KEY);
7581
if (!StringUtils.hasText(token)) {
76-
throw new UserRestrictionException();
82+
throw new UserRestrictionException("Token is NULL");
7783
}
7884
if (user.isSuperUser() && !StringUtils.hasText(apiTokenRequest.getOrganizationGUID())) {
79-
throw new UserRestrictionException();
85+
throw new UserRestrictionException("Super user must specify API token OrganizationGUID");
8086
}
8187
APIToken apiToken;
8288
if (user.isSuperUser() || user.isInstitutionAdmin()) {
@@ -96,16 +102,17 @@ public ResponseEntity<APIToken> create(@Validated @RequestBody APIToken apiToken
96102
@DeleteMapping("/{id}")
97103
public ResponseEntity<Void> deleteToken(@PathVariable("id") Long id, @Parameter(hidden = true) User user) {
98104
LOG.debug(String.format("DELETE /tokens/deleteToken with id %s for user %s", id.toString(), user.getEduPersonPrincipalName()));
105+
99106
UserPermissions.assertAuthority(user, Authority.INVITER);
100107
APIToken apiToken = apiTokenRepository.findById(id).orElseThrow(() -> new NotFoundException("API token not found"));
101108
if (apiToken.isSuperUserToken() && !user.isSuperUser()) {
102-
throw new UserRestrictionException();
109+
throw new UserRestrictionException("Non super-user not allowed to delete super-user token: " + user.getEmail());
103110
}
104111
if (user.isInstitutionAdmin() && !apiToken.getOrganizationGUID().equals(user.getOrganizationGUID())) {
105-
throw new UserRestrictionException();
112+
throw new UserRestrictionException("User not allowed to delete token for different organization: " + user.getEmail());
106113
}
107114
if (!user.isSuperUser() && !user.isInstitutionAdmin() && !Objects.equals(user.getId(), apiToken.getOwner().getId())) {
108-
throw new UserRestrictionException();
115+
throw new UserRestrictionException("User not allowed to delete token for different owner: " + user.getEmail());
109116
}
110117
apiTokenRepository.delete(apiToken);
111118
return Results.deleteResult();

server/src/main/java/invite/api/InvitationController.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ public InvitationController(MailBox mailBox,
160160
"message": "Personal message included in the email",
161161
"language": "en",
162162
"guestRoleIncluded": true,
163+
"suppressSendingEmails": false,
163164
"invites": [
164165
"admin@service.org"
165166
],

server/src/main/java/invite/api/RoleController.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ public ResponseEntity<List<Role>> rolesPerApplicationId(@PathVariable("manageId"
179179
.collect(Collectors.toSet());
180180
applicationManageIdentifiers.addAll(roleManageIdentifiers);
181181
if (!applicationManageIdentifiers.contains(manageId)) {
182-
throw new UserRestrictionException();
182+
throw new UserRestrictionException(String.format("User %s has no access to manageID %s", user.getEmail(), manageId));
183183
}
184184
roles = roleRepository.findByOrganizationGUIDAndApplicationUsagesApplicationManageId(user.getOrganizationGUID(), manageId);
185185
}
@@ -194,7 +194,7 @@ public ResponseEntity<Role> newRole(@Validated @RequestBody RoleRequest roleRequ
194194
UserPermissions.assertAuthority(user, Authority.INSTITUTION_ADMIN);
195195
//For super_users we require an organization GUID from the input form
196196
if (user.isSuperUser() && !StringUtils.hasText(roleRequest.getOrganizationGUID())) {
197-
throw new UserRestrictionException();
197+
throw new UserRestrictionException("Super users must specify an organizationGUID");
198198
}
199199
Role role = new Role(roleRequest);
200200
role.setOrganizationGUID(user.isSuperUser() ? roleRequest.getOrganizationGUID() : user.getOrganizationGUID());
@@ -244,7 +244,8 @@ public ResponseEntity<Void> deleteRole(@PathVariable("id") Long id,
244244

245245
if (!user.isSuperUser() &&
246246
!Objects.equals(user.getOrganizationGUID(), role.getOrganizationGUID())) {
247-
throw new UserRestrictionException();
247+
throw new UserRestrictionException(String.format("Non super user %s not allowd to delete role %s",
248+
user.getEmail(), role.getName()));
248249
}
249250

250251
provisioningService.deleteGroupRequest(role);

0 commit comments

Comments
 (0)