/*
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.cloudfoundry.reactor.uaa.groups;
import org.cloudfoundry.reactor.InteractionContext;
import org.cloudfoundry.reactor.TestRequest;
import org.cloudfoundry.reactor.TestResponse;
import org.cloudfoundry.reactor.uaa.AbstractUaaApiTest;
import org.cloudfoundry.uaa.Metadata;
import org.cloudfoundry.uaa.groups.AddMemberRequest;
import org.cloudfoundry.uaa.groups.AddMemberResponse;
import org.cloudfoundry.uaa.groups.CheckMembershipRequest;
import org.cloudfoundry.uaa.groups.CheckMembershipResponse;
import org.cloudfoundry.uaa.groups.CreateGroupRequest;
import org.cloudfoundry.uaa.groups.CreateGroupResponse;
import org.cloudfoundry.uaa.groups.DeleteGroupRequest;
import org.cloudfoundry.uaa.groups.DeleteGroupResponse;
import org.cloudfoundry.uaa.groups.ExternalGroupResource;
import org.cloudfoundry.uaa.groups.GetGroupRequest;
import org.cloudfoundry.uaa.groups.GetGroupResponse;
import org.cloudfoundry.uaa.groups.Group;
import org.cloudfoundry.uaa.groups.ListExternalGroupMappingsRequest;
import org.cloudfoundry.uaa.groups.ListExternalGroupMappingsResponse;
import org.cloudfoundry.uaa.groups.ListGroupsRequest;
import org.cloudfoundry.uaa.groups.ListGroupsResponse;
import org.cloudfoundry.uaa.groups.ListMembersRequest;
import org.cloudfoundry.uaa.groups.ListMembersResponse;
import org.cloudfoundry.uaa.groups.MapExternalGroupRequest;
import org.cloudfoundry.uaa.groups.MapExternalGroupResponse;
import org.cloudfoundry.uaa.groups.Member;
import org.cloudfoundry.uaa.groups.MemberSummary;
import org.cloudfoundry.uaa.groups.MemberType;
import org.cloudfoundry.uaa.groups.RemoveMemberRequest;
import org.cloudfoundry.uaa.groups.RemoveMemberResponse;
import org.cloudfoundry.uaa.groups.UnmapExternalGroupByGroupDisplayNameRequest;
import org.cloudfoundry.uaa.groups.UnmapExternalGroupByGroupDisplayNameResponse;
import org.cloudfoundry.uaa.groups.UnmapExternalGroupByGroupIdRequest;
import org.cloudfoundry.uaa.groups.UnmapExternalGroupByGroupIdResponse;
import org.cloudfoundry.uaa.groups.UpdateGroupRequest;
import org.cloudfoundry.uaa.groups.UpdateGroupResponse;
import org.cloudfoundry.uaa.groups.UserEntity;
import org.cloudfoundry.uaa.users.Email;
import org.cloudfoundry.uaa.users.Meta;
import org.cloudfoundry.uaa.users.Name;
import org.junit.Test;
import reactor.test.StepVerifier;
import java.time.Duration;
import static io.netty.handler.codec.http.HttpMethod.DELETE;
import static io.netty.handler.codec.http.HttpMethod.GET;
import static io.netty.handler.codec.http.HttpMethod.POST;
import static io.netty.handler.codec.http.HttpMethod.PUT;
import static io.netty.handler.codec.http.HttpResponseStatus.CREATED;
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
import static org.cloudfoundry.uaa.SortOrder.ASCENDING;
public final class ReactorGroupsTest extends AbstractUaaApiTest {
private final ReactorGroups groups = new ReactorGroups(CONNECTION_CONTEXT, this.root, TOKEN_PROVIDER);
@Test
public void addMember() {
mockRequest(InteractionContext.builder()
.request(TestRequest.builder()
.method(POST).path("/Groups/test-group-id/members")
.payload("fixtures/uaa/groups/POST_{id}_members_request.json")
.build())
.response(TestResponse.builder()
.status(CREATED)
.payload("fixtures/uaa/groups/POST_{id}_members_response.json")
.build())
.build());
this.groups
.addMember(AddMemberRequest.builder()
.groupId("test-group-id")
.origin("uaa")
.type(MemberType.USER)
.memberId("40bc8ef1-0719-4a0c-9f60-e9f843cd4af2")
.build())
.as(StepVerifier::create)
.expectNext(AddMemberResponse.builder()
.origin("uaa")
.type(MemberType.USER)
.memberId("40bc8ef1-0719-4a0c-9f60-e9f843cd4af2")
.build())
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
public void checkMember() {
mockRequest(InteractionContext.builder()
.request(TestRequest.builder()
.method(GET).path("/Groups/test-group-id/members/test-member-id")
.build())
.response(TestResponse.builder()
.status(OK)
.payload("fixtures/uaa/groups/GET_{id}_members_{id}_response.json")
.build())
.build());
this.groups
.checkMembership(CheckMembershipRequest.builder()
.groupId("test-group-id")
.memberId("test-member-id")
.build())
.as(StepVerifier::create)
.expectNext(CheckMembershipResponse.builder()
.origin("uaa")
.type(MemberType.USER)
.memberId("test-member-id")
.build())
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
public void create() {
mockRequest(InteractionContext.builder()
.request(TestRequest.builder()
.header("X-Identity-Zone-Id", "uaa")
.method(POST).path("/Groups")
.payload("fixtures/uaa/groups/POST_request.json")
.build())
.response(TestResponse.builder()
.status(CREATED)
.payload("fixtures/uaa/groups/POST_response.json")
.build())
.build());
this.groups
.create(CreateGroupRequest.builder()
.description("the cool group")
.displayName("Cool Group Name")
.identityZoneId("uaa")
.member(MemberSummary.builder()
.origin("uaa")
.type(MemberType.USER)
.memberId("f0e6a061-6e3a-4be9-ace5-142ee24e20b7")
.build())
.build())
.as(StepVerifier::create)
.expectNext(CreateGroupResponse.builder()
.id("46081184-7ca9-453d-9bf8-74da7113bec6")
.metadata(Metadata.builder()
.created("2016-06-03T17:59:30.527Z")
.lastModified("2016-06-03T17:59:30.527Z")
.version(0)
.build())
.description("the cool group")
.displayName("Cool Group Name")
.member(MemberSummary.builder()
.origin("uaa")
.type(MemberType.USER)
.memberId("f0e6a061-6e3a-4be9-ace5-142ee24e20b7")
.build())
.schema("urn:scim:schemas:core:1.0")
.zoneId("uaa")
.build())
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
public void delete() {
mockRequest(InteractionContext.builder()
.request(TestRequest.builder()
.header("If-Match", "*")
.method(DELETE).path("/Groups/test-group-id")
.build())
.response(TestResponse.builder()
.status(OK)
.payload("fixtures/uaa/groups/DELETE_{id}_response.json")
.build())
.build());
this.groups
.delete(DeleteGroupRequest.builder()
.groupId("test-group-id")
.version("*")
.build())
.as(StepVerifier::create)
.expectNext(DeleteGroupResponse.builder()
.id("test-group-id")
.metadata(Metadata.builder()
.created("2016-06-03T17:59:30.527Z")
.lastModified("2016-06-03T17:59:30.561Z")
.version(1)
.build())
.description("the cool group")
.displayName("Cooler Group Name for Delete")
.member(MemberSummary.builder()
.origin("uaa")
.type(MemberType.USER)
.memberId("f0e6a061-6e3a-4be9-ace5-142ee24e20b7")
.build())
.schema("urn:scim:schemas:core:1.0")
.zoneId("uaa")
.build())
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
public void get() {
mockRequest(InteractionContext.builder()
.request(TestRequest.builder()
.method(GET).path("/Groups/test-group-id")
.build())
.response(TestResponse.builder()
.status(OK)
.payload("fixtures/uaa/groups/GET_{id}_response.json")
.build())
.build());
this.groups
.get(GetGroupRequest.builder()
.groupId("test-group-id")
.build())
.as(StepVerifier::create)
.expectNext(GetGroupResponse.builder()
.id("test-group-id")
.metadata(Metadata.builder()
.created("2016-06-03T17:59:30.527Z")
.lastModified("2016-06-03T17:59:30.561Z")
.version(1)
.build())
.description("the cool group")
.displayName("Cooler Group Name for Retrieve")
.member(MemberSummary.builder()
.origin("uaa")
.type(MemberType.USER)
.memberId("f0e6a061-6e3a-4be9-ace5-142ee24e20b7")
.build())
.schema("urn:scim:schemas:core:1.0")
.zoneId("uaa")
.build())
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
public void list() {
mockRequest(InteractionContext.builder()
.request(TestRequest.builder()
.method(GET)
.path("/Groups?count=50&filter=id%2Beq%2B%22f87c557a-8ddc-43d3-98fb-e420ebc7f0f1%22%2Bor%2BdisplayName%2Beq%2B%22Cooler%20Group%20Name%20for%20List%22" +
"&sortBy=email&sortOrder=ascending&startIndex=1")
.build())
.response(TestResponse.builder()
.status(OK)
.payload("fixtures/uaa/groups/GET_response.json")
.build())
.build());
this.groups
.list(ListGroupsRequest.builder()
.filter("id+eq+\"f87c557a-8ddc-43d3-98fb-e420ebc7f0f1\"+or+displayName+eq+\"Cooler Group Name for List\"")
.count(50)
.startIndex(1)
.sortBy("email")
.sortOrder(ASCENDING)
.build())
.as(StepVerifier::create)
.expectNext(ListGroupsResponse.builder()
.resource(Group.builder()
.id("f87c557a-8ddc-43d3-98fb-e420ebc7f0f1")
.metadata(Metadata.builder()
.created("2016-06-16T00:01:41.692Z")
.lastModified("2016-06-16T00:01:41.728Z")
.version(1)
.build())
.description("the cool group")
.displayName("Cooler Group Name for List")
.member(MemberSummary.builder()
.origin("uaa")
.type(MemberType.USER)
.memberId("40bc8ef1-0719-4a0c-9f60-e9f843cd4af2")
.build())
.schema("urn:scim:schemas:core:1.0")
.zoneId("uaa")
.build()
)
.startIndex(1)
.itemsPerPage(50)
.totalResults(1)
.schema("urn:scim:schemas:core:1.0")
.build())
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
public void listExternalGroupMappings() {
mockRequest(InteractionContext.builder()
.request(TestRequest.builder()
.method(GET)
.path("/Groups/External?count=50&filter=group_id%2Beq%2B%220480db7f-d1bc-4d2b-b723-febc684c0ee9%22&startIndex=1")
.build())
.response(TestResponse.builder()
.status(OK)
.payload("fixtures/uaa/groups/GET_external_response.json")
.build())
.build());
this.groups
.listExternalGroupMappings(ListExternalGroupMappingsRequest.builder()
.filter("group_id+eq+\"0480db7f-d1bc-4d2b-b723-febc684c0ee9\"")
.count(50)
.startIndex(1)
.build())
.as(StepVerifier::create)
.expectNext(ListExternalGroupMappingsResponse.builder()
.resource(ExternalGroupResource.builder()
.groupId("c4a41861-6c83-45a7-995e-64fb66565dce")
.displayName("Group For Testing Retrieving External Group Mappings")
.origin("ldap")
.externalGroup("external group")
.build()
)
.startIndex(1)
.itemsPerPage(1)
.totalResults(1)
.schema("urn:scim:schemas:core:1.0")
.build())
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
public void listMembers() {
mockRequest(InteractionContext.builder()
.request(TestRequest.builder()
.method(GET)
.path("/Groups/f87c557a-8ddc-43d3-98fb-e420ebc7f0f1/members?returnEntities=true")
.build())
.response(TestResponse.builder()
.status(OK)
.payload("fixtures/uaa/groups/GET_members_response.json")
.build())
.build());
this.groups
.listMembers(ListMembersRequest.builder()
.groupId("f87c557a-8ddc-43d3-98fb-e420ebc7f0f1")
.returnEntities(true)
.build())
.as(StepVerifier::create)
.expectNext(ListMembersResponse.builder()
.member(Member.builder()
.memberId("40bc8ef1-0719-4a0c-9f60-e9f843cd4af2")
.type(MemberType.USER)
.origin("uaa")
.entity(UserEntity.builder()
.id("40bc8ef1-0719-4a0c-9f60-e9f843cd4af2")
.externalId("test-user")
.meta(Meta.builder()
.version(0)
.created("2016-06-16T00:01:41.665Z")
.lastModified("2016-06-16T00:01:41.665Z")
.build())
.userName("40HfKc")
.name(Name.builder()
.familyName("cool-familyName")
.givenName("cool-name")
.build())
.email(Email.builder()
.value("cool@chill.com")
.primary(false)
.build())
.active(true)
.verified(true)
.origin("uaa")
.zoneId("uaa")
.passwordLastModified("2016-06-16T00:01:41.000Z")
.schema("urn:scim:schemas:core:1.0")
.build()
)
.build())
.build())
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
public void listMembersNoEntity() {
mockRequest(InteractionContext.builder()
.request(TestRequest.builder()
.method(GET)
.path("/Groups/f87c557a-8ddc-43d3-98fb-e420ebc7f0f1/members?returnEntities=false")
.build())
.response(TestResponse.builder()
.status(OK)
.payload("fixtures/uaa/groups/GET_members_response_no_entity.json")
.build())
.build());
this.groups
.listMembers(ListMembersRequest.builder()
.groupId("f87c557a-8ddc-43d3-98fb-e420ebc7f0f1")
.returnEntities(false)
.build())
.as(StepVerifier::create)
.expectNext(ListMembersResponse.builder()
.member(Member.builder()
.memberId("40bc8ef1-0719-4a0c-9f60-e9f843cd4af2")
.type(MemberType.USER)
.origin("uaa")
.build())
.build())
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
public void mapExternalGroup() {
mockRequest(InteractionContext.builder()
.request(TestRequest.builder()
.method(POST).path("/Groups/External")
.payload("fixtures/uaa/groups/POST_external_request.json")
.build())
.response(TestResponse.builder()
.status(CREATED)
.payload("fixtures/uaa/groups/POST_external_response.json")
.build())
.build());
this.groups
.mapExternalGroup(MapExternalGroupRequest.builder()
.groupId("76937b62-346c-4848-953c-d790b87ec80a")
.externalGroup("External group")
.build())
.as(StepVerifier::create)
.expectNext(MapExternalGroupResponse.builder()
.groupId("76937b62-346c-4848-953c-d790b87ec80a")
.displayName("Group For Testing Creating External Group Mapping")
.origin("ldap")
.externalGroup("External group")
.metadata(Metadata.builder()
.created("2016-06-16T00:01:41.393Z")
.lastModified("2016-06-16T00:01:41.393Z")
.version(0)
.build())
.schema("urn:scim:schemas:core:1.0")
.build())
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
public void removeMember() {
mockRequest(InteractionContext.builder()
.request(TestRequest.builder()
.method(DELETE).path("/Groups/test-group-id/members/40bc8ef1-0719-4a0c-9f60-e9f843cd4af2")
.build())
.response(TestResponse.builder()
.status(OK)
.payload("fixtures/uaa/groups/DELETE_{id}_members_{id}_response.json")
.build())
.build());
this.groups
.removeMember(RemoveMemberRequest.builder()
.groupId("test-group-id")
.memberId("40bc8ef1-0719-4a0c-9f60-e9f843cd4af2")
.build())
.as(StepVerifier::create)
.expectNext(RemoveMemberResponse.builder()
.memberId("40bc8ef1-0719-4a0c-9f60-e9f843cd4af2")
.type(MemberType.USER)
.origin("uaa")
.build())
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
public void success() {
mockRequest(InteractionContext.builder()
.request(TestRequest.builder()
.method(PUT).path("/Groups/test-group-id")
.header("If-Match", "0")
.header("X-Identity-Zone-Id", "uaa")
.payload("fixtures/uaa/groups/PUT_{id}_request.json")
.build())
.response(TestResponse.builder()
.status(OK)
.payload("fixtures/uaa/groups/PUT_{id}_response.json")
.build())
.build());
this.groups
.update(UpdateGroupRequest.builder()
.identityZoneId("uaa")
.groupId("test-group-id")
.version("0")
.description("the cool group")
.displayName("Cooler Group Name for Update")
.member(MemberSummary.builder()
.origin("uaa")
.type(MemberType.USER)
.memberId("f0e6a061-6e3a-4be9-ace5-142ee24e20b7")
.build())
.build())
.as(StepVerifier::create)
.expectNext(UpdateGroupResponse.builder()
.id("test-group-id")
.metadata(Metadata.builder()
.created("2016-06-03T17:59:30.527Z")
.lastModified("2016-06-03T17:59:30.561Z")
.version(1)
.build())
.description("the cool group")
.displayName("Cooler Group Name for Update")
.member(MemberSummary.builder()
.origin("uaa")
.type(MemberType.USER)
.memberId("f0e6a061-6e3a-4be9-ace5-142ee24e20b7")
.build())
.schema("urn:scim:schemas:core:1.0")
.zoneId("uaa")
.build())
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
public void unmapExternalGroupByGroupDisplayName() {
mockRequest(InteractionContext.builder()
.request(TestRequest.builder()
.method(DELETE).path("/Groups/External/displayName/Group%20For%20Testing%20Deleting%20External%20Group%20Mapping%20By%20Name/externalGroup/external%20group/origin/ldap")
.build())
.response(TestResponse.builder()
.status(OK)
.payload("fixtures/uaa/groups/DELETE_external_displayname_{displayName}_externalgroup_{externalGroup}_origin_{origin}_response.json")
.build())
.build());
this.groups
.unmapExternalGroupByGroupDisplayName(UnmapExternalGroupByGroupDisplayNameRequest.builder()
.groupDisplayName("Group For Testing Deleting External Group Mapping By Name")
.externalGroup("external group")
.origin("ldap")
.build())
.as(StepVerifier::create)
.expectNext(UnmapExternalGroupByGroupDisplayNameResponse.builder()
.groupId("f8f0048f-de32-4d20-b41d-5820b690063d")
.displayName("Group For Testing Deleting External Group Mapping By Name")
.origin("ldap")
.externalGroup("external group")
.metadata(Metadata.builder()
.created("2016-06-16T00:01:41.465Z")
.lastModified("2016-06-16T00:01:41.465Z")
.version(0)
.build())
.schema("urn:scim:schemas:core:1.0")
.build())
.expectComplete()
.verify(Duration.ofSeconds(5));
}
@Test
public void unmapExternalGroupByGroupId() {
mockRequest(InteractionContext.builder()
.request(TestRequest.builder()
.method(DELETE).path("/Groups/External/groupId/d68167b4-81b3-490d-9838-94092d5c89f6/externalGroup/external%20group/origin/ldap")
.build())
.response(TestResponse.builder()
.status(OK)
.payload("fixtures/uaa/groups/DELETE_external_groupid_{groupId}_externalgroup_{externalGroup}_origin_{origin}_response.json")
.build())
.build());
this.groups
.unmapExternalGroupByGroupId(UnmapExternalGroupByGroupIdRequest.builder()
.groupId("d68167b4-81b3-490d-9838-94092d5c89f6")
.externalGroup("external group")
.origin("ldap")
.build())
.as(StepVerifier::create)
.expectNext(UnmapExternalGroupByGroupIdResponse.builder()
.groupId("d68167b4-81b3-490d-9838-94092d5c89f6")
.displayName("Group For Testing Deleting External Group Mapping")
.origin("ldap")
.externalGroup("external group")
.metadata(Metadata.builder()
.created("2016-06-16T00:01:41.223Z")
.lastModified("2016-06-16T00:01:41.223Z")
.version(0)
.build())
.schema("urn:scim:schemas:core:1.0")
.build())
.expectComplete()
.verify(Duration.ofSeconds(5));
}
}