|
@@ -18,6 +18,8 @@ use function \ForkBB\__;
|
|
|
|
|
|
class RegLog extends Page
|
|
class RegLog extends Page
|
|
{
|
|
{
|
|
|
|
+ const TIMEOUT = 5;
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Обрабатывает нажатие одной из кнопок провайдеров
|
|
* Обрабатывает нажатие одной из кнопок провайдеров
|
|
*/
|
|
*/
|
|
@@ -70,7 +72,7 @@ class RegLog extends Page
|
|
|
|
|
|
foreach ($stages as $stage) {
|
|
foreach ($stages as $stage) {
|
|
$result = match ($stage) {
|
|
$result = match ($stage) {
|
|
- 1 => $provider->verifyAuth($_GET),
|
|
|
|
|
|
+ 1 => $provider->verifyAuth(),
|
|
2 => $provider->reqAccessToken(),
|
|
2 => $provider->reqAccessToken(),
|
|
3 => $provider->reqUserInfo(),
|
|
3 => $provider->reqUserInfo(),
|
|
};
|
|
};
|
|
@@ -82,132 +84,172 @@ class RegLog extends Page
|
|
|
|
|
|
$uid = $this->c->providerUser->findUser($provider);
|
|
$uid = $this->c->providerUser->findUser($provider);
|
|
|
|
|
|
- // гость
|
|
|
|
if ($this->user->isGuest) {
|
|
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 $auth->forget([], 'GET', $provider->userEmail);
|
|
|
|
- }
|
|
|
|
|
|
+ return $this->byGuest($provider, $uid);
|
|
|
|
+ } else {
|
|
|
|
+ return $this->byUser($provider, $uid);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- if (1 !== $this->c->config->b_regs_allow) {
|
|
|
|
- return $this->c->Message->message('No new regs');
|
|
|
|
- }
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Обрабатыет ответ для пользователя
|
|
|
|
+ */
|
|
|
|
+ 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');
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- $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 Failed image processing', [
|
|
|
|
- 'user' => $user->fLog(),
|
|
|
|
- 'error' => $image->error(),
|
|
|
|
- ]);
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- $this->c->Log->warning('OAuth Avatar not image', [
|
|
|
|
- 'user' => $user->fLog(),
|
|
|
|
- 'error' => $this->c->Files->error(),
|
|
|
|
- ]);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Обрабатыет ответ для гостя
|
|
|
|
+ */
|
|
|
|
+ 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');
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- $this->c->users->insert($user);
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Обрабатывает добавление нового аккаунта для пользователя
|
|
|
|
+ */
|
|
|
|
+ protected function addAccount(Driver $provider, int $uid): Page
|
|
|
|
+ {
|
|
|
|
+ $redirect = $this->c->Redirect->page('EditUserOAuth', ['id' => $this->user->id]);
|
|
|
|
|
|
- if (true !== $this->c->providerUser->registration($user, $provider)) {
|
|
|
|
- throw new RuntimeException('Failed to insert data'); // ??????????????????????????????????????????
|
|
|
|
- }
|
|
|
|
|
|
+ // аккаунт есть и он привязан к текущему пользователю
|
|
|
|
+ if ($uid === $this->user->id) {
|
|
|
|
+ return $redirect->message('Already linked to you', FORK_MESS_SUCC, self::TIMEOUT);
|
|
|
|
|
|
- $this->c->Log->info('OAuth Reg: ok', [
|
|
|
|
- 'user' => $user->fLog(),
|
|
|
|
- 'provider' => $provider->name,
|
|
|
|
- 'userInfo' => $provider->userInfo,
|
|
|
|
- 'headers' => true,
|
|
|
|
- ]);
|
|
|
|
|
|
+ // аккаунт есть и он привязан к другому пользователю
|
|
|
|
+ } elseif ($uid > 0) {
|
|
|
|
+ return $redirect->message('Already linked to another', FORK_MESS_WARN, self::TIMEOUT);
|
|
|
|
+ }
|
|
|
|
|
|
- } else {
|
|
|
|
- $user = $this->c->users->load($uid);
|
|
|
|
- }
|
|
|
|
|
|
+ $uid = $this->c->providerUser->findByEmail($provider->userEmail);
|
|
|
|
|
|
- // вход
|
|
|
|
- return $this->c->Auth->login([], 'POST', '', $user);
|
|
|
|
|
|
+ // email принадлежит другому пользователю
|
|
|
|
+ if (
|
|
|
|
+ $uid
|
|
|
|
+ && $uid !== $this->user->id
|
|
|
|
+ ) {
|
|
|
|
+ return $redirect->message(['Email registered by another', __($provider->name)], FORK_MESS_WARN, self::TIMEOUT);
|
|
|
|
+ }
|
|
|
|
|
|
- // пользователь
|
|
|
|
- } else {
|
|
|
|
- $redirect = $this->c->Redirect->page('EditUserOAuth', ['id' => $this->user->id]);
|
|
|
|
|
|
+ $user = $this->c->users->loadByEmail($provider->userEmail);
|
|
|
|
|
|
- // аккаунт есть и он привязан к текущему пользователю
|
|
|
|
- if ($uid === $this->user->id) {
|
|
|
|
- return $redirect->message('Already linked to you', FORK_MESS_SUCC, 5);
|
|
|
|
|
|
+ // email принадлежит другому пользователю
|
|
|
|
+ if (
|
|
|
|
+ $user instanceof User
|
|
|
|
+ && $user !== $this->user
|
|
|
|
+ ) {
|
|
|
|
+ return $redirect->message(['Email registered by another', __($provider->name)], FORK_MESS_WARN, self::TIMEOUT);
|
|
|
|
+ }
|
|
|
|
|
|
- // аккаунт есть и он привязан к другому пользователю
|
|
|
|
- } elseif ($uid > 0) {
|
|
|
|
- return $redirect->message('Already linked to another', FORK_MESS_WARN, 5);
|
|
|
|
- }
|
|
|
|
|
|
+ if (true !== $this->c->providerUser->registration($this->user, $provider)) {
|
|
|
|
+ throw new RuntimeException('Failed to insert data'); // ??????????????????????????????????????????
|
|
|
|
+ }
|
|
|
|
|
|
- $uid = $this->c->providerUser->findByEmail($provider->userEmail);
|
|
|
|
|
|
+ return $redirect->message('Account linked', FORK_MESS_SUCC);
|
|
|
|
+ }
|
|
|
|
|
|
- // email принадлежит другому пользователю
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Обрабатывает вход/регистрацию гостя
|
|
|
|
+ */
|
|
|
|
+ protected function authOrReg(Driver $provider, int $uid): Page
|
|
|
|
+ {
|
|
|
|
+ // регистрация
|
|
|
|
+ if (empty($uid)) {
|
|
|
|
+ // на форуме есть пользователь с таким email
|
|
if (
|
|
if (
|
|
- $uid
|
|
|
|
- && $uid !== $this->user->id
|
|
|
|
|
|
+ $this->c->providerUser->findByEmail($provider->userEmail) > 0
|
|
|
|
+ || $this->c->users->loadByEmail($provider->userEmail) instanceof User
|
|
) {
|
|
) {
|
|
- return $redirect->message(['Email registered by another', __($provider->name)], FORK_MESS_WARN, 5);
|
|
|
|
|
|
+ $auth = $this->c->Auth;
|
|
|
|
+ $auth->fIswev = [FORK_MESS_INFO, ['Email message', __($provider->name)]];
|
|
|
|
+
|
|
|
|
+ return $auth->forget([], 'GET', $provider->userEmail);
|
|
}
|
|
}
|
|
|
|
|
|
- $user = $this->c->users->loadByEmail($provider->userEmail);
|
|
|
|
|
|
+ if (1 !== $this->c->config->b_regs_allow) {
|
|
|
|
+ return $this->c->Message->message('No new regs');
|
|
|
|
+ }
|
|
|
|
|
|
- // email принадлежит другому пользователю
|
|
|
|
- if (
|
|
|
|
- $user instanceof User
|
|
|
|
- && $user !== $this->user
|
|
|
|
- ) {
|
|
|
|
- return $redirect->message(['Email registered by another', __($provider->name)], FORK_MESS_WARN, 5);
|
|
|
|
|
|
+ $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 Failed image processing', [
|
|
|
|
+ 'user' => $user->fLog(),
|
|
|
|
+ 'error' => $image->error(),
|
|
|
|
+ ]);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ $this->c->Log->warning('OAuth Avatar not image', [
|
|
|
|
+ 'user' => $user->fLog(),
|
|
|
|
+ 'error' => $this->c->Files->error(),
|
|
|
|
+ ]);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- if (true !== $this->c->providerUser->registration($this->user, $provider)) {
|
|
|
|
|
|
+ $this->c->users->insert($user);
|
|
|
|
+
|
|
|
|
+ if (true !== $this->c->providerUser->registration($user, $provider)) {
|
|
throw new RuntimeException('Failed to insert data'); // ??????????????????????????????????????????
|
|
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);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|