Skip to content

Instantly share code, notes, and snippets.

@alexivashchenko
Last active June 27, 2025 07:40
Show Gist options
  • Save alexivashchenko/344fc05a3c8d30629b04c17f7a5a3759 to your computer and use it in GitHub Desktop.
Save alexivashchenko/344fc05a3c8d30629b04c17f7a5a3759 to your computer and use it in GitHub Desktop.
Laravel command to create md table with all User Roles
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use ReflectionClass;
use ReflectionMethod;
class GenerateUserAccessMatrix extends Command
{
protected $signature = 'generate:access-matrix';
protected $description = 'Generate user access matrix from policy files';
public function handle()
{
$policiesPath = app_path('Policies');
$policyFiles = File::glob($policiesPath . '/*.php');
$roles = $this->extractRoles();
$accessMatrix = [];
foreach ($policyFiles as $file) {
$className = 'App\\Policies\\' . basename($file, '.php');
if (! class_exists($className)) {
continue;
}
$reflection = new ReflectionClass($className);
$methods = $reflection->getMethods(ReflectionMethod::IS_PUBLIC);
$resource = str_replace('Policy', '', basename($file, '.php'));
foreach ($methods as $method) {
if (in_array($method->getName(), ['before', '__construct'])) {
continue;
}
$accessMatrix[$resource][$method->getName()] = $this->analyzeMethod($className, $method->getName());
}
}
$markdown = $this->generateMarkdown($roles, $accessMatrix);
File::put(base_path('USER_ACCESS_MATRIX-['.date('Y-m-d-H-i-s').'].md'), $markdown);
$this->info('User access matrix generated successfully!');
}
private function extractRoles()
{
$enumPath = app_path('Enumerations/User/RolesEnum.php');
if (! File::exists($enumPath)) {
return ['Administrator', 'AccountManager'];
}
$content = File::get($enumPath);
preg_match_all('/case\s+(\w+)\s*=/', $content, $matches);
return $matches[1] ?? ['Administrator', 'AccountManager'];
}
private function analyzeMethod($className, $methodName)
{
$content = File::get(str_replace('\\', '/', app_path()) . '/Policies/' . class_basename($className) . '.php');
$pattern = "/function\s+{$methodName}\s*\([^}]+\}/s";
preg_match($pattern, $content, $matches);
if (empty($matches)) {
return [];
}
$methodContent = $matches[0];
$access = [];
// Check for Administrator access via before method
if (strpos($content, 'RolesEnum::Administrator') !== false && strpos($content, 'before(') !== false) {
$access['Administrator'] = '✅';
}
// Check for AccountManager access
if (strpos($methodContent, 'RolesEnum::AccountManager') !== false) {
$access['AccountManager'] = '✅';
} else {
$access['AccountManager'] = '❌';
}
// Check for ownership conditions
if (strpos($methodContent, 'accountManagerIs') !== false) {
$access['notes'] = 'Account Manager: Own records only';
}
return $access;
}
private function generateMarkdown($roles, $accessMatrix)
{
$markdown = "# User Access Matrix\n\n";
$markdown .= "Based on policies in `app/Policies` folder\n\n";
$markdown .= "## User Roles\n";
foreach ($roles as $role) {
$markdown .= "- **{$role}**: " . ($role === 'Administrator' ? 'Full access to all resources' : 'Limited access to specific resources') . "\n";
}
$markdown .= "\n## Access Matrix\n\n";
$markdown .= "| Resource | Action | Administrator | Account Manager | Notes |\n";
$markdown .= "|----------|--------|---------------|-----------------|-------|\n";
foreach ($accessMatrix as $resource => $methods) {
$first = true;
foreach ($methods as $method => $access) {
$resourceName = $first ? "**{$resource}**" : "";
$admin = $access['Administrator'] ?? '✅';
$manager = $access['AccountManager'] ?? '❌';
$notes = $access['notes'] ?? '';
$markdown .= "| {$resourceName} | " . ucfirst($method) . " | {$admin} | {$manager} | {$notes} |\n";
$first = false;
}
}
$markdown .= "\n## Key Notes\n";
$markdown .= "- **Administrator** role has universal access via `before()` method in all policies\n";
$markdown .= "- **Account Manager** has ownership-based access for certain resources\n";
$markdown .= "- Most policies deny access by default and explicitly grant permissions\n";
return $markdown;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment