93 lines
1.9 KiB
Go

// Package auth provides authentication and session management functionality.
// It includes secure session storage with in-memory caching and JSON persistence,
// user authentication against the database, and secure cookie handling.
package auth
import (
"dk/internal/password"
"dk/internal/session"
"dk/internal/users"
)
var Manager *AuthManager
type AuthManager struct {
store *session.Store
}
func Init(sessionsFilePath string) {
Manager = &AuthManager{
store: session.NewStore(sessionsFilePath),
}
}
func (am *AuthManager) Authenticate(usernameOrEmail, plainPassword string) (*users.User, error) {
var user *users.User
var err error
user, err = users.ByUsername(usernameOrEmail)
if err != nil {
user, err = users.ByEmail(usernameOrEmail)
if err != nil {
return nil, err
}
}
isValid, err := password.Verify(plainPassword, user.Password)
if err != nil {
return nil, err
}
if !isValid {
return nil, ErrInvalidCredentials
}
return user, nil
}
func (am *AuthManager) CreateSession(user *users.User) *session.Session {
sess := session.New(user.ID, user.Username, user.Email)
am.store.Save(sess)
return sess
}
func (am *AuthManager) GetSession(sessionID string) (*session.Session, bool) {
return am.store.Get(sessionID)
}
func (am *AuthManager) UpdateSession(sessionID string) bool {
sess, exists := am.store.Get(sessionID)
if !exists {
return false
}
sess.Touch()
am.store.Save(sess)
return true
}
func (am *AuthManager) DeleteSession(sessionID string) {
am.store.Delete(sessionID)
}
func (am *AuthManager) SessionStats() (total, active int) {
return am.store.Stats()
}
func (am *AuthManager) Close() error {
return am.store.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
}