diff --git a/README.md b/README.md index cf57d8c..1289587 100644 --- a/README.md +++ b/README.md @@ -13,13 +13,7 @@ It has its own router component and is heavily inspired by [Symfony](https://sym 2. Configure your web server so that its root directory is `/public` and the fallback resource is `index.php`. -3. Make sure the timezone is set in your PHP configuration, or else the Session component will misbehave: -``` -[Date] -date.timezone = UTC -``` - -4. Create `/config/pdo.ini` with the following lines to configure database connection details: +3. Create `/config/pdo.ini` with the following lines to configure database connection details: ``` driver = mysql host = localhost @@ -31,7 +25,7 @@ username = example password = example ``` -5. Add routes in the file `/config/routes.xml` and start building your first controller at `/src/Controller/`. You can also try our [Fragments application](https://github.com/o-alquimista/fragments-app) to get an idea of how things work. +4. Add routes in the file `/config/routes.xml` and start building your first controller at `/src/Controller/`. You can also try our [Fragments application](https://github.com/o-alquimista/fragments-app) to get an idea of how things work. ## License Copyright 2019-2020 Douglas Silva (0x9fd287d56ec107ac) diff --git a/src/Fragments/Component/CsrfTokenManager.php b/src/Fragments/Component/CsrfTokenManager.php index d1f2632..2385eff 100644 --- a/src/Fragments/Component/CsrfTokenManager.php +++ b/src/Fragments/Component/CsrfTokenManager.php @@ -21,7 +21,6 @@ namespace Fragments\Component; -use Fragments\Component\SessionManagement\Session; use Fragments\Bundle\Exception\AccessDeniedHttpException; /** @@ -31,13 +30,6 @@ class CsrfTokenManager { private const PREFIX = '_csrf/'; - private $session; - - public function __construct() - { - $this->session = new Session; - } - /** * Get a new CSRF token. * @@ -47,12 +39,12 @@ public function getToken(string $id): string { $tokenName = self::PREFIX . $id; - if ($this->session->exists($tokenName)) { - return $this->session->get($tokenName); + if (isset($_SESSION[$tokenName])) { + return $_SESSION[$tokenName]; } $value = $this->generate(); - $this->session->set($tokenName, $value); + $_SESSION[$tokenName] = $value; return $value; } @@ -64,11 +56,11 @@ public function isTokenValid(string $tokenReceived, string $targetId): bool { $targetId = self::PREFIX . $targetId; - if (false === $this->session->exists($targetId)) { + if (!isset($_SESSION[$targetId])) { throw new AccessDeniedHttpException('The CSRF token identifier could not be found.'); } - $tokenStored = $this->session->get($targetId); + $tokenStored = $_SESSION[$targetId]; $tokenValid = hash_equals($tokenStored, $tokenReceived); if ($tokenValid) { diff --git a/src/Fragments/Component/Feedback.php b/src/Fragments/Component/Feedback.php index ebc41f0..9e13f53 100644 --- a/src/Fragments/Component/Feedback.php +++ b/src/Fragments/Component/Feedback.php @@ -21,21 +21,15 @@ namespace Fragments\Component; -use Fragments\Component\SessionManagement\Session; - class Feedback { - private const BAG_NAME = 'feedbackBag'; - - private $session; + const BAG_NAME = 'feedbackBag'; public function __construct() { - $this->session = new Session; - // If the bag doesn't exist yet, create it - if (false === $this->session->exists(self::BAG_NAME)) { - $this->session->set(self::BAG_NAME, []); + if (false === isset($_SESSION[self::BAG_NAME])) { + $_SESSION[self::BAG_NAME] = []; } } @@ -44,9 +38,9 @@ public function __construct() */ public function add(string $type, string $message) { - $bag = $this->session->get(self::BAG_NAME); + $bag = $_SESSION[self::BAG_NAME]; $bag[$type][] = $message; - $this->session->set(self::BAG_NAME, $bag); + $_SESSION[self::BAG_NAME] = $bag; } /** @@ -54,8 +48,8 @@ public function add(string $type, string $message) */ public function get(): array { - $bag = $this->session->get(self::BAG_NAME); - $this->session->set(self::BAG_NAME, []); + $bag = $_SESSION[self::BAG_NAME]; + $_SESSION[self::BAG_NAME] = []; return $bag; } diff --git a/src/Fragments/Component/SessionManagement/Init/AbstractSessionInit.php b/src/Fragments/Component/SessionManagement/Init/AbstractSessionInit.php deleted file mode 100644 index d190398..0000000 --- a/src/Fragments/Component/SessionManagement/Init/AbstractSessionInit.php +++ /dev/null @@ -1,49 +0,0 @@ -. - */ - -namespace Fragments\Component\SessionManagement\Init; - -/** - * Session initialization - * - * Important: This is only meant to be used within the - * Session Utility. To start a new session at the - * controllers, refer to the Session class in this file. - */ -abstract class AbstractSessionInit -{ - protected $options = array( - 'use_only_cookies' => 1, - 'use_trans_sid' => 0, - 'cookie_httponly' => 1, - ); - - public function __construct() - { - if (version_compare(phpversion(), '7.3.0', '>')) { - // Helps prevent CSRF attacks - $this->options['cookie_samesite'] = 'Lax'; - } - - // 'cookie_secure' requires SSL to be configured - // $this->options['cookie_secure'] = 1; - } -} diff --git a/src/Fragments/Component/SessionManagement/Init/SessionStrict.php b/src/Fragments/Component/SessionManagement/Init/SessionStrict.php deleted file mode 100644 index 8aba3be..0000000 --- a/src/Fragments/Component/SessionManagement/Init/SessionStrict.php +++ /dev/null @@ -1,35 +0,0 @@ -. - */ - -namespace Fragments\Component\SessionManagement\Init; - -use Fragments\Bundle\Exception\ServerErrorHttpException; - -class SessionStrict extends AbstractSessionInit -{ - public function init() - { - $this->options['use_strict_mode'] = 1; - if (!session_start($this->options)) { - throw new ServerErrorHttpException('Failed to start the session.'); - } - } -} diff --git a/src/Fragments/Component/SessionManagement/Init/SessionUnsafe.php b/src/Fragments/Component/SessionManagement/Init/SessionUnsafe.php deleted file mode 100644 index 0f52eb5..0000000 --- a/src/Fragments/Component/SessionManagement/Init/SessionUnsafe.php +++ /dev/null @@ -1,35 +0,0 @@ -. - */ - -namespace Fragments\Component\SessionManagement\Init; - -use Fragments\Bundle\Exception\ServerErrorHttpException; - -class SessionUnsafe extends AbstractSessionInit -{ - public function init() - { - $this->options['use_strict_mode'] = 0; - if (!session_start($this->options)) { - throw new ServerErrorHttpException('Failed to start the session.'); - } - } -} diff --git a/src/Fragments/Component/SessionManagement/Session.php b/src/Fragments/Component/SessionManagement/Session.php deleted file mode 100644 index 8f53a9c..0000000 --- a/src/Fragments/Component/SessionManagement/Session.php +++ /dev/null @@ -1,190 +0,0 @@ -. - */ - -namespace Fragments\Component\SessionManagement; - -use Fragments\Component\SessionManagement\Init\SessionStrict; -use Fragments\Component\SessionManagement\Init\SessionUnsafe; -use Fragments\Bundle\Exception\AccessDeniedHttpException; - -/** - * Session Utility. - * - * Handles starting a session and regenerating - * a new session ID while attempting to avoid - * lost sessions due to unstable connections. - * - * If the session contains the flag 'session_obsolete', - * we will check if it has expired. If it has, - * all session variables will be wiped and a session - * expired exception will be thrown. - * - * If it hasn't expired yet, an attempt to reset the - * newly generated ID will be made. - */ -class Session -{ - private $sessionStrict; - - private $sessionUnsafe; - - public function __construct() - { - $this->sessionStrict = new SessionStrict; - $this->sessionUnsafe = new SessionUnsafe; - } - - public function start() - { - if (session_status() == PHP_SESSION_ACTIVE) { - return; - } - - $this->sessionStrict->init(); - - // If 'session_obsolete' is set, check if it's expired next - if (false === $this->exists('session_obsolete')) { - return; - } - - /* - * The timestamp of the moment that the session ID is regenerated, - * used to determine the right moment to destroy an obsolete session. - */ - $obsoleteTime = $this->get('session_obsolete'); - - /* - * Wipes all session variables if the flag 'session_obsolete' has - * been set for more than 5 minutes. - */ - if ($obsoleteTime < time() - 300) { - $this->destroyAll(); - - throw new AccessDeniedHttpException('The session has expired.'); - } - - /* - * If the session variable 'new_session_id' exists, - * attempt to restart the session with it. - */ - if (false === $this->exists('new_session_id')) { - return; - } - - $newSessionId = $this->get('new_session_id'); - - session_commit(); - session_id($newSessionId); - - $this->sessionStrict->init(); - } - - public function regenerate() - { - // Cannot regenerate the ID of an inactive session - if (session_status() !== PHP_SESSION_ACTIVE) { - return; - } - - $newID = session_create_id(); - $this->set('new_session_id', $newID); - - /* - * We mark the current session ID with 'session_obsolete' - * and store the current timestamp in this - * session variable, so we can count the time - * until this session expires. - */ - $this->set('session_obsolete', time()); - - session_commit(); - - /* - * Set session ID to the one we generated (uninitialized) - */ - session_id($newID); - - /* - * The session must be started with strict_mode disabled, - * closed and then started again with strict_mode enabled. - * - * This ensures the new session ID is initialized and accepted. - */ - $this->sessionUnsafe->init(); - session_commit(); - $this->sessionStrict->init(); - - /* - * Remove leftover session variables from the ID regeneration process. - */ - $this->destroy('session_obsolete'); - $this->destroy('new_session_id'); - } - - public function get(string $key, $default = null) - { - $this->start(); - - if ($this->exists($key)) { - return $_SESSION[$key]; - } - - return $default; - } - - public function set(string $key, $value) - { - $this->start(); - - $_SESSION[$key] = $value; - } - - public function exists(string $key): bool - { - $this->start(); - - if (array_key_exists($key, $_SESSION)) { - return true; - } - - return false; - } - - /** - * Unset the specified session variable. - */ - public function destroy(string $key) - { - $this->start(); - - unset($_SESSION[$key]); - } - - /** - * Wipe all session variables. - */ - public function destroyAll() - { - $this->start(); - - $_SESSION = []; - } -} diff --git a/src/Fragments/Component/TemplateHelper.php b/src/Fragments/Component/TemplateHelper.php index 3851011..192a657 100644 --- a/src/Fragments/Component/TemplateHelper.php +++ b/src/Fragments/Component/TemplateHelper.php @@ -24,7 +24,6 @@ use Fragments\Component\Feedback; use Fragments\Component\CsrfTokenManager; use Fragments\Component\Request; -use Fragments\Component\SessionManagement\Session; use Fragments\Component\Routing\Router; class TemplateHelper { @@ -58,11 +57,6 @@ public function getCsrfToken(string $id): string return $token; } - public function getSession(): Session - { - return new Session; - } - public function getRequest(): Request { return new Request; @@ -89,9 +83,7 @@ public function generateUrl(string $routeId, array $parameters = []): string public function isAuthenticated(): bool { - $session = new Session(); - - if ($session->exists('user')) { + if (isset($_SESSION['user'])) { return true; }