Просмотр исходного кода

Allow hyphens in namespaces.

Signed-off-by: Matthew Riley <mattdr@google.com>
Matthew Riley 10 лет назад
Родитель
Сommit
6c126d443b
2 измененных файлов с 56 добавлено и 18 удалено
  1. 12 3
      registry/registry.go
  2. 44 15
      registry/registry_test.go

+ 12 - 3
registry/registry.go

@@ -23,7 +23,7 @@ var (
 	ErrInvalidRepositoryName = errors.New("Invalid repository name (ex: \"registry.domain.tld/myrepos\")")
 	ErrDoesNotExist          = errors.New("Image does not exist")
 	errLoginRequired         = errors.New("Authentication is required.")
-	validNamespace           = regexp.MustCompile(`^([a-z0-9_]{4,30})$`)
+	validNamespaceChars      = regexp.MustCompile(`^([a-z0-9-_]*)$`)
 	validRepo                = regexp.MustCompile(`^([a-z0-9-_.]+)$`)
 )
 
@@ -178,8 +178,17 @@ func validateRepositoryName(repositoryName string) error {
 		namespace = nameParts[0]
 		name = nameParts[1]
 	}
-	if !validNamespace.MatchString(namespace) {
-		return fmt.Errorf("Invalid namespace name (%s), only [a-z0-9_] are allowed, size between 4 and 30", namespace)
+	if !validNamespaceChars.MatchString(namespace) {
+		return fmt.Errorf("Invalid namespace name (%s). Only [a-z0-9-_] are allowed.", namespace)
+	}
+	if len(namespace) < 4 || len(namespace) > 30 {
+		return fmt.Errorf("Invalid namespace name (%s). Cannot be fewer than 4 or more than 30 characters.", namespace)
+	}
+	if strings.HasPrefix(namespace, "-") || strings.HasSuffix(namespace, "-") {
+		return fmt.Errorf("Invalid namespace name (%s). Cannot begin or end with a hyphen.", namespace)
+	}
+	if strings.Contains(namespace, "--") {
+		return fmt.Errorf("Invalid namespace name (%s). Cannot contain consecutive hyphens.", namespace)
 	}
 	if !validRepo.MatchString(name) {
 		return fmt.Errorf("Invalid repository name (%s), only [a-z0-9-_.] are allowed", name)

+ 44 - 15
registry/registry_test.go

@@ -233,24 +233,53 @@ func TestSearchRepositories(t *testing.T) {
 }
 
 func TestValidRepositoryName(t *testing.T) {
-	if err := validateRepositoryName("docker/docker"); err != nil {
-		t.Fatal(err)
-	}
-	// Support 64-byte non-hexadecimal names (hexadecimal names are forbidden)
-	if err := validateRepositoryName("thisisthesongthatneverendsitgoesonandonandonthisisthesongthatnev"); err != nil {
-		t.Fatal(err)
+	validRepositoryNames := []string{
+		// Sanity check.
+		"docker/docker",
+
+		// Allow 64-character non-hexadecimal names (hexadecimal names are forbidden).
+		"thisisthesongthatneverendsitgoesonandonandonthisisthesongthatnev",
+
+		// Allow embedded hyphens.
+		"docker-rules/docker",
+
+		// Allow underscores everywhere (as opposed to hyphens).
+		"____/____",
 	}
-	if err := validateRepositoryName("docker/Docker"); err == nil {
-		t.Log("Repository name should be invalid")
-		t.Fail()
+	for _, repositoryName := range validRepositoryNames {
+		if err := validateRepositoryName(repositoryName); err != nil {
+			t.Errorf("Repository name should be valid: %v. Error: %v", repositoryName, err)
+		}
 	}
-	if err := validateRepositoryName("docker///docker"); err == nil {
-		t.Log("Repository name should be invalid")
-		t.Fail()
+
+	invalidRepositoryNames := []string{
+		// Disallow capital letters.
+		"docker/Docker",
+
+		// Only allow one slash.
+		"docker///docker",
+
+		// Disallow 64-character hexadecimal.
+		"1a3f5e7d9c1b3a5f7e9d1c3b5a7f9e1d3c5b7a9f1e3d5d7c9b1a3f5e7d9c1b3a",
+
+		// Disallow leading and trailing hyphens in namespace.
+		"-docker/docker",
+		"docker-/docker",
+		"-docker-/docker",
+
+		// Disallow consecutive hyphens.
+		"dock--er/docker",
+
+		// Namespace too short.
+		"doc/docker",
+
+		// No repository.
+		"docker/",
 	}
-	if err := validateRepositoryName("1a3f5e7d9c1b3a5f7e9d1c3b5a7f9e1d3c5b7a9f1e3d5d7c9b1a3f5e7d9c1b3a"); err == nil {
-		t.Log("Repository name should be invalid, 64-byte hexadecimal names forbidden")
-		t.Fail()
+	for _, repositoryName := range invalidRepositoryNames {
+		if err := validateRepositoryName(repositoryName); err == nil {
+			t.Errorf("Repository name should be invalid: %v", repositoryName)
+		}
 	}
 }