mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-08 14:35:45 +01:00
validate namespace strategies on configuration update
This commit is contained in:
@@ -5,6 +5,7 @@ import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
|||||||
import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
||||||
import sonia.scm.config.ConfigurationPermissions;
|
import sonia.scm.config.ConfigurationPermissions;
|
||||||
import sonia.scm.config.ScmConfiguration;
|
import sonia.scm.config.ScmConfiguration;
|
||||||
|
import sonia.scm.repository.NamespaceStrategyValidator;
|
||||||
import sonia.scm.util.ScmConfigurationUtil;
|
import sonia.scm.util.ScmConfigurationUtil;
|
||||||
import sonia.scm.web.VndMediaType;
|
import sonia.scm.web.VndMediaType;
|
||||||
|
|
||||||
@@ -27,12 +28,16 @@ public class ConfigResource {
|
|||||||
private final ConfigDtoToScmConfigurationMapper dtoToConfigMapper;
|
private final ConfigDtoToScmConfigurationMapper dtoToConfigMapper;
|
||||||
private final ScmConfigurationToConfigDtoMapper configToDtoMapper;
|
private final ScmConfigurationToConfigDtoMapper configToDtoMapper;
|
||||||
private final ScmConfiguration configuration;
|
private final ScmConfiguration configuration;
|
||||||
|
private final NamespaceStrategyValidator namespaceStrategyValidator;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ConfigResource(ConfigDtoToScmConfigurationMapper dtoToConfigMapper, ScmConfigurationToConfigDtoMapper configToDtoMapper, ScmConfiguration configuration) {
|
public ConfigResource(ConfigDtoToScmConfigurationMapper dtoToConfigMapper,
|
||||||
|
ScmConfigurationToConfigDtoMapper configToDtoMapper,
|
||||||
|
ScmConfiguration configuration, NamespaceStrategyValidator namespaceStrategyValidator) {
|
||||||
this.dtoToConfigMapper = dtoToConfigMapper;
|
this.dtoToConfigMapper = dtoToConfigMapper;
|
||||||
this.configToDtoMapper = configToDtoMapper;
|
this.configToDtoMapper = configToDtoMapper;
|
||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
|
this.namespaceStrategyValidator = namespaceStrategyValidator;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -78,6 +83,9 @@ public class ConfigResource {
|
|||||||
// But to where to check? load() or store()? Leave it for now, SCMv1 legacy that can be cleaned up later.
|
// But to where to check? load() or store()? Leave it for now, SCMv1 legacy that can be cleaned up later.
|
||||||
ConfigurationPermissions.write(configuration).check();
|
ConfigurationPermissions.write(configuration).check();
|
||||||
|
|
||||||
|
// ensure the namespace strategy is valid
|
||||||
|
namespaceStrategyValidator.check(configDto.getNamespaceStrategy());
|
||||||
|
|
||||||
ScmConfiguration config = dtoToConfigMapper.map(configDto);
|
ScmConfiguration config = dtoToConfigMapper.map(configDto);
|
||||||
synchronized (ScmConfiguration.class) {
|
synchronized (ScmConfiguration.class) {
|
||||||
configuration.load(config);
|
configuration.load(config);
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package sonia.scm.repository;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static sonia.scm.ScmConstraintViolationException.Builder.doThrow;
|
||||||
|
|
||||||
|
public class NamespaceStrategyValidator {
|
||||||
|
|
||||||
|
private final Set<NamespaceStrategy> strategies;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public NamespaceStrategyValidator(Set<NamespaceStrategy> strategies) {
|
||||||
|
this.strategies = strategies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void check(String name) {
|
||||||
|
doThrow()
|
||||||
|
.violation("unknown NamespaceStrategy " + name, "namespaceStrategy")
|
||||||
|
.when(!isValid(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValid(String name) {
|
||||||
|
return strategies.stream().anyMatch(ns -> ns.getClass().getSimpleName().equals(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,9 @@ import org.junit.Rule;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
import sonia.scm.config.ScmConfiguration;
|
import sonia.scm.config.ScmConfiguration;
|
||||||
|
import sonia.scm.repository.NamespaceStrategyValidator;
|
||||||
import sonia.scm.web.VndMediaType;
|
import sonia.scm.web.VndMediaType;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
@@ -22,10 +24,12 @@ import java.io.UnsupportedEncodingException;
|
|||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.MockitoAnnotations.initMocks;
|
import static org.mockito.MockitoAnnotations.initMocks;
|
||||||
|
|
||||||
@SubjectAware(
|
@SubjectAware(
|
||||||
@@ -46,6 +50,9 @@ public class ConfigResourceTest {
|
|||||||
@SuppressWarnings("unused") // Is injected
|
@SuppressWarnings("unused") // Is injected
|
||||||
private ResourceLinks resourceLinks = ResourceLinksMock.createMock(baseUri);
|
private ResourceLinks resourceLinks = ResourceLinksMock.createMock(baseUri);
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private NamespaceStrategyValidator namespaceStrategyValidator;
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
private ConfigDtoToScmConfigurationMapperImpl dtoToConfigMapper;
|
private ConfigDtoToScmConfigurationMapperImpl dtoToConfigMapper;
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
@@ -62,7 +69,7 @@ public class ConfigResourceTest {
|
|||||||
public void prepareEnvironment() {
|
public void prepareEnvironment() {
|
||||||
initMocks(this);
|
initMocks(this);
|
||||||
|
|
||||||
ConfigResource configResource = new ConfigResource(dtoToConfigMapper, configToDtoMapper, createConfiguration());
|
ConfigResource configResource = new ConfigResource(dtoToConfigMapper, configToDtoMapper, createConfiguration(), namespaceStrategyValidator);
|
||||||
|
|
||||||
dispatcher.getRegistry().addSingletonResource(configResource);
|
dispatcher.getRegistry().addSingletonResource(configResource);
|
||||||
}
|
}
|
||||||
@@ -140,6 +147,21 @@ public class ConfigResourceTest {
|
|||||||
assertEquals(HttpServletResponse.SC_BAD_REQUEST, response.getStatus());
|
assertEquals(HttpServletResponse.SC_BAD_REQUEST, response.getStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SubjectAware(username = "readWrite")
|
||||||
|
public void shouldValidateNamespaceStrategy() throws URISyntaxException {
|
||||||
|
MockHttpRequest request = MockHttpRequest.put("/" + ConfigResource.CONFIG_PATH_V2)
|
||||||
|
.contentType(VndMediaType.CONFIG)
|
||||||
|
.content("{ \"namespaceStrategy\": \"AwesomeStrategy\" }".getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
MockHttpResponse response = new MockHttpResponse();
|
||||||
|
dispatcher.invoke(request, response);
|
||||||
|
|
||||||
|
assertEquals(HttpServletResponse.SC_NO_CONTENT, response.getStatus());
|
||||||
|
verify(namespaceStrategyValidator).check("AwesomeStrategy");
|
||||||
|
}
|
||||||
|
|
||||||
private MockHttpRequest post(String resourceName) throws IOException, URISyntaxException {
|
private MockHttpRequest post(String resourceName) throws IOException, URISyntaxException {
|
||||||
URL url = Resources.getResource(resourceName);
|
URL url = Resources.getResource(resourceName);
|
||||||
byte[] configJson = Resources.toByteArray(url);
|
byte[] configJson = Resources.toByteArray(url);
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package sonia.scm.repository;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import sonia.scm.ScmConstraintViolationException;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
class NamespaceStrategyValidatorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldThrowConstraintValidationException() {
|
||||||
|
NamespaceStrategyValidator validator = new NamespaceStrategyValidator(Collections.emptySet());
|
||||||
|
assertThrows(ScmConstraintViolationException.class, () -> validator.check("AwesomeStrategy"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldDoNotThrowAnException() {
|
||||||
|
NamespaceStrategyValidator validator = new NamespaceStrategyValidator(Sets.newHashSet(new AwesomeStrategy()));
|
||||||
|
validator.check("AwesomeStrategy");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AwesomeStrategy implements NamespaceStrategy {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String createNamespace(Repository repository) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user