merge with 2.0.0-m3

This commit is contained in:
Sebastian Sdorra
2018-10-17 15:54:25 +02:00
161 changed files with 5951 additions and 10483 deletions

View File

@@ -0,0 +1,47 @@
package sonia.scm.api.v2;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Collection;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static java.util.Arrays.asList;
import static org.junit.Assert.assertFalse;
import static sonia.scm.api.v2.ValidationConstraints.USER_GROUP_PATTERN;
@RunWith(Parameterized.class)
public class ValidationConstraints_IllegalCharactersTest {
private static final List<Character> ACCEPTED_CHARS = asList('@', '_', '-', '.');
private final Pattern userGroupPattern=Pattern.compile(USER_GROUP_PATTERN);
private final String expression;
public ValidationConstraints_IllegalCharactersTest(String expression) {
this.expression = expression;
}
@Parameterized.Parameters(name = "{0}")
public static Collection<String[]> createParameters() {
return Stream.concat(IntStream.range(0x20, 0x2f).mapToObj(i -> (char) i), // chars before '0'
Stream.concat(IntStream.range(0x3a, 0x40).mapToObj(i -> (char) i), // chars between '9' and 'A'
Stream.concat(IntStream.range(0x5b, 0x60).mapToObj(i -> (char) i), // chars between 'Z' and 'a'
IntStream.range(0x7b, 0xff).mapToObj(i -> (char) i)))) // chars after 'z'
.filter(c -> !ACCEPTED_CHARS.contains(c))
.flatMap(c -> Stream.of("abc" + c + "xyz", "@" + c, c + "tail"))
.map(c -> new String[] {c})
.collect(Collectors.toList());
}
@Test
public void shouldNotAcceptSpecialCharacters() {
assertFalse(userGroupPattern.matcher(expression).matches());
}
}

View File

