diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Controllers/BaseController.php | 11 | ||||
-rw-r--r-- | src/Helpers/AuthenticatorServiceProvider.php | 1 | ||||
-rw-r--r-- | src/Http/Exceptions/HttpForbidden.php | 23 | ||||
-rw-r--r-- | src/Http/Request.php | 2 | ||||
-rw-r--r-- | src/Middleware/CallableHandler.php | 8 | ||||
-rw-r--r-- | src/Middleware/RequestHandler.php | 45 |
6 files changed, 89 insertions, 1 deletions
diff --git a/src/Controllers/BaseController.php b/src/Controllers/BaseController.php index 6a27a066..cbc00931 100644 --- a/src/Controllers/BaseController.php +++ b/src/Controllers/BaseController.php @@ -4,5 +4,16 @@ namespace Engelsystem\Controllers; abstract class BaseController { + /** @var string[]|string[][] A list of Permissions required to access the controller or certain pages */ + protected $permissions = []; + /** + * Returns the list of permissions + * + * @return string[]|string[][] + */ + public function getPermissions() + { + return $this->permissions; + } } diff --git a/src/Helpers/AuthenticatorServiceProvider.php b/src/Helpers/AuthenticatorServiceProvider.php index b7508b01..715a592f 100644 --- a/src/Helpers/AuthenticatorServiceProvider.php +++ b/src/Helpers/AuthenticatorServiceProvider.php @@ -13,5 +13,6 @@ class AuthenticatorServiceProvider extends ServiceProvider $this->app->instance(Authenticator::class, $authenticator); $this->app->instance('authenticator', $authenticator); + $this->app->instance('auth', $authenticator); } } diff --git a/src/Http/Exceptions/HttpForbidden.php b/src/Http/Exceptions/HttpForbidden.php new file mode 100644 index 00000000..01c0a5ec --- /dev/null +++ b/src/Http/Exceptions/HttpForbidden.php @@ -0,0 +1,23 @@ +<?php + +namespace Engelsystem\Http\Exceptions; + +use Throwable; + +class HttpForbidden extends HttpException +{ + /** + * @param string $message + * @param array $headers + * @param int $code + * @param Throwable|null $previous + */ + public function __construct( + string $message = '', + array $headers = [], + int $code = 0, + Throwable $previous = null + ) { + parent::__construct(403, $message, $headers, $code, $previous); + } +} diff --git a/src/Http/Request.php b/src/Http/Request.php index 0d8d28b4..06900a18 100644 --- a/src/Http/Request.php +++ b/src/Http/Request.php @@ -363,7 +363,7 @@ class Request extends SymfonyRequest implements ServerRequestInterface foreach ($uploadedFiles as $file) { /** @var UploadedFileInterface $file */ $filename = tempnam(sys_get_temp_dir(), 'upload'); - $handle = fopen($filename, "w"); + $handle = fopen($filename, 'w'); fwrite($handle, $file->getStream()->getContents()); fclose($handle); diff --git a/src/Middleware/CallableHandler.php b/src/Middleware/CallableHandler.php index eb493bf1..0bb666a3 100644 --- a/src/Middleware/CallableHandler.php +++ b/src/Middleware/CallableHandler.php @@ -74,4 +74,12 @@ class CallableHandler implements MiddlewareInterface, RequestHandlerInterface $response = $this->container->get('response'); return $response->withContent($return); } + + /** + * @return callable + */ + public function getCallable() + { + return $this->callable; + } } diff --git a/src/Middleware/RequestHandler.php b/src/Middleware/RequestHandler.php index ebe1ff9e..b0fc664f 100644 --- a/src/Middleware/RequestHandler.php +++ b/src/Middleware/RequestHandler.php @@ -3,6 +3,9 @@ namespace Engelsystem\Middleware; use Engelsystem\Application; +use Engelsystem\Controllers\BaseController; +use Engelsystem\Helpers\Authenticator; +use Engelsystem\Http\Exceptions\HttpForbidden; use InvalidArgumentException; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; @@ -37,6 +40,14 @@ class RequestHandler implements MiddlewareInterface $requestHandler = $request->getAttribute('route-request-handler'); $requestHandler = $this->resolveRequestHandler($requestHandler); + if ($requestHandler instanceof CallableHandler) { + $callable = $requestHandler->getCallable(); + + if (is_array($callable) && $callable[0] instanceof BaseController) { + $this->checkPermissions($callable[0], $callable[1]); + } + } + if ($requestHandler instanceof MiddlewareInterface) { return $requestHandler->process($request, $handler); } @@ -49,6 +60,8 @@ class RequestHandler implements MiddlewareInterface } /** + * Resolve the given class + * * @param string|callable|MiddlewareInterface|RequestHandlerInterface $handler * @return MiddlewareInterface|RequestHandlerInterface */ @@ -76,4 +89,36 @@ class RequestHandler implements MiddlewareInterface return $this->resolveMiddleware($handler); } + + /** + * Check required page permissions + * + * @param BaseController $controller + * @param string $method + * @return bool + */ + protected function checkPermissions(BaseController $controller, string $method): bool + { + /** @var Authenticator $auth */ + $auth = $this->container->get('auth'); + $permissions = $controller->getPermissions(); + + // Merge action permissions + if (isset($permissions[$method])) { + $permissions = array_merge($permissions, (array)$permissions[$method]); + } + + foreach ($permissions as $key => $permission) { + // Skip all action permission entries + if (!is_int($key)) { + continue; + } + + if (!$auth->can($permission)) { + throw new HttpForbidden(); + } + } + + return true; + } } |