Skip to content

Commit

Permalink
[8.x] Adds on-demand gate authorization (#39789)
Browse files Browse the repository at this point in the history
* Adds on-demand gate authorization.

* Removes lingering PHPDoc written by mistake.

* Style changes.

* Removes unused function.

* formatting

* Added exception when auth user is required and is guest.

* Minor line style fix.

* Use `canBeCalledWithUser()` instead.

* Additional tests.

* Moved logic to shared method.

* Removed `value` helper.

* Adds support for `Response` object. Minor formatting.

* Style changes.

* formatting

Co-authored-by: Taylor Otwell <[email protected]>
  • Loading branch information
DarkGhostHunter and taylorotwell authored Dec 2, 2021
1 parent 9b26b62 commit 02b1667
Showing 1 changed file with 59 additions and 0 deletions.
59 changes: 59 additions & 0 deletions Access/Gate.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Illuminate\Auth\Access;

use Closure;
use Exception;
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Contracts\Container\Container;
Expand Down Expand Up @@ -117,6 +118,64 @@ public function has($ability)
return true;
}

/**
* Perform an on-demand authorization check. Throw an authorization exception if the condition or callback is false.
*
* @param \Illuminate\Auth\Access\Response|\Closure|bool $condition
* @param string|null $message
* @param string|null $code
* @return \Illuminate\Auth\Access\Response
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function allowIf($condition, $message = null, $code = null)
{
return $this->authorizeOnDemand($condition, $message, $code, true);
}

/**
* Perform an on-demand authorization check. Throw an authorization exception if the condition or callback is true.
*
* @param \Illuminate\Auth\Access\Response|\Closure|bool $condition
* @param string|null $message
* @param string|null $code
* @return \Illuminate\Auth\Access\Response
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function denyIf($condition, $message = null, $code = null)
{
return $this->authorizeOnDemand($condition, $message, $code, false);
}

/**
* Authorize a given condition or callback.
*
* @param \Illuminate\Auth\Access\Response|\Closure|bool $condition
* @param string|null $message
* @param string|null $code
* @param bool $allowWhenResponseIs
* @return \Illuminate\Auth\Access\Response
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
protected function authorizeOnDemand($condition, $message, $code, $allowWhenResponseIs)
{
$user = $this->resolveUser();

if ($condition instanceof Closure) {
$response = $this->canBeCalledWithUser($user, $condition)
? $condition($user)
: new Response(false, $message, $code);
} else {
$response = $condition;
}

return with($response instanceof Response ? $response : new Response(
(bool) $response === $allowWhenResponseIs, $message, $code
))->authorize();
}

/**
* Define a new ability.
*
Expand Down

0 comments on commit 02b1667

Please sign in to comment.