Files
openaccounting-server/core/auth/auth.go
Aaron Guise b5ea2095e4 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>
2025-06-30 22:09:36 +12:00

211 lines
4.8 KiB
Go

package auth
import (
"errors"
"github.com/openaccounting/oa-server/core/model/db"
"github.com/openaccounting/oa-server/core/model/types"
"github.com/openaccounting/oa-server/core/util"
)
var Instance Interface
type AuthService struct {
db db.Datastore
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)
AuthenticateSession(string) (*types.User, error)
AuthenticateApiKey(string) (*types.User, error)
AuthenticateEmailVerifyCode(string) (*types.User, error)
}
func NewAuthService(db db.Datastore, bcrypt util.Bcrypt) *AuthService {
authService := &AuthService{db: db, bcrypt: bcrypt}
Instance = 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)
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 *AuthService) AuthenticateUser(email string, password string) (*types.User, error) {
u, err := auth.db.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 *AuthService) AuthenticateSession(id string) (*types.User, error) {
u, err := auth.db.GetUserByActiveSession(id)
if err != nil {
return nil, errors.New("Invalid session")
}
auth.db.UpdateSessionActivity(id)
return u, nil
}
func (auth *AuthService) AuthenticateApiKey(id string) (*types.User, error) {
u, err := auth.db.GetUserByApiKey(id)
if err != nil {
return nil, errors.New("Access denied")
}
auth.db.UpdateApiKeyActivity(id)
return u, nil
}
func (auth *AuthService) AuthenticateEmailVerifyCode(code string) (*types.User, error) {
u, err := auth.db.GetUserByEmailVerifyCode(code)
if err != nil {
return nil, errors.New("Access denied")
}
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
}