@@ -0,0 +1,263 @@
package sonia.scm.api.v2.resources;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.sdorra.shiro.ShiroRule;
import com.github.sdorra.shiro.SubjectAware;
import org.apache.shiro.util.ThreadContext;
import org.assertj.core.util.Lists;
import org.jboss.resteasy.core.Dispatcher;
import org.jboss.resteasy.mock.MockHttpRequest;
import org.jboss.resteasy.mock.MockHttpResponse;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import sonia.scm.Manager;
import sonia.scm.group.DefaultGroupManager;
import sonia.scm.group.Group;
import sonia.scm.group.GroupManager;
import sonia.scm.group.xml.XmlGroupDAO;
import sonia.scm.store.ConfigurationStore;
import sonia.scm.store.ConfigurationStoreFactory;
import sonia.scm.user.DefaultUserManager;
import sonia.scm.user.User;
import sonia.scm.user.UserManager;
import sonia.scm.user.xml.XmlUserDAO;
import sonia.scm.web.VndMediaType;
import sonia.scm.xml.XmlDatabase;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import static sonia.scm.api.v2.resources.DispatcherMock.createDispatcher;
@SubjectAware(configuration = "classpath:sonia/scm/shiro-002.ini")
@RunWith(MockitoJUnitRunner.Silent.class)
public class AutoCompleteResourceTest {
@Rule
public final ShiroRule shiroRule = new ShiroRule();
public static final String URL = "/" + AutoCompleteResource.PATH;
private final Integer defaultLimit = Manager.DEFAULT_LIMIT;
private Dispatcher dispatcher;
private XmlUserDAO userDao;
private XmlGroupDAO groupDao;
private XmlDatabase xmlDB;
private ObjectMapper jsonObjectMapper = new ObjectMapper();
@Before
public void prepareEnvironment() {
initMocks(this);
ConfigurationStoreFactory storeFactory = mock(ConfigurationStoreFactory.class);
ConfigurationStore<Object> storeConfig = mock(ConfigurationStore.class);
xmlDB = mock(XmlDatabase.class);
when(storeConfig.get()).thenReturn(xmlDB);
when(storeFactory.getStore(any(), any())).thenReturn(storeConfig);
XmlUserDAO userDao = new XmlUserDAO(storeFactory);
this.userDao = spy(userDao);
XmlGroupDAO groupDAO = new XmlGroupDAO(storeFactory);
groupDao = spy(groupDAO);
ReducedObjectModelToDtoMapperImpl mapper = new ReducedObjectModelToDtoMapperImpl();
UserManager userManager = new DefaultUserManager(this.userDao);
GroupManager groupManager = new DefaultGroupManager(groupDao);
AutoCompleteResource autoCompleteResource = new AutoCompleteResource(mapper, userManager, groupManager);
dispatcher = createDispatcher(autoCompleteResource);
}
@After
public void cleanupContext() {
ThreadContext.unbindSubject();
}
@Test
public void shouldGet400IfParameterLengthLessThan2CharsForUserSearch() throws Exception {
MockHttpRequest request = MockHttpRequest
.get("/" + AutoCompleteResource.PATH + "users?q=a")
.contentType(VndMediaType.AUTOCOMPLETE)
.accept(VndMediaType.AUTOCOMPLETE);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(400, response.getStatus());
}
@Test
@SubjectAware(username = "trillian", password = "secret")
public void shouldGet400OnFailedParameterForUserSearch() throws Exception {
MockHttpRequest request = MockHttpRequest
.get("/" + AutoCompleteResource.PATH + "users")
.contentType(VndMediaType.AUTOCOMPLETE)
.accept(VndMediaType.AUTOCOMPLETE);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(400, response.getStatus());
}
@Test
@SubjectAware(username = "trillian", password = "secret")
public void shouldSearchUsers() throws Exception {
ArrayList<User> users = Lists.newArrayList(createMockUser("YuCantFindMe", "ha ha"), createMockUser("user1", "User 1"), createMockUser("user2", "User 2"));
String searched = "user";
when(xmlDB.values()).thenReturn(users);
MockHttpRequest request = MockHttpRequest
.get("/" + AutoCompleteResource.PATH + "users?q=" + searched)
.contentType(VndMediaType.AUTOCOMPLETE)
.accept(VndMediaType.AUTOCOMPLETE);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
assertResultSize(response, 2);
assertTrue(response.getContentAsString().contains("\"id\":\"user1\""));
assertTrue(response.getContentAsString().contains("\"displayName\":\"User 1\""));
assertTrue(response.getContentAsString().contains("\"id\":\"user2\""));
assertTrue(response.getContentAsString().contains("\"displayName\":\"User 2\""));
}
@Test
@SubjectAware(username = "user_without_autocomplete_permission", password = "secret")
public void shouldGet403OnAutoCompleteUsers() throws Exception {
MockHttpRequest request = MockHttpRequest
.get("/" + AutoCompleteResource.PATH + "users?q=user" )
.contentType(VndMediaType.AUTOCOMPLETE)
.accept(VndMediaType.AUTOCOMPLETE);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus());
}
@Test
@SubjectAware(username = "trillian", password = "secret")
public void shouldSearchUsersWithDefaultLimitLength() throws Exception {
List<User> userList = IntStream.range(0, 10).boxed().map(i -> createMockUser("user" + i, "User " + i)).collect(Collectors.toList());
when(xmlDB.values()).thenReturn(userList);
MockHttpRequest request = MockHttpRequest
.get("/" + AutoCompleteResource.PATH + "users?q=user")
.contentType(VndMediaType.AUTOCOMPLETE)
.accept(VndMediaType.AUTOCOMPLETE);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
assertResultSize(response, defaultLimit);
}
@Test
@SubjectAware(username = "trillian", password = "secret")
public void shouldGet400OnFailedParameterForGroupSearch() throws Exception {
MockHttpRequest request = MockHttpRequest
.get("/" + AutoCompleteResource.PATH + "groups")
.contentType(VndMediaType.AUTOCOMPLETE)
.accept(VndMediaType.AUTOCOMPLETE);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(400, response.getStatus());
}
@Test
@SubjectAware(username = "trillian", password = "secret")
public void shouldGet400IfParameterLengthLessThan2CharsForGroupSearch() throws Exception {
MockHttpRequest request = MockHttpRequest
.get("/" + AutoCompleteResource.PATH + "groups?q=a")
.contentType(VndMediaType.AUTOCOMPLETE)
.accept(VndMediaType.AUTOCOMPLETE);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(400, response.getStatus());
}
@Test
@SubjectAware(username = "trillian", password = "secret")
public void shouldSearchGroups() throws Exception {
ArrayList<Group> groups = Lists.newArrayList(createMockGroup("YuCantFindMe"), createMockGroup("group_1"), createMockGroup("group_2"));
String searched = "group";
when(xmlDB.values()).thenReturn(groups);
MockHttpRequest request = MockHttpRequest
.get("/" + AutoCompleteResource.PATH + "groups?q=" + searched)
.contentType(VndMediaType.AUTOCOMPLETE)
.accept(VndMediaType.AUTOCOMPLETE);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
assertResultSize(response, 2);
assertTrue(response.getContentAsString().contains("\"id\":\"group_1\""));
assertTrue(response.getContentAsString().contains("\"displayName\":\"group_1\""));
assertTrue(response.getContentAsString().contains("\"id\":\"group_2\""));
assertTrue(response.getContentAsString().contains("\"displayName\":\"group_2\""));
}
@Test
@SubjectAware(username = "user_without_autocomplete_permission", password = "secret")
public void shouldGet403OnAutoCompleteGroups() throws Exception {
MockHttpRequest request = MockHttpRequest
.get("/" + AutoCompleteResource.PATH + "groups?q=user" )
.contentType(VndMediaType.AUTOCOMPLETE)
.accept(VndMediaType.AUTOCOMPLETE);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus());
}
@Test
@SubjectAware(username = "trillian", password = "secret")
public void shouldSearchGroupsWithDefaultLimitLength() throws Exception {
List<Group> groups = IntStream.range(0, 10).boxed().map(i -> createMockGroup("group_" + i)).collect(Collectors.toList());
when(xmlDB.values()).thenReturn(groups);
MockHttpRequest request = MockHttpRequest
.get("/" + AutoCompleteResource.PATH + "groups?q=group")
.contentType(VndMediaType.AUTOCOMPLETE)
.accept(VndMediaType.AUTOCOMPLETE);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
assertResultSize(response, defaultLimit);
}
private User createMockUser(String id, String name) {
return new User(id, name, "em@l.de");
}
private Group createMockGroup(String name) {
Group group = new Group("type", name);
group.setDescription(name);
return group;
}
private void assertResultSize(MockHttpResponse response, int size) throws java.io.IOException {
ReducedObjectModelDto[] reducedObjectModelDtos = jsonObjectMapper.readValue(response.getContentAsString(), ReducedObjectModelDto[].class);
assertEquals(reducedObjectModelDtos.length, size);
}
}

