Documentation
¶
Overview ¶
Package admin provides role-based access control (RBAC) and administrative user management.
This plugin extends the auth.User model with:
- Role management (admin role assignment)
- User ban/unban functionality with expiry dates
- Platform statistics and analytics
- Administrative CRUD operations for user accounts
All admin endpoints require the 'admin' role via RequireAdminMiddleware.
Key Features:
- Role-based authorization (admin role)
- User ban management with reasons and expiry dates
- User enable/disable controls
- User listing with pagination
- Platform statistics
Database Extensions: Adds columns to the 'user' table:
- role (VARCHAR): User role (e.g., "admin")
- banned (BOOLEAN): Ban status
- ban_reason (TEXT): Ban reason text
- ban_expiry (TIMESTAMP): Ban expiration date (NULL for permanent)
- ban_counter (INTEGER): Number of times user has been banned
Route Structure:
- GET /admin/users - List all users (paginated)
- GET /admin/users/:id - Get user details
- POST /admin/users/:id/disable - Disable user account
- POST /admin/users/:id/enable - Enable user account
- DELETE /admin/users/:id - Delete user account
- POST /admin/users/:id/ban - Ban user with reason
- POST /admin/users/:id/unban - Unban user
- PUT /admin/users/:id/role - Update user role
- GET /admin/stats - Get platform statistics
Index ¶
- Constants
- func GetMigrations(dialect plugins.Dialect) ([]plugins.Migration, error)
- func GetSchemaRequirements(dialect plugins.Dialect) []plugins.SchemaRequirement
- type Plugin
- func (a *Plugin) AssignRole(ctx context.Context, userID string, role string) error
- func (a *Plugin) BanUser(ctx context.Context, userID, reason string, expiresAt *time.Time) error
- func (a *Plugin) DeleteUser(ctx context.Context, userID string) error
- func (a *Plugin) Dependencies() []plugins.Dependency
- func (a *Plugin) Description() string
- func (a *Plugin) DisableUser(ctx context.Context, userID string) error
- func (a *Plugin) EnableUser(ctx context.Context, userID string) error
- func (a *Plugin) EnrichUser(ctx context.Context, user *core.EnrichedUser) error
- func (a *Plugin) EnrichUserMiddleware() func(http.Handler) http.Handler
- func (a *Plugin) GetAdminUser(ctx context.Context, userID string) (admintypes.User, error)
- func (a *Plugin) GetMigrations() []plugins.Migration
- func (a *Plugin) GetStats(ctx context.Context) (admintypes.StatsResponse, error)
- func (a *Plugin) GetUser(ctx context.Context, userID string) (admintypes.User, error)
- func (a *Plugin) GetUserRaw(ctx context.Context, userID string) (map[string]any, error)
- func (a *Plugin) GetUserRole(ctx context.Context, userID string) (string, error)
- func (a *Plugin) Init(ctx context.Context, aegis plugins.Aegis) error
- func (a *Plugin) ListUsers(ctx context.Context, offset, limit int) ([]admintypes.User, error)
- func (a *Plugin) ListUsersRaw(ctx context.Context, offset, limit int) ([]map[string]any, error)
- func (a *Plugin) MountRoutes(r router.Router, prefix string)
- func (a *Plugin) Name() string
- func (a *Plugin) ProvidesAuthMethods() []string
- func (a *Plugin) RemoveRole(ctx context.Context, userID string, role string) error
- func (a *Plugin) RequireAdminMiddleware() func(http.Handler) http.Handler
- func (a *Plugin) RequireRoleMiddleware(requiredRole string) func(http.Handler) http.Handler
- func (a *Plugin) RequiresTables() []string
- func (a *Plugin) UnbanUser(ctx context.Context, userID string) error
- func (a *Plugin) Version() string
Constants ¶
const ( // ExtKeyRole is the key for user role in EnrichedUser extensions. // // Available as: // - In handlers: enriched.GetString("role") // - In middleware: plugins.GetUserExtensionString(ctx, ExtKeyRole) // - In JSON: {"role": "admin"} ExtKeyRole = "role" // ExtKeyPermissions is the key for user permissions in EnrichedUser extensions. // // Available as: // - In handlers: enriched.GetStringSlice("permissions") // - In JSON: {"permissions": [...]} // // Note: Currently not implemented - reserved for future use. ExtKeyPermissions = "permissions" // RoleAdmin is the default role for administrative users. RoleAdmin = "admin" )
Admin plugin context keys for EnrichedUser extensions.
These keys are used to store admin-specific data in the user context, making them available throughout the request lifecycle and in API responses.
Simple field names are used - they become top-level JSON fields in responses.
const ( // Request schemas SchemaBanUserRequest = "BanUserRequest" SchemaUpdateRoleRequest = "UpdateRoleRequest" // Response schemas SchemaAdminUser = "AdminUser" SchemaAdminStats = "AdminStats" )
Schema names for OpenAPI specification generation.
Variables ¶
This section is empty.
Functions ¶
func GetMigrations ¶
GetMigrations returns all database migrations for the admin plugin.
This function loads migrations from embedded SQL files and returns them in version order.
Version Numbering:
- Version 001+: Migrations from migrations/<dialect>/<version>_<description>.<up|down>.sql
Migration File Format:
- Up migration: 001_initial.up.sql
- Down migration: 001_initial.down.sql
Parameters:
- dialect: Database dialect (postgres, mysql, sqlite)
Returns:
- []plugins.Migration: Sorted list of migrations (oldest first)
- error: If migration files cannot be read or parsed
func GetSchemaRequirements ¶
func GetSchemaRequirements(dialect plugins.Dialect) []plugins.SchemaRequirement
GetSchemaRequirements returns schema validation requirements for the admin plugin.
This function defines structural requirements that must be satisfied for the plugin to function correctly. The Init() method validates these requirements at startup.
Validation Checks:
- Column existence: role, banned, ban_reason, ban_expiry, ban_counter in 'user' table
- Column properties: Data types, nullability (not fully implemented yet)
These checks help detect schema drift, incomplete migrations, or manual schema changes that could break admin functionality.
Parameters:
- dialect: Database dialect (postgres, mysql)
Returns:
- []plugins.SchemaRequirement: List of validation requirements
Types ¶
type Plugin ¶
type Plugin struct {
// contains filtered or unexported fields
}
Plugin provides role-based access control and administrative user management.
This plugin integrates with the core authentication system to provide:
- Plugin role verification via middleware
- User account management (enable/disable/delete)
- Ban management with expiry dates and reasons
- Platform statistics and analytics
The plugin implements plugins.UserEnricher to automatically add role information to authenticated users, making it available in API responses.
func New ¶
func New(store admintypes.Store, dialect ...plugins.Dialect) *Plugin
New creates a new Admin plugin instance.
Parameters:
- store: AdminStore implementation for database operations (can be nil, will use DefaultAdminStore)
- dialect: Optional database dialect (defaults to PostgreSQL)
Returns:
- *Admin: Configured admin plugin ready for initialization
Example:
admin := admin.New(nil, plugins.DialectPostgres) aegis.RegisterPlugin(admin)
func (*Plugin) AssignRole ¶
AssignRole assigns a role to a user programmatically.
func (*Plugin) DeleteUser ¶
DeleteUser permanently deletes a user account programmatically.
func (*Plugin) Dependencies ¶
func (a *Plugin) Dependencies() []plugins.Dependency
Dependencies returns the plugin dependencies
func (*Plugin) Description ¶
Description returns a human-readable description for logging and diagnostics.
func (*Plugin) DisableUser ¶
DisableUser disables a user account programmatically.
func (*Plugin) EnableUser ¶
EnableUser re-enables a user account programmatically.
func (*Plugin) EnrichUser ¶
EnrichUser implements plugins.UserEnricher to add admin-specific fields to user responses.
This method is called automatically by the authentication system after user lookup. It adds the user's role to the EnrichedUser, making it available in API responses without requiring separate queries.
Fields Added:
- "role" (string): User's role (e.g., "admin", empty if no role)
The enriched role is accessible via:
- In API responses: {"user": {"id": "...", "role": "admin", ...}}
- In middleware: plugins.GetUserExtensionString(ctx, ExtKeyRole)
- In handlers: enrichedUser.GetString("role")
Parameters:
- ctx: Request context
- user: EnrichedUser to populate with admin data
Returns:
- error: Always nil (role lookup failure is not an error)
func (*Plugin) EnrichUserMiddleware ¶
EnrichUserMiddleware fetches the user's role and adds it to the EnrichedUser.
This middleware should be used after RequireAuthMiddleware to add admin-specific data to the user context. The enriched data is automatically included in API responses.
Enrichment Process:
- Retrieve authenticated user from context
- Fetch user's role from database
- Add role to EnrichedUser via plugins.ExtendUser
- Role becomes available as {"role": "admin"} in JSON responses
Usage:
router.Use(auth.RequireAuthMiddleware()) router.Use(admin.EnrichUserMiddleware())
The role is then accessible via:
- core.GetUserExtensionString(ctx, "role")
- JSON responses: {"user": {"id": "...", "role": "admin", ...}}
func (*Plugin) GetAdminUser ¶
GetAdminUser retrieves a user with admin-specific information.
func (*Plugin) GetMigrations ¶
GetMigrations returns the plugin migrations
func (*Plugin) GetStats ¶
func (a *Plugin) GetStats(ctx context.Context) (admintypes.StatsResponse, error)
GetStats returns platform statistics programmatically.
func (*Plugin) GetUser ¶
GetUser retrieves detailed information for a specific user programmatically.
func (*Plugin) GetUserRaw ¶
GetUserRaw retrieves detailed information for a specific user as raw map data programmatically.
func (*Plugin) GetUserRole ¶
GetUserRole retrieves the role of a user programmatically.
func (*Plugin) Init ¶
Init initializes the admin plugin and validates database schema.
Initialization Steps:
- Create DefaultAdminStore if custom store not provided
- Store session service reference for authentication middleware
- Build schema validation requirements (table + column checks)
- Validate admin schema extensions exist in database
Schema Validation: Checks for required columns in 'user' table:
- role: VARCHAR for role assignment
- banned, ban_reason, ban_expiry, ban_counter: Ban management fields
Parameters:
- ctx: Context for database operations
- aegis: Main Aegis instance providing DB access and services
Returns:
- error: If schema validation fails or initialization errors occur
func (*Plugin) ListUsersRaw ¶
ListUsersRaw lists all users as raw map data programmatically.
func (*Plugin) MountRoutes ¶
MountRoutes registers administrative management endpoints.
func (*Plugin) ProvidesAuthMethods ¶
ProvidesAuthMethods returns the provided auth methods
func (*Plugin) RemoveRole ¶
RemoveRole removes a role from a user programmatically.
func (*Plugin) RequireAdminMiddleware ¶
RequireAdminMiddleware ensures the user has the 'admin' role.
This middleware enforces admin-only access to protected routes. It checks for the admin role in two ways:
- First checks EnrichedUser context (if already enriched) - fast path
- Falls back to database lookup if not enriched - slow path
Authentication Flow:
- Retrieve authenticated user from context (via RequireAuthMiddleware)
- Check if role is already in EnrichedUser ("role" extension)
- If not found, fetch role from database
- Verify role is "admin"
- Enrich user context for subsequent handlers
Usage:
adminRouter := router.NewGroup("/admin")
adminRouter.Use(auth.RequireAuthMiddleware())
adminRouter.Use(admin.RequireAdminMiddleware())
Response Codes:
- 401 Unauthorized: User not authenticated
- 403 Forbidden: User authenticated but not admin
func (*Plugin) RequireRoleMiddleware ¶
RequireRoleMiddleware ensures the user has a specific role.
This is a generalized version of RequireAdminMiddleware for custom role requirements. It follows the same enrichment pattern (check context first, then database).
Usage:
// Require moderator role
router.Use(admin.RequireRoleMiddleware("moderator"))
Parameters:
- requiredRole: Role string to check (e.g., "admin", "moderator", "editor")
Response Codes:
- 401 Unauthorized: User not authenticated
- 403 Forbidden: User authenticated but lacks required role
func (*Plugin) RequiresTables ¶
RequiresTables returns the core tables this plugin reads from.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package defaultstore implements the SQL-backed default store for the admin plugin.
|
Package defaultstore implements the SQL-backed default store for the admin plugin. |
|
internal
|
|
|
Package types defines the domain models and request/response types used by the admin plugin.
|
Package types defines the domain models and request/response types used by the admin plugin. |