mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-08 14:35:45 +01:00
add the autoComplete link to the index resource
This commit is contained in:
@@ -15,7 +15,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
public class AutoCompleteITCase {
|
public class AutoCompleteITCase {
|
||||||
|
|
||||||
|
|
||||||
public static final String CREATED_USER_PREFIX = "user";
|
public static final String CREATED_USER_PREFIX = "user_";
|
||||||
public static final String CREATED_GROUP_PREFIX = "group_";
|
public static final String CREATED_GROUP_PREFIX = "group_";
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -28,9 +28,10 @@ public class AutoCompleteITCase {
|
|||||||
createUsers();
|
createUsers();
|
||||||
ScmRequests.start()
|
ScmRequests.start()
|
||||||
.given()
|
.given()
|
||||||
.url(TestData.getUsersAutoCompleteUrl("user*"))
|
.requestIndexResource(TestData.USER_SCM_ADMIN,TestData.USER_SCM_ADMIN)
|
||||||
.usernameAndPassword(TestData.USER_SCM_ADMIN, TestData.USER_SCM_ADMIN)
|
.assertStatusCode(200)
|
||||||
.getAutoCompleteResource()
|
.usingIndexResponse()
|
||||||
|
.requestAutoCompleteUsers("user*")
|
||||||
.assertStatusCode(200)
|
.assertStatusCode(200)
|
||||||
.usingAutoCompleteResponse()
|
.usingAutoCompleteResponse()
|
||||||
.assertAutoCompleteResults(assertAutoCompleteResult(CREATED_USER_PREFIX));
|
.assertAutoCompleteResults(assertAutoCompleteResult(CREATED_USER_PREFIX));
|
||||||
@@ -44,9 +45,10 @@ public class AutoCompleteITCase {
|
|||||||
createUsers();
|
createUsers();
|
||||||
ScmRequests.start()
|
ScmRequests.start()
|
||||||
.given()
|
.given()
|
||||||
.url(TestData.getUsersAutoCompleteUrl("user*"))
|
.requestIndexResource(username,password)
|
||||||
.usernameAndPassword(username, password)
|
.assertStatusCode(200)
|
||||||
.getAutoCompleteResource()
|
.usingIndexResponse()
|
||||||
|
.requestAutoCompleteUsers("user*")
|
||||||
.assertStatusCode(200)
|
.assertStatusCode(200)
|
||||||
.usingAutoCompleteResponse()
|
.usingAutoCompleteResponse()
|
||||||
.assertAutoCompleteResults(assertAutoCompleteResult(CREATED_USER_PREFIX));
|
.assertAutoCompleteResults(assertAutoCompleteResult(CREATED_USER_PREFIX));
|
||||||
@@ -57,9 +59,10 @@ public class AutoCompleteITCase {
|
|||||||
createGroups();
|
createGroups();
|
||||||
ScmRequests.start()
|
ScmRequests.start()
|
||||||
.given()
|
.given()
|
||||||
.url(TestData.getGroupsAutoCompleteUrl("group*"))
|
.requestIndexResource(TestData.USER_SCM_ADMIN,TestData.USER_SCM_ADMIN)
|
||||||
.usernameAndPassword(TestData.USER_SCM_ADMIN, TestData.USER_SCM_ADMIN)
|
.assertStatusCode(200)
|
||||||
.getAutoCompleteResource()
|
.usingIndexResponse()
|
||||||
|
.applyAutoCompleteGroups("group*")
|
||||||
.assertStatusCode(200)
|
.assertStatusCode(200)
|
||||||
.usingAutoCompleteResponse()
|
.usingAutoCompleteResponse()
|
||||||
.assertAutoCompleteResults(assertAutoCompleteResult(CREATED_GROUP_PREFIX));
|
.assertAutoCompleteResults(assertAutoCompleteResult(CREATED_GROUP_PREFIX));
|
||||||
@@ -73,9 +76,10 @@ public class AutoCompleteITCase {
|
|||||||
createGroups();
|
createGroups();
|
||||||
ScmRequests.start()
|
ScmRequests.start()
|
||||||
.given()
|
.given()
|
||||||
.url(TestData.getGroupsAutoCompleteUrl("group*"))
|
.requestIndexResource(username,password)
|
||||||
.usernameAndPassword(username, password)
|
.assertStatusCode(200)
|
||||||
.getAutoCompleteResource()
|
.usingIndexResponse()
|
||||||
|
.applyAutoCompleteGroups("group*")
|
||||||
.assertStatusCode(200)
|
.assertStatusCode(200)
|
||||||
.usingAutoCompleteResponse()
|
.usingAutoCompleteResponse()
|
||||||
.assertAutoCompleteResults(assertAutoCompleteResult(CREATED_GROUP_PREFIX));
|
.assertAutoCompleteResults(assertAutoCompleteResult(CREATED_GROUP_PREFIX));
|
||||||
|
|||||||
@@ -46,24 +46,46 @@ public class ScmRequests {
|
|||||||
* @return the response of the GET request using the given link
|
* @return the response of the GET request using the given link
|
||||||
*/
|
*/
|
||||||
private Response applyGETRequestFromLink(Response response, String linkPropertyName) {
|
private Response applyGETRequestFromLink(Response response, String linkPropertyName) {
|
||||||
return applyGETRequest(response
|
return applyGETRequestFromLinkWithParams(response, linkPropertyName, "");
|
||||||
.then()
|
|
||||||
.extract()
|
|
||||||
.path(linkPropertyName));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply a GET Request to the extracted url from the given link
|
||||||
|
*
|
||||||
|
* @param linkPropertyName the property name of link
|
||||||
|
* @param response the response containing the link
|
||||||
|
* @param queryParams query params eg. ?q=xyz&count=12
|
||||||
|
* @return the response of the GET request using the given link
|
||||||
|
*/
|
||||||
|
private Response applyGETRequestFromLinkWithParams(Response response, String linkPropertyName, String queryParams) {
|
||||||
|
return applyGETRequestWithQueryParams(response
|
||||||
|
.then()
|
||||||
|
.extract()
|
||||||
|
.path(linkPropertyName), queryParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply a GET Request to the given <code>url</code> and return the response.
|
||||||
|
*
|
||||||
|
* @param url the url of the GET request
|
||||||
|
* @param htmlQueryParams query params eg. ?q=xyz&count=12
|
||||||
|
* @return the response of the GET request using the given <code>url</code>
|
||||||
|
*/
|
||||||
|
private Response applyGETRequestWithQueryParams(String url, String htmlQueryParams) {
|
||||||
|
return RestAssured.given()
|
||||||
|
.auth().preemptive().basic(username, password)
|
||||||
|
.when()
|
||||||
|
.get(url + htmlQueryParams);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply a GET Request to the given <code>url</code> and return the response.
|
* Apply a GET Request to the given <code>url</code> and return the response.
|
||||||
*
|
*
|
||||||
* @param url the url of the GET request
|
* @param url the url of the GET request
|
||||||
* @return the response of the GET request using the given <code>url</code>
|
* @return the response of the GET request using the given <code>url</code>
|
||||||
*/
|
**/
|
||||||
private Response applyGETRequest(String url) {
|
private Response applyGETRequest(String url) {
|
||||||
return RestAssured.given()
|
return applyGETRequestWithQueryParams(url, "");
|
||||||
.auth().preemptive().basic(username, password)
|
|
||||||
.when()
|
|
||||||
.get(url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -133,6 +155,12 @@ public class ScmRequests {
|
|||||||
return new GivenUrl();
|
return new GivenUrl();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AppliedIndexResource requestIndexResource(String username, String password) {
|
||||||
|
setUsername(username);
|
||||||
|
setPassword(password);
|
||||||
|
return new AppliedIndexResource(applyGETRequest(RestUtil.REST_BASE_URL.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
public GivenUrl url(URI url) {
|
public GivenUrl url(URI url) {
|
||||||
setUrl(url.toString());
|
setUrl(url.toString());
|
||||||
return new GivenUrl();
|
return new GivenUrl();
|
||||||
@@ -480,17 +508,46 @@ public class ScmRequests {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AutoCompleteResponse extends ModelResponse<AutoCompleteResponse>{
|
public class AutoCompleteResponse extends ModelResponse<AutoCompleteResponse> {
|
||||||
|
|
||||||
public AutoCompleteResponse(Response response) {
|
public AutoCompleteResponse(Response response) {
|
||||||
super(response);
|
super(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AutoCompleteResponse assertAutoCompleteResults(Consumer<List<Map>> checker){
|
public AutoCompleteResponse assertAutoCompleteResults(Consumer<List<Map>> checker) {
|
||||||
List<Map> result = response.then().extract().path("");
|
List<Map> result = response.then().extract().path("");
|
||||||
checker.accept(result);
|
checker.accept(result);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class AppliedIndexResource extends AppliedRequest<AppliedIndexResource> {
|
||||||
|
public AppliedIndexResource(Response response) {
|
||||||
|
super(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IndexResponse usingIndexResponse() {
|
||||||
|
return new IndexResponse(super.response);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IndexResponse extends ModelResponse<IndexResponse> {
|
||||||
|
|
||||||
|
public static final String AUTOCOMPLETE_USERS = "_links.autocompleteUsers.href";
|
||||||
|
public static final String AUTOCOMPLETE_GROUPS = "_links.autocompleteGroups.href";
|
||||||
|
|
||||||
|
public IndexResponse(Response response) {
|
||||||
|
super(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AppliedAutoCompleteRequest requestAutoCompleteUsers(String q) {
|
||||||
|
return new AppliedAutoCompleteRequest(applyGETRequestFromLinkWithParams(response, AUTOCOMPLETE_USERS, "?q="+q));
|
||||||
|
}
|
||||||
|
|
||||||
|
public AppliedAutoCompleteRequest applyAutoCompleteGroups(String q) {
|
||||||
|
return new AppliedAutoCompleteRequest(applyGETRequestFromLinkWithParams(response, AUTOCOMPLETE_GROUPS, "?q="+q));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import javax.ws.rs.GET;
|
|||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.QueryParam;
|
import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ public class AutoCompleteResource {
|
|||||||
@ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"user:autocomplete\" privilege"),
|
@ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"user:autocomplete\" privilege"),
|
||||||
@ResponseCode(code = 500, condition = "internal server error")
|
@ResponseCode(code = 500, condition = "internal server error")
|
||||||
})
|
})
|
||||||
public Response searchUser(@NotEmpty(message = PARAMETER_IS_REQUIRED) @Size(min = MIN_SEARCHED_CHARS, message = INVALID_PARAMETER_LENGTH) @QueryParam("q") String filter) {
|
public List<ReducedObjectModelDto> searchUser(@NotEmpty(message = PARAMETER_IS_REQUIRED) @Size(min = MIN_SEARCHED_CHARS, message = INVALID_PARAMETER_LENGTH) @QueryParam("q") String filter) {
|
||||||
return map(userManager.autocomplete(filter));
|
return map(userManager.autocomplete(filter));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,16 +64,15 @@ public class AutoCompleteResource {
|
|||||||
@ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"group:autocomplete\" privilege"),
|
@ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"group:autocomplete\" privilege"),
|
||||||
@ResponseCode(code = 500, condition = "internal server error")
|
@ResponseCode(code = 500, condition = "internal server error")
|
||||||
})
|
})
|
||||||
public Response searchGroup(@NotEmpty(message = PARAMETER_IS_REQUIRED) @Size(min = MIN_SEARCHED_CHARS, message = INVALID_PARAMETER_LENGTH) @QueryParam("q") String filter) {
|
public List<ReducedObjectModelDto> searchGroup(@NotEmpty(message = PARAMETER_IS_REQUIRED) @Size(min = MIN_SEARCHED_CHARS, message = INVALID_PARAMETER_LENGTH) @QueryParam("q") String filter) {
|
||||||
return map(groupManager.autocomplete(filter));
|
return map(groupManager.autocomplete(filter));
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T extends ReducedModelObject> Response map(Collection<T> autocomplete) {
|
private <T extends ReducedModelObject> List<ReducedObjectModelDto> map(Collection<T> autocomplete) {
|
||||||
return Response.ok(autocomplete
|
return autocomplete
|
||||||
.stream()
|
.stream()
|
||||||
.map(mapper::map)
|
.map(mapper::map)
|
||||||
.collect(Collectors.toList()))
|
.collect(Collectors.toList());
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,12 @@ public class IndexDtoGenerator {
|
|||||||
if (UserPermissions.list().isPermitted()) {
|
if (UserPermissions.list().isPermitted()) {
|
||||||
builder.single(link("users", resourceLinks.userCollection().self()));
|
builder.single(link("users", resourceLinks.userCollection().self()));
|
||||||
}
|
}
|
||||||
|
if (UserPermissions.autocomplete().isPermitted()) {
|
||||||
|
builder.single(link("autocompleteUsers", resourceLinks.autoComplete().users()));
|
||||||
|
}
|
||||||
|
if (GroupPermissions.autocomplete().isPermitted()) {
|
||||||
|
builder.single(link("autocompleteGroups", resourceLinks.autoComplete().groups()));
|
||||||
|
}
|
||||||
if (GroupPermissions.list().isPermitted()) {
|
if (GroupPermissions.list().isPermitted()) {
|
||||||
builder.single(link("groups", resourceLinks.groupCollection().self()));
|
builder.single(link("groups", resourceLinks.groupCollection().self()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,6 +142,26 @@ class ResourceLinks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AutoCompleteLinks autoComplete() {
|
||||||
|
return new AutoCompleteLinks (scmPathInfoStore.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
static class AutoCompleteLinks {
|
||||||
|
private final LinkBuilder linkBuilder;
|
||||||
|
|
||||||
|
AutoCompleteLinks (ScmPathInfo pathInfo) {
|
||||||
|
linkBuilder = new LinkBuilder(pathInfo, AutoCompleteResource.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
String users() {
|
||||||
|
return linkBuilder.method("searchUser").parameters().href();
|
||||||
|
}
|
||||||
|
|
||||||
|
String groups() {
|
||||||
|
return linkBuilder.method("searchGroup").parameters().href();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ConfigLinks config() {
|
ConfigLinks config() {
|
||||||
return new ConfigLinks(scmPathInfoStore.get());
|
return new ConfigLinks(scmPathInfoStore.get());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ import sonia.scm.SCMContextProvider;
|
|||||||
import sonia.scm.TransformFilter;
|
import sonia.scm.TransformFilter;
|
||||||
import sonia.scm.search.SearchRequest;
|
import sonia.scm.search.SearchRequest;
|
||||||
import sonia.scm.search.SearchUtil;
|
import sonia.scm.search.SearchUtil;
|
||||||
import sonia.scm.user.UserPermissions;
|
|
||||||
import sonia.scm.util.CollectionAppender;
|
import sonia.scm.util.CollectionAppender;
|
||||||
import sonia.scm.util.Util;
|
import sonia.scm.util.Util;
|
||||||
|
|
||||||
@@ -245,7 +244,7 @@ public class DefaultGroupManager extends AbstractGroupManager
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Group> autocomplete(String filter) {
|
public Collection<Group> autocomplete(String filter) {
|
||||||
UserPermissions.autocomplete().check();
|
GroupPermissions.autocomplete().check();
|
||||||
SearchRequest searchRequest = new SearchRequest(filter, true, DEFAULT_LIMIT);
|
SearchRequest searchRequest = new SearchRequest(filter, true, DEFAULT_LIMIT);
|
||||||
return SearchUtil.search(searchRequest, groupDAO.getAll(), group -> matches(searchRequest,group)?group:null);
|
return SearchUtil.search(searchRequest, groupDAO.getAll(), group -> matches(searchRequest,group)?group:null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import java.util.Optional;
|
|||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@SubjectAware(configuration = "classpath:sonia/scm/shiro-001.ini")
|
@SubjectAware(configuration = "classpath:sonia/scm/shiro-002.ini")
|
||||||
public class IndexResourceTest {
|
public class IndexResourceTest {
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
@@ -94,6 +94,24 @@ public class IndexResourceTest {
|
|||||||
Assertions.assertThat(index.getLinks().getLinkBy("config")).matches(o -> !o.isPresent());
|
Assertions.assertThat(index.getLinks().getLinkBy("config")).matches(o -> !o.isPresent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SubjectAware(username = "trillian", password = "secret")
|
||||||
|
public void shouldRenderAutoCompleteLinks() {
|
||||||
|
IndexDto index = indexResource.getIndex();
|
||||||
|
|
||||||
|
Assertions.assertThat(index.getLinks().getLinkBy("autocompleteUsers")).matches(Optional::isPresent);
|
||||||
|
Assertions.assertThat(index.getLinks().getLinkBy("autocompleteGroups")).matches(Optional::isPresent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SubjectAware(username = "user_without_autocomplete_permission", password = "secret")
|
||||||
|
public void userWithoutAutocompletePermissionShouldNotSeeAutoCompleteLinks() {
|
||||||
|
IndexDto index = indexResource.getIndex();
|
||||||
|
|
||||||
|
Assertions.assertThat(index.getLinks().getLinkBy("autocompleteUsers")).matches(o -> !o.isPresent());
|
||||||
|
Assertions.assertThat(index.getLinks().getLinkBy("autocompleteGroups")).matches(o -> !o.isPresent());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SubjectAware(username = "dent", password = "secret")
|
@SubjectAware(username = "dent", password = "secret")
|
||||||
public void shouldRenderAdminLinksIfAuthorized() {
|
public void shouldRenderAdminLinksIfAuthorized() {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ public class ResourceLinksMock {
|
|||||||
when(resourceLinks.user()).thenReturn(userLinks);
|
when(resourceLinks.user()).thenReturn(userLinks);
|
||||||
when(resourceLinks.me()).thenReturn(new ResourceLinks.MeLinks(uriInfo,userLinks));
|
when(resourceLinks.me()).thenReturn(new ResourceLinks.MeLinks(uriInfo,userLinks));
|
||||||
when(resourceLinks.userCollection()).thenReturn(new ResourceLinks.UserCollectionLinks(uriInfo));
|
when(resourceLinks.userCollection()).thenReturn(new ResourceLinks.UserCollectionLinks(uriInfo));
|
||||||
|
when(resourceLinks.autoComplete()).thenReturn(new ResourceLinks.AutoCompleteLinks(uriInfo));
|
||||||
when(resourceLinks.group()).thenReturn(new ResourceLinks.GroupLinks(uriInfo));
|
when(resourceLinks.group()).thenReturn(new ResourceLinks.GroupLinks(uriInfo));
|
||||||
when(resourceLinks.groupCollection()).thenReturn(new ResourceLinks.GroupCollectionLinks(uriInfo));
|
when(resourceLinks.groupCollection()).thenReturn(new ResourceLinks.GroupCollectionLinks(uriInfo));
|
||||||
when(resourceLinks.repository()).thenReturn(new ResourceLinks.RepositoryLinks(uriInfo));
|
when(resourceLinks.repository()).thenReturn(new ResourceLinks.RepositoryLinks(uriInfo));
|
||||||
|
|||||||
9
scm-webapp/src/test/resources/sonia/scm/shiro-002.ini
Normal file
9
scm-webapp/src/test/resources/sonia/scm/shiro-002.ini
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[users]
|
||||||
|
user_without_autocomplete_permission = secret
|
||||||
|
trillian = secret, user_ac, group_ac
|
||||||
|
dent = secret, admin
|
||||||
|
|
||||||
|
[roles]
|
||||||
|
admin = *
|
||||||
|
user_ac = user:autocomplete
|
||||||
|
group_ac = group:autocomplete
|
||||||
Reference in New Issue
Block a user