- WIP on user auth
This commit is contained in:
parent
7769b1a1ca
commit
9ae3e2d6f9
|
@ -7,7 +7,7 @@ use Ulmus\User\Entity\UserInterface;
|
||||||
|
|
||||||
interface AuthorizeMethodInterface
|
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;
|
public function catchRequest(ServerRequestInterface $request) : bool;
|
||||||
}
|
}
|
|
@ -4,13 +4,12 @@ namespace Ulmus\User\Authorize;
|
||||||
|
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Ulmus\User\Common\AuthorizeContentTypeEnum;
|
use Ulmus\User\Common\AuthorizeContentTypeEnum;
|
||||||
use Ulmus\User\Entity\User;
|
|
||||||
use Ulmus\User\Entity\UserInterface;
|
use Ulmus\User\Entity\UserInterface;
|
||||||
use Ulmus\User\Lib\Authenticate;
|
use Ulmus\User\Lib\Authorize;
|
||||||
|
|
||||||
class HeaderAuthentication implements AuthorizeMethodInterface
|
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') ) ) {
|
if ( null !== ( $auth = $request->getHeaderLine('Authorization') ) ) {
|
||||||
|
|
||||||
|
@ -18,7 +17,7 @@ class HeaderAuthentication implements AuthorizeMethodInterface
|
||||||
|
|
||||||
switch(strtolower(strtolower($method))) {
|
switch(strtolower(strtolower($method))) {
|
||||||
case "basic":
|
case "basic":
|
||||||
return $this->basicMethod($userPass);
|
return $this->basicMethod($user, $userPass);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new \InvalidArgumentException("An authentication method must be provided");
|
throw new \InvalidArgumentException("An authentication method must be provided");
|
||||||
|
@ -28,25 +27,24 @@ class HeaderAuthentication implements AuthorizeMethodInterface
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function basicMethod(string $userPassword) : UserInterface|false
|
protected function basicMethod(UserInterface $user, string $userPassword) : bool
|
||||||
{
|
{
|
||||||
if ( false === $decoded = base64_decode($userPassword) ) {
|
if ( false === $decoded = base64_decode($userPassword) ) {
|
||||||
throw new \RuntimeException("Base64 decoding of given username:password failed");
|
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");
|
throw new \RuntimeException("A username must be provided");
|
||||||
}
|
}
|
||||||
elseif ( empty($password) ) {
|
elseif ( empty($password) ) {
|
||||||
throw new \RuntimeException("A password must be provided");
|
throw new \RuntimeException("A password must be provided");
|
||||||
}
|
}
|
||||||
|
|
||||||
$authenticate = new Authenticate();
|
( new Authorize($user) )->authenticate([ 'email' => $userName, 'username' => $userName ], $password);
|
||||||
|
|
||||||
|
return $user->isLoaded();
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function catchRequest(ServerRequestInterface $request) : bool
|
public function catchRequest(ServerRequestInterface $request) : bool
|
||||||
|
|
|
@ -9,17 +9,17 @@ use Ulmus\User\Lib\Authenticate;
|
||||||
class PostRequestAuthentication implements AuthorizeMethodInterface
|
class PostRequestAuthentication implements AuthorizeMethodInterface
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
protected Authenticate $authenticate,
|
public Authenticate $authenticate,
|
||||||
protected string $fieldUser = "username",
|
protected string $fieldUser = "email",
|
||||||
protected string $postFieldUser = "username",
|
protected string $postFieldUser = "email",
|
||||||
protected string $postFieldPassword = "password",
|
protected string $postFieldPassword = "password",
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public function connect(ServerRequestInterface $request, UserInterface $user): UserInterface|false
|
public function connect(ServerRequestInterface $request, UserInterface $user): bool
|
||||||
{
|
{
|
||||||
$post = $request->getParsedBody();
|
$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
|
public function catchRequest(ServerRequestInterface $request): bool
|
||||||
|
|
|
@ -5,35 +5,37 @@ namespace Ulmus\User\Lib;
|
||||||
use Storage\{Session, Cookie};
|
use Storage\{Session, Cookie};
|
||||||
|
|
||||||
use \Closure;
|
use \Closure;
|
||||||
|
|
||||||
use Ulmus\User\Entity\User;
|
|
||||||
use Ulmus\Exception;
|
use Ulmus\Exception;
|
||||||
|
use Ulmus\User\Entity\UserInterface;
|
||||||
|
|
||||||
class Authenticate {
|
class Authenticate {
|
||||||
protected bool $logged = false;
|
|
||||||
|
|
||||||
protected Closure $authenticationEvent;
|
protected Closure $authenticationEvent;
|
||||||
|
|
||||||
public ? User $user = null;
|
public UserInterface $user;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
UserInterface $user,
|
||||||
protected ? Session $session = null,
|
protected ? Session $session = null,
|
||||||
protected ? Cookie $cookie = 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) {
|
$logUser = function(? int $id) {
|
||||||
if ( $id === null || null === ( $user = $repository->loadFromPk($id) ) ) {
|
if ( $id === null || null === ( $user = $this->user::repository()->loadFromPk($id) ) ) {
|
||||||
throw new \InvalidArgumentException(sprintf("User having id '%s' was not found.", $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") ) {
|
if ( $this->session && $this->session->has("user.id") ) {
|
||||||
|
@ -52,14 +54,18 @@ class Authenticate {
|
||||||
$this->session->destroy();
|
$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) {
|
foreach($userLogin as $field => $value) {
|
||||||
$repository->or($field, $value);
|
$repository->or($field, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->user = $repository->loadOne() ?: $repository->instanciateEntity();
|
if (null !== $entity = $repository->loadOne()) {
|
||||||
|
$this->user->fromArray($entity->toArray());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(Exception\EmptyDatasetException $e) {
|
catch(Exception\EmptyDatasetException $e) {
|
||||||
if ( ! call_user_func_array($this->authenticationEvent, [ false, 'userNotFound', $this->user ]) ) {
|
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 ] ]);
|
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
|
public function logout() : self
|
||||||
|
|
|
@ -2,17 +2,12 @@
|
||||||
|
|
||||||
namespace Ulmus\User\Lib;
|
namespace Ulmus\User\Lib;
|
||||||
|
|
||||||
use Ulmus\User\Entity\User;
|
use Ulmus\User\Entity\UserInterface;
|
||||||
|
|
||||||
class Authorize extends Authenticate
|
class Authorize extends Authenticate
|
||||||
{
|
{
|
||||||
public function rememberMe(\Ulmus\Repository $repository) : ? User
|
public function rememberMe() : ? UserInterface
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function authorize(\Ulmus\Repository $repository, array $userLogin, string $password) : User
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -26,6 +26,8 @@ class PostRequestAuthenticationMiddleware implements MiddlewareInterface
|
||||||
|
|
||||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||||
{
|
{
|
||||||
|
$this->authenticator->authenticate->rememberMe();
|
||||||
|
|
||||||
if ( $this->authenticator->catchRequest($request) ) {
|
if ( $this->authenticator->catchRequest($request) ) {
|
||||||
if ( ! $this->authenticator->connect($request, $this->entity) ) {
|
if ( ! $this->authenticator->connect($request, $this->entity) ) {
|
||||||
return call_user_func($this->loginFailedResponse, "Login failed");
|
return call_user_func($this->loginFailedResponse, "Login failed");
|
||||||
|
|
Loading…
Reference in New Issue