-
Notifications
You must be signed in to change notification settings - Fork 17
Exception Handling
The Efficiently\AuthorityController\Exceptions\AccessDenied
exception is raised when calling authorize
in the controller and the user is not able to perform the given action. A message can optionally be provided.
$this->authorize('read', 'Article', ['message' => "Unable to read this article."]);
This exception can also be raised manually if you want more custom behavior.
throw new Efficiently\AuthorityController\Exceptions\AccessDenied("Not authorized!", 'read', 'Article');
The message can also be customized through internationalization.
// in resources/lang/en/messages.php # For Laravel 5.0
// in app/lang/en/messages.php # For Laravel 4.*
return [
'unauthorized' => [
'default' => 'You are not authorized to access this page.',
'manage' => [
'all' => "Not authorized to :action :subject.",
'user' => "Not allowed to manage other user accounts.",
],
'update' => [
'project' => "Not allowed to update this project.",
],
],
];
Notice manage
and all
can be used to generalize the subject and actions. Also :action
and :subject
can be used as variables in the message.
You can catch the exception and modify its behavior in the app/start/global.php
file. For example here we set the error message to a flash and redirect to the home page.
App::error(function(Efficiently\AuthorityController\Exceptions\AccessDenied $e, $code, $fromConsole)
{
$msg = $e->getMessage();
if ($fromConsole) {
return 'Error '.$code.': '.$msg."\n";
}
Log::error('Access denied! '.$msg);
return Redirect::route('home')->with('flash_alert', $msg);
});
You can catch the exception and modify its behavior in the render()
method of the app/Exceptions/Handler.php
file. For example here we set the error message to a flash and redirect to the home page.
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
if ($e instanceof \Efficiently\AuthorityController\Exceptions\AccessDenied) {
$msg = $e->getMessage();
\Log::error('Access denied! '.$msg);
return redirect('/home')->with('flash_alert', $msg);
}
return parent::render($request, $e);
}
//code...
The action and subject can be retrieved through the exception to customize the behavior further.
$e->action; //-> 'read'
$e->subject; //-> 'Article'
The default error message can also be customized through the exception. This will be used if no message was provided.
$e->setDefaultMessage("Default error message");
$e->getMessage(); //-> "Default error message"
Create a app/views/errors/forbidden.php
file and write a error handler like this example in the app/start/global.php
file:
App::error(function(Efficiently\AuthorityController\Exceptions\AccessDenied $e, $code, $fromConsole)
{
$msg = $e->getMessage();
if ($fromConsole) {
return 'Error '.$code.': '.$msg."\n";
}
return Response::view('errors.forbidden', compact('code', 'msg'), 403);
});
Create a resources/views/errors/forbidden.php
file and write a error handler like this example in the app/Exceptions/Handler.php
file:
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
if ($e instanceof \Efficiently\AuthorityController\Exceptions\AccessDenied) {
$msg = $e->getMessage();
return response()->view('errors.forbidden', compact('msg'), 403);
}
return parent::render($request, $e);
}
//code...
forbidden.php
should be pure HTML, CSS, and JavaScript--not a template, to avoid errors.
If you are getting unexpected behavior when rescuing from the exception it is best to add some logging . See Debugging Authority rules for details.
See Authorization in Web Services for rescuing exceptions for XML responses.