diff --git a/pom.xml b/pom.xml index 6991d94..5a5d8c5 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.openconext voot-service - 5.0.1 + 6.0.0-SNAPSHOT jar voot-service diff --git a/src/main/java/voot/ExternalGroupsService.java b/src/main/java/voot/ExternalGroupsService.java index ed797d0..932e3ed 100644 --- a/src/main/java/voot/ExternalGroupsService.java +++ b/src/main/java/voot/ExternalGroupsService.java @@ -117,7 +117,8 @@ public Set getAllGroups() { protected Set filterDuplicatesWithLowerImportance(List groups) { return groups.stream().collect(groupingBy(group -> group.id)).values().stream() - .map(groupList -> groupList.stream().max(Comparator.comparing(group -> group.membership)).get()).collect(toSet()); + .map(groupList -> groupList.stream().max(Comparator.comparing(group -> group.membership)).get()) + .collect(toSet()); } @SneakyThrows diff --git a/src/main/java/voot/VootServiceApplication.java b/src/main/java/voot/VootServiceApplication.java index 25e8875..99bff49 100644 --- a/src/main/java/voot/VootServiceApplication.java +++ b/src/main/java/voot/VootServiceApplication.java @@ -64,6 +64,8 @@ public ExternalGroupsService externalGroupsService( return new OpenSocialMembersClient(configuration); case GUESTS: return new EduIDGuestProvider(configuration); + case INVITE: + return new InviteProvider(configuration); default: throw new IllegalArgumentException("Unknown external provider-type: " + type); } diff --git a/src/main/java/voot/model/User.java b/src/main/java/voot/model/User.java index 8a51f07..d1e076d 100644 --- a/src/main/java/voot/model/User.java +++ b/src/main/java/voot/model/User.java @@ -8,9 +8,9 @@ @Getter public class User { - private String clientId; - private String unspecifiedId; - private String schacHomeOrganization; + private final String clientId; + private final String unspecifiedId; + private final String schacHomeOrganization; public User(BearerTokenAuthentication bearerTokenAuthentication) { Map tokenAttributes = bearerTokenAuthentication.getTokenAttributes(); diff --git a/src/main/java/voot/provider/GroupProviderType.java b/src/main/java/voot/provider/GroupProviderType.java index c0507ab..f89fc8d 100644 --- a/src/main/java/voot/provider/GroupProviderType.java +++ b/src/main/java/voot/provider/GroupProviderType.java @@ -2,6 +2,6 @@ public enum GroupProviderType { - TEAMS, OPEN_SOCIAL, OPEN_SOCIAL_MEMBERS, VOOT2, GUESTS + TEAMS, OPEN_SOCIAL, OPEN_SOCIAL_MEMBERS, VOOT2, GUESTS, INVITE } diff --git a/src/main/java/voot/provider/InviteProvider.java b/src/main/java/voot/provider/InviteProvider.java new file mode 100644 index 0000000..0dd1dda --- /dev/null +++ b/src/main/java/voot/provider/InviteProvider.java @@ -0,0 +1,63 @@ +package voot.provider; + +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpMethod; +import org.springframework.http.RequestEntity; +import org.springframework.http.ResponseEntity; +import voot.model.Group; +import voot.model.Member; +import voot.model.Membership; + +import java.net.URI; +import java.util.*; +import java.util.stream.Collectors; + +public class InviteProvider extends AbstractProvider { + + private final String groupMembershipsUrlTemplate; + + public InviteProvider(Configuration configuration) { + super(configuration); + groupMembershipsUrlTemplate = "%s/api/voot/%s"; + } + + @Override + public boolean shouldBeQueriedForMemberships(String schacHomeOrganization) { + return true; + } + + @Override + public Set getGroupMemberships(String uid) { + String uri = String.format(groupMembershipsUrlTemplate, configuration.url, uid); + RequestEntity>> requestEntity = new RequestEntity<>(HttpMethod.GET, URI.create(uri)); + return restTemplate.exchange(requestEntity, new ParameterizedTypeReference>>() { + }).getBody().stream() + .map(this::parseGroup) + .collect(Collectors.toSet()); + } + + private Group parseGroup(Map map) { + String name = map.get("name"); + return new Group(map.get("urn"), name, name, "Invite", Membership.MEMBER); + } + + @Override + public Set getAllGroups() { + return Collections.emptySet(); + } + + @Override + public Optional getGroupMembership(String uid, String groupId) { + return Optional.empty(); + } + + @Override + public Set getMembers(String groupId) { + return Collections.emptySet(); + } + + @Override + public Set getMembers(String personId, String groupId) { + return Collections.emptySet(); + } +} diff --git a/src/test/java/voot/VootServiceApplicationTest.java b/src/test/java/voot/VootServiceApplicationTest.java index 6a52967..4b2e1f9 100644 --- a/src/test/java/voot/VootServiceApplicationTest.java +++ b/src/test/java/voot/VootServiceApplicationTest.java @@ -23,12 +23,12 @@ void externalGroupsService() throws IOException { ExternalGroupsService externalGroupsService = app.externalGroupsService(new ClassPathResource("/testAllExternalProviders.yml")); Object providers = ReflectionTestUtils.getField(externalGroupsService, "providers"); - assertEquals(5, ((List) providers).size()); + assertEquals(6, ((List) providers).size()); } @Test - void externalGroupsServiceUnknown() throws IOException { + void externalGroupsServiceUnknown() { VootServiceApplication app = new VootServiceApplication(); Assertions.assertThrows(IllegalArgumentException.class, () -> app.externalGroupsService(new ClassPathResource("/testUnknownExternalProviders.yml"))); diff --git a/src/test/java/voot/provider/InviteProviderTest.java b/src/test/java/voot/provider/InviteProviderTest.java new file mode 100644 index 0000000..b70f9a4 --- /dev/null +++ b/src/test/java/voot/provider/InviteProviderTest.java @@ -0,0 +1,57 @@ +package voot.provider; + +import com.nimbusds.jose.util.IOUtils; +import org.junit.jupiter.api.Test; +import org.springframework.core.io.ClassPathResource; +import voot.AbstractTest; +import voot.model.Group; + +import java.io.IOException; +import java.util.Set; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + + +class InviteProviderTest extends AbstractTest { + + private final InviteProvider subject = new InviteProvider( + new Provider.Configuration(GroupProviderType.INVITE, "http://localhost:8889", + new Provider.Configuration.Credentials("user", "password"), + 2000, "N/A", "invite")); + + @Test + void getGroupMemberships() throws IOException { + String json = IOUtils.readInputStreamToString(new ClassPathResource("json/invite/group_memberships.json").getInputStream()); + String urn = "urn:collab:person:example.com:admin"; + stubFor(get(urlPathEqualTo("/api/voot/" + urn)) + .willReturn(aResponse() + .withStatus(200) + .withHeader("Content-type", "application/json"). + withBody(json))); + Set groupMemberships = subject.getGroupMemberships(urn); + assertEquals(2, groupMemberships.size()); + } + + @Test + void getAllGroups() { + assertEquals(0, subject.getAllGroups().size()); + } + + @Test + void getGroupMembership() { + assertFalse(subject.getGroupMembership("uid", "groupId").isPresent()); + + } + + @Test + void getMembers() { + assertEquals(0, subject.getMembers("groupId").size()); + } + + @Test + void getMembersByPersonId() { + assertEquals(0, subject.getMembers("personId", "groupId").size()); + } +} diff --git a/src/test/resources/json/invite/group_memberships.json b/src/test/resources/json/invite/group_memberships.json new file mode 100644 index 0000000..4e73e06 --- /dev/null +++ b/src/test/resources/json/invite/group_memberships.json @@ -0,0 +1,10 @@ +[ + { + "urn": "urn1", + "name": "administrator" + }, + { + "urn": "urn2", + "name": "guest" + } +] diff --git a/src/test/resources/testAllExternalProviders.yml b/src/test/resources/testAllExternalProviders.yml index 35d816b..9f42928 100644 --- a/src/test/resources/testAllExternalProviders.yml +++ b/src/test/resources/testAllExternalProviders.yml @@ -54,3 +54,14 @@ externalGroupProviders: name: "Bar", timeoutMillis: 5000 } + - { + type: "invite", + url: "http://localhost:8999/", + credentials: { + username: "foo", + secret: "bar" + }, + schacHomeOrganization: "N/A", + name: "Invite", + timeoutMillis: 5000 + }