62 lines
1014 B
Go
62 lines
1014 B
Go
package data
|
|
|
|
const (
|
|
scryptN = 32768
|
|
scriptR = 8
|
|
scryptP = 1
|
|
)
|
|
|
|
type User struct {
|
|
ID string
|
|
Created int64
|
|
User string
|
|
Password []byte
|
|
Salt []byte
|
|
}
|
|
|
|
type Login struct {
|
|
User string `json:"user"`
|
|
Password string `json:"password,omitzero"`
|
|
Token string `json:"token,omitzero"`
|
|
}
|
|
|
|
func derive(password string, salt []byte) []byte {
|
|
return scrypt.Key(login.Password, u.Salt, scryptN, scryptR, scryptN, 32)
|
|
}
|
|
|
|
func (u *User) Check(login *Login) bool {
|
|
if u.User != login.User {
|
|
return false
|
|
}
|
|
|
|
derived := derive(login.Password, u.Salt)
|
|
|
|
if subtle.ConstantTimeCompare(derived, u.Password) != 0 {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func (u *User) Register(login *Login) error {
|
|
var err error
|
|
|
|
if u.User != "" && u.User != login.User {
|
|
return errors.New("invalid user")
|
|
}
|
|
|
|
if u.ID == "" {
|
|
u.ID = ulid.Make()
|
|
}
|
|
|
|
u.User = login.User
|
|
u.Salt, err = Salt()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to register user: %w", err)
|
|
}
|
|
|
|
u.Password = derive(login.Password, u.Salt)
|
|
return nil
|
|
}
|
|
|