mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-15 09:46:16 +01:00
merge + refactoring
This commit is contained in:
@@ -50,6 +50,8 @@ import javax.xml.bind.annotation.XmlAccessorType;
|
|||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
|
|
||||||
|
import static sonia.scm.user.InvalidPasswordException.INVALID_MATCHING;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -278,6 +280,21 @@ public class User extends BasicPropertiesAware implements Principal, ModelObject
|
|||||||
setPassword(password);
|
setPassword(password);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Match given old password from the dto with the stored password before updating
|
||||||
|
*
|
||||||
|
* @param newPassword the new password
|
||||||
|
* @param oldPassword the old password
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public User changePassword(String newPassword, String oldPassword){
|
||||||
|
if (!getPassword().equals(oldPassword)) {
|
||||||
|
throw new InvalidPasswordException(INVALID_MATCHING);
|
||||||
|
}
|
||||||
|
setPassword(newPassword);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
//~--- get methods ----------------------------------------------------------
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -75,23 +75,6 @@ public interface UserManager
|
|||||||
*/
|
*/
|
||||||
public String getDefaultType();
|
public String getDefaultType();
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a user can modify the password
|
|
||||||
*
|
|
||||||
* 1 - the permission changeOwnPassword should be checked
|
|
||||||
* 2 - Only account of the default type "xml" can change their password
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
default Consumer<User> getChangePasswordChecker() {
|
|
||||||
return user -> {
|
|
||||||
UserPermissions.changeOwnPassword().check();
|
|
||||||
if (!isTypeDefault(user)) {
|
|
||||||
throw new ChangePasswordNotAllowedException(MessageFormat.format(WRONG_USER_TYPE, user.getType()));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean isTypeDefault(User user) {
|
default boolean isTypeDefault(User user) {
|
||||||
return getDefaultType().equals(user.getType());
|
return getDefaultType().equals(user.getType());
|
||||||
}
|
}
|
||||||
|
|||||||
73
scm-it/src/test/java/sonia/scm/it/AutoCompleteITCase.java
Normal file
73
scm-it/src/test/java/sonia/scm/it/AutoCompleteITCase.java
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
package sonia.scm.it;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import sonia.scm.it.utils.ScmRequests;
|
||||||
|
import sonia.scm.it.utils.TestData;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class AutoCompleteITCase {
|
||||||
|
|
||||||
|
|
||||||
|
public static final String CREATED_USER_PREFIX = "user_";
|
||||||
|
public static final String CREATED_GROUP_PREFIX = "group_";
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
TestData.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void adminShouldAutoComplete() {
|
||||||
|
shouldAutocomplete(TestData.USER_SCM_ADMIN, TestData.USER_SCM_ADMIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void userShouldAutoComplete() {
|
||||||
|
String username = "nonAdmin";
|
||||||
|
String password = "pass";
|
||||||
|
TestData.createUser(username, password, false, "xml", "email@e.de");
|
||||||
|
shouldAutocomplete(username, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shouldAutocomplete(String username, String password) {
|
||||||
|
createUsers();
|
||||||
|
createGroups();
|
||||||
|
ScmRequests.start()
|
||||||
|
.requestIndexResource(username, password)
|
||||||
|
.assertStatusCode(200)
|
||||||
|
.requestAutoCompleteGroups("group*")
|
||||||
|
.assertStatusCode(200)
|
||||||
|
.assertAutoCompleteResults(assertAutoCompleteResult(CREATED_GROUP_PREFIX))
|
||||||
|
.returnToPrevious()
|
||||||
|
.requestAutoCompleteUsers("user*")
|
||||||
|
.assertStatusCode(200)
|
||||||
|
.assertAutoCompleteResults(assertAutoCompleteResult(CREATED_USER_PREFIX));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private Consumer<List<Map>> assertAutoCompleteResult(String id) {
|
||||||
|
return autoCompleteDtos -> {
|
||||||
|
IntStream.range(0, 5).forEach(i -> {
|
||||||
|
assertThat(autoCompleteDtos).as("return maximum 5 entries").hasSize(5);
|
||||||
|
assertThat(autoCompleteDtos.get(i)).containsEntry("id", id + (i + 1));
|
||||||
|
assertThat(autoCompleteDtos.get(i)).containsEntry("displayName", id + (i + 1));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createUsers() {
|
||||||
|
IntStream.range(0, 6).forEach(i -> TestData.createUser(CREATED_USER_PREFIX + (i + 1), "pass", false, "xml", CREATED_USER_PREFIX + (i + 1) + "@scm-manager.org"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createGroups() {
|
||||||
|
IntStream.range(0, 6).forEach(i -> TestData.createGroup(CREATED_GROUP_PREFIX + (i + 1), CREATED_GROUP_PREFIX + (i + 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -20,12 +20,9 @@ public class MeITCase {
|
|||||||
String newPassword = TestData.USER_SCM_ADMIN + "1";
|
String newPassword = TestData.USER_SCM_ADMIN + "1";
|
||||||
// admin change the own password
|
// admin change the own password
|
||||||
ScmRequests.start()
|
ScmRequests.start()
|
||||||
.given()
|
.requestIndexResource(TestData.USER_SCM_ADMIN, TestData.USER_SCM_ADMIN)
|
||||||
.url(TestData.getMeUrl())
|
.requestMe()
|
||||||
.usernameAndPassword(TestData.USER_SCM_ADMIN, TestData.USER_SCM_ADMIN)
|
|
||||||
.getMeResource()
|
|
||||||
.assertStatusCode(200)
|
.assertStatusCode(200)
|
||||||
.usingMeResponse()
|
|
||||||
.assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE))
|
.assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE))
|
||||||
.assertPassword(Assert::assertNull)
|
.assertPassword(Assert::assertNull)
|
||||||
.assertType(s -> assertThat(s).isEqualTo("xml"))
|
.assertType(s -> assertThat(s).isEqualTo("xml"))
|
||||||
@@ -33,12 +30,9 @@ public class MeITCase {
|
|||||||
.assertStatusCode(204);
|
.assertStatusCode(204);
|
||||||
// assert password is changed -> login with the new Password than undo changes
|
// assert password is changed -> login with the new Password than undo changes
|
||||||
ScmRequests.start()
|
ScmRequests.start()
|
||||||
.given()
|
.requestIndexResource(TestData.USER_SCM_ADMIN, newPassword)
|
||||||
.url(TestData.getUserUrl(TestData.USER_SCM_ADMIN))
|
.requestMe()
|
||||||
.usernameAndPassword(TestData.USER_SCM_ADMIN, newPassword)
|
|
||||||
.getMeResource()
|
|
||||||
.assertStatusCode(200)
|
.assertStatusCode(200)
|
||||||
.usingMeResponse()
|
|
||||||
.assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE))// still admin
|
.assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE))// still admin
|
||||||
.requestChangePassword(newPassword, TestData.USER_SCM_ADMIN)
|
.requestChangePassword(newPassword, TestData.USER_SCM_ADMIN)
|
||||||
.assertStatusCode(204);
|
.assertStatusCode(204);
|
||||||
@@ -49,15 +43,12 @@ public class MeITCase {
|
|||||||
String newPassword = "pass1";
|
String newPassword = "pass1";
|
||||||
String username = "user1";
|
String username = "user1";
|
||||||
String password = "pass";
|
String password = "pass";
|
||||||
TestData.createUser(username, password,false,"xml");
|
TestData.createUser(username, password,false,"xml", "em@l.de");
|
||||||
// user change the own password
|
// user change the own password
|
||||||
ScmRequests.start()
|
ScmRequests.start()
|
||||||
.given()
|
.requestIndexResource(username, password)
|
||||||
.url(TestData.getMeUrl())
|
.requestMe()
|
||||||
.usernameAndPassword(username, password)
|
|
||||||
.getMeResource()
|
|
||||||
.assertStatusCode(200)
|
.assertStatusCode(200)
|
||||||
.usingMeResponse()
|
|
||||||
.assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.FALSE))
|
.assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.FALSE))
|
||||||
.assertPassword(Assert::assertNull)
|
.assertPassword(Assert::assertNull)
|
||||||
.assertType(s -> assertThat(s).isEqualTo("xml"))
|
.assertType(s -> assertThat(s).isEqualTo("xml"))
|
||||||
@@ -65,10 +56,8 @@ public class MeITCase {
|
|||||||
.assertStatusCode(204);
|
.assertStatusCode(204);
|
||||||
// assert password is changed -> login with the new Password than undo changes
|
// assert password is changed -> login with the new Password than undo changes
|
||||||
ScmRequests.start()
|
ScmRequests.start()
|
||||||
.given()
|
.requestIndexResource(username, newPassword)
|
||||||
.url(TestData.getMeUrl())
|
.requestMe()
|
||||||
.usernameAndPassword(username, newPassword)
|
|
||||||
.getMeResource()
|
|
||||||
.assertStatusCode(200);
|
.assertStatusCode(200);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -78,14 +67,11 @@ public class MeITCase {
|
|||||||
String newUser = "user";
|
String newUser = "user";
|
||||||
String password = "pass";
|
String password = "pass";
|
||||||
String type = "not XML Type";
|
String type = "not XML Type";
|
||||||
TestData.createUser(newUser, password, true, type);
|
TestData.createUser(newUser, password, true, type, "user@scm-manager.org");
|
||||||
ScmRequests.start()
|
ScmRequests.start()
|
||||||
.given()
|
.requestIndexResource(newUser, password)
|
||||||
.url(TestData.getMeUrl())
|
.requestMe()
|
||||||
.usernameAndPassword(newUser, password)
|
|
||||||
.getMeResource()
|
|
||||||
.assertStatusCode(200)
|
.assertStatusCode(200)
|
||||||
.usingMeResponse()
|
|
||||||
.assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE))
|
.assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE))
|
||||||
.assertPassword(Assert::assertNull)
|
.assertPassword(Assert::assertNull)
|
||||||
.assertType(s -> assertThat(s).isEqualTo(type))
|
.assertType(s -> assertThat(s).isEqualTo(type))
|
||||||
|
|||||||
@@ -87,13 +87,13 @@ public class PermissionsITCase {
|
|||||||
@Before
|
@Before
|
||||||
public void prepareEnvironment() {
|
public void prepareEnvironment() {
|
||||||
TestData.createDefault();
|
TestData.createDefault();
|
||||||
TestData.createUser(USER_READ, USER_PASS);
|
TestData.createNotAdminUser(USER_READ, USER_PASS);
|
||||||
TestData.createUserPermission(USER_READ, PermissionType.READ, repositoryType);
|
TestData.createUserPermission(USER_READ, PermissionType.READ, repositoryType);
|
||||||
TestData.createUser(USER_WRITE, USER_PASS);
|
TestData.createNotAdminUser(USER_WRITE, USER_PASS);
|
||||||
TestData.createUserPermission(USER_WRITE, PermissionType.WRITE, repositoryType);
|
TestData.createUserPermission(USER_WRITE, PermissionType.WRITE, repositoryType);
|
||||||
TestData.createUser(USER_OWNER, USER_PASS);
|
TestData.createNotAdminUser(USER_OWNER, USER_PASS);
|
||||||
TestData.createUserPermission(USER_OWNER, PermissionType.OWNER, repositoryType);
|
TestData.createUserPermission(USER_OWNER, PermissionType.OWNER, repositoryType);
|
||||||
TestData.createUser(USER_OTHER, USER_PASS);
|
TestData.createNotAdminUser(USER_OTHER, USER_PASS);
|
||||||
createdPermissions = 3;
|
createdPermissions = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class RepositoryAccessITCase {
|
|||||||
|
|
||||||
private final String repositoryType;
|
private final String repositoryType;
|
||||||
private File folder;
|
private File folder;
|
||||||
private ScmRequests.AppliedRepositoryRequest repositoryGetRequest;
|
private ScmRequests.RepositoryResponse<ScmRequests.IndexResponse> repositoryResponse;
|
||||||
|
|
||||||
public RepositoryAccessITCase(String repositoryType) {
|
public RepositoryAccessITCase(String repositoryType) {
|
||||||
this.repositoryType = repositoryType;
|
this.repositoryType = repositoryType;
|
||||||
@@ -59,17 +59,13 @@ public class RepositoryAccessITCase {
|
|||||||
public void init() {
|
public void init() {
|
||||||
TestData.createDefault();
|
TestData.createDefault();
|
||||||
folder = tempFolder.getRoot();
|
folder = tempFolder.getRoot();
|
||||||
repositoryGetRequest = ScmRequests.start()
|
String namespace = ADMIN_USERNAME;
|
||||||
.given()
|
String repo = TestData.getDefaultRepoName(repositoryType);
|
||||||
.url(TestData.getDefaultRepositoryUrl(repositoryType))
|
repositoryResponse =
|
||||||
.usernameAndPassword(ADMIN_USERNAME, ADMIN_PASSWORD)
|
ScmRequests.start()
|
||||||
.getRepositoryResource()
|
.requestIndexResource(ADMIN_USERNAME, ADMIN_PASSWORD)
|
||||||
|
.requestRepository(namespace, repo)
|
||||||
.assertStatusCode(HttpStatus.SC_OK);
|
.assertStatusCode(HttpStatus.SC_OK);
|
||||||
ScmRequests.AppliedMeRequest meGetRequest = ScmRequests.start()
|
|
||||||
.given()
|
|
||||||
.url(TestData.getMeUrl())
|
|
||||||
.usernameAndPassword(ADMIN_USERNAME, ADMIN_PASSWORD)
|
|
||||||
.getMeResource();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -306,17 +302,12 @@ public class RepositoryAccessITCase {
|
|||||||
public void shouldFindFileHistory() throws IOException {
|
public void shouldFindFileHistory() throws IOException {
|
||||||
RepositoryClient repositoryClient = RepositoryUtil.createRepositoryClient(repositoryType, folder);
|
RepositoryClient repositoryClient = RepositoryUtil.createRepositoryClient(repositoryType, folder);
|
||||||
Changeset changeset = RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, "folder/subfolder/a.txt", "a");
|
Changeset changeset = RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, "folder/subfolder/a.txt", "a");
|
||||||
repositoryGetRequest
|
repositoryResponse
|
||||||
.usingRepositoryResponse()
|
|
||||||
.requestSources()
|
.requestSources()
|
||||||
.usingSourcesResponse()
|
|
||||||
.requestSelf("folder")
|
.requestSelf("folder")
|
||||||
.usingSourcesResponse()
|
|
||||||
.requestSelf("subfolder")
|
.requestSelf("subfolder")
|
||||||
.usingSourcesResponse()
|
|
||||||
.requestFileHistory("a.txt")
|
.requestFileHistory("a.txt")
|
||||||
.assertStatusCode(HttpStatus.SC_OK)
|
.assertStatusCode(HttpStatus.SC_OK)
|
||||||
.usingChangesetsResponse()
|
|
||||||
.assertChangesets(changesets -> {
|
.assertChangesets(changesets -> {
|
||||||
assertThat(changesets).hasSize(1);
|
assertThat(changesets).hasSize(1);
|
||||||
assertThat(changesets.get(0)).containsEntry("id", changeset.getId());
|
assertThat(changesets.get(0)).containsEntry("id", changeset.getId());
|
||||||
@@ -332,14 +323,11 @@ public class RepositoryAccessITCase {
|
|||||||
String fileName = "a.txt";
|
String fileName = "a.txt";
|
||||||
Changeset changeset = RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, fileName, "a");
|
Changeset changeset = RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, fileName, "a");
|
||||||
String revision = changeset.getId();
|
String revision = changeset.getId();
|
||||||
repositoryGetRequest
|
repositoryResponse
|
||||||
.usingRepositoryResponse()
|
|
||||||
.requestChangesets()
|
.requestChangesets()
|
||||||
.assertStatusCode(HttpStatus.SC_OK)
|
.assertStatusCode(HttpStatus.SC_OK)
|
||||||
.usingChangesetsResponse()
|
|
||||||
.requestModifications(revision)
|
.requestModifications(revision)
|
||||||
.assertStatusCode(HttpStatus.SC_OK)
|
.assertStatusCode(HttpStatus.SC_OK)
|
||||||
.usingModificationsResponse()
|
|
||||||
.assertRevision(actualRevision -> assertThat(actualRevision).isEqualTo(revision))
|
.assertRevision(actualRevision -> assertThat(actualRevision).isEqualTo(revision))
|
||||||
.assertAdded(addedFiles -> assertThat(addedFiles)
|
.assertAdded(addedFiles -> assertThat(addedFiles)
|
||||||
.hasSize(1)
|
.hasSize(1)
|
||||||
@@ -359,14 +347,11 @@ public class RepositoryAccessITCase {
|
|||||||
Changeset changeset = RepositoryUtil.removeAndCommitFile(repositoryClient, ADMIN_USERNAME, fileName);
|
Changeset changeset = RepositoryUtil.removeAndCommitFile(repositoryClient, ADMIN_USERNAME, fileName);
|
||||||
|
|
||||||
String revision = changeset.getId();
|
String revision = changeset.getId();
|
||||||
repositoryGetRequest
|
repositoryResponse
|
||||||
.usingRepositoryResponse()
|
|
||||||
.requestChangesets()
|
.requestChangesets()
|
||||||
.assertStatusCode(HttpStatus.SC_OK)
|
.assertStatusCode(HttpStatus.SC_OK)
|
||||||
.usingChangesetsResponse()
|
|
||||||
.requestModifications(revision)
|
.requestModifications(revision)
|
||||||
.assertStatusCode(HttpStatus.SC_OK)
|
.assertStatusCode(HttpStatus.SC_OK)
|
||||||
.usingModificationsResponse()
|
|
||||||
.assertRevision(actualRevision -> assertThat(actualRevision).isEqualTo(revision))
|
.assertRevision(actualRevision -> assertThat(actualRevision).isEqualTo(revision))
|
||||||
.assertRemoved(removedFiles -> assertThat(removedFiles)
|
.assertRemoved(removedFiles -> assertThat(removedFiles)
|
||||||
.hasSize(1)
|
.hasSize(1)
|
||||||
@@ -386,14 +371,11 @@ public class RepositoryAccessITCase {
|
|||||||
Changeset changeset = RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, fileName, "new Content");
|
Changeset changeset = RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, fileName, "new Content");
|
||||||
|
|
||||||
String revision = changeset.getId();
|
String revision = changeset.getId();
|
||||||
repositoryGetRequest
|
repositoryResponse
|
||||||
.usingRepositoryResponse()
|
|
||||||
.requestChangesets()
|
.requestChangesets()
|
||||||
.assertStatusCode(HttpStatus.SC_OK)
|
.assertStatusCode(HttpStatus.SC_OK)
|
||||||
.usingChangesetsResponse()
|
|
||||||
.requestModifications(revision)
|
.requestModifications(revision)
|
||||||
.assertStatusCode(HttpStatus.SC_OK)
|
.assertStatusCode(HttpStatus.SC_OK)
|
||||||
.usingModificationsResponse()
|
|
||||||
.assertRevision(actualRevision -> assertThat(actualRevision).isEqualTo(revision))
|
.assertRevision(actualRevision -> assertThat(actualRevision).isEqualTo(revision))
|
||||||
.assertModified(modifiedFiles -> assertThat(modifiedFiles)
|
.assertModified(modifiedFiles -> assertThat(modifiedFiles)
|
||||||
.hasSize(1)
|
.hasSize(1)
|
||||||
@@ -423,14 +405,11 @@ public class RepositoryAccessITCase {
|
|||||||
Changeset changeset = RepositoryUtil.commitMultipleFileModifications(repositoryClient, ADMIN_USERNAME, addedFiles, modifiedFiles, removedFiles);
|
Changeset changeset = RepositoryUtil.commitMultipleFileModifications(repositoryClient, ADMIN_USERNAME, addedFiles, modifiedFiles, removedFiles);
|
||||||
|
|
||||||
String revision = changeset.getId();
|
String revision = changeset.getId();
|
||||||
repositoryGetRequest
|
repositoryResponse
|
||||||
.usingRepositoryResponse()
|
|
||||||
.requestChangesets()
|
.requestChangesets()
|
||||||
.assertStatusCode(HttpStatus.SC_OK)
|
.assertStatusCode(HttpStatus.SC_OK)
|
||||||
.usingChangesetsResponse()
|
|
||||||
.requestModifications(revision)
|
.requestModifications(revision)
|
||||||
.assertStatusCode(HttpStatus.SC_OK)
|
.assertStatusCode(HttpStatus.SC_OK)
|
||||||
.usingModificationsResponse()
|
|
||||||
.assertRevision(actualRevision -> assertThat(actualRevision).isEqualTo(revision))
|
.assertRevision(actualRevision -> assertThat(actualRevision).isEqualTo(revision))
|
||||||
.assertAdded(a -> assertThat(a)
|
.assertAdded(a -> assertThat(a)
|
||||||
.hasSize(1)
|
.hasSize(1)
|
||||||
@@ -463,14 +442,11 @@ public class RepositoryAccessITCase {
|
|||||||
Changeset changeset = RepositoryUtil.commitMultipleFileModifications(repositoryClient, ADMIN_USERNAME, addedFiles, modifiedFiles, removedFiles);
|
Changeset changeset = RepositoryUtil.commitMultipleFileModifications(repositoryClient, ADMIN_USERNAME, addedFiles, modifiedFiles, removedFiles);
|
||||||
|
|
||||||
String revision = changeset.getId();
|
String revision = changeset.getId();
|
||||||
repositoryGetRequest
|
repositoryResponse
|
||||||
.usingRepositoryResponse()
|
|
||||||
.requestChangesets()
|
.requestChangesets()
|
||||||
.assertStatusCode(HttpStatus.SC_OK)
|
.assertStatusCode(HttpStatus.SC_OK)
|
||||||
.usingChangesetsResponse()
|
|
||||||
.requestModifications(revision)
|
.requestModifications(revision)
|
||||||
.assertStatusCode(HttpStatus.SC_OK)
|
.assertStatusCode(HttpStatus.SC_OK)
|
||||||
.usingModificationsResponse()
|
|
||||||
.assertRevision(actualRevision -> assertThat(actualRevision).isEqualTo(revision))
|
.assertRevision(actualRevision -> assertThat(actualRevision).isEqualTo(revision))
|
||||||
.assertAdded(a -> assertThat(a)
|
.assertAdded(a -> assertThat(a)
|
||||||
.hasSize(3)
|
.hasSize(3)
|
||||||
|
|||||||
@@ -19,57 +19,48 @@ public class UserITCase {
|
|||||||
public void adminShouldChangeOwnPassword() {
|
public void adminShouldChangeOwnPassword() {
|
||||||
String newUser = "user";
|
String newUser = "user";
|
||||||
String password = "pass";
|
String password = "pass";
|
||||||
TestData.createUser(newUser, password, true, "xml");
|
TestData.createUser(newUser, password, true, "xml", "user@scm-manager.org");
|
||||||
String newPassword = "new_password";
|
String newPassword = "new_password";
|
||||||
// admin change the own password
|
// admin change the own password
|
||||||
ScmRequests.start()
|
ScmRequests.start()
|
||||||
.given()
|
.requestIndexResource(newUser, password)
|
||||||
.url(TestData.getUserUrl(newUser))
|
.assertStatusCode(200)
|
||||||
.usernameAndPassword(newUser, password)
|
.requestUser(newUser)
|
||||||
.getUserResource()
|
|
||||||
.assertStatusCode(200)
|
.assertStatusCode(200)
|
||||||
.usingUserResponse()
|
|
||||||
.assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE))
|
.assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE))
|
||||||
.assertPassword(Assert::assertNull)
|
.assertPassword(Assert::assertNull)
|
||||||
.requestChangePassword(password, newPassword) // the oldPassword is needed when the own password should be changed
|
.requestChangePassword(password, newPassword) // the oldPassword is needed when the own password should be changed
|
||||||
.assertStatusCode(204);
|
.assertStatusCode(204);
|
||||||
// assert password is changed -> login with the new Password
|
// assert password is changed -> login with the new Password
|
||||||
ScmRequests.start()
|
ScmRequests.start()
|
||||||
.given()
|
.requestIndexResource(newUser, newPassword)
|
||||||
.url(TestData.getUserUrl(newUser))
|
|
||||||
.usernameAndPassword(newUser, newPassword)
|
|
||||||
.getUserResource()
|
|
||||||
.assertStatusCode(200)
|
.assertStatusCode(200)
|
||||||
.usingUserResponse()
|
.requestUser(newUser)
|
||||||
.assertAdmin(isAdmin -> assertThat(isAdmin).isEqualTo(Boolean.TRUE))
|
.assertAdmin(isAdmin -> assertThat(isAdmin).isEqualTo(Boolean.TRUE))
|
||||||
.assertPassword(Assert::assertNull);
|
.assertPassword(Assert::assertNull);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void adminShouldChangePasswordOfOtherUser() {
|
public void adminShouldChangePasswordOfOtherUser() {
|
||||||
String newUser = "user";
|
String newUser = "user";
|
||||||
String password = "pass";
|
String password = "pass";
|
||||||
TestData.createUser(newUser, password, true, "xml");
|
TestData.createUser(newUser, password, true, "xml", "user@scm-manager.org");
|
||||||
String newPassword = "new_password";
|
String newPassword = "new_password";
|
||||||
// admin change the password of the user
|
// admin change the password of the user
|
||||||
ScmRequests.start()
|
ScmRequests.start()
|
||||||
.given()
|
.requestIndexResource(TestData.USER_SCM_ADMIN, TestData.USER_SCM_ADMIN)
|
||||||
.url(TestData.getUserUrl(newUser))// the admin get the user object
|
|
||||||
.usernameAndPassword(TestData.USER_SCM_ADMIN, TestData.USER_SCM_ADMIN)
|
|
||||||
.getUserResource()
|
|
||||||
.assertStatusCode(200)
|
.assertStatusCode(200)
|
||||||
.usingUserResponse()
|
.requestUser(newUser)
|
||||||
.assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE))
|
.assertStatusCode(200)
|
||||||
|
.assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE)) // the user anonymous is not an admin
|
||||||
.assertPassword(Assert::assertNull)
|
.assertPassword(Assert::assertNull)
|
||||||
.requestChangePassword(newPassword) // the oldPassword is not needed in the user resource
|
.requestChangePassword(newPassword) // the oldPassword is not needed in the user resource
|
||||||
.assertStatusCode(204);
|
.assertStatusCode(204);
|
||||||
// assert password is changed
|
// assert password is changed
|
||||||
ScmRequests.start()
|
ScmRequests.start()
|
||||||
.given()
|
.requestIndexResource(newUser, newPassword)
|
||||||
.url(TestData.getUserUrl(newUser))
|
.assertStatusCode(200)
|
||||||
.usernameAndPassword(newUser, newPassword)
|
.requestUser(newUser)
|
||||||
.getUserResource()
|
|
||||||
.assertStatusCode(200);
|
.assertStatusCode(200);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -78,41 +69,42 @@ public class UserITCase {
|
|||||||
public void nonAdminUserShouldNotChangePasswordOfOtherUser() {
|
public void nonAdminUserShouldNotChangePasswordOfOtherUser() {
|
||||||
String user = "user";
|
String user = "user";
|
||||||
String password = "pass";
|
String password = "pass";
|
||||||
TestData.createUser(user, password, false, "xml");
|
TestData.createUser(user, password, false, "xml", "em@l.de");
|
||||||
String user2 = "user2";
|
String user2 = "user2";
|
||||||
TestData.createUser(user2, password, false, "xml");
|
TestData.createUser(user2, password, false, "xml", "em@l.de");
|
||||||
ScmRequests.start()
|
ScmRequests.start()
|
||||||
.given()
|
.requestIndexResource(user, password)
|
||||||
.url(TestData.getUserUrl(user2))
|
.assertUsersLinkDoesNotExists();
|
||||||
.usernameAndPassword(user, password)
|
// use the users/ endpoint bypassed the index resource
|
||||||
.getUserResource()
|
ScmRequests.start()
|
||||||
|
.requestUser(user, password, user2)
|
||||||
|
.assertStatusCode(403);
|
||||||
|
// use the users/password endpoint bypassed the index and users resources
|
||||||
|
ScmRequests.start()
|
||||||
|
.requestUserChangePassword(user, password, user2, "newPassword")
|
||||||
.assertStatusCode(403);
|
.assertStatusCode(403);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void nonAdminUserShouldChangeOwnPassword() {
|
public void nonAdminUserShouldChangeOwnPassword() {
|
||||||
String newUser = "user";
|
String newUser = "user1";
|
||||||
String password = "pass";
|
String password = "pass";
|
||||||
TestData.createUser(newUser, password, false, "xml");
|
TestData.createUser(newUser, password, false, "xml", "em@l.de");
|
||||||
String newPassword = "new_password";
|
String newPassword = "new_password";
|
||||||
ScmRequests.start()
|
ScmRequests.start()
|
||||||
.given()
|
.requestIndexResource(newUser, password)
|
||||||
.url(TestData.getUserUrl(newUser))
|
.assertUsersLinkDoesNotExists();
|
||||||
.usernameAndPassword(newUser, password)
|
// use the users/password endpoint bypassed the index resource
|
||||||
.getUserResource()
|
ScmRequests.start()
|
||||||
|
.requestUser(newUser, password, newUser)
|
||||||
.assertStatusCode(200)
|
.assertStatusCode(200)
|
||||||
.usingUserResponse()
|
|
||||||
.assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.FALSE))
|
.assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.FALSE))
|
||||||
.requestChangePassword(password, newPassword) // the oldPassword is needed when the own password should be changed
|
.requestChangePassword(password, newPassword) // the oldPassword is needed when the own password should be changed
|
||||||
.assertStatusCode(204);
|
.assertStatusCode(204);
|
||||||
// assert password is changed -> login with the new Password
|
// // assert password is changed -> login with the new Password
|
||||||
ScmRequests.start()
|
ScmRequests.start()
|
||||||
.given()
|
.requestUser(newUser, newPassword, newUser)
|
||||||
.url(TestData.getUserUrl(newUser))
|
|
||||||
.usernameAndPassword(newUser, newPassword)
|
|
||||||
.getUserResource()
|
|
||||||
.assertStatusCode(200)
|
.assertStatusCode(200)
|
||||||
.usingUserResponse()
|
|
||||||
.assertAdmin(isAdmin -> assertThat(isAdmin).isEqualTo(Boolean.FALSE))
|
.assertAdmin(isAdmin -> assertThat(isAdmin).isEqualTo(Boolean.FALSE))
|
||||||
.assertPassword(Assert::assertNull);
|
.assertPassword(Assert::assertNull);
|
||||||
}
|
}
|
||||||
@@ -122,14 +114,12 @@ public class UserITCase {
|
|||||||
String newUser = "user";
|
String newUser = "user";
|
||||||
String password = "pass";
|
String password = "pass";
|
||||||
String type = "not XML Type";
|
String type = "not XML Type";
|
||||||
TestData.createUser(newUser, password, true, type);
|
TestData.createUser(newUser, password, true, type, "user@scm-manager.org");
|
||||||
ScmRequests.start()
|
ScmRequests.start()
|
||||||
.given()
|
.requestIndexResource(newUser, password)
|
||||||
.url(TestData.getMeUrl())
|
.assertStatusCode(200)
|
||||||
.usernameAndPassword(newUser, password)
|
.requestUser(newUser)
|
||||||
.getUserResource()
|
|
||||||
.assertStatusCode(200)
|
.assertStatusCode(200)
|
||||||
.usingUserResponse()
|
|
||||||
.assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE))
|
.assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE))
|
||||||
.assertPassword(Assert::assertNull)
|
.assertPassword(Assert::assertNull)
|
||||||
.assertType(s -> assertThat(s).isEqualTo(type))
|
.assertType(s -> assertThat(s).isEqualTo(type))
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import io.restassured.RestAssured;
|
|||||||
import io.restassured.response.Response;
|
import io.restassured.response.Response;
|
||||||
import sonia.scm.web.VndMediaType;
|
import sonia.scm.web.VndMediaType;
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@@ -33,10 +32,24 @@ public class ScmRequests {
|
|||||||
return new ScmRequests();
|
return new ScmRequests();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Given given() {
|
public IndexResponse requestIndexResource(String username, String password) {
|
||||||
return new Given();
|
setUsername(username);
|
||||||
|
setPassword(password);
|
||||||
|
return new IndexResponse(applyGETRequest(RestUtil.REST_BASE_URL.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UserResponse<UserResponse> requestUser(String username, String password, String pathParam) {
|
||||||
|
setUsername(username);
|
||||||
|
setPassword(password);
|
||||||
|
return new UserResponse<>(applyGETRequest(RestUtil.REST_BASE_URL.resolve("users/"+pathParam).toString()), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChangePasswordResponse<ChangePasswordResponse> requestUserChangePassword(String username, String password, String userPathParam, String newPassword) {
|
||||||
|
setUsername(username);
|
||||||
|
setPassword(password);
|
||||||
|
return new ChangePasswordResponse<>(applyPUTRequest(RestUtil.REST_BASE_URL.resolve("users/"+userPathParam+"/password").toString(), VndMediaType.PASSWORD_CHANGE, TestData.createPasswordChangeJson(password,newPassword)), null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply a GET Request to the extracted url from the given link
|
* Apply a GET Request to the extracted url from the given link
|
||||||
@@ -46,24 +59,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 params query params eg. ?q=xyz&count=12 or path params eg. namespace/name
|
||||||
|
* @return the response of the GET request using the given link
|
||||||
|
*/
|
||||||
|
private Response applyGETRequestFromLinkWithParams(Response response, String linkPropertyName, String params) {
|
||||||
|
return applyGETRequestWithQueryParams(response
|
||||||
|
.then()
|
||||||
|
.extract()
|
||||||
|
.path(linkPropertyName), params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply a GET Request to the given <code>url</code> and return the response.
|
||||||
|
*
|
||||||
|
* @param url the url of the GET request
|
||||||
|
* @param params query params eg. ?q=xyz&count=12 or path params eg. namespace/name
|
||||||
|
* @return the response of the GET request using the given <code>url</code>
|
||||||
|
*/
|
||||||
|
private Response applyGETRequestWithQueryParams(String url, String params) {
|
||||||
|
return RestAssured.given()
|
||||||
|
.auth().preemptive().basic(username, password)
|
||||||
|
.when()
|
||||||
|
.get(url + params);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -101,11 +136,6 @@ public class ScmRequests {
|
|||||||
.put(url);
|
.put(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void setUrl(String url) {
|
|
||||||
this.url = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUsername(String username) {
|
private void setUsername(String username) {
|
||||||
this.username = username;
|
this.username = username;
|
||||||
}
|
}
|
||||||
@@ -114,300 +144,191 @@ public class ScmRequests {
|
|||||||
this.password = password;
|
this.password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getUrl() {
|
|
||||||
return url;
|
|
||||||
|
public class IndexResponse extends ModelResponse<IndexResponse, IndexResponse> {
|
||||||
|
public static final String LINK_AUTOCOMPLETE_USERS = "_links.autocomplete.find{it.name=='users'}.href";
|
||||||
|
public static final String LINK_AUTOCOMPLETE_GROUPS = "_links.autocomplete.find{it.name=='groups'}.href";
|
||||||
|
public static final String LINK_REPOSITORIES = "_links.repositories.href";
|
||||||
|
private static final String LINK_ME = "_links.me.href";
|
||||||
|
private static final String LINK_USERS = "_links.users.href";
|
||||||
|
|
||||||
|
public IndexResponse(Response response) {
|
||||||
|
super(response, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getUsername() {
|
public AutoCompleteResponse<IndexResponse> requestAutoCompleteUsers(String q) {
|
||||||
return username;
|
return new AutoCompleteResponse<>(applyGETRequestFromLinkWithParams(response, LINK_AUTOCOMPLETE_USERS, "?q=" + q), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getPassword() {
|
public AutoCompleteResponse<IndexResponse> requestAutoCompleteGroups(String q) {
|
||||||
return password;
|
return new AutoCompleteResponse<>(applyGETRequestFromLinkWithParams(response, LINK_AUTOCOMPLETE_GROUPS, "?q=" + q), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Given {
|
public RepositoryResponse<IndexResponse> requestRepository(String namespace, String name) {
|
||||||
|
return new RepositoryResponse<>(applyGETRequestFromLinkWithParams(response, LINK_REPOSITORIES, namespace + "/" + name), this);
|
||||||
public GivenUrl url(String url) {
|
|
||||||
setUrl(url);
|
|
||||||
return new GivenUrl();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GivenUrl url(URI url) {
|
public MeResponse<IndexResponse> requestMe() {
|
||||||
setUrl(url.toString());
|
return new MeResponse<>(applyGETRequestFromLink(response, LINK_ME), this);
|
||||||
return new GivenUrl();
|
}
|
||||||
|
|
||||||
|
public UserResponse<IndexResponse> requestUser(String username) {
|
||||||
|
return new UserResponse<>(applyGETRequestFromLinkWithParams(response, LINK_USERS, username), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IndexResponse assertUsersLinkDoesNotExists() {
|
||||||
|
return super.assertPropertyPathDoesNotExists(LINK_USERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RepositoryResponse<PREV extends ModelResponse> extends ModelResponse<RepositoryResponse<PREV>, PREV> {
|
||||||
|
|
||||||
|
|
||||||
|
public static final String LINKS_SOURCES = "_links.sources.href";
|
||||||
|
public static final String LINKS_CHANGESETS = "_links.changesets.href";
|
||||||
|
|
||||||
|
public RepositoryResponse(Response response, PREV previousResponse) {
|
||||||
|
super(response, previousResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SourcesResponse<RepositoryResponse> requestSources() {
|
||||||
|
return new SourcesResponse<>(applyGETRequestFromLink(response, LINKS_SOURCES), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChangesetsResponse<RepositoryResponse> requestChangesets() {
|
||||||
|
return new ChangesetsResponse<>(applyGETRequestFromLink(response, LINKS_CHANGESETS), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GivenWithUrlAndAuth {
|
public class ChangesetsResponse<PREV extends ModelResponse> extends ModelResponse<ChangesetsResponse<PREV>, PREV> {
|
||||||
public AppliedMeRequest getMeResource() {
|
|
||||||
return new AppliedMeRequest(applyGETRequest(url));
|
|
||||||
}
|
|
||||||
|
|
||||||
public AppliedUserRequest getUserResource() {
|
public ChangesetsResponse(Response response, PREV previousResponse) {
|
||||||
return new AppliedUserRequest(applyGETRequest(url));
|
super(response, previousResponse);
|
||||||
}
|
|
||||||
|
|
||||||
public AppliedRepositoryRequest getRepositoryResource() {
|
|
||||||
return new AppliedRepositoryRequest(
|
|
||||||
applyGETRequest(url)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AppliedRequest<SELF extends AppliedRequest> {
|
|
||||||
private Response response;
|
|
||||||
|
|
||||||
public AppliedRequest(Response response) {
|
|
||||||
this.response = response;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* apply custom assertions to the actual response
|
|
||||||
*
|
|
||||||
* @param consumer consume the response in order to assert the content. the header, the payload etc..
|
|
||||||
* @return the self object
|
|
||||||
*/
|
|
||||||
public SELF assertResponse(Consumer<Response> consumer) {
|
|
||||||
consumer.accept(response);
|
|
||||||
return (SELF) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* special assertion of the status code
|
|
||||||
*
|
|
||||||
* @param expectedStatusCode the expected status code
|
|
||||||
* @return the self object
|
|
||||||
*/
|
|
||||||
public SELF assertStatusCode(int expectedStatusCode) {
|
|
||||||
this.response.then().assertThat().statusCode(expectedStatusCode);
|
|
||||||
return (SELF) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AppliedRepositoryRequest extends AppliedRequest<AppliedRepositoryRequest> {
|
|
||||||
|
|
||||||
public AppliedRepositoryRequest(Response response) {
|
|
||||||
super(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RepositoryResponse usingRepositoryResponse() {
|
|
||||||
return new RepositoryResponse(super.response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RepositoryResponse {
|
|
||||||
|
|
||||||
private Response repositoryResponse;
|
|
||||||
|
|
||||||
public RepositoryResponse(Response repositoryResponse) {
|
|
||||||
this.repositoryResponse = repositoryResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AppliedSourcesRequest requestSources() {
|
|
||||||
return new AppliedSourcesRequest(applyGETRequestFromLink(repositoryResponse, "_links.sources.href"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public AppliedChangesetsRequest requestChangesets() {
|
|
||||||
return new AppliedChangesetsRequest(applyGETRequestFromLink(repositoryResponse, "_links.changesets.href"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AppliedChangesetsRequest extends AppliedRequest<AppliedChangesetsRequest> {
|
|
||||||
|
|
||||||
public AppliedChangesetsRequest(Response response) {
|
|
||||||
super(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChangesetsResponse usingChangesetsResponse() {
|
|
||||||
return new ChangesetsResponse(super.response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ChangesetsResponse {
|
|
||||||
private Response changesetsResponse;
|
|
||||||
|
|
||||||
public ChangesetsResponse(Response changesetsResponse) {
|
|
||||||
this.changesetsResponse = changesetsResponse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChangesetsResponse assertChangesets(Consumer<List<Map>> changesetsConsumer) {
|
public ChangesetsResponse assertChangesets(Consumer<List<Map>> changesetsConsumer) {
|
||||||
List<Map> changesets = changesetsResponse.then().extract().path("_embedded.changesets");
|
List<Map> changesets = response.then().extract().path("_embedded.changesets");
|
||||||
changesetsConsumer.accept(changesets);
|
changesetsConsumer.accept(changesets);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppliedDiffRequest requestDiff(String revision) {
|
public DiffResponse<ChangesetsResponse> requestDiff(String revision) {
|
||||||
return new AppliedDiffRequest(applyGETRequestFromLink(changesetsResponse, "_embedded.changesets.find{it.id=='" + revision + "'}._links.diff.href"));
|
return new DiffResponse<>(applyGETRequestFromLink(response, "_embedded.changesets.find{it.id=='" + revision + "'}._links.diff.href"), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppliedModificationsRequest requestModifications(String revision) {
|
public ModificationsResponse<ChangesetsResponse> requestModifications(String revision) {
|
||||||
return new AppliedModificationsRequest(applyGETRequestFromLink(changesetsResponse, "_embedded.changesets.find{it.id=='" + revision + "'}._links.modifications.href"));
|
return new ModificationsResponse<>(applyGETRequestFromLink(response, "_embedded.changesets.find{it.id=='" + revision + "'}._links.modifications.href"), this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AppliedSourcesRequest extends AppliedRequest<AppliedSourcesRequest> {
|
|
||||||
|
|
||||||
public AppliedSourcesRequest(Response sourcesResponse) {
|
public class SourcesResponse<PREV extends ModelResponse> extends ModelResponse<SourcesResponse<PREV>, PREV> {
|
||||||
super(sourcesResponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SourcesResponse usingSourcesResponse() {
|
public SourcesResponse(Response response, PREV previousResponse) {
|
||||||
return new SourcesResponse(super.response);
|
super(response, previousResponse);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SourcesResponse {
|
|
||||||
|
|
||||||
private Response sourcesResponse;
|
|
||||||
|
|
||||||
public SourcesResponse(Response sourcesResponse) {
|
|
||||||
this.sourcesResponse = sourcesResponse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SourcesResponse assertRevision(Consumer<String> assertRevision) {
|
public SourcesResponse assertRevision(Consumer<String> assertRevision) {
|
||||||
String revision = sourcesResponse.then().extract().path("revision");
|
String revision = response.then().extract().path("revision");
|
||||||
assertRevision.accept(revision);
|
assertRevision.accept(revision);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SourcesResponse assertFiles(Consumer<List> assertFiles) {
|
public SourcesResponse assertFiles(Consumer<List> assertFiles) {
|
||||||
List files = sourcesResponse.then().extract().path("files");
|
List files = response.then().extract().path("files");
|
||||||
assertFiles.accept(files);
|
assertFiles.accept(files);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppliedChangesetsRequest requestFileHistory(String fileName) {
|
public ChangesetsResponse<SourcesResponse> requestFileHistory(String fileName) {
|
||||||
return new AppliedChangesetsRequest(applyGETRequestFromLink(sourcesResponse, "_embedded.files.find{it.name=='" + fileName + "'}._links.history.href"));
|
return new ChangesetsResponse<>(applyGETRequestFromLink(response, "_embedded.files.find{it.name=='" + fileName + "'}._links.history.href"), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppliedSourcesRequest requestSelf(String fileName) {
|
public SourcesResponse<SourcesResponse> requestSelf(String fileName) {
|
||||||
return new AppliedSourcesRequest(applyGETRequestFromLink(sourcesResponse, "_embedded.files.find{it.name=='" + fileName + "'}._links.self.href"));
|
return new SourcesResponse<>(applyGETRequestFromLink(response, "_embedded.files.find{it.name=='" + fileName + "'}._links.self.href"), this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AppliedDiffRequest extends AppliedRequest<AppliedDiffRequest> {
|
public class ModificationsResponse<PREV extends ModelResponse> extends ModelResponse<ModificationsResponse<PREV>, PREV> {
|
||||||
|
|
||||||
public AppliedDiffRequest(Response response) {
|
public ModificationsResponse(Response response, PREV previousResponse) {
|
||||||
super(response);
|
super(response, previousResponse);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GivenUrl {
|
public ModificationsResponse<PREV> assertRevision(Consumer<String> assertRevision) {
|
||||||
|
String revision = response.then().extract().path("revision");
|
||||||
public GivenWithUrlAndAuth usernameAndPassword(String username, String password) {
|
|
||||||
setUsername(username);
|
|
||||||
setPassword(password);
|
|
||||||
return new GivenWithUrlAndAuth();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AppliedModificationsRequest extends AppliedRequest<AppliedModificationsRequest> {
|
|
||||||
public AppliedModificationsRequest(Response response) {
|
|
||||||
super(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModificationsResponse usingModificationsResponse() {
|
|
||||||
return new ModificationsResponse(super.response);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ModificationsResponse {
|
|
||||||
private Response resource;
|
|
||||||
|
|
||||||
public ModificationsResponse(Response resource) {
|
|
||||||
this.resource = resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModificationsResponse assertRevision(Consumer<String> assertRevision) {
|
|
||||||
String revision = resource.then().extract().path("revision");
|
|
||||||
assertRevision.accept(revision);
|
assertRevision.accept(revision);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModificationsResponse assertAdded(Consumer<List<String>> assertAdded) {
|
public ModificationsResponse<PREV> assertAdded(Consumer<List<String>> assertAdded) {
|
||||||
List<String> added = resource.then().extract().path("added");
|
List<String> added = response.then().extract().path("added");
|
||||||
assertAdded.accept(added);
|
assertAdded.accept(added);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModificationsResponse assertRemoved(Consumer<List<String>> assertRemoved) {
|
public ModificationsResponse<PREV> assertRemoved(Consumer<List<String>> assertRemoved) {
|
||||||
List<String> removed = resource.then().extract().path("removed");
|
List<String> removed = response.then().extract().path("removed");
|
||||||
assertRemoved.accept(removed);
|
assertRemoved.accept(removed);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModificationsResponse assertModified(Consumer<List<String>> assertModified) {
|
public ModificationsResponse<PREV> assertModified(Consumer<List<String>> assertModified) {
|
||||||
List<String> modified = resource.then().extract().path("modified");
|
List<String> modified = response.then().extract().path("modified");
|
||||||
assertModified.accept(modified);
|
assertModified.accept(modified);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AppliedMeRequest extends AppliedRequest<AppliedMeRequest> {
|
public class MeResponse<PREV extends ModelResponse> extends UserResponse<PREV> {
|
||||||
|
|
||||||
public AppliedMeRequest(Response response) {
|
|
||||||
super(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MeResponse usingMeResponse() {
|
|
||||||
return new MeResponse(super.response);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MeResponse extends UserResponse<MeResponse> {
|
|
||||||
|
|
||||||
|
|
||||||
public MeResponse(Response response) {
|
public MeResponse(Response response, PREV previousResponse) {
|
||||||
super(response);
|
super(response, previousResponse);
|
||||||
}
|
|
||||||
|
|
||||||
public AppliedChangePasswordRequest requestChangePassword(String oldPassword, String newPassword) {
|
|
||||||
return new AppliedChangePasswordRequest(applyPUTRequestFromLink(super.response, "_links.password.href", VndMediaType.PASSWORD_CHANGE, createPasswordChangeJson(oldPassword, newPassword)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UserResponse<SELF extends UserResponse> extends ModelResponse<SELF> {
|
public class UserResponse<PREV extends ModelResponse> extends ModelResponse<UserResponse<PREV>, PREV> {
|
||||||
|
|
||||||
public static final String LINKS_PASSWORD_HREF = "_links.password.href";
|
public static final String LINKS_PASSWORD_HREF = "_links.password.href";
|
||||||
|
|
||||||
public UserResponse(Response response) {
|
public UserResponse(Response response, PREV previousResponse) {
|
||||||
super(response);
|
super(response, previousResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SELF assertPassword(Consumer<String> assertPassword) {
|
public UserResponse<PREV> assertPassword(Consumer<String> assertPassword) {
|
||||||
return super.assertSingleProperty(assertPassword, "password");
|
return super.assertSingleProperty(assertPassword, "password");
|
||||||
}
|
}
|
||||||
|
|
||||||
public SELF assertType(Consumer<String> assertType) {
|
public UserResponse<PREV> assertType(Consumer<String> assertType) {
|
||||||
return assertSingleProperty(assertType, "type");
|
return assertSingleProperty(assertType, "type");
|
||||||
}
|
}
|
||||||
|
|
||||||
public SELF assertAdmin(Consumer<Boolean> assertAdmin) {
|
public UserResponse<PREV> assertAdmin(Consumer<Boolean> assertAdmin) {
|
||||||
return assertSingleProperty(assertAdmin, "admin");
|
return assertSingleProperty(assertAdmin, "admin");
|
||||||
}
|
}
|
||||||
|
|
||||||
public SELF assertPasswordLinkDoesNotExists() {
|
public UserResponse<PREV> assertPasswordLinkDoesNotExists() {
|
||||||
return assertPropertyPathDoesNotExists(LINKS_PASSWORD_HREF);
|
return assertPropertyPathDoesNotExists(LINKS_PASSWORD_HREF);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SELF assertPasswordLinkExists() {
|
public UserResponse<PREV> assertPasswordLinkExists() {
|
||||||
return assertPropertyPathExists(LINKS_PASSWORD_HREF);
|
return assertPropertyPathExists(LINKS_PASSWORD_HREF);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppliedChangePasswordRequest requestChangePassword(String newPassword) {
|
public ChangePasswordResponse<UserResponse> requestChangePassword(String newPassword) {
|
||||||
return new AppliedChangePasswordRequest(applyPUTRequestFromLink(super.response, LINKS_PASSWORD_HREF, VndMediaType.PASSWORD_CHANGE, createPasswordChangeJson(null, newPassword)));
|
return requestChangePassword(null, newPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppliedChangePasswordRequest requestChangePassword(String oldPassword , String newPassword) {
|
public ChangePasswordResponse<UserResponse> requestChangePassword(String oldPassword, String newPassword) {
|
||||||
return new AppliedChangePasswordRequest(applyPUTRequestFromLink(super.response, LINKS_PASSWORD_HREF, VndMediaType.PASSWORD_CHANGE, createPasswordChangeJson(oldPassword, newPassword)));
|
return new ChangePasswordResponse<>(applyPUTRequestFromLink(super.response, LINKS_PASSWORD_HREF, VndMediaType.PASSWORD_CHANGE, createPasswordChangeJson(oldPassword, newPassword)), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -416,12 +337,18 @@ public class ScmRequests {
|
|||||||
/**
|
/**
|
||||||
* encapsulate standard assertions over model properties
|
* encapsulate standard assertions over model properties
|
||||||
*/
|
*/
|
||||||
public class ModelResponse<SELF extends ModelResponse> {
|
public class ModelResponse<SELF extends ModelResponse<SELF, PREV>, PREV extends ModelResponse> {
|
||||||
|
|
||||||
|
protected PREV previousResponse;
|
||||||
protected Response response;
|
protected Response response;
|
||||||
|
|
||||||
public ModelResponse(Response response) {
|
public ModelResponse(Response response, PREV previousResponse) {
|
||||||
this.response = response;
|
this.response = response;
|
||||||
|
this.previousResponse = previousResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PREV returnToPrevious() {
|
||||||
|
return previousResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> SELF assertSingleProperty(Consumer<T> assertSingleProperty, String propertyJsonPath) {
|
public <T> SELF assertSingleProperty(Consumer<T> assertSingleProperty, String propertyJsonPath) {
|
||||||
@@ -445,25 +372,45 @@ public class ScmRequests {
|
|||||||
assertProperties.accept(properties);
|
assertProperties.accept(properties);
|
||||||
return (SELF) this;
|
return (SELF) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* special assertion of the status code
|
||||||
|
*
|
||||||
|
* @param expectedStatusCode the expected status code
|
||||||
|
* @return the self object
|
||||||
|
*/
|
||||||
|
public SELF assertStatusCode(int expectedStatusCode) {
|
||||||
|
this.response.then().assertThat().statusCode(expectedStatusCode);
|
||||||
|
return (SELF) this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AppliedChangePasswordRequest extends AppliedRequest<AppliedChangePasswordRequest> {
|
public class AutoCompleteResponse<PREV extends ModelResponse> extends ModelResponse<AutoCompleteResponse<PREV>, PREV> {
|
||||||
|
|
||||||
public AppliedChangePasswordRequest(Response response) {
|
public AutoCompleteResponse(Response response, PREV previousResponse) {
|
||||||
super(response);
|
super(response, previousResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AutoCompleteResponse<PREV> assertAutoCompleteResults(Consumer<List<Map>> checker) {
|
||||||
|
List<Map> result = response.then().extract().path("");
|
||||||
|
checker.accept(result);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AppliedUserRequest extends AppliedRequest<AppliedUserRequest> {
|
|
||||||
|
|
||||||
public AppliedUserRequest(Response response) {
|
public class DiffResponse<PREV extends ModelResponse> extends ModelResponse<DiffResponse<PREV>, PREV> {
|
||||||
super(response);
|
|
||||||
|
public DiffResponse(Response response, PREV previousResponse) {
|
||||||
|
super(response, previousResponse);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserResponse usingUserResponse() {
|
public class ChangePasswordResponse<PREV extends ModelResponse> extends ModelResponse<ChangePasswordResponse<PREV>, PREV> {
|
||||||
return new UserResponse(super.response);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public ChangePasswordResponse(Response response, PREV previousResponse) {
|
||||||
|
super(response, previousResponse);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,11 +46,11 @@ public class TestData {
|
|||||||
return DEFAULT_REPOSITORIES.get(repositoryType);
|
return DEFAULT_REPOSITORIES.get(repositoryType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void createUser(String username, String password) {
|
public static void createNotAdminUser(String username, String password) {
|
||||||
createUser(username, password, false, "xml");
|
createUser(username, password, false, "xml", "user1@scm-manager.org");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void createUser(String username, String password, boolean isAdmin, String type) {
|
public static void createUser(String username, String password, boolean isAdmin, String type, final String email) {
|
||||||
LOG.info("create user with username: {}", username);
|
LOG.info("create user with username: {}", username);
|
||||||
String admin = isAdmin ? "true" : "false";
|
String admin = isAdmin ? "true" : "false";
|
||||||
given(VndMediaType.USER)
|
given(VndMediaType.USER)
|
||||||
@@ -61,7 +61,7 @@ public class TestData {
|
|||||||
.append(" \"admin\": ").append(admin).append(",\n")
|
.append(" \"admin\": ").append(admin).append(",\n")
|
||||||
.append(" \"creationDate\": \"2018-08-21T12:26:46.084Z\",\n")
|
.append(" \"creationDate\": \"2018-08-21T12:26:46.084Z\",\n")
|
||||||
.append(" \"displayName\": \"").append(username).append("\",\n")
|
.append(" \"displayName\": \"").append(username).append("\",\n")
|
||||||
.append(" \"mail\": \"user1@scm-manager.org\",\n")
|
.append(" \"mail\": \"" + email + "\",\n")
|
||||||
.append(" \"name\": \"").append(username).append("\",\n")
|
.append(" \"name\": \"").append(username).append("\",\n")
|
||||||
.append(" \"password\": \"").append(password).append("\",\n")
|
.append(" \"password\": \"").append(password).append("\",\n")
|
||||||
.append(" \"type\": \"").append(type).append("\"\n")
|
.append(" \"type\": \"").append(type).append("\"\n")
|
||||||
@@ -71,6 +71,16 @@ public class TestData {
|
|||||||
.statusCode(HttpStatus.SC_CREATED)
|
.statusCode(HttpStatus.SC_CREATED)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
public static void createGroup(String groupName, String desc) {
|
||||||
|
LOG.info("create group with group name: {} and description {}", groupName, desc);
|
||||||
|
given(VndMediaType.GROUP)
|
||||||
|
.when()
|
||||||
|
.content(getGroupJson(groupName,desc))
|
||||||
|
.post(getGroupsUrl())
|
||||||
|
.then()
|
||||||
|
.statusCode(HttpStatus.SC_CREATED)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
public static void createUserPermission(String name, PermissionType permissionType, String repositoryType) {
|
public static void createUserPermission(String name, PermissionType permissionType, String repositoryType) {
|
||||||
String defaultPermissionUrl = TestData.getDefaultPermissionUrl(USER_SCM_ADMIN, USER_SCM_ADMIN, repositoryType);
|
String defaultPermissionUrl = TestData.getDefaultPermissionUrl(USER_SCM_ADMIN, USER_SCM_ADMIN, repositoryType);
|
||||||
@@ -193,28 +203,31 @@ public class TestData {
|
|||||||
return JSON_BUILDER
|
return JSON_BUILDER
|
||||||
.add("contact", "zaphod.beeblebrox@hitchhiker.com")
|
.add("contact", "zaphod.beeblebrox@hitchhiker.com")
|
||||||
.add("description", "Heart of Gold")
|
.add("description", "Heart of Gold")
|
||||||
.add("name", "HeartOfGold-" + repositoryType)
|
.add("name", getDefaultRepoName(repositoryType))
|
||||||
.add("archived", false)
|
.add("archived", false)
|
||||||
.add("type", repositoryType)
|
.add("type", repositoryType)
|
||||||
.build().toString();
|
.build().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static URI getMeUrl() {
|
public static String getDefaultRepoName(String repositoryType) {
|
||||||
return RestUtil.createResourceUrl("me/");
|
return "HeartOfGold-" + repositoryType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getGroupJson(String groupname , String desc) {
|
||||||
|
return JSON_BUILDER
|
||||||
|
.add("name", groupname)
|
||||||
|
.add("description", desc)
|
||||||
|
.build().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static URI getGroupsUrl() {
|
||||||
|
return RestUtil.createResourceUrl("groups/");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static URI getUsersUrl() {
|
public static URI getUsersUrl() {
|
||||||
return RestUtil.createResourceUrl("users/");
|
return RestUtil.createResourceUrl("users/");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static URI getUserUrl(String username) {
|
|
||||||
return getUsersUrl().resolve(username);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static String createPasswordChangeJson(String oldPassword, String newPassword) {
|
public static String createPasswordChangeJson(String oldPassword, String newPassword) {
|
||||||
return JSON_BUILDER
|
return JSON_BUILDER
|
||||||
.add("oldPassword", oldPassword)
|
.add("oldPassword", oldPassword)
|
||||||
@@ -225,4 +238,5 @@ public class TestData {
|
|||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ class Permissions extends React.Component<Props> {
|
|||||||
{t("permission.group-permission")}
|
{t("permission.group-permission")}
|
||||||
</th>
|
</th>
|
||||||
<th>{t("permission.type")}</th>
|
<th>{t("permission.type")}</th>
|
||||||
|
<th />
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ public class AutoCompleteResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("user")
|
@Path("users")
|
||||||
@Produces(VndMediaType.AUTOCOMPLETE)
|
@Produces(VndMediaType.AUTOCOMPLETE)
|
||||||
@StatusCodes({
|
@StatusCodes({
|
||||||
@ResponseCode(code = 200, condition = "success"),
|
@ResponseCode(code = 200, condition = "success"),
|
||||||
@@ -50,12 +50,12 @@ 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("filter") 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("group")
|
@Path("groups")
|
||||||
@Produces(VndMediaType.AUTOCOMPLETE)
|
@Produces(VndMediaType.AUTOCOMPLETE)
|
||||||
@StatusCodes({
|
@StatusCodes({
|
||||||
@ResponseCode(code = 200, condition = "success"),
|
@ResponseCode(code = 200, condition = "success"),
|
||||||
@@ -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("filter") 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,20 +6,24 @@ import sonia.scm.AlreadyExistsException;
|
|||||||
import sonia.scm.ConcurrentModificationException;
|
import sonia.scm.ConcurrentModificationException;
|
||||||
import sonia.scm.Manager;
|
import sonia.scm.Manager;
|
||||||
import sonia.scm.ModelObject;
|
import sonia.scm.ModelObject;
|
||||||
import sonia.scm.NotFoundException;
|
|
||||||
import sonia.scm.PageResult;
|
import sonia.scm.PageResult;
|
||||||
|
import sonia.scm.user.ChangePasswordNotAllowedException;
|
||||||
import sonia.scm.user.User;
|
import sonia.scm.user.User;
|
||||||
|
import sonia.scm.user.UserManager;
|
||||||
import sonia.scm.user.UserPermissions;
|
import sonia.scm.user.UserPermissions;
|
||||||
import sonia.scm.util.AssertUtil;
|
import sonia.scm.util.AssertUtil;
|
||||||
import sonia.scm.util.AuthenticationUtil;
|
import sonia.scm.util.AuthenticationUtil;
|
||||||
|
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
|
import java.text.MessageFormat;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import static sonia.scm.user.ChangePasswordNotAllowedException.WRONG_USER_TYPE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Facade for {@link SingleResourceManagerAdapter} and {@link CollectionResourceManagerAdapter}
|
* Facade for {@link SingleResourceManagerAdapter} and {@link CollectionResourceManagerAdapter}
|
||||||
* for model objects handled by a single id.
|
* for model objects handled by a single id.
|
||||||
@@ -51,7 +55,7 @@ class IdResourceManagerAdapter<MODEL_OBJECT extends ModelObject,
|
|||||||
* @param usernameToChangePassword the user name of the user we want to change password
|
* @param usernameToChangePassword the user name of the user we want to change password
|
||||||
* @return function to verify permission
|
* @return function to verify permission
|
||||||
*/
|
*/
|
||||||
public Function<MODEL_OBJECT, PermissionCheck> getChangePasswordPermission(String usernameToChangePassword) {
|
private Function<MODEL_OBJECT, PermissionCheck> getChangePasswordPermission(String usernameToChangePassword) {
|
||||||
AssertUtil.assertIsNotEmpty(usernameToChangePassword);
|
AssertUtil.assertIsNotEmpty(usernameToChangePassword);
|
||||||
return model -> {
|
return model -> {
|
||||||
User user = (User) model;
|
User user = (User) model;
|
||||||
@@ -62,12 +66,32 @@ class IdResourceManagerAdapter<MODEL_OBJECT extends ModelObject,
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public Response changePassword(String id, Function<MODEL_OBJECT, MODEL_OBJECT> applyChanges, Consumer<MODEL_OBJECT> checker ) throws ConcurrentModificationException {
|
|
||||||
|
/**
|
||||||
|
* Check if a user can modify the password
|
||||||
|
*
|
||||||
|
* 1 - the permission changeOwnPassword should be checked
|
||||||
|
* 2 - Only account of the default type "xml" can change their password
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private Consumer<MODEL_OBJECT> getChangePasswordChecker() {
|
||||||
|
return model -> {
|
||||||
|
User user = (User) model;
|
||||||
|
UserPermissions.changeOwnPassword().check();
|
||||||
|
UserManager userManager = (UserManager) manager;
|
||||||
|
if (!userManager.isTypeDefault(user)) {
|
||||||
|
throw new ChangePasswordNotAllowedException(MessageFormat.format(WRONG_USER_TYPE, user.getType()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Response changePassword(String id, Function<MODEL_OBJECT, MODEL_OBJECT> applyChanges ) throws ConcurrentModificationException {
|
||||||
return singleAdapter.changePassword(
|
return singleAdapter.changePassword(
|
||||||
loadBy(id),
|
loadBy(id),
|
||||||
applyChanges,
|
applyChanges,
|
||||||
idStaysTheSame(id),
|
idStaysTheSame(id),
|
||||||
checker,
|
getChangePasswordChecker(),
|
||||||
getChangePasswordPermission(id));
|
getChangePasswordPermission(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package sonia.scm.api.v2.resources;
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import de.otto.edison.hal.Link;
|
||||||
import de.otto.edison.hal.Links;
|
import de.otto.edison.hal.Links;
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
import sonia.scm.SCMContextProvider;
|
import sonia.scm.SCMContextProvider;
|
||||||
@@ -8,6 +10,7 @@ import sonia.scm.group.GroupPermissions;
|
|||||||
import sonia.scm.user.UserPermissions;
|
import sonia.scm.user.UserPermissions;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static de.otto.edison.hal.Link.link;
|
import static de.otto.edison.hal.Link.link;
|
||||||
|
|
||||||
@@ -24,6 +27,7 @@ public class IndexDtoGenerator {
|
|||||||
|
|
||||||
public IndexDto generate() {
|
public IndexDto generate() {
|
||||||
Links.Builder builder = Links.linkingTo();
|
Links.Builder builder = Links.linkingTo();
|
||||||
|
List<Link> autoCompleteLinks = Lists.newArrayList();
|
||||||
builder.self(resourceLinks.index().self());
|
builder.self(resourceLinks.index().self());
|
||||||
builder.single(link("uiPlugins", resourceLinks.uiPluginCollection().self()));
|
builder.single(link("uiPlugins", resourceLinks.uiPluginCollection().self()));
|
||||||
if (SecurityUtils.getSubject().isAuthenticated()) {
|
if (SecurityUtils.getSubject().isAuthenticated()) {
|
||||||
@@ -34,6 +38,13 @@ 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()) {
|
||||||
|
autoCompleteLinks.add(Link.linkBuilder("autocomplete", resourceLinks.autoComplete().users()).withName("users").build());
|
||||||
|
}
|
||||||
|
if (GroupPermissions.autocomplete().isPermitted()) {
|
||||||
|
autoCompleteLinks.add(Link.linkBuilder("autocomplete", resourceLinks.autoComplete().groups()).withName("groups").build());
|
||||||
|
}
|
||||||
|
builder.array(autoCompleteLinks);
|
||||||
if (GroupPermissions.list().isPermitted()) {
|
if (GroupPermissions.list().isPermitted()) {
|
||||||
builder.single(link("groups", resourceLinks.groupCollection().self()));
|
builder.single(link("groups", resourceLinks.groupCollection().self()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,17 +83,7 @@ public class MeResource {
|
|||||||
if (passwordChangeDto.getOldPassword() == null){
|
if (passwordChangeDto.getOldPassword() == null){
|
||||||
throw new ChangePasswordNotAllowedException(ChangePasswordNotAllowedException.OLD_PASSWORD_REQUIRED);
|
throw new ChangePasswordNotAllowedException(ChangePasswordNotAllowedException.OLD_PASSWORD_REQUIRED);
|
||||||
}
|
}
|
||||||
return adapter.changePassword(name, user -> user.clone().changePassword(passwordService.encryptPassword(passwordChangeDto.getNewPassword())), userManager.getChangePasswordChecker().andThen(getOldOriginalPasswordChecker(passwordChangeDto.getOldPassword())));
|
return adapter.changePassword(name, user -> user.clone().changePassword(passwordService.encryptPassword(passwordChangeDto.getNewPassword()), passwordService.encryptPassword(passwordChangeDto.getOldPassword())));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Match given old password from the dto with the stored password before updating
|
|
||||||
*/
|
|
||||||
private Consumer<User> getOldOriginalPasswordChecker(String oldPassword) {
|
|
||||||
return user -> {
|
|
||||||
if (!user.getPassword().equals(passwordService.encryptPassword(oldPassword))) {
|
|
||||||
throw new InvalidPasswordException(INVALID_MATCHING);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ public class UserResource {
|
|||||||
if (currentUserName.equals(name) && passwordChangeDto.getOldPassword() == null){
|
if (currentUserName.equals(name) && passwordChangeDto.getOldPassword() == null){
|
||||||
throw new ChangePasswordNotAllowedException(ChangePasswordNotAllowedException.OLD_PASSWORD_REQUIRED);
|
throw new ChangePasswordNotAllowedException(ChangePasswordNotAllowedException.OLD_PASSWORD_REQUIRED);
|
||||||
}
|
}
|
||||||
return adapter.changePassword(name, user -> user.changePassword(passwordService.encryptPassword(passwordChangeDto.getNewPassword())), userManager.getChangePasswordChecker());
|
return adapter.changePassword(name, user -> user.changePassword(passwordService.encryptPassword(passwordChangeDto.getNewPassword())));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -245,7 +245,8 @@ public class DefaultGroupManager extends AbstractGroupManager
|
|||||||
@Override
|
@Override
|
||||||
public Collection<Group> autocomplete(String filter) {
|
public Collection<Group> autocomplete(String filter) {
|
||||||
GroupPermissions.autocomplete().check();
|
GroupPermissions.autocomplete().check();
|
||||||
return search(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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -235,6 +235,13 @@ public class DefaultUserManager extends AbstractUserManager
|
|||||||
fresh.copyProperties(user);
|
fresh.copyProperties(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<User> autocomplete(String filter) {
|
||||||
|
UserPermissions.autocomplete().check();
|
||||||
|
SearchRequest searchRequest = new SearchRequest(filter, true, DEFAULT_LIMIT);
|
||||||
|
return SearchUtil.search(searchRequest, userDAO.getAll(), user -> matches(searchRequest,user)?user:null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method description
|
* Method description
|
||||||
*
|
*
|
||||||
@@ -306,12 +313,6 @@ public class DefaultUserManager extends AbstractUserManager
|
|||||||
return getAll(null);
|
return getAll(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<User> autocomplete(String filter) {
|
|
||||||
UserPermissions.autocomplete().check();
|
|
||||||
return search(new SearchRequest(filter,true, DEFAULT_LIMIT));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method description
|
* Method description
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
package sonia.scm.api.v2.resources;
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.apache.shiro.subject.Subject;
|
import com.github.sdorra.shiro.ShiroRule;
|
||||||
import org.apache.shiro.subject.support.SubjectThreadState;
|
import com.github.sdorra.shiro.SubjectAware;
|
||||||
import org.apache.shiro.util.ThreadContext;
|
import org.apache.shiro.util.ThreadContext;
|
||||||
import org.apache.shiro.util.ThreadState;
|
|
||||||
import org.assertj.core.util.Lists;
|
import org.assertj.core.util.Lists;
|
||||||
import org.jboss.resteasy.core.Dispatcher;
|
import org.jboss.resteasy.core.Dispatcher;
|
||||||
import org.jboss.resteasy.mock.MockHttpRequest;
|
import org.jboss.resteasy.mock.MockHttpRequest;
|
||||||
import org.jboss.resteasy.mock.MockHttpResponse;
|
import org.jboss.resteasy.mock.MockHttpResponse;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
@@ -43,16 +43,17 @@ import static org.mockito.Mockito.when;
|
|||||||
import static org.mockito.MockitoAnnotations.initMocks;
|
import static org.mockito.MockitoAnnotations.initMocks;
|
||||||
import static sonia.scm.api.v2.resources.DispatcherMock.createDispatcher;
|
import static sonia.scm.api.v2.resources.DispatcherMock.createDispatcher;
|
||||||
|
|
||||||
|
@SubjectAware(configuration = "classpath:sonia/scm/shiro-002.ini")
|
||||||
@RunWith(MockitoJUnitRunner.Silent.class)
|
@RunWith(MockitoJUnitRunner.Silent.class)
|
||||||
public class AutoCompleteResourceTest {
|
public class AutoCompleteResourceTest {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public final ShiroRule shiroRule = new ShiroRule();
|
||||||
|
|
||||||
public static final String URL = "/" + AutoCompleteResource.PATH;
|
public static final String URL = "/" + AutoCompleteResource.PATH;
|
||||||
private final Integer defaultLimit = Manager.DEFAULT_LIMIT;
|
private final Integer defaultLimit = Manager.DEFAULT_LIMIT;
|
||||||
private Dispatcher dispatcher;
|
private Dispatcher dispatcher;
|
||||||
|
|
||||||
private final Subject subject = mock(Subject.class);
|
|
||||||
private final ThreadState subjectThreadState = new SubjectThreadState(subject);
|
|
||||||
|
|
||||||
private XmlUserDAO userDao;
|
private XmlUserDAO userDao;
|
||||||
private XmlGroupDAO groupDao;
|
private XmlGroupDAO groupDao;
|
||||||
private XmlDatabase xmlDB;
|
private XmlDatabase xmlDB;
|
||||||
@@ -75,9 +76,6 @@ public class AutoCompleteResourceTest {
|
|||||||
GroupManager groupManager = new DefaultGroupManager(groupDao);
|
GroupManager groupManager = new DefaultGroupManager(groupDao);
|
||||||
AutoCompleteResource autoCompleteResource = new AutoCompleteResource(mapper, userManager, groupManager);
|
AutoCompleteResource autoCompleteResource = new AutoCompleteResource(mapper, userManager, groupManager);
|
||||||
dispatcher = createDispatcher(autoCompleteResource);
|
dispatcher = createDispatcher(autoCompleteResource);
|
||||||
subjectThreadState.bind();
|
|
||||||
ThreadContext.bind(subject);
|
|
||||||
when(subject.isPermitted(any(String.class))).thenReturn(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
@@ -85,23 +83,10 @@ public class AutoCompleteResourceTest {
|
|||||||
ThreadContext.unbindSubject();
|
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
|
@Test
|
||||||
public void shouldGet400IfParameterLengthLessThan2CharsForUserSearch() throws Exception {
|
public void shouldGet400IfParameterLengthLessThan2CharsForUserSearch() throws Exception {
|
||||||
MockHttpRequest request = MockHttpRequest
|
MockHttpRequest request = MockHttpRequest
|
||||||
.get("/" + AutoCompleteResource.PATH + "user?filter=a")
|
.get("/" + AutoCompleteResource.PATH + "users?q=a")
|
||||||
.contentType(VndMediaType.AUTOCOMPLETE)
|
.contentType(VndMediaType.AUTOCOMPLETE)
|
||||||
.accept(VndMediaType.AUTOCOMPLETE);
|
.accept(VndMediaType.AUTOCOMPLETE);
|
||||||
MockHttpResponse response = new MockHttpResponse();
|
MockHttpResponse response = new MockHttpResponse();
|
||||||
@@ -112,12 +97,27 @@ public class AutoCompleteResourceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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 {
|
public void shouldSearchUsers() throws Exception {
|
||||||
ArrayList<User> users = Lists.newArrayList(createMockUser("YuCantFindMe", "ha ha"), createMockUser("user1", "User 1"), createMockUser("user2", "User 2"));
|
ArrayList<User> users = Lists.newArrayList(createMockUser("YuCantFindMe", "ha ha"), createMockUser("user1", "User 1"), createMockUser("user2", "User 2"));
|
||||||
String searched = "user";
|
String searched = "user";
|
||||||
when(xmlDB.values()).thenReturn(users);
|
when(xmlDB.values()).thenReturn(users);
|
||||||
MockHttpRequest request = MockHttpRequest
|
MockHttpRequest request = MockHttpRequest
|
||||||
.get("/" + AutoCompleteResource.PATH + "user?filter=" + searched)
|
.get("/" + AutoCompleteResource.PATH + "users?q=" + searched)
|
||||||
.contentType(VndMediaType.AUTOCOMPLETE)
|
.contentType(VndMediaType.AUTOCOMPLETE)
|
||||||
.accept(VndMediaType.AUTOCOMPLETE);
|
.accept(VndMediaType.AUTOCOMPLETE);
|
||||||
MockHttpResponse response = new MockHttpResponse();
|
MockHttpResponse response = new MockHttpResponse();
|
||||||
@@ -134,11 +134,27 @@ public class AutoCompleteResourceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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 {
|
public void shouldSearchUsersWithDefaultLimitLength() throws Exception {
|
||||||
List<User> userList = IntStream.range(0, 10).boxed().map(i -> createMockUser("user" + i, "User " + i)).collect(Collectors.toList());
|
List<User> userList = IntStream.range(0, 10).boxed().map(i -> createMockUser("user" + i, "User " + i)).collect(Collectors.toList());
|
||||||
when(xmlDB.values()).thenReturn(userList);
|
when(xmlDB.values()).thenReturn(userList);
|
||||||
MockHttpRequest request = MockHttpRequest
|
MockHttpRequest request = MockHttpRequest
|
||||||
.get("/" + AutoCompleteResource.PATH + "user?filter=user")
|
.get("/" + AutoCompleteResource.PATH + "users?q=user")
|
||||||
.contentType(VndMediaType.AUTOCOMPLETE)
|
.contentType(VndMediaType.AUTOCOMPLETE)
|
||||||
.accept(VndMediaType.AUTOCOMPLETE);
|
.accept(VndMediaType.AUTOCOMPLETE);
|
||||||
MockHttpResponse response = new MockHttpResponse();
|
MockHttpResponse response = new MockHttpResponse();
|
||||||
@@ -150,9 +166,10 @@ public class AutoCompleteResourceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@SubjectAware(username = "trillian", password = "secret")
|
||||||
public void shouldGet400OnFailedParameterForGroupSearch() throws Exception {
|
public void shouldGet400OnFailedParameterForGroupSearch() throws Exception {
|
||||||
MockHttpRequest request = MockHttpRequest
|
MockHttpRequest request = MockHttpRequest
|
||||||
.get("/" + AutoCompleteResource.PATH + "group")
|
.get("/" + AutoCompleteResource.PATH + "groups")
|
||||||
.contentType(VndMediaType.AUTOCOMPLETE)
|
.contentType(VndMediaType.AUTOCOMPLETE)
|
||||||
.accept(VndMediaType.AUTOCOMPLETE);
|
.accept(VndMediaType.AUTOCOMPLETE);
|
||||||
MockHttpResponse response = new MockHttpResponse();
|
MockHttpResponse response = new MockHttpResponse();
|
||||||
@@ -163,9 +180,10 @@ public class AutoCompleteResourceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@SubjectAware(username = "trillian", password = "secret")
|
||||||
public void shouldGet400IfParameterLengthLessThan2CharsForGroupSearch() throws Exception {
|
public void shouldGet400IfParameterLengthLessThan2CharsForGroupSearch() throws Exception {
|
||||||
MockHttpRequest request = MockHttpRequest
|
MockHttpRequest request = MockHttpRequest
|
||||||
.get("/" + AutoCompleteResource.PATH + "group?filter=a")
|
.get("/" + AutoCompleteResource.PATH + "groups?q=a")
|
||||||
.contentType(VndMediaType.AUTOCOMPLETE)
|
.contentType(VndMediaType.AUTOCOMPLETE)
|
||||||
.accept(VndMediaType.AUTOCOMPLETE);
|
.accept(VndMediaType.AUTOCOMPLETE);
|
||||||
MockHttpResponse response = new MockHttpResponse();
|
MockHttpResponse response = new MockHttpResponse();
|
||||||
@@ -176,12 +194,13 @@ public class AutoCompleteResourceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@SubjectAware(username = "trillian", password = "secret")
|
||||||
public void shouldSearchGroups() throws Exception {
|
public void shouldSearchGroups() throws Exception {
|
||||||
ArrayList<Group> groups = Lists.newArrayList(createMockGroup("YuCantFindMe"), createMockGroup("group_1"), createMockGroup("group_2"));
|
ArrayList<Group> groups = Lists.newArrayList(createMockGroup("YuCantFindMe"), createMockGroup("group_1"), createMockGroup("group_2"));
|
||||||
String searched = "group";
|
String searched = "group";
|
||||||
when(xmlDB.values()).thenReturn(groups);
|
when(xmlDB.values()).thenReturn(groups);
|
||||||
MockHttpRequest request = MockHttpRequest
|
MockHttpRequest request = MockHttpRequest
|
||||||
.get("/" + AutoCompleteResource.PATH + "group?filter=" + searched)
|
.get("/" + AutoCompleteResource.PATH + "groups?q=" + searched)
|
||||||
.contentType(VndMediaType.AUTOCOMPLETE)
|
.contentType(VndMediaType.AUTOCOMPLETE)
|
||||||
.accept(VndMediaType.AUTOCOMPLETE);
|
.accept(VndMediaType.AUTOCOMPLETE);
|
||||||
MockHttpResponse response = new MockHttpResponse();
|
MockHttpResponse response = new MockHttpResponse();
|
||||||
@@ -197,11 +216,26 @@ public class AutoCompleteResourceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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 {
|
public void shouldSearchGroupsWithDefaultLimitLength() throws Exception {
|
||||||
List<Group> groups = IntStream.range(0, 10).boxed().map(i -> createMockGroup("group_" + i)).collect(Collectors.toList());
|
List<Group> groups = IntStream.range(0, 10).boxed().map(i -> createMockGroup("group_" + i)).collect(Collectors.toList());
|
||||||
when(xmlDB.values()).thenReturn(groups);
|
when(xmlDB.values()).thenReturn(groups);
|
||||||
MockHttpRequest request = MockHttpRequest
|
MockHttpRequest request = MockHttpRequest
|
||||||
.get("/" + AutoCompleteResource.PATH + "group?filter=group")
|
.get("/" + AutoCompleteResource.PATH + "groups?q=group")
|
||||||
.contentType(VndMediaType.AUTOCOMPLETE)
|
.contentType(VndMediaType.AUTOCOMPLETE)
|
||||||
.accept(VndMediaType.AUTOCOMPLETE);
|
.accept(VndMediaType.AUTOCOMPLETE);
|
||||||
MockHttpResponse response = new MockHttpResponse();
|
MockHttpResponse response = new MockHttpResponse();
|
||||||
|
|||||||
@@ -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,26 @@ 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().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
|
@Test
|
||||||
@SubjectAware(username = "dent", password = "secret")
|
@SubjectAware(username = "dent", password = "secret")
|
||||||
public void shouldRenderAdminLinksIfAuthorized() {
|
public void shouldRenderAdminLinksIfAuthorized() {
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ public class MeResourceTest {
|
|||||||
doNothing().when(userManager).modify(userCaptor.capture());
|
doNothing().when(userManager).modify(userCaptor.capture());
|
||||||
doNothing().when(userManager).delete(userCaptor.capture());
|
doNothing().when(userManager).delete(userCaptor.capture());
|
||||||
when(userManager.isTypeDefault(userCaptor.capture())).thenCallRealMethod();
|
when(userManager.isTypeDefault(userCaptor.capture())).thenCallRealMethod();
|
||||||
when(userManager.getChangePasswordChecker()).thenCallRealMethod();
|
|
||||||
when(userManager.getDefaultType()).thenReturn("xml");
|
when(userManager.getDefaultType()).thenReturn("xml");
|
||||||
MeResource meResource = new MeResource(userToDtoMapper, userManager, passwordService);
|
MeResource meResource = new MeResource(userToDtoMapper, userManager, passwordService);
|
||||||
when(uriInfo.getApiRestUri()).thenReturn(URI.create("/"));
|
when(uriInfo.getApiRestUri()).thenReturn(URI.create("/"));
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -69,7 +69,6 @@ public class UserRootResourceTest {
|
|||||||
originalUser = createDummyUser("Neo");
|
originalUser = createDummyUser("Neo");
|
||||||
when(userManager.create(userCaptor.capture())).thenAnswer(invocation -> invocation.getArguments()[0]);
|
when(userManager.create(userCaptor.capture())).thenAnswer(invocation -> invocation.getArguments()[0]);
|
||||||
when(userManager.isTypeDefault(userCaptor.capture())).thenCallRealMethod();
|
when(userManager.isTypeDefault(userCaptor.capture())).thenCallRealMethod();
|
||||||
when(userManager.getChangePasswordChecker()).thenCallRealMethod();
|
|
||||||
doNothing().when(userManager).modify(userCaptor.capture());
|
doNothing().when(userManager).modify(userCaptor.capture());
|
||||||
doNothing().when(userManager).delete(userCaptor.capture());
|
doNothing().when(userManager).delete(userCaptor.capture());
|
||||||
when(userManager.getDefaultType()).thenReturn("xml");
|
when(userManager.getDefaultType()).thenReturn("xml");
|
||||||
|
|||||||
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