From 44a7e4a8df5296c544bdae0ed49b1113b1662336 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexandre=20G=C3=A9rault?= <alexandre@hexium.io>
Date: Sat, 29 May 2021 16:20:11 +0200
Subject: [PATCH 1/6] feat(auth): add interfaces

---
 .../Authentication/AuthenticatableInterface.php  | 15 +++++++++++++++
 .../AuthenticatableProviderInterface.php         |  8 ++++++++
 .../Authentication/AuthenticatorInterface.php    | 16 ++++++++++++++++
 .../AuthenticatableNotFoundException.php         |  9 +++++++++
 4 files changed, 48 insertions(+)
 create mode 100644 src/AGerault/Contracts/Authentication/AuthenticatableInterface.php
 create mode 100644 src/AGerault/Contracts/Authentication/AuthenticatableProviderInterface.php
 create mode 100644 src/AGerault/Contracts/Authentication/AuthenticatorInterface.php
 create mode 100644 src/AGerault/Contracts/Authentication/Exceptions/AuthenticatableNotFoundException.php

diff --git a/src/AGerault/Contracts/Authentication/AuthenticatableInterface.php b/src/AGerault/Contracts/Authentication/AuthenticatableInterface.php
new file mode 100644
index 0000000..345bb22
--- /dev/null
+++ b/src/AGerault/Contracts/Authentication/AuthenticatableInterface.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace AGerault\Framework\Contracts\Authentication;
+
+interface AuthenticatableInterface
+{
+    /**
+     * A unique identifier to fetch a user
+     */
+    public function key(): int|string;
+    
+    public function login(): string;
+    
+    public function password(): string;
+}
diff --git a/src/AGerault/Contracts/Authentication/AuthenticatableProviderInterface.php b/src/AGerault/Contracts/Authentication/AuthenticatableProviderInterface.php
new file mode 100644
index 0000000..4cf8a27
--- /dev/null
+++ b/src/AGerault/Contracts/Authentication/AuthenticatableProviderInterface.php
@@ -0,0 +1,8 @@
+<?php
+
+namespace AGerault\Framework\Contracts\Authentication;
+
+interface AuthenticatableProviderInterface
+{
+    public function fetch(string|int $key): AuthenticatableInterface;
+}
diff --git a/src/AGerault/Contracts/Authentication/AuthenticatorInterface.php b/src/AGerault/Contracts/Authentication/AuthenticatorInterface.php
new file mode 100644
index 0000000..e09802a
--- /dev/null
+++ b/src/AGerault/Contracts/Authentication/AuthenticatorInterface.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace AGerault\Framework\Contracts\Authentication;
+
+interface AuthenticatorInterface
+{
+    /**
+     * Check whether the credentials match for a given user
+     */
+    public function check(AuthenticatableInterface $authenticatable, array $credentials): bool;
+
+    /**
+     * Try to log in a given user based on credentials
+     */
+    public function attempt(AuthenticatableInterface $authenticatable, array $credentials): ?AuthenticatableInterface;
+}
diff --git a/src/AGerault/Contracts/Authentication/Exceptions/AuthenticatableNotFoundException.php b/src/AGerault/Contracts/Authentication/Exceptions/AuthenticatableNotFoundException.php
new file mode 100644
index 0000000..e2d1720
--- /dev/null
+++ b/src/AGerault/Contracts/Authentication/Exceptions/AuthenticatableNotFoundException.php
@@ -0,0 +1,9 @@
+<?php
+
+namespace AGerault\Framework\Contracts\Authentication\Exceptions;
+
+use Exception;
+
+class AuthenticatableNotFoundException extends Exception
+{
+}

From df425e6e076baa336a497392c1f711d6c728874b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexandre=20G=C3=A9rault?= <alexandre@hexium.io>
Date: Sat, 29 May 2021 16:21:03 +0200
Subject: [PATCH 2/6] feat: add session interface

---
 src/AGerault/Contracts/Session/SessionInterface.php | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/AGerault/Contracts/Session/SessionInterface.php b/src/AGerault/Contracts/Session/SessionInterface.php
index 18698f8..fdf78c7 100755
--- a/src/AGerault/Contracts/Session/SessionInterface.php
+++ b/src/AGerault/Contracts/Session/SessionInterface.php
@@ -4,5 +4,13 @@
 
 interface SessionInterface
 {
+    public function has(string $key): bool;
 
+    public function get(string $key): mixed;
+
+    public function put(string $key, mixed $payload): void;
+
+    public function clear(): void;
+
+    public function forget(string $key): void;
 }

From 8fa82ad29a3740a28d175b86901a5dbee510062e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexandre=20G=C3=A9rault?= <alexandre@hexium.io>
Date: Sat, 29 May 2021 19:43:59 +0200
Subject: [PATCH 3/6] feat: add session class

