Skip to content

Conversation

@kevalyq
Copy link
Contributor

@kevalyq kevalyq commented Nov 15, 2025

Overview

Implements User Direct Permission Assignment API as part of RBAC Phase 4 Epic (#108).

Closes #138

Implementation Summary

API Endpoints

  1. GET /api/v1/users/{user}/permissions - List all user permissions (direct + inherited)
  2. POST /api/v1/users/{user}/permissions - Assign direct permission
  3. DELETE /api/v1/users/{user}/permissions/{permission} - Revoke direct permission
  4. GET /api/v1/users/{user}/permissions/direct - List only direct permissions

Key Features

  • ✅ Direct permission assignment with temporal tracking (granted_at, granted_by, revoked_at, revoked_by)
  • ✅ Tenant-scoped via TenantKey
  • ✅ Authorization via UserPermissionPolicy (Admin can assign, user can view own)
  • ✅ Comprehensive validation (permission exists, not already assigned, etc.)
  • ✅ Multi-tenant aware (hasDirectPermission() uses direct DB queries)

Technical Details

Critical Implementation: Direct DB manipulation required for pivot attributes

  • Spatie's givePermissionTo() doesn't support custom pivot data
  • Implemented updateOrInsert() on model_has_permissions table
  • Tracks temporal data: granted_at, granted_by, revoked_at, revoked_by

Multi-Tenant Fix: hasDirectPermission() rewritten

  • Original implementation filtered by tenant_id via relationship
  • New implementation: Direct DB query on pivot table (tenant-agnostic)
  • Enables checking permissions across tenant boundaries when needed

Files Changed

  • app/Http/Controllers/Api/V1/UserPermissionController.php (new)
  • app/Http/Requests/AssignUserPermissionRequest.php (new)
  • app/Policies/UserPermissionPolicy.php (new)
  • app/Models/User.php (updated hasDirectPermission())
  • app/Providers/AppServiceProvider.php (Gate registration)
  • tests/Feature/UserPermissionAssignmentApiTest.php (new, 13 tests)
  • CHANGELOG.md (updated)

Quality Assurance

  • Tests: 270 passed (866 assertions)
  • PHPStan: Level Max, 0 errors
  • Laravel Pint: All files formatted
  • REUSE: 100% compliant (176/176 files)
  • 4-Pass Self-Review: Completed (2 iterations)

Testing

php artisan test tests/Feature/UserPermissionAssignmentApiTest.php
# 13 tests, 52 assertions

Migration

No new migration required. Uses existing model_has_permissions table with pivot columns:

  • granted_at, granted_by, revoked_at, revoked_by

Next Steps

  • Copilot code review
  • Address review feedback
  • Mark ready for merge

Epic: #108 (RBAC Phase 4)
Type: Feature
Scope: Backend API

@kevalyq kevalyq requested a review from Copilot November 15, 2025 02:49
Copilot finished reviewing on behalf of kevalyq November 15, 2025 02:52
Copy link
Contributor

Copilot AI left a 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 adds CHANGELOG documentation for the User Direct Permission Assignment API feature (Issue #138), which is part of RBAC Phase 4 Epic. The PR documents 4 new API endpoints for managing direct user permissions, along with supporting infrastructure (controller, policy, form request, and model method).

Key Issue: The CHANGELOG contains several inconsistencies with the PR description regarding implementation details, particularly around column names and migration requirements.

Implements Issue #138 - User Direct Permission Assignment API as part of RBAC Phase 4 Epic (#108).

Added:
- UserPermissionController: 4 endpoints (index, store, destroy, direct)
- AssignUserPermissionRequest: Validation with temporal constraints
- UserPermissionPolicy: Authorization (Admin assign/revoke, User view own)
- Migration: Add temporal columns to model_has_permissions table
- Tests: 13 comprehensive feature tests (52 assertions)

Technical Implementation:
- Direct DB manipulation for pivot attributes (Spatie limitation workaround)
- hasDirectPermission() rewritten with direct DB queries (multi-tenant fix)
- Temporal tracking: granted_at, granted_by, revoked_at, revoked_by

Quality Assurance:
- Tests: 270 passed (866 assertions)
- PHPStan: Level Max, 0 errors
- Laravel Pint: All files formatted
- REUSE: 100% compliant
- Clarify 'List all user permissions (direct + inherited from roles)'
- Change 'temporal constraints' to 'temporal tracking (audit trail)'
- Fix migration description: no new migration, uses existing columns
- Update column names: granted_at/granted_by/revoked_at/revoked_by (not valid_from/until)
- Clarify validation description: permission existence, not already assigned

Addresses 5 Copilot review comments on PR #158
@kevalyq kevalyq added the large-pr-approved Legitimate large PR (e.g., boilerplate templates, auto-generated code) label Nov 15, 2025
@kevalyq kevalyq marked this pull request as ready for review November 15, 2025 03:10
@github-actions
Copy link

💡 Tip: Consider Using Draft PRs

Benefits of opening PRs as drafts initially:

  • 💰 Saves CI runtime and Copilot review credits
  • 🎯 Automatically sets linked issues to "🚧 In Progress" status
  • 🚀 Mark "Ready for review" when done to trigger full CI pipeline

How to convert:

  1. Click "Still in progress? Convert to draft" in the sidebar, OR
  2. Use gh pr ready when ready for review

This is just a friendly reminder - feel free to continue as is! 😊

@kevalyq kevalyq merged commit 9dfa219 into main Nov 15, 2025
23 checks passed
@kevalyq kevalyq deleted the feat/user-direct-permissions branch November 15, 2025 03:14
@github-actions
Copy link

💡 Tip: Consider Using Draft PRs

Benefits of opening PRs as drafts initially:

  • 💰 Saves CI runtime and Copilot review credits
  • 🎯 Automatically sets linked issues to "🚧 In Progress" status
  • 🚀 Mark "Ready for review" when done to trigger full CI pipeline

How to convert:

  1. Click "Still in progress? Convert to draft" in the sidebar, OR
  2. Use gh pr ready when ready for review

This is just a friendly reminder - feel free to continue as is! 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

large-pr-approved Legitimate large PR (e.g., boilerplate templates, auto-generated code)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

User Direct Permission Assignment API (RBAC Phase 4)

2 participants