OAuth: Pass request type through provider

Needed to control the behavior of the authorization/registration algorithm without saving data to the session/cookies.
This commit is contained in:
Visman 2023-05-28 19:50:38 +07:00
parent 23afcdbb7b
commit 4d837f00c2
7 changed files with 31 additions and 13 deletions

View file

@ -109,7 +109,7 @@ class Routing
if (1 === $config->b_oauth_allow) {
$r->add(
$r::PST,
'/reglog/redirect',
'/reglog/redirect/{type}',
'RegLog:redirect',
'RegLogRedirect'
);

View file

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

View file

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

View file

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

View file

@ -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,

View file

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

View file

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