chore: user password login check

This commit is contained in:
kekskurse 2025-03-17 21:22:28 +01:00
parent 487a75c9d1
commit be92a9bfee
3 changed files with 97 additions and 0 deletions

View file

@ -6,4 +6,5 @@ var (
ErrCantOpenDatabase = errors.New("failed to open database")
ErrCantExecuteQuery = errors.New("cant execute query")
ErrCantEncryptPassword = errors.New("cant encrypt password")
ErrPasswordDontMatch = errors.New("user password dont match")
)

View file

@ -1,10 +1,20 @@
package userstore
import (
"database/sql"
"fmt"
"time"
"git.keks.cloud/kekskurse/miniauth/pkg/utils"
"golang.org/x/crypto/bcrypt"
)
type User struct {
Username string
CreatedAt time.Time
UpdatedAt time.Time
}
func (s Store) UserWrite(username, password string) (int64, error) {
query := "INSERT INTO users (username, password) VALUES (?, ?);"
log := s.log.With().Str("func", "UserWrite").Str("query", query).Str("username", username).Logger()
@ -26,6 +36,39 @@ func (s Store) UserWrite(username, password string) (int64, error) {
return id, nil
}
func (s Store) UserCheckPassword(username, password string) (User, error) {
query := fmt.Sprintf("SELECT %v FROM users WHERE username = ?", s.userGetFields())
log := s.log.With().Str("func", "UserLogin").Str("username", username).Str("query", query).Logger()
var pwHash string
row := s.db.QueryRow(query, username)
user, pwHash, err := s.userScan(row)
if err != nil {
return User{}, utils.WrapError(ErrCantExecuteQuery, err, log)
}
err = bcrypt.CompareHashAndPassword([]byte(pwHash), []byte(password))
if err != nil {
return User{}, utils.WrapError(ErrPasswordDontMatch, err, log)
}
return user, nil
}
func (s Store) userGetFields() string {
return "username, password, created_at, updated_at"
}
func (s Store) userScan(row *sql.Row) (User, string, error) {
u := User{}
var pwHash string
err := row.Scan(&u.Username, &pwHash, &u.CreatedAt, &u.UpdatedAt)
if err != nil {
return User{}, "", err
}
return u, pwHash, nil
}
func (s Store) UserExists(username string) (bool, error) {
query := "SELECT COUNT(*) FROM users WHERE username = ?"
log := s.log.With().Str("func", "UserExists").Str("query", query).Str("username", username).Logger()

View file

@ -2,6 +2,7 @@ package userstore
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
@ -134,3 +135,55 @@ func TestUserRemoveFaildMailExists(t *testing.T) {
assert.Nil(t, err, "should be abel to get user count without error")
assert.Equal(t, 2, count, "should found 2 users")
}
func TestUserPasswordCheck(t *testing.T) {
store, err := NewDummyStore()
assert.Nil(t, err, "[setup] should get dummy store without error")
_, err = store.UserWrite("kekskurse", "kekskurse")
assert.Nil(t, err, "[setup] should be abel to create user")
tts := []struct {
name string
username string
password string
expectErr error
expectErrString string
expectUsername string
}{
{
name: "user not found",
expectErr: ErrCantExecuteQuery,
expectErrString: "cant execute query: sql: no rows in result set",
},
{
name: "wrong password",
username: "kekskurse",
expectErr: ErrPasswordDontMatch,
expectErrString: "user password dont match: crypto/bcrypt: hashedPassword is not the hash of the given password",
},
{
name: "successfull",
username: "kekskurse",
password: "kekskurse",
expectErr: nil,
expectUsername: "kekskurse",
},
}
for _, tt := range tts {
t.Run(tt.name, func(t *testing.T) {
user, err := store.UserCheckPassword(tt.username, tt.password)
if tt.expectErr != nil {
assert.ErrorIs(t, err, tt.expectErr)
assert.Equal(t, tt.expectErrString, err.Error())
return
}
assert.Nil(t, err)
assert.Equal(t, tt.expectUsername, user.Username)
assert.Equal(t, time.Now().Year(), user.CreatedAt.Year())
assert.Equal(t, time.Now().Year(), user.UpdatedAt.Year())
})
}
}