c77_rbac/USAGE-P3.md
2025-05-23 23:29:45 -05:00

4.6 KiB

c77_rbac Usage Guide - Part 3: Framework Integration

This is Part 3 of the comprehensive c77_rbac usage guide, covering detailed integration with popular web frameworks.

Complete Guide Structure:

  • Part 1: Core Concepts and Basic Usage
  • Part 2: Advanced Usage Scenarios
  • Part 3: Framework Integration (this document)
  • Part 4: Real-World Examples and Performance Optimization
  • Part 5: Security Best Practices and Troubleshooting

Table of Contents

  1. Laravel Integration
  2. Django Integration
  3. Ruby on Rails Integration
  4. Node.js Integration

Laravel Integration

Complete Laravel Setup

1. Service Provider

<?php
// app/Providers/RbacServiceProvider.php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Gate;
use App\Services\RbacService;

class RbacServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton(RbacService::class);
    }

    public function boot()
    {
        // Register middleware
        $this->app['router']->aliasMiddleware('rbac.context', 
            \App\Http\Middleware\SetRbacContext::class);
        $this->app['router']->aliasMiddleware('rbac.require', 
            \App\Http\Middleware\RequirePermission::class);

        // Integrate with Laravel Gates
        Gate::before(function ($user, $ability) {
            // Check RBAC format: 'feature:scope_type/scope_id'
            if (strpos($ability, ':') !== false) {
                [$feature, $scope] = explode(':', $ability, 2);
                if (strpos($scope, '/') !== false) {
                    [$scopeType, $scopeId] = explode('/', $scope, 2);
                    return app(RbacService::class)->can($feature, $scopeType, $scopeId);
                }
            }
            
            // Default to global scope
            return app(RbacService::class)->can($ability, 'global', 'all');
        });

        // Register Artisan commands
        if ($this->app->runningInConsole()) {
            $this->commands([
                \App\Console\Commands\RbacAssignRole::class,
                \App\Console\Commands\RbacSyncAdmin::class,
                \App\Console\Commands\RbacListPermissions::class,
            ]);
        }
    }
}

2. RBAC Service

<?php
// app/Services/RbacService.php

namespace App\Services;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

class RbacService
{
    /**
     * Check if current user has access to a feature
     */
    public function can(string $feature, string $scopeType = 'global', string $scopeId = 'all'): bool
    {
        if (!Auth::check()) {
            return false;
        }
        
        $userId = Auth::id();
        $cacheKey = "rbac:can:{$userId}:{$feature}:{$scopeType}:{$scopeId}";
        
        return Cache::remember($cacheKey, 300, function () use ($feature, $userId, $scopeType, $scopeId) {
            try {
                $result = DB::selectOne(
                    'SELECT public.c77_rbac_can_access(?, ?, ?, ?) AS allowed',
                    [$feature, (string)$userId, $scopeType, $scopeId]
                );
                
                return $result->allowed ?? false;
            } catch (\Exception $e) {
                Log::error('RBAC permission check failed', [
                    'feature' => $feature,
                    'user_id' => $userId,
                    'scope_type' => $scopeType,
                    'scope_id' => $scopeId,
                    'error' => $e->getMessage()
                ]);
                return false;
            }
        });
    }
    
    /**
     * Assign role to user
     */
    public function assignRole(int $userId, string $role, string $scopeType = 'global', string $scopeId = 'all'): bool
    {
        try {
            DB::statement(
                'SELECT public.c77_rbac_assign_subject(?, ?, ?, ?)',
                [(string)$userId, $role, $scopeType, $scopeId]
            );
            
            // Clear user's permission cache
            $this->clearUserCache($userId);
            
            Log::info('Role assigned', [
                'user_id' => $userId,
                'role' => $role,
                'scope_type' => $scopeType,
                'scope_id' => $scopeId
            ]);
            
            return true;
        } catch (\Exception $e) {
            Log::error('Failed to assign role', [
                'user_id' => $userId,
                'role' => $role,