revelation-user 0.1.1

User domain crate for Revelation ecosystem
Documentation


Table of Contents


Features

  • Multiple Auth Methods — Telegram, Email, Phone authentication out of the box
  • JWT Claims — Type-safe claims with expiration and role checking
  • RBAC Permissions — Fine-grained permission system with bitflags
  • Framework Extractors — Zero-boilerplate auth for Axum and Actix-web
  • Projections — Type-safe views that prevent accidental data leaks
  • Extensibleextend_user! macro for application-specific fields
  • Entity-Derive Integration — Auto-generated DTOs via entity-derive

Installation

[dependencies]
revelation-user = { version = "0.1", features = ["axum"] }

Available Features

Feature Description
postgres PostgreSQL support via sqlx
api OpenAPI schema generation via utoipa
validate Validation derives via validator
axum Axum framework extractors
actix Actix-web framework extractors

Note: axum and actix features are mutually exclusive.

Quick Start

use revelation_user::{RUser, Claims, RUserRole};

// Create user from authentication
let user = RUser::from_telegram(123456789);
let user = RUser::from_email("user@example.com");
let user = RUser::from_phone("+14155551234");

// Create JWT claims
let exp = (chrono::Utc::now().timestamp() + 3600) as usize;
let claims = Claims::new(user.id, RUserRole::User, exp);

// Check permissions
assert!(!claims.is_expired());
assert!(!claims.is_admin());

Core Types

Entity

Type Description
RUser Core user entity with all fields
Claims JWT claims for authentication

Projections

Type Description
RUserPublic Safe for API responses (excludes sensitive data)
RUserAuth For JWT/session context (includes role)

DTOs

Type Description
CreateUserRequest Create new user
UpdateProfileRequest Update user profile
BindTelegram Bind Telegram account
BindEmail Bind email address
BindPhone Bind phone number

Framework Integration

Axum

use axum::{Router, Json, routing::get};
use revelation_user::{Claims, RUserPublic};

async fn me(claims: Claims) -> Json<RUserPublic> {
    // Claims extracted from JWT cookie or Authorization header
    todo!()
}

let app = Router::new().route("/me", get(me));

Actix-web

use actix_web::{web, HttpResponse};
use revelation_user::Claims;

async fn me(claims: Claims) -> HttpResponse {
    HttpResponse::Ok().json(claims.user_id())
}

Extending Users

Use the extend_user! macro for application-specific fields:

use revelation_user::{extend_user, RUser};
use uuid::Uuid;

extend_user! {
    /// Corporate user with company-specific fields.
    pub struct CorpUser {
        pub company_id: Uuid,
        pub department: String,
    }
}

let user = CorpUser::from_telegram(123456789)
    .name("John")
    .then()
    .company_id(Uuid::now_v7())
    .department("Engineering")
    .build();

// Access RUser fields via Deref
assert!(user.telegram_id.is_some());

RBAC Permissions

Fine-grained permission system:

use revelation_user::{Permissions, RUserRole, Role};

// Check role permissions
let role = RUserRole::Premium;
assert!(role.can(Permissions::READ));
assert!(role.can(Permissions::WRITE));

// Admin has all permissions
let admin = RUserRole::Admin;
assert!(admin.can(Permissions::all()));

// Custom permission checks in Claims
let claims = Claims::new(uuid::Uuid::now_v7(), RUserRole::User, exp);
assert!(claims.can(Permissions::READ));

Permission Flags

Permission Description
READ Read access
WRITE Write access
DELETE Delete access
ADMIN Administrative access

Code Coverage

We maintain high test coverage to ensure reliability. Below are visual representations of our codebase coverage:

Sunburst

The inner circle represents the entire project. Moving outward: folders, then individual files. Size = number of statements, color = coverage percentage.

Grid

Each block represents a file. Size = number of statements, color = coverage level (green = high, red = low).

Icicle

Hierarchical view: top = entire project, descending through folders to individual files. Size and color represent statements and coverage.

License

MIT