diff --git a/meta/i18n/en/lean.error.json b/meta/i18n/en/lean.error.json index dbb3be1..00bbbe7 100644 --- a/meta/i18n/en/lean.error.json +++ b/meta/i18n/en/lean.error.json @@ -5,5 +5,12 @@ "subtitle": "You may have followed an invalid or expired link...", "message": "It seems like an error occured on the link you visited / action you tried. A notification was sent to the application's developer.", "back": "Return to previous page" + }, + "500": { + "title": "An error occured", + "page-title": "500 - An error occured", + "subtitle": "L'action que vous avez tenté d'effectué semble avoir échoué.", + "message": "Un message d'erreur a été envoyé au développeur de cette application.", + "back": "Revenir à la page précédente" } } \ No newline at end of file diff --git a/meta/i18n/fr/lean.error.json b/meta/i18n/fr/lean.error.json index 96329fe..04021b7 100644 --- a/meta/i18n/fr/lean.error.json +++ b/meta/i18n/fr/lean.error.json @@ -1,4 +1,11 @@ { + "401": { + "title": "Accès refusé", + "page-title": "401 - Accès refusé ", + "subtitle": "Vous n'avez pas les droits nécessaire pour consulter ce lien...", + "message": "Vous avez tentez d'accéder un lien qui ne vous est pas permis ou dont la permission ne vous a pas été accordé.", + "back": "Revenir à la page précédente" + }, "404": { "title": "Page introuvable", "page-title": "404 - Page introuvable", diff --git a/skeleton/meta/definitions/auth.php b/skeleton/meta/definitions/auth.php index aa5a32e..39f0859 100644 --- a/skeleton/meta/definitions/auth.php +++ b/skeleton/meta/definitions/auth.php @@ -24,7 +24,7 @@ return [ SecurityHandler::class => create(SecurityHandler::class)->constructor(function() { return new RedirectResponse(getenv("URL_BASE")."/connexion"); - }), + }, get('authentication.unauthorize')), 'authentication.error' => function($c, Picea $picea) { return function($message) use ($picea) { @@ -36,6 +36,16 @@ return [ }; }, + 'authentication.unauthorize' => function($c, Picea $picea) { + return function($message) use ($picea) { + return new HtmlResponse($picea->renderHtml('lean/error/401', [ + 'title' => "", + 'subtitle' => "", + 'message' => $message, + ])); + }; + }, + EmailConfiguration::class => function($c) { $email = new EmailConfiguration( EmailConfiguration::AUTH_TYPE_SMTP ); $email->smtpHost = getenv('SMTP_HOST'); diff --git a/skeleton/var/cache/.gitkeep b/skeleton/var/cache/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/skeleton/var/logs/.gitkeep b/skeleton/var/logs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/ControllerTrait.php b/src/ControllerTrait.php index e6f554c..785db8d 100644 --- a/src/ControllerTrait.php +++ b/src/ControllerTrait.php @@ -10,7 +10,7 @@ use Picea, use Psr\Http\Message\ServerRequestInterface; use Storage\Session; -use Laminas\Diactoros\Response\{ HtmlResponse, TextResponse, RedirectResponse, JsonResponse }; +use Laminas\Diactoros\Response\{ HtmlResponse, TextResponse, RedirectResponse, JsonResponse, EmptyResponse }; use Ulmus\EntityCollection; @@ -21,12 +21,13 @@ use TheBugs\Email\MailerInterface; use Notes\Route\Annotation\Object\Route as RouteParam, Notes\Route\Annotation\Method\Route, Notes\Security\Annotation\Security, + Notes\Security\Annotation\Taxus, Notes\Tell\Annotation\Language; use function file_get_contents; /** - * @Security("locked" => false) + * @Security("locked" => true) * @RouteParam("methods" => [ "GET", "POST", "DELETE" ]) */ trait ControllerTrait { @@ -68,9 +69,9 @@ trait ControllerTrait { return new RedirectResponse($url, $code, $headers); } - public function renderPdf($rawdata, int $status = 200, array $headers = []) : PdfResponse + public static function renderNothing(int $code = 204, array $headers = []) : ResponseInterface { - return new PdfResponse($rawdata, $status, $headers); + return new EmptyResponse($code, $headers); } public static function renderText(string $text, int $code = 200, array $headers = []) : ResponseInterface @@ -88,6 +89,11 @@ trait ControllerTrait { return new JsonResponse($data, $code, $headers); } + public function renderPdf($rawdata, int $status = 200, array $headers = []) : PdfResponse + { + return new PdfResponse($rawdata, $status, $headers); + } + public static function renderDownloadable(string $data, string $filename, int $code = 200, array $headers = []) : ResponseInterface { return new DownloadResponse($data, $filename, $code, $headers); diff --git a/src/Kernel.php b/src/Kernel.php index 09d69a7..5a313dd 100644 --- a/src/Kernel.php +++ b/src/Kernel.php @@ -58,19 +58,25 @@ class Kernel { // Environment vars (accessible from \DI\env(), getenv(), $_ENV and $_SERVER) Dotenv::create(getenv("PROJECT_PATH"))->load(); - // Paths and directories - foreach($this->paths as $name => $envkey) { - if ( ! getenv($name) ) { - static::putenv($name, realpath(getenv("PROJECT_PATH") . DIRECTORY_SEPARATOR . getenv($envkey))); - } - } - // Override using headers foreach(['APP_ENV', 'DEBUG', ] as $env) { if ( null !== $value = $_SERVER["HTTP_$env"] ?? null ) { static::putenv($env, $value); } } + + // Paths and directories + foreach($this->paths as $name => $envkey) { + if ( ! getenv($name) ) { + $path = getenv("PROJECT_PATH") . DIRECTORY_SEPARATOR . getenv($envkey); + + if (getenv('DEBUG') && ! file_exists($path)) { + mkdir($path, 0755, true); + } + + static::putenv($name, realpath($path)); + } + } } protected function initializeEngine() : self @@ -81,6 +87,10 @@ class Kernel { setlocale(LC_ALL, $this->locale = getenv("DEFAULT_LOCAL")); setlocale(LC_TIME, getenv("DEFAULT_TIME"), getenv("DEFAULT_TIME_FALLBACK")); + if ( class_exists('Locale') ) { + \Locale::setDefault($this->locale); + } + ini_set("log_errors", "1"); ini_set("error_log", $this->errorLogPath); ini_set('display_errors', getenv("DEBUG") ? 'on' : 'on'); diff --git a/src/Routing.php b/src/Routing.php index 01f863b..5069831 100644 --- a/src/Routing.php +++ b/src/Routing.php @@ -2,7 +2,7 @@ namespace Lean; -use function DI\autowire, DI\create; +use Taxus\Taxus; use League\Route\RouteGroup, League\Route\Router; @@ -23,6 +23,8 @@ use Picea\Picea, use Storage\Cookie, Storage\Session; +use function DI\autowire, DI\create; + class Routing { protected Session $session; @@ -37,6 +39,8 @@ class Routing { protected LanguageHandler $language; + protected Taxus $taxus; + public function __construct( Session $session, Cookie $cookie, @@ -44,7 +48,8 @@ class Routing { Router $router, RouteFetcher $routeFetcher, SecurityHandler $security, - LanguageHandler $language + LanguageHandler $language, + Taxus $taxus ) { $this->session = $session; @@ -54,6 +59,7 @@ class Routing { $this->security = $security; $this->language = $language; $this->router = $router; + $this->taxus = $taxus; } public function registerRoute(ContainerInterface $container, string $urlBase) { @@ -84,12 +90,16 @@ class Routing { $object = $container->get($class); # Checking if user needs to be logged - if ( ! $object->user->logged && ( $redirect = $this->security->verify($class, $method) ) ) { + if ( ( $redirect = $this->security->verify($class, $method) ) && ( empty($object->user) || ! $object->user->logged ) ) { $this->session->redirectedFrom = (string) $request->getUri(); return $redirect; } + if ( $forbidden = $this->security->taxus($class, $method, $object->user) ) { + return $forbidden; + } + if ( $container->has(Picea::class) ) { $container->get(Picea::class)->globalVariables['route'] = $annotation; } diff --git a/view/lean/error/401.phtml b/view/lean/error/401.phtml new file mode 100644 index 0000000..f421d07 --- /dev/null +++ b/view/lean/error/401.phtml @@ -0,0 +1,26 @@ +{% extends "lean/layout/error" %} + +{% language.set "lean.error.401" %} + +{% title _('page-title') %} + +{% section "content-right" %} +
+
{% _ "title" %}
+
{% _ "subtitle" %}
+
{% _ "message" %}
+ {% _ "back" %} +
+{% endsection %} + +{% section "content-left" %} +
+ {% view "lean/picto/undraw_forbidden" %} +
+{% endsection %} + +{% section "head.css" %} + .title {font-size:2rem} + .subtitle {font-size:1.25rem; padding-top: 1rem;} + .content {padding-top:1rem} +{% endsection %} diff --git a/view/lean/error/404.phtml b/view/lean/error/404.phtml index e2984e0..fdcc1f4 100644 --- a/view/lean/error/404.phtml +++ b/view/lean/error/404.phtml @@ -14,7 +14,9 @@ {% endsection %} {% section "content-left" %} - +
+ {% view "lean/picto/undraw_lost" %} +
{% endsection %} {% section "head.css" %} diff --git a/view/lean/error/500.phtml b/view/lean/error/500.phtml index 2e531e4..dc5c150 100644 --- a/view/lean/error/500.phtml +++ b/view/lean/error/500.phtml @@ -14,7 +14,9 @@ {% endsection %} {% section "content-left" %} - +
+ {% view "lean/picto/undraw_error" %} +
{% endsection %} {% section "head.css" %} diff --git a/view/lean/layout/error.phtml b/view/lean/layout/error.phtml index c3f8de6..1ba919b 100644 --- a/view/lean/layout/error.phtml +++ b/view/lean/layout/error.phtml @@ -20,7 +20,7 @@ #wrapper-content .content-left {background:#ffffff;padding:5vh 2vw;border-radius:0 6px 6px 0;display:flex;align-items:center;justify-content: center} .form-user-login {width:80%;} - .picto-login {max-width:80%;} + .picto-login svg {max-width:100%;} {% section "head.css" %}{% endsection %} diff --git a/view/lean/picto/undraw_error.phtml b/view/lean/picto/undraw_error.phtml new file mode 100644 index 0000000..4e74be9 --- /dev/null +++ b/view/lean/picto/undraw_error.phtml @@ -0,0 +1 @@ +bug fixing \ No newline at end of file diff --git a/view/lean/picto/undraw_forbidden.phtml b/view/lean/picto/undraw_forbidden.phtml new file mode 100644 index 0000000..c8a514c --- /dev/null +++ b/view/lean/picto/undraw_forbidden.phtml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/view/lean/picto/undraw_lost.phtml b/view/lean/picto/undraw_lost.phtml new file mode 100644 index 0000000..a16a792 --- /dev/null +++ b/view/lean/picto/undraw_lost.phtml @@ -0,0 +1 @@ + \ No newline at end of file