Ver código fonte

stabilize interfaces and improve handler contract

michelphp 23 horas atrás
pai
commit
04bb7cc6cc

+ 2 - 2
README.md

@@ -33,13 +33,13 @@ Then, create a provider implementing `Michel\Auth\UserProviderInterface` to fetc
 Set up form authentication for your web application.
 
 ```php
-use Michel\Auth\Handler\FormAuthHandler;
+use Michel\Auth\Handler\FormAuthAuthHandler;
 use Michel\Auth\Middlewares\AuthMiddleware;
 
 // $userProvider = new YourUserProvider();
 // $sessionStorage = new YourSessionStorage();
 
-$formHandler = new FormAuthHandler($userProvider, $sessionStorage, [
+$formHandler = new FormAuthAuthHandler($userProvider, $sessionStorage, [
     'login_path' => '/login',
     'login_key' => 'email',
     'password_key' => 'password',

+ 0 - 1
src/AuthIdentity.php

@@ -12,7 +12,6 @@ final class AuthIdentity
         bool          $isNewLogin = false
     )
     {
-
         $this->user = $user;
         $this->isNewLogin = $isNewLogin;
     }

+ 2 - 1
src/AuthHandlerInterface.php → src/Handler/AuthHandlerInterface.php

@@ -1,7 +1,8 @@
 <?php
 
-namespace Michel\Auth;
+namespace Michel\Auth\Handler;
 
+use Michel\Auth\AuthIdentity;
 use Michel\Auth\Exception\AuthenticationException;
 use Psr\Http\Message\ResponseFactoryInterface;
 use Psr\Http\Message\ResponseInterface;

+ 11 - 4
src/Handler/FormAuthHandler.php → src/Handler/FormAuthAuthHandler.php

@@ -2,7 +2,6 @@
 
 namespace Michel\Auth\Handler;
 
-use Michel\Auth\AuthHandlerInterface;
 use Michel\Auth\AuthIdentity;
 use Michel\Auth\Exception\AuthenticationException;
 use Michel\Auth\Exception\InvalidCredentialsException;
@@ -17,7 +16,7 @@ use Psr\Http\Message\ResponseFactoryInterface;
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
 
-class FormAuthHandler implements AuthHandlerInterface
+class FormAuthAuthHandler implements AuthHandlerInterface, StatefulAuthHandlerInterface
 {
     public const AUTHENTICATION_ERROR = '_form.last_error';
     public const LAST_USERNAME = '_form.last_username';
@@ -27,6 +26,7 @@ class FormAuthHandler implements AuthHandlerInterface
     private string $loginPath;
     private string $loginKey;
     private string $passwordKey;
+    private string $targetPath;
 
     /**
      * @var callable
@@ -46,6 +46,7 @@ class FormAuthHandler implements AuthHandlerInterface
             Option::string('login_path', '/login')->min(1),
             Option::string('login_key', 'login')->min(1),
             Option::string('password_key', 'password')->min(1),
+            Option::string('target_path', '/')->min(1),
             Option::mixed('on_failure')->validator(function ($value) {
                 return is_callable($value) || $value === null;
             })->setOptional(null),
@@ -55,6 +56,7 @@ class FormAuthHandler implements AuthHandlerInterface
         $this->loginPath = '/'.ltrim($options['login_path'], '/');
         $this->loginKey = $options['login_key'];
         $this->passwordKey = $options['password_key'];
+        $this->targetPath = '/'.ltrim($options['target_path'], '/');
         $this->onFailure = $options['on_failure'];
     }
 
@@ -106,7 +108,7 @@ class FormAuthHandler implements AuthHandlerInterface
             throw new AuthenticationException("The resolved user does not support password authentication.");
         }
 
-        if (!$this->userProvider->checkPassword($user, $password)) {
+        if (!$this->userProvider->isPasswordValid($user, $password)) {
             throw new InvalidCredentialsException("Invalid username or password.");
         }
 
@@ -114,6 +116,12 @@ class FormAuthHandler implements AuthHandlerInterface
         return new AuthIdentity($user,  true);
     }
 
+    public function onSuccess(ServerRequestInterface $request, ResponseFactoryInterface $responseFactory): ?ResponseInterface
+    {
+        $response = $responseFactory->createResponse(302);
+        return $response->withHeader('Location', $this->targetPath);
+    }
+
     public function onFailure(ServerRequestInterface $request, ResponseFactoryInterface $responseFactory, ?AuthenticationException $exception = null): ResponseInterface
     {
         if ($exception) {
@@ -138,5 +146,4 @@ class FormAuthHandler implements AuthHandlerInterface
             $pass
         ];
     }
-
 }

+ 13 - 0
src/Handler/StatefulAuthHandlerInterface.php

@@ -0,0 +1,13 @@
+<?php
+
+namespace Michel\Auth\Handler;
+
+use Michel\Auth\Exception\AuthenticationException;
+use Psr\Http\Message\ResponseFactoryInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+
+interface StatefulAuthHandlerInterface
+{
+    public function onSuccess(ServerRequestInterface $request, ResponseFactoryInterface $responseFactory): ?ResponseInterface;
+}

+ 0 - 1
src/Handler/TokenAuthHandler.php

@@ -2,7 +2,6 @@
 
 namespace Michel\Auth\Handler;
 
-use Michel\Auth\AuthHandlerInterface;
 use Michel\Auth\AuthIdentity;
 use Michel\Auth\Exception\AuthenticationException;
 use Michel\Auth\Exception\InvalidCredentialsException;

+ 4 - 4
src/MichelPackage/MichelAuthPackage.php

@@ -3,7 +3,7 @@
 namespace Michel\Auth\MichelPackage;
 
 use Michel\Auth\Command\AuthPasswordHashCommand;
-use Michel\Auth\Handler\FormAuthHandler;
+use Michel\Auth\Handler\FormAuthAuthHandler;
 use Michel\Auth\Middlewares\AuthMiddleware;
 use Michel\Auth\UserProviderInterface;
 use Michel\Package\PackageInterface;
@@ -20,13 +20,13 @@ class MichelAuthPackage implements PackageInterface
         return [
             AuthMiddleware::class => static function (ContainerInterface $container) {
                 return new AuthMiddleware(
-                    $container->get(FormAuthHandler::class),
+                    $container->get(FormAuthAuthHandler::class),
                     $container->get(ResponseFactoryInterface::class),
                     $container->get(LoggerInterface::class)
                 );
             },
-            FormAuthHandler::class => static function (ContainerInterface $container) {
-                return new FormAuthHandler(
+            FormAuthAuthHandler::class => static function (ContainerInterface $container) {
+                return new FormAuthAuthHandler(
                     $container->get(UserProviderInterface::class),
                     $container->get(SessionStorageInterface::class),
                     [

+ 8 - 1
src/Middlewares/AuthMiddleware.php

@@ -2,9 +2,10 @@
 
 namespace Michel\Auth\Middlewares;
 
-use Michel\Auth\AuthHandlerInterface;
 use Michel\Auth\AuthIdentity;
 use Michel\Auth\Exception\AuthenticationException;
+use Michel\Auth\Handler\AuthHandlerInterface;
+use Michel\Auth\Handler\StatefulAuthHandlerInterface;
 use Michel\Auth\Helper\IpHelper;
 use Psr\Http\Message\ResponseFactoryInterface;
 use Psr\Http\Message\ResponseInterface;
@@ -50,6 +51,12 @@ final class AuthMiddleware implements MiddlewareInterface
                         'ip'         => IpHelper::getIpFromRequest($request),
                     ]
                 );
+                if ($this->authHandler instanceof StatefulAuthHandlerInterface) {
+                    $response = $this->authHandler->onSuccess($request, $this->responseFactory);
+                    if ($response instanceof ResponseInterface) {
+                        return $response;
+                    }
+                }
             }
             return $handler->handle($request);
         }catch (AuthenticationException $exception) {

+ 0 - 2
src/PasswordAuthenticatedUserInterface.php

@@ -5,6 +5,4 @@ namespace Michel\Auth;
 interface PasswordAuthenticatedUserInterface
 {
     public function getPassword(): string;
-
-    public function setPassword(?string $password);
 }

+ 1 - 1
src/UserProviderInterface.php

@@ -6,7 +6,7 @@ interface UserProviderInterface
 {
     public function findByIdentifier(string $identifier): ?UserInterface;
     public function findByToken(string $token): ?UserInterface;
-    public function checkPassword(PasswordAuthenticatedUserInterface $user, string $plainPassword): bool;
+    public function isPasswordValid(PasswordAuthenticatedUserInterface $user, string $plainPassword): bool;
     public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newPlainPassword): void;
     public function hashPassword(string $plainPassword): string;
 }