@@ -21,7 +21,6 @@ import (
21
21
"errors"
22
22
"fmt"
23
23
"net/mail"
24
- "strings"
25
24
26
25
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
27
26
"github.com/superseriousbusiness/gotosocial/internal/config"
@@ -32,8 +31,8 @@ import (
32
31
)
33
32
34
33
const (
35
- maximumPasswordLength = 256
36
- minimumPasswordEntropy = 60 // dictates password strength. See https://github.com/wagslane/go-password-validator
34
+ maximumPasswordLength = 72 // 72 bytes is the maximum length afforded by bcrypt. See https://pkg.go.dev/golang.org/x/crypto/bcrypt#GenerateFromPassword.
35
+ minimumPasswordEntropy = 60 // Heuristic for password strength. See https://github.com/wagslane/go-password-validator.
37
36
minimumReasonLength = 40
38
37
maximumReasonLength = 500
39
38
maximumSiteTitleLength = 40
@@ -47,23 +46,29 @@ const (
47
46
maximumListTitleLength = 200
48
47
)
49
48
50
- // NewPassword returns an error if the given password is not sufficiently strong, or nil if it's ok.
49
+ // NewPassword returns a helpful error if the given password
50
+ // is too short, too long, or not sufficiently strong.
51
51
func NewPassword (password string ) error {
52
- if password == "" {
53
- return errors .New ("no password provided" )
54
- }
55
-
56
- if len ([]rune (password )) > maximumPasswordLength {
57
- return fmt .Errorf ("password should be no more than %d chars" , maximumPasswordLength )
52
+ // Ensure length is OK first.
53
+ if pwLen := len (password ); pwLen == 0 {
54
+ return errors .New ("no password provided / provided password was 0 bytes" )
55
+ } else if pwLen > maximumPasswordLength {
56
+ return fmt .Errorf (
57
+ "password should be no more than %d bytes, provided password was %d bytes" ,
58
+ maximumPasswordLength , pwLen ,
59
+ )
58
60
}
59
61
60
62
if err := pwv .Validate (password , minimumPasswordEntropy ); err != nil {
61
- // Modify error message to include percentage requred entropy the password has
62
- percent := int (100 * pwv .GetEntropy (password ) / minimumPasswordEntropy )
63
- return errors .New (strings .ReplaceAll (
64
- err .Error (),
65
- "insecure password" ,
66
- fmt .Sprintf ("password is only %d%% strength" , percent )))
63
+ // Calculate the percentage of our desired entropy this password fulfils.
64
+ entropyPercent := int (100 * pwv .GetEntropy (password ) / minimumPasswordEntropy )
65
+
66
+ // Replace the first 17 bytes (`insecure password`)
67
+ // of the error string with our own entropy message.
68
+ entropyMsg := fmt .Sprintf ("password is only %d%% strength" , entropyPercent )
69
+ errMsg := entropyMsg + err .Error ()[17 :]
70
+
71
+ return errors .New (errMsg )
67
72
}
68
73
69
74
return nil // password OK
0 commit comments