View File

@@ -0,0 +1,61 @@
package sonia.scm.api.v2.resources;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import sonia.scm.PageResult;
import sonia.scm.repository.Changeset;
import sonia.scm.repository.Repository;
import java.net.URI;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class ChangesetCollectionToDtoMapperTest {
public static final Repository REPOSITORY = new Repository("", "git", "space", "name");
public static final Changeset CHANGESET = new Changeset();
private final ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper = mock(ChangesetToChangesetDtoMapper.class);
private final ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper = new ChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, ResourceLinksMock.createMock(URI.create("/")));
@Test
public void shouldMapCollectionEntries() {
ChangesetDto expectedChangesetDto = new ChangesetDto();
when(changesetToChangesetDtoMapper.map(CHANGESET, REPOSITORY)).thenReturn(expectedChangesetDto);
CollectionDto collectionDto = changesetCollectionToDtoMapper.map(0, 1, new PageResult<>(asList(CHANGESET), 1), REPOSITORY);
assertThat(collectionDto.getEmbedded().hasItem("changesets")).isTrue();
assertThat(collectionDto.getEmbedded().getItemsBy("changesets")).containsExactly(expectedChangesetDto);
assertThat(collectionDto.getEmbedded().hasItem("branch")).isFalse();
}
@Test
public void shouldNotEmbedBranchIfNotSpecified() {
ChangesetDto expectedChangesetDto = new ChangesetDto();
when(changesetToChangesetDtoMapper.map(CHANGESET, REPOSITORY)).thenReturn(expectedChangesetDto);
CollectionDto collectionDto = changesetCollectionToDtoMapper.map(0, 1, new PageResult<>(asList(CHANGESET), 1), REPOSITORY);
assertThat(collectionDto.getEmbedded().hasItem("branch")).isFalse();
}
@Test
public void shouldEmbedBranchIfSpecified() {
ChangesetDto expectedChangesetDto = new ChangesetDto();
when(changesetToChangesetDtoMapper.map(CHANGESET, REPOSITORY)).thenReturn(expectedChangesetDto);
CollectionDto collectionDto = changesetCollectionToDtoMapper.map(0, 1, new PageResult<>(asList(CHANGESET), 1), REPOSITORY, "someBranch");
assertThat(collectionDto.getEmbedded().hasItem("branch")).isTrue();
assertThat(collectionDto.getEmbedded().getItemsBy("branch"))
.hasSize(1)
.first().matches(b -> b.getLinks().getLinkBy("self").isPresent())
.extracting(b -> b.getLinks().getLinkBy("self").get().getHref()).first().isEqualTo("/v2/repositories/space/name/branches/someBranch");
assertThat(collectionDto.getEmbedded().getItemsBy("branch"))
.first().extracting("name").first().isEqualTo("someBranch");
}
}

