mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-15 09:46:16 +01:00
align validation of repository name and namespace
This commit is contained in:
@@ -248,7 +248,8 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per
|
||||
/**
|
||||
* Returns true if the {@link Repository} is valid.
|
||||
* <ul>
|
||||
* <li>The name is not empty and contains only A-z, 0-9, _, -, /</li>
|
||||
* <li>The namespace is valid</li>
|
||||
* <li>The name is valid</li>
|
||||
* <li>The type is not empty</li>
|
||||
* <li>The contact is empty or contains a valid email address</li>
|
||||
* </ul>
|
||||
@@ -257,9 +258,10 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per
|
||||
*/
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return ValidationUtil.isRepositoryNameValid(name) && Util.isNotEmpty(type)
|
||||
&& ((Util.isEmpty(contact))
|
||||
|| ValidationUtil.isMailAddressValid(contact));
|
||||
return ValidationUtil.isRepositoryNameValid(namespace)
|
||||
&& ValidationUtil.isRepositoryNameValid(name)
|
||||
&& Util.isNotEmpty(type)
|
||||
&& ((Util.isEmpty(contact)) || ValidationUtil.isMailAddressValid(contact));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -35,14 +35,12 @@ package sonia.scm.util;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
|
||||
import sonia.scm.Validateable;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
@@ -58,10 +56,10 @@ public final class ValidationUtil
|
||||
private static final String REGEX_NAME =
|
||||
"^[A-z0-9\\.\\-_@]|[^ ]([A-z0-9\\.\\-_@ ]*[A-z0-9\\.\\-_@]|[^ ])?$";
|
||||
|
||||
public static final String REGEX_REPOSITORYNAME = "(?!^\\.\\.$)(?!^\\.$)(?!.*[\\\\\\[\\]])^[A-z0-9\\.][A-z0-9\\.\\-_]*$";
|
||||
|
||||
/** Field description */
|
||||
private static final Pattern REGEX_REPOSITORYNAME = Pattern.compile(
|
||||
"(?!^\\.\\.$)(?!^\\.$)(?!.*[\\\\\\[\\]])^[A-z0-9\\.][A-z0-9\\.\\-_]*$"
|
||||
);
|
||||
private static final Pattern PATTERN_REPOSITORYNAME = Pattern.compile(REGEX_REPOSITORYNAME);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
@@ -151,7 +149,7 @@ public final class ValidationUtil
|
||||
* @return {@code true} if repository name is valid
|
||||
*/
|
||||
public static boolean isRepositoryNameValid(String name) {
|
||||
return REGEX_REPOSITORYNAME.matcher(name).matches();
|
||||
return PATTERN_REPOSITORYNAME.matcher(name).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
// @flow
|
||||
import { validation } from "@scm-manager/ui-components";
|
||||
|
||||
const nameRegex = /(?!^\.\.$)(?!^\.$)(?!.*[\\\[\]])^[A-z0-9\.][A-z0-9\.\-_]*$/;
|
||||
|
||||
export const isNameValid = (name: string) => {
|
||||
return validation.isNameValid(name);
|
||||
return nameRegex.test(name);
|
||||
};
|
||||
|
||||
export function isContactValid(mail: string) {
|
||||
|
||||
@@ -11,6 +11,81 @@ describe("repository name validation", () => {
|
||||
expect(validator.isNameValid("scm/manager")).toBe(false);
|
||||
expect(validator.isNameValid("scm/ma/nager")).toBe(false);
|
||||
});
|
||||
|
||||
it("should allow same names as the backend", () => {
|
||||
const validPaths = [
|
||||
"scm",
|
||||
"s",
|
||||
"sc",
|
||||
".hiddenrepo",
|
||||
"b.",
|
||||
"...",
|
||||
"..c",
|
||||
"d..",
|
||||
"a..c"
|
||||
];
|
||||
|
||||
validPaths.forEach((path) =>
|
||||
expect(validator.isNameValid(path)).toBe(true)
|
||||
);
|
||||
});
|
||||
|
||||
it("should deny same names as the backend", () => {
|
||||
const invalidPaths = [
|
||||
".",
|
||||
"/",
|
||||
"//",
|
||||
"..",
|
||||
"/.",
|
||||
"/..",
|
||||
"./",
|
||||
"../",
|
||||
"/../",
|
||||
"/./",
|
||||
"/...",
|
||||
"/abc",
|
||||
".../",
|
||||
"/sdf/",
|
||||
"asdf/",
|
||||
"./b",
|
||||
"scm/plugins/.",
|
||||
"scm/../plugins",
|
||||
"scm/main/",
|
||||
"/scm/main/",
|
||||
"scm/./main",
|
||||
"scm//main",
|
||||
"scm\\main",
|
||||
"scm/main-$HOME",
|
||||
"scm/main-${HOME}-home",
|
||||
"scm/main-%HOME-home",
|
||||
"scm/main-%HOME%-home",
|
||||
"abc$abc",
|
||||
"abc%abc",
|
||||
"abc<abc",
|
||||
"abc>abc",
|
||||
"abc#abc",
|
||||
"abc+abc",
|
||||
"abc{abc",
|
||||
"abc}abc",
|
||||
"abc(abc",
|
||||
"abc)abc",
|
||||
"abc[abc",
|
||||
"abc]abc",
|
||||
"abc|abc",
|
||||
"scm/main",
|
||||
"scm/plugins/git-plugin",
|
||||
".scm/plugins",
|
||||
"a/b..",
|
||||
"a/..b",
|
||||
"scm/main",
|
||||
"scm/plugins/git-plugin",
|
||||
"scm/plugins/git-plugin"
|
||||
];
|
||||
|
||||
invalidPaths.forEach((path) =>
|
||||
expect(validator.isNameValid(path)).toBe(false)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("repository contact validation", () => {
|
||||
|
||||
@@ -9,6 +9,7 @@ import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.validator.constraints.Email;
|
||||
import org.hibernate.validator.constraints.NotEmpty;
|
||||
import sonia.scm.util.ValidationUtil;
|
||||
|
||||
import javax.validation.constraints.Pattern;
|
||||
import java.time.Instant;
|
||||
@@ -25,8 +26,9 @@ public class RepositoryDto extends HalRepresentation {
|
||||
private List<HealthCheckFailureDto> healthCheckFailures;
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
private Instant lastModified;
|
||||
// we could not validate the namespace, this must be done by the namespace strategy
|
||||
private String namespace;
|
||||
@Pattern(regexp = "^[A-z0-9\\-_]+$")
|
||||
@Pattern(regexp = ValidationUtil.REGEX_REPOSITORYNAME)
|
||||
private String name;
|
||||
private boolean archived = false;
|
||||
@NotEmpty
|
||||
|
||||
Reference in New Issue
Block a user