mirror of
https://github.com/elyby/accounts.git
synced 2025-05-31 14:11:46 +05:30
Implementation of the backend for the OAuth2 clients management
This commit is contained in:
@@ -18,14 +18,12 @@ class ClientStorage extends AbstractStorage implements ClientInterface {
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function get($clientId, $clientSecret = null, $redirectUri = null, $grantType = null) {
|
||||
$query = OauthClient::find()->andWhere(['id' => $clientId]);
|
||||
if ($clientSecret !== null) {
|
||||
$query->andWhere(['secret' => $clientSecret]);
|
||||
$model = $this->findClient($clientId);
|
||||
if ($model === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var OauthClient|null $model */
|
||||
$model = $query->one();
|
||||
if ($model === null) {
|
||||
if ($clientSecret !== null && $clientSecret !== $model->secret) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -60,8 +58,7 @@ class ClientStorage extends AbstractStorage implements ClientInterface {
|
||||
throw new \ErrorException('This module assumes that $session typeof ' . SessionEntity::class);
|
||||
}
|
||||
|
||||
/** @var OauthClient|null $model */
|
||||
$model = OauthClient::findOne($session->getClientId());
|
||||
$model = $this->findClient($session->getClientId());
|
||||
if ($model === null) {
|
||||
return null;
|
||||
}
|
||||
@@ -80,4 +77,8 @@ class ClientStorage extends AbstractStorage implements ClientInterface {
|
||||
return $entity;
|
||||
}
|
||||
|
||||
private function findClient(string $clientId): ?OauthClient {
|
||||
return OauthClient::findOne($clientId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -86,5 +86,6 @@ return [
|
||||
'mojang' => api\modules\mojang\Module::class,
|
||||
'internal' => api\modules\internal\Module::class,
|
||||
'accounts' => api\modules\accounts\Module::class,
|
||||
'oauth' => api\modules\oauth\Module::class,
|
||||
],
|
||||
];
|
||||
|
@@ -3,8 +3,17 @@
|
||||
* @var array $params
|
||||
*/
|
||||
return [
|
||||
'/oauth2/v1/<action>' => 'oauth/<action>',
|
||||
// Oauth module routes
|
||||
'/oauth2/v1/<action>' => 'oauth/authorization/<action>',
|
||||
'POST /v1/oauth2/<type>' => 'oauth/clients/create',
|
||||
'GET /v1/oauth2/<clientId>' => 'oauth/clients/get',
|
||||
'PUT /v1/oauth2/<clientId>' => 'oauth/clients/update',
|
||||
'DELETE /v1/oauth2/<clientId>' => 'oauth/clients/delete',
|
||||
'POST /v1/oauth2/<clientId>/reset' => 'oauth/clients/reset',
|
||||
'GET /v1/accounts/<accountId:\d+>/oauth2/clients' => 'oauth/clients/get-per-account',
|
||||
'/account/v1/info' => 'oauth/identity/index',
|
||||
|
||||
// Accounts module routes
|
||||
'GET /v1/accounts/<id:\d+>' => 'accounts/default/get',
|
||||
'GET /v1/accounts/<id:\d+>/two-factor-auth' => 'accounts/default/get-two-factor-auth-credentials',
|
||||
'POST /v1/accounts/<id:\d+>/two-factor-auth' => 'accounts/default/enable-two-factor-auth',
|
||||
@@ -13,6 +22,7 @@ return [
|
||||
'DELETE /v1/accounts/<id:\d+>/ban' => 'accounts/default/pardon',
|
||||
'/v1/accounts/<id:\d+>/<action>' => 'accounts/default/<action>',
|
||||
|
||||
// Legacy accounts endpoints. It should be removed after frontend will be updated.
|
||||
'GET /accounts/current' => 'accounts/default/get',
|
||||
'POST /accounts/change-username' => 'accounts/default/username',
|
||||
'POST /accounts/change-password' => 'accounts/default/password',
|
||||
@@ -25,14 +35,14 @@ return [
|
||||
'DELETE /two-factor-auth' => 'accounts/default/disable-two-factor-auth',
|
||||
'POST /accounts/change-lang' => 'accounts/default/language',
|
||||
|
||||
'/account/v1/info' => 'identity-info/index',
|
||||
|
||||
// Session server module routes
|
||||
'/minecraft/session/join' => 'session/session/join',
|
||||
'/minecraft/session/legacy/join' => 'session/session/join-legacy',
|
||||
'/minecraft/session/hasJoined' => 'session/session/has-joined',
|
||||
'/minecraft/session/legacy/hasJoined' => 'session/session/has-joined-legacy',
|
||||
'/minecraft/session/profile/<uuid>' => 'session/session/profile',
|
||||
|
||||
// Mojang API module routes
|
||||
'/mojang/profiles/<username>' => 'mojang/api/uuid-by-username',
|
||||
'/mojang/profiles/<uuid>/names' => 'mojang/api/usernames-by-uuid',
|
||||
'POST /mojang/profiles' => 'mojang/api/uuids-by-usernames',
|
||||
|
10
api/modules/oauth/Module.php
Normal file
10
api/modules/oauth/Module.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace api\modules\oauth;
|
||||
|
||||
use yii\base\Module as BaseModule;
|
||||
|
||||
class Module extends BaseModule {
|
||||
|
||||
public $id = 'oauth';
|
||||
|
||||
}
|
@@ -1,16 +1,17 @@
|
||||
<?php
|
||||
namespace api\controllers;
|
||||
namespace api\modules\oauth\controllers;
|
||||
|
||||
use api\models\OauthProcess;
|
||||
use api\controllers\Controller;
|
||||
use api\modules\oauth\models\OauthProcess;
|
||||
use common\rbac\Permissions as P;
|
||||
use Yii;
|
||||
use yii\filters\AccessControl;
|
||||
use yii\helpers\ArrayHelper;
|
||||
|
||||
class OauthController extends Controller {
|
||||
class AuthorizationController extends Controller {
|
||||
|
||||
public function behaviors(): array {
|
||||
return ArrayHelper::merge(parent::behaviors(), [
|
||||
return ArrayHelper::merge(Controller::behaviors(), [
|
||||
'authenticator' => [
|
||||
'only' => ['complete'],
|
||||
],
|
192
api/modules/oauth/controllers/ClientsController.php
Normal file
192
api/modules/oauth/controllers/ClientsController.php
Normal file
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
namespace api\modules\oauth\controllers;
|
||||
|
||||
use api\controllers\Controller;
|
||||
use api\exceptions\ThisShouldNotHappenException;
|
||||
use api\modules\oauth\exceptions\UnsupportedOauthClientType;
|
||||
use api\modules\oauth\models\OauthClientForm;
|
||||
use api\modules\oauth\models\OauthClientFormFactory;
|
||||
use api\modules\oauth\models\OauthClientTypeForm;
|
||||
use common\models\Account;
|
||||
use common\models\OauthClient;
|
||||
use common\rbac\Permissions as P;
|
||||
use Yii;
|
||||
use yii\filters\AccessControl;
|
||||
use yii\helpers\ArrayHelper;
|
||||
use yii\web\NotFoundHttpException;
|
||||
|
||||
class ClientsController extends Controller {
|
||||
|
||||
public function behaviors(): array {
|
||||
return ArrayHelper::merge(parent::behaviors(), [
|
||||
'access' => [
|
||||
'class' => AccessControl::class,
|
||||
'rules' => [
|
||||
[
|
||||
'actions' => ['create'],
|
||||
'allow' => true,
|
||||
'permissions' => [P::CREATE_OAUTH_CLIENTS],
|
||||
],
|
||||
[
|
||||
'actions' => ['update', 'delete', 'reset'],
|
||||
'allow' => true,
|
||||
'permissions' => [P::MANAGE_OAUTH_CLIENTS],
|
||||
'roleParams' => function() {
|
||||
return [
|
||||
'clientId' => Yii::$app->request->get('clientId'),
|
||||
];
|
||||
},
|
||||
],
|
||||
[
|
||||
'actions' => ['get'],
|
||||
'allow' => true,
|
||||
'permissions' => [P::VIEW_OAUTH_CLIENTS],
|
||||
'roleParams' => function() {
|
||||
return [
|
||||
'clientId' => Yii::$app->request->get('clientId'),
|
||||
];
|
||||
},
|
||||
],
|
||||
[
|
||||
'actions' => ['get-per-account'],
|
||||
'allow' => true,
|
||||
'permissions' => [P::VIEW_OAUTH_CLIENTS],
|
||||
'roleParams' => function() {
|
||||
return [
|
||||
'accountId' => Yii::$app->request->get('accountId'),
|
||||
];
|
||||
},
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function actionGet(string $clientId): array {
|
||||
return $this->formatClient($this->findOauthClient($clientId));
|
||||
}
|
||||
|
||||
public function actionCreate(string $type): array {
|
||||
$account = Yii::$app->user->identity->getAccount();
|
||||
if ($account === null) {
|
||||
throw new ThisShouldNotHappenException('This form should not to be executed without associated account');
|
||||
}
|
||||
|
||||
$client = new OauthClient();
|
||||
$client->account_id = $account->id;
|
||||
$client->type = $type;
|
||||
$requestModel = $this->createForm($client);
|
||||
$requestModel->load(Yii::$app->request->post());
|
||||
$form = new OauthClientForm($client);
|
||||
if (!$form->save($requestModel)) {
|
||||
return [
|
||||
'success' => false,
|
||||
'errors' => $requestModel->getValidationErrors(),
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'data' => $this->formatClient($client),
|
||||
];
|
||||
}
|
||||
|
||||
public function actionUpdate(string $clientId): array {
|
||||
$client = $this->findOauthClient($clientId);
|
||||
$requestModel = $this->createForm($client);
|
||||
$requestModel->load(Yii::$app->request->post());
|
||||
$form = new OauthClientForm($client);
|
||||
if (!$form->save($requestModel)) {
|
||||
return [
|
||||
'success' => false,
|
||||
'errors' => $requestModel->getValidationErrors(),
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'data' => $this->formatClient($client),
|
||||
];
|
||||
}
|
||||
|
||||
public function actionDelete(string $clientId): array {
|
||||
$client = $this->findOauthClient($clientId);
|
||||
(new OauthClientForm($client))->delete();
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
];
|
||||
}
|
||||
|
||||
public function actionReset(string $clientId, string $regenerateSecret = null): array {
|
||||
$client = $this->findOauthClient($clientId);
|
||||
$form = new OauthClientForm($client);
|
||||
$form->reset($regenerateSecret !== null);
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'data' => $this->formatClient($client),
|
||||
];
|
||||
}
|
||||
|
||||
public function actionGetPerAccount(int $accountId): array {
|
||||
/** @var Account|null $account */
|
||||
$account = Account::findOne(['id' => $accountId]);
|
||||
if ($account === null) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
|
||||
$clients = $account->oauthClients;
|
||||
$result = array_map(function(OauthClient $client) {
|
||||
return $this->formatClient($client);
|
||||
}, $clients);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function formatClient(OauthClient $client): array {
|
||||
$result = [
|
||||
'clientId' => $client->id,
|
||||
'clientSecret' => $client->secret,
|
||||
'type' => $client->type,
|
||||
'name' => $client->name,
|
||||
'websiteUrl' => $client->website_url,
|
||||
'createdAt' => $client->created_at,
|
||||
'countUsers' => (int)$client->getSessions()->count(),
|
||||
];
|
||||
|
||||
switch ($client->type) {
|
||||
case OauthClient::TYPE_APPLICATION:
|
||||
$result['description'] = $client->description;
|
||||
$result['redirectUri'] = $client->redirect_uri;
|
||||
break;
|
||||
case OauthClient::TYPE_MINECRAFT_SERVER:
|
||||
$result['minecraftServerIp'] = $client->minecraft_server_ip;
|
||||
break;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function createForm(OauthClient $client): OauthClientTypeForm {
|
||||
try {
|
||||
$model = OauthClientFormFactory::create($client);
|
||||
} catch (UnsupportedOauthClientType $e) {
|
||||
Yii::warning('Someone tried use ' . $client->type . ' type of oauth form.');
|
||||
throw new NotFoundHttpException(null, 0, $e);
|
||||
}
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
private function findOauthClient(string $clientId): OauthClient {
|
||||
/** @var OauthClient|null $client */
|
||||
$client = OauthClient::findOne($clientId);
|
||||
if ($client === null) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
|
||||
return $client;
|
||||
}
|
||||
|
||||
}
|
@@ -1,16 +1,17 @@
|
||||
<?php
|
||||
namespace api\controllers;
|
||||
namespace api\modules\oauth\controllers;
|
||||
|
||||
use api\models\OauthAccountInfo;
|
||||
use api\controllers\Controller;
|
||||
use api\modules\oauth\models\IdentityInfo;
|
||||
use common\rbac\Permissions as P;
|
||||
use Yii;
|
||||
use yii\filters\AccessControl;
|
||||
use yii\helpers\ArrayHelper;
|
||||
|
||||
class IdentityInfoController extends Controller {
|
||||
class IdentityController extends Controller {
|
||||
|
||||
public function behaviors(): array {
|
||||
return ArrayHelper::merge(parent::behaviors(), [
|
||||
return ArrayHelper::merge(Controller::behaviors(), [
|
||||
'access' => [
|
||||
'class' => AccessControl::class,
|
||||
'rules' => [
|
||||
@@ -32,7 +33,7 @@ class IdentityInfoController extends Controller {
|
||||
|
||||
public function actionIndex(): array {
|
||||
/** @noinspection NullPointerExceptionInspection */
|
||||
return (new OauthAccountInfo(Yii::$app->user->getIdentity()->getAccount()))->info();
|
||||
return (new IdentityInfo(Yii::$app->user->getIdentity()->getAccount()))->info();
|
||||
}
|
||||
|
||||
}
|
8
api/modules/oauth/exceptions/InvalidOauthClientState.php
Normal file
8
api/modules/oauth/exceptions/InvalidOauthClientState.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
namespace api\modules\oauth\exceptions;
|
||||
|
||||
use yii\base\Exception;
|
||||
|
||||
class InvalidOauthClientState extends Exception implements OauthException {
|
||||
|
||||
}
|
7
api/modules/oauth/exceptions/OauthException.php
Normal file
7
api/modules/oauth/exceptions/OauthException.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace api\modules\oauth\exceptions;
|
||||
|
||||
interface OauthException {
|
||||
}
|
23
api/modules/oauth/exceptions/UnsupportedOauthClientType.php
Normal file
23
api/modules/oauth/exceptions/UnsupportedOauthClientType.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
namespace api\modules\oauth\exceptions;
|
||||
|
||||
use Throwable;
|
||||
use yii\base\Exception;
|
||||
|
||||
class UnsupportedOauthClientType extends Exception implements OauthException {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $type;
|
||||
|
||||
public function __construct(string $type, int $code = 0, Throwable $previous = null) {
|
||||
parent::__construct('Unsupported oauth client type', $code, $previous);
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
public function getType(): string {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
}
|
30
api/modules/oauth/models/ApplicationType.php
Normal file
30
api/modules/oauth/models/ApplicationType.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace api\modules\oauth\models;
|
||||
|
||||
use common\helpers\Error as E;
|
||||
use common\models\OauthClient;
|
||||
use yii\helpers\ArrayHelper;
|
||||
|
||||
class ApplicationType extends BaseOauthClientType {
|
||||
|
||||
public $description;
|
||||
|
||||
public $redirectUri;
|
||||
|
||||
public function rules(): array {
|
||||
return ArrayHelper::merge(parent::rules(), [
|
||||
['redirectUri', 'required', 'message' => E::REDIRECT_URI_REQUIRED],
|
||||
['redirectUri', 'url', 'validSchemes' => ['[\w]+'], 'message' => E::REDIRECT_URI_INVALID],
|
||||
['description', 'string'],
|
||||
]);
|
||||
}
|
||||
|
||||
public function applyToClient(OauthClient $client): void {
|
||||
parent::applyToClient($client);
|
||||
$client->description = $this->description;
|
||||
$client->redirect_uri = $this->redirectUri;
|
||||
}
|
||||
|
||||
}
|
40
api/modules/oauth/models/BaseOauthClientType.php
Normal file
40
api/modules/oauth/models/BaseOauthClientType.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace api\modules\oauth\models;
|
||||
|
||||
use api\models\base\ApiForm;
|
||||
use common\helpers\Error as E;
|
||||
use common\models\OauthClient;
|
||||
|
||||
abstract class BaseOauthClientType extends ApiForm implements OauthClientTypeForm {
|
||||
|
||||
public $name;
|
||||
|
||||
public $websiteUrl;
|
||||
|
||||
public function rules(): array {
|
||||
return [
|
||||
['name', 'required', 'message' => E::NAME_REQUIRED],
|
||||
['websiteUrl', 'url', 'message' => E::WEBSITE_URL_INVALID],
|
||||
];
|
||||
}
|
||||
|
||||
public function load($data, $formName = null): bool {
|
||||
return parent::load($data, $formName);
|
||||
}
|
||||
|
||||
public function validate($attributeNames = null, $clearErrors = true): bool {
|
||||
return parent::validate($attributeNames, $clearErrors);
|
||||
}
|
||||
|
||||
public function getValidationErrors(): array {
|
||||
return $this->getFirstErrors();
|
||||
}
|
||||
|
||||
public function applyToClient(OauthClient $client): void {
|
||||
$client->name = $this->name;
|
||||
$client->website_url = $this->websiteUrl;
|
||||
}
|
||||
|
||||
}
|
@@ -1,11 +1,13 @@
|
||||
<?php
|
||||
namespace api\models;
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace api\modules\oauth\models;
|
||||
|
||||
use api\models\base\BaseAccountForm;
|
||||
use api\modules\accounts\models\AccountInfo;
|
||||
use common\models\Account;
|
||||
|
||||
class OauthAccountInfo extends BaseAccountForm {
|
||||
class IdentityInfo extends BaseAccountForm {
|
||||
|
||||
private $model;
|
||||
|
26
api/modules/oauth/models/MinecraftServerType.php
Normal file
26
api/modules/oauth/models/MinecraftServerType.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace api\modules\oauth\models;
|
||||
|
||||
use common\helpers\Error as E;
|
||||
use common\models\OauthClient;
|
||||
use common\validators\MinecraftServerAddressValidator;
|
||||
use yii\helpers\ArrayHelper;
|
||||
|
||||
class MinecraftServerType extends BaseOauthClientType {
|
||||
|
||||
public $minecraftServerIp;
|
||||
|
||||
public function rules(): array {
|
||||
return ArrayHelper::merge(parent::rules(), [
|
||||
['minecraftServerIp', MinecraftServerAddressValidator::class, 'message' => E::MINECRAFT_SERVER_IP_INVALID],
|
||||
]);
|
||||
}
|
||||
|
||||
public function applyToClient(OauthClient $client): void {
|
||||
parent::applyToClient($client);
|
||||
$client->minecraft_server_ip = $this->minecraftServerIp;
|
||||
}
|
||||
|
||||
}
|
96
api/modules/oauth/models/OauthClientForm.php
Normal file
96
api/modules/oauth/models/OauthClientForm.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace api\modules\oauth\models;
|
||||
|
||||
use api\exceptions\ThisShouldNotHappenException;
|
||||
use api\modules\oauth\exceptions\InvalidOauthClientState;
|
||||
use common\models\OauthClient;
|
||||
use common\tasks\ClearOauthSessions;
|
||||
use Yii;
|
||||
use yii\helpers\Inflector;
|
||||
|
||||
class OauthClientForm {
|
||||
|
||||
/**
|
||||
* @var OauthClient
|
||||
*/
|
||||
private $client;
|
||||
|
||||
public function __construct(OauthClient $client) {
|
||||
if ($client->type === null) {
|
||||
throw new InvalidOauthClientState('client\'s type field must be set');
|
||||
}
|
||||
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
public function getClient(): OauthClient {
|
||||
return $this->client;
|
||||
}
|
||||
|
||||
public function save(OauthClientTypeForm $form): bool {
|
||||
if (!$form->validate()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$client = $this->getClient();
|
||||
$form->applyToClient($client);
|
||||
|
||||
if ($client->isNewRecord) {
|
||||
$baseId = $id = substr(Inflector::slug($client->name), 0, 250);
|
||||
$i = 0;
|
||||
while ($this->isClientExists($id)) {
|
||||
$id = $baseId . ++$i;
|
||||
}
|
||||
|
||||
$client->id = $id;
|
||||
$client->generateSecret();
|
||||
}
|
||||
|
||||
if (!$client->save()) {
|
||||
throw new ThisShouldNotHappenException('Cannot save oauth client');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function delete(): bool {
|
||||
$transaction = Yii::$app->db->beginTransaction();
|
||||
|
||||
$client = $this->client;
|
||||
$client->is_deleted = true;
|
||||
if (!$client->save()) {
|
||||
throw new ThisShouldNotHappenException('Cannot update oauth client');
|
||||
}
|
||||
|
||||
Yii::$app->queue->push(ClearOauthSessions::createFromOauthClient($client));
|
||||
|
||||
$transaction->commit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function reset(bool $regenerateSecret = false): bool {
|
||||
$transaction = Yii::$app->db->beginTransaction();
|
||||
|
||||
$client = $this->client;
|
||||
if ($regenerateSecret) {
|
||||
$client->generateSecret();
|
||||
if (!$client->save()) {
|
||||
throw new ThisShouldNotHappenException('Cannot update oauth client');
|
||||
}
|
||||
}
|
||||
|
||||
Yii::$app->queue->push(ClearOauthSessions::createFromOauthClient($client, time()));
|
||||
|
||||
$transaction->commit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function isClientExists(string $id): bool {
|
||||
return OauthClient::find()->andWhere(['id' => $id])->exists();
|
||||
}
|
||||
|
||||
}
|
37
api/modules/oauth/models/OauthClientFormFactory.php
Normal file
37
api/modules/oauth/models/OauthClientFormFactory.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace api\modules\oauth\models;
|
||||
|
||||
use api\modules\oauth\exceptions\UnsupportedOauthClientType;
|
||||
use common\models\OauthClient;
|
||||
|
||||
class OauthClientFormFactory {
|
||||
|
||||
/**
|
||||
* @param OauthClient $client
|
||||
*
|
||||
* @return OauthClientTypeForm
|
||||
* @throws UnsupportedOauthClientType
|
||||
*/
|
||||
public static function create(OauthClient $client): OauthClientTypeForm {
|
||||
switch ($client->type) {
|
||||
case OauthClient::TYPE_APPLICATION:
|
||||
return new ApplicationType([
|
||||
'name' => $client->name,
|
||||
'websiteUrl' => $client->website_url,
|
||||
'description' => $client->description,
|
||||
'redirectUri' => $client->redirect_uri,
|
||||
]);
|
||||
case OauthClient::TYPE_MINECRAFT_SERVER:
|
||||
return new MinecraftServerType([
|
||||
'name' => $client->name,
|
||||
'websiteUrl' => $client->website_url,
|
||||
'minecraftServerIp' => $client->minecraft_server_ip,
|
||||
]);
|
||||
}
|
||||
|
||||
throw new UnsupportedOauthClientType($client->type);
|
||||
}
|
||||
|
||||
}
|
18
api/modules/oauth/models/OauthClientTypeForm.php
Normal file
18
api/modules/oauth/models/OauthClientTypeForm.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace api\modules\oauth\models;
|
||||
|
||||
use common\models\OauthClient;
|
||||
|
||||
interface OauthClientTypeForm {
|
||||
|
||||
public function load($data): bool;
|
||||
|
||||
public function validate(): bool;
|
||||
|
||||
public function getValidationErrors(): array;
|
||||
|
||||
public function applyToClient(OauthClient $client): void;
|
||||
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace api\models;
|
||||
namespace api\modules\oauth\models;
|
||||
|
||||
use api\components\OAuth2\Exception\AcceptRequiredException;
|
||||
use api\components\OAuth2\Exception\AccessDeniedException;
|
||||
@@ -52,8 +52,8 @@ class OauthProcess {
|
||||
try {
|
||||
$authParams = $this->getAuthorizationCodeGrant()->checkAuthorizeParams();
|
||||
$client = $authParams->getClient();
|
||||
/** @var \common\models\OauthClient $clientModel */
|
||||
$clientModel = OauthClient::findOne($client->getId());
|
||||
/** @var OauthClient $clientModel */
|
||||
$clientModel = $this->findClient($client->getId());
|
||||
$response = $this->buildSuccessResponse(
|
||||
Yii::$app->request->getQueryParams(),
|
||||
$clientModel,
|
||||
@@ -90,9 +90,10 @@ class OauthProcess {
|
||||
Yii::$app->statsd->inc('oauth.complete.attempt');
|
||||
$grant = $this->getAuthorizationCodeGrant();
|
||||
$authParams = $grant->checkAuthorizeParams();
|
||||
/** @var Account $account */
|
||||
$account = Yii::$app->user->identity->getAccount();
|
||||
/** @var \common\models\OauthClient $clientModel */
|
||||
$clientModel = OauthClient::findOne($authParams->getClient()->getId());
|
||||
$clientModel = $this->findClient($authParams->getClient()->getId());
|
||||
|
||||
if (!$this->canAutoApprove($account, $clientModel, $authParams)) {
|
||||
Yii::$app->statsd->inc('oauth.complete.approve_required');
|
||||
@@ -164,6 +165,10 @@ class OauthProcess {
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function findClient(string $clientId): ?OauthClient {
|
||||
return OauthClient::findOne($clientId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Метод проверяет, может ли текущий пользователь быть автоматически авторизован
|
||||
* для указанного клиента без запроса доступа к необходимому списку прав
|
@@ -85,7 +85,7 @@ class RateLimiter extends \yii\filters\RateLimiter {
|
||||
}
|
||||
|
||||
if ($this->server === null) {
|
||||
/** @var OauthClient $server */
|
||||
/** @var OauthClient|null $server */
|
||||
$this->server = OauthClient::findOne($serverId);
|
||||
// TODO: убедится, что это сервер
|
||||
if ($this->server === null) {
|
||||
|
Reference in New Issue
Block a user