Skip to main content
The admin dashboard provides administrative users with access to management features and system controls. Access is restricted to users with the Admin role.

Route Protection

The admin dashboard uses the AdminUser request guard to ensure only administrators can access it:
src/web/mod.rs
#[get("/admin")]
pub fn admin(_user: AdminUser<'_>) -> Template {
    Template::render("admin", &{})
}
The AdminUser guard validates:
  1. A valid JWT token exists in the cookie
  2. The token is not expired
  3. The user has Roles::Admin or higher

Admin Role Assignment

Admins are assigned during the Discord OAuth callback:
src/web/api/mod.rs
let user = User::new(user_info.id.parse().unwrap());

// Check for specific admin user ID
let token = if user_info.id == "242385294123335690" {
    user.create_token(Roles::Admin)
} else {
    user.create_token(Roles::User)
};
Currently, admin status is hard-coded by Discord user ID. In production, this should be managed through a database or configuration file.

Access Control Flow

AdminUser Request Guard

The guard implementation provides automatic route protection:
src/web/auth.rs
#[rocket::async_trait]
impl<'r> FromRequest<'r> for AdminUser<'r> {
    type Error = ApiKeyError;

    async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error> {
        fn is_valid(key: &str) -> bool {
            let is_valid = User::verify_token(key);
            let has_role = User::user_has_role(key, Roles::Admin);
            
            println!("Is valid: {}", is_valid);
            is_valid && has_role
        }

        let key = req.cookies().get("token").map(|cookie| cookie.value());
        match key {
            None => Outcome::Error((Status::Unauthorized, ApiKeyError::Missing)),
            Some(key) if is_valid(key) => Outcome::Success(AdminUser(key)),
            Some(_) => Outcome::Error((Status::Unauthorized, ApiKeyError::Invalid)),
        }
    }
}

Validation Steps

  1. Extract token: Get token from token cookie
  2. Verify signature: Validate JWT signature with SECRET_KEY
  3. Check expiration: Ensure token hasn’t expired (24h lifetime)
  4. Verify role: Confirm user has Admin role (role >= 3)

Error Handling

When authorization fails, a custom 401 page is shown:
src/web/mod.rs
#[catch(401)]
pub fn unauthorized(_req: &Request) -> Template {
    Template::render("401", &{})
}
This provides a user-friendly message explaining why access was denied.

Home Page Admin Detection

The home page detects admin status to show appropriate UI:
src/web/mod.rs
#[derive(serde::Serialize)]
struct HomeContext {
    is_logged_in: bool,
    is_admin: bool,
}

#[get("/")]
pub async fn index(jar: &CookieJar<'_>) -> Template {
    let is_logged_in = is_logged_in(jar).await;
    let is_admin = User::user_has_role(
        jar.get("token").map(|cookie| cookie.value()).unwrap_or_default(), 
        Roles::Admin
    );
    
    let ctx = HomeContext {
        is_logged_in,
        is_admin,
    };
    
    Template::render("wip", &ctx)
}
This allows the template to conditionally show admin-only features.

Admin Features

The admin dashboard template (admin.html.hbs) likely includes:
  • User management
  • Verification status overview
  • System configuration
  • Analytics and metrics
  • Moderation tools
  • Database management
The actual features rendered depend on the Handlebars template implementation in templates/admin.html.hbs.

Role Hierarchy

The role system uses numeric values for hierarchical checks:
src/web/auth.rs
pub enum Roles {
    Unprivileged,  // 0
    User,          // 1
    Moderator,     // 2
    Admin,         // 3
}
Role checking uses >= comparison, so:
  • Admin (3) can access User (1), Moderator (2), and Admin (3) routes
  • Moderator (2) can access User (1) and Moderator (2) routes
  • User (1) can only access User (1) routes

Testing Admin Access

The application generates a test admin token on startup:
src/main.rs
let example_user = User::new(1234567890).create_token(web::auth::Roles::Admin);
println!("Example admin token: {}", example_user);
This token can be set in cookies for testing admin features.

Security Best Practices

Token Security

  • Tokens expire after 24 hours
  • HTTP-only cookies prevent XSS
  • Secure flag requires HTTPS
  • HMAC-SHA256 signing

Role Management

  • Admin IDs should be in database
  • Audit admin actions
  • Use principle of least privilege
  • Regular token rotation

Future Enhancements

1

Database-backed roles

Move admin user IDs from code to database for easier management
2

Granular permissions

Implement specific permissions beyond role levels
3

Audit logging

Log all admin actions for security and compliance
4

Multi-factor authentication

Add MFA requirement for admin access

Authentication

Learn about the JWT authentication system

User Management

Managing regular users and verification

Build docs developers (and LLMs) love