diff --git a/src/Illuminate/Foundation/Http/FormRequest.php b/src/Illuminate/Foundation/Http/FormRequest.php index 9708e5253624..a20dffe2fbe7 100644 --- a/src/Illuminate/Foundation/Http/FormRequest.php +++ b/src/Illuminate/Foundation/Http/FormRequest.php @@ -3,6 +3,7 @@ namespace Illuminate\Foundation\Http; use Illuminate\Auth\Access\AuthorizationException; +use Illuminate\Auth\Access\Response; use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Validation\Factory as ValidationFactory; use Illuminate\Contracts\Validation\ValidatesWhenResolved; @@ -163,11 +164,15 @@ protected function getRedirectUrl() * Determine if the request passes the authorization check. * * @return bool + * + * @throws \Illuminate\Auth\Access\AuthorizationException */ protected function passesAuthorization() { if (method_exists($this, 'authorize')) { - return $this->container->call([$this, 'authorize']); + $result = $this->container->call([$this, 'authorize']); + + return $result instanceof Response ? $result->authorize() : $result; } return true; diff --git a/tests/Foundation/FoundationFormRequestTest.php b/tests/Foundation/FoundationFormRequestTest.php index d394566ce6cb..9f2456583bc7 100644 --- a/tests/Foundation/FoundationFormRequestTest.php +++ b/tests/Foundation/FoundationFormRequestTest.php @@ -4,6 +4,7 @@ use Exception; use Illuminate\Auth\Access\AuthorizationException; +use Illuminate\Auth\Access\Response; use Illuminate\Container\Container; use Illuminate\Contracts\Translation\Translator; use Illuminate\Contracts\Validation\Factory as ValidationFactoryContract; @@ -101,6 +102,19 @@ public function testValidateMethodThrowsWhenAuthorizationFails() $this->createRequest([], FoundationTestFormRequestForbiddenStub::class)->validateResolved(); } + public function testValidateThrowsExceptionFromAuthorizationResponse() + { + $this->expectException(AuthorizationException::class); + $this->expectExceptionMessage('foo'); + + $this->createRequest([], FoundationTestFormRequestForbiddenWithResponseStub::class)->validateResolved(); + } + + public function testValidateDoesntThrowExceptionFromResponseAllowed() + { + $this->createRequest([], FoundationTestFormRequestPassesWithResponseStub::class)->validateResolved(); + } + public function testPrepareForValidationRunsBeforeValidation() { $this->createRequest([], FoundationTestFormRequestHooks::class)->validateResolved(); @@ -322,3 +336,24 @@ public function passedValidation() $this->replace(['name' => 'Adam']); } } + +class FoundationTestFormRequestForbiddenWithResponseStub extends FormRequest +{ + public function authorize() + { + return Response::deny('foo'); + } +} + +class FoundationTestFormRequestPassesWithResponseStub extends FormRequest +{ + public function rules() + { + return []; + } + + public function authorize() + { + return Response::allow('baz'); + } +}