---
 src/AGerault/Session/Session.php | 38 ++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)
 create mode 100644 src/AGerault/Session/Session.php

diff --git a/src/AGerault/Session/Session.php b/src/AGerault/Session/Session.php
new file mode 100644
index 0000000..95d26a4
--- /dev/null
+++ b/src/AGerault/Session/Session.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace AGerault\Framework\Session;
+
+use AGerault\Framework\Contracts\Session\SessionInterface;
+
+class Session implements SessionInterface
+{
+    public function __construct()
+    {
+        session_start();
+    }
+
+    public function has(string $key): bool
+    {
+        return isset($_SESSION[$key]);
+    }
+
+    public function get(string $key): mixed
+    {
+        return $_SESSION[$key] ?? null;
+    }
+
+    public function put(string $key, mixed $payload): void
+    {
+        $_SESSION[$key] = $payload;
+    }
+
+    public function clear(): void
+    {
+        session_destroy();
+    }
+
+    public function forget(string $key): void
+    {
+        unset($_SESSION[$key]);
+    }
+}

From d2c4b68cb649e252eca8a6e6465e5814ad40a764 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexandre=20G=C3=A9rault?= <alexandre@hexium.io>
Date: Sat, 29 May 2021 19:44:27 +0200
Subject: [PATCH 4/6] feat(auth): add authenticator implementation

---
 src/AGerault/Authentication/Authenticator.php | 22 +++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 src/AGerault/Authentication/Authenticator.php

diff --git a/src/AGerault/Authentication/Authenticator.php b/src/AGerault/Authentication/Authenticator.php
new file mode 100644
index 0000000..d5196ce
--- /dev/null
+++ b/src/AGerault/Authentication/Authenticator.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace AGerault\Framework\Authentication;
+
+use AGerault\Framework\Contracts\Authentication\AuthenticatableInterface;
+use AGerault\Framework\Contracts\Authentication\AuthenticatorInterface;
+
+class Authenticator implements AuthenticatorInterface
+{
+
+    public function check(AuthenticatableInterface $authenticatable, array $credentials): bool
+    {
+        return true;
+    }
+
+    public function attempt(AuthenticatableInterface $authenticatable, array $credentials): ?AuthenticatableInterface
+    {
+        return $credentials['login'] === $authenticatable->login()
+               && password_verify($credentials['password'], $authenticatable->password()) ? $authenticatable : null;
+    }
+
+}

From 390400d7ecec875cdcdc6c5ae2c8f8e87e35b992 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexandre=20G=C3=A9rault?= <alexandre@hexium.io>
Date: Mon, 31 May 2021 09:23:58 +0200
Subject: [PATCH 5/6] refactor(container): call factory only in resolve

---
 src/AGerault/Services/ServiceContainer.php | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/src/AGerault/Services/ServiceContainer.php b/src/AGerault/Services/ServiceContainer.php
index fc11617..4ca3fa8 100755
--- a/src/AGerault/Services/ServiceContainer.php
+++ b/src/AGerault/Services/ServiceContainer.php
@@ -58,11 +58,6 @@ class ServiceContainer implements ServiceContainerInterface
      */
     public function get(string $id): mixed
     {
-        // If we have no instances of this id, let's build one
-        if (array_key_exists($id, $this->factories)) {
-            return call_user_func($this->factories[$id]);
-        }
-
         if (!$this->has($id)) {
             $instance = $this->resolve($id);
 
@@ -217,6 +212,10 @@ private function resolve(string $id): object
 
         $this->getDefinition($id);
 
+        if (array_key_exists($id, $this->factories)) {
+            return call_user_func($this->factories[$id]);
+        }
+
         // If the constructor of the class is null, no dependencies are required
         if ($reflectionClass->getConstructor() === null) {
             return $reflectionClass->newInstance();

From e6baf8c576ae2d292a8cc663bd07fc2979cc94ef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexandre=20G=C3=A9rault?= <alexandre@hexium.io>
Date: Mon, 14 Jun 2021 12:44:36 +0200
Subject: [PATCH 6/6] style: remove blank line

---
 src/AGerault/Core/HttpRequestHandler.php | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/AGerault/Core/HttpRequestHandler.php b/src/AGerault/Core/HttpRequestHandler.php
index e0592a1..64a5c4f 100644
--- a/src/AGerault/Core/HttpRequestHandler.php
+++ b/src/AGerault/Core/HttpRequestHandler.php
@@ -16,7 +16,6 @@ public function __construct(UrlMatcherInterface $matcher)
         $this->matcher = $matcher;
     }
 
-
     public function handle(ServerRequestInterface $request): ResponseInterface
     {
             $route = $this->matcher->match(