OAuth (part 4 draft)

This commit is contained in:
Visman 2023-05-09 22:01:01 +07:00
parent 32d9aed7c1
commit 76350bc12e
5 changed files with 140 additions and 3 deletions

View file

@ -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();

View file

@ -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');
}
}

View file

@ -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)));
}
}

View 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;
}
}

View file

@ -169,6 +169,7 @@ return [
'github' => \ForkBB\Models\Provider\Driver\GitHub::class,
],
],
'providerUser' => \ForkBB\Models\ProviderUser\ProviderUser::class,
'Csrf' => [
'class' => \ForkBB\Core\Csrf::class,