Implement canAny handling for controllers

This commit is contained in:
Igor Scheller 2024-04-07 19:26:56 +02:00 committed by xuwhite
parent a214e0ff8f
commit 87f7a74f27
2 changed files with 60 additions and 3 deletions

View File

@ -8,6 +8,7 @@ use Engelsystem\Application;
use Engelsystem\Controllers\BaseController; use Engelsystem\Controllers\BaseController;
use Engelsystem\Helpers\Authenticator; use Engelsystem\Helpers\Authenticator;
use Engelsystem\Http\Exceptions\HttpForbidden; use Engelsystem\Http\Exceptions\HttpForbidden;
use Illuminate\Support\Str;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\MiddlewareInterface;
@ -103,10 +104,16 @@ class RequestHandler implements MiddlewareInterface
continue; continue;
} }
if (!$auth->can($permission)) { foreach ((array) $permission as $value) {
if (
Str::contains($value, '||')
? !$auth->canAny(explode('||', $value))
: !$auth->can($permission)
) {
throw new HttpForbidden(); throw new HttpForbidden();
} }
} }
}
return true; return true;
} }

View File

@ -7,11 +7,13 @@ namespace Engelsystem\Test\Unit\Middleware;
use Engelsystem\Application; use Engelsystem\Application;
use Engelsystem\Helpers\Authenticator; use Engelsystem\Helpers\Authenticator;
use Engelsystem\Http\Exceptions\HttpForbidden; use Engelsystem\Http\Exceptions\HttpForbidden;
use Engelsystem\Http\Request;
use Engelsystem\Http\Response;
use Engelsystem\Middleware\CallableHandler; use Engelsystem\Middleware\CallableHandler;
use Engelsystem\Middleware\RequestHandler; use Engelsystem\Middleware\RequestHandler;
use Engelsystem\Test\Unit\Middleware\Stub\ControllerImplementation; use Engelsystem\Test\Unit\Middleware\Stub\ControllerImplementation;
use Engelsystem\Test\Unit\TestCase;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\MiddlewareInterface;
@ -212,6 +214,54 @@ class RequestHandlerTest extends TestCase
$middleware->process($request, $handler); $middleware->process($request, $handler);
} }
/**
* @covers \Engelsystem\Middleware\RequestHandler::checkPermissions
*/
public function testCheckPermissionsAnyForbidden(): void
{
/** @var RequestHandlerInterface|MockObject $handler */
list(, , $handler) = $this->getMocks();
$this->app->instance('response', new Response());
/** @var Authenticator|MockObject $auth */
$auth = $this->createMock(Authenticator::class);
$this->setExpects($auth, 'canAny', [['foo', 'bar', 'baz']], false);
$this->app->instance('auth', $auth);
$controller = new ControllerImplementation();
$request = (new Request())
->withAttribute('route-request-handler', [$controller, 'actionStub']);
$middleware = new RequestHandler($this->app);
$controller->setPermissions(['foo||bar||baz']);
$this->expectException(HttpForbidden::class);
$middleware->process($request, $handler);
}
/**
* @covers \Engelsystem\Middleware\RequestHandler::checkPermissions
*/
public function testCheckPermissionsAny(): void
{
/** @var RequestHandlerInterface|MockObject $handler */
list(, , $handler) = $this->getMocks();
$this->app->instance('response', new Response());
/** @var Authenticator|MockObject $auth */
$auth = $this->createMock(Authenticator::class);
$this->setExpects($auth, 'canAny', [['foo', 'bar', 'baz']], true);
$this->app->instance('auth', $auth);
$controller = new ControllerImplementation();
$request = (new Request())
->withAttribute('route-request-handler', [$controller, 'actionStub']);
$middleware = new RequestHandler($this->app);
$controller->setPermissions(['actionStub' => 'foo||bar||baz']);
$response = $middleware->process($request, $handler);
$this->assertEquals(200, $response->getStatusCode());
}
protected function getMocks(): array protected function getMocks(): array
{ {
/** @var Application|MockObject $container */ /** @var Application|MockObject $container */