73 lines
1.7 KiB
Go
73 lines
1.7 KiB
Go
package domain
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"unicode"
|
|
"unicode/utf8"
|
|
|
|
"golang.org/x/text/cases"
|
|
"golang.org/x/text/unicode/norm"
|
|
)
|
|
|
|
const (
|
|
MinimumPasswordRunes = 12
|
|
MaximumPasswordBytes = 1024
|
|
MaximumIdentityRunes = 128
|
|
)
|
|
|
|
var (
|
|
ErrInvalidUsername = errors.New("invalid username")
|
|
ErrInvalidDisplayName = errors.New("invalid display name")
|
|
ErrInvalidPassword = errors.New("invalid password")
|
|
)
|
|
|
|
type OwnerIdentity struct {
|
|
Username string
|
|
UsernameKey string
|
|
DisplayName string
|
|
}
|
|
|
|
func NewOwnerIdentity(username, displayName string) (OwnerIdentity, error) {
|
|
username, usernameKey, err := NormalizeUsername(username)
|
|
if err != nil {
|
|
return OwnerIdentity{}, err
|
|
}
|
|
displayName = norm.NFC.String(strings.TrimSpace(displayName))
|
|
if !validIdentityText(displayName) {
|
|
return OwnerIdentity{}, ErrInvalidDisplayName
|
|
}
|
|
return OwnerIdentity{
|
|
Username: username,
|
|
UsernameKey: usernameKey,
|
|
DisplayName: displayName,
|
|
}, nil
|
|
}
|
|
|
|
func NormalizeUsername(username string) (string, string, error) {
|
|
username = norm.NFC.String(strings.TrimSpace(username))
|
|
if !validIdentityText(username) {
|
|
return "", "", ErrInvalidUsername
|
|
}
|
|
return username, cases.Fold().String(username), nil
|
|
}
|
|
|
|
func ValidatePassword(password string) error {
|
|
if !utf8.ValidString(password) || len(password) > MaximumPasswordBytes || utf8.RuneCountInString(password) < MinimumPasswordRunes {
|
|
return ErrInvalidPassword
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func validIdentityText(value string) bool {
|
|
count := utf8.RuneCountInString(value)
|
|
if count == 0 || count > MaximumIdentityRunes {
|
|
return false
|
|
}
|
|
for _, character := range value {
|
|
if unicode.IsControl(character) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|