mini\Authorizer\Authorization class

Documentation

Authorization service

Manages ability registration and authorization queries via Handler dispatch. Handlers are registered per-class and resolved by type specificity.

Execution Order

For can(Ability::Delete, $post) where Post extends Model implements TenantScoped:

  1. Guards (deny-only, type-specific): Post guards → TenantScoped guards → Model guards If any guard returns false → deny immediately

  2. Handlers (allow/deny, type-specific): Post → TenantScoped → Model → fallback

  3. Default: allow (if no handler responds)

Guards (Cross-Cutting Security)

// Guards run FIRST and can only deny or pass
$auth->guard(TenantScoped::class)->listen(function(AuthorizationQuery $q): ?bool {
    $entity = $q->instance();
    if ($entity && $entity->tenant_id !== auth()->getClaim('tenant_id')) {
        return false;  // Deny - wrong tenant
    }
    return null;  // Pass - continue checking
});

Handlers

// Handlers run after guards pass
$auth->for(User::class)->listen(function(AuthorizationQuery $q): ?bool {
    return match ($q->ability) {
        Ability::List => auth()->isAuthenticated(),
        Ability::Create => auth()->hasRole('admin'),
        Ability::Read => true,
        Ability::Update, Ability::Delete =>
            $q->instance()?->id === auth()->getUserId() || auth()->hasRole('admin'),
        default => null,
    };
});

Properties (4)

private array $guards
private array $handlers
public mini\Hooks\Handler $fallback
private array $customAbilities

Methods (6)

Documentation missing

Get or create guard for a specific resource

Get or create handler for a specific resource

Check if the current user can perform an ability on an entity

Register a custom string ability

Walk class hierarchy in specificity order

Source

src/Authorizer/Authorization.php:55-209