105 lines
2.3 KiB
Go
105 lines
2.3 KiB
Go
package auth
|
|
|
|
import (
|
|
"dk/internal/database"
|
|
"dk/internal/password"
|
|
"dk/internal/users"
|
|
)
|
|
|
|
// Manager is the global singleton instance
|
|
var Manager *AuthManager
|
|
|
|
type User struct {
|
|
ID int
|
|
Username string
|
|
Email string
|
|
}
|
|
|
|
type AuthManager struct {
|
|
sessionStore *SessionStore
|
|
db *database.DB
|
|
}
|
|
|
|
func NewAuthManager(db *database.DB, sessionsFilePath string) *AuthManager {
|
|
return &AuthManager{
|
|
sessionStore: NewSessionStore(sessionsFilePath),
|
|
db: db,
|
|
}
|
|
}
|
|
|
|
// InitializeManager initializes the global Manager singleton
|
|
func InitializeManager(db *database.DB, sessionsFilePath string) {
|
|
Manager = NewAuthManager(db, sessionsFilePath)
|
|
}
|
|
|
|
func (am *AuthManager) Authenticate(usernameOrEmail, plainPassword string) (*User, error) {
|
|
var user *users.User
|
|
var err error
|
|
|
|
// Try to find user by username first
|
|
user, err = users.GetByUsername(am.db, usernameOrEmail)
|
|
if err != nil {
|
|
// Try by email if username lookup failed
|
|
user, err = users.GetByEmail(am.db, usernameOrEmail)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
// Verify password
|
|
isValid, err := password.Verify(plainPassword, user.Password)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if !isValid {
|
|
return nil, ErrInvalidCredentials
|
|
}
|
|
|
|
return &User{
|
|
ID: user.ID,
|
|
Username: user.Username,
|
|
Email: user.Email,
|
|
}, nil
|
|
}
|
|
|
|
func (am *AuthManager) CreateSession(user *User) *Session {
|
|
return am.sessionStore.Create(user.ID, user.Username, user.Email)
|
|
}
|
|
|
|
func (am *AuthManager) GetSession(sessionID string) (*Session, bool) {
|
|
return am.sessionStore.Get(sessionID)
|
|
}
|
|
|
|
func (am *AuthManager) UpdateSession(sessionID string) bool {
|
|
return am.sessionStore.Update(sessionID)
|
|
}
|
|
|
|
func (am *AuthManager) DeleteSession(sessionID string) {
|
|
am.sessionStore.Delete(sessionID)
|
|
}
|
|
|
|
func (am *AuthManager) SessionStats() (total, active int) {
|
|
return am.sessionStore.Stats()
|
|
}
|
|
|
|
func (am *AuthManager) DB() *database.DB {
|
|
return am.db
|
|
}
|
|
|
|
func (am *AuthManager) Close() error {
|
|
return am.sessionStore.Close()
|
|
}
|
|
|
|
var (
|
|
ErrInvalidCredentials = &AuthError{"invalid username/email or password"}
|
|
ErrSessionNotFound = &AuthError{"session not found"}
|
|
ErrSessionExpired = &AuthError{"session expired"}
|
|
)
|
|
|
|
type AuthError struct {
|
|
Message string
|
|
}
|
|
|
|
func (e *AuthError) Error() string {
|
|
return e.Message
|
|
} |