diff --git a/app/Controllers/Routing.php b/app/Controllers/Routing.php index 7cc00ab8..9f23dcfa 100644 --- a/app/Controllers/Routing.php +++ b/app/Controllers/Routing.php @@ -109,7 +109,7 @@ class Routing if (1 === $config->b_oauth_allow) { $r->add( $r::PST, - '/reglog/redirect', + '/reglog/redirect/{type}', 'RegLog:redirect', 'RegLogRedirect' ); diff --git a/app/Models/Pages/Auth.php b/app/Models/Pages/Auth.php index 02b18533..846ad7c1 100644 --- a/app/Models/Pages/Auth.php +++ b/app/Models/Pages/Auth.php @@ -128,7 +128,7 @@ class Auth extends Page $save = $v->save ?? true; $redirect = $v->redirect ?? $this->c->Router->validate($ref, 'Index'); $this->form = $this->formLogin($username, (bool) $save, $redirect); - $this->formOAuth = $this->reglogForm(); + $this->formOAuth = $this->reglogForm('auth'); return $this; } diff --git a/app/Models/Pages/Profile/OAuth.php b/app/Models/Pages/Profile/OAuth.php index 7c0abbe4..e5ce34eb 100644 --- a/app/Models/Pages/Profile/OAuth.php +++ b/app/Models/Pages/Profile/OAuth.php @@ -45,7 +45,7 @@ class OAuth extends Profile ] ); $this->form = $this->formList($args); - $this->formOAuth = $this->reglogForm(); + $this->formOAuth = $this->reglogForm('add'); $this->actionBtns = $this->btns('edit'); $this->profileIdSuffix = '-oauth'; diff --git a/app/Models/Pages/RegLog.php b/app/Models/Pages/RegLog.php index aca20b06..134efcfc 100644 --- a/app/Models/Pages/RegLog.php +++ b/app/Models/Pages/RegLog.php @@ -21,7 +21,7 @@ class RegLog extends Page /** * Обрабатывает нажатие одной из кнопок провайдеров */ - public function redirect(): Page + public function redirect(array $args): Page { if ( 1 !== $this->c->config->b_oauth_allow @@ -38,7 +38,7 @@ class RegLog extends Page $rules[$name] = 'string'; } - $v = $this->c->Validator->reset()->addRules($rules); + $v = $this->c->Validator->reset()->addRules($rules)->addArguments(['token' => $args]); if ( ! $v->validation($_POST) @@ -47,7 +47,7 @@ class RegLog extends Page return $this->c->Message->message('Bad request'); } - return $this->c->Redirect->url($this->c->providers->init()->get(\array_key_first($form))->linkAuth); + return $this->c->Redirect->url($this->c->providers->init()->get(\array_key_first($form))->linkAuth($args['type'])); } /** diff --git a/app/Models/Pages/RegLogTrait.php b/app/Models/Pages/RegLogTrait.php index c988da0f..714ac3e1 100644 --- a/app/Models/Pages/RegLogTrait.php +++ b/app/Models/Pages/RegLogTrait.php @@ -15,7 +15,7 @@ use function \ForkBB\__; trait RegLogTrait { - protected function reglogForm(): array + protected function reglogForm(string $type): array { if ( 1 !== $this->c->config->b_oauth_allow @@ -35,10 +35,12 @@ trait RegLogTrait ]; } + $args = ['type' => $type]; + return [ - 'action' => $this->c->Router->link('RegLogRedirect'), + 'action' => $this->c->Router->link('RegLogRedirect', $args), 'hidden' => [ - 'token' => $this->c->Csrf->create('RegLogRedirect'), + 'token' => $this->c->Csrf->create('RegLogRedirect', $args), ], 'sets' => [], 'btns' => $btns, diff --git a/app/Models/Pages/Register.php b/app/Models/Pages/Register.php index f61882fd..5e2116af 100644 --- a/app/Models/Pages/Register.php +++ b/app/Models/Pages/Register.php @@ -98,7 +98,7 @@ class Register extends Page $this->titles = 'Register'; $this->robots = 'noindex'; $this->form = $this->formReg($v); - $this->formOAuth = $this->reglogForm(); + $this->formOAuth = $this->reglogForm('reg'); return $this; } diff --git a/app/Models/Provider/Driver.php b/app/Models/Provider/Driver.php index 772707c3..7ac6a7d8 100644 --- a/app/Models/Provider/Driver.php +++ b/app/Models/Provider/Driver.php @@ -12,6 +12,7 @@ namespace ForkBB\Models\Provider; use ForkBB\Core\Container; use ForkBB\Models\Model; +use InvalidArgumentException; use RuntimeException; abstract class Driver extends Model @@ -79,12 +80,18 @@ abstract class Driver extends Model /** * Формирует ссылку авторизации на сервере провайдера */ - protected function getlinkAuth(): string + public function linkAuth(string $type): string { + if ('' == $type) { + throw new InvalidArgumentException('Expected non-empty type'); + } elseif (0 !== \preg_match('%[^a-zA-Z]%', $type)) { + throw new InvalidArgumentException('Invalid characters in type'); + } + $params = [ 'response_type' => 'code', 'scope' => $this->scope, - 'state' => $this->c->Csrf->createHash($this->origName, ['ip' => $this->c->user->ip]), + 'state' => $type . '_' . $this->c->Csrf->createHash($this->origName, ['ip' => $this->c->user->ip, 'type' => $type]), 'client_id' => $this->client_id, 'redirect_uri' => $this->linkCallback, ]; @@ -94,10 +101,19 @@ abstract class Driver extends Model /** * Проверяет правильность state + * Запоминает stateType */ protected function verifyState(string $state): bool { - return $this->c->Csrf->verify($state, $this->origName, ['ip' => $this->c->user->ip]); + $state = \explode('_', $state, 2); + + if (2 !== \count($state)) { + return false; + } + + $this->stateType = $state[0]; + + return $this->c->Csrf->verify($state[1], $this->origName, ['ip' => $this->c->user->ip, 'type' => $state[0]]); } /**