lmrc-auth

Crates.iolmrc-auth
lib.rslmrc-auth
version0.3.16
created_at2025-12-02 15:35:09.852883+00
updated_at2025-12-11 13:28:26.068532+00
descriptionAuthentication framework for LMRC Stack applications
homepage
repositoryhttps://gitlab.com/lemarco/lmrc-stack
max_upload_size
id1962069
size110,471
Le Marc (lemarco)

documentation

README

lmrc-auth

Authentication framework for LMRC Stack applications.

Provides flexible, trait-based authentication with multiple providers, session management, and ready-to-use Axum handlers.

Features

  • Flexible Authentication: Trait-based design supports database, LDAP, OAuth, and custom providers
  • Session Management: Secure session creation, validation, and destruction
  • Password Hashing: Built-in bcrypt support for secure password storage
  • Database Integration: SeaORM-based provider for PostgreSQL authentication
  • Axum Ready: Pre-built handlers and middleware for Axum web framework
  • Type-Safe: Leverages Rust's type system for security

Installation

[dependencies]
lmrc-auth = "0.3.11"

Feature Flags

  • bcrypt (default) - Password hashing with bcrypt
  • database - Database-backed authentication provider with SeaORM

To enable all features:

[dependencies]
lmrc-auth = { version = "0.3.11", features = ["database"] }

Quick Start

1. Database Setup

Create the required tables:

CREATE TABLE users (
    id BIGSERIAL PRIMARY KEY,
    email VARCHAR(255) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    role VARCHAR(50) NOT NULL DEFAULT 'user',
    is_active BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMP NOT NULL DEFAULT NOW()
);

CREATE TABLE sessions (
    token VARCHAR(255) PRIMARY KEY,
    user_id BIGINT NOT NULL REFERENCES users(id),
    expires_at TIMESTAMP NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT NOW()
);

2. Configure Authentication

use lmrc_auth::{DatabaseAuthProvider, AuthConfig};
use sea_orm::Database;
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Connect to database
    let db = Database::connect("postgres://user:pass@localhost/mydb").await?;

    // Create auth provider
    let auth_provider = Arc::new(
        DatabaseAuthProvider::new(
            db,
            "users",      // users table name
            "sessions",   // sessions table name
            AuthConfig::default()
        )
    );

    // Use in your Axum application
    Ok(())
}

3. Add Authentication Routes

use axum::{Router, routing::post};
use lmrc_auth::handlers::{login_handler, logout_handler, me_handler};

let auth_routes = Router::new()
    .route("/auth/login", post(login_handler))
    .route("/auth/logout", post(logout_handler))
    .route("/auth/me", get(me_handler))
    .with_state((auth_provider.clone(), auth_config));

4. Protect Routes with Middleware

use axum::middleware;
use lmrc_auth::middleware::auth_middleware;

let protected_routes = Router::new()
    .route("/admin/users", get(list_users))
    .route("/admin/settings", get(get_settings))
    .layer(middleware::from_fn_with_state(
        (auth_provider, auth_config),
        auth_middleware
    ));

Core Concepts

AuthProvider Trait

The AuthProvider trait defines the authentication interface:

#[async_trait]
pub trait AuthProvider: Send + Sync {
    async fn authenticate(&self, email: &str, password: &str) -> AuthResult<AuthUser>;
    async fn create_session(&self, user_id: i64) -> AuthResult<Session>;
    async fn validate_session(&self, token: &str) -> AuthResult<Option<AuthUser>>;
    async fn destroy_session(&self, token: &str) -> AuthResult<()>;
    async fn get_user(&self, user_id: i64) -> AuthResult<Option<AuthUser>>;
}

Custom Providers

Implement custom authentication strategies:

use lmrc_auth::{AuthProvider, AuthUser, Session, AuthResult};
use async_trait::async_trait;

struct LdapAuthProvider {
    ldap_url: String,
}

#[async_trait]
impl AuthProvider for LdapAuthProvider {
    async fn authenticate(&self, email: &str, password: &str) -> AuthResult<AuthUser> {
        // Your LDAP authentication logic
        todo!()
    }

    // Implement other methods...
}

Data Models

AuthUser

pub struct AuthUser {
    pub id: i64,
    pub email: String,
    pub role: String,
}

Session

pub struct Session {
    pub token: String,
    pub user_id: i64,
    pub expires_at: chrono::NaiveDateTime,
}

Credentials

pub struct Credentials {
    pub email: String,
    pub password: String,
}

Configuration

AuthConfig

pub struct AuthConfig {
    /// Session expiration in hours (default: 168 / 7 days)
    pub session_expiration_hours: i64,

    /// Cookie name for session token (default: "session_token")
    pub cookie_name: String,

    /// Cookie domain (default: None)
    pub cookie_domain: Option<String>,

    /// Cookie secure flag - HTTPS only (default: true)
    pub cookie_secure: bool,
}

Custom Configuration

let config = AuthConfig {
    session_expiration_hours: 24, // 1 day
    cookie_name: "my_session".to_string(),
    cookie_domain: Some(".example.com".to_string()),
    cookie_secure: true,
};

Examples

Login Handler

use axum::{Json, extract::State};
use lmrc_auth::{handlers::login_handler, Credentials, LoginResponse};

// POST /auth/login
// Body: {"email": "user@example.com", "password": "secret"}
// Returns: {"token": "...", "user": {...}, "expires_at": "..."}

Logout Handler

// POST /auth/logout
// Cookie: session_token=...
// Returns: 204 No Content

Get Current User

// GET /auth/me
// Cookie: session_token=...
// Returns: {"id": 1, "email": "user@example.com", "role": "admin"}

Testing

cargo test -p lmrc-auth --all-features

Security Considerations

  1. Password Hashing: Uses bcrypt with appropriate cost factor
  2. Session Tokens: Generated using UUID v4 (cryptographically random)
  3. Session Expiration: Configurable expiration with automatic cleanup
  4. Secure Cookies: HTTPS-only cookies by default
  5. SQL Injection: Uses parameterized queries via SeaORM

Integration with lmrc-http-common

Works seamlessly with lmrc-http-common for error handling, middleware, and HTTP utilities.

Contributing

This library is part of the LMRC Stack monorepo.

License

Dual licensed under MIT OR Apache-2.0 (your choice).

Commit count: 0

cargo fmt