admin

package
v1.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 30, 2026 License: MIT Imports: 17 Imported by: 0

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

View Source
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.

View Source
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

func GetMigrations(dialect plugins.Dialect) ([]plugins.Migration, error)

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

func (a *Plugin) AssignRole(ctx context.Context, userID string, role string) error

AssignRole assigns a role to a user programmatically.

func (*Plugin) BanUser

func (a *Plugin) BanUser(ctx context.Context, userID, reason string, expiresAt *time.Time) error

BanUser bans a user programmatically.

func (*Plugin) DeleteUser

func (a *Plugin) DeleteUser(ctx context.Context, userID string) error

DeleteUser permanently deletes a user account programmatically.

func (*Plugin) Dependencies

func (a *Plugin) Dependencies() []plugins.Dependency

Dependencies returns the plugin dependencies

func (*Plugin) Description

func (a *Plugin) Description() string

Description returns a human-readable description for logging and diagnostics.

func (*Plugin) DisableUser

func (a *Plugin) DisableUser(ctx context.Context, userID string) error

DisableUser disables a user account programmatically.

func (*Plugin) EnableUser

func (a *Plugin) EnableUser(ctx context.Context, userID string) error

EnableUser re-enables a user account programmatically.

func (*Plugin) EnrichUser

func (a *Plugin) EnrichUser(ctx context.Context, user *core.EnrichedUser) error

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

func (a *Plugin) EnrichUserMiddleware() func(http.Handler) http.Handler

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:

  1. Retrieve authenticated user from context
  2. Fetch user's role from database
  3. Add role to EnrichedUser via plugins.ExtendUser
  4. 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

func (a *Plugin) GetAdminUser(ctx context.Context, userID string) (admintypes.User, error)

GetAdminUser retrieves a user with admin-specific information.

func (*Plugin) GetMigrations

func (a *Plugin) GetMigrations() []plugins.Migration

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

func (a *Plugin) GetUser(ctx context.Context, userID string) (admintypes.User, error)

GetUser retrieves detailed information for a specific user programmatically.

func (*Plugin) GetUserRaw

func (a *Plugin) GetUserRaw(ctx context.Context, userID string) (map[string]any, error)

GetUserRaw retrieves detailed information for a specific user as raw map data programmatically.

func (*Plugin) GetUserRole

func (a *Plugin) GetUserRole(ctx context.Context, userID string) (string, error)

GetUserRole retrieves the role of a user programmatically.

func (*Plugin) Init

func (a *Plugin) Init(ctx context.Context, aegis plugins.Aegis) error

Init initializes the admin plugin and validates database schema.

Initialization Steps:

  1. Create DefaultAdminStore if custom store not provided
  2. Store session service reference for authentication middleware
  3. Build schema validation requirements (table + column checks)
  4. 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) ListUsers

func (a *Plugin) ListUsers(ctx context.Context, offset, limit int) ([]admintypes.User, error)

ListUsers lists all users programmatically.

func (*Plugin) ListUsersRaw

func (a *Plugin) ListUsersRaw(ctx context.Context, offset, limit int) ([]map[string]any, error)

ListUsersRaw lists all users as raw map data programmatically.

func (*Plugin) MountRoutes

func (a *Plugin) MountRoutes(r router.Router, prefix string)

MountRoutes registers administrative management endpoints.

func (*Plugin) Name

func (a *Plugin) Name() string

Name returns the plugin identifier.

func (*Plugin) ProvidesAuthMethods

func (a *Plugin) ProvidesAuthMethods() []string

ProvidesAuthMethods returns the provided auth methods

func (*Plugin) RemoveRole

func (a *Plugin) RemoveRole(ctx context.Context, userID string, role string) error

RemoveRole removes a role from a user programmatically.

func (*Plugin) RequireAdminMiddleware

func (a *Plugin) RequireAdminMiddleware() func(http.Handler) http.Handler

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:

  1. First checks EnrichedUser context (if already enriched) - fast path
  2. Falls back to database lookup if not enriched - slow path

Authentication Flow:

  1. Retrieve authenticated user from context (via RequireAuthMiddleware)
  2. Check if role is already in EnrichedUser ("role" extension)
  3. If not found, fetch role from database
  4. Verify role is "admin"
  5. 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

func (a *Plugin) RequireRoleMiddleware(requiredRole string) func(http.Handler) http.Handler

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

func (a *Plugin) RequiresTables() []string

RequiresTables returns the core tables this plugin reads from.

func (*Plugin) UnbanUser

func (a *Plugin) UnbanUser(ctx context.Context, userID string) error

UnbanUser removes the ban from a user account programmatically.

func (*Plugin) Version

func (a *Plugin) Version() string

Version returns the plugin version for compatibility tracking.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL