master

laravel/framework

Last updated at: 29/12/2023 09:23

AuthorizesRequests.php

TLDR

The AuthorizesRequests.php file is a trait that provides authorization functionality for the current user in a Laravel application. It includes methods for authorizing actions, guessing ability names, authorizing actions for a specific user, authorizing resource actions based on the incoming request, and getting the resource methods and abilities map.

Methods

authorize

This method authorizes a given action for the current user.

  • Parameters:
    • ability: The ability to be authorized.
    • arguments (optional): Additional arguments for the authorization.
  • Returns: An Illuminate\Auth\Access\Response object representing the authorization result.
  • Throws: An Illuminate\Auth\Access\AuthorizationException if the authorization fails.

authorizeForUser

This method authorizes a given action for a specific user.

  • Parameters:
    • user: The user for whom the action should be authorized.
    • ability: The ability to be authorized.
    • arguments (optional): Additional arguments for the authorization.
  • Returns: An Illuminate\Auth\Access\Response object representing the authorization result.
  • Throws: An Illuminate\Auth\Access\AuthorizationException if the authorization fails.

parseAbilityAndArguments

This protected method parses the given ability and arguments.

  • Parameters:
    • ability: The ability to be parsed.
    • arguments: The arguments to be parsed.
  • Returns: An array containing the parsed ability and arguments.

normalizeGuessedAbilityName

This protected method normalizes the guessed ability name based on the method name.

  • Parameters:
    • ability: The ability name to be normalized.
  • Returns: The normalized ability name.

authorizeResource

This method authorizes a resource action based on the incoming request.

  • Parameters:
    • model: The resource model or models (can be a string or an array).
    • parameter: The resource parameter or parameters (can be a string or an array).
    • options: Additional options for the resource authorization.
    • request (optional): The incoming HTTP request.
  • Returns: void

resourceAbilityMap

This protected method returns a map of resource methods to ability names.

  • Returns: An array representing the resource methods and their corresponding ability names.

resourceMethodsWithoutModels

This protected method returns a list of resource methods that do not have model parameters.

  • Returns: An array representing the resource methods without model parameters.
<?php

namespace Illuminate\Foundation\Auth\Access;

use Illuminate\Contracts\Auth\Access\Gate;
use Illuminate\Support\Str;

trait AuthorizesRequests
{
    /**
     * Authorize a given action for the current user.
     *
     * @param  mixed  $ability
     * @param  mixed|array  $arguments
     * @return \Illuminate\Auth\Access\Response
     *
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    public function authorize($ability, $arguments = [])
    {
        [$ability, $arguments] = $this->parseAbilityAndArguments($ability, $arguments);

        return app(Gate::class)->authorize($ability, $arguments);
    }

    /**
     * Authorize a given action for a user.
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable|mixed  $user
     * @param  mixed  $ability
     * @param  mixed|array  $arguments
     * @return \Illuminate\Auth\Access\Response
     *
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    public function authorizeForUser($user, $ability, $arguments = [])
    {
        [$ability, $arguments] = $this->parseAbilityAndArguments($ability, $arguments);

        return app(Gate::class)->forUser($user)->authorize($ability, $arguments);
    }

    /**
     * Guesses the ability's name if it wasn't provided.
     *
     * @param  mixed  $ability
     * @param  mixed|array  $arguments
     * @return array
     */
    protected function parseAbilityAndArguments($ability, $arguments)
    {
        if (is_string($ability) && ! str_contains($ability, '\\')) {
            return [$ability, $arguments];
        }

        $method = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3)[2]['function'];

        return [$this->normalizeGuessedAbilityName($method), $ability];
    }

    /**
     * Normalize the ability name that has been guessed from the method name.
     *
     * @param  string  $ability
     * @return string
     */
    protected function normalizeGuessedAbilityName($ability)
    {
        $map = $this->resourceAbilityMap();

        return $map[$ability] ?? $ability;
    }

    /**
     * Authorize a resource action based on the incoming request.
     *
     * @param  string|array  $model
     * @param  string|array|null  $parameter
     * @param  array  $options
     * @param  \Illuminate\Http\Request|null  $request
     * @return void
     */
    public function authorizeResource($model, $parameter = null, array $options = [], $request = null)
    {
        $model = is_array($model) ? implode(',', $model) : $model;

        $parameter = is_array($parameter) ? implode(',', $parameter) : $parameter;

        $parameter = $parameter ?: Str::snake(class_basename($model));

        $middleware = [];

        foreach ($this->resourceAbilityMap() as $method => $ability) {
            $modelName = in_array($method, $this->resourceMethodsWithoutModels()) ? $model : $parameter;

            $middleware["can:{$ability},{$modelName}"][] = $method;
        }

        foreach ($middleware as $middlewareName => $methods) {
            $this->middleware($middlewareName, $options)->only($methods);
        }
    }

    /**
     * Get the map of resource methods to ability names.
     *
     * @return array
     */
    protected function resourceAbilityMap()
    {
        return [
            'index' => 'viewAny',
            'show' => 'view',
            'create' => 'create',
            'store' => 'create',
            'edit' => 'update',
            'update' => 'update',
            'destroy' => 'delete',
        ];
    }

    /**
     * Get the list of resource methods which do not have model parameters.
     *
     * @return array
     */
    protected function resourceMethodsWithoutModels()
    {
        return ['index', 'create', 'store'];
    }
}