View File

@@ -224,6 +224,64 @@ public class GroupRootResourceTest {
assertEquals("user1", createdGroup.getMembers().get(0));
}
@Test
public void shouldGet400OnCreatingNewGroupWithNotAllowedCharacters() throws URISyntaxException {
// the @ character at the begin of the name is not allowed
String groupJson = "{ \"name\": \"@grpname\", \"type\": \"admin\" }";
MockHttpRequest request = MockHttpRequest
.post("/" + GroupRootResource.GROUPS_PATH_V2)
.contentType(VndMediaType.GROUP)
.content(groupJson.getBytes());
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(400, response.getStatus());
// the whitespace at the begin of the name is not allowed
groupJson = "{ \"name\": \" grpname\", \"type\": \"admin\" }";
request = MockHttpRequest
.post("/" + GroupRootResource.GROUPS_PATH_V2)
.contentType(VndMediaType.GROUP)
.content(groupJson.getBytes());
dispatcher.invoke(request, response);
assertEquals(400, response.getStatus());
// the characters {[ are not allowed
groupJson = "{ \"name\": \"grp{name}\", \"type\": \"admin\" }";
request = MockHttpRequest
.post("/" + GroupRootResource.GROUPS_PATH_V2)
.contentType(VndMediaType.GROUP)
.content(groupJson.getBytes());
dispatcher.invoke(request, response);
assertEquals(400, response.getStatus());
groupJson = "{ \"name\": \"grp[name]\", \"type\": \"admin\" }";
request = MockHttpRequest
.post("/" + GroupRootResource.GROUPS_PATH_V2)
.contentType(VndMediaType.GROUP)
.content(groupJson.getBytes());
dispatcher.invoke(request, response);
assertEquals(400, response.getStatus());
groupJson = "{ \"name\": \"grp/name\", \"type\": \"admin\" }";
request = MockHttpRequest
.post("/" + GroupRootResource.GROUPS_PATH_V2)
.contentType(VndMediaType.GROUP)
.content(groupJson.getBytes());
dispatcher.invoke(request, response);
assertEquals(400, response.getStatus());
}
@Test
public void shouldFailForMissingContent() throws URISyntaxException {
MockHttpRequest request = MockHttpRequest

View File

@@ -0,0 +1,135 @@
package sonia.scm.api.v2.resources;
import com.github.sdorra.shiro.ShiroRule;
import com.github.sdorra.shiro.SubjectAware;
import org.assertj.core.api.Assertions;
import org.junit.Rule;
import org.junit.Test;
import sonia.scm.SCMContextProvider;
import java.net.URI;
import java.util.Optional;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@SubjectAware(configuration = "classpath:sonia/scm/shiro-002.ini")
public class IndexResourceTest {
@Rule
public final ShiroRule shiroRule = new ShiroRule();
private final SCMContextProvider scmContextProvider = mock(SCMContextProvider.class);
private final IndexDtoGenerator indexDtoGenerator = new IndexDtoGenerator(ResourceLinksMock.createMock(URI.create("/")), scmContextProvider);
private final IndexResource indexResource = new IndexResource(indexDtoGenerator);
@Test
public void shouldRenderLoginUrlsForUnauthenticatedRequest() {
IndexDto index = indexResource.getIndex();
Assertions.assertThat(index.getLinks().getLinkBy("login")).matches(Optional::isPresent);
}
@Test
public void shouldRenderSelfLinkForUnauthenticatedRequest() {
IndexDto index = indexResource.getIndex();
Assertions.assertThat(index.getLinks().getLinkBy("self")).matches(Optional::isPresent);
}
@Test
public void shouldRenderUiPluginsLinkForUnauthenticatedRequest() {
IndexDto index = indexResource.getIndex();
Assertions.assertThat(index.getLinks().getLinkBy("uiPlugins")).matches(Optional::isPresent);
}
@Test
@SubjectAware(username = "trillian", password = "secret")
public void shouldRenderSelfLinkForAuthenticatedRequest() {
IndexDto index = indexResource.getIndex();
Assertions.assertThat(index.getLinks().getLinkBy("self")).matches(Optional::isPresent);
}
@Test
@SubjectAware(username = "trillian", password = "secret")
public void shouldRenderUiPluginsLinkForAuthenticatedRequest() {
IndexDto index = indexResource.getIndex();
Assertions.assertThat(index.getLinks().getLinkBy("uiPlugins")).matches(Optional::isPresent);
}
@Test
@SubjectAware(username = "trillian", password = "secret")
public void shouldRenderMeUrlForAuthenticatedRequest() {
IndexDto index = indexResource.getIndex();
Assertions.assertThat(index.getLinks().getLinkBy("me")).matches(Optional::isPresent);
}
@Test
@SubjectAware(username = "trillian", password = "secret")
public void shouldRenderLogoutUrlForAuthenticatedRequest() {
IndexDto index = indexResource.getIndex();
Assertions.assertThat(index.getLinks().getLinkBy("logout")).matches(Optional::isPresent);
}
@Test
@SubjectAware(username = "trillian", password = "secret")
public void shouldRenderRepositoriesForAuthenticatedRequest() {
IndexDto index = indexResource.getIndex();
Assertions.assertThat(index.getLinks().getLinkBy("repositories")).matches(Optional::isPresent);
}
@Test
@SubjectAware(username = "trillian", password = "secret")
public void shouldNotRenderAdminLinksIfNotAuthorized() {
IndexDto index = indexResource.getIndex();
Assertions.assertThat(index.getLinks().getLinkBy("users")).matches(o -> !o.isPresent());
Assertions.assertThat(index.getLinks().getLinkBy("groups")).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().getLinksBy("autocomplete"))
.extracting("name")
.containsExactlyInAnyOrder("users", "groups");
}
@Test
@SubjectAware(username = "user_without_autocomplete_permission", password = "secret")
public void userWithoutAutocompletePermissionShouldNotSeeAutoCompleteLinks() {
IndexDto index = indexResource.getIndex();
Assertions.assertThat(index.getLinks().getLinksBy("autocomplete"))
.extracting("name")
.doesNotContainSequence("users", "groups");
}
@Test
@SubjectAware(username = "dent", password = "secret")
public void shouldRenderAdminLinksIfAuthorized() {
IndexDto index = indexResource.getIndex();
Assertions.assertThat(index.getLinks().getLinkBy("users")).matches(Optional::isPresent);
Assertions.assertThat(index.getLinks().getLinkBy("groups")).matches(Optional::isPresent);
Assertions.assertThat(index.getLinks().getLinkBy("config")).matches(Optional::isPresent);
}
@Test
public void shouldGenerateVersion() {
when(scmContextProvider.getVersion()).thenReturn("v1");
IndexDto index = indexResource.getIndex();
Assertions.assertThat(index.getVersion()).isEqualTo("v1");
}
}

