Skip to content

Commit

Permalink
Fixes #538
Browse files Browse the repository at this point in the history
  • Loading branch information
oharsta committed Oct 29, 2024
1 parent 2c490b1 commit 919235e
Show file tree
Hide file tree
Showing 14 changed files with 95 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.net.URI;
import java.net.URL;
import java.util.HashSet;
import java.util.Map;
Expand Down Expand Up @@ -53,7 +54,7 @@ public void resolveIDisposableEmailProviders() {
String localLocation = "email/fake_filter.json";
Map<String, Object> emailProviders = this.testEnvironment ?
objectMapper.readValue(new ClassPathResource(localLocation).getInputStream(), mapTypeReference) :
objectMapper.readValue(new URL(remoteLocation), mapTypeReference);
objectMapper.readValue(new URI(remoteLocation).toURL(), mapTypeReference);

Map<String, Object> domains = (Map<String, Object>) emailProviders.get("domains");
disposableEmailProviders = parseDisposableEmailProviders(domains);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.io.*;
import java.net.InetAddress;
import java.net.URI;
import java.net.URL;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
Expand Down Expand Up @@ -115,7 +116,7 @@ public void refresh() {
}
File file = new File(String.format("%s/%s/%s.tar.gz", this.downloadDirectory, name, GEO_LITE_2_CITY));
try (FileOutputStream fileOutputStream = new FileOutputStream(file);
InputStream inputStream = new URL(String.format(urlTemplate, licenseKey)).openStream();
InputStream inputStream = new URI(String.format(urlTemplate, licenseKey)).toURL().openStream();

) {
IOUtils.copy(inputStream, fileOutputStream);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class ExternalLinkedAccount implements Serializable, ProvisionedLinkedAcc
private String serviceID;
private String subjectIssuer;
@Setter
private String brinCode;
private List<String> brinCodes;

private String initials;
private String chosenName;
Expand All @@ -45,6 +45,7 @@ public class ExternalLinkedAccount implements Serializable, ProvisionedLinkedAcc
@Setter
@Schema(type = "integer", format = "int64", example = "1634813554997")
private Date dateOfBirth;
@Setter
@Schema(type = "integer", format = "int64", example = "1634813554997")
private Date createdAt;
@Schema(type = "integer", format = "int64", example = "1634813554997")
Expand All @@ -67,7 +68,7 @@ public ExternalLinkedAccount(String subjectId,
String serviceUUID,
String serviceID,
String subjectIssuer,
String brinCode,
List<String> brinCodes,
String initials,
String chosenName,
String firstName,
Expand All @@ -88,7 +89,7 @@ public ExternalLinkedAccount(String subjectId,
this.serviceUUID = serviceUUID;
this.serviceID = serviceID;
this.subjectIssuer = subjectIssuer;
this.brinCode = brinCode;
this.brinCodes = brinCodes;
this.initials = initials;
this.chosenName = chosenName;
this.firstName = firstName;
Expand Down
37 changes: 15 additions & 22 deletions myconext-server/src/main/java/myconext/model/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ public User(CreateInstitutionEduID createInstitutionEduID, Map<String, Object> u
this.familyName = (String) userInfo.get("family_name");
}

public User(String uid, String email, String chosenName, String givenName, String familyName, String schacHomeOrganization, String preferredLanguage,
public User(String uid, String email, String chosenName, String givenName, String familyName,
String schacHomeOrganization, String preferredLanguage,
String serviceProviderEntityId, Manage manage) {
this.uid = uid;
this.email = email;
Expand All @@ -109,27 +110,20 @@ public User(String uid, String email, String chosenName, String givenName, Strin
this.familyName = familyName;
this.schacHomeOrganization = StringUtils.hasText(schacHomeOrganization) ? schacHomeOrganization.toLowerCase() : schacHomeOrganization ;
this.preferredLanguage = preferredLanguage;

this.computeEduIdForServiceProviderIfAbsent(serviceProviderEntityId, manage);
if (StringUtils.hasText(serviceProviderEntityId)) {
this.computeEduIdForServiceProviderIfAbsent(serviceProviderEntityId, manage);
}
this.newUser = true;
this.created = System.currentTimeMillis() / 1000L;
this.updatedAt = created;
}

public User(String uid, String email, String chosenName, String givenName, String familyName, String schacHomeOrganization, String preferredLanguage,
IdentityProvider identityProvider, Manage manage) {
this.uid = uid;
this.email = email;
this.chosenName = chosenName;
this.givenName = givenName;
this.familyName = familyName;
this.schacHomeOrganization = StringUtils.hasText(schacHomeOrganization) ? schacHomeOrganization.toLowerCase() : schacHomeOrganization ;
this.preferredLanguage = preferredLanguage;

this.computeEduIdForIdentityProviderProviderIfAbsent(identityProvider, manage);
this.newUser = true;
this.created = System.currentTimeMillis() / 1000L;
this.updatedAt = created;
public User(String uid, String email, String chosenName, String givenName, String familyName,
String schacHomeOrganization, String preferredLanguage,
RemoteProvider remoteProvider, Manage manage) {
this(uid, email, chosenName, givenName, familyName, schacHomeOrganization, preferredLanguage, (String) null,
manage);
this.computeEduIdForIdentityProviderProviderIfAbsent(remoteProvider, manage);
}

public void validate() {
Expand Down Expand Up @@ -183,11 +177,10 @@ public String computeEduIdForServiceProviderIfAbsent(String entityId, Manage man
}

@Transient
public String computeEduIdForIdentityProviderProviderIfAbsent(IdentityProvider identityProvider, Manage manage) {
ServiceProvider serviceProvider = new ServiceProvider(
new RemoteProvider(null, identityProvider.getName(), identityProvider.getNameNl(), identityProvider.getInstitutionGuid(), identityProvider.getLogoUrl()),
null
);
public String computeEduIdForIdentityProviderProviderIfAbsent(RemoteProvider remoteProvider, Manage manage) {
//we want to pre-provision the eduID based on the institutional GUID, not the entityID
remoteProvider.setEntityId(null);
ServiceProvider serviceProvider = new ServiceProvider(remoteProvider, null);
return doComputeEduIDIfAbsent(serviceProvider, manage);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class NewExternalEduID implements Serializable {
private Verification verification;

@Schema(description = "Can be initial NULL")
private String brinCode;
private List<String> brinCodes;

public void validate() {
List<String> requiredAttributes = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,29 +64,33 @@ public RemoteCreationController(UserRepository userRepository, Manage manage, Ma
responses = {
@ApiResponse(responseCode = "200", description = "Found",
content = {@Content(schema = @Schema(implementation = EmailExistsResponse.class),
examples = {@ExampleObject(value = "{\"status\":200,\"eduIDValue\":\"8048ADA1-8C30-4CDA-8C88-36B865CD16FA\" }")})}),
examples = {@ExampleObject(value = """
{"status":200,"eduIDValue":"8048ADA1-8C30-4CDA-8C88-36B865CD16FA" }
""")})}),
@ApiResponse(responseCode = "400", description = "BadRequest",
content = {@Content(schema = @Schema(implementation = StatusResponse.class),
examples = {@ExampleObject(value = "{\"status\":400}")})}),
@ApiResponse(responseCode = "404", description = "User not found by email [email protected]",
content = {@Content(schema = @Schema(implementation = StatusResponse.class),
examples = {@ExampleObject(value = "{\n" +
" \"timestamp\": 1717671062532,\n" +
" \"status\": 404,\n" +
" \"error\": \"Not Found\",\n" +
" \"exception\": \"myconext.exceptions.UserNotFoundException\",\n" +
" \"message\": \"User not found by email [email protected]\",\n" +
" \"path\": \"/api/remote-creation/email-eduid-exists\"\n" +
"}")})})})
examples = {@ExampleObject(value = """
{
"timestamp": 1717671062532,
"status": 404,
"error": "Not Found",
"exception": "myconext.exceptions.UserNotFoundException",
"message": "User not found by email [email protected]",
"path": "/api/remote-creation/email-eduid-exists"
}
""")})})})
public ResponseEntity<EmailExistsResponse> emailEduIDExists(@Parameter(hidden = true) @AuthenticationPrincipal(errorOnInvalidType = true) RemoteUser remoteUser,
@RequestParam(value = "email") String email) {
LOG.info(String.format("GET email-eduid-exists by %s for %s", remoteUser.getUsername(), email));

String remoteUserName = remoteUser.getUsername();
User user = userRepository.findUserByEmail(email)
.orElseThrow(() -> new UserNotFoundException(String.format("User not found by email %s", email)));
IdentityProvider identityProvider = getIdentityProvider(remoteUser, new NewExternalEduID(), remoteUserName);
String eduIDValue = user.computeEduIdForIdentityProviderProviderIfAbsent(identityProvider, manage);
RemoteProvider remoteProvider = getRemoteProvider(remoteUser, remoteUserName);
String eduIDValue = user.computeEduIdForIdentityProviderProviderIfAbsent(remoteProvider, manage);
userRepository.save(user);

return ResponseEntity.ok(new EmailExistsResponse(HttpStatus.OK.value(), eduIDValue));
Expand Down Expand Up @@ -186,7 +190,8 @@ public ResponseEntity<EduIDValue> eduIDForInstitution(@Parameter(hidden = true)
" \"message\": \"Email already in use\",\n" +
" \"path\": \"/api/remote-creation/eduid-create\"\n" +
"}")})})})
public ResponseEntity<UpdateExternalEduID> createEduID(@Parameter(hidden = true) @AuthenticationPrincipal(errorOnInvalidType = true) RemoteUser remoteUser,
public ResponseEntity<UpdateExternalEduID> createEduID(@Parameter(hidden = true)
@AuthenticationPrincipal(errorOnInvalidType = true) RemoteUser remoteUser,
@RequestBody @Validated NewExternalEduID externalEduID) {
String email = externalEduID.getEmail();
String apiUserName = remoteUser.getUsername();
Expand All @@ -198,12 +203,12 @@ public ResponseEntity<UpdateExternalEduID> createEduID(@Parameter(hidden = true)
userRepository.findUserByEmail(email).ifPresent(u -> {
throw new DuplicateUserEmailException("There already exists a user with email " + email);
});
IdentityProvider identityProvider = getIdentityProvider(remoteUser, externalEduID, apiUserName);
RemoteProvider remoteProvider = getRemoteProvider(remoteUser, apiUserName);
String lastNamePrefix = externalEduID.getLastNamePrefix();
String lastName = StringUtils.hasText(lastNamePrefix) ? String.format("%s %s", lastNamePrefix, externalEduID.getLastName()) : externalEduID.getLastName();
User user = new User(UUID.randomUUID().toString(), externalEduID.getEmail(), externalEduID.getChosenName(),
externalEduID.getFirstName(), lastName, remoteUser.getSchacHome(), LocaleContextHolder.getLocale().getLanguage(),
identityProvider, manage);
externalEduID.getFirstName(), lastName, remoteUser.getSchacHome(), LocaleContextHolder.getLocale().getLanguage(), remoteProvider
, manage);
//Otherwise another email is sent out when the user logs in
user.setNewUser(false);

Expand Down Expand Up @@ -261,12 +266,12 @@ public ResponseEntity<UpdateExternalEduID> updateEduID(@Parameter(hidden = true)
optionalExternalLinkedAccount.ifPresentOrElse(externalLinkedAccount -> {
//Not all external attributes can be changed
externalLinkedAccount.setVerification(externalEduID.getVerification());
externalLinkedAccount.setBrinCode(externalEduID.getBrinCode());
externalLinkedAccount.setBrinCodes(externalEduID.getBrinCodes());
externalLinkedAccount.setDateOfBirth(AttributeMapper.parseDate(externalEduID.getDateOfBirth()));
}, () -> {
//Create external account for this remoteAPI user
IdentityProvider identityProvider = getIdentityProvider(remoteUser, externalEduID, remoteUserName);
String provisionedEduIDValue = user.computeEduIdForIdentityProviderProviderIfAbsent(identityProvider, manage);
RemoteProvider remoteProvider = getRemoteProvider(remoteUser, remoteUserName);
String provisionedEduIDValue = user.computeEduIdForIdentityProviderProviderIfAbsent(remoteProvider, manage);
externalEduID.setEduIDValue(provisionedEduIDValue);
ExternalLinkedAccount externalLinkedAccount = attributeMapper.createExternalLinkedAccount(externalEduID, IdpScoping.valueOf(remoteUserName));
user.getExternalLinkedAccounts().add(externalLinkedAccount);
Expand Down Expand Up @@ -305,16 +310,13 @@ public ResponseEntity<Void> deleteEduID(@Parameter(hidden = true) @Authenticatio
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
}

private static IdentityProvider getIdentityProvider(RemoteUser remoteUser, NewExternalEduID externalEduID, String remoteUserName) {
RemoteProvider remoteProvider = new RemoteProvider(
private static RemoteProvider getRemoteProvider(RemoteUser remoteUser, String remoteUserName) {
return new RemoteProvider(
null,
remoteUserName,
remoteUserName,
remoteUser.getInstitutionGUID(),
String.format("https://static.surfconext.nl/logos/org/%s.png", remoteUser.getInstitutionGUID()));


return new IdentityProvider(remoteProvider, externalEduID.getBrinCode());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;

@NoArgsConstructor
@Getter
Expand All @@ -19,8 +20,10 @@ public class UpdateExternalEduID extends NewExternalEduID {
@Schema(description = "Generated by the RemoteCreation POST API, must be send with PUT update requests")
private String eduIDValue;

public UpdateExternalEduID(String email, String eduIDValue, @NotBlank String chosenName, String firstName, String lastNamePrefix, @NotBlank String lastName, String dateOfBirth, @NotBlank String identifier, @NotNull Verification verification, String brinCode) {
super(email, chosenName, firstName, lastNamePrefix, lastName, dateOfBirth, identifier, verification, brinCode);
public UpdateExternalEduID(String email, String eduIDValue, @NotBlank String chosenName, String firstName,
String lastNamePrefix, @NotBlank String lastName, String dateOfBirth, @NotBlank String identifier,
@NotNull Verification verification, List<String> brinCodes) {
super(email, chosenName, firstName, lastNamePrefix, lastName, dateOfBirth, identifier, verification, brinCodes);
this.eduIDValue = eduIDValue;
}

Expand All @@ -33,7 +36,7 @@ public UpdateExternalEduID(NewExternalEduID externalEduID, String newEduIDValue)
externalEduID.getDateOfBirth(),
externalEduID.getIdentifier(),
externalEduID.getVerification(),
externalEduID.getBrinCode());
externalEduID.getBrinCodes());
this.eduIDValue = newEduIDValue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public String send(String mobile, String code, Locale locale) {
byte[] bytes = format.getBytes(StandardCharsets.UTF_8);
File tempFile = File.createTempFile("javasms", ".html");
FileCopyUtils.copy(bytes, tempFile);
Runtime.getRuntime().exec("open " + tempFile.getAbsolutePath());
Runtime.getRuntime().exec(new String[]{"open",tempFile.getAbsolutePath()});
}
return format;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ public ExternalLinkedAccount createExternalLinkedAccount(NewExternalEduID eduID,
//String subjectIssuer
IdpScoping.studielink.name(),
//String brinCode
eduID.getBrinCode(),
eduID.getBrinCodes(),
//String initials
null,
//String chosenName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1352,7 +1352,7 @@ public void updateExternalLinkedAccount() {
"serviceUUID",
"serviceID",
"subjectIssuer",
"brinCode",
List.of("brinCode"),
"initials",
"chosenName",
"firstName",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ void provisionEduid() {
.as(new TypeRef<>() {
});
User user = userRepository.findOneUserByEmail("[email protected]");
EduID newEduID = user.getEduIDS().stream().filter(eduID -> eduID.getValue().equals(newEduIDProvision.getEduIDValue()))
EduID newEduID = user.getEduIDS().stream()
.filter(eduID -> eduID.getValue().equals(newEduIDProvision.getEduIDValue()))
.findFirst()
.orElseThrow(IllegalArgumentException::new);
List<ServiceProvider> services = newEduID.getServices();
Expand Down
Loading

0 comments on commit 919235e

Please sign in to comment.