VOOZH about

URL: https://deepwiki.com/hypervel/permission/3.1-permission-middleware

⇱ Permission Middleware | hypervel/permission | DeepWiki


Loading...
Menu

Permission Middleware

Purpose and Scope

The PermissionMiddleware is an HTTP middleware component that enforces permission-based authorization at the request level. It intercepts incoming HTTP requests and validates that the authenticated user possesses at least one of the required permissions before allowing the request to proceed to the route handler.

This middleware works in conjunction with the HasPermission trait (see HasPermission Trait) by calling the hasAnyPermissions() method on the authenticated user. For role-based route protection, see Role Middleware. For detailed information about exception types and their HTTP status codes, see Exception Handling.

Sources: src/Middlewares/PermissionMiddleware.php1-102


Architecture and Components

The middleware is implemented in a single class that integrates with the PSR-15 middleware specification and the Hypervel authentication system.

Component Overview


Sources: src/Middlewares/PermissionMiddleware.php19-101


Request Processing Flow

The middleware follows a strict validation sequence that ensures authentication and authorization requirements are met before allowing request processing to continue.

Processing Sequence


Sources: src/Middlewares/PermissionMiddleware.php28-75


Authentication Validation

The middleware performs two levels of authentication validation before checking permissions.

Validation Checks

CheckConditionExceptionStatus CodeMessage Format
User Authenticated$user === nullUnauthorizedException401User is not authenticated. Cannot check permissions: {permissions}
Method Available!method_exists($user, 'hasAnyPermissions')UnauthorizedException500User "{identifier}" does not have the "hasAnyPermissions" method. Cannot check permissions: {permissions}
Permission Check!$user->hasAnyPermissions($permissions)PermissionException403User "{identifier}" does not have any of the required permissions: {permissions}

Authentication Check

The middleware first retrieves the authenticated user from the AuthManager:

<FileRef file-url="https://github.com/hypervel/permission/blob/4603b048/src/Middlewares/PermissionMiddleware.php#L33-L43" min=33 max=43 file-path="src/Middlewares/PermissionMiddleware.php">Hii</FileRef>

This check ensures that only authenticated users can access protected routes. If no user is authenticated, an UnauthorizedException with status code 401 is thrown immediately.

Contract Validation

After confirming authentication, the middleware validates that the user model implements the required permission checking contract:

<FileRef file-url="https://github.com/hypervel/permission/blob/4603b048/src/Middlewares/PermissionMiddleware.php#L45-L55" min=45 max=55 file-path="src/Middlewares/PermissionMiddleware.php">Hii</FileRef>

This check ensures that the user model has mixed in the HasPermission trait (see HasPermission Trait). If the method is missing, an UnauthorizedException with status code 500 is thrown, indicating a configuration error rather than an authorization failure.

Sources: src/Middlewares/PermissionMiddleware.php33-55


Permission Authorization

Once authentication and contract validation pass, the middleware performs the actual permission check.

Permission Check Logic


The middleware splits the permission string by the pipe (|) character to create an array of permission names:

<FileRef file-url="https://github.com/hypervel/permission/blob/4603b048/src/Middlewares/PermissionMiddleware.php#L56-L56" min=56 file-path="src/Middlewares/PermissionMiddleware.php">Hii</FileRef>

It then delegates to the user's hasAnyPermissions() method, which implements the actual permission checking logic including support for forbidden permissions:

<FileRef file-url="https://github.com/hypervel/permission/blob/4603b048/src/Middlewares/PermissionMiddleware.php#L58-L72" min=58 max=72 file-path="src/Middlewares/PermissionMiddleware.php">Hii</FileRef>

The PermissionException includes the array of required permissions, making it possible for error handlers to provide detailed feedback about which permissions were required but missing.

Sources: src/Middlewares/PermissionMiddleware.php56-72 src/Exceptions/PermissionException.php12-26


Middleware Registration

The middleware provides a static helper method for generating unique middleware identifiers when registering routes.

The using() Method


The using() method generates a unique identifier for the middleware based on the permissions it will check:

<FileRef file-url="https://github.com/hypervel/permission/blob/4603b048/src/Middlewares/PermissionMiddleware.php#L80-L83" min=80 max=83 file-path="src/Middlewares/PermissionMiddleware.php">Hii</FileRef>

This identifier is used by the routing system to distinguish between different permission middleware instances with different permission requirements.

Usage Example

When registering routes, the middleware can be referenced using this pattern:


Sources: src/Middlewares/PermissionMiddleware.php80-83


Permission Parsing

The middleware includes sophisticated permission parsing logic that handles multiple input formats including arrays, strings, and enums.

