75 lines
1.7 KiB
Go
75 lines
1.7 KiB
Go
package auth
|
|
|
|
import (
|
|
"addrss/pkg/repo"
|
|
"fmt"
|
|
"math/rand"
|
|
"time"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
type NewPassword struct {
|
|
Password string `json:"-"`
|
|
Hash string `json:"-"`
|
|
}
|
|
|
|
type PasswordChange struct {
|
|
UserId int64 `json:"userId"`
|
|
OldPassword string `json:"oldPassword"`
|
|
NewPassword string `json:"newPassword"`
|
|
ConfirmPassword string `json:"confirmPassword"`
|
|
}
|
|
|
|
func ChangePassword(pc PasswordChange) error {
|
|
u, err := repo.GetUserById(pc.UserId)
|
|
if err != nil {
|
|
return fmt.Errorf("could not get user for user id %d: %v", pc.UserId, err)
|
|
}
|
|
|
|
if err = bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(pc.OldPassword)); err != nil {
|
|
return fmt.Errorf("incorrect password for user id %d", pc.UserId)
|
|
}
|
|
|
|
h, err := bcrypt.GenerateFromPassword([]byte(pc.NewPassword), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return fmt.Errorf("bcrypt error: %v", err)
|
|
}
|
|
|
|
u.Password = string(h)
|
|
if err = repo.UpdateUserPassword(u); err != nil {
|
|
return fmt.Errorf("failed to update password for user id %d: %v", u.Id, err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetRandomPassword(length int) (NewPassword, error) {
|
|
p := GetRandomString(length)
|
|
|
|
h, err := bcrypt.GenerateFromPassword([]byte(p), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return NewPassword{}, err
|
|
}
|
|
|
|
np := NewPassword{
|
|
Password: p,
|
|
Hash: string(h),
|
|
}
|
|
|
|
return np, nil
|
|
}
|
|
|
|
// GetRandomString Keep as a separate function in case this becomes useful for some other purpose
|
|
func GetRandomString(length int) string {
|
|
const chars = "!@#$%?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
|
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
|
|
b := make([]byte, length)
|
|
for i := range b {
|
|
b[i] = chars[rnd.Intn(len(chars))]
|
|
}
|
|
|
|
return string(b)
|
|
}
|