Validate namespaces correctly

This commit is contained in:
René Pfeuffer
2020-09-10 09:18:50 +02:00
parent 4df9c2947b
commit 94105f7766
4 changed files with 30 additions and 14 deletions

View File

@@ -268,7 +268,7 @@ class RepositoryForm extends React.Component<Props, State> {
handleNamespaceChange = (namespace: string) => { handleNamespaceChange = (namespace: string) => {
this.setState({ this.setState({
namespaceValidationError: !validator.isNameValid(namespace), namespaceValidationError: !validator.isNamespaceValid(namespace),
repository: { repository: {
...this.state.repository, ...this.state.repository,
namespace namespace

View File

@@ -25,6 +25,11 @@
import { validation } from "@scm-manager/ui-components"; import { validation } from "@scm-manager/ui-components";
const nameRegex = /(?!^\.\.$)(?!^\.$)(?!.*[.]git$)(?!.*[\\\[\]])^[A-Za-z0-9\.][A-Za-z0-9\.\-_]*$/; const nameRegex = /(?!^\.\.$)(?!^\.$)(?!.*[.]git$)(?!.*[\\\[\]])^[A-Za-z0-9\.][A-Za-z0-9\.\-_]*$/;
const namespaceExceptionsRegex = /^(([0-9]{1,3})|(create))$/;
export const isNamespaceValid = (name: string) => {
return nameRegex.test(name) && !namespaceExceptionsRegex.test(name);
};
export const isNameValid = (name: string) => { export const isNameValid = (name: string) => {
return nameRegex.test(name); return nameRegex.test(name);

View File

@@ -27,17 +27,25 @@ package sonia.scm.repository;
import sonia.scm.plugin.Extension; import sonia.scm.plugin.Extension;
import sonia.scm.util.ValidationUtil; import sonia.scm.util.ValidationUtil;
import java.util.regex.Pattern;
import static sonia.scm.ScmConstraintViolationException.Builder.doThrow; import static sonia.scm.ScmConstraintViolationException.Builder.doThrow;
@Extension @Extension
public class CustomNamespaceStrategy implements NamespaceStrategy { public class CustomNamespaceStrategy implements NamespaceStrategy {
private static final Pattern ONE_TO_THREE_DIGITS = Pattern.compile("[0-9]{1,3}");
@Override @Override
public String createNamespace(Repository repository) { public String createNamespace(Repository repository) {
String namespace = repository.getNamespace(); String namespace = repository.getNamespace();
doThrow() doThrow()
.violation("invalid namespace", "namespace") .violation("invalid namespace", "namespace")
.when(!ValidationUtil.isRepositoryNameValid(namespace) || namespace.matches("[0-9]{1,3}")); .when(
!ValidationUtil.isRepositoryNameValid(namespace)
|| ONE_TO_THREE_DIGITS.matcher(namespace).matches()
|| namespace.equals("create"));
return namespace; return namespace;
} }

View File

@@ -21,10 +21,11 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
package sonia.scm.repository; package sonia.scm.repository;
import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import sonia.scm.ScmConstraintViolationException; import sonia.scm.ScmConstraintViolationException;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@@ -34,19 +35,21 @@ class CustomNamespaceStrategyTest {
private final NamespaceStrategy namespaceStrategy = new CustomNamespaceStrategy(); private final NamespaceStrategy namespaceStrategy = new CustomNamespaceStrategy();
@Test @ParameterizedTest
void shouldReturnNamespaceFromRepository() { @ValueSource(strings = {"valid", "123_", "something_valid", "1234", "create_it"})
Repository heartOfGold = RepositoryTestData.createHeartOfGold(); void shouldReturnNamespaceFromRepository(String expectedValidNamespace) {
assertThat(namespaceStrategy.createNamespace(heartOfGold)).isEqualTo(RepositoryTestData.NAMESPACE); Repository repository = RepositoryTestData.createHeartOfGold();
repository.setNamespace(expectedValidNamespace);
assertThat(namespaceStrategy.createNamespace(repository)).isEqualTo(expectedValidNamespace);
} }
@Test @ParameterizedTest
void shouldThrowAnValidationExceptionForAnInvalidNamespace() { @ValueSource(strings = {"..", " ", "0", "123", "create"})
Repository repository = new Repository(); void shouldThrowAnValidationExceptionForAnInvalidNamespace(String expectedAsInvalidNamespace) {
repository.setNamespace(".."); Repository repository = RepositoryTestData.createHeartOfGold();
repository.setName("."); repository.setNamespace(expectedAsInvalidNamespace);
assertThrows(ScmConstraintViolationException.class, () -> namespaceStrategy.createNamespace(repository)); assertThrows(ScmConstraintViolationException.class, () -> namespaceStrategy.createNamespace(repository));
} }
} }