定制 glueful/aegis 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

glueful/aegis

Composer 安装命令:

composer require glueful/aegis

包简介

Aegis: Role-Based Access Control extension for Glueful

README 文档

README

Overview

Aegis provides a comprehensive, modern Role-Based Access Control (RBAC) system for your Glueful application. It implements hierarchical roles, direct user permissions, resource-level filters, and optional audit logging.

Features

  • Hierarchical roles: Create nested roles where child roles inherit ancestor permissions
  • Direct user permissions: Per-user grants that augment role permissions
  • Resource-level filters: Limit permissions to specific resources/types
  • Temporal permissions: Expiry on roles and direct grants
  • Scoped access: Multi-tenant friendly with scoping
  • Audit service: Structured audit helpers + optional check logging
  • Targeted caching: Catalog and non-temporal lookup caches via CacheStore
  • REST API: Full CRUD + assignment endpoints
  • Flexible config: Tunable caching, inheritance, and logging

Installation

Installation (Recommended)

Install via Composer

composer require glueful/aegis

# Rebuild the extensions cache after adding new packages
php glueful extensions:cache

Composer discovers packages of type glueful-extension, but installing does not auto-enable them — the provider must be added to config/extensions.php's enabled allow-list. The CLI does that for you:

# Enable (adds the provider FQCN to config/extensions.php + recompiles the cache)
php glueful extensions:enable aegis

# Disable (removes it)
php glueful extensions:disable aegis

In production, manage the enabled list in config and run php glueful extensions:cache in your deploy step.

Run database migrations (if not auto-run by your workflow):

php glueful migrate:run

Local Development Installation

To develop the extension locally, register it as a Composer path repository in your app's composer.json, then require and enable it:

// composer.json
"repositories": [
    { "type": "path", "url": "extensions/aegis", "options": { "symlink": true } }
]
composer require glueful/aegis:@dev
php glueful extensions:enable aegis

Entries in config/extensions.php are plain string FQCNs (no ::class) — prefer extensions:enable over editing by hand.

Run the migrations to create the necessary database tables:

php glueful migrate run
  1. Generate API documentation (optional, if your tooling supports it):
php glueful generate:json doc
  1. Restart your web server to apply the changes.

Verify Installation

Check status and details:

php glueful extensions:list
php glueful extensions:info aegis
php glueful extensions:diagnose

Post-install checklist:

  • Run migrations (if not auto-run): php glueful migrate run
  • Hit an endpoint to verify: GET /rbac/roles
  • Rebuild cache after Composer operations: php glueful extensions:cache
  • Check logs for initialization messages or errors

Quick Start

Create a role, assign it to a user, and verify via the API. Replace placeholders before running:

  • API_BASE with your base URL (e.g., http://localhost:8000)
  • TOKEN with a valid bearer token
  • USER_UUID with an existing user's UUID
API_BASE=http://localhost:8000
TOKEN="<YOUR_BEARER_TOKEN>"
USER_UUID="<AN_EXISTING_USER_UUID>"

# 1) Create a role
create_resp=$(curl -s -X POST "$API_BASE/rbac/roles" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Editor",
    "slug": "editor",
    "description": "Can edit content"
  }')

# Extract role UUID (requires jq). If jq is unavailable, inspect $create_resp
ROLE_UUID=$(printf "%s" "$create_resp" | jq -r '.data.uuid')
echo "Created role UUID: $ROLE_UUID"

# 2) Assign the role to a user
curl -s -X POST "$API_BASE/rbac/roles/$ROLE_UUID/assign" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\n    \"user_uuid\": \"$USER_UUID\",\n    \"scope\": {\"tenant_id\": \"tenant_1\"}\n  }" | jq .

# 3a) Verify: list the user's roles
curl -s "$API_BASE/rbac/users/$USER_UUID/roles" \
  -H "Authorization: Bearer $TOKEN" | jq .

# 3b) Verify: explicit role check by slug
curl -s -X POST "$API_BASE/rbac/users/$USER_UUID/check-role" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "role_slug": "editor"
  }' | jq .

Quick Start (PHP)

Programmatic equivalent using the container and services:

<?php
use Glueful\Extensions\Aegis\Services\RoleService;
use Glueful\Extensions\Aegis\AegisPermissionProvider;

// Resolve services from the container
$roleService = container()->get(RoleService::class);
$provider = container()->get(AegisPermissionProvider::class);

$userUuid = '<AN_EXISTING_USER_UUID>';

// 1) Create a role
$role = $roleService->createRole([
    'name' => 'Editor',
    'slug' => 'editor',
    'description' => 'Can edit content',
]);

// 2) Assign the role to the user
$roleService->assignRoleToUser($userUuid, $role->getUuid(), [
    'scope' => ['tenant_id' => 'tenant_1'],
]);

// 3a) Verify via provider
$hasRole = $provider->hasRole($userUuid, 'editor');

// 3b) Or verify via RoleService helper
$hasRole2 = $roleService->userHasRole($userUuid, 'editor');

