131 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
namespace Ulmus\User\Lib;
 | 
						|
 | 
						|
use Storage\{Session, Cookie};
 | 
						|
 | 
						|
use \Closure;
 | 
						|
 | 
						|
use Ulmus\User\Entity\User;
 | 
						|
use Ulmus\Exception;
 | 
						|
 | 
						|
class Authenticate {
 | 
						|
 | 
						|
    protected ? Session $session;
 | 
						|
 | 
						|
    protected ? Cookie $cookie;
 | 
						|
 | 
						|
    protected bool $logged = false;
 | 
						|
 | 
						|
    protected Closure $authenticationEvent;
 | 
						|
 | 
						|
    public ? User $user = null;
 | 
						|
 | 
						|
    public string $connection_fields = 'email';
 | 
						|
 | 
						|
    public function __construct(
 | 
						|
        ? Session $session = null,
 | 
						|
        ? Cookie  $cookie = null,
 | 
						|
        ? Closure $authenticationEvent = null
 | 
						|
    ) {
 | 
						|
        $this->session = $session;
 | 
						|
        $this->cookie = $cookie;
 | 
						|
        $this->authenticationEvent = $authenticationEvent ?: function(bool $authenticated, string $message, ? User $user, array $data = []) : ? bool {return null;} ;
 | 
						|
    }
 | 
						|
 | 
						|
    public function rememberMe(\Ulmus\Repository $repository) : ? User
 | 
						|
    {
 | 
						|
        $logUser = function(int $id) use ($repository) {
 | 
						|
            if ( null === ( $user = $repository->loadFromPk($id) ) ) {
 | 
						|
                throw new \Exception("User not found.");
 | 
						|
            }
 | 
						|
 | 
						|
            $user->logged = true;
 | 
						|
            
 | 
						|
            return $user;
 | 
						|
        };
 | 
						|
 | 
						|
        if ( $this->session && $this->session->has("user.id") ) {
 | 
						|
            return $logUser($this->session->get("user.id"));
 | 
						|
        }
 | 
						|
 | 
						|
        if ( $this->cookie && $this->cookie->has("user.id") ) {
 | 
						|
            return $logUser($this->cookie->get("user.id"));
 | 
						|
        }
 | 
						|
 | 
						|
        return null;
 | 
						|
    }
 | 
						|
 | 
						|
    public function forgetMe() {
 | 
						|
        $this->cookie->delete("user.id");
 | 
						|
        $this->session->destroy();
 | 
						|
    }
 | 
						|
 | 
						|
    public function authenticate(\Ulmus\Repository $repository, array $userLogin, string $password) : User
 | 
						|
    {
 | 
						|
        foreach($userLogin as $field => $value) {
 | 
						|
            $repository->or($field, $value);
 | 
						|
        }
 | 
						|
 | 
						|
        try {
 | 
						|
            $this->user = $repository->loadOne() ?: $repository->instanciateEntity();
 | 
						|
        }
 | 
						|
        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->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);
 | 
						|
                }
 | 
						|
 | 
						|
                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;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Force user disconnection and handle memory trashing
 | 
						|
     */
 | 
						|
    public function logout() : self
 | 
						|
    {
 | 
						|
        if ( $this->session ) {
 | 
						|
            $this->session->delete('user.id');
 | 
						|
        }
 | 
						|
 | 
						|
        if ( $this->cookie ) {
 | 
						|
            $this->cookie->delete('user.id');
 | 
						|
        }
 | 
						|
 | 
						|
        $this->user->logged = false;
 | 
						|
 | 
						|
        return $this;
 | 
						|
    }
 | 
						|
}
 |