Update RegLog page

This commit is contained in:
Visman 2023-05-30 23:01:28 +07:00
parent 207ba891f5
commit 61c613123a
2 changed files with 151 additions and 109 deletions

View file

@ -18,6 +18,8 @@ use function \ForkBB\__;
class RegLog extends Page
{
const TIMEOUT = 5;
/**
* Обрабатывает нажатие одной из кнопок провайдеров
*/
@ -70,7 +72,7 @@ class RegLog extends Page
foreach ($stages as $stage) {
$result = match ($stage) {
1 => $provider->verifyAuth($_GET),
1 => $provider->verifyAuth(),
2 => $provider->reqAccessToken(),
3 => $provider->reqUserInfo(),
};
@ -82,132 +84,172 @@ class RegLog extends Page
$uid = $this->c->providerUser->findUser($provider);
// гость
if ($this->user->isGuest) {
// регистрация
if (empty($uid)) {
// на форуме есть пользователь с таким email
if (
$this->c->providerUser->findByEmail($provider->userEmail) > 0
|| $this->c->users->loadByEmail($provider->userEmail) instanceof User
) {
$auth = $this->c->Auth;
$auth->fIswev = [FORK_MESS_INFO, ['Email message', __($provider->name)]];
return $this->byGuest($provider, $uid);
} else {
return $this->byUser($provider, $uid);
}
}
return $auth->forget([], 'GET', $provider->userEmail);
}
/**
* Обрабатыет ответ для пользователя
*/
protected function byUser(Driver $provider, int $uid): Page
{
switch ($provider->stateType) {
case 'add':
return $this->addAccount($provider, $uid);
default:
return $this->c->Message->message('Bad request');
}
}
if (1 !== $this->c->config->b_regs_allow) {
return $this->c->Message->message('No new regs');
}
/**
* Обрабатыет ответ для гостя
*/
protected function byGuest(Driver $provider, int $uid): Page
{
switch ($provider->stateType) {
case 'reg':
case 'auth':
return $this->authOrReg($provider, $uid);
default:
return $this->c->Message->message('Bad request');
}
}
$user = $this->c->users->create();
/**
* Обрабатывает добавление нового аккаунта для пользователя
*/
protected function addAccount(Driver $provider, int $uid): Page
{
$redirect = $this->c->Redirect->page('EditUserOAuth', ['id' => $this->user->id]);
$user->username = $this->nameGenerator($provider);
$user->password = 'oauth_' . $this->c->Secury->randomPass(7);
$user->group_id = $this->c->config->i_default_user_group;
$user->email = $provider->userEmail;
$user->email_confirmed = $provider->userEmailVerifed ? 1 : 0;
$user->activate_string = '';
$user->u_mark_all_read = \time();
$user->email_setting = $this->c->config->i_default_email_setting;
$user->timezone = $this->c->config->o_default_timezone;
$user->language = $this->user->language;
$user->style = $this->user->style;
$user->registered = \time();
$user->registration_ip = $this->user->ip;
$user->ip_check_type = 0;
$user->signature = '';
$user->location = $provider->userLocation;
$user->url = $provider->userURL;
// аккаунт есть и он привязан к текущему пользователю
if ($uid === $this->user->id) {
return $redirect->message('Already linked to you', FORK_MESS_SUCC, self::TIMEOUT);
if ($provider->userAvatar) {
$image = $this->c->Files->uploadFromLink($provider->userAvatar);
// аккаунт есть и он привязан к другому пользователю
} elseif ($uid > 0) {
return $redirect->message('Already linked to another', FORK_MESS_WARN, self::TIMEOUT);
}
if ($image instanceof Image) {
$name = $this->c->Secury->randomPass(8);
$path = $this->c->DIR_PUBLIC . "{$this->c->config->o_avatars_dir}/{$name}.(webp|jpg|png|gif)";
$result = $image
->rename(true)
->rewrite(false)
->resize($this->c->config->i_avatars_width, $this->c->config->i_avatars_height)
->toFile($path, $this->c->config->i_avatars_size);
$uid = $this->c->providerUser->findByEmail($provider->userEmail);
if (true === $result) {
$user->avatar = $image->name() . '.' . $image->ext();
} else {
$this->c->Log->warning('OAuth Failed image processing', [
'user' => $user->fLog(),
'error' => $image->error(),
]);
}
// email принадлежит другому пользователю
if (
$uid
&& $uid !== $this->user->id
) {
return $redirect->message(['Email registered by another', __($provider->name)], FORK_MESS_WARN, self::TIMEOUT);
}
$user = $this->c->users->loadByEmail($provider->userEmail);
// email принадлежит другому пользователю
if (
$user instanceof User
&& $user !== $this->user
) {
return $redirect->message(['Email registered by another', __($provider->name)], FORK_MESS_WARN, self::TIMEOUT);
}
if (true !== $this->c->providerUser->registration($this->user, $provider)) {
throw new RuntimeException('Failed to insert data'); // ??????????????????????????????????????????
}
return $redirect->message('Account linked', FORK_MESS_SUCC);
}
/**
* Обрабатывает вход/регистрацию гостя
*/
protected function authOrReg(Driver $provider, int $uid): Page
{
// регистрация
if (empty($uid)) {
// на форуме есть пользователь с таким email
if (
$this->c->providerUser->findByEmail($provider->userEmail) > 0
|| $this->c->users->loadByEmail($provider->userEmail) instanceof User
) {
$auth = $this->c->Auth;
$auth->fIswev = [FORK_MESS_INFO, ['Email message', __($provider->name)]];
return $auth->forget([], 'GET', $provider->userEmail);
}
if (1 !== $this->c->config->b_regs_allow) {
return $this->c->Message->message('No new regs');
}
$user = $this->c->users->create();
$user->username = $this->nameGenerator($provider);
$user->password = 'oauth_' . $this->c->Secury->randomPass(7);
$user->group_id = $this->c->config->i_default_user_group;
$user->email = $provider->userEmail;
$user->email_confirmed = $provider->userEmailVerifed ? 1 : 0;
$user->activate_string = '';
$user->u_mark_all_read = \time();
$user->email_setting = $this->c->config->i_default_email_setting;
$user->timezone = $this->c->config->o_default_timezone;
$user->language = $this->user->language;
$user->style = $this->user->style;
$user->registered = \time();
$user->registration_ip = $this->user->ip;
$user->ip_check_type = 0;
$user->signature = '';
$user->location = $provider->userLocation;
$user->url = $provider->userURL;
if ($provider->userAvatar) {
$image = $this->c->Files->uploadFromLink($provider->userAvatar);
if ($image instanceof Image) {
$name = $this->c->Secury->randomPass(8);
$path = $this->c->DIR_PUBLIC . "{$this->c->config->o_avatars_dir}/{$name}.(webp|jpg|png|gif)";
$result = $image
->rename(true)
->rewrite(false)
->resize($this->c->config->i_avatars_width, $this->c->config->i_avatars_height)
->toFile($path, $this->c->config->i_avatars_size);
if (true === $result) {
$user->avatar = $image->name() . '.' . $image->ext();
} else {
$this->c->Log->warning('OAuth Avatar not image', [
$this->c->Log->warning('OAuth Failed image processing', [
'user' => $user->fLog(),
'error' => $this->c->Files->error(),
'error' => $image->error(),
]);
}
} else {
$this->c->Log->warning('OAuth Avatar not image', [
'user' => $user->fLog(),
'error' => $this->c->Files->error(),
]);
}
$this->c->users->insert($user);
if (true !== $this->c->providerUser->registration($user, $provider)) {
throw new RuntimeException('Failed to insert data'); // ??????????????????????????????????????????
}
$this->c->Log->info('OAuth Reg: ok', [
'user' => $user->fLog(),
'provider' => $provider->name,
'userInfo' => $provider->userInfo,
'headers' => true,
]);
} else {
$user = $this->c->users->load($uid);
}
// вход
return $this->c->Auth->login([], 'POST', '', $user);
$this->c->users->insert($user);
// пользователь
} else {
$redirect = $this->c->Redirect->page('EditUserOAuth', ['id' => $this->user->id]);
// аккаунт есть и он привязан к текущему пользователю
if ($uid === $this->user->id) {
return $redirect->message('Already linked to you', FORK_MESS_SUCC, 5);
// аккаунт есть и он привязан к другому пользователю
} elseif ($uid > 0) {
return $redirect->message('Already linked to another', FORK_MESS_WARN, 5);
}
$uid = $this->c->providerUser->findByEmail($provider->userEmail);
// email принадлежит другому пользователю
if (
$uid
&& $uid !== $this->user->id
) {
return $redirect->message(['Email registered by another', __($provider->name)], FORK_MESS_WARN, 5);
}
$user = $this->c->users->loadByEmail($provider->userEmail);
// email принадлежит другому пользователю
if (
$user instanceof User
&& $user !== $this->user
) {
return $redirect->message(['Email registered by another', __($provider->name)], FORK_MESS_WARN, 5);
}
if (true !== $this->c->providerUser->registration($this->user, $provider)) {
if (true !== $this->c->providerUser->registration($user, $provider)) {
throw new RuntimeException('Failed to insert data'); // ??????????????????????????????????????????
}
return $redirect->message('Account linked', FORK_MESS_SUCC);
$this->c->Log->info('OAuth Reg: ok', [
'user' => $user->fLog(),
'provider' => $provider->name,
'userInfo' => $provider->userInfo,
'headers' => true,
]);
} else {
$user = $this->c->users->load($uid);
}
// вход
return $this->c->Auth->login([], 'POST', '', $user);
}
/**

View file

@ -120,9 +120,9 @@ abstract class Driver extends Model
* Проверяет ответ сервера провайдера после авторизации пользователя
* Запоминает code
*/
public function verifyAuth(array $data): bool
public function verifyAuth(): bool
{
$data = $this->c->Secury->replInvalidChars($data);
$data = $this->c->Secury->replInvalidChars($_GET);
$this->code = '';
if (! \is_string($data['code'] ?? null)) {