// Optional: check permissions using the permission manager
$permissionManager = container()->get('permission.manager');
$canEdit = $permissionManager->can($userUuid, 'posts.edit', 'post:123');

var_dump([
    'role_uuid' => $role->getUuid(),
    'has_editor_role' => $hasRole,
    'has_editor_role_via_service' => $hasRole2,
    'can_edit_post' => $canEdit,
]);

Database Schema

Aegis creates the following tables:

  • roles: Role definitions with hierarchy support
  • permissions: Permission definitions with categories and resource types
  • role_permissions: Role-to-permission mappings
  • user_roles: User role assignments with scope and expiry support
  • user_permissions: Direct user permission assignments
  • permission_audit: Reserved schema for database audit trails; the current audit service writes structured events to the rbac_audit log channel.

Configuration

config/rbac.php ships empty so the extension can run with framework defaults. Applications can override the following keys in their app config:

<?php
return [
    'roles' => [
        // Inherit permissions up the role hierarchy
        'inherit_permissions' => true,
        // Maximum depth for hierarchy resolution
        'max_hierarchy_depth' => 10,
    ],
    'permissions' => [
        // Distributed caching for user permissions
        'cache_enabled' => true,
        // TTL for user permissions (seconds)
        'cache_ttl' => 3600,
        'cache_prefix' => 'rbac:',
        // Enable role-permission inheritance
        'inheritance_enabled' => true,
    ],
    'logging' => [
        // When true, logs each permission check (verbose)
        'log_check_operations' => false,
    ],
];

Usage

Basic Permission Checking

use Glueful\Permissions\PermissionManager;

$permissionManager = container()->get('permission.manager');

// Check if user has permission
$canEdit = $permissionManager->can($userUuid, 'posts.edit', 'post:123');

// Check with additional context (e.g., tenant scope)
$canDelete = $permissionManager->can($userUuid, 'posts.delete', 'post:123', [
    'scope' => ['tenant_id' => 'tenant_1'],
]);

Role Management

use Glueful\Extensions\Aegis\Services\RoleService;

$roleService = container()->get(RoleService::class);

// Create a new role
$adminRole = $roleService->createRole([
    'name' => 'Administrator',
    'slug' => 'admin',
    'description' => 'System administrator with full access',
]);

// Create a child role
$moderatorRole = $roleService->createRole([
    'name' => 'Moderator',
    'slug' => 'moderator',
    'parent_uuid' => $adminRole->getUuid(),
    'description' => 'Content moderator',
]);

// Assign role to user
$roleService->assignRoleToUser($userUuid, $adminRole->getUuid(), [
    'expires_at' => '2024-12-31 23:59:59',
    'scope' => ['tenant_id' => 'tenant_1'],
]);

Permission Management

use Glueful\Extensions\Aegis\Services\PermissionAssignmentService;

$permissionService = container()->get(PermissionAssignmentService::class);

// Create a new permission
$permission = $permissionService->createPermission([
    'name' => 'Edit Posts',
    'slug' => 'posts.edit',
    'description' => 'Ability to edit blog posts',
    'category' => 'content',
    'resource_type' => 'posts',
]);

// Assign permission directly to user (adds to role permissions)
$permissionService->assignPermissionToUser(
    $userUuid,
    'posts.edit',
    'post:123', // Specific resource
    [
        'expires_at' => '2024-06-30 23:59:59',
        'constraints' => ['ip_range' => '192.168.1.0/24'],
    ]
);

// Batch assign permissions
$permissionService->batchAssignPermissions($userUuid, [
    ['permission' => 'posts.read', 'resource' => '*'],
    ['permission' => 'posts.edit', 'resource' => 'post:123'],
    ['permission' => 'comments.moderate', 'resource' => '*'],
]);

Direct user grants use exact resource matching. Wildcard resource filters are supported on role-permission grants; direct user grants are intended for precise per-user exceptions.

Using the RBAC Permission Provider

The Aegis provider is auto-registered with the framework’s permission manager. You can either use the manager (recommended) or get the provider directly:

use Glueful\Extensions\Aegis\AegisPermissionProvider;

// Recommended: use the permission manager for checks
$permissionManager = container()->get('permission.manager');
$can = $permissionManager->can($userUuid, 'posts.edit', 'post:123');

// Direct access to provider when needed
$rbacProvider = container()->get(AegisPermissionProvider::class);

// Assign a role
$rbacProvider->assignRole($userUuid, 'editor', [
    'scope' => ['tenant_id' => 'tenant_1'],
    'expires_at' => '2024-12-31 23:59:59',
]);

// Check if user has role
$hasRole = $rbacProvider->hasRole($userUuid, 'admin');

// Get user's effective permissions
$permissions = $rbacProvider->getUserPermissions($userUuid);

API Endpoints

All endpoints are prefixed with /rbac and require authentication. Highlights include:

Roles

  • GET /rbac/roles – List roles (with filters/pagination)
  • POST /rbac/roles – Create a role
  • GET /rbac/roles/{uuid} – Get role details
  • PUT /rbac/roles/{uuid} – Update a role
  • DELETE /rbac/roles/{uuid} – Delete a role
  • Extra: GET /rbac/roles/stats, bulk operations, assign/revoke users

Permissions

  • GET /rbac/permissions – List permissions (with filters/pagination)
  • POST /rbac/permissions – Create a permission
  • GET /rbac/permissions/{uuid} – Get permission details
  • PUT /rbac/permissions/{uuid} – Update a permission
  • DELETE /rbac/permissions/{uuid} – Delete a permission
  • Extra: GET /rbac/permissions/stats, POST /rbac/permissions/cleanup-expired, categories, resource-types

Users

  • GET /rbac/users/{user_uuid}/roles – List a user’s roles
  • POST /rbac/users/{user_uuid}/roles – Assign roles to a user
  • DELETE /rbac/users/{user_uuid}/roles/{role_uuid} – Revoke a user’s role
  • GET /rbac/users/{user_uuid}/permissions – List direct permissions
  • POST /rbac/users/{user_uuid}/permissions – Grant direct permissions
  • DELETE /rbac/users/{user_uuid}/permissions/{permission_uuid} – Revoke direct permission

Hierarchical Roles

The RBAC system supports role hierarchy:

// Create role hierarchy: Admin -> Manager -> Employee
$adminRole = $roleService->createRole([
    'name' => 'Administrator',
    'slug' => 'admin',
    'level' => 0
]);

$managerRole = $roleService->createRole([
    'name' => 'Manager',
    'slug' => 'manager',
    'parent_uuid' => $adminRole->getUuid(),
    'level' => 1
]);

$employeeRole = $roleService->createRole([
    'name' => 'Employee',
    'slug' => 'employee',
    'parent_uuid' => $managerRole->getUuid(),
    'level' => 2
]);

// Users with the employee role inherit manager and admin permissions through their ancestors.

Scoped Permissions

Support multi-tenant environments with scoped permissions:

// Assign role with scope
$roleService->assignRoleToUser($userUuid, $managerRole->getUuid(), [
    'scope' => [
        'tenant_id' => 'tenant_1',
        'department' => 'marketing'
    ]
]);

// Check permission with scope context
$canAccess = $permissionManager->can($userUuid, 'reports.view', '*', [
    'scope' => ['tenant_id' => 'tenant_1']
]);

Audit Logging

An audit service is provided for RBAC-related events, and permission-check logging can be enabled via config:

use Glueful\Extensions\Aegis\Services\AuditService;

$audit = container()->get(AuditService::class);
$audit->logSecurityEvent('unauthorized_access', ['path' => '/rbac/roles'], $userUuid ?? null);

// In app config:
// 'logging' => ['log_check_operations' => true]
// When enabled, permission checks are logged to the 'rbac_audit' channel.

Caching

  • Catalog and lookup caches: Non-temporal catalog lookups and permission summaries can use in-process or distributed cache.
  • Temporal safety: Final authorization decisions and active temporal grants are not cached past their expires_at.
// Clear a user’s RBAC cache
$rbacProvider->invalidateUserCache($userUuid);

// Clear all RBAC cache entries
$rbacProvider->invalidateAllCache();

Performance Considerations

  • Batched lookups to minimize N+1 queries
  • Prefer role-level resource filters and scoped assignments to keep permission sets focused

Security Considerations

  • System roles/permissions can be protected
  • Circular hierarchies are prevented
  • All endpoints require authentication and proper permissions
  • Optional audit trails improve accountability
  • Expiring grants are evaluated against the database on the active authorization path

Migration from Legacy Systems

If migrating from an existing permission system:

  1. Export existing roles and permissions
  2. Use the batch assignment APIs to recreate the structure
  3. Test thoroughly with your existing codebase
  4. Update permission checks to use the new RBAC provider

Troubleshooting

Common Issues

  1. Permissions not working: Confirm Aegis is enabled and DB tables exist; use permission.manager for checks.
  2. Cache issues: Clear RBAC cache via invalidateUserCache()/invalidateAllCache().
  3. Performance issues: Use role-level resource filters and scoped assignments to keep permission sets focused.
  4. Audit logs not appearing: Enable logging.log_check_operations and verify your rbac_audit log channel.

Debugging

Set app-level rbac config overrides to tune caches or enable check logging as needed.

Requirements

  • PHP 8.3 or higher
  • Glueful 1.55.0 or higher
  • MySQL, PostgreSQL, or SQLite database
  • Redis or Memcached (optional, for distributed caching)

License

This extension is licensed under the same license as the Glueful framework.

Support

For issues, feature requests, or questions, please create an issue in the repository.

glueful/aegis 适用场景与选型建议

glueful/aegis 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 73 次下载、GitHub Stars 达 1, 最近一次更新时间为 2025 年 10 月 14 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 glueful/aegis 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 glueful/aegis 我们能提供哪些服务?
定制开发 / 二次开发

基于 glueful/aegis 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 73
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 18
  • 依赖项目数: 1
  • 推荐数: 2

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-10-14