Auth Package (internal/auth/): - Service: main auth orchestrator with multi-provider support - LocalProvider: username/password auth with bcrypt hashing - LDAPProvider: LDAP/Active Directory authentication with: - Service account bind for user search - User bind for password verification - Automatic user provisioning on first login - Group membership to role synchronization - SessionManager: token-based session lifecycle - Middleware: Gin middleware for route protection - API: REST endpoints for login/logout/register Security Features: - bcrypt with cost factor 12 for password hashing - Secure random 32-byte session tokens - HTTP-only session cookies with SameSite=Lax - Bearer token support for API clients - Session expiration and cleanup - Account disable with session invalidation API Endpoints: - POST /auth/login - Authenticate and get session - POST /auth/logout - Invalidate current session - POST /auth/logout/all - Invalidate all user sessions - POST /auth/register - Create account (if enabled) - GET /auth/me - Get current user info - PUT /auth/me - Update profile - PUT /auth/me/password - Change password 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
52 lines
1.1 KiB
Go
52 lines
1.1 KiB
Go
package auth
|
|
|
|
import (
|
|
"context"
|
|
|
|
"tyto/internal/database"
|
|
)
|
|
|
|
// LocalProvider handles local username/password authentication.
|
|
type LocalProvider struct {
|
|
db database.Database
|
|
}
|
|
|
|
// NewLocalProvider creates a new local authentication provider.
|
|
func NewLocalProvider(db database.Database) *LocalProvider {
|
|
return &LocalProvider{db: db}
|
|
}
|
|
|
|
// Name returns the provider name.
|
|
func (p *LocalProvider) Name() string {
|
|
return "local"
|
|
}
|
|
|
|
// Available returns true (local auth is always available).
|
|
func (p *LocalProvider) Available() bool {
|
|
return true
|
|
}
|
|
|
|
// Authenticate validates username and password against local database.
|
|
func (p *LocalProvider) Authenticate(ctx context.Context, username, password string) (*database.User, error) {
|
|
user, err := p.db.GetUserByUsername(ctx, username)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if user == nil {
|
|
return nil, ErrUserNotFound
|
|
}
|
|
|
|
// Only authenticate local users
|
|
if user.AuthProvider != database.AuthProviderLocal {
|
|
return nil, ErrInvalidCredentials
|
|
}
|
|
|
|
// Verify password
|
|
if !CheckPassword(password, user.PasswordHash) {
|
|
return nil, ErrInvalidCredentials
|
|
}
|
|
|
|
return user, nil
|
|
}
|