Skip to content

Instantly share code, notes, and snippets.

@alezhu
Last active October 7, 2016 06:53
Show Gist options
  • Save alezhu/d9973d1667e67a9a47ba851050fa24f8 to your computer and use it in GitHub Desktop.
Save alezhu/d9973d1667e67a9a47ba851050fa24f8 to your computer and use it in GitHub Desktop.
Lumen middleware for check contoller methods availability via Doctrine annotation
<?php
/*
in app.php add
$app->routeMiddleware([
'action' =>\App\Http\Middleware\ActionMiddleware::class,
]);
AnnotationRegistry::registerLoader('class_exists');
in route add something like
$app->group([
'prefix' => 'api',
'middleware' => ['action'],
'namespace' => 'App\Http\Controllers',
], function () use ($app) {
...
});
in controller add somethiong like
/**
* @return \Symfony\Component\HttpFoundation\Response
*
* @CheckAction(Action::ADMIN_USER_READ)
*
* /
public function index() ....
*/
namespace App\Http\Middleware;
use App\Core\CheckAction;
use App\Models\ActionService;
use Auth;
use Closure;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\CachedReader;
use Doctrine\Common\Cache\FilesystemCache;
use Illuminate\Http\Request;
use Log;
/**
* Class ActionMiddleware
* @package App\Http\Middleware
*/
class ActionMiddleware
{
private $reader;
/**
* ActionMiddleware constructor.
*/
public function __construct()
{
if(empty(env('APP_DEBUG'))) {
$this->reader = new CachedReader(
new AnnotationReader(),
new FilesystemCache(app()->storagePath()),
$debug = true);
} else {
$this->reader = new AnnotationReader();
}
AnnotationReader::addGlobalIgnoredName('dummy');
AnnotationReader::addGlobalIgnoredName('action');
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string $action
* @return mixed
*/
public function handle(Request $request, Closure $next, $action = null)
{
/** @var array $route */
$route = $request->route();
if (!empty($route) && is_array($route) && count($route) > 2) {
$uses = $route[1]['uses'];
if (!empty($uses) && !($uses instanceof Closure)) {
list($controller, $method) = explode('@', $uses);
$refMeth = new \ReflectionMethod($controller, $method);
$checkAction = $this->reader->getMethodAnnotation($refMeth, CheckAction::class);
if (!is_null($checkAction)) {
$user = Auth::user();
if ($user && !ActionService::allowForUser($checkAction->value, $user)) {
/** @var Request $request */
Log::alert('Access denied:', ['user' => Auth::user(), 'action' => $action, 'url' => $request->fullUrl()]);
return error2response(4, "Нет прав");
}
}
}
}
return $next($request);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment