-
Notifications
You must be signed in to change notification settings - Fork 0
feat: implement Permission Management CRUD API (#137) #153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Add 5 RESTful endpoints for permission management
- GET /v1/permissions - List all permissions grouped by resource
- POST /v1/permissions - Create permission with resource.action validation
- GET /v1/permissions/{id} - Get details with assigned roles
- PATCH /v1/permissions/{id} - Update description (name immutable)
- DELETE /v1/permissions/{id} - Delete (blocked if assigned to roles)
- Extend Spatie Permission model with description field
- New migration: add description column to permissions table
- Custom App\Models\Permission with description support
- Configure custom model in config/permission.php
- Implement authorization via PermissionManagementPolicy
- Admin-only access (permissions.read/create/update/delete)
- Consistent with RoleManagementPolicy pattern
- Add form request validation
- CreatePermissionRequest: strict resource.action regex, max 255 chars
- UpdatePermissionRequest: description-only updates, name prohibited
- Add comprehensive test coverage
- 24 tests covering all endpoints and edge cases
- 109 assertions for authorization, validation, and business logic
- Tests for deletion blocking when assigned to roles
Quality gates passed:
- PHPStan Level Max: ✅ No errors
- Laravel Pint: ✅ Code style compliant
- Tests: ✅ 257 passed (814 assertions)
- REUSE: ✅ All files have SPDX headers
Part of RBAC Phase 4 Epic (#108)
Enables Issue #138 (User Direct Permission Assignment)
💡 Tip: Consider Using Draft PRsBenefits of opening PRs as drafts initially:
How to convert:
This is just a friendly reminder - feel free to continue as is! 😊 |
💡 Tip: Consider Using Draft PRsBenefits of opening PRs as drafts initially:
How to convert:
This is just a friendly reminder - feel free to continue as is! 😊 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements a complete CRUD API for system-wide permission management as part of the RBAC Phase 4 Epic. It introduces 5 RESTful endpoints with strict validation, admin-only authorization, and safety features like immutable permission names and deletion blocking for assigned permissions.
Key Changes:
- New Permission Management CRUD endpoints with resource.action naming validation
- Extended Spatie Permission model with description field
- Comprehensive test suite with 24 tests covering authentication, authorization, validation, and edge cases
Reviewed Changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Feature/PermissionManagementApiTest.php | Comprehensive test suite with 24 tests covering all CRUD operations and edge cases |
| routes/api.php | Added 5 new permission management routes under auth:sanctum middleware |
| database/migrations/2025_11_12_193139_add_description_to_permissions_table.php | Migration adding nullable description column to permissions table |
| config/permission.php | Updated to use custom App\Models\Permission instead of Spatie's model |
| app/Providers/AppServiceProvider.php | Registered PermissionManagementPolicy for Permission model |
| app/Policies/PermissionManagementPolicy.php | New policy enforcing permissions-based authorization for all operations |
| app/Models/Permission.php | Extended Spatie Permission model with description field support |
| app/Http/Requests/Api/V1/UpdatePermissionRequest.php | Validation for updates - description only, name prohibited for security |
| app/Http/Requests/Api/V1/CreatePermissionRequest.php | Validation for creation with strict resource.action format enforcement |
| app/Http/Controllers/Api/V1/PermissionManagementController.php | Controller implementing 5 CRUD methods with authorization and safety checks |
| CHANGELOG.md | Documented new permission management API feature |
- Change Permission model to use casts() method (project convention) - Fix AppServiceProvider to import App\Models\Permission (was using Spatie) - Fix tests to import App\Models\Permission (was using Spatie) - Use assertJsonCount instead of closure for better readability Note: Copilot suggested nullsafe operators for timestamps, but PHPStan correctly identified them as unnecessary (created_at/updated_at never null). RoleManagementController has same pattern but predates strict PHPStan rules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
Found through systematic grep search after initial review fixes. CRITICAL SECURITY ISSUES FIXED: - PermissionManagementPolicy: Used wrong model class (authorization bypass risk) - CreateRoleRequest/UpdateRoleRequest: Wrong validation model - RolesAndPermissionsSeeder: Created Spatie models instead of custom - PersonApiTest/RoleApiTest/RoleManagementApiTest: Used wrong model in tests All files now correctly import App\Models\Permission instead of Spatie\Permission\Models\Permission. Root cause: Pattern-based copying without systematic verification after creating custom Permission model. Should have run: grep -r 'Spatie\\Permission\\Models\\Permission' . Affected files (7): - app/Policies/PermissionManagementPolicy.php - app/Http/Requests/Api/V1/CreateRoleRequest.php - app/Http/Requests/Api/V1/UpdateRoleRequest.php - database/seeders/RolesAndPermissionsSeeder.php - tests/Feature/PersonApiTest.php - tests/Feature/RoleApiTest.php - tests/Feature/RoleManagementApiTest.php
Copilot review identified missing $fillable property for description field. While Spatie Permission has $guarded = [], explicitly declaring fillable fields is Laravel best practice for: - Security: Prevent accidental mass assignment of future fields - Documentation: Clear intent of which fields are expected - Maintainability: Easier to understand model interface Fixes Copilot review comment #9. Tests: All 24 Permission Management tests pass.
💡 Tip: Consider Using Draft PRsBenefits of opening PRs as drafts initially:
How to convert:
This is just a friendly reminder - feel free to continue as is! 😊 |
🎯 Issue #137 - Permission Management CRUD API
Part of RBAC Phase 4 Epic (#108)
📋 Summary
Implements complete CRUD API for system-wide permission management, enabling admins to create, read, update, and delete permissions with strict validation and safety checks.
✨ Features
5 RESTful Endpoints:
GET /v1/permissions- List all permissions grouped by resourcePOST /v1/permissions- Create permission with resource.action validationGET /v1/permissions/{id}- Get details with assigned rolesPATCH /v1/permissions/{id}- Update description (name immutable for safety)DELETE /v1/permissions/{id}- Delete permission (blocked if assigned to roles)Key Design Decisions:
🏗️ Implementation
New Files:
PermissionManagementController.php(153 lines) - 5 RESTful methodsCreatePermissionRequest.php(56 lines) - Validation with regexUpdatePermissionRequest.php(49 lines) - Description-only updatesPermissionManagementPolicy.php(55 lines) - Admin authorizationPermission.php(34 lines) - Extended Spatie modelPermissionManagementApiTest.php(344 lines) - 24 tests, 109 assertionsModified Files:
routes/api.php- Added 5 routes under auth:sanctumconfig/permission.php- Configured custom Permission modelAppServiceProvider.php- Registered policyCHANGELOG.md- Documented changes✅ Quality Gates
📊 Test Coverage
24 comprehensive tests covering:
🔗 Dependencies
752 lines (exceeds 600 line limit)
Reason: Atomic TDD implementation
Splitting would violate:
📝 Checklist
Closes #137