rs-tenant 0.4.0

Multi-tenant RBAC authorization engine for Rust
Documentation
use async_trait::async_trait;
use futures::executor::block_on;
use rs_tenant::{
    AuthSubject, AuthorizationSource, EngineBuilder, GrantScope, MembershipStatus, Permission,
    RoleAssignment, RoleId, SourceError, TenantAccessRequest, TenantId, TenantStatus,
};

#[derive(Clone)]
struct DbAuthorizationSource;

#[async_trait]
impl AuthorizationSource for DbAuthorizationSource {
    async fn tenant_status(
        &self,
        _tenant: &TenantId,
    ) -> std::result::Result<TenantStatus, SourceError> {
        Ok(TenantStatus::Active)
    }

    async fn membership_status(
        &self,
        _subject: &AuthSubject,
    ) -> std::result::Result<MembershipStatus, SourceError> {
        Ok(MembershipStatus::Active)
    }

    async fn role_assignments(
        &self,
        _subject: &AuthSubject,
    ) -> std::result::Result<Vec<RoleAssignment>, SourceError> {
        let role = RoleId::parse("reader").map_err(|err| Box::new(err) as SourceError)?;
        Ok(vec![RoleAssignment::new(role, GrantScope::tenant())])
    }

    async fn role_permissions(
        &self,
        _tenant: &TenantId,
        _role: &RoleId,
    ) -> std::result::Result<Vec<Permission>, SourceError> {
        let permission =
            Permission::parse("invoice:read").map_err(|err| Box::new(err) as SourceError)?;
        Ok(vec![permission])
    }

    async fn parent_roles(
        &self,
        _tenant: &TenantId,
        _role: &RoleId,
    ) -> std::result::Result<Vec<RoleId>, SourceError> {
        Ok(Vec::new())
    }
}

fn main() -> rs_tenant::Result<()> {
    block_on(async {
        let engine = EngineBuilder::new(DbAuthorizationSource).build();
        let _decision = engine
            .can_tenant(TenantAccessRequest {
                subject: AuthSubject::new(
                    TenantId::parse("tenant_demo")?,
                    rs_tenant::PrincipalId::parse("user_demo")?,
                ),
                permission: Permission::parse("invoice:read")?,
            })
            .await?;
        Ok(())
    })
}