1
0
mirror of https://github.com/flarum/core.git synced 2025-08-04 07:27:39 +02:00

Add external authenticator (social login) API

Allows registrations to be completed with a pre-confirmed email address
and no password.
This commit is contained in:
Toby Zerner
2015-09-15 11:27:31 +09:30
parent 53f7112248
commit 6beb4fe898
27 changed files with 516 additions and 96 deletions

View File

@@ -13,7 +13,6 @@ namespace Flarum\Core\Users\Commands;
use Flarum\Core\Users\UserRepository;
use Flarum\Events\UserWillBeSaved;
use Flarum\Core\Support\DispatchesEvents;
use Flarum\Core\Exceptions\InvalidConfirmationTokenException;
use Flarum\Core\Users\EmailToken;
use DateTime;
@@ -36,16 +35,14 @@ class ConfirmEmailHandler
/**
* @param ConfirmEmail $command
* @return \Flarum\Core\Users\User
*
* @throws InvalidConfirmationTokenException
*
* @return \Flarum\Core\Users\User
*/
public function handle(ConfirmEmail $command)
{
$token = EmailToken::find($command->token);
if (! $token || $token->created_at < new DateTime('-1 day')) {
throw new InvalidConfirmationTokenException;
}
$token = EmailToken::validOrFail($command->token);
$user = $token->user;
$user->changeEmail($token->email);

View File

@@ -11,17 +11,25 @@
namespace Flarum\Core\Users\Commands;
use Flarum\Core\Users\User;
use Flarum\Core\Users\EmailToken;
use Flarum\Events\UserWillBeSaved;
use Flarum\Core\Support\DispatchesEvents;
use Flarum\Core\Settings\SettingsRepository;
use Flarum\Core\Exceptions\PermissionDeniedException;
use DateTime;
class RegisterUserHandler
{
use DispatchesEvents;
/**
* @var SettingsRepository
*/
protected $settings;
/**
* @param SettingsRepository $settings
*/
public function __construct(SettingsRepository $settings)
{
$this->settings = $settings;
@@ -29,27 +37,57 @@ class RegisterUserHandler
/**
* @param RegisterUser $command
*
* @throws PermissionDeniedException if signup is closed and the actor is
* not an administrator.
* @throws \Flarum\Core\Exceptions\InvalidConfirmationTokenException if an
* email confirmation token is provided but is invalid.
*
* @return User
* @throws PermissionDeniedException
*/
public function handle(RegisterUser $command)
{
if (! $this->settings->get('allow_sign_up')) {
throw new PermissionDeniedException;
}
$actor = $command->actor;
$data = $command->data;
if (! $this->settings->get('allow_sign_up') && ! $actor->isAdmin()) {
throw new PermissionDeniedException;
}
// If a valid email confirmation token was provided as an attribute,
// then we can create a random password for this user and consider their
// email address confirmed.
if (isset($data['attributes']['token'])) {
$token = EmailToken::whereNull('user_id')->validOrFail($data['attributes']['token']);
$email = $token->email;
$password = array_get($data, 'attributes.password', str_random(20));
} else {
$email = array_get($data, 'attributes.email');
$password = array_get($data, 'attributes.password');
}
// Create the user's new account. If their email was set via token, then
// we can activate their account from the get-go, and they won't need
// to confirm their email address.
$user = User::register(
array_get($data, 'attributes.username'),
array_get($data, 'attributes.email'),
array_get($data, 'attributes.password')
$email,
$password
);
if (isset($token)) {
$user->activate();
}
event(new UserWillBeSaved($user, $actor, $data));
$user->save();
if (isset($token)) {
$token->delete();
}
$this->dispatchEventsFor($user);
return $user;

View File

@@ -11,6 +11,8 @@
namespace Flarum\Core\Users;
use Flarum\Core\Model;
use Flarum\Core\Exceptions\InvalidConfirmationTokenException;
use DateTime;
/**
* @todo document database columns with @property
@@ -37,11 +39,12 @@ class EmailToken extends Model
/**
* Generate an email token for the specified user.
*
* @param int $userId
* @param string $email
* @param int $userId
*
* @return static
*/
public static function generate($userId, $email)
public static function generate($email, $userId = null)
{
$token = new static;
@@ -62,4 +65,25 @@ class EmailToken extends Model
{
return $this->belongsTo('Flarum\Core\Users\User');
}
/**
* Find the token with the given ID, and assert that it has not expired.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param string $id
*
* @throws InvalidConfirmationTokenException
*
* @return static
*/
public function scopeValidOrFail($query, $id)
{
$token = $query->find($id);
if (! $token || $token->created_at < new DateTime('-1 day')) {
throw new InvalidConfirmationTokenException;
}
return $token;
}
}

View File

@@ -57,6 +57,11 @@ class EmailConfirmationMailer
public function whenUserWasRegistered(UserWasRegistered $event)
{
$user = $event->user;
if ($user->is_activated) {
return;
}
$data = $this->getEmailData($user, $user->email);
$this->mailer->send(['text' => 'flarum::emails.activateAccount'], $data, function (Message $message) use ($user) {
@@ -82,11 +87,12 @@ class EmailConfirmationMailer
/**
* @param User $user
* @param string $email
*
* @return EmailToken
*/
protected function generateToken(User $user, $email)
{
$token = EmailToken::generate($user->id, $email);
$token = EmailToken::generate($email, $user->id);
$token->save();
return $token;
@@ -97,6 +103,7 @@ class EmailConfirmationMailer
*
* @param User $user
* @param string $email
*
* @return array
*/
protected function getEmailData(User $user, $email)