- WIP on user auth

This commit is contained in:
Dave M. 2023-11-08 06:53:13 -05:00
parent 7769b1a1ca
commit 9ae3e2d6f9
6 changed files with 38 additions and 37 deletions

View File

@ -7,7 +7,7 @@ use Ulmus\User\Entity\UserInterface;
interface AuthorizeMethodInterface
{
public function connect(ServerRequestInterface $request, UserInterface $user) : UserInterface|false;
public function connect(ServerRequestInterface $request, UserInterface $user) : bool;
public function catchRequest(ServerRequestInterface $request) : bool;
}

View File

@ -4,13 +4,12 @@ namespace Ulmus\User\Authorize;
use Psr\Http\Message\ServerRequestInterface;
use Ulmus\User\Common\AuthorizeContentTypeEnum;
use Ulmus\User\Entity\User;
use Ulmus\User\Entity\UserInterface;
use Ulmus\User\Lib\Authenticate;
use Ulmus\User\Lib\Authorize;
class HeaderAuthentication implements AuthorizeMethodInterface
{
public function connect(ServerRequestInterface $request, UserInterface $user): UserInterface|false
public function connect(ServerRequestInterface $request, UserInterface $user): bool
{
if ( null !== ( $auth = $request->getHeaderLine('Authorization') ) ) {
@ -18,7 +17,7 @@ class HeaderAuthentication implements AuthorizeMethodInterface
switch(strtolower(strtolower($method))) {
case "basic":
return $this->basicMethod($userPass);
return $this->basicMethod($user, $userPass);
default:
throw new \InvalidArgumentException("An authentication method must be provided");
@ -28,25 +27,24 @@ class HeaderAuthentication implements AuthorizeMethodInterface
return false;
}
protected function basicMethod(string $userPassword) : UserInterface|false
protected function basicMethod(UserInterface $user, string $userPassword) : bool
{
if ( false === $decoded = base64_decode($userPassword) ) {
throw new \RuntimeException("Base64 decoding of given username:password failed");
}
list($user, $password) = explode(':', $decoded) + [ null, null ];
list($userName, $password) = explode(':', $decoded) + [ null, null ];
if ( empty($user) ) {
if ( empty($userName) ) {
throw new \RuntimeException("A username must be provided");
}
elseif ( empty($password) ) {
throw new \RuntimeException("A password must be provided");
}
$authenticate = new Authenticate();
( new Authorize($user) )->authenticate([ 'email' => $userName, 'username' => $userName ], $password);
return false;
return $user->isLoaded();
}
public function catchRequest(ServerRequestInterface $request) : bool

View File

@ -9,17 +9,17 @@ use Ulmus\User\Lib\Authenticate;
class PostRequestAuthentication implements AuthorizeMethodInterface
{
public function __construct(
protected Authenticate $authenticate,
protected string $fieldUser = "username",
protected string $postFieldUser = "username",
public Authenticate $authenticate,
protected string $fieldUser = "email",
protected string $postFieldUser = "email",
protected string $postFieldPassword = "password",
) {}
public function connect(ServerRequestInterface $request, UserInterface $user): UserInterface|false
public function connect(ServerRequestInterface $request, UserInterface $user): bool
{
$post = $request->getParsedBody();
return $this->authenticate->authenticate($user::repository(), [ $this->fieldUser => $post[$this->postFieldUser] ], $post[$this->postFieldPassword]);
return $this->authenticate->authenticate([ $this->fieldUser => $post[$this->postFieldUser] ], $post[$this->postFieldPassword]);
}
public function catchRequest(ServerRequestInterface $request): bool

View File

@ -5,35 +5,37 @@ namespace Ulmus\User\Lib;
use Storage\{Session, Cookie};
use \Closure;
use Ulmus\User\Entity\User;
use Ulmus\Exception;
use Ulmus\User\Entity\UserInterface;
class Authenticate {
protected bool $logged = false;
protected Closure $authenticationEvent;
public ? User $user = null;
public UserInterface $user;
public function __construct(
UserInterface $user,
protected ? Session $session = null,
protected ? Cookie $cookie = null,
? Closure $authenticationEvent = null
? Closure $authenticationEvent = null,
) {
$this->authenticationEvent = $authenticationEvent ?: fn(bool $authenticated, string $message, ? User $user, array $data = []) : ? bool => null;
$this->authenticationEvent = $authenticationEvent ?: fn(bool $authenticated, string $message, ? UserInterface $user, array $data = []) : ? bool => null;
$this->user = $user;
}
public function rememberMe(\Ulmus\Repository $repository) : ? User
public function rememberMe() : ? UserInterface
{
$logUser = function(? int $id) use ($repository) {
if ( $id === null || null === ( $user = $repository->loadFromPk($id) ) ) {
$logUser = function(? int $id) {
if ( $id === null || null === ( $user = $this->user::repository()->loadFromPk($id) ) ) {
throw new \InvalidArgumentException(sprintf("User having id '%s' was not found.", $id));
}
$user->logged = true;
$this->user->fromArray($user);
return $user;
$this->user->logged = true;
return $this->user;
};
if ( $this->session && $this->session->has("user.id") ) {
@ -52,14 +54,18 @@ class Authenticate {
$this->session->destroy();
}
public function authenticate(\Ulmus\Repository $repository, array $userLogin, string $password) : User
public function authenticate(array $userLogin, string $password) : bool
{
$repository = $this->user::repository();
foreach($userLogin as $field => $value) {
$repository->or($field, $value);
}
try {
$this->user = $repository->loadOne() ?: $repository->instanciateEntity();
if (null !== $entity = $repository->loadOne()) {
$this->user->fromArray($entity->toArray());
}
}
catch(Exception\EmptyDatasetException $e) {
if ( ! call_user_func_array($this->authenticationEvent, [ false, 'userNotFound', $this->user ]) ) {
@ -98,7 +104,7 @@ class Authenticate {
call_user_func_array($this->authenticationEvent, [ false, 'authenticationFailed', $this->user, [ 'user_login' => $userLogin, 'password' => $password ] ]);
}
return $this->user;
return $this->user->logged;
}
public function logout() : self

View File

@ -2,17 +2,12 @@
namespace Ulmus\User\Lib;
use Ulmus\User\Entity\User;
use Ulmus\User\Entity\UserInterface;
class Authorize extends Authenticate
{
public function rememberMe(\Ulmus\Repository $repository) : ? User
public function rememberMe() : ? UserInterface
{
return null;
}
public function authorize(\Ulmus\Repository $repository, array $userLogin, string $password) : User
{
}
}

View File

@ -26,6 +26,8 @@ class PostRequestAuthenticationMiddleware implements MiddlewareInterface
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$this->authenticator->authenticate->rememberMe();
if ( $this->authenticator->catchRequest($request) ) {
if ( ! $this->authenticator->connect($request, $this->entity) ) {
return call_user_func($this->loginFailedResponse, "Login failed");