Skip to content

Commit bef8f52

Browse files
authored
Merge pull request #386 from urnetwork/username-validation
validates network name is lowercase and alphanumeric
2 parents 2a53488 + 9540b87 commit bef8f52

2 files changed

Lines changed: 106 additions & 10 deletions

File tree

model/network_model.go

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ const (
5757
)
5858

5959
func NetworkCheck(check *NetworkCheckArgs, session *session.ClientSession) (*NetworkCheckResult, error) {
60+
61+
_, err := validateNetworkName(check.NetworkName)
62+
if err != nil {
63+
return &NetworkCheckResult{
64+
Available: false,
65+
}, nil
66+
}
67+
6068
taken := networkNameSearch().AnyAround(session.Ctx, check.NetworkName, 1)
6169

6270
result := &NetworkCheckResult{
@@ -112,6 +120,36 @@ type NetworkCreateResultError struct {
112120
Message string `json:"message"`
113121
}
114122

123+
func validateNetworkName(networkName string) (string, error) {
124+
trimmed := strings.TrimSpace(networkName)
125+
126+
// to lowercase
127+
normalized := strings.ToLower(trimmed)
128+
129+
// replace spaces with underscores
130+
normalized = strings.ReplaceAll(normalized, " ", "-")
131+
132+
// ensure length is at least 5 characters
133+
if len(normalized) < 5 {
134+
return "", errors.New("Network name must have at least 5 characters")
135+
}
136+
137+
// ensure length is less than 50 characters
138+
if len(normalized) > 50 {
139+
return "", errors.New("Network name must be less than 50 characters")
140+
}
141+
142+
// ensure ASCII characters only
143+
for _, char := range normalized {
144+
if !((char >= 'a' && char <= 'z') || (char >= '0' && char <= '9') || char == '-') {
145+
return "", errors.New("Network name must contain only lowercase letters, numbers, and dashes")
146+
}
147+
}
148+
149+
return normalized, nil
150+
151+
}
152+
115153
func NetworkCreate(
116154
networkCreate NetworkCreateArgs,
117155
session *session.ClientSession,
@@ -173,10 +211,19 @@ func NetworkCreate(
173211
}
174212
}
175213

176-
// user is create an authenticated network
214+
validatedNetworkName, error := validateNetworkName(networkCreate.NetworkName)
215+
216+
if error != nil {
217+
result := &NetworkCreateResult{
218+
Error: &NetworkCreateResultError{
219+
Message: error.Error(),
220+
},
221+
}
222+
return result, nil
223+
}
177224

178225
// check if the network name is already taken
179-
err := checkNetworkNameAvailability(networkCreate.NetworkName, session)
226+
err := checkNetworkNameAvailability(validatedNetworkName, session)
180227
if err != nil {
181228
result := &NetworkCreateResult{
182229
Error: &NetworkCreateResultError{
@@ -186,7 +233,7 @@ func NetworkCreate(
186233
return result, nil
187234
}
188235

189-
containsProfanity := goaway.IsProfane(networkCreate.NetworkName)
236+
containsProfanity := goaway.IsProfane(validatedNetworkName)
190237

191238
if networkCreate.UserAuth != nil {
192239
// user is creating a network via email/phone + pass
@@ -205,6 +252,7 @@ func NetworkCreate(
205252
session.Ctx,
206253
&networkCreate,
207254
userAuth,
255+
validatedNetworkName,
208256
containsProfanity,
209257
)
210258

@@ -246,6 +294,7 @@ func NetworkCreate(
246294
&networkCreate,
247295
containsProfanity,
248296
*authJwt,
297+
validatedNetworkName,
249298
normalJwtUserAuth,
250299
)
251300

@@ -335,6 +384,7 @@ func NetworkCreate(
335384
networkCreateResult := networkCreateWalletAuth(
336385
session.Ctx,
337386
&networkCreate,
387+
validatedNetworkName,
338388
containsProfanity,
339389
)
340390

@@ -424,6 +474,7 @@ type networkCreateResult struct {
424474
func networkCreateWalletAuth(
425475
ctx context.Context,
426476
networkCreate *NetworkCreateArgs,
477+
validatedNetworkName string,
427478
containsProfanity bool,
428479
) networkCreateResult {
429480

@@ -495,7 +546,7 @@ func networkCreateWalletAuth(
495546
VALUES ($1, $2, $3, $4)
496547
`,
497548
createdNetworkId,
498-
networkCreate.NetworkName,
549+
validatedNetworkName,
499550
createdUserId,
500551
containsProfanity,
501552
)
@@ -534,6 +585,7 @@ func networkCreateAuthJwt(
534585
networkCreate *NetworkCreateArgs,
535586
containsProfanity bool,
536587
parsedAuthJwt AuthJwt,
588+
validatedNetworkName string,
537589
normalizedUserAuth string,
538590
) networkCreateResult {
539591

@@ -609,7 +661,7 @@ func networkCreateAuthJwt(
609661
VALUES ($1, $2, $3, $4)
610662
`,
611663
createdNetworkId,
612-
networkCreate.NetworkName,
664+
validatedNetworkName,
613665
createdUserId,
614666
containsProfanity,
615667
)
@@ -648,6 +700,7 @@ func networkCreateUserAuth(
648700
ctx context.Context,
649701
networkCreate *NetworkCreateArgs,
650702
userAuth *string,
703+
validatedNetworkName string,
651704
containsProfanity bool,
652705
) networkCreateResult {
653706

@@ -741,7 +794,7 @@ func networkCreateUserAuth(
741794
VALUES ($1, $2, $3, $4)
742795
`,
743796
createdNetworkId,
744-
networkCreate.NetworkName,
797+
validatedNetworkName,
745798
createdUserId,
746799
containsProfanity,
747800
)
@@ -907,12 +960,13 @@ func checkNetworkNameAvailability(
907960

908961
var existingNetworkId *server.Id
909962

910-
if len(networkName) < 5 {
911-
err = errors.New("Network name must have at least 5 characters")
963+
validatedNetworkName, validationErr := validateNetworkName(networkName)
964+
if validationErr != nil {
965+
err = validationErr
912966
return
913967
}
914968

915-
taken := networkNameSearch().AnyAround(session.Ctx, networkName, 1)
969+
taken := networkNameSearch().AnyAround(session.Ctx, validatedNetworkName, 1)
916970

917971
if taken {
918972
err = errors.New("Network name not available")
@@ -926,7 +980,7 @@ func checkNetworkNameAvailability(
926980
`
927981
SELECT network_id FROM network WHERE network_name = $1
928982
`,
929-
networkName,
983+
validatedNetworkName,
930984
)
931985
server.WithPgResult(result, queryErr, func() {
932986
if result.Next() {

model/network_model_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,3 +349,45 @@ func TestNetworkUpdate(t *testing.T) {
349349

350350
})
351351
}
352+
353+
func TestNetworkNameValidation(t *testing.T) {
354+
server.DefaultTestEnv().Run(func() {
355+
356+
// too short
357+
networkName := ""
358+
_, err := validateNetworkName(networkName)
359+
assert.NotEqual(t, err, nil)
360+
361+
// too long
362+
networkName = "a123456789012345678901234567890123456789012345678901"
363+
_, err = validateNetworkName(networkName)
364+
assert.NotEqual(t, err, nil)
365+
366+
/**
367+
* testing special characters
368+
*/
369+
networkName = "abcde$"
370+
_, err = validateNetworkName(networkName)
371+
assert.NotEqual(t, err, nil)
372+
373+
networkName = "abcdeé"
374+
_, err = validateNetworkName(networkName)
375+
assert.NotEqual(t, err, nil)
376+
377+
networkName = "東京タワー"
378+
_, err = validateNetworkName(networkName)
379+
assert.NotEqual(t, err, nil)
380+
381+
// test spaces
382+
networkName = "abc def"
383+
expected := "abc-def"
384+
validated, err := validateNetworkName(networkName)
385+
assert.Equal(t, validated, expected)
386+
387+
// valid name should pass
388+
networkName = "abcdef"
389+
_, err = validateNetworkName(networkName)
390+
assert.Equal(t, err, nil)
391+
392+
})
393+
}

0 commit comments

Comments
 (0)