Permission Parser Flow


Parser Implementation

The parsePermissionsToString() method handles multiple permission input formats:

<FileRef file-url="https://github.com/hypervel/permission/blob/4603b048/src/Middlewares/PermissionMiddleware.php#L85-L101" min=85 max=101 file-path="src/Middlewares/PermissionMiddleware.php">Hii</FileRef>

Supported Input Types

Input TypeHandlingExample
BackedEnumExtracts .value propertyStatus::Published->value
UnitEnumExtracts .name propertyStatus::Published->name
stringUsed directly'view-posts'
intUsed directly42
Nested arraysFlattened recursively[['a', 'b'], 'c']['a', 'b', 'c']

The parser uses a Collection to flatten nested arrays and normalize all values before joining them with the pipe (|) delimiter. This allows the middleware to accept permissions in flexible formats while maintaining a consistent internal representation.

Sources: src/Middlewares/PermissionMiddleware.php85-101


Exception Handling

The middleware throws two types of exceptions, each indicating a different failure scenario.

Exception Types and Scenarios


UnauthorizedException

The UnauthorizedException is thrown for two distinct failure cases:

Authentication Failure (401):

  • Thrown when no user is authenticated
  • Indicates the request requires authentication
  • Message includes the list of permissions that would be checked
<FileRef file-url="https://github.com/hypervel/permission/blob/4603b048/src/Middlewares/PermissionMiddleware.php#L36-L42" min=36 max=42 file-path="src/Middlewares/PermissionMiddleware.php">Hii</FileRef>

Configuration Error (500):

  • Thrown when the user model doesn't implement the required contract
  • Indicates a development/configuration issue
  • Message includes the user identifier and required method name
<FileRef file-url="https://github.com/hypervel/permission/blob/4603b048/src/Middlewares/PermissionMiddleware.php#L46-L54" min=46 max=54 file-path="src/Middlewares/PermissionMiddleware.php">Hii</FileRef>

PermissionException

The PermissionException is thrown when an authenticated user lacks the required permissions:

<FileRef file-url="https://github.com/hypervel/permission/blob/4603b048/src/Middlewares/PermissionMiddleware.php#L59-L71" min=59 max=71 file-path="src/Middlewares/PermissionMiddleware.php">Hii</FileRef>

This exception includes:

  • Status Code: 403 (Forbidden)
  • Message: User identifier and list of required permissions
  • Permissions Array: Accessible via $exception->permissions() method

The permissions array is stored as a property on the exception:

<FileRef file-url="https://github.com/hypervel/permission/blob/4603b048/src/Exceptions/PermissionException.php#L12-L26" min=12 max=26 file-path="src/Exceptions/PermissionException.php">Hii</FileRef>

Sources: src/Middlewares/PermissionMiddleware.php36-71 src/Exceptions/PermissionException.php12-26 src/Exceptions/UnauthorizedException.php1-11


Integration with HasPermission Trait

The middleware delegates the actual permission checking logic to the user model's hasAnyPermissions() method, which is provided by the HasPermission trait.

Integration Points

Middleware ResponsibilityHasPermission Responsibility
Retrieve authenticated userN/A
Validate method existenceProvide hasAnyPermissions() method
Parse permission stringsN/A
Throw HTTP exceptionsReturn boolean result
Handle request continuationQuery permissions from database/cache
N/AHandle forbidden permissions logic
N/AManage permission relationships

The middleware acts as a thin HTTP layer that validates authentication and translates permission checking results into HTTP responses, while the HasPermission trait handles the complex business logic of permission evaluation. For details on how hasAnyPermissions() works, including forbidden permission handling and caching, see HasPermission Trait.

Sources: src/Middlewares/PermissionMiddleware.php45-72


Summary

The PermissionMiddleware class provides HTTP-level permission enforcement with the following characteristics:

  1. PSR-15 Compliance: Implements MiddlewareInterface for framework integration
  2. Three-Tier Validation: Checks authentication, contract compliance, and permissions in sequence
  3. Flexible Permission Input: Supports arrays, strings, integers, and enums via parsePermissionsToString()
  4. Clear Error Signaling: Uses appropriate HTTP status codes (401, 403, 500) for different failure scenarios
  5. Detailed Exception Data: Includes permission lists and user identifiers in exception messages
  6. Route Registration Helper: Provides using() method for generating unique middleware identifiers

The middleware serves as a gatekeeper at the HTTP request boundary, ensuring that only authenticated users with appropriate permissions can access protected routes.

Sources: src/Middlewares/PermissionMiddleware.php1-102 src/Exceptions/PermissionException.php1-27 src/Exceptions/UnauthorizedException.php1-11