OAuth (part 4 draft)
This commit is contained in:
parent
32d9aed7c1
commit
76350bc12e
5 changed files with 140 additions and 3 deletions
app
|
@ -499,6 +499,11 @@ class Update extends Admin
|
|||
'\\ForkBB\\Models\\Pages\\RegLog::class',
|
||||
'Register'
|
||||
);
|
||||
$coreConfig->add(
|
||||
'shared=>providerUser',
|
||||
'\\ForkBB\\Models\\ProviderUser\\ProviderUser::class',
|
||||
'providers'
|
||||
);
|
||||
|
||||
$coreConfig->save();
|
||||
|
||||
|
|
|
@ -22,6 +22,11 @@ class Auth extends Page
|
|||
{
|
||||
use RegLogTrait;
|
||||
|
||||
/**
|
||||
* Флаг входа c использованием html формы
|
||||
*/
|
||||
protected bool $loginWithForm = true;
|
||||
|
||||
/**
|
||||
* Выход пользователя
|
||||
*/
|
||||
|
@ -59,6 +64,24 @@ class Auth extends Page
|
|||
$v = null;
|
||||
|
||||
if ('POST' === $method) {
|
||||
// вход без html формы
|
||||
if (
|
||||
isset($args['user'])
|
||||
&& $args['user'] instanceof User
|
||||
) {
|
||||
$this->userAfterLogin = $args['user'];
|
||||
$this->loginWithForm = false;
|
||||
|
||||
$_POST = [
|
||||
'token' => $this->c->Csrf->create('Login'),
|
||||
'redirect' => $this->c->Csrf->create('Index'),
|
||||
'username' => $this->userAfterLogin->username,
|
||||
'password' => $this->userAfterLogin->password,
|
||||
'save' => '1',
|
||||
'login' => 'Login User model',
|
||||
];
|
||||
}
|
||||
|
||||
$v = $this->c->Validator->reset()
|
||||
->addValidators([
|
||||
'login_check' => [$this, 'vLoginCheck'],
|
||||
|
@ -188,7 +211,9 @@ class Auth extends Page
|
|||
public function vLoginCheck(Validator $v, #[SensitiveParameter] string $password ): string
|
||||
{
|
||||
if (empty($v->getErrors())) {
|
||||
$this->userAfterLogin = $this->c->users->loadByName($v->username);
|
||||
if ($this->loginWithForm) {
|
||||
$this->userAfterLogin = $this->c->users->loadByName($v->username);
|
||||
}
|
||||
|
||||
if (
|
||||
! $this->userAfterLogin instanceof User
|
||||
|
@ -197,7 +222,10 @@ class Auth extends Page
|
|||
$v->addError('Wrong user/pass');
|
||||
} elseif ($this->userAfterLogin->isUnverified) {
|
||||
$v->addError('Account is not activated', 'w');
|
||||
} elseif (! \password_verify($password, $this->userAfterLogin->password)) {
|
||||
} elseif (
|
||||
$this->loginWithForm
|
||||
&& ! \password_verify($password, $this->userAfterLogin->password)
|
||||
) {
|
||||
$v->addError('Wrong user/pass');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,6 +80,28 @@ class RegLog extends Page
|
|||
}
|
||||
}
|
||||
|
||||
exit(var_dump($provider->userId, $provider->userName, $provider->userEmail));
|
||||
// гость
|
||||
if ($this->user->isGuest) {
|
||||
$uid = $this->c->providerUser->findUser($provider);
|
||||
|
||||
// логин
|
||||
if ($uid > 0) {
|
||||
$args = [
|
||||
'user' => $this->c->users->load($uid),
|
||||
];
|
||||
|
||||
return $this->c->Auth->login($args, 'POST');
|
||||
|
||||
// регистрация
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
// пользователь
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
exit(var_dump($provider->userId, $provider->userName, $provider->userEmail, $this->c->NormEmail->normalize($provider->userEmail)));
|
||||
}
|
||||
}
|
||||
|
|
81
app/Models/ProviderUser/ProviderUser.php
Normal file
81
app/Models/ProviderUser/ProviderUser.php
Normal file
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of the ForkBB <https://github.com/forkbb>.
|
||||
*
|
||||
* @copyright (c) Visman <mio.visman@yandex.ru, https://github.com/MioVisman>
|
||||
* @license The MIT License (MIT)
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ForkBB\Models\ProviderUser;
|
||||
|
||||
use ForkBB\Core\Container;
|
||||
use ForkBB\Models\Model;
|
||||
use ForkBB\Models\Provider\Driver;
|
||||
use PDO;
|
||||
use RuntimeException;
|
||||
|
||||
class ProviderUser extends Model
|
||||
{
|
||||
/**
|
||||
* Ключ модели для контейнера
|
||||
*/
|
||||
protected string $cKey = 'ProvUser';
|
||||
|
||||
/**
|
||||
* Возращает id локального пользователя по данным провайдера или 0
|
||||
* Поиск идет по провайдеру и идентификатору пользователя
|
||||
*/
|
||||
public function findUser(Driver $provider): int
|
||||
{
|
||||
if ('' == $provider->userId) {
|
||||
throw new RuntimeException('The user ID is empty');
|
||||
}
|
||||
|
||||
$vars = [
|
||||
':name' => $provider->name,
|
||||
':id' => $provider->userId,
|
||||
];
|
||||
$query = 'SELECT pu.uid
|
||||
FROM ::providers_users AS pu
|
||||
WHERE pu.pr_name=?s:name AND pu.pu_uid=?s:id';
|
||||
|
||||
$result = $this->c->DB->query($query, $vars)->fetchAll(PDO::FETCH_COLUMN);
|
||||
$count = \count($result);
|
||||
|
||||
if ($count > 1) {
|
||||
throw new RuntimeException("Many entries for '{$provider->name}-{$provider->userId}'");
|
||||
}
|
||||
|
||||
return $count ? \array_pop($result) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возращает id локального пользователя по данным провайдера или 0
|
||||
* Поиск идет по email
|
||||
*/
|
||||
public function findEmail(Driver $provider): int
|
||||
{
|
||||
if ('' == $provider->userEmail) {
|
||||
throw new RuntimeException('The user email is empty');
|
||||
}
|
||||
|
||||
$vars = [
|
||||
':email' => $this->c->NormEmail->normalize($provider->userEmail),
|
||||
];
|
||||
$query = 'SELECT pu.uid
|
||||
FROM ::providers_users AS pu
|
||||
WHERE pu.pu_email_normal=?s:email
|
||||
GROUP BY pu.uid';
|
||||
|
||||
$result = $this->c->DB->query($query, $vars)->fetchAll(PDO::FETCH_COLUMN);
|
||||
$count = \count($result);
|
||||
|
||||
if ($count > 1) {
|
||||
throw new RuntimeException("Many entries for '{$provider->userEmail}'");
|
||||
}
|
||||
|
||||
return $count ? \array_pop($result) : 0;
|
||||
}
|
||||
}
|
|
@ -169,6 +169,7 @@ return [
|
|||
'github' => \ForkBB\Models\Provider\Driver\GitHub::class,
|
||||
],
|
||||
],
|
||||
'providerUser' => \ForkBB\Models\ProviderUser\ProviderUser::class,
|
||||
|
||||
'Csrf' => [
|
||||
'class' => \ForkBB\Core\Csrf::class,
|
||||
|
|
Loading…
Add table
Reference in a new issue