diff --git a/internal/accounts/api/controller.go b/internal/accounts/api/controller.go index 11b7522..1a246f1 100644 --- a/internal/accounts/api/controller.go +++ b/internal/accounts/api/controller.go @@ -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 } + } diff --git a/internal/accounts/domain/account.go b/internal/accounts/domain/account.go index 6f9d139..d4209c7 100644 --- a/internal/accounts/domain/account.go +++ b/internal/accounts/domain/account.go @@ -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 +} diff --git a/internal/accounts/domain/repository.go b/internal/accounts/domain/repository.go index 1bf6b12..72210eb 100644 --- a/internal/accounts/domain/repository.go +++ b/internal/accounts/domain/repository.go @@ -1,6 +1,6 @@ package domain type AccountRepository interface { - Insert(account *Account) (int, error) + Insert(account Account) (int, error) FetchOneByUsername(username string) (*Account, error) } diff --git a/internal/accounts/domain/service.go b/internal/accounts/domain/service.go index 8baaca8..7cc23a9 100644 --- a/internal/accounts/domain/service.go +++ b/internal/accounts/domain/service.go @@ -1,4 +1,7 @@ package domain +import "gitea.qpismont.fr/qpismont/trepa/internal/core" + type AccountService interface { + Login(login AccountLogin) (*Account, *core.HTTPError) } diff --git a/internal/accounts/repository/account.go b/internal/accounts/repository/account.go index 5c6f42c..17caafb 100644 --- a/internal/accounts/repository/account.go +++ b/internal/accounts/repository/account.go @@ -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) diff --git a/internal/accounts/repository/account_test.go b/internal/accounts/repository/account_test.go index 0e56437..e1aaf7b 100644 --- a/internal/accounts/repository/account_test.go +++ b/internal/accounts/repository/account_test.go @@ -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, diff --git a/internal/accounts/service/account.go b/internal/accounts/service/account.go index 8cca60c..9925549 100644 --- a/internal/accounts/service/account.go +++ b/internal/accounts/service/account.go @@ -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 +} diff --git a/internal/core/helpers.go b/internal/core/env.go similarity index 100% rename from internal/core/helpers.go rename to internal/core/env.go diff --git a/internal/core/helpers_test.go b/internal/core/env_test.go similarity index 100% rename from internal/core/helpers_test.go rename to internal/core/env_test.go diff --git a/internal/core/hash.go b/internal/core/hash.go new file mode 100644 index 0000000..f5cb3e6 --- /dev/null +++ b/internal/core/hash.go @@ -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 +} diff --git a/internal/core/hash_test.go b/internal/core/hash_test.go new file mode 100644 index 0000000..ff194d1 --- /dev/null +++ b/internal/core/hash_test.go @@ -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)) +}