diff --git a/provisioning-mock/src/main/java/provisioning/api/EVAController.java b/provisioning-mock/src/main/java/provisioning/api/EVAController.java index 2e2ab39..5f71b28 100644 --- a/provisioning-mock/src/main/java/provisioning/api/EVAController.java +++ b/provisioning-mock/src/main/java/provisioning/api/EVAController.java @@ -44,7 +44,7 @@ public ResponseEntity> createUser(GuestAccount guestAccount) provisioningRepository.save(new Provisioning( ProvisioningType.eva, objectMapper.valueToTree(user), - HttpMethod.DELETE, + HttpMethod.POST, ResourceType.USERS, "eva/api/v1/guest/create" )); diff --git a/server/src/main/java/access/provision/ProvisioningServiceDefault.java b/server/src/main/java/access/provision/ProvisioningServiceDefault.java index bbff1b8..54da5af 100644 --- a/server/src/main/java/access/provision/ProvisioningServiceDefault.java +++ b/server/src/main/java/access/provision/ProvisioningServiceDefault.java @@ -2,6 +2,7 @@ import access.eduid.EduID; import access.eduid.EduIDProvision; +import access.exception.InvalidInputException; import access.exception.RemoteException; import access.manage.Manage; import access.manage.ManageIdentifier; @@ -146,10 +147,16 @@ public void updateUserRoleRequest(UserRole userRole) { List provisionings = getProvisionings(userRole.getUser()); provisionings.forEach(provisioning -> { if (this.hasEvaHook(provisioning)) { - RequestEntity requestEntity = this.evaClient.updateUserRequest(provisioning, userRole.getUser()); - doExchange(requestEntity, USER_API, stringParameterizedTypeReference, provisioning); + try { + //For now only eva is eligible for update's for the userRole (e.g. new end date) + RequestEntity requestEntity = this.evaClient.updateUserRequest(provisioning, userRole.getUser()); + doExchange(requestEntity, USER_API, stringParameterizedTypeReference, provisioning); + } catch (InvalidInputException e) { + //Can't be helped and won't happen on production + LOG.error("Error from evaClient", e); + } } - //For now only eva is eligible for update's for the userRole (e.g. new end date) + }); } diff --git a/server/src/main/java/access/provision/eva/EvaClient.java b/server/src/main/java/access/provision/eva/EvaClient.java index 1630d62..84dc71a 100644 --- a/server/src/main/java/access/provision/eva/EvaClient.java +++ b/server/src/main/java/access/provision/eva/EvaClient.java @@ -1,5 +1,6 @@ package access.provision.eva; +import access.model.RemoteProvisionedUser; import access.model.User; import access.provision.Provisioning; import access.repository.RemoteProvisionedUserRepository; @@ -13,6 +14,7 @@ import java.net.URI; import java.util.List; +import java.util.Optional; @SuppressWarnings("unchecked") public class EvaClient { @@ -66,11 +68,10 @@ private RequestEntity doEvaRequest(Provisioning provisioning, User user, String } MultiValueMap map = new GuestAccount(user, provisioning).getRequest(); if (requestType.equals(RequestType.update)) { - this.remoteProvisionedUserRepository.findByManageProvisioningIdAndUser(provisioning.getId(), user) - .ifPresent(remoteProvisionedUser -> { - map.add("id", remoteProvisionedUser.getRemoteIdentifier()); - map.replace("dateFrom", List.of(GuestAccount.dateFrom(remoteProvisionedUser))); - }); + Optional optionalRemoteProvisionedUser = this.remoteProvisionedUserRepository.findByManageProvisioningIdAndUser(provisioning.getId(), user); + optionalRemoteProvisionedUser + .ifPresent(remoteProvisionedUser -> + map.add("id", remoteProvisionedUser.getRemoteIdentifier())); } return new RequestEntity(map, headers, HttpMethod.POST, URI.create(url)); } diff --git a/server/src/main/java/access/provision/eva/GuestAccount.java b/server/src/main/java/access/provision/eva/GuestAccount.java index 95166c2..6499763 100644 --- a/server/src/main/java/access/provision/eva/GuestAccount.java +++ b/server/src/main/java/access/provision/eva/GuestAccount.java @@ -1,9 +1,12 @@ package access.provision.eva; +import access.exception.InvalidInputException; import access.model.RemoteProvisionedUser; import access.model.User; import access.provision.Provisioning; import access.provision.ProvisioningType; +import lombok.Getter; +import org.hibernate.AssertionFailure; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; @@ -11,12 +14,15 @@ import java.sql.Date; import java.text.SimpleDateFormat; import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.Comparator; +@Getter public class GuestAccount { - private static final String EVA_DATE_PATTERN = "yyyy-MM-dd"; + protected static final String EVA_DATE_PATTERN = "yyyy-MM-dd"; + private final MultiValueMap request; public GuestAccount(User user, Provisioning provisioning) { @@ -25,8 +31,12 @@ public GuestAccount(User user, Provisioning provisioning) { Instant dateTill = user.userRolesForProvisioning(provisioning) .stream() .map(userRole -> userRole.getEndDate()) + .filter(date -> date != null) .max(Comparator.naturalOrder()) .orElseThrow(() -> new AssertionError("No userRoles found for provisioning:" + provisioning.getEntityId())); + if (dateTill.isBefore(now)) { + throw new InvalidInputException(String.format("dateTill %s is before now %s. No EVA provisioning possible", dateTill, now)); + } String language = LocaleContextHolder.getLocale().getLanguage(); request = new LinkedMultiValueMap<>(); request.add("name", user.getName()); @@ -39,11 +49,4 @@ public GuestAccount(User user, Provisioning provisioning) { request.add("preferredLanguage", language); } - public static String dateFrom(RemoteProvisionedUser remoteProvisionedUser) { - return new SimpleDateFormat(EVA_DATE_PATTERN).format(Date.from(remoteProvisionedUser.getCreatedAt())); - } - - public MultiValueMap getRequest() { - return request; - } } diff --git a/server/src/test/java/access/provision/eva/GuestAccountTest.java b/server/src/test/java/access/provision/eva/GuestAccountTest.java index 7ba1a26..3e4d8d7 100644 --- a/server/src/test/java/access/provision/eva/GuestAccountTest.java +++ b/server/src/test/java/access/provision/eva/GuestAccountTest.java @@ -1,13 +1,23 @@ package access.provision.eva; -import access.model.User; +import access.exception.InvalidInputException; +import access.manage.EntityType; +import access.model.*; import access.provision.Provisioning; import access.provision.ProvisioningType; import org.junit.jupiter.api.Test; +import org.springframework.util.MultiValueMap; +import java.sql.Date; +import java.text.SimpleDateFormat; +import java.time.Instant; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Set; +import static access.provision.eva.GuestAccount.EVA_DATE_PATTERN; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; class GuestAccountTest { @@ -23,6 +33,45 @@ void getRequest() { assertThrows(AssertionError.class, () -> new GuestAccount(new User(), new Provisioning(map))); } + @Test + void invalidDateTill() { + Map map = new HashMap<>(); + map.put("provisioning_type", ProvisioningType.eva.name()); + map.put("eva_token", "secret"); + map.put("eva_url", "https://eva"); + map.put("applications", List.of(Map.of("id", "manageId", "type", EntityType.SAML20_SP.name()))); + + User user = new User(); + ApplicationUsage applicationUsage = new ApplicationUsage(new Application("manageId", EntityType.SAML20_SP), "https://landingpage.com"); + Role role = new Role( + "name", "description", Set.of(applicationUsage), -5, false, false); + UserRole userRole = new UserRole(Authority.GUEST, role); + + user.getUserRoles().add(userRole); + + assertThrows(InvalidInputException.class, () -> new GuestAccount(user, new Provisioning(map))); + } + + @Test + void nullDateTill() { + Map map = new HashMap<>(); + map.put("provisioning_type", ProvisioningType.eva.name()); + map.put("eva_token", "secret"); + map.put("eva_url", "https://eva"); + map.put("applications", List.of(Map.of("id", "manageId", "type", EntityType.SAML20_SP.name()))); + + User user = new User(); + ApplicationUsage applicationUsage = new ApplicationUsage(new Application("manageId", EntityType.SAML20_SP), "https://landingpage.com"); + Role role = new Role( + "name", "description", Set.of(applicationUsage), -5, false, false); + UserRole userRole = new UserRole(Authority.GUEST, role); + userRole.setEndDate(null); + + user.getUserRoles().add(userRole); + + assertThrows(AssertionError.class, () -> new GuestAccount(user, new Provisioning(map))); + } + @Test void noUserRoles() { Map map = new HashMap<>();