Files
tyto/backend/internal/auth/local.go
vikingowl 50c5811e22 feat: add authentication system with local and LDAP support
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>
2025-12-28 08:24:39 +01:00

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
}