Skip to content

Commit

Permalink
Don't throw exception from ->deny() and set the gate response on the …
Browse files Browse the repository at this point in the history
…exception.
  • Loading branch information
garygreen committed Jul 9, 2019
1 parent 69de466 commit dcd6b59
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 10 deletions.
30 changes: 30 additions & 0 deletions src/Illuminate/Auth/Access/AuthorizationException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@

class AuthorizationException extends Exception
{
/**
* The response from the gate.
*
* @var \Illuminate\Auth\Access\Response
*/
protected $response;

/**
* Create a new authorization exception instance.
*
Expand All @@ -21,6 +28,29 @@ public function __construct($message = '', $code = null, Exception $previous = n
$this->code = $code;
}

/**
* Set the response from the gate.
*
* @param \Illuminate\Auth\Access\Response $response
* @return $this
*/
public function setResponse($response)
{
$this->response = $response;

return $this;
}

/**
* Get the response from the gate.
*
* @return \Illuminate\Auth\Access\Response
*/
public function getResponse()
{
return $this->response;
}

/**
* Create a deny response object from this exception.
*
Expand Down
6 changes: 2 additions & 4 deletions src/Illuminate/Auth/Access/HandlesAuthorization.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,10 @@ protected function allow($message = null, $code = null)
*
* @param string $message
* @param mixed|null $code
* @return void
*
* @throws \Illuminate\Auth\Access\AuthorizationException
* @return \Illuminate\Auth\Access\Response
*/
protected function deny($message = 'This action is unauthorized.', $code = null)
{
throw new AuthorizationException($message, $code);
return Response::deny($message, $code);
}
}
3 changes: 2 additions & 1 deletion src/Illuminate/Auth/Access/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ public function code()
public function authorize()
{
if ($this->denied()) {
throw new AuthorizationException($this->message(), $this->code());
throw (new AuthorizationException($this->message(), $this->code()))
->setResponse($this);
}

return $this;
Expand Down
23 changes: 23 additions & 0 deletions tests/Auth/AuthAccessGateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,20 @@ public function test_authorize_with_policy_that_returns_denied_response_object_t
$gate->authorize('create', new AccessGateTestDummy);
}

public function test_policy_that_throws_authorization_exception_is_caught_in_inspect()
{
$gate = $this->getBasicGate();

$gate->policy(AccessGateTestDummy::class, AccessGateTestPolicyThrowingAuthorizationException::class);

$response = $gate->inspect('create', new AccessGateTestDummy);

$this->assertTrue($response->denied());
$this->assertFalse($response->allowed());
$this->assertEquals('Not allowed.', $response->message());
$this->assertEquals('some_code', $response->code());
}

public function test_authorize_returns_allowed_response()
{
$gate = $this->getBasicGate(true);
Expand Down Expand Up @@ -1086,3 +1100,12 @@ public function create()
return Response::deny('Not allowed.', 'some_code');
}
}

class AccessGateTestPolicyThrowingAuthorizationException
{
public function create()
{
throw new AuthorizationException('Not allowed.', 'some_code');
}
}

12 changes: 7 additions & 5 deletions tests/Auth/AuthAccessResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@ public function test_deny_method()

public function test_authorize_method_throws_authorization_exception_when_response_denied()
{
$this->expectException(AuthorizationException::class);
$this->expectExceptionMessage('Some message.');
$this->expectExceptionCode('some_code');

$response = Response::deny('Some message.', 'some_code');

$response->authorize();
try {
$response->authorize();
} catch (AuthorizationException $e) {
$this->assertEquals('Some message.', $e->getMessage());
$this->assertEquals('some_code', $e->getCode());
$this->assertEquals($response, $e->getResponse());
}
}

public function test_throw_if_needed_doesnt_throw_authorization_exception_when_response_allowed()
Expand Down
31 changes: 31 additions & 0 deletions tests/Auth/AuthHandlesAuthorizationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Illuminate\Tests\Auth;

use PHPUnit\Framework\TestCase;
use Illuminate\Auth\Access\HandlesAuthorization;

class AuthHandlesAuthorizationTest extends TestCase
{
use HandlesAuthorization;

public function test_allow_method()
{
$response = $this->allow('some message', 'some_code');

$this->assertTrue($response->allowed());
$this->assertFalse($response->denied());
$this->assertEquals('some message', $response->message());
$this->assertEquals('some_code', $response->code());
}

public function test_deny_method()
{
$response = $this->deny('some message', 'some_code');

$this->assertTrue($response->denied());
$this->assertFalse($response->allowed());
$this->assertEquals('some message', $response->message());
$this->assertEquals('some_code', $response->code());
}
}

0 comments on commit dcd6b59

Please sign in to comment.