Skip to content

Commit 7aa42b7

Browse files
committed
WIP for #538
1 parent 6547502 commit 7aa42b7

19 files changed

+154
-28
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ public ResponseEntity<InvitationResponse> newInvitation(@Validated @RequestBody
109109
return this.invitationOperations.sendInvitation(invitationRequest, user, null);
110110
}
111111

112-
113112
@DeleteMapping("/{id}")
114113
public ResponseEntity<Void> deleteInvitation(@PathVariable("id") Long id,
115114
@Parameter(hidden = true) User user) {
@@ -252,6 +251,7 @@ public ResponseEntity<Map<String, Object>> accept(@Validated @RequestBody Accept
252251
saveOAuth2AuthenticationToken(authentication, user, servletRequest, servletResponse);
253252
}
254253
}
254+
user.setInternalPlaceholderIdentifier(invitation.getInternalPlaceholderIdentifier());
255255
userRepository.save(user);
256256
AccessLogger.user(LOG, Event.Created, user);
257257
newUserRoles.forEach(userRole -> userRoleAuditService.logAction(userRole, UserRoleAudit.ActionType.ADD));

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

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public InvitationOperations(InvitationResource invitationResource) {
4040
public ResponseEntity<InvitationResponse> sendInvitation(InvitationRequest invitationRequest,
4141
User user,
4242
RemoteUser remoteUser) {
43+
invitationRequest.verify();
4344
Authority intendedAuthority = invitationRequest.getIntendedAuthority();
4445
if (!List.of(Authority.INSTITUTION_ADMIN, Authority.SUPER_USER).contains(intendedAuthority)
4546
&& CollectionUtils.isEmpty(invitationRequest.getRoleIdentifiers())) {
@@ -65,19 +66,26 @@ public ResponseEntity<InvitationResponse> sendInvitation(InvitationRequest invit
6566
invitationRequest.setRoleExpiryDate(Instant.now().plus(defaultExpiryDays, ChronoUnit.DAYS));
6667
}
6768
}
68-
69-
List<Invitation> invitations = invitationRequest.getInvites().stream()
70-
.filter(email -> {
71-
boolean valid = emailFormatValidator.isValid(email);
69+
List<Invite> invites = invitationRequest.getInvitations();
70+
if (invites == null) {
71+
invites = new ArrayList<>();
72+
}
73+
List<String> requestInvites = invitationRequest.getInvites();
74+
if (requestInvites != null) {
75+
invites.addAll(requestInvites.stream().map(invite -> new Invite(invite, null)).toList());
76+
}
77+
List<Invitation> invitations = invites.stream()
78+
.filter(invite -> {
79+
boolean valid = emailFormatValidator.isValid(invite.getEmail());
7280
if (!valid) {
73-
LOG.debug("Not sending invalid email for invitation: " + email);
81+
LOG.debug("Not sending invalid email for invitation: " + invite.getEmail());
7482
}
7583
return valid;
7684
})
77-
.map(invitee -> new Invitation(
85+
.map(invite -> new Invitation(
7886
intendedAuthority,
7987
HashGenerator.generateRandomHash(),
80-
invitee,
88+
invite.getEmail(),
8189
invitationRequest.isEnforceEmailEquality(),
8290
invitationRequest.isEduIDOnly(),
8391
invitationRequest.isGuestRoleIncluded(),
@@ -88,8 +96,9 @@ public ResponseEntity<InvitationResponse> sendInvitation(InvitationRequest invit
8896
invitationRequest.getRoleExpiryDate(),
8997
requestedRoles.stream()
9098
.map(InvitationRole::new)
91-
.collect(toSet())))
92-
.toList();
99+
.collect(toSet()),
100+
invite.getInternalPlaceholderIdentifier())
101+
).toList();
93102
if (user == null) {
94103
invitations.forEach(invitation -> invitation.setRemoteApiUser(remoteUser.getName()));
95104
}

server/src/main/java/invite/exception/InvalidInputException.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
@ResponseStatus(HttpStatus.BAD_REQUEST)
77
public class InvalidInputException extends BaseException {
8+
89
public InvalidInputException(String message) {
910
super(message);
1011
}

server/src/main/java/invite/model/Invitation.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ public class Invitation implements Serializable {
7373
@Column(name = "organization_guid")
7474
private String organizationGUID;
7575

76+
@Column(name = "internal_placeholder_identifier")
77+
private String internalPlaceholderIdentifier;
78+
7679
@ManyToOne(fetch = FetchType.EAGER)
7780
@JoinColumn(name = "inviter_id")
7881
@JsonIgnore
@@ -98,7 +101,8 @@ public Invitation(Authority intendedAuthority,
98101
User inviter,
99102
Instant expiryDate,
100103
Instant roleExpiryDate,
101-
@NotEmpty Set<InvitationRole> roles) {
104+
@NotEmpty Set<InvitationRole> roles,
105+
String internalPlaceholderIdentifier) {
102106
this.intendedAuthority = intendedAuthority;
103107
this.hash = hash;
104108
this.enforceEmailEquality = enforceEmailEquality;

server/src/main/java/invite/model/InvitationRequest.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package invite.model;
22

3-
import jakarta.validation.constraints.NotEmpty;
3+
import invite.exception.InvalidInputException;
44
import jakarta.validation.constraints.NotNull;
55
import lombok.AllArgsConstructor;
66
import lombok.Getter;
77
import lombok.NoArgsConstructor;
88
import lombok.Setter;
9+
import org.springframework.util.CollectionUtils;
910

1011
import java.io.Serializable;
1112
import java.time.Instant;
@@ -32,9 +33,10 @@ public class InvitationRequest implements Serializable {
3233

3334
private boolean suppressSendingEmails;
3435

35-
@NotEmpty
3636
private List<String> invites;
3737

38+
private List<Invite> invitations;
39+
3840
private List<Long> roleIdentifiers;
3941

4042
private String organizationGUID;
@@ -43,4 +45,10 @@ public class InvitationRequest implements Serializable {
4345

4446
@NotNull
4547
private Instant expiryDate;
48+
49+
public void verify() {
50+
if (CollectionUtils.isEmpty(invitations) && CollectionUtils.isEmpty(invites)) {
51+
throw new InvalidInputException("Either at least one invitation or invite is required");
52+
}
53+
}
4654
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package invite.model;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Getter;
5+
import lombok.NoArgsConstructor;
6+
import lombok.Setter;
7+
8+
import java.io.Serializable;
9+
10+
@Getter
11+
@Setter
12+
@NoArgsConstructor
13+
@AllArgsConstructor
14+
public class Invite implements Serializable {
15+
16+
private String email;
17+
private String internalPlaceholderIdentifier;
18+
19+
}

server/src/main/java/invite/model/User.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ public class User implements Serializable, Provisionable {
7575
@Column
7676
private String email;
7777

78+
@Column(name = "internal_placeholder_identifier")
79+
private String internalPlaceholderIdentifier;
80+
7881
@Column(name = "created_at")
7982
private Instant createdAt;
8083

server/src/main/java/invite/provision/scim/UserRequest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ public UserRequest(User user, Provisioning provisioning) {
3636
this.emails = List.of(new Email("other",user.getEmail()));
3737
//Add a default phonenumber, for remote systems that require that
3838
this.phoneNumbers = Collections.singletonList(new PhoneNumber("+31600000000"));
39+
if (StringUtils.hasText(user.getInternalPlaceholderIdentifier())) {
40+
this.id = user.getInternalPlaceholderIdentifier();
41+
}
3942
}
4043

4144
public UserRequest(User user, Provisioning provisioning, String remoteScimIdentifier) {

server/src/main/java/invite/repository/RemoteProvisionedUserRepository.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ public interface RemoteProvisionedUserRepository extends JpaRepository<RemotePro
1212

1313
Optional<RemoteProvisionedUser> findByManageProvisioningIdAndUser(String manageId, User user);
1414

15+
Optional<RemoteProvisionedUser> findByRemoteScimIdentifier(String remoteScimIdentifier);
1516
}

server/src/main/java/invite/seed/PerformanceSeed.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ private Invitation createInvitation(User inviter, Role role) {
140140
inviter,
141141
Instant.now().plus(30, ChronoUnit.DAYS),
142142
Instant.now().plus(365 * 5, ChronoUnit.DAYS),
143-
roles);
143+
roles,
144+
null);
144145
}
145146

146147
private Role createRole(List<Map<String, Object>> providers, String institutionGuid) {

0 commit comments

Comments
 (0)