-
Notifications
You must be signed in to change notification settings - Fork 18
/
password.go
52 lines (45 loc) · 1.75 KB
/
password.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package auth
import (
"errors"
"golang.org/x/crypto/bcrypt"
)
var (
errSameUsernamePassword = errors.New("Username and password must be different")
errInvalidUsername = errors.New("Username must be at least 3 characters and only letters, numbers, underscores, and dashes are allowed")
errInvalidPassword = errors.New("Password must be at least 5 characters and only letters, numbers, underscores, and dashes are allowed")
)
// hashPassword generates a bcrypt-encrypted hash from given password
func hashPassword(password string) (string, error) {
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
return "", errors.New("bcrypt password hashing unsuccessful: " + err.Error())
}
return string(hash), nil
}
// correctPassword checks if given password maps correctly to the given hash
func correctPassword(hash string, password string) bool {
return bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) == nil
}
// validateCredentialValues takes a username and password and verifies
// if they are of sufficient length and if they only contain legal characters
func validateCredentialValues(username, password string) error {
if username == password {
return errSameUsernamePassword
}
if len(password) < 5 || len(password) >= 128 || !isLegalString(password) {
return errInvalidPassword
}
if len(username) < 3 || len(username) >= 128 || !isLegalString(username) {
return errInvalidUsername
}
return nil
}
// isLegalString returns true if `str` only contains characters [A-Z], [a-z], or '_' or '-'
func isLegalString(str string) bool {
for _, c := range str {
if (c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < 48 || c > 57) && c != '_' && c != '-' {
return false
}
}
return true
}