Use links from protocols instead of resource links

Add links only for requests with according permissions
This commit is contained in:
René Pfeuffer
2018-09-04 12:40:41 +02:00
parent b55955f273
commit 3f772b3688
9 changed files with 132 additions and 20 deletions

View File

@@ -1,6 +1,7 @@
package sonia.scm.api.v2.resources;
import com.google.inject.Inject;
import de.otto.edison.hal.Link;
import de.otto.edison.hal.Links;
import org.mapstruct.AfterMapping;
import org.mapstruct.Mapper;
@@ -11,9 +12,14 @@ import sonia.scm.repository.RepositoryPermissions;
import sonia.scm.repository.api.Command;
import sonia.scm.repository.api.RepositoryService;
import sonia.scm.repository.api.RepositoryServiceFactory;
import sonia.scm.repository.api.ScmProtocol;
import java.util.Collection;
import java.util.List;
import static de.otto.edison.hal.Link.link;
import static de.otto.edison.hal.Links.linkingTo;
import static java.util.stream.Collectors.toList;
// Mapstruct does not support parameterized (i.e. non-default) constructors. Thus, we need to use field injection.
@SuppressWarnings("squid:S3306")
@@ -24,13 +30,14 @@ public abstract class RepositoryToRepositoryDtoMapper extends BaseMapper<Reposit
private ResourceLinks resourceLinks;
@Inject
private RepositoryServiceFactory serviceFactory;
@Inject
private UriInfoStore uriInfoStore;
abstract HealthCheckFailureDto toDto(HealthCheckFailure failure);
@AfterMapping
void appendLinks(Repository repository, @MappingTarget RepositoryDto target) {
Links.Builder linksBuilder = linkingTo().self(resourceLinks.repository().self(target.getNamespace(), target.getName()));
linksBuilder.single(link("httpProtocol", resourceLinks.repository().clone(target.getType(), target.getNamespace(), target.getName())));
if (RepositoryPermissions.delete(repository).isPermitted()) {
linksBuilder.single(link("delete", resourceLinks.repository().delete(target.getNamespace(), target.getName())));
}
@@ -39,6 +46,14 @@ public abstract class RepositoryToRepositoryDtoMapper extends BaseMapper<Reposit
linksBuilder.single(link("permissions", resourceLinks.permission().all(target.getNamespace(), target.getName())));
}
try (RepositoryService repositoryService = serviceFactory.create(repository)) {
if (RepositoryPermissions.pull(repository).isPermitted()) {
Collection<ScmProtocol> supportedProtocols = repositoryService.getSupportedProtocols();
List<Link> protocolLinks = supportedProtocols
.stream()
.map(this::createProtocolLink)
.collect(toList());
linksBuilder.array(protocolLinks);
}
if (repositoryService.isSupported(Command.TAGS)) {
linksBuilder.single(link("tags", resourceLinks.tag().all(target.getNamespace(), target.getName())));
}
@@ -50,4 +65,8 @@ public abstract class RepositoryToRepositoryDtoMapper extends BaseMapper<Reposit
linksBuilder.single(link("sources", resourceLinks.source().selfWithoutRevision(target.getNamespace(), target.getName())));
target.add(linksBuilder.build());
}
private Link createProtocolLink(ScmProtocol protocol) {
return Link.linkBuilder("protocol", protocol.getUrl(uriInfoStore.get())).withName(protocol.getType()).build();
}
}

View File

@@ -4,7 +4,6 @@ import sonia.scm.repository.NamespaceAndName;
import javax.inject.Inject;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
class ResourceLinks {
@@ -141,10 +140,6 @@ class ResourceLinks {
return repositoryLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("get").parameters().href();
}
String clone(String type, String namespace, String name) {
return uriInfo.getBaseUri().resolve(URI.create("../../" + type + "/" + namespace + "/" + name)).toASCIIString();
}
String delete(String namespace, String name) {
return repositoryLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("delete").parameters().href();
}