Add fallback provider for user login

This commit is contained in:
philipp lang 2021-11-23 19:15:16 +01:00
parent 6d6aa60363
commit f30a1d19bf
4 changed files with 76 additions and 34 deletions

View File

@ -12,7 +12,8 @@ trait AuthenticatesNamiUsers {
protected function validateLogin(Request $request) protected function validateLogin(Request $request)
{ {
$request->validate([ $request->validate([
$this->username() => 'required|numeric', 'mglnr' => 'required_if:provider,nami',
'email' => 'required_if:provider,database',
'password' => 'required|string', 'password' => 'required|string',
]); ]);
} }
@ -22,4 +23,15 @@ trait AuthenticatesNamiUsers {
return 'mglnr'; return 'mglnr';
} }
/**
* Get the needed authorization credentials from the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function credentials(Request $request)
{
return $request->only($this->username(), 'email', 'password', 'provider');
}
} }

View File

@ -8,7 +8,9 @@ use Illuminate\Cache\Repository as CacheRepository;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Guard; use Illuminate\Contracts\Auth\Guard;
use Illuminate\Foundation\Auth\User as AuthenticatableUser;
use Illuminate\Session\Store as SessionStore; use Illuminate\Session\Store as SessionStore;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Event;
use Illuminate\Support\Str; use Illuminate\Support\Str;
@ -22,9 +24,12 @@ class NamiGuard {
protected CacheRepository $cache; protected CacheRepository $cache;
/** @var <int, callback> $loginCallbacks */ /** @var array<int, callable> $loginCallbacks */
public static array $loginCallbacks = []; public static array $loginCallbacks = [];
/** @var array<int, string> */
public array $fallbacks;
/** /**
* The currently authenticated user. * The currently authenticated user.
* *
@ -39,18 +44,28 @@ class NamiGuard {
$this->cache = $cache; $this->cache = $cache;
} }
/**
* @param array<int, string> $fallbacks
*/
public function setFallbacks(array $fallbacks): self
{
$this->fallbacks = $fallbacks;
return $this;
}
/** /**
* Set the current user. * Set the current user.
* *
* @param NamiUser|null $user * @param NamiUser|AuthenticatableUser|null $user
* @return void * @return void
*/ */
public function setUser(?NamiUser $user): void public function setUser($user): void
{ {
$this->user = $user; $this->user = $user;
} }
public function user(): ?NamiUser public function user()
{ {
if (! is_null($this->user)) { if (! is_null($this->user)) {
return $this->user; return $this->user;
@ -71,6 +86,14 @@ class NamiGuard {
*/ */
public function attempt(array $credentials = [], bool $remember = false): bool public function attempt(array $credentials = [], bool $remember = false): bool
{ {
if (in_array($credentials['provider'], $this->fallbacks) && $this->loginFallback($credentials['provider'], $credentials)) {
return true;
}
if (data_get($credentials, 'provider', '') !== 'nami') {
return false;
}
$beforeResult = static::runBeforeLogin($credentials, $remember); $beforeResult = static::runBeforeLogin($credentials, $remember);
if (!is_null($beforeResult)) { if (!is_null($beforeResult)) {
@ -78,7 +101,7 @@ class NamiGuard {
} }
try { try {
return $this->login($credentials); return $this->loginNami($credentials);
} catch (LoginException $e) { } catch (LoginException $e) {
return false; return false;
} }
@ -87,7 +110,35 @@ class NamiGuard {
/** /**
* @param array<string, string> $credentials * @param array<string, string> $credentials
*/ */
public function login(array $credentials): bool public function loginFallback(string $provider, array $credentials): bool
{
$provider = auth()->createUserProvider($provider);
$user = $user = $provider->retrieveByCredentials(Arr::except($credentials, ['provider']));
if (!$user) {
return false;
}
if (!$provider->validateCredentials($user, $credentials)) {
return false;
}
$payload = [
'id' => $user->id,
];
$this->setUser($user);
$key = $this->newCacheKey();
Cache::forever("namiauth-{$key}", $payload);
$this->updateSession($key);
return true;
}
/**
* @param array<string, string> $credentials
*/
public function loginNami(array $credentials): bool
{ {
$api = Nami::login($credentials['mglnr'], $credentials['password']); $api = Nami::login($credentials['mglnr'], $credentials['password']);
$user = $api->findNr((int) $credentials['mglnr']); $user = $api->findNr((int) $credentials['mglnr']);

View File

@ -6,7 +6,7 @@ use Cache;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
class NamiUser implements Authenticatable { class NamiUser {
public $mglnr; public $mglnr;
public $password; public $password;
@ -42,10 +42,6 @@ class NamiUser implements Authenticatable {
return $this->group_id; return $this->group_id;
} }
public function getAuthIdentifierName() {
return 'mglnr';
}
public function getMglnr() { public function getMglnr() {
return $this->mglnr; return $this->mglnr;
} }
@ -58,22 +54,4 @@ class NamiUser implements Authenticatable {
return $this->lastname; return $this->lastname;
} }
public function getAuthIdentifier() {
return $this->{$this->getAuthIdentifierName()}.'-'.$this->groupid;
}
public function getAuthPassword() {
return null;
}
public function getRememberToken() {
return null;
}
public function setRememberToken($value) {}
public function getRememberTokenName() {
return null;
}
} }

View File

@ -2,20 +2,21 @@
namespace Zoomyboy\LaravelNami\Providers; namespace Zoomyboy\LaravelNami\Providers;
use Illuminate\Support\Facades\Auth;
use GuzzleHttp\Client as GuzzleClient; use GuzzleHttp\Client as GuzzleClient;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use Zoomyboy\LaravelNami\Backend\LiveBackend;
use Zoomyboy\LaravelNami\Api; use Zoomyboy\LaravelNami\Api;
use Zoomyboy\LaravelNami\Cookies\CacheCookie;
use Zoomyboy\LaravelNami\Authentication\NamiGuard; use Zoomyboy\LaravelNami\Authentication\NamiGuard;
use Zoomyboy\LaravelNami\Backend\LiveBackend;
use Zoomyboy\LaravelNami\Cookies\CacheCookie;
class NamiServiceProvider extends ServiceProvider class NamiServiceProvider extends ServiceProvider
{ {
public function boot() public function boot()
{ {
Auth::extend('nami', function ($app, $name, array $config) { Auth::extend('nami', function ($app, $name, array $config) {
return new NamiGuard($this->app['session.store'], $this->app['cache.store']); return (new NamiGuard($this->app['session.store'], $this->app['cache.store']))
->setFallbacks(data_get($config, 'other_providers', []));
}); });
} }