Merge pull request #535 from dmstr-forks/master

Fix Social Network Auth
This commit is contained in:
Lorenzo Milesi
2024-01-10 21:07:30 +01:00
committed by GitHub
16 changed files with 80 additions and 9 deletions

View File

@ -2,6 +2,8 @@
## dev ## dev
- Fix: Social Network Auth (eluhr)
## 1.6.2 Jan 4th, 2024 ## 1.6.2 Jan 4th, 2024
- Fix: Two Factor Authentication - Filter - Blocks even when two factor authentication is enabled - Fix: Two Factor Authentication - Filter - Blocks even when two factor authentication is enabled

View File

@ -143,6 +143,15 @@ List of urls that does not require explicit data processing consent to be access
Setting this attribute allows the registration process. If you set it to `false`, the module won't allow users to Setting this attribute allows the registration process. If you set it to `false`, the module won't allow users to
register by throwing a `NotFoundHttpException` if the `RegistrationController::actionRegister()` is accessed. register by throwing a `NotFoundHttpException` if the `RegistrationController::actionRegister()` is accessed.
#### enableSocialNetworkRegistration (type: `boolean`, default: `true`)
Setting this attribute allows the registration process via social networks. If you set it to `false`, the module won't allow users to
register.
#### sendWelcomeMailAfterSocialNetworkRegistration (type: `boolean`, default: `true`)
Setting this attribute controls wether a confirmation mail should be send or not.
#### enableEmailConfirmation (type: `boolean`, default: `true`) #### enableEmailConfirmation (type: `boolean`, default: `true`)
If `true`, the module will send an email with a confirmation link that user needs to click through to complete its If `true`, the module will send an email with a confirmation link that user needs to click through to complete its

View File

