Skip to content

Commit b120247

Browse files
authored
fix: extend regex for template version name (#6876)
1 parent 563c3ad commit b120247

File tree

3 files changed

+80
-1
lines changed

3 files changed

+80
-1
lines changed

coderd/httpapi/httpapi.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func init() {
4444
valid := NameValid(str)
4545
return valid == nil
4646
}
47-
for _, tag := range []string{"username", "template_name", "workspace_name", "template_version_name"} {
47+
for _, tag := range []string{"username", "template_name", "workspace_name"} {
4848
err := Validate.RegisterValidation(tag, nameValidator)
4949
if err != nil {
5050
panic(err)
@@ -64,6 +64,20 @@ func init() {
6464
if err != nil {
6565
panic(err)
6666
}
67+
68+
templateVersionNameValidator := func(fl validator.FieldLevel) bool {
69+
f := fl.Field().Interface()
70+
str, ok := f.(string)
71+
if !ok {
72+
return false
73+
}
74+
valid := TemplateVersionNameValid(str)
75+
return valid == nil
76+
}
77+
err = Validate.RegisterValidation("template_version_name", templateVersionNameValidator)
78+
if err != nil {
79+
panic(err)
80+
}
6781
}
6882

6983
// Convenience error functions don't take contexts since their responses are

coderd/httpapi/name.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ var (
1212
UsernameValidRegex = regexp.MustCompile("^[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*$")
1313
usernameReplace = regexp.MustCompile("[^a-zA-Z0-9-]*")
1414

15+
templateVersionName = regexp.MustCompile(`^[a-zA-Z0-9]+(?:[_.-]{1}[a-zA-Z0-9]+)*$`)
1516
templateDisplayName = regexp.MustCompile(`^[^\s](.*[^\s])?$`)
1617
)
1718

@@ -52,6 +53,18 @@ func NameValid(str string) error {
5253
return nil
5354
}
5455

56+
// TemplateVersionNameValid returns whether the input string is a valid template version name.
57+
func TemplateVersionNameValid(str string) error {
58+
if len(str) > 64 {
59+
return xerrors.New("must be <= 64 characters")
60+
}
61+
matched := templateVersionName.MatchString(str)
62+
if !matched {
63+
return xerrors.New("must be alphanumeric with underscores and dots")
64+
}
65+
return nil
66+
}
67+
5568
// TemplateDisplayNameValid returns whether the input string is a valid template display name.
5669
func TemplateDisplayNameValid(str string) error {
5770
if len(str) == 0 {

coderd/httpapi/name_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package httpapi_test
33
import (
44
"testing"
55

6+
"github.com/moby/moby/pkg/namesgenerator"
67
"github.com/stretchr/testify/require"
78

89
"github.com/coder/coder/coderd/httpapi"
@@ -120,6 +121,57 @@ func TestTemplateDisplayNameValid(t *testing.T) {
120121
}
121122
}
122123

124+
func TestTemplateVersionNameValid(t *testing.T) {
125+
t.Parallel()
126+
127+
testCases := []struct {
128+
Name string
129+
Valid bool
130+
}{
131+
{"1", true},
132+
{"12", true},
133+
{"1_2", true},
134+
{"1-2", true},
135+
{"cray", true},
136+
{"123_456", true},
137+
{"123-456", true},
138+
{"1234_678901234567890", true},
139+
{"1234-678901234567890", true},
140+
{"S", true},
141+
{"a1", true},
142+
{"a1K2", true},
143+
{"fuzzy_bear3", true},
144+
{"fuzzy-bear3", true},
145+
{"v1.0.0", true},
146+
{"heuristic_cray2", true},
147+
148+
{"", false},
149+
{".v1", false},
150+
{"v1..0", false},
151+
{"4--4", false},
152+
{"<b> </b>", false},
153+
{"!!!!1 ?????", false},
154+
}
155+
for _, testCase := range testCases {
156+
testCase := testCase
157+
t.Run(testCase.Name, func(t *testing.T) {
158+
t.Parallel()
159+
valid := httpapi.TemplateVersionNameValid(testCase.Name)
160+
require.Equal(t, testCase.Valid, valid == nil)
161+
})
162+
}
163+
}
164+
165+
func TestGeneratedTemplateVersionNameValid(t *testing.T) {
166+
t.Parallel()
167+
168+
for i := 0; i < 1000; i++ {
169+
name := namesgenerator.GetRandomName(1)
170+
err := httpapi.TemplateVersionNameValid(name)
171+
require.NoError(t, err, "invalid template version name: %s", name)
172+
}
173+
}
174+
123175
func TestFrom(t *testing.T) {
124176
t.Parallel()
125177
testCases := []struct {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy