144 lines
4.9 KiB
PHP
144 lines
4.9 KiB
PHP
<?php
|
|
|
|
namespace App\Auth;
|
|
|
|
use App\Models\Customer;
|
|
use Illuminate\Auth\EloquentUserProvider;
|
|
use Illuminate\Contracts\Auth\Authenticatable;
|
|
use Illuminate\Contracts\Auth\UserProvider;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Session;
|
|
use LDC\LDCCRM\Enums\ApiError;
|
|
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
|
use LDC\LDCCRM\Exceptions\CrmException;
|
|
use LDC\LDCCRM\Models\Customer as CrmCustomer;
|
|
|
|
/**
|
|
* Crm user provider to integrate nicely with Laravel
|
|
*/
|
|
class CrmUserProvider extends EloquentUserProvider implements UserProvider
|
|
{
|
|
/**
|
|
* The model to use, specified in auth config guard.
|
|
*
|
|
* @var string
|
|
*/
|
|
private $usedModel = Customer::class;
|
|
|
|
/**
|
|
* Retrieve a user by the given credentials.
|
|
*
|
|
* @param array $credentials
|
|
* @return \Illuminate\Contracts\Auth\Authenticatable|null
|
|
*/
|
|
public function retrieveByCredentials(array $credentials): \Illuminate\Contracts\Auth\Authenticatable|null
|
|
{
|
|
/** @var \Illuminate\Contracts\Auth\Authenticatable|null $model */
|
|
$model = parent::retrieveByCredentials($credentials);
|
|
|
|
try {
|
|
/** @var \LDC\LDCCRM\CrmApiV4 */
|
|
$crm = app('crmAPI');
|
|
|
|
// Si pas de compte local.
|
|
if (!$model) {
|
|
$crmCustomer = $crm->getCustomer($credentials['email']);
|
|
|
|
if (!$crmCustomer) {
|
|
// * Customer is not found on CRM.
|
|
return null;
|
|
}
|
|
$model = $this->createLocalCustomer($crmCustomer);
|
|
}
|
|
|
|
return $model;
|
|
} catch (ApiErrorException $e) {
|
|
// * Customer is not found.
|
|
if ($e->getApiError()->equals(ApiError::modelNotFound)) {
|
|
return null;
|
|
}
|
|
report($e);
|
|
Log::error('Unhandled response ' . $e->getApiError()->label());
|
|
} catch (CrmException | \Exception $e) {
|
|
report($e);
|
|
// Une erreur critique est survenue avec la CRM.
|
|
return null;
|
|
} //end try
|
|
Log::error(__CLASS__ . '::retrieveByCredentials reached end of possibilities.');
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Validate a user against the given credentials.
|
|
*
|
|
* @param \Illuminate\Contracts\Auth\Authenticatable $model
|
|
* @param array $credentials
|
|
* @return boolean
|
|
* @throws \RuntimeException If model provided is not a Customer or connection to server fails.
|
|
* @throws \LDC\LDCCRM\Exceptions\CrmException On CRM call error.
|
|
* @throws \Exception On CRM call error.
|
|
*/
|
|
public function validateCredentials(Authenticatable $model, array $credentials): bool
|
|
{
|
|
/** @var \Illuminate\Database\Eloquent\Model $model */
|
|
if (\get_class($model) !== $this->usedModel) {
|
|
throw new \RuntimeException('Cannot authenticate any thing else than ' . $this->usedModel);
|
|
}
|
|
|
|
try {
|
|
/** @var \LDC\LDCCRM\CrmApiV4 */
|
|
$crm = app('crmAPI');
|
|
|
|
// * Ne devrait pas survenir, $crm->login throws ApiError::authFailed
|
|
return $crm->login($credentials['email'], $credentials['password']);
|
|
} catch (ApiErrorException $e) {
|
|
// @phpstan-ignore-next-line
|
|
if (!$model->hashcode or !CrmCustomer::find($model->hashcode)) {
|
|
$model->delete();
|
|
return false;
|
|
}
|
|
if ($e->getApiError()->equals(ApiError::authFailed)) {
|
|
return false;
|
|
}
|
|
// ! Assert Authenticable model must be valided (MustValidate trait).
|
|
if ($e->getApiError()->equals(ApiError::customerNotActivated)) {
|
|
Session::flash('warning', \trans('Vous devez activer votre compte'));
|
|
return true;
|
|
}
|
|
} catch (CrmException | \Exception $e) {
|
|
report($e);
|
|
if (config('app.debug')) {
|
|
throw $e;
|
|
}
|
|
return false;
|
|
} //end try
|
|
|
|
Log::error(__CLASS__ . '::validateCredentials reached end of possibilities.');
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Create a local customer
|
|
*
|
|
* @param \LDC\LDCCRM\Models\Customer $crmCustomer
|
|
* @return \Illuminate\Database\Eloquent\Model
|
|
* @throws \Throwable If saving to DB failed.
|
|
*/
|
|
private function createLocalCustomer(\LDC\LDCCRM\Models\Customer $crmCustomer): \Illuminate\Database\Eloquent\Model
|
|
{
|
|
/** @var \Illuminate\Database\Eloquent\Model $model */
|
|
$model = $this->usedModel::firstOrNew([
|
|
'email' => $crmCustomer->email,
|
|
'firstname' => $crmCustomer->firstname,
|
|
'lastname' => $crmCustomer->lastname,
|
|
]);
|
|
// @phpstan-ignore-next-line
|
|
$model->hashcode = $crmCustomer->hashcode;
|
|
// @phpstan-ignore-next-line
|
|
$model->email_verified_at = $crmCustomer->status ? now() : null;
|
|
$model->saveOrFail();
|
|
|
|
return $model;
|
|
}
|
|
}
|