From 0ade91ac853a33599bf47376839ce4f956505d33 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 3 Dec 2020 10:46:43 +0100 Subject: [PATCH] Use mapper and improve validation We have to use the repository mapper in order to fix missing fields contact and description in the created repository. Use bean validation to ensure correct validation and require import url. --- .../RepositoryDtoToRepositoryMapper.java | 6 ++++- .../resources/RepositoryImportResource.java | 23 +++++++++---------- .../resources/RepositoryRootResourceTest.java | 2 +- .../sonia/scm/api/v2/import-repo.json | 1 + 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryDtoToRepositoryMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryDtoToRepositoryMapper.java index 09be059b7c..f3f0ac6aa3 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryDtoToRepositoryMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryDtoToRepositoryMapper.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + package sonia.scm.api.v2.resources; import org.mapstruct.*; @@ -30,6 +30,10 @@ import sonia.scm.repository.Repository; @Mapper public abstract class RepositoryDtoToRepositoryMapper extends BaseDtoMapper { + public Repository map(RepositoryDto repositoryDto) { + return map(repositoryDto, null); + } + @Mapping(target = "creationDate", ignore = true) @Mapping(target = "id", ignore = true) @Mapping(target = "healthCheckFailures", ignore = true) diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryImportResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryImportResource.java index badfd5185e..e06c23528d 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryImportResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryImportResource.java @@ -57,6 +57,7 @@ import sonia.scm.repository.api.RepositoryServiceFactory; import sonia.scm.util.ValidationUtil; import sonia.scm.web.VndMediaType; +import javax.validation.Valid; import javax.validation.constraints.Email; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; @@ -70,13 +71,9 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import java.io.IOException; import java.net.URI; -import java.time.Instant; -import java.util.List; import java.util.Set; import java.util.function.Consumer; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; import static java.util.Collections.singletonList; public class RepositoryImportResource { @@ -84,16 +81,19 @@ public class RepositoryImportResource { private static final Logger logger = LoggerFactory.getLogger(RepositoryImportResource.class); private final RepositoryManager manager; + private final RepositoryDtoToRepositoryMapper mapper; private final RepositoryServiceFactory serviceFactory; private final ResourceLinks resourceLinks; private final ScmEventBus eventBus; @Inject public RepositoryImportResource(RepositoryManager manager, + RepositoryDtoToRepositoryMapper mapper, RepositoryServiceFactory serviceFactory, ResourceLinks resourceLinks, ScmEventBus eventBus) { this.manager = manager; + this.mapper = mapper; this.serviceFactory = serviceFactory; this.resourceLinks = resourceLinks; this.eventBus = eventBus; @@ -141,21 +141,19 @@ public class RepositoryImportResource { ) ) public Response importFromUrl(@Context UriInfo uriInfo, - @PathParam("type") String type, RepositoryImportDto request) { + @PathParam("type") String type, @Valid RepositoryImportDto request) { RepositoryPermissions.create().check(); - checkNotNull(request, "request is required"); - checkArgument(!Strings.isNullOrEmpty(request.getName()), - "request does not contain name of the repository"); - checkArgument(!Strings.isNullOrEmpty(request.getImportUrl()), - "request does not contain url of the remote repository"); Type t = type(type); + if (!t.getName().equals(request.getType())) { + throw new WebApplicationException("type of import url and repository does not match", Response.Status.BAD_REQUEST); + } checkSupport(t, Command.PULL, request); logger.info("start {} import for external url {}", type, request.getImportUrl()); - Repository repository = new Repository(null, type, request.getNamespace(), request.getName()); + Repository repository = mapper.map(request); repository.setPermissions(singletonList(new RepositoryPermission(SecurityUtils.getSubject().getPrincipal().toString(), "OWNER", false))); try { @@ -231,6 +229,7 @@ public class RepositoryImportResource { @NoArgsConstructor @SuppressWarnings("java:S2160") public static class RepositoryImportDto extends RepositoryDto implements ImportRepositoryDto { + @NotEmpty private String importUrl; private String username; private String password; @@ -241,7 +240,6 @@ public class RepositoryImportResource { } interface ImportRepositoryDto { - String getNamespace(); @Pattern(regexp = ValidationUtil.REGEX_REPOSITORYNAME) String getName(); @@ -250,6 +248,7 @@ public class RepositoryImportResource { @Email String getContact(); String getDescription(); + @NotEmpty String getImportUrl(); String getUsername(); String getPassword(); 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 c014ad546e..daabb9ae20 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 @@ -153,7 +153,7 @@ public class RepositoryRootResourceTest extends RepositoryTestBase { super.manager = repositoryManager; RepositoryCollectionToDtoMapper repositoryCollectionToDtoMapper = new RepositoryCollectionToDtoMapper(repositoryToDtoMapper, resourceLinks); super.repositoryCollectionResource = new RepositoryCollectionResource(repositoryManager, repositoryCollectionToDtoMapper, dtoToRepositoryMapper, resourceLinks, repositoryInitializer); - super.repositoryImportResource = new RepositoryImportResource(repositoryManager, serviceFactory, resourceLinks, eventBus); + super.repositoryImportResource = new RepositoryImportResource(repositoryManager, dtoToRepositoryMapper, serviceFactory, resourceLinks, eventBus); dispatcher.addSingletonResource(getRepositoryRootResource()); when(serviceFactory.create(any(Repository.class))).thenReturn(service); when(scmPathInfoStore.get()).thenReturn(uriInfo); diff --git a/scm-webapp/src/test/resources/sonia/scm/api/v2/import-repo.json b/scm-webapp/src/test/resources/sonia/scm/api/v2/import-repo.json index efbdf2fd9b..4670e9151e 100644 --- a/scm-webapp/src/test/resources/sonia/scm/api/v2/import-repo.json +++ b/scm-webapp/src/test/resources/sonia/scm/api/v2/import-repo.json @@ -1,5 +1,6 @@ { "namespace": "hitchhiker", "name": "HeartOfGold", + "type": "git", "importUrl": "https://scm-manager-org/scm/repo/secret/puzzle42" }