mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-09 15:05:44 +01:00
Fix repository permission rest interface
This commit is contained in:
@@ -80,6 +80,7 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per
|
|||||||
private Long lastModified;
|
private Long lastModified;
|
||||||
private String namespace;
|
private String namespace;
|
||||||
private String name;
|
private String name;
|
||||||
|
@XmlElement(name = "permission")
|
||||||
private final Set<RepositoryPermission> permissions = new HashSet<>();
|
private final Set<RepositoryPermission> permissions = new HashSet<>();
|
||||||
@XmlElement(name = "public")
|
@XmlElement(name = "public")
|
||||||
private boolean publicReadable = false;
|
private boolean publicReadable = false;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import sonia.scm.io.FileSystem;
|
|||||||
import sonia.scm.repository.InitialRepositoryLocationResolver;
|
import sonia.scm.repository.InitialRepositoryLocationResolver;
|
||||||
import sonia.scm.repository.NamespaceAndName;
|
import sonia.scm.repository.NamespaceAndName;
|
||||||
import sonia.scm.repository.Repository;
|
import sonia.scm.repository.Repository;
|
||||||
|
import sonia.scm.repository.RepositoryPermission;
|
||||||
import sonia.scm.repository.RepositoryTestData;
|
import sonia.scm.repository.RepositoryTestData;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -23,9 +24,11 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
@@ -329,6 +332,20 @@ class XmlRepositoryDAOTest {
|
|||||||
assertThat(content).contains("Awesome Spaceship");
|
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
|
@Test
|
||||||
void shouldReadPathDatabaseAndMetadataOfRepositories() {
|
void shouldReadPathDatabaseAndMetadataOfRepositories() {
|
||||||
Repository heartOfGold = createHeartOfGold();
|
Repository heartOfGold = createHeartOfGold();
|
||||||
|
|||||||
@@ -58,7 +58,10 @@ import static org.junit.Assert.assertNull;
|
|||||||
import static sonia.scm.it.utils.RepositoryUtil.addAndCommitRandomFile;
|
import static sonia.scm.it.utils.RepositoryUtil.addAndCommitRandomFile;
|
||||||
import static sonia.scm.it.utils.RestUtil.given;
|
import static sonia.scm.it.utils.RestUtil.given;
|
||||||
import static sonia.scm.it.utils.ScmTypes.availableScmTypes;
|
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.USER_SCM_ADMIN;
|
||||||
|
import static sonia.scm.it.utils.TestData.WRITE;
|
||||||
import static sonia.scm.it.utils.TestData.callRepository;
|
import static sonia.scm.it.utils.TestData.callRepository;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
@@ -90,13 +93,12 @@ public class PermissionsITCase {
|
|||||||
public void prepareEnvironment() {
|
public void prepareEnvironment() {
|
||||||
TestData.createDefault();
|
TestData.createDefault();
|
||||||
TestData.createNotAdminUser(USER_READ, USER_PASS);
|
TestData.createNotAdminUser(USER_READ, USER_PASS);
|
||||||
// TODO RP
|
TestData.createUserPermission(USER_READ, READ, repositoryType);
|
||||||
// TestData.createUserPermission(USER_READ, PermissionType.READ, repositoryType);
|
TestData.createNotAdminUser(USER_WRITE, USER_PASS);
|
||||||
// TestData.createNotAdminUser(USER_WRITE, USER_PASS);
|
TestData.createUserPermission(USER_WRITE, WRITE, repositoryType);
|
||||||
// TestData.createUserPermission(USER_WRITE, PermissionType.WRITE, repositoryType);
|
TestData.createNotAdminUser(USER_OWNER, USER_PASS);
|
||||||
// TestData.createNotAdminUser(USER_OWNER, USER_PASS);
|
TestData.createUserPermission(USER_OWNER, OWNER, repositoryType);
|
||||||
// TestData.createUserPermission(USER_OWNER, PermissionType.OWNER, repositoryType);
|
TestData.createNotAdminUser(USER_OTHER, USER_PASS);
|
||||||
// TestData.createNotAdminUser(USER_OTHER, USER_PASS);
|
|
||||||
createdPermissions = asList(USER_READ, USER_WRITE, USER_OWNER);
|
createdPermissions = asList(USER_READ, USER_WRITE, USER_OWNER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,11 @@ import sonia.scm.web.VndMediaType;
|
|||||||
import javax.json.Json;
|
import javax.json.Json;
|
||||||
import javax.json.JsonObjectBuilder;
|
import javax.json.JsonObjectBuilder;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
import static sonia.scm.it.utils.RestUtil.createResourceUrl;
|
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_SCM_ADMIN = "scmadmin";
|
||||||
public static final String USER_ANONYMOUS = "anonymous";
|
public static final String USER_ANONYMOUS = "anonymous";
|
||||||
|
|
||||||
|
public static final Collection<String> READ = asList("read", "pull");
|
||||||
|
public static final Collection<String> WRITE = asList("read", "write", "pull", "push");
|
||||||
|
public static final Collection<String> OWNER = asList("*");
|
||||||
|
|
||||||
private static final List<String> PROTECTED_USERS = asList(USER_SCM_ADMIN, USER_ANONYMOUS);
|
private static final List<String> PROTECTED_USERS = asList(USER_SCM_ADMIN, USER_ANONYMOUS);
|
||||||
|
|
||||||
private static Map<String, String> DEFAULT_REPOSITORIES = new HashMap<>();
|
private static Map<String, String> DEFAULT_REPOSITORIES = new HashMap<>();
|
||||||
@@ -81,23 +88,22 @@ public class TestData {
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO RP
|
public static void createUserPermission(String name, Collection<String> 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);
|
LOG.info("create permission with name {} and type: {} using the endpoint: {}", name, permissionType, defaultPermissionUrl);
|
||||||
// LOG.info("create permission with name {} and type: {} using the endpoint: {}", name, permissionType, defaultPermissionUrl);
|
given(VndMediaType.PERMISSION)
|
||||||
// given(VndMediaType.PERMISSION)
|
.when()
|
||||||
// .when()
|
.content("{\n" +
|
||||||
// .content("{\n" +
|
"\t\"verbs\": " + permissionType.stream().collect(Collectors.joining("\",\"", "[\"", "\"]")) + ",\n" +
|
||||||
// "\t\"type\": \"" + permissionType.name() + "\",\n" +
|
"\t\"name\": \"" + name + "\",\n" +
|
||||||
// "\t\"name\": \"" + name + "\",\n" +
|
"\t\"groupPermission\": false\n" +
|
||||||
// "\t\"groupPermission\": false\n" +
|
"\t\n" +
|
||||||
// "\t\n" +
|
"}")
|
||||||
// "}")
|
.post(defaultPermissionUrl)
|
||||||
// .post(defaultPermissionUrl)
|
.then()
|
||||||
// .then()
|
.statusCode(HttpStatus.SC_CREATED)
|
||||||
// .statusCode(HttpStatus.SC_CREATED)
|
;
|
||||||
// ;
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
public static List<Map> getUserPermissions(String username, String password, String repositoryType) {
|
public static List<Map> getUserPermissions(String username, String password, String repositoryType) {
|
||||||
return callUserPermissions(username, password, repositoryType, HttpStatus.SC_OK)
|
return callUserPermissions(username, password, repositoryType, HttpStatus.SC_OK)
|
||||||
|
|||||||
@@ -26,12 +26,11 @@ public class RepositoryPermissionCollectionToDtoMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public HalRepresentation map(Repository repository) {
|
public HalRepresentation map(Repository repository) {
|
||||||
// List<RepositoryPermissionDto> repositoryPermissionDtoList = repository.getPermissions()
|
List<RepositoryPermissionDto> repositoryPermissionDtoList = repository.getPermissions()
|
||||||
// .stream()
|
.stream()
|
||||||
// .map(permission -> repositoryPermissionToRepositoryPermissionDtoMapper.map(permission, repository))
|
.map(permission -> repositoryPermissionToRepositoryPermissionDtoMapper.map(permission, repository))
|
||||||
// .collect(toList());
|
.collect(toList());
|
||||||
// return new HalRepresentation(createLinks(repository), embedDtos(repositoryPermissionDtoList));
|
return new HalRepresentation(createLinks(repository), embedDtos(repositoryPermissionDtoList));
|
||||||
return new HalRepresentation(createLinks(repository));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Links createLinks(Repository repository) {
|
private Links createLinks(Repository repository) {
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import lombok.ToString;
|
|||||||
|
|
||||||
import javax.validation.constraints.Pattern;
|
import javax.validation.constraints.Pattern;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import static sonia.scm.api.v2.ValidationConstraints.USER_GROUP_PATTERN;
|
import static sonia.scm.api.v2.ValidationConstraints.USER_GROUP_PATTERN;
|
||||||
|
|
||||||
@Getter @Setter @ToString @NoArgsConstructor
|
@Getter @Setter @ToString @NoArgsConstructor
|
||||||
@@ -20,16 +22,7 @@ public class RepositoryPermissionDto extends HalRepresentation {
|
|||||||
@Pattern(regexp = USER_GROUP_PATTERN)
|
@Pattern(regexp = USER_GROUP_PATTERN)
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
/**
|
private Collection<String> verbs;
|
||||||
* 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 boolean groupPermission = false;
|
private boolean groupPermission = false;
|
||||||
|
|
||||||
@@ -38,7 +31,6 @@ public class RepositoryPermissionDto extends HalRepresentation {
|
|||||||
this.groupPermission = groupPermission;
|
this.groupPermission = groupPermission;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("squid:S1185") // We want to have this method available in this package
|
@SuppressWarnings("squid:S1185") // We want to have this method available in this package
|
||||||
protected HalRepresentation add(Links links) {
|
protected HalRepresentation add(Links links) {
|
||||||
|
|||||||
@@ -37,16 +37,19 @@ import static sonia.scm.api.v2.resources.RepositoryPermissionDto.GROUP_PREFIX;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class RepositoryPermissionRootResource {
|
public class RepositoryPermissionRootResource {
|
||||||
|
|
||||||
|
|
||||||
private RepositoryPermissionDtoToRepositoryPermissionMapper dtoToModelMapper;
|
private RepositoryPermissionDtoToRepositoryPermissionMapper dtoToModelMapper;
|
||||||
private RepositoryPermissionToRepositoryPermissionDtoMapper modelToDtoMapper;
|
private RepositoryPermissionToRepositoryPermissionDtoMapper modelToDtoMapper;
|
||||||
private RepositoryPermissionCollectionToDtoMapper repositoryPermissionCollectionToDtoMapper;
|
private RepositoryPermissionCollectionToDtoMapper repositoryPermissionCollectionToDtoMapper;
|
||||||
private ResourceLinks resourceLinks;
|
private ResourceLinks resourceLinks;
|
||||||
private final RepositoryManager manager;
|
private final RepositoryManager manager;
|
||||||
|
|
||||||
|
|
||||||
@Inject
|
@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.dtoToModelMapper = dtoToModelMapper;
|
||||||
this.modelToDtoMapper = modelToDtoMapper;
|
this.modelToDtoMapper = modelToDtoMapper;
|
||||||
this.repositoryPermissionCollectionToDtoMapper = repositoryPermissionCollectionToDtoMapper;
|
this.repositoryPermissionCollectionToDtoMapper = repositoryPermissionCollectionToDtoMapper;
|
||||||
@@ -54,7 +57,6 @@ public class RepositoryPermissionRootResource {
|
|||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a new permission to the user or group managed by the repository
|
* Adds a new permission to the user or group managed by the repository
|
||||||
*
|
*
|
||||||
@@ -78,14 +80,12 @@ public class RepositoryPermissionRootResource {
|
|||||||
Repository repository = load(namespace, name);
|
Repository repository = load(namespace, name);
|
||||||
RepositoryPermissions.permissionWrite(repository).check();
|
RepositoryPermissions.permissionWrite(repository).check();
|
||||||
checkPermissionAlreadyExists(permission, repository);
|
checkPermissionAlreadyExists(permission, repository);
|
||||||
// TODO RP
|
repository.addPermission(dtoToModelMapper.map(permission));
|
||||||
// repository.addPermission(dtoToModelMapper.map(permission));
|
|
||||||
manager.modify(repository);
|
manager.modify(repository);
|
||||||
String urlPermissionName = modelToDtoMapper.getUrlPermissionName(permission);
|
String urlPermissionName = modelToDtoMapper.getUrlPermissionName(permission);
|
||||||
return Response.created(URI.create(resourceLinks.repositoryPermission().self(namespace, name, urlPermissionName))).build();
|
return Response.created(URI.create(resourceLinks.repositoryPermission().self(namespace, name, urlPermissionName))).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the searched permission with permission name related to a repository
|
* Get the searched permission with permission name related to a repository
|
||||||
*
|
*
|
||||||
@@ -107,17 +107,15 @@ public class RepositoryPermissionRootResource {
|
|||||||
Repository repository = load(namespace, name);
|
Repository repository = load(namespace, name);
|
||||||
RepositoryPermissions.permissionRead(repository).check();
|
RepositoryPermissions.permissionRead(repository).check();
|
||||||
return Response.ok(
|
return Response.ok(
|
||||||
// TODO RP
|
repository.getPermissions()
|
||||||
// repository.getPermissions()
|
.stream()
|
||||||
// .stream()
|
.filter(filterPermission(permissionName))
|
||||||
// .filter(filterPermission(permissionName))
|
.map(permission -> modelToDtoMapper.map(permission, repository))
|
||||||
// .map(permission -> modelToDtoMapper.map(permission, repository))
|
.findFirst()
|
||||||
// .findFirst()
|
.orElseThrow(() -> notFound(entity(RepositoryPermission.class, namespace).in(Repository.class, namespace + "/" + name)))
|
||||||
// .orElseThrow(() -> notFound(entity(RepositoryPermission.class, namespace).in(Repository.class, namespace + "/" + name)))
|
|
||||||
).build();
|
).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all permissions related to a repository
|
* Get all permissions related to a repository
|
||||||
*
|
*
|
||||||
@@ -141,7 +139,6 @@ public class RepositoryPermissionRootResource {
|
|||||||
return Response.ok(repositoryPermissionCollectionToDtoMapper.map(repository)).build();
|
return Response.ok(repositoryPermissionCollectionToDtoMapper.map(repository)).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a permission to the user or group managed by the repository
|
* 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)
|
* 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);
|
checkPermissionAlreadyExists(permission, repository);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO RP
|
RepositoryPermission existingPermission = repository.getPermissions()
|
||||||
// RepositoryPermission existingPermission = repository.getPermissions()
|
.stream()
|
||||||
// .stream()
|
.filter(filterPermission(permissionName))
|
||||||
// .filter(filterPermission(permissionName))
|
.findFirst()
|
||||||
// .findFirst()
|
.orElseThrow(() -> notFound(entity(RepositoryPermission.class, namespace).in(Repository.class, namespace + "/" + name)));
|
||||||
// .orElseThrow(() -> notFound(entity(RepositoryPermission.class, namespace).in(Repository.class, namespace + "/" + name)));
|
dtoToModelMapper.modify(existingPermission, permission);
|
||||||
// dtoToModelMapper.modify(existingPermission, permission);
|
|
||||||
manager.modify(repository);
|
manager.modify(repository);
|
||||||
log.info("the permission with name: {} is updated.", permissionName);
|
log.info("the permission with name: {} is updated.", permissionName);
|
||||||
return Response.noContent().build();
|
return Response.noContent().build();
|
||||||
@@ -208,22 +204,20 @@ public class RepositoryPermissionRootResource {
|
|||||||
log.info("try to delete the permission with name: {}.", permissionName);
|
log.info("try to delete the permission with name: {}.", permissionName);
|
||||||
Repository repository = load(namespace, name);
|
Repository repository = load(namespace, name);
|
||||||
RepositoryPermissions.modify(repository).check();
|
RepositoryPermissions.modify(repository).check();
|
||||||
// TODO RP
|
repository.getPermissions()
|
||||||
// repository.getPermissions()
|
.stream()
|
||||||
// .stream()
|
.filter(filterPermission(permissionName))
|
||||||
// .filter(filterPermission(permissionName))
|
.findFirst()
|
||||||
// .findFirst()
|
.ifPresent(repository::removePermission);
|
||||||
// .ifPresent(repository::removePermission)
|
|
||||||
// ;
|
|
||||||
manager.modify(repository);
|
manager.modify(repository);
|
||||||
log.info("the permission with name: {} is updated.", permissionName);
|
log.info("the permission with name: {} is updated.", permissionName);
|
||||||
return Response.noContent().build();
|
return Response.noContent().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
Predicate<RepositoryPermission> filterPermission(String permissionName) {
|
private Predicate<RepositoryPermission> filterPermission(String name) {
|
||||||
return permission -> getPermissionName(permissionName).equals(permission.getName())
|
return permission -> getPermissionName(name).equals(permission.getName())
|
||||||
&&
|
&&
|
||||||
permission.isGroupPermission() == isGroupPermission(permissionName);
|
permission.isGroupPermission() == isGroupPermission(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getPermissionName(String permissionName) {
|
private String getPermissionName(String permissionName) {
|
||||||
@@ -236,7 +230,6 @@ public class RepositoryPermissionRootResource {
|
|||||||
return permissionName.startsWith(GROUP_PREFIX);
|
return permissionName.startsWith(GROUP_PREFIX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check if the actual user is permitted to manage the repository permissions
|
* check if the actual user is permitted to manage the repository permissions
|
||||||
* return the repository if the user is permitted
|
* return the repository if the user is permitted
|
||||||
@@ -266,10 +259,9 @@ public class RepositoryPermissionRootResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isPermissionExist(RepositoryPermissionDto permission, Repository repository) {
|
private boolean isPermissionExist(RepositoryPermissionDto permission, Repository repository) {
|
||||||
return true;
|
return repository.getPermissions()
|
||||||
// return repository.getPermissions()
|
.stream()
|
||||||
// .stream()
|
.anyMatch(p -> p.getName().equals(permission.getName()) && p.isGroupPermission() == permission.isGroupPermission());
|
||||||
// .anyMatch(p -> p.getName().equals(permission.getName()) && p.isGroupPermission() == permission.isGroupPermission());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,6 @@ import sonia.scm.user.UserPermissions;
|
|||||||
import sonia.scm.util.Util;
|
import sonia.scm.util.Util;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
@@ -199,12 +198,7 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector
|
|||||||
private void collectRepositoryPermissions(Builder<String> builder,
|
private void collectRepositoryPermissions(Builder<String> builder,
|
||||||
Repository repository, User user, GroupNames groups)
|
Repository repository, User user, GroupNames groups)
|
||||||
{
|
{
|
||||||
|
Collection<RepositoryPermission> repositoryPermissions = repository.getPermissions();
|
||||||
// TODO RP
|
|
||||||
|
|
||||||
Collection<RepositoryPermission> repositoryPermissions
|
|
||||||
= Collections.emptyList();
|
|
||||||
// = repository.getPermissions();
|
|
||||||
|
|
||||||
if (Util.isNotEmpty(repositoryPermissions))
|
if (Util.isNotEmpty(repositoryPermissions))
|
||||||
{
|
{
|
||||||
@@ -214,7 +208,7 @@ public class DefaultAuthorizationCollector implements AuthorizationCollector
|
|||||||
hasPermission = isUserPermitted(user, groups, permission);
|
hasPermission = isUserPermitted(user, groups, permission);
|
||||||
if (hasPermission)
|
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())
|
if (logger.isTraceEnabled())
|
||||||
{
|
{
|
||||||
logger.trace("add repository permission {} for user {} at repository {}",
|
logger.trace("add repository permission {} for user {} at repository {}",
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
<name>WRITER</name>
|
<name>WRITER</name>
|
||||||
<verbs>
|
<verbs>
|
||||||
<verb>read</verb>
|
<verb>read</verb>
|
||||||
<verb>push</verb>
|
|
||||||
<verb>pull</verb>
|
<verb>pull</verb>
|
||||||
|
<verb>push</verb>
|
||||||
</verbs>
|
</verbs>
|
||||||
</role>
|
</role>
|
||||||
<role>
|
<role>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package sonia.scm.api.v2.resources;
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.github.sdorra.shiro.ShiroRule;
|
import com.github.sdorra.shiro.ShiroRule;
|
||||||
import com.github.sdorra.shiro.SubjectAware;
|
import com.github.sdorra.shiro.SubjectAware;
|
||||||
@@ -29,9 +30,9 @@ import org.junit.jupiter.api.TestFactory;
|
|||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import sonia.scm.repository.NamespaceAndName;
|
import sonia.scm.repository.NamespaceAndName;
|
||||||
import sonia.scm.repository.RepositoryPermission;
|
|
||||||
import sonia.scm.repository.Repository;
|
import sonia.scm.repository.Repository;
|
||||||
import sonia.scm.repository.RepositoryManager;
|
import sonia.scm.repository.RepositoryManager;
|
||||||
|
import sonia.scm.repository.RepositoryPermission;
|
||||||
import sonia.scm.web.VndMediaType;
|
import sonia.scm.web.VndMediaType;
|
||||||
|
|
||||||
import java.io.IOException;
|
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.Link.link;
|
||||||
import static de.otto.edison.hal.Links.linkingTo;
|
import static de.otto.edison.hal.Links.linkingTo;
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.fail;
|
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 PERMISSION_NAME = "perm";
|
||||||
private static final String PATH_OF_ALL_PERMISSIONS = REPOSITORY_NAMESPACE + "/" + REPOSITORY_NAME + "/permissions/";
|
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 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<RepositoryPermission> TEST_PERMISSIONS = Lists
|
private static final ArrayList<RepositoryPermission> TEST_PERMISSIONS = Lists
|
||||||
.newArrayList(
|
.newArrayList(
|
||||||
new RepositoryPermission("user_write", asList("read","modify"), false),
|
new RepositoryPermission("user_write", asList("read","modify"), false),
|
||||||
@@ -232,7 +234,7 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase {
|
|||||||
public void shouldGet400OnCreatingNewPermissionWithNotAllowedCharacters() throws URISyntaxException {
|
public void shouldGet400OnCreatingNewPermissionWithNotAllowedCharacters() throws URISyntaxException {
|
||||||
// the @ character at the begin of the name is not allowed
|
// the @ character at the begin of the name is not allowed
|
||||||
createUserWithRepository("user");
|
createUserWithRepository("user");
|
||||||
String permissionJson = "{ \"name\": \"@permission\", \"type\": \"OWNER\" }";
|
String permissionJson = "{ \"name\": \"@permission\", \"verbs\": [\"*\"] }";
|
||||||
MockHttpRequest request = MockHttpRequest
|
MockHttpRequest request = MockHttpRequest
|
||||||
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + PATH_OF_ALL_PERMISSIONS)
|
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + PATH_OF_ALL_PERMISSIONS)
|
||||||
.content(permissionJson.getBytes())
|
.content(permissionJson.getBytes())
|
||||||
@@ -244,7 +246,7 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase {
|
|||||||
assertEquals(400, response.getStatus());
|
assertEquals(400, response.getStatus());
|
||||||
|
|
||||||
// the whitespace at the begin opf the name is not allowed
|
// the whitespace at the begin opf the name is not allowed
|
||||||
permissionJson = "{ \"name\": \" permission\", \"type\": \"OWNER\" }";
|
permissionJson = "{ \"name\": \" permission\", \"verbs\": [\"*\"] }";
|
||||||
request = MockHttpRequest
|
request = MockHttpRequest
|
||||||
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + PATH_OF_ALL_PERMISSIONS)
|
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + PATH_OF_ALL_PERMISSIONS)
|
||||||
.content(permissionJson.getBytes())
|
.content(permissionJson.getBytes())
|
||||||
@@ -259,12 +261,12 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase {
|
|||||||
@Test
|
@Test
|
||||||
public void shouldGetCreatedPermissions() throws URISyntaxException {
|
public void shouldGetCreatedPermissions() throws URISyntaxException {
|
||||||
createUserWithRepositoryAndPermissions(TEST_PERMISSIONS, PERMISSION_WRITE);
|
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<RepositoryPermission> permissions = Lists.newArrayList(TEST_PERMISSIONS);
|
ArrayList<RepositoryPermission> permissions = Lists.newArrayList(TEST_PERMISSIONS);
|
||||||
permissions.add(newPermission);
|
permissions.add(newPermission);
|
||||||
ImmutableList<RepositoryPermission> expectedPermissions = ImmutableList.copyOf(permissions);
|
ImmutableList<RepositoryPermission> expectedPermissions = ImmutableList.copyOf(permissions);
|
||||||
assertExpectedRequest(requestPOSTPermission
|
assertExpectedRequest(requestPOSTPermission
|
||||||
.content("{\"name\" : \"" + newPermission.getName() + "\" , \"type\" : \"WRITE\" , \"groupPermission\" : true}")
|
.content("{\"name\" : \"" + newPermission.getName() + "\" , \"verbs\" : [\"read\",\"pull\",\"push\"], \"groupPermission\" : true}")
|
||||||
.expectedResponseStatus(201)
|
.expectedResponseStatus(201)
|
||||||
.responseValidator(response -> assertThat(response.getContentAsString())
|
.responseValidator(response -> assertThat(response.getContentAsString())
|
||||||
.as("POST response has no body")
|
.as("POST response has no body")
|
||||||
@@ -278,7 +280,7 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase {
|
|||||||
createUserWithRepositoryAndPermissions(TEST_PERMISSIONS, PERMISSION_WRITE);
|
createUserWithRepositoryAndPermissions(TEST_PERMISSIONS, PERMISSION_WRITE);
|
||||||
RepositoryPermission newPermission = TEST_PERMISSIONS.get(0);
|
RepositoryPermission newPermission = TEST_PERMISSIONS.get(0);
|
||||||
assertExpectedRequest(requestPOSTPermission
|
assertExpectedRequest(requestPOSTPermission
|
||||||
.content("{\"name\" : \"" + newPermission.getName() + "\" , \"type\" : \"WRITE\" , \"groupPermission\" : false}")
|
.content("{\"name\" : \"" + newPermission.getName() + "\" , \"verbs\" : [\"read\",\"pull\",\"push\"], \"groupPermission\" : false}")
|
||||||
.expectedResponseStatus(409)
|
.expectedResponseStatus(409)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -288,10 +290,10 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase {
|
|||||||
createUserWithRepositoryAndPermissions(TEST_PERMISSIONS, PERMISSION_WRITE);
|
createUserWithRepositoryAndPermissions(TEST_PERMISSIONS, PERMISSION_WRITE);
|
||||||
RepositoryPermission modifiedPermission = TEST_PERMISSIONS.get(0);
|
RepositoryPermission modifiedPermission = TEST_PERMISSIONS.get(0);
|
||||||
// modify the type to owner
|
// modify the type to owner
|
||||||
modifiedPermission.setVerbs(asList("read", "modify", "delete"));
|
modifiedPermission.setVerbs(new ArrayList<>(singletonList("*")));
|
||||||
ImmutableList<RepositoryPermission> expectedPermissions = ImmutableList.copyOf(TEST_PERMISSIONS);
|
ImmutableList<RepositoryPermission> expectedPermissions = ImmutableList.copyOf(TEST_PERMISSIONS);
|
||||||
assertExpectedRequest(requestPUTPermission
|
assertExpectedRequest(requestPUTPermission
|
||||||
.content("{\"name\" : \"" + modifiedPermission.getName() + "\" , \"type\" : \"OWNER\" , \"groupPermission\" : false}")
|
.content("{\"name\" : \"" + modifiedPermission.getName() + "\" , \"verbs\" : [\"*\"], \"groupPermission\" : false}")
|
||||||
.path(PATH_OF_ALL_PERMISSIONS + modifiedPermission.getName())
|
.path(PATH_OF_ALL_PERMISSIONS + modifiedPermission.getName())
|
||||||
.expectedResponseStatus(204)
|
.expectedResponseStatus(204)
|
||||||
.responseValidator(response -> assertThat(response.getContentAsString())
|
.responseValidator(response -> assertThat(response.getContentAsString())
|
||||||
@@ -353,7 +355,10 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase {
|
|||||||
.map(hal -> {
|
.map(hal -> {
|
||||||
RepositoryPermissionDto result = new RepositoryPermissionDto();
|
RepositoryPermissionDto result = new RepositoryPermissionDto();
|
||||||
result.setName(hal.getAttribute("name").asText());
|
result.setName(hal.getAttribute("name").asText());
|
||||||
result.setType(hal.getAttribute("type").asText());
|
JsonNode attribute = hal.getAttribute("verbs");
|
||||||
|
List<String> verbs = new ArrayList<>();
|
||||||
|
attribute.iterator().forEachRemaining(v -> verbs.add(v.asText()));
|
||||||
|
result.setVerbs(verbs);
|
||||||
result.setGroupPermission(hal.getAttribute("groupPermission").asBoolean());
|
result.setGroupPermission(hal.getAttribute("groupPermission").asBoolean());
|
||||||
result.add(hal.getLinks());
|
result.add(hal.getLinks());
|
||||||
return result;
|
return result;
|
||||||
@@ -382,7 +387,7 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase {
|
|||||||
RepositoryPermissionDto result = new RepositoryPermissionDto();
|
RepositoryPermissionDto result = new RepositoryPermissionDto();
|
||||||
result.setName(permission.getName());
|
result.setName(permission.getName());
|
||||||
result.setGroupPermission(permission.isGroupPermission());
|
result.setGroupPermission(permission.isGroupPermission());
|
||||||
// result.setType(permission.getVerbs()); TODO RP
|
result.setVerbs(permission.getVerbs());
|
||||||
String permissionName = Optional.of(permission.getName())
|
String permissionName = Optional.of(permission.getName())
|
||||||
.filter(p -> !permission.isGroupPermission())
|
.filter(p -> !permission.isGroupPermission())
|
||||||
.orElse(GROUP_PREFIX + permission.getName());
|
.orElse(GROUP_PREFIX + permission.getName());
|
||||||
@@ -412,8 +417,7 @@ public class RepositoryPermissionRootResourceTest extends RepositoryTestBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void createUserWithRepositoryAndPermissions(ArrayList<RepositoryPermission> permissions, String userPermission) {
|
private void createUserWithRepositoryAndPermissions(ArrayList<RepositoryPermission> permissions, String userPermission) {
|
||||||
// TODO RP
|
createUserWithRepository(userPermission).setPermissions(permissions);
|
||||||
// createUserWithRepository(userPermission).setPermissions(permissions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Stream<DynamicTest> createDynamicTestsToAssertResponses(ExpectedRequest... expectedRequests) {
|
private Stream<DynamicTest> createDynamicTestsToAssertResponses(ExpectedRequest... expectedRequests) {
|
||||||
|
|||||||
@@ -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_NO_CONTENT;
|
||||||
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
||||||
import static javax.servlet.http.HttpServletResponse.SC_PRECONDITION_FAILED;
|
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.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.any;
|
||||||
import static org.mockito.Matchers.anyObject;
|
import static org.mockito.Matchers.anyObject;
|
||||||
@@ -286,13 +285,12 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
|||||||
|
|
||||||
dispatcher.invoke(request, response);
|
dispatcher.invoke(request, response);
|
||||||
|
|
||||||
// TODO RP
|
assertThat(createCaptor.getValue().getPermissions())
|
||||||
// Assertions.assertThat(createCaptor.getValue().getPermissions())
|
.hasSize(1)
|
||||||
// .hasSize(1)
|
.allSatisfy(p -> {
|
||||||
// .allSatisfy(p -> {
|
assertThat(p.getName()).isEqualTo("trillian");
|
||||||
// assertThat(p.getName()).isEqualTo("trillian");
|
assertThat(p.getVerbs()).containsExactly("*");
|
||||||
// assertThat(p.getType()).isEqualTo(PermissionType.OWNER);
|
});
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -116,17 +116,6 @@ public class GitLfsITCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLfsAPIWithOwnerPermissions() throws IOException {
|
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();
|
User trillian = UserTestData.createTrillian();
|
||||||
trillian.setPassword("secret123");
|
trillian.setPassword("secret123");
|
||||||
createUser(trillian);
|
createUser(trillian);
|
||||||
|
|||||||
@@ -225,12 +225,11 @@ public class DefaultAuthorizationCollectorTest {
|
|||||||
authenticate(UserTestData.createTrillian(), group);
|
authenticate(UserTestData.createTrillian(), group);
|
||||||
Repository heartOfGold = RepositoryTestData.createHeartOfGold();
|
Repository heartOfGold = RepositoryTestData.createHeartOfGold();
|
||||||
heartOfGold.setId("one");
|
heartOfGold.setId("one");
|
||||||
// TODO RP
|
heartOfGold.setPermissions(Lists.newArrayList(new RepositoryPermission("trillian", asList("read", "pull"), false)));
|
||||||
// heartOfGold.setPermissions(Lists.newArrayList(new RepositoryPermission("trillian")));
|
|
||||||
Repository puzzle42 = RepositoryTestData.create42Puzzle();
|
Repository puzzle42 = RepositoryTestData.create42Puzzle();
|
||||||
puzzle42.setId("two");
|
puzzle42.setId("two");
|
||||||
RepositoryPermission permission = new RepositoryPermission(group, asList("read","modify"), true);
|
RepositoryPermission permission = new RepositoryPermission(group, asList("read", "pull", "push"), true);
|
||||||
// puzzle42.setPermissions(Lists.newArrayList(permission));
|
puzzle42.setPermissions(Lists.newArrayList(permission));
|
||||||
when(repositoryDAO.getAll()).thenReturn(Lists.newArrayList(heartOfGold, puzzle42));
|
when(repositoryDAO.getAll()).thenReturn(Lists.newArrayList(heartOfGold, puzzle42));
|
||||||
|
|
||||||
// execute and assert
|
// execute and assert
|
||||||
|
|||||||
Reference in New Issue
Block a user