blob: 5bcb8a0988a0de177849045c02ce12a5d1d86752 [file] [log] [blame]
iomodo48c837e2021-02-19 01:17:07 +04001package model
2
3import (
iomodo48c837e2021-02-19 01:17:07 +04004 "regexp"
iomodo48c837e2021-02-19 01:17:07 +04005 "unicode"
6
7 "github.com/pkg/errors"
iomodo352127d2021-03-26 20:10:32 +04008 "golang.org/x/crypto/bcrypt"
iomodo48c837e2021-02-19 01:17:07 +04009)
10
11const (
12 userNameMaxLength = 64
13 userNameMinLength = 1
14 userEmailMaxLength = 128
15)
16
17// User contains the details about the user.
iomodo48c837e2021-02-19 01:17:07 +040018type User struct {
19 ID string `json:"id"`
20 CreateAt int64 `json:"create_at,omitempty"`
21 UpdateAt int64 `json:"update_at,omitempty"`
22 DeleteAt int64 `json:"delete_at"`
23 Username string `json:"username"`
24 Password string `json:"password,omitempty"`
iomodo48c837e2021-02-19 01:17:07 +040025 LastPasswordUpdate int64 `json:"last_password_update,omitempty"`
26}
27
28// IsValid validates the user and returns an error if it isn't configured
29// correctly.
30func (u *User) IsValid() error {
31 if !isValidID(u.ID) {
32 return invalidUserError("id", "")
33 }
34
35 if u.CreateAt == 0 {
36 return invalidUserError("create_at", u.ID)
37 }
38
39 if u.UpdateAt == 0 {
40 return invalidUserError("update_at", u.ID)
41 }
42
43 if !isValidUsername(u.Username) {
44 return invalidUserError("username", u.ID)
45 }
46
iomodo48c837e2021-02-19 01:17:07 +040047 return nil
48}
49
iomodo352127d2021-03-26 20:10:32 +040050// Clone clones the object
iomodo07334d22021-02-24 01:08:40 +040051func (u *User) Clone() *User {
52 user := *u
53 return &user
54}
55
iomodo352127d2021-03-26 20:10:32 +040056// SanitizeInput removes input data from the user object that is not user controlled
57func (u *User) SanitizeInput() {
58 u.ID = ""
59 u.CreateAt = 0
60 u.UpdateAt = 0
61 u.DeleteAt = 0
62 u.LastPasswordUpdate = 0
63}
64
65// SanitizeOutput removes output data from the user object that is not user controlled
66func (u *User) SanitizeOutput() {
67 u.Password = ""
68}
69
70// HashPassword hashes user's password
71func (u *User) HashPassword() {
72 if u.Password == "" {
73 return
74 }
75
76 hash, err := bcrypt.GenerateFromPassword([]byte(u.Password), 10)
77 if err != nil {
78 panic(err)
79 }
80
81 u.Password = string(hash)
82}
83
iomodo48c837e2021-02-19 01:17:07 +040084func isValidID(value string) bool {
85 if len(value) != 26 {
86 return false
87 }
88
89 for _, r := range value {
90 if !unicode.IsLetter(r) && !unicode.IsNumber(r) {
91 return false
92 }
93 }
94
95 return true
96}
97
98func invalidUserError(fieldName string, userID string) error {
99 return errors.Errorf("Invalid User field: %s; id: %s", fieldName, userID)
100}
101
102func isValidUsername(s string) bool {
103 if len(s) < userNameMinLength || len(s) > userNameMaxLength {
104 return false
105 }
106
107 validUsernameChars := regexp.MustCompile(`^[a-z0-9\.\-_]+$`)
108 if !validUsernameChars.MatchString(s) {
109 return false
110 }
111
112 return true
113}