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) }