. */ declare(strict_types=1); namespace FireflyIII\Http\Middleware; use Closure; use FireflyIII\Exceptions\FireflyException; use FireflyIII\User; use Illuminate\Auth\AuthenticationException; use Illuminate\Contracts\Auth\Factory as Auth; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; /** * Class Authenticate */ class Authenticate { /** * Create a new middleware instance. */ public function __construct( /** * The authentication factory instance. */ protected Auth $auth ) {} /** * Handle an incoming request. * * @param Request $request * @param string[] ...$guards * * @return mixed * * @throws FireflyException * @throws AuthenticationException */ public function handle($request, Closure $next, ...$guards) { $this->authenticate($request, $guards); return $next($request); } /** * Determine if the user is logged in to any of the given guards. * * @param mixed $request * * @return mixed * * @throws FireflyException * @throws AuthenticationException * * @SuppressWarnings("PHPMD.UnusedFormalParameter") */ protected function authenticate($request, array $guards) { if (0 === count($guards)) { Log::debug('in Authenticate::authenticate() with zero guards.'); // There are no guards defined, go for the default guard: if (auth()->check()) { Log::debug('User is authenticated.'); $user = auth()->user(); $this->validateBlockedUser($user, $guards); return; } // @noinspection PhpUndefinedMethodInspection $this->auth->authenticate(); if (!$this->auth->check()) { throw new AuthenticationException('The user is not logged in but must be.', $guards); } } throw new FireflyException('This point is generally unreachable.'); // exit('five'); // foreach ($guards as $guard) { // exit('six'); // if ('api' !== $guard) { // $this->auth->guard($guard)->authenticate(); // } // $result = $this->auth->guard($guard)->check(); // if ($result) { // $user = $this->auth->guard($guard)->user(); // $this->validateBlockedUser($user, $guards); // // // According to PHPstan the method returns void, but we'll see. // return $this->auth->shouldUse($guard); // } // } // // exit('seven'); // this is a massive hack, but if the handler has the oauth exception // at this point we can report its error instead of a generic one. // $message = 'Unauthenticated.'; // if (Handler::$lastError instanceof OAuthServerException) { // $message = Handler::$lastError->getHint(); // } // // throw new AuthenticationException($message, $guards); } /** * @throws AuthenticationException */ private function validateBlockedUser(?User $user, array $guards): void { if (!$user instanceof User) { Log::warning('User is null, throw exception?'); } // \Illuminate\Support\Facades\Log::debug(get_class($user)); if ($user instanceof User && 1 === (int) $user->blocked) { $message = (string) trans('firefly.block_account_logout'); if ('email_changed' === $user->blocked_code) { $message = (string) trans('firefly.email_changed_logout'); } Log::warning('User is blocked, cannot use authentication method.'); app('session')->flash('logoutMessage', $message); // @noinspection PhpUndefinedMethodInspection $this->auth->logout(); throw new AuthenticationException('Blocked account.', $guards); } Log::debug(sprintf('User #%d is not blocked.', $user->id)); } }