mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-14 17:26:22 +01:00
Merge with 2.0.0-m3
This commit is contained in:
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.apache.shiro.subject.support.SubjectThreadState;
|
||||
import org.apache.shiro.util.ThreadContext;
|
||||
import org.apache.shiro.util.ThreadState;
|
||||
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.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;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.Silent.class)
|
||||
public class AutoCompleteResourceTest {
|
||||
|
||||
public static final String URL = "/" + AutoCompleteResource.PATH;
|
||||
private final Integer defaultLimit = Manager.DEFAULT_LIMIT;
|
||||
private Dispatcher dispatcher;
|
||||
|
||||
private final Subject subject = mock(Subject.class);
|
||||
private final ThreadState subjectThreadState = new SubjectThreadState(subject);
|
||||
|
||||
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);
|
||||
subjectThreadState.bind();
|
||||
ThreadContext.bind(subject);
|
||||
when(subject.isPermitted(any(String.class))).thenReturn(true);
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanupContext() {
|
||||
ThreadContext.unbindSubject();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGet400OnFailedParameterForUserSearch() throws Exception {
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.get("/" + AutoCompleteResource.PATH + "user")
|
||||
.contentType(VndMediaType.AUTOCOMPLETE)
|
||||
.accept(VndMediaType.AUTOCOMPLETE);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertEquals(400, response.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGet400IfParameterLengthLessThan2CharsForUserSearch() throws Exception {
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.get("/" + AutoCompleteResource.PATH + "user?filter=a")
|
||||
.contentType(VndMediaType.AUTOCOMPLETE)
|
||||
.accept(VndMediaType.AUTOCOMPLETE);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertEquals(400, response.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
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 + "user?filter=" + 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
|
||||
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 + "user?filter=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
|
||||
public void shouldGet400OnFailedParameterForGroupSearch() throws Exception {
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.get("/" + AutoCompleteResource.PATH + "group")
|
||||
.contentType(VndMediaType.AUTOCOMPLETE)
|
||||
.accept(VndMediaType.AUTOCOMPLETE);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertEquals(400, response.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGet400IfParameterLengthLessThan2CharsForGroupSearch() throws Exception {
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.get("/" + AutoCompleteResource.PATH + "group?filter=a")
|
||||
.contentType(VndMediaType.AUTOCOMPLETE)
|
||||
.accept(VndMediaType.AUTOCOMPLETE);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertEquals(400, response.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
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 + "group?filter=" + 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
|
||||
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 + "group?filter=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);
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
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-001.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 = "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");
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -34,6 +34,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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 ---------------------------------------------------------
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user