@ -12,10 +12,14 @@
namespace Da\User\AuthClient; namespace Da\User\AuthClient;
use Da\User\Contracts\AuthClientInterface; use Da\User\Contracts\AuthClientInterface;
use Da\User\Traits\AuthClientUserIdTrait;
use yii\authclient\clients\Facebook as BaseFacebook; use yii\authclient\clients\Facebook as BaseFacebook;
class Facebook extends BaseFacebook implements AuthClientInterface class Facebook extends BaseFacebook implements AuthClientInterface
{ {
use AuthClientUserIdTrait;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View File

@ -12,10 +12,12 @@
namespace Da\User\AuthClient; namespace Da\User\AuthClient;
use Da\User\Contracts\AuthClientInterface; use Da\User\Contracts\AuthClientInterface;
use Da\User\Traits\AuthClientUserIdTrait;
use yii\authclient\clients\GitHub as BaseGitHub; use yii\authclient\clients\GitHub as BaseGitHub;
class GitHub extends BaseGitHub implements AuthClientInterface class GitHub extends BaseGitHub implements AuthClientInterface
{ {
use AuthClientUserIdTrait;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View File

@ -12,10 +12,12 @@
namespace Da\User\AuthClient; namespace Da\User\AuthClient;
use Da\User\Contracts\AuthClientInterface; use Da\User\Contracts\AuthClientInterface;
use Da\User\Traits\AuthClientUserIdTrait;
use yii\authclient\clients\Google as BaseGoogle; use yii\authclient\clients\Google as BaseGoogle;
class Google extends BaseGoogle implements AuthClientInterface class Google extends BaseGoogle implements AuthClientInterface
{ {
use AuthClientUserIdTrait;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View File

@ -12,10 +12,13 @@
namespace Da\User\AuthClient; namespace Da\User\AuthClient;
use Da\User\Contracts\AuthClientInterface; use Da\User\Contracts\AuthClientInterface;
use Da\User\Traits\AuthClientUserIdTrait;
use yii\authclient\clients\LinkedIn as BaseLinkedIn; use yii\authclient\clients\LinkedIn as BaseLinkedIn;
class LinkedIn extends BaseLinkedIn implements AuthClientInterface class LinkedIn extends BaseLinkedIn implements AuthClientInterface
{ {
use AuthClientUserIdTrait;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View File

@ -12,10 +12,13 @@
namespace Da\User\AuthClient; namespace Da\User\AuthClient;
use Da\User\Contracts\AuthClientInterface; use Da\User\Contracts\AuthClientInterface;
use Da\User\Traits\AuthClientUserIdTrait;
use yii\authclient\clients\Twitter as BaseTwitter; use yii\authclient\clients\Twitter as BaseTwitter;
class Twitter extends BaseTwitter implements AuthClientInterface class Twitter extends BaseTwitter implements AuthClientInterface
{ {
use AuthClientUserIdTrait;
/** /**
* @return string * @return string
*/ */

View File

@ -12,11 +12,14 @@
namespace Da\User\AuthClient; namespace Da\User\AuthClient;
use Da\User\Contracts\AuthClientInterface; use Da\User\Contracts\AuthClientInterface;
use Da\User\Traits\AuthClientUserIdTrait;
use Yii; use Yii;
use yii\authclient\clients\VKontakte as BaseVKontakte; use yii\authclient\clients\VKontakte as BaseVKontakte;
class VKontakte extends BaseVKontakte implements AuthClientInterface class VKontakte extends BaseVKontakte implements AuthClientInterface
{ {
use AuthClientUserIdTrait;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View File

@ -12,11 +12,14 @@
namespace Da\User\AuthClient; namespace Da\User\AuthClient;
use Da\User\Contracts\AuthClientInterface; use Da\User\Contracts\AuthClientInterface;
use Da\User\Traits\AuthClientUserIdTrait;
use Yii; use Yii;
use yii\authclient\clients\Yandex as BaseYandex; use yii\authclient\clients\Yandex as BaseYandex;
class Yandex extends BaseYandex implements AuthClientInterface class Yandex extends BaseYandex implements AuthClientInterface
{ {
use AuthClientUserIdTrait;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View File

@ -14,8 +14,9 @@ namespace Da\User\Contracts;
use yii\authclient\ClientInterface; use yii\authclient\ClientInterface;
/** /**
* @property-read string $email * @property-read string|null $email
* @property-read string $username * @property-read string|null $userName
* @property-read mixed|null $userId
*/ */
interface AuthClientInterface extends ClientInterface interface AuthClientInterface extends ClientInterface
{ {
@ -28,4 +29,9 @@ interface AuthClientInterface extends ClientInterface
* @return string|null username * @return string|null username
*/ */
public function getUserName(); public function getUserName();
/**
* @return mixed|null user id
*/
public function getUserId();
} }

View File

@ -17,6 +17,7 @@ use Da\User\Event\UserEvent;
use Da\User\Factory\MailFactory; use Da\User\Factory\MailFactory;
use Da\User\Form\RegistrationForm; use Da\User\Form\RegistrationForm;
use Da\User\Form\ResendForm; use Da\User\Form\ResendForm;
use Da\User\Helper\SecurityHelper;
use Da\User\Model\SocialNetworkAccount; use Da\User\Model\SocialNetworkAccount;
use Da\User\Model\User; use Da\User\Model\User;
use Da\User\Query\SocialNetworkAccountQuery; use Da\User\Query\SocialNetworkAccountQuery;
@ -152,6 +153,10 @@ class RegistrationController extends Controller
*/ */
public function actionConnect($code) public function actionConnect($code)
{ {
if (!$this->module->enableSocialNetworkRegistration) {
throw new NotFoundHttpException();
}
/** @var SocialNetworkAccount $account */ /** @var SocialNetworkAccount $account */
$account = $this->socialNetworkAccountQuery->whereCode($code)->one(); $account = $this->socialNetworkAccountQuery->whereCode($code)->one();
if ($account === null || $account->getIsConnected()) { if ($account === null || $account->getIsConnected()) {
@ -171,7 +176,11 @@ class RegistrationController extends Controller
if ($user->load(Yii::$app->request->post()) && $user->validate()) { if ($user->load(Yii::$app->request->post()) && $user->validate()) {
$this->trigger(SocialNetworkConnectEvent::EVENT_BEFORE_CONNECT, $event); $this->trigger(SocialNetworkConnectEvent::EVENT_BEFORE_CONNECT, $event);
$mailService = MailFactory::makeWelcomeMailerService($user); if ($this->module->sendWelcomeMailAfterSocialNetworkRegistration) {
$mailService = MailFactory::makeWelcomeMailerService($user);
} else {
$mailService = null;
}
if ($this->make(UserCreateService::class, [$user, $mailService])->run()) { if ($this->make(UserCreateService::class, [$user, $mailService])->run()) {
$account->connect($user); $account->connect($user);
$this->trigger(SocialNetworkConnectEvent::EVENT_AFTER_CONNECT, $event); $this->trigger(SocialNetworkConnectEvent::EVENT_AFTER_CONNECT, $event);

View File

@ -117,6 +117,14 @@ class Module extends BaseModule
* @var bool whether to allow registration process or not * @var bool whether to allow registration process or not
*/ */
public $enableRegistration = true; public $enableRegistration = true;
/**
* @var bool whether to allow registration process for social network or not
*/
public $enableSocialNetworkRegistration = true;
/**
* @var bool whether to send a welcome mail after the registration process for social network
*/
public $sendWelcomeMailAfterSocialNetworkRegistration = true;
/** /**
* @var bool whether to force email confirmation to * @var bool whether to force email confirmation to
*/ */

View File

@ -83,7 +83,7 @@ class SocialNetworkAccountConnectService implements ServiceInterface
[], [],
[ [
'provider' => $this->client->getId(), 'provider' => $this->client->getId(),
'client_id' => $data['id'], 'client_id' => $this->client->getUserId(),
'data' => json_encode($data), 'data' => json_encode($data),
] ]
); );

View File

@ -48,7 +48,7 @@ class SocialNetworkAuthenticateService implements ServiceInterface
public function run() public function run()
{ {
$account = $this->socialNetworkAccountQuery->whereClient($this->client)->one(); $account = $this->socialNetworkAccountQuery->whereClient($this->client)->one();
if (!$this->controller->module->enableRegistration && ($account === null || $account->user === null)) { if (!$this->controller->module->enableSocialNetworkRegistration && ($account === null || $account->user === null)) {
Yii::$app->session->setFlash('danger', Yii::t('usuario', 'Registration on this website is disabled')); Yii::$app->session->setFlash('danger', Yii::t('usuario', 'Registration on this website is disabled'));
$this->authAction->setSuccessUrl(Url::to(['/user/security/login'])); $this->authAction->setSuccessUrl(Url::to(['/user/security/login']));
@ -97,7 +97,7 @@ class SocialNetworkAuthenticateService implements ServiceInterface
[], [],
[ [
'provider' => $this->client->getId(), 'provider' => $this->client->getId(),
'client_id' => $data['id'], 'client_id' => $this->client->getUserId(),
'data' => json_encode($data), 'data' => json_encode($data),
'username' => $this->client->getUserName(), 'username' => $this->client->getUserName(),
'email' => $this->client->getEmail(), 'email' => $this->client->getEmail(),
@ -106,7 +106,10 @@ class SocialNetworkAuthenticateService implements ServiceInterface
if (($user = $this->getUser($account)) instanceof User) { if (($user = $this->getUser($account)) instanceof User) {
$account->user_id = $user->id; $account->user_id = $user->id;
$account->save(false); }
if (!$account->save(false)) {
return null;
} }
return $account; return $account;

View File

@ -31,7 +31,7 @@ class UserCreateService implements ServiceInterface
protected $securityHelper; protected $securityHelper;
protected $mailService; protected $mailService;
public function __construct(User $model, MailService $mailService, SecurityHelper $securityHelper) public function __construct(User $model, ?MailService $mailService, SecurityHelper $securityHelper)
{ {
$this->model = $model; $this->model = $model;
$this->mailService = $mailService; $this->mailService = $mailService;
@ -70,7 +70,7 @@ class UserCreateService implements ServiceInterface
} }
$model->trigger(UserEvent::EVENT_AFTER_CREATE, $event); $model->trigger(UserEvent::EVENT_AFTER_CREATE, $event);
if (!$this->sendMail($model)) { if ($this->mailService instanceof MailService && !$this->sendMail($model)) {
$error_msg = Yii::t( $error_msg = Yii::t(
'usuario', 'usuario',
'Error sending welcome message to "{email}". Please try again later.', 'Error sending welcome message to "{email}". Please try again later.',

View File

@ -0,0 +1,14 @@
<?php
namespace Da\User\Traits;
trait AuthClientUserIdTrait
{
/**
* @see \Da\User\Contracts\AuthClientInterface::getUserId()
*/
public function getUserId()
{
return $this->getUserAttributes()['id'] ?? null;
}
}