diff --git a/scm-core/src/main/java/sonia/scm/repository/Repository.java b/scm-core/src/main/java/sonia/scm/repository/Repository.java index 3adb215d27..568b75e525 100644 --- a/scm-core/src/main/java/sonia/scm/repository/Repository.java +++ b/scm-core/src/main/java/sonia/scm/repository/Repository.java @@ -80,6 +80,7 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per private Long lastModified; private String namespace; private String name; + @XmlElement(name = "permission") private final Set permissions = new HashSet<>(); @XmlElement(name = "public") private boolean publicReadable = false; diff --git a/scm-dao-xml/src/test/java/sonia/scm/repository/xml/XmlRepositoryDAOTest.java b/scm-dao-xml/src/test/java/sonia/scm/repository/xml/XmlRepositoryDAOTest.java index 6330db56a0..68d8803c89 100644 --- a/scm-dao-xml/src/test/java/sonia/scm/repository/xml/XmlRepositoryDAOTest.java +++ b/scm-dao-xml/src/test/java/sonia/scm/repository/xml/XmlRepositoryDAOTest.java @@ -16,6 +16,7 @@ import sonia.scm.io.FileSystem; import sonia.scm.repository.InitialRepositoryLocationResolver; import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryPermission; import sonia.scm.repository.RepositoryTestData; import java.io.IOException; @@ -23,9 +24,11 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.time.Clock; +import java.util.Arrays; import java.util.Collection; import java.util.concurrent.atomic.AtomicLong; +import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; @@ -329,6 +332,20 @@ class XmlRepositoryDAOTest { assertThat(content).contains("Awesome Spaceship"); } + @Test + void x() throws IOException { + Repository heartOfGold = createHeartOfGold(); + heartOfGold.setPermissions(asList(new RepositoryPermission("trillian", asList("read", "write"), false), new RepositoryPermission("vorgons", asList("delete"), true))); + dao.add(heartOfGold); + + Path repositoryDirectory = getAbsolutePathFromDao(heartOfGold.getId()); + Path metadataPath = dao.resolveMetadataPath(repositoryDirectory); + + String content = content(metadataPath); + System.out.println(content); + assertThat(content).contains("Awesome Spaceship"); + } + @Test void shouldReadPathDatabaseAndMetadataOfRepositories() { Repository heartOfGold = createHeartOfGold(); diff --git a/scm-it/src/test/java/sonia/scm/it/PermissionsITCase.java b/scm-it/src/test/java/sonia/scm/it/PermissionsITCase.java index 15f5e30abc..1f61cdb93a 100644 --- a/scm-it/src/test/java/sonia/scm/it/PermissionsITCase.java +++ b/scm-it/src/test/java/sonia/scm/it/PermissionsITCase.java @@ -58,7 +58,10 @@ import static org.junit.Assert.assertNull; import static sonia.scm.it.utils.RepositoryUtil.addAndCommitRandomFile; import static sonia.scm.it.utils.RestUtil.given; import static sonia.scm.it.utils.ScmTypes.availableScmTypes; +import static sonia.scm.it.utils.TestData.OWNER; +import static sonia.scm.it.utils.TestData.READ; import static sonia.scm.it.utils.TestData.USER_SCM_ADMIN; +import static sonia.scm.it.utils.TestData.WRITE; import static sonia.scm.it.utils.TestData.callRepository; @RunWith(Parameterized.class) @@ -90,13 +93,12 @@ public class PermissionsITCase { public void prepareEnvironment() { TestData.createDefault(); TestData.createNotAdminUser(USER_READ, USER_PASS); - // TODO RP -// TestData.createUserPermission(USER_READ, PermissionType.READ, repositoryType); -// TestData.createNotAdminUser(USER_WRITE, USER_PASS); -// TestData.createUserPermission(USER_WRITE, PermissionType.WRITE, repositoryType); -// TestData.createNotAdminUser(USER_OWNER, USER_PASS); -// TestData.createUserPermission(USER_OWNER, PermissionType.OWNER, repositoryType); -// TestData.createNotAdminUser(USER_OTHER, USER_PASS); + TestData.createUserPermission(USER_READ, READ, repositoryType); + TestData.createNotAdminUser(USER_WRITE, USER_PASS); + TestData.createUserPermission(USER_WRITE, WRITE, repositoryType); + TestData.createNotAdminUser(USER_OWNER, USER_PASS); + TestData.createUserPermission(USER_OWNER, OWNER, repositoryType); + TestData.createNotAdminUser(USER_OTHER, USER_PASS); createdPermissions = asList(USER_READ, USER_WRITE, USER_OWNER); } diff --git a/scm-it/src/test/java/sonia/scm/it/utils/TestData.java b/scm-it/src/test/java/sonia/scm/it/utils/TestData.java index fb92628287..1a2394edda 100644 --- a/scm-it/src/test/java/sonia/scm/it/utils/TestData.java +++ b/scm-it/src/test/java/sonia/scm/it/utils/TestData.java @@ -9,9 +9,11 @@ import sonia.scm.web.VndMediaType; import javax.json.Json; import javax.json.JsonObjectBuilder; import java.net.URI; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import static java.util.Arrays.asList; import static sonia.scm.it.utils.RestUtil.createResourceUrl; @@ -24,6 +26,11 @@ public class TestData { public static final String USER_SCM_ADMIN = "scmadmin"; public static final String USER_ANONYMOUS = "anonymous"; + + public static final Collection READ = asList("read", "pull"); + public static final Collection WRITE = asList("read", "write", "pull", "push"); + public static final Collection OWNER = asList("*"); + private static final List PROTECTED_USERS = asList(USER_SCM_ADMIN, USER_ANONYMOUS); private static Map DEFAULT_REPOSITORIES = new HashMap<>(); @@ -81,23 +88,22 @@ public class TestData { ; } - // TODO RP -// public static void createUserPermission(String name, PermissionType permissionType, String repositoryType) { -// String defaultPermissionUrl = TestData.getDefaultPermissionUrl(USER_SCM_ADMIN, USER_SCM_ADMIN, repositoryType); -// LOG.info("create permission with name {} and type: {} using the endpoint: {}", name, permissionType, defaultPermissionUrl); -// given(VndMediaType.PERMISSION) -// .when() -// .content("{\n" + -// "\t\"type\": \"" + permissionType.name() + "\",\n" + -// "\t\"name\": \"" + name + "\",\n" + -// "\t\"groupPermission\": false\n" + -// "\t\n" + -// "}") -// .post(defaultPermissionUrl) -// .then() -// .statusCode(HttpStatus.SC_CREATED) -// ; -// } + public static void createUserPermission(String name, Collection permissionType, String repositoryType) { + String defaultPermissionUrl = TestData.getDefaultPermissionUrl(USER_SCM_ADMIN, USER_SCM_ADMIN, repositoryType); + LOG.info("create permission with name {} and type: {} using the endpoint: {}", name, permissionType, defaultPermissionUrl); + given(VndMediaType.PERMISSION) + .when() + .content("{\n" + + "\t\"verbs\": " + permissionType.stream().collect(Collectors.joining("\",\"", "[\"", "\"]")) + ",\n" + + "\t\"name\": \"" + name + "\",\n" + + "\t\"groupPermission\": false\n" + + "\t\n" + + "}") + .post(defaultPermissionUrl) + .then() + .statusCode(HttpStatus.SC_CREATED) + ; + } public static List getUserPermissions(String username, String password, String repositoryType) { return callUserPermissions(username, password, repositoryType, HttpStatus.SC_OK) diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionCollectionToDtoMapper.java index 9c05f80de4..5e678212e8 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionCollectionToDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionCollectionToDtoMapper.java @@ -26,12 +26,11 @@ public class RepositoryPermissionCollectionToDtoMapper { } public HalRepresentation map(Repository repository) { -// List repositoryPermissionDtoList = repository.getPermissions() -// .stream() -// .map(permission -> repositoryPermissionToRepositoryPermissionDtoMapper.map(permission, repository)) -// .collect(toList()); -// return new HalRepresentation(createLinks(repository), embedDtos(repositoryPermissionDtoList)); - return new HalRepresentation(createLinks(repository)); + List repositoryPermissionDtoList = repository.getPermissions() + .stream() + .map(permission -> repositoryPermissionToRepositoryPermissionDtoMapper.map(permission, repository)) + .collect(toList()); + return new HalRepresentation(createLinks(repository), embedDtos(repositoryPermissionDtoList)); } private Links createLinks(Repository repository) { diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionDto.java index 6e6b9fd7fc..0699b78e91 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionDto.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionDto.java @@ -10,6 +10,8 @@ import lombok.ToString; import javax.validation.constraints.Pattern; +import java.util.Collection; + import static sonia.scm.api.v2.ValidationConstraints.USER_GROUP_PATTERN; @Getter @Setter @ToString @NoArgsConstructor @@ -20,16 +22,7 @@ public class RepositoryPermissionDto extends HalRepresentation { @Pattern(regexp = USER_GROUP_PATTERN) private String name; - /** - * the type can be replaced with a dto enum if the mapstruct 1.3.0 is stable - * the mapstruct has a Bug on mapping enums in the 1.2.0-Final Version - * - * see the bug fix: https://github.com/mapstruct/mapstruct/commit/460e87eef6eb71245b387fdb0509c726676a8e19 - * - **/ - @JsonInclude(JsonInclude.Include.NON_NULL) - private String type; - + private Collection verbs; private boolean groupPermission = false; @@ -38,7 +31,6 @@ public class RepositoryPermissionDto extends HalRepresentation { this.groupPermission = groupPermission; } - @Override @SuppressWarnings("squid:S1185") // We want to have this method available in this package protected HalRepresentation add(Links links) { diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionRootResource.java index 9c22a5e1b0..97ba519df8 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryPermissionRootResource.java @@ -37,16 +37,19 @@ import static sonia.scm.api.v2.resources.RepositoryPermissionDto.GROUP_PREFIX; @Slf4j public class RepositoryPermissionRootResource { - private RepositoryPermissionDtoToRepositoryPermissionMapper dtoToModelMapper; private RepositoryPermissionToRepositoryPermissionDtoMapper modelToDtoMapper; private RepositoryPermissionCollectionToDtoMapper repositoryPermissionCollectionToDtoMapper; private ResourceLinks resourceLinks; private final RepositoryManager manager; - @Inject - public RepositoryPermissionRootResource(RepositoryPermissionDtoToRepositoryPermissionMapper dtoToModelMapper, RepositoryPermissionToRepositoryPermissionDtoMapper modelToDtoMapper, RepositoryPermissionCollectionToDtoMapper repositoryPermissionCollectionToDtoMapper, ResourceLinks resourceLinks, RepositoryManager manager) { + public RepositoryPermissionRootResource( + RepositoryPermissionDtoToRepositoryPermissionMapper dtoToModelMapper, + RepositoryPermissionToRepositoryPermissionDtoMapper modelToDtoMapper, + RepositoryPermissionCollectionToDtoMapper repositoryPermissionCollectionToDtoMapper, + ResourceLinks resourceLinks, + RepositoryManager manager) { this.dtoToModelMapper = dtoToModelMapper; this.modelToDtoMapper = modelToDtoMapper; this.repositoryPermissionCollectionToDtoMapper = repositoryPermissionCollectionToDtoMapper; @@ -54,7 +57,6 @@ public class RepositoryPermissionRootResource { this.manager = manager; } - /** * Adds a new permission to the user or group managed by the repository * @@ -73,19 +75,17 @@ public class RepositoryPermissionRootResource { @TypeHint(TypeHint.NO_CONTENT.class) @Consumes(VndMediaType.PERMISSION) @Path("") - public Response create(@PathParam("namespace") String namespace, @PathParam("name") String name,@Valid RepositoryPermissionDto permission) { + public Response create(@PathParam("namespace") String namespace, @PathParam("name") String name, @Valid RepositoryPermissionDto permission) { log.info("try to add new permission: {}", permission); Repository repository = load(namespace, name); RepositoryPermissions.permissionWrite(repository).check(); checkPermissionAlreadyExists(permission, repository); - // TODO RP -// repository.addPermission(dtoToModelMapper.map(permission)); + repository.addPermission(dtoToModelMapper.map(permission)); manager.modify(repository); String urlPermissionName = modelToDtoMapper.getUrlPermissionName(permission); return Response.created(URI.create(resourceLinks.repositoryPermission().self(namespace, name, urlPermissionName))).build(); } - /** * Get the searched permission with permission name related to a repository * @@ -107,17 +107,15 @@ public class RepositoryPermissionRootResource { Repository repository = load(namespace, name); RepositoryPermissions.permissionRead(repository).check(); return Response.ok( - // TODO RP -// repository.getPermissions() -// .stream() -// .filter(filterPermission(permissionName)) -// .map(permission -> modelToDtoMapper.map(permission, repository)) -// .findFirst() -// .orElseThrow(() -> notFound(entity(RepositoryPermission.class, namespace).in(Repository.class, namespace + "/" + name))) + repository.getPermissions() + .stream() + .filter(filterPermission(permissionName)) + .map(permission -> modelToDtoMapper.map(permission, repository)) + .findFirst() + .orElseThrow(() -> notFound(entity(RepositoryPermission.class, namespace).in(Repository.class, namespace + "/" + name))) ).build(); } - /** * Get all permissions related to a repository * @@ -141,7 +139,6 @@ public class RepositoryPermissionRootResource { return Response.ok(repositoryPermissionCollectionToDtoMapper.map(repository)).build(); } - /** * Update a permission to the user or group managed by the repository * ignore the user input for groupPermission and take it from the path parameter (if the group prefix (@) exists it is a group permission) @@ -175,13 +172,12 @@ public class RepositoryPermissionRootResource { checkPermissionAlreadyExists(permission, repository); } - // TODO RP -// RepositoryPermission existingPermission = repository.getPermissions() -// .stream() -// .filter(filterPermission(permissionName)) -// .findFirst() -// .orElseThrow(() -> notFound(entity(RepositoryPermission.class, namespace).in(Repository.class, namespace + "/" + name))); -// dtoToModelMapper.modify(existingPermission, permission); + RepositoryPermission existingPermission = repository.getPermissions() + .stream() + .filter(filterPermission(permissionName)) + .findFirst() + .orElseThrow(() -> notFound(entity(RepositoryPermission.class, namespace).in(Repository.class, namespace + "/" + name))); + dtoToModelMapper.modify(existingPermission, permission); manager.modify(repository); log.info("the permission with name: {} is updated.", permissionName); return Response.noContent().build(); @@ -208,22 +204,20 @@ public class RepositoryPermissionRootResource { log.info("try to delete the permission with name: {}.", permissionName); Repository repository = load(namespace, name); RepositoryPermissions.modify(repository).check(); - // TODO RP -// repository.getPermissions() -// .stream() -// .filter(filterPermission(permissionName)) -// .findFirst() -// .ifPresent(repository::removePermission) -// ; + repository.getPermissions() + .stream() + .filter(filterPermission(permissionName)) + .findFirst() + .ifPresent(repository::removePermission); manager.modify(repository); log.info("the permission with name: {} is updated.", permissionName); return Response.noContent().build(); } - Predicate filterPermission(String permissionName) { - return permission -> getPermissionName(permissionName).equals(permission.getName()) + private Predicate filterPermission(String name) { + return permission -> getPermissionName(name).equals(permission.getName()) && - permission.isGroupPermission() == isGroupPermission(permissionName); + permission.isGroupPermission() == isGroupPermission(name); } private String getPermissionName(String permissionName) { @@ -236,7 +230,6 @@ public class RepositoryPermissionRootResource { return permissionName.startsWith(GROUP_PREFIX); } - /** * check if the actual user is permitted to manage the repository permissions * return the repository if the user is permitted @@ -266,10 +259,9 @@ public class RepositoryPermissionRootResource { } private boolean isPermissionExist(RepositoryPermissionDto permission, Repository repository) { - return true; -// return repository.getPermissions() -// .stream() -// .anyMatch(p -> p.getName().equals(permission.getName()) && p.isGroupPermission() == permission.isGroupPermission()); + return repository.getPermissions() + .stream() + .anyMatch(p -> p.getName().equals(permission.getName()) && p.isGroupPermission() == permission.isGroupPermission()); } } diff --git a/scm-webapp/src/main/java/sonia/scm/security/DefaultAuthorizationCollector.java b/scm-webapp/src/main/java/sonia/scm/security/DefaultAuthorizationCollector.java index e015ed90f6..1e0bffa568 100644 --- a/scm-webapp/src/main/java/sonia/scm/security/DefaultAuthorizationCollector.java +++ b/scm-webapp/src/main/java/sonia/scm/security/DefaultAuthorizationCollector.java @@ -63,7 +63,6 @@ import sonia.scm.user.UserPermissions; import sonia.scm.util.Util; import java.util.Collection; -import java.util.Collections; import java.util.Set; //~--- JDK imports ------------------------------------------------------------ @@ -199,12 +198,7 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector private void collectRepositoryPermissions(Builder builder, Repository repository, User user, GroupNames groups) { - - // TODO RP - - Collection repositoryPermissions - = Collections.emptyList(); -// = repository.getPermissions(); + Collection repositoryPermissions = repository.getPermissions(); if (Util.isNotEmpty(repositoryPermissions)) { @@ -214,7 +208,7 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector hasPermission = isUserPermitted(user, groups, permission); if (hasPermission) { - String perm = null; // TODO RP permission.getType().getPermissionPrefix().concat(repository.getId()); + String perm = "repository:" + String.join(",", permission.getVerbs()) + ":" + repository.getId(); if (logger.isTraceEnabled()) { logger.trace("add repository permission {} for user {} at repository {}", diff --git a/scm-webapp/src/main/resources/META-INF/scm/repository-permissions.xml b/scm-webapp/src/main/resources/META-INF/scm/repository-permissions.xml index 9df450efb0..89d47e156f 100644 --- a/scm-webapp/src/main/resources/META-INF/scm/repository-permissions.xml +++ b/scm-webapp/src/main/resources/META-INF/scm/repository-permissions.xml @@ -14,8 +14,8 @@ WRITER read - push pull + push diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryPermissionRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryPermissionRootResourceTest.java index 9fe13a71d8..6f44b8d522 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryPermissionRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryPermissionRootResourceTest.java @@ -1,5 +1,6 @@ package sonia.scm.api.v2.resources; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.sdorra.shiro.ShiroRule; import com.github.sdorra.shiro.SubjectAware; @@ -29,9 +30,9 @@ import org.junit.jupiter.api.TestFactory; import org.mockito.InjectMocks; import org.mockito.Mock; import sonia.scm.repository.NamespaceAndName; -import sonia.scm.repository.RepositoryPermission; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryManager; +import sonia.scm.repository.RepositoryPermission; import sonia.scm.web.VndMediaType; import java.io.IOException; @@ -47,6 +48,7 @@ import java.util.stream.Stream; import static de.otto.edison.hal.Link.link; import static de.otto.edison.hal.Links.linkingTo; import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; @@ -76,7 +78,7 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase { private static final String PERMISSION_NAME = "perm"; private static final String PATH_OF_ALL_PERMISSIONS = REPOSITORY_NAMESPACE + "/" + REPOSITORY_NAME + "/permissions/"; private static final String PATH_OF_ONE_PERMISSION = PATH_OF_ALL_PERMISSIONS + PERMISSION_NAME; - private static final String PERMISSION_TEST_PAYLOAD = "{ \"name\" : \"permission_name\", \"type\" : \"READ\" }"; + private static final String PERMISSION_TEST_PAYLOAD = "{ \"name\" : \"permission_name\", \"verbs\" : [\"read\",\"pull\"] }"; private static final ArrayList TEST_PERMISSIONS = Lists .newArrayList( new RepositoryPermission("user_write", asList("read","modify"), false), @@ -232,7 +234,7 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase { public void shouldGet400OnCreatingNewPermissionWithNotAllowedCharacters() throws URISyntaxException { // the @ character at the begin of the name is not allowed createUserWithRepository("user"); - String permissionJson = "{ \"name\": \"@permission\", \"type\": \"OWNER\" }"; + String permissionJson = "{ \"name\": \"@permission\", \"verbs\": [\"*\"] }"; MockHttpRequest request = MockHttpRequest .post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + PATH_OF_ALL_PERMISSIONS) .content(permissionJson.getBytes()) @@ -244,7 +246,7 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase { assertEquals(400, response.getStatus()); // the whitespace at the begin opf the name is not allowed - permissionJson = "{ \"name\": \" permission\", \"type\": \"OWNER\" }"; + permissionJson = "{ \"name\": \" permission\", \"verbs\": [\"*\"] }"; request = MockHttpRequest .post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + PATH_OF_ALL_PERMISSIONS) .content(permissionJson.getBytes()) @@ -259,12 +261,12 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase { @Test public void shouldGetCreatedPermissions() throws URISyntaxException { createUserWithRepositoryAndPermissions(TEST_PERMISSIONS, PERMISSION_WRITE); - RepositoryPermission newPermission = new RepositoryPermission("new_group_perm", asList("read","modify"), true); + RepositoryPermission newPermission = new RepositoryPermission("new_group_perm", asList("read", "pull", "push"), true); ArrayList permissions = Lists.newArrayList(TEST_PERMISSIONS); permissions.add(newPermission); ImmutableList expectedPermissions = ImmutableList.copyOf(permissions); assertExpectedRequest(requestPOSTPermission - .content("{\"name\" : \"" + newPermission.getName() + "\" , \"type\" : \"WRITE\" , \"groupPermission\" : true}") + .content("{\"name\" : \"" + newPermission.getName() + "\" , \"verbs\" : [\"read\",\"pull\",\"push\"], \"groupPermission\" : true}") .expectedResponseStatus(201) .responseValidator(response -> assertThat(response.getContentAsString()) .as("POST response has no body") @@ -278,7 +280,7 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase { createUserWithRepositoryAndPermissions(TEST_PERMISSIONS, PERMISSION_WRITE); RepositoryPermission newPermission = TEST_PERMISSIONS.get(0); assertExpectedRequest(requestPOSTPermission - .content("{\"name\" : \"" + newPermission.getName() + "\" , \"type\" : \"WRITE\" , \"groupPermission\" : false}") + .content("{\"name\" : \"" + newPermission.getName() + "\" , \"verbs\" : [\"read\",\"pull\",\"push\"], \"groupPermission\" : false}") .expectedResponseStatus(409) ); } @@ -288,10 +290,10 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase { createUserWithRepositoryAndPermissions(TEST_PERMISSIONS, PERMISSION_WRITE); RepositoryPermission modifiedPermission = TEST_PERMISSIONS.get(0); // modify the type to owner - modifiedPermission.setVerbs(asList("read", "modify", "delete")); + modifiedPermission.setVerbs(new ArrayList<>(singletonList("*"))); ImmutableList expectedPermissions = ImmutableList.copyOf(TEST_PERMISSIONS); assertExpectedRequest(requestPUTPermission - .content("{\"name\" : \"" + modifiedPermission.getName() + "\" , \"type\" : \"OWNER\" , \"groupPermission\" : false}") + .content("{\"name\" : \"" + modifiedPermission.getName() + "\" , \"verbs\" : [\"*\"], \"groupPermission\" : false}") .path(PATH_OF_ALL_PERMISSIONS + modifiedPermission.getName()) .expectedResponseStatus(204) .responseValidator(response -> assertThat(response.getContentAsString()) @@ -353,7 +355,10 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase { .map(hal -> { RepositoryPermissionDto result = new RepositoryPermissionDto(); result.setName(hal.getAttribute("name").asText()); - result.setType(hal.getAttribute("type").asText()); + JsonNode attribute = hal.getAttribute("verbs"); + List verbs = new ArrayList<>(); + attribute.iterator().forEachRemaining(v -> verbs.add(v.asText())); + result.setVerbs(verbs); result.setGroupPermission(hal.getAttribute("groupPermission").asBoolean()); result.add(hal.getLinks()); return result; @@ -382,7 +387,7 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase { RepositoryPermissionDto result = new RepositoryPermissionDto(); result.setName(permission.getName()); result.setGroupPermission(permission.isGroupPermission()); -// result.setType(permission.getVerbs()); TODO RP + result.setVerbs(permission.getVerbs()); String permissionName = Optional.of(permission.getName()) .filter(p -> !permission.isGroupPermission()) .orElse(GROUP_PREFIX + permission.getName()); @@ -412,8 +417,7 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase { } private void createUserWithRepositoryAndPermissions(ArrayList permissions, String userPermission) { - // TODO RP -// createUserWithRepository(userPermission).setPermissions(permissions); + createUserWithRepository(userPermission).setPermissions(permissions); } private Stream createDynamicTestsToAssertResponses(ExpectedRequest... expectedRequests) { diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java index a18b63c53f..bf4366f0b2 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java @@ -38,9 +38,8 @@ import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT; import static javax.servlet.http.HttpServletResponse.SC_OK; import static javax.servlet.http.HttpServletResponse.SC_PRECONDITION_FAILED; -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyObject; @@ -286,13 +285,12 @@ public class RepositoryRootResourceTest extends RepositoryTestBase { dispatcher.invoke(request, response); - // TODO RP -// Assertions.assertThat(createCaptor.getValue().getPermissions()) -// .hasSize(1) -// .allSatisfy(p -> { -// assertThat(p.getName()).isEqualTo("trillian"); -// assertThat(p.getType()).isEqualTo(PermissionType.OWNER); -// }); + assertThat(createCaptor.getValue().getPermissions()) + .hasSize(1) + .allSatisfy(p -> { + assertThat(p.getName()).isEqualTo("trillian"); + assertThat(p.getVerbs()).containsExactly("*"); + }); } @Test diff --git a/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java b/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java index 242c9b3047..a377337eea 100644 --- a/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java +++ b/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java @@ -116,17 +116,6 @@ public class GitLfsITCase { @Test public void testLfsAPIWithOwnerPermissions() throws IOException { - // TODO RP - uploadAndDownloadAsUser(); - } - - @Test - public void testLfsAPIWithWritePermissions() throws IOException { - // TODO RP - uploadAndDownloadAsUser(); - } - - private void uploadAndDownloadAsUser() throws IOException { User trillian = UserTestData.createTrillian(); trillian.setPassword("secret123"); createUser(trillian); diff --git a/scm-webapp/src/test/java/sonia/scm/security/DefaultAuthorizationCollectorTest.java b/scm-webapp/src/test/java/sonia/scm/security/DefaultAuthorizationCollectorTest.java index d04c35686f..e9345c9599 100644 --- a/scm-webapp/src/test/java/sonia/scm/security/DefaultAuthorizationCollectorTest.java +++ b/scm-webapp/src/test/java/sonia/scm/security/DefaultAuthorizationCollectorTest.java @@ -225,12 +225,11 @@ public class DefaultAuthorizationCollectorTest { authenticate(UserTestData.createTrillian(), group); Repository heartOfGold = RepositoryTestData.createHeartOfGold(); heartOfGold.setId("one"); - // TODO RP -// heartOfGold.setPermissions(Lists.newArrayList(new RepositoryPermission("trillian"))); + heartOfGold.setPermissions(Lists.newArrayList(new RepositoryPermission("trillian", asList("read", "pull"), false))); Repository puzzle42 = RepositoryTestData.create42Puzzle(); puzzle42.setId("two"); - RepositoryPermission permission = new RepositoryPermission(group, asList("read","modify"), true); -// puzzle42.setPermissions(Lists.newArrayList(permission)); + RepositoryPermission permission = new RepositoryPermission(group, asList("read", "pull", "push"), true); + puzzle42.setPermissions(Lists.newArrayList(permission)); when(repositoryDAO.getAll()).thenReturn(Lists.newArrayList(heartOfGold, puzzle42)); // execute and assert