144 lines
4.0 KiB
PHP
144 lines
4.0 KiB
PHP
<?php
|
|
|
|
namespace Ulmus\User\Lib;
|
|
|
|
use Storage\{Session, Cookie};
|
|
|
|
use \Closure;
|
|
use Ulmus\Exception;
|
|
use Ulmus\User\Entity\UserInterface;
|
|
|
|
class Authenticate {
|
|
|
|
protected Closure $authenticationEvent;
|
|
|
|
public UserInterface $user;
|
|
|
|
public function __construct(
|
|
UserInterface $user,
|
|
protected ? Session $session = null,
|
|
protected ? Cookie $cookie = null,
|
|
? Closure $authenticationEvent = null,
|
|
) {
|
|
$this->authenticationEvent = $authenticationEvent ?: fn(bool $authenticated, string $message, ? UserInterface $user, array $data = []) : ? bool => null;
|
|
$this->user = $user;
|
|
}
|
|
|
|
public function rememberMe() : ? UserInterface
|
|
{
|
|
if ( $this->session && $this->session->has("user.id") ) {
|
|
return $this->logUser($this->session->get("user.id"));
|
|
}
|
|
|
|
if ( $this->cookie && $this->cookie->has("user.id") ) {
|
|
return $this->logUser($this->cookie->get("user.id"));
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function forgetMe() {
|
|
$this->cookie->delete("user.id");
|
|
$this->session->destroy();
|
|
}
|
|
|
|
public function authenticate(array $userLogin, string $password) : bool
|
|
{
|
|
$repository = $this->user::repository();
|
|
|
|
foreach($userLogin as $field => $value) {
|
|
$repository->or($field, $value);
|
|
}
|
|
|
|
try {
|
|
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 ]) ) {
|
|
return $repository->instanciateEntity();
|
|
}
|
|
}
|
|
|
|
if ( ! $this->user->isLoaded() ) {
|
|
call_user_func_array($this->authenticationEvent, [ false, 'userNotFound', $this->user, [ 'user_login' => $userLogin, 'password' => $password ] ]);
|
|
}
|
|
|
|
if ($this->user->isLoaded()) {
|
|
$response = call_user_func_array($this->authenticationEvent, [ false, 'verifyPassword', $this->user, [ 'password' => $password ] ]);
|
|
|
|
if ( $response !== null ? $response : $this->user->verifyPassword($password) ) {
|
|
$this->login();
|
|
|
|
call_user_func_array($this->authenticationEvent, [ true, 'success', $this->user ]);
|
|
}
|
|
else {
|
|
$this->user->logged = false;
|
|
|
|
call_user_func_array($this->authenticationEvent, [ false, 'invalidPassword', $this->user ]);
|
|
}
|
|
}
|
|
|
|
if ( ! $this->user->isLoaded() ) {
|
|
call_user_func_array($this->authenticationEvent, [ false, 'authenticationFailed', $this->user, [ 'user_login' => $userLogin, 'password' => $password ] ]);
|
|
}
|
|
|
|
return $this->user->logged;
|
|
}
|
|
|
|
|
|
public function login() : void
|
|
{
|
|
if ( !$this->user->isLoaded() ) {
|
|
return;
|
|
}
|
|
|
|
$this->user->logged = true;
|
|
|
|
if ( $this->session ) {
|
|
$this->session->set("user.id", $this->user->id);
|
|
}
|
|
|
|
if ( $this->cookie ) {
|
|
$this->cookie->set("user.id", $this->user->id);
|
|
}
|
|
}
|
|
|
|
public function logout() : self
|
|
{
|
|
$this->user->logged = false;
|
|
|
|
if ( $this->session ) {
|
|
$this->session->delete('user.id');
|
|
}
|
|
|
|
if ( $this->cookie ) {
|
|
$this->cookie->delete('user.id');
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function logUser(null|int|object $id) : ? UserInterface
|
|
{
|
|
if (! is_object($id)) {
|
|
try {
|
|
if ($id === null || null === ($entity = $this->user::repository()->loadFromPk($id))) {
|
|
return null;
|
|
}
|
|
} catch (\Exception $ex) {
|
|
return null;
|
|
}
|
|
}
|
|
else {
|
|
$entity = $id;
|
|
}
|
|
|
|
$this->user->fromArray($entity);
|
|
|
|
$this->user->loggedIn(true);
|
|
|
|
return $this->user;
|
|
}
|
|
} |