diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 0f35e75e9c..34e24e137c 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -22,8 +22,12 @@ declare(strict_types=1); namespace FireflyIII\Providers; +use FireflyIII\Support\Authentication\RemoteUserGuard; +use FireflyIII\Support\Authentication\RemoteUserProvider; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; +use Illuminate\Support\Facades\Auth; use Laravel\Passport\Passport; +use Log; /** * @codeCoverageIgnore @@ -48,11 +52,28 @@ class AuthServiceProvider extends ServiceProvider */ public function boot(): void { + Log::debug('Boot() of AuthServiceProvider'); + + Auth::provider( + 'remote_user_provider', function ($app, array $config) { + //Log::debug('Creating remote_user_provider in Closure'); + return new RemoteUserProvider($app, $config); + } + ); + + Auth::extend( + 'remote_user_guard', static function ($app, string $name, array $config) { + //Log::debug('Creating remote_user_guard in Closure'); + return new RemoteUserGuard(Auth::createUserProvider($config['provider']), $app); + } + ); + $this->registerPolicies(); + + Passport::routes(); Passport::tokensExpireIn(now()->addDays(14)); - // } } diff --git a/app/Support/Authentication/RemoteUserGuard.php b/app/Support/Authentication/RemoteUserGuard.php new file mode 100644 index 0000000000..96e37d52a8 --- /dev/null +++ b/app/Support/Authentication/RemoteUserGuard.php @@ -0,0 +1,122 @@ +application = $app; + $this->provider = $provider; + $this->user = null; + } + + /** + * + */ + public function authenticate(): void + { + Log::debug(sprintf('Now at %s', __METHOD__)); + if (!is_null($this->user)) { + Log::debug('No user found.'); + + return; + } + // Get the user identifier from $_SERVER + $userID = request()->server('REMOTE_USER') ?? null; + if (null === $userID) { + Log::debug('No user in REMOTE_USER.'); + throw new FireflyException('The REMOTE_USER header was unexpectedly empty.'); + } + + + // do some basic debugging here: + // $userID = 'test@firefly'; + + /** @var User $user */ + $user = $this->provider->retrieveById($userID); + + Log::debug(sprintf('Result of getting user from provider: %s', $user->email)); + $this->user = $user; + } + + /** + * @inheritDoc + */ + public function check(): bool + { + $result = !is_null($this->user()); + Log::debug(sprintf('Now in check(). Will return %s', var_export($result, true))); + + return $result; + } + + /** + * @inheritDoc + */ + public function guest(): bool + { + //Log::debug(sprintf('Now at %s', __METHOD__)); + return !$this->check(); + } + + /** + * @inheritDoc + */ + public function id(): ?User + { + //Log::debug(sprintf('Now at %s', __METHOD__)); + return $this->user; + } + + /** + * @inheritDoc + */ + public function setUser(Authenticatable $user) + { + //Log::debug(sprintf('Now at %s', __METHOD__)); + $this->user = $user; + } + + /** + * @inheritDoc + */ + public function user(): ?User + { + //Log::debug(sprintf('Now in user(). Will return NULL: %s', var_export(null === $this->user, true))); + return $this->user; + } + + /** + * @inheritDoc + */ + public function validate(array $credentials = []) + { + throw new FireflyException('Did not implement RemoteUserGuard::validate()'); + } +} diff --git a/app/Support/Authentication/RemoteUserProvider.php b/app/Support/Authentication/RemoteUserProvider.php new file mode 100644 index 0000000000..52dd983e75 --- /dev/null +++ b/app/Support/Authentication/RemoteUserProvider.php @@ -0,0 +1,89 @@ +first(); + if (null === $user) { + Log::debug(sprintf('User with email "%s" not found. Will be created.', $identifier)); + $user = User::create( + [ + 'blocked' => false, + 'blocked_code' => null, + 'email' => $identifier, + 'password' => bcrypt(Str::random(64)), + ] + ); + } + Log::debug(sprintf('Going to return user #%d (%s)', $user->id, $user->email)); + + return $user; + } + + /** + * @inheritDoc + */ + public function retrieveByToken($identifier, $token) + { + Log::debug(sprintf('Now at %s', __METHOD__)); + throw new FireflyException(sprintf('Did not implement %s', __METHOD__)); + } + + /** + * @inheritDoc + */ + public function updateRememberToken(Authenticatable $user, $token) + { + Log::debug(sprintf('Now at %s', __METHOD__)); + throw new FireflyException(sprintf('Did not implement %s', __METHOD__)); + } + + /** + * @inheritDoc + */ + public function validateCredentials(Authenticatable $user, array $credentials) + { + Log::debug(sprintf('Now at %s', __METHOD__)); + throw new FireflyException(sprintf('Did not implement %s', __METHOD__)); + } +} diff --git a/config/auth.php b/config/auth.php index 5c8f4f365a..189babdc0a 100644 --- a/config/auth.php +++ b/config/auth.php @@ -34,7 +34,7 @@ return [ */ 'defaults' => [ - 'guard' => 'web', + 'guard' => envNonEmpty('AUTHENTICATION_GUARD', 'web'), 'passwords' => 'users', ], @@ -56,11 +56,15 @@ return [ */ 'guards' => [ - 'web' => [ + 'web' => [ 'driver' => 'session', 'provider' => 'users', ], - 'api' => [ + 'remote_user_guard' => [ + 'driver' => 'remote_user_guard', + 'provider' => 'remote_user_provider', + ], + 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], @@ -84,10 +88,14 @@ return [ */ 'providers' => [ - 'users' => [ + 'users' => [ 'driver' => envNonEmpty('LOGIN_PROVIDER', 'eloquent'), //'adldap', 'model' => FireflyIII\User::class, ], + 'remote_user_provider' => [ + 'driver' => 'remote_user_provider', + 'model' => FireflyIII\User::class, + ], ], /*