align validation of repository name and namespace

This commit is contained in:
Sebastian Sdorra
2019-03-12 15:10:05 +01:00
parent c180457214
commit f7f5102541
5 changed files with 93 additions and 14 deletions

View File

@@ -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));
}
/**

View File

@@ -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();
}
/**

View File

@@ -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) {

View File

@@ -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", () => {

View File

@@ -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