Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
70.00% covered (warning)
70.00%
7 / 10
CRAP
65.79% covered (warning)
65.79%
25 / 38
Auth
0.00% covered (danger)
0.00%
0 / 1
70.00% covered (warning)
70.00%
7 / 10
36.02
65.79% covered (warning)
65.79%
25 / 38
 __construct
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
4 / 4
 connected
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 is
0.00% covered (danger)
0.00%
0 / 1
10.75
25.00% covered (danger)
25.00%
2 / 8
 clean
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 current
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
1 / 1
 login
0.00% covered (danger)
0.00%
0 / 1
4.02
90.00% covered (success)
90.00%
9 / 10
 logout
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 deleteAccount
0.00% covered (danger)
0.00%
0 / 1
6.80
25.00% covered (danger)
25.00%
2 / 8
 messages
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 redirect
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
2 / 2
<?php
    declare(strict_types=1);
namespace Eywa\Security\Authentication
{
    use Eywa\Collection\Collect;
    use Eywa\Exception\Kedavra;
    use Eywa\Http\Response\RedirectResponse;
    use Eywa\Http\Response\Response;
    use Eywa\Message\Flash\Flash;
    use Eywa\Session\SessionInterface;
    use ReflectionClass;
    use stdClass;
    /**
     *
     * Class Auth
     *
     * @package Eywa\Security\Authentication
     *
     */
    class Auth implements AuthInterface
    {
        /**
         *
         * The session
         *
         */
        private SessionInterface $session;
        private ReflectionClass $model;
        /**
         * @inheritDoc
         */
        public function __construct(SessionInterface $session, string $model)
        {
            $this->session = $session;
            is_false(class_exists($model), true, 'The model not exist');
            $this->model =   new ReflectionClass($model);
        }
        /**
         * @inheritDoc
         */
        public function connected(): bool
        {
            return $this->session->has('user');
        }
        /**
         * @inheritDoc
         */
        public function is(string $role): bool
        {
            if ($this->connected()) {
                switch ($role) {
                    case 'admin':
                        return $this->current()->id == '1';
                    case 'redac':
                        return in_array($this->current()->id, ['1','2'], true);
                    default:
                        return false;
                }
            }
            return false;
        }
        /**
         * @inheritDoc
         */
        public function clean(): bool
        {
            return $this->session->destroy(['user']);
        }
        /**
         * @inheritDoc
         */
        public function current(): stdClass
        {
            return $this->session->has('user') ? unserialize($this->session->get('user')) : new stdClass();
        }
        /**
         * @inheritDoc
         */
        public function login(string $username, string $password): Response
        {
            try {
                $user = $this->model->getMethod('by')->invokeArgs($this->model->newInstance(), ['username',$username]);
            } catch (Kedavra $exception) {
                return $this->redirect('/login', alert([$this->messages()->get('user_not_found')]));
            }
            if (def($user)) {
                if (check($password, $user->password)) {
                    $this->session->set('user', serialize($user));
                    return $this->redirect('/home', alert([ $this->messages()->get('welcome')], true), true);
                } else {
                    $this->clean();
                    return $this->redirect('/login', alert([$this->messages()->get('password_no_match')]));
                }
            }
            return $this->redirect('/login', alert([$this->messages()->get('user_not_found')]));
        }
        /**
         * @inheritDoc
         */
        public function logout(): Response
        {
            $this->clean();
            return $this->redirect('/', $this->messages()->get('bye'), true);
        }
        /**
         * @inheritDoc
         */
        public function deleteAccount(): Response
        {
            if ($this->connected()) {
                if (
                    $this->model->getMethod('destroy')
                    ->invokeArgs(
                        $this->model->newInstance(),
                        [intval($this->current()->id)]
                    )
                ) {
                    return $this->redirect('/', $this->messages()->get('account_removed_successfully'), true);
                }
                return $this->redirect('/', $this->messages()->get('account_removed_fail'));
            }
            return $this->redirect('/', $this->messages()->get('not_connected'));
        }
        /**
         *
         * Get all messages
         *
         * @return Collect
         *
         * @throws Kedavra
         *
         */
        private function messages(): Collect
        {
            return collect(config('auth', 'messages'));
        }
        /**
         *
         * Get all messages
         *
         * @param string $url
         * @param string $message
         * @param bool $success
         * @return Response
         *
         * @throws Kedavra
         */
        private function redirect(string $url, string $message, bool $success = false): Response
        {
            $success ?  (new Flash())->set(SUCCESS, $message) : (new Flash())->set(FAILURE, $message);
            return  (new RedirectResponse($url))->send();
        }
    }
}