You've already forked openaccounting-server
forked from cybercinch/openaccounting-server
fix: update authentication layer for GORM repository integration
- Update auth.go to use new repository interfaces - Fix test compilation errors in auth_test.go - Maintain compatibility with existing authentication flows - Update mock implementations for repository pattern 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit was merged in pull request #5.
This commit is contained in:
@@ -14,6 +14,22 @@ type AuthService struct {
|
||||
bcrypt util.Bcrypt
|
||||
}
|
||||
|
||||
// AuthRepository interface for dependency injection
|
||||
type AuthRepository interface {
|
||||
GetVerifiedUserByEmail(string) (*types.User, error)
|
||||
GetUserByActiveSession(string) (*types.User, error)
|
||||
GetUserByApiKey(string) (*types.User, error)
|
||||
GetUserByEmailVerifyCode(string) (*types.User, error)
|
||||
UpdateSessionActivity(string) error
|
||||
UpdateApiKeyActivity(string) error
|
||||
}
|
||||
|
||||
// GormAuthService uses the repository pattern
|
||||
type GormAuthService struct {
|
||||
repository AuthRepository
|
||||
bcrypt util.Bcrypt
|
||||
}
|
||||
|
||||
type Interface interface {
|
||||
Authenticate(string, string) (*types.User, error)
|
||||
AuthenticateUser(email string, password string) (*types.User, error)
|
||||
@@ -28,6 +44,12 @@ func NewAuthService(db db.Datastore, bcrypt util.Bcrypt) *AuthService {
|
||||
return authService
|
||||
}
|
||||
|
||||
func NewGormAuthService(repository AuthRepository, bcrypt util.Bcrypt) *GormAuthService {
|
||||
authService := &GormAuthService{repository: repository, bcrypt: bcrypt}
|
||||
Instance = authService
|
||||
return authService
|
||||
}
|
||||
|
||||
func (auth *AuthService) Authenticate(emailOrKey string, password string) (*types.User, error) {
|
||||
// authenticate via session, apikey or user
|
||||
user, err := auth.AuthenticateSession(emailOrKey)
|
||||
@@ -106,3 +128,83 @@ func (auth *AuthService) AuthenticateEmailVerifyCode(code string) (*types.User,
|
||||
|
||||
return u, nil
|
||||
}
|
||||
|
||||
// GormAuthService implementations
|
||||
func (auth *GormAuthService) Authenticate(emailOrKey string, password string) (*types.User, error) {
|
||||
// authenticate via session, apikey or user
|
||||
user, err := auth.AuthenticateSession(emailOrKey)
|
||||
|
||||
if err == nil {
|
||||
return user, nil
|
||||
}
|
||||
|
||||
user, err = auth.AuthenticateApiKey(emailOrKey)
|
||||
|
||||
if err == nil {
|
||||
return user, nil
|
||||
}
|
||||
|
||||
user, err = auth.AuthenticateUser(emailOrKey, password)
|
||||
|
||||
if err == nil {
|
||||
return user, nil
|
||||
}
|
||||
|
||||
user, err = auth.AuthenticateEmailVerifyCode(emailOrKey)
|
||||
|
||||
if err == nil {
|
||||
return user, nil
|
||||
}
|
||||
|
||||
return nil, errors.New("Unauthorized")
|
||||
}
|
||||
|
||||
func (auth *GormAuthService) AuthenticateUser(email string, password string) (*types.User, error) {
|
||||
u, err := auth.repository.GetVerifiedUserByEmail(email)
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.New("Invalid email or password")
|
||||
}
|
||||
|
||||
err = auth.bcrypt.CompareHashAndPassword([]byte(u.PasswordHash), []byte(password))
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.New("Invalid email or password")
|
||||
}
|
||||
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (auth *GormAuthService) AuthenticateSession(id string) (*types.User, error) {
|
||||
u, err := auth.repository.GetUserByActiveSession(id)
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.New("Invalid session")
|
||||
}
|
||||
|
||||
auth.repository.UpdateSessionActivity(id)
|
||||
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (auth *GormAuthService) AuthenticateApiKey(id string) (*types.User, error) {
|
||||
u, err := auth.repository.GetUserByApiKey(id)
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.New("Access denied")
|
||||
}
|
||||
|
||||
auth.repository.UpdateApiKeyActivity(id)
|
||||
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (auth *GormAuthService) AuthenticateEmailVerifyCode(code string) (*types.User, error) {
|
||||
u, err := auth.repository.GetUserByEmailVerifyCode(code)
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.New("Access denied")
|
||||
}
|
||||
|
||||
return u, nil
|
||||
}
|
||||
|
||||
@@ -2,12 +2,13 @@ package auth
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/openaccounting/oa-server/core/model/db"
|
||||
"github.com/openaccounting/oa-server/core/model/types"
|
||||
"github.com/openaccounting/oa-server/core/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TdUser struct {
|
||||
@@ -28,18 +29,19 @@ func (td *TdUser) GetVerifiedUserByEmail(email string) (*types.User, error) {
|
||||
|
||||
func (td *TdUser) GetVerifiedUserByEmail_1(email string) (*types.User, error) {
|
||||
return &types.User{
|
||||
"1",
|
||||
time.Unix(0, 0),
|
||||
time.Unix(0, 0),
|
||||
"John",
|
||||
"Doe",
|
||||
"johndoe@email.com",
|
||||
"password",
|
||||
"$2a$10$KrtvADe7jwrmYIe3GXFbNupOQaPIvyOKeng5826g4VGOD47TpAisG",
|
||||
true,
|
||||
"",
|
||||
false,
|
||||
"",
|
||||
Id: "1",
|
||||
Inserted: time.Unix(0, 0),
|
||||
Updated: time.Unix(0, 0),
|
||||
FirstName: "John",
|
||||
LastName: "Doe",
|
||||
Email: "johndoe@email.com",
|
||||
Password: "password",
|
||||
PasswordHash: "$2a$10$KrtvADe7jwrmYIe3GXFbNupOQaPIvyOKeng5826g4VGOD47TpAisG",
|
||||
AgreeToTerms: true,
|
||||
PasswordReset: "",
|
||||
EmailVerified: false,
|
||||
EmailVerifyCode: "",
|
||||
SignupSource: "",
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user