View File

@@ -48,6 +48,7 @@ import java.util.stream.Stream;
import static de.otto.edison.hal.Link.link;
import static de.otto.edison.hal.Links.linkingTo;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.junit.jupiter.api.DynamicTest.dynamicTest;
import static org.mockito.Matchers.any;
@@ -233,6 +234,35 @@ public class PermissionRootResourceTest extends RepositoryTestBase {
);
}
@Test
public void shouldGet400OnCreatingNewPermissionWithNotAllowedCharacters() throws URISyntaxException {
// the @ character at the begin of the name is not allowed
createUserWithRepository("user");
String permissionJson = "{ \"name\": \"@permission\", \"type\": \"OWNER\" }";
MockHttpRequest request = MockHttpRequest
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + PATH_OF_ALL_PERMISSIONS)
.content(permissionJson.getBytes())
.contentType(VndMediaType.PERMISSION);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(400, response.getStatus());
// the whitespace at the begin opf the name is not allowed
permissionJson = "{ \"name\": \" permission\", \"type\": \"OWNER\" }";
request = MockHttpRequest
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + PATH_OF_ALL_PERMISSIONS)
.content(permissionJson.getBytes())
.contentType(VndMediaType.PERMISSION);
response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(400, response.getStatus());
}
@Test
public void shouldGetCreatedPermissions() throws URISyntaxException {
createUserWithRepositoryAndPermissions(TEST_PERMISSIONS, PERMISSION_WRITE);

View File

@@ -16,6 +16,7 @@ public class ResourceLinksMock {
when(resourceLinks.user()).thenReturn(userLinks);
when(resourceLinks.me()).thenReturn(new ResourceLinks.MeLinks(uriInfo,userLinks));
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.groupCollection()).thenReturn(new ResourceLinks.GroupCollectionLinks(uriInfo));
when(resourceLinks.repository()).thenReturn(new ResourceLinks.RepositoryLinks(uriInfo));
@@ -34,6 +35,8 @@ public class ResourceLinksMock {
when(resourceLinks.repositoryTypeCollection()).thenReturn(new ResourceLinks.RepositoryTypeCollectionLinks(uriInfo));
when(resourceLinks.uiPluginCollection()).thenReturn(new ResourceLinks.UIPluginCollectionLinks(uriInfo));
when(resourceLinks.uiPlugin()).thenReturn(new ResourceLinks.UIPluginLinks(uriInfo));
when(resourceLinks.authentication()).thenReturn(new ResourceLinks.AuthenticationLinks(uriInfo));
when(resourceLinks.index()).thenReturn(new ResourceLinks.IndexLinks(uriInfo));
return resourceLinks;
}

View File

@@ -23,7 +23,6 @@ import javax.servlet.http.HttpServletResponse;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.text.MessageFormat;
import static java.util.Collections.singletonList;
import static org.junit.Assert.assertEquals;
@@ -98,6 +97,32 @@ public class UserRootResourceTest {
assertTrue(response.getContentAsString().contains("\"delete\":{\"href\":\"/v2/users/Neo\"}"));
}
@Test
public void shouldGet400OnCreatingNewUserWithNotAllowedCharacters() throws URISyntaxException {
// the @ character at the begin of the name is not allowed
String userJson = "{ \"name\": \"@user\", \"type\": \"db\" }";
MockHttpRequest request = MockHttpRequest
.post("/" + UserRootResource.USERS_PATH_V2)
.contentType(VndMediaType.USER)
.content(userJson.getBytes());
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(400, response.getStatus());
// the whitespace at the begin opf the name is not allowed
userJson = "{ \"name\": \" user\", \"type\": \"db\" }";
request = MockHttpRequest
.post("/" + UserRootResource.USERS_PATH_V2)
.contentType(VndMediaType.USER)
.content(userJson.getBytes());
dispatcher.invoke(request, response);
assertEquals(400, response.getStatus());
}
@Test
@SubjectAware(username = "unpriv")
public void shouldCreateLimitedResponseForSimpleUser() throws URISyntaxException {

View File

@@ -107,7 +107,7 @@ public class SecurityFilterTest {
*/
@Test
public void testDoOnAuthenticationUrlV1() throws IOException, ServletException {
checkIfAuthenticationUrlIsPassedThrough("/scm/api/rest/auth/access_token");
checkIfAuthenticationUrlIsPassedThrough("/scm/api/auth/access_token");
}
/**
@@ -118,7 +118,7 @@ public class SecurityFilterTest {
*/
@Test
public void testDoOnAuthenticationUrlV2() throws IOException, ServletException {
checkIfAuthenticationUrlIsPassedThrough("/scm/api/rest/v2/auth/access_token");
checkIfAuthenticationUrlIsPassedThrough("/scm/api/v2/auth/access_token");
}
private void checkIfAuthenticationUrlIsPassedThrough(String uri) throws IOException, ServletException {

View File

@@ -78,7 +78,7 @@ public final class IntegrationTestUtil
public static final String BASE_URL = "http://localhost:8081/scm/";
/** scm-manager base url for the rest api */
public static final String REST_BASE_URL = BASE_URL.concat("api/rest/v2/");
public static final String REST_BASE_URL = BASE_URL.concat("api/v2/");
//~--- constructors ---------------------------------------------------------

View File

@@ -37,6 +37,7 @@ package sonia.scm.it;
import com.sun.jersey.api.client.ClientResponse;
import de.otto.edison.hal.HalRepresentation;
import org.junit.Assume;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import sonia.scm.api.rest.ObjectMapperProvider;
@@ -158,6 +159,7 @@ public class UserPermissionITCase extends AbstractPermissionITCaseBase<User>
@Override
protected void checkGetAllResponse(ClientResponse response)
{
Assume.assumeTrue(credentials.getUsername() == null);
if (!credentials.isAnonymous())
{
assertNotNull(response);

View File

@@ -57,6 +57,7 @@ import sonia.scm.repository.RepositoryTestData;
import sonia.scm.user.User;
import sonia.scm.user.UserTestData;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.nullValue;
@@ -160,7 +161,8 @@ public class DefaultAuthorizationCollectorTest {
AuthorizationInfo authInfo = collector.collect();
assertThat(authInfo.getRoles(), Matchers.contains(Role.USER));
assertThat(authInfo.getStringPermissions(), hasSize(0));
assertThat(authInfo.getStringPermissions(), hasSize(3));
assertThat(authInfo.getStringPermissions(), containsInAnyOrder("user:autocomplete", "group:autocomplete", "user:read:trillian"));
assertThat(authInfo.getObjectPermissions(), nullValue());
}
@@ -207,7 +209,7 @@ public class DefaultAuthorizationCollectorTest {
AuthorizationInfo authInfo = collector.collect();
assertThat(authInfo.getRoles(), Matchers.containsInAnyOrder(Role.USER));
assertThat(authInfo.getObjectPermissions(), nullValue());
assertThat(authInfo.getStringPermissions(), containsInAnyOrder("repository:read,pull:one", "repository:read,pull,push:two"));
assertThat(authInfo.getStringPermissions(), containsInAnyOrder("user:autocomplete", "group:autocomplete", "repository:read,pull:one", "repository:read,pull,push:two", "user:read:trillian"));
}
/**
@@ -228,7 +230,7 @@ public class DefaultAuthorizationCollectorTest {
AuthorizationInfo authInfo = collector.collect();
assertThat(authInfo.getRoles(), Matchers.containsInAnyOrder(Role.USER));
assertThat(authInfo.getObjectPermissions(), nullValue());
assertThat(authInfo.getStringPermissions(), containsInAnyOrder("one:one", "two:two"));
assertThat(authInfo.getStringPermissions(), containsInAnyOrder("one:one", "two:two", "user:read:trillian", "user:autocomplete" , "group:autocomplete" ));
}
private void authenticate(User user, String group, String... groups) {

View File

@@ -21,7 +21,7 @@ public class SecurityRequestsTest {
@Test
public void testIsAuthenticationRequestWithContextPath() {
when(request.getRequestURI()).thenReturn("/scm/api/rest/auth/access_token");
when(request.getRequestURI()).thenReturn("/scm/api/auth/access_token");
when(request.getContextPath()).thenReturn("/scm");
assertTrue(SecurityRequests.isAuthenticationRequest(request));
@@ -29,9 +29,9 @@ public class SecurityRequestsTest {
@Test
public void testIsAuthenticationRequest() throws Exception {
assertTrue(SecurityRequests.isAuthenticationRequest("/api/rest/auth/access_token"));
assertTrue(SecurityRequests.isAuthenticationRequest("/api/rest/v2/auth/access_token"));
assertFalse(SecurityRequests.isAuthenticationRequest("/api/rest/repositories"));
assertFalse(SecurityRequests.isAuthenticationRequest("/api/rest/v2/repositories"));
assertTrue(SecurityRequests.isAuthenticationRequest("/api/auth/access_token"));
assertTrue(SecurityRequests.isAuthenticationRequest("/api/v2/auth/access_token"));
assertFalse(SecurityRequests.isAuthenticationRequest("/api/repositories"));
assertFalse(SecurityRequests.isAuthenticationRequest("/api/v2/repositories"));
}
}