Refactor account handling: update Login method signature, introduce AccountLogin and AccountCreate types, modify repository interface, and implement login logic in service. Add environment variable loading and hashing functions with tests.
This commit is contained in:
parent
dcc5df8300
commit
26ce8522ac
11 changed files with 69 additions and 5 deletions
|
@ -19,7 +19,7 @@ func NewController(service domain.AccountService) Controller {
|
|||
return Controller{service: service}
|
||||
}
|
||||
|
||||
func (c *Controller) Login(w *core.Response, r *http.Request) {
|
||||
func (c Controller) Login(w *core.Response, r *http.Request) {
|
||||
var request LoginAccountRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
|
||||
w.WriteError(core.ErrInvalidStruct)
|
||||
|
@ -30,4 +30,5 @@ func (c *Controller) Login(w *core.Response, r *http.Request) {
|
|||
w.WriteError(core.ErrInvalidStruct)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,3 +8,14 @@ type Account struct {
|
|||
CreatedAt string `db:"created_at" json:"created_at"`
|
||||
UpdatedAt string `db:"updated_at" json:"updated_at"`
|
||||
}
|
||||
|
||||
type AccountLogin struct {
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
type AccountCreate struct {
|
||||
Username string
|
||||
Password string
|
||||
RoleId int
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package domain
|
||||
|
||||
type AccountRepository interface {
|
||||
Insert(account *Account) (int, error)
|
||||
Insert(account Account) (int, error)
|
||||
FetchOneByUsername(username string) (*Account, error)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
package domain
|
||||
|
||||
import "gitea.qpismont.fr/qpismont/trepa/internal/core"
|
||||
|
||||
type AccountService interface {
|
||||
Login(login AccountLogin) (*Account, *core.HTTPError)
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ func NewRepository(db *sqlx.DB) domain.AccountRepository {
|
|||
return &Repository{db: db}
|
||||
}
|
||||
|
||||
func (r *Repository) Insert(account *domain.Account) (int, error) {
|
||||
func (r *Repository) Insert(account domain.Account) (int, error) {
|
||||
var id int
|
||||
|
||||
stmt, err := r.db.Prepare(SqlInsert)
|
||||
|
|
|
@ -14,7 +14,7 @@ func TestRepository_Insert(t *testing.T) {
|
|||
|
||||
repo := NewRepository(db)
|
||||
|
||||
account := &domain.Account{
|
||||
account := domain.Account{
|
||||
Username: "test",
|
||||
Password: "test",
|
||||
RoleId: 1,
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package service
|
||||
|
||||
import "gitea.qpismont.fr/qpismont/trepa/internal/accounts/domain"
|
||||
import (
|
||||
"gitea.qpismont.fr/qpismont/trepa/internal/accounts/domain"
|
||||
"gitea.qpismont.fr/qpismont/trepa/internal/core"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
repository domain.AccountRepository
|
||||
|
@ -9,3 +12,16 @@ type Service struct {
|
|||
func NewService(repository domain.AccountRepository) domain.AccountService {
|
||||
return &Service{repository: repository}
|
||||
}
|
||||
|
||||
func (s *Service) Login(login domain.AccountLogin) (*domain.Account, *core.HTTPError) {
|
||||
account, err := s.repository.FetchOneByUsername(login.Username)
|
||||
if err != nil {
|
||||
return nil, domain.ErrAccountNotFound
|
||||
}
|
||||
|
||||
if !core.ComparePassword(login.Password, account.Password) {
|
||||
return nil, domain.ErrBadPassword
|
||||
}
|
||||
|
||||
return account, nil
|
||||
}
|
||||
|
|
12
internal/core/hash.go
Normal file
12
internal/core/hash.go
Normal file
|
@ -0,0 +1,12 @@
|
|||
package core
|
||||
|
||||
import "golang.org/x/crypto/argon2"
|
||||
|
||||
func HashPassword(password string) string {
|
||||
return string(argon2.IDKey([]byte(password), nil, 1, 64*1024, 4, 32))
|
||||
}
|
||||
|
||||
func ComparePassword(password string, hash string) bool {
|
||||
hashedPassword := HashPassword(password)
|
||||
return hashedPassword == hash
|
||||
}
|
21
internal/core/hash_test.go
Normal file
21
internal/core/hash_test.go
Normal file
|
@ -0,0 +1,21 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestHashPassword(t *testing.T) {
|
||||
password := "password"
|
||||
hashedPassword := HashPassword(password)
|
||||
assert.NotEmpty(t, hashedPassword)
|
||||
t.Log(hashedPassword)
|
||||
assert.Equal(t, hashedPassword, "LOLPASSWORD")
|
||||
}
|
||||
|
||||
func TestComparePassword(t *testing.T) {
|
||||
password := "password"
|
||||
hashedPassword := HashPassword(password)
|
||||
assert.True(t, ComparePassword(password, hashedPassword))
|
||||
}
|
Loading…
Reference in a new issue