package auth import ( "dk/internal/password" "dk/internal/users" ) // Manager is the global singleton instance var Manager *AuthManager // AuthManager is a wrapper for the session store to add // authentication tools over the store itself type AuthManager struct { store *SessionStore } // Init initializes the global auth manager (auth.Manager) func Init(sessionsFilePath string) { Manager = &AuthManager{ store: NewSessionStore(sessionsFilePath), } } // Authenticate checks for the usernaname or email, then verifies the plain password // against the stored hash. func (am *AuthManager) Authenticate(usernameOrEmail, plainPassword string) (*users.User, error) { var user *users.User var err error // Try to find user by username first user, err = users.GetByUsername(usernameOrEmail) if err != nil { user, err = users.GetByEmail(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 { return am.store.Create(user.ID, user.Username, user.Email) } func (am *AuthManager) GetSession(sessionID string) (*Session, bool) { return am.store.Get(sessionID) } func (am *AuthManager) UpdateSession(sessionID string) bool { return am.store.Update(sessionID) } 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 }