Skip to content

Phase 3: Introduce Laravel Policies for project authorization #10

@dkwiebe

Description

@dkwiebe

Summary

Authorization logic for the two-tier permission system (super admin + project-scoped roles) is spread across User model methods, ProjectAccessService, AdminMiddleware, and inline controller checks. There is also a gap: the project-request approve/reject routes in routes/web.php only carry auth middleware and rely entirely on in-controller checks.

Consolidating into Laravel Policies creates a single, testable source of truth.

Implementation

1. Create app/Policies/ProjectPolicy.php

public function viewAny(User $user): bool   // super admin or has any assigned project
public function view(User $user, Project $project): bool   // super admin or assigned to project
public function manage(User $user, Project $project): bool  // super admin or project admin
public function create(User $user): bool    // super admin only

2. Create app/Policies/ProjectRequestPolicy.php

public function approve(User $user): bool   // super admin only
public function reject(User $user): bool    // super admin only

3. Register in AuthServiceProvider (or via model discovery in Laravel 11)

4. Update controllers to use $this->authorize() or Gate::authorize():

  • ProjectManagementControllerauthorize('manage', $project)
  • ProjectRequestControllerauthorize('approve', ProjectRequest::class)
  • Remove the duplicate isSuperAdmin() inline checks

5. Update routes/web.php — the project-request routes can optionally add the admin middleware as a belt-and-suspenders guard, since the Policy now enforces it explicitly.

Acceptance Criteria

  • All project access decisions route through the Policy
  • Existing role-based behavior is preserved exactly
  • Policy methods have unit tests
  • No inline isSuperAdmin() / isAdminForProject() checks remain in controllers

Metadata

Metadata

Assignees

No one assigned

    Labels

    architectureCode quality and architecturephase-3Architecture cleanup

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions