1package utils
2
3import (
4 "errors"
5 "fmt"
6 "net/mail"
7 "path"
8 "strings"
9 "unicode"
10)
11
12var (
13
14 // ErrInvalidEmail indicates that an email address is invalid.
15 ErrInvalidEmail = errors.New("invalid email address")
16)
17
18// SanitizeRepo returns a sanitized version of the given repository name.
19func SanitizeRepo(repo string) string {
20 repo = strings.TrimPrefix(repo, "/")
21 // We're using path instead of filepath here because this is not OS dependent
22 // looking at you Windows
23 repo = path.Clean(repo)
24 repo = strings.TrimSuffix(repo, ".git")
25 return repo
26}
27
28// ValidateHandle returns an error if any of the given usernames are invalid.
29func ValidateHandle(handle string) error {
30 if handle == "" {
31 return fmt.Errorf("cannot be empty")
32 }
33
34 if !unicode.IsLetter(rune(handle[0])) {
35 return fmt.Errorf("must start with a letter")
36 }
37
38 for _, r := range handle {
39 if !unicode.IsLetter(r) && !unicode.IsDigit(r) && r != '-' {
40 return fmt.Errorf("can only contain letters, numbers, and hyphens")
41 }
42 }
43
44 return nil
45}
46
47// ValidateRepo returns an error if the given repository name is invalid.
48func ValidateRepo(repo string) error {
49 if repo == "" {
50 return fmt.Errorf("repo cannot be empty")
51 }
52
53 for _, r := range repo {
54 if !unicode.IsLetter(r) && !unicode.IsDigit(r) && r != '-' && r != '_' && r != '.' && r != '/' {
55 return fmt.Errorf("repo can only contain letters, numbers, hyphens, underscores, periods, and slashes")
56 }
57 }
58
59 return nil
60}
61
62// ValidateEmail returns an error if the given email address is invalid.
63func ValidateEmail(email string) error {
64 if strings.ContainsAny(email, " <>") {
65 return ErrInvalidEmail
66 }
67
68 _, err := mail.ParseAddress(email)
69 if err != nil {
70 return fmt.Errorf("%w: %s", ErrInvalidEmail, err)
71 }
72
73 return nil
74}