mirror of
https://github.com/elyby/accounts.git
synced 2024-11-09 15:02:19 +05:30
Return user field when requestUser param received on authentication/refresh endpoint [deploy]
This commit is contained in:
parent
077db4f328
commit
1aed8f59cb
@ -4,39 +4,33 @@ declare(strict_types=1);
|
||||
namespace api\modules\authserver\models;
|
||||
|
||||
use common\models\Account;
|
||||
use Lcobucci\JWT\Token;
|
||||
|
||||
class AuthenticateData {
|
||||
final class AuthenticateData {
|
||||
|
||||
/**
|
||||
* @var Account
|
||||
*/
|
||||
private $account;
|
||||
private Account $account;
|
||||
|
||||
/**
|
||||
* @var Token
|
||||
*/
|
||||
private $accessToken;
|
||||
private string $accessToken;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $clientToken;
|
||||
private string $clientToken;
|
||||
|
||||
public function __construct(Account $account, string $accessToken, string $clientToken) {
|
||||
private bool $requestUser;
|
||||
|
||||
public function __construct(Account $account, string $accessToken, string $clientToken, bool $requestUser) {
|
||||
$this->account = $account;
|
||||
$this->accessToken = $accessToken;
|
||||
$this->clientToken = $clientToken;
|
||||
$this->requestUser = $requestUser;
|
||||
}
|
||||
|
||||
public function getResponseData(bool $includeAvailableProfiles = false): array {
|
||||
$uuid = str_replace('-', '', $this->account->uuid);
|
||||
$result = [
|
||||
'accessToken' => $this->accessToken,
|
||||
'clientToken' => $this->clientToken,
|
||||
'selectedProfile' => [
|
||||
'id' => str_replace('-', '', $this->account->uuid),
|
||||
// Might contain a lot more fields, but even Mojang returns only those:
|
||||
'id' => $uuid,
|
||||
'name' => $this->account->username,
|
||||
'legacy' => false,
|
||||
],
|
||||
];
|
||||
|
||||
@ -46,6 +40,20 @@ class AuthenticateData {
|
||||
$result['availableProfiles'] = $availableProfiles;
|
||||
}
|
||||
|
||||
if ($this->requestUser) {
|
||||
// There are a lot of fields, but even Mojang returns only those:
|
||||
$result['user'] = [
|
||||
'id' => $uuid,
|
||||
'username' => $this->account->username,
|
||||
'properties' => [
|
||||
[
|
||||
'name' => 'preferredLanguage',
|
||||
'value' => $this->account->lang,
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
@ -34,10 +34,16 @@ class AuthenticationForm extends ApiForm {
|
||||
*/
|
||||
public $clientToken;
|
||||
|
||||
/**
|
||||
* @var string|bool
|
||||
*/
|
||||
public $requestUser;
|
||||
|
||||
public function rules(): array {
|
||||
return [
|
||||
[['username', 'password', 'clientToken'], RequiredValidator::class],
|
||||
[['clientToken'], ClientTokenValidator::class],
|
||||
[['requestUser'], 'boolean'],
|
||||
];
|
||||
}
|
||||
|
||||
@ -85,7 +91,7 @@ class AuthenticationForm extends ApiForm {
|
||||
/** @var Account $account */
|
||||
$account = $loginForm->getAccount();
|
||||
$token = Yii::$app->tokensFactory->createForMinecraftAccount($account, $this->clientToken);
|
||||
$dataModel = new AuthenticateData($account, (string)$token, $this->clientToken);
|
||||
$dataModel = new AuthenticateData($account, (string)$token, $this->clientToken, (bool)$this->requestUser);
|
||||
/** @var OauthSession|null $minecraftOauthSession */
|
||||
$minecraftOauthSession = $account->getOauthSessions()
|
||||
->andWhere(['client_id' => OauthClient::UNAUTHORIZED_MINECRAFT_GAME_LAUNCHER])
|
||||
|
@ -28,10 +28,16 @@ class RefreshTokenForm extends ApiForm {
|
||||
*/
|
||||
public $clientToken;
|
||||
|
||||
/**
|
||||
* @var string|bool
|
||||
*/
|
||||
public $requestUser;
|
||||
|
||||
public function rules(): array {
|
||||
return [
|
||||
[['accessToken', 'clientToken'], RequiredValidator::class],
|
||||
[['accessToken'], AccessTokenValidator::class, 'verifyExpiration' => false],
|
||||
[['requestUser'], 'boolean'],
|
||||
];
|
||||
}
|
||||
|
||||
@ -83,7 +89,7 @@ class RefreshTokenForm extends ApiForm {
|
||||
$minecraftOauthSession->last_used_at = time();
|
||||
Assert::true($minecraftOauthSession->save());
|
||||
|
||||
return new AuthenticateData($account, (string)$token, $this->clientToken);
|
||||
return new AuthenticateData($account, (string)$token, $this->clientToken, (bool)$this->requestUser);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,33 +10,70 @@ use Ramsey\Uuid\Uuid;
|
||||
class AuthorizationCest {
|
||||
|
||||
/**
|
||||
* # Matrix:
|
||||
* # * login: username/email
|
||||
* # * requestUser: true/false
|
||||
* # * json: true/false
|
||||
*
|
||||
* JSON: false
|
||||
* @example {"login": "admin", "password": "password_0"}
|
||||
* @example {"login": "admin", "password": "password_0", "requestUser": true}
|
||||
* @example {"login": "admin@ely.by", "password": "password_0"}
|
||||
* @example {"login": "admin@ely.by", "password": "password_0", "requestUser": true}
|
||||
*
|
||||
* JSON: true
|
||||
* @example {"json": true, "login": "admin", "password": "password_0"}
|
||||
* @example {"json": true, "login": "admin", "password": "password_0", "requestUser": true}
|
||||
* @example {"json": true, "login": "admin@ely.by", "password": "password_0"}
|
||||
* @example {"json": true, "login": "admin@ely.by", "password": "password_0", "requestUser": true}
|
||||
*/
|
||||
public function byFormParamsPostRequest(FunctionalTester $I, Example $example) {
|
||||
$I->wantTo('authenticate by username and password');
|
||||
$I->sendPOST('/api/authserver/authentication/authenticate', [
|
||||
'username' => $example['login'],
|
||||
'password' => $example['password'],
|
||||
public function authenticate(FunctionalTester $I, Example $case) {
|
||||
$params = [
|
||||
'username' => $case['login'],
|
||||
'password' => $case['password'],
|
||||
'clientToken' => Uuid::uuid4()->toString(),
|
||||
];
|
||||
if ($case['requestUser'] ?? false) {
|
||||
$params['requestUser'] = true;
|
||||
}
|
||||
|
||||
if ($case['json'] ?? false) {
|
||||
$params = json_encode($params);
|
||||
}
|
||||
|
||||
$I->sendPOST('/api/authserver/authentication/authenticate', $params);
|
||||
|
||||
$I->canSeeResponseJsonMatchesJsonPath('$.accessToken');
|
||||
$I->canSeeResponseJsonMatchesJsonPath('$.clientToken');
|
||||
$I->canSeeResponseContainsJson([
|
||||
'selectedProfile' => [
|
||||
'id' => 'df936908b2e1544d96f82977ec213022',
|
||||
'name' => 'Admin',
|
||||
],
|
||||
'availableProfiles' => [
|
||||
[
|
||||
'id' => 'df936908b2e1544d96f82977ec213022',
|
||||
'name' => 'Admin',
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$this->testSuccessResponse($I);
|
||||
}
|
||||
|
||||
/**
|
||||
* @example {"login": "admin", "password": "password_0"}
|
||||
* @example {"login": "admin@ely.by", "password": "password_0"}
|
||||
*/
|
||||
public function byJsonPostRequest(FunctionalTester $I, Example $example) {
|
||||
$I->wantTo('authenticate by username and password sent via post body');
|
||||
$I->sendPOST('/api/authserver/authentication/authenticate', json_encode([
|
||||
'username' => $example['login'],
|
||||
'password' => $example['password'],
|
||||
'clientToken' => Uuid::uuid4()->toString(),
|
||||
]));
|
||||
|
||||
$this->testSuccessResponse($I);
|
||||
if ($case['requestUser'] ?? false) {
|
||||
$I->canSeeResponseContainsJson([
|
||||
'user' => [
|
||||
'id' => 'df936908b2e1544d96f82977ec213022',
|
||||
'username' => 'Admin',
|
||||
'properties' => [
|
||||
[
|
||||
'name' => 'preferredLanguage',
|
||||
'value' => 'en',
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
} else {
|
||||
$I->cantSeeResponseJsonMatchesJsonPath('$.user');
|
||||
}
|
||||
}
|
||||
|
||||
public function byEmailWithEnabledTwoFactorAuth(FunctionalTester $I) {
|
||||
@ -125,17 +162,4 @@ class AuthorizationCest {
|
||||
]);
|
||||
}
|
||||
|
||||
private function testSuccessResponse(FunctionalTester $I) {
|
||||
$I->seeResponseCodeIs(200);
|
||||
$I->seeResponseIsJson();
|
||||
$I->canSeeResponseJsonMatchesJsonPath('$.accessToken');
|
||||
$I->canSeeResponseJsonMatchesJsonPath('$.clientToken');
|
||||
$I->canSeeResponseJsonMatchesJsonPath('$.availableProfiles[0].id');
|
||||
$I->canSeeResponseJsonMatchesJsonPath('$.availableProfiles[0].name');
|
||||
$I->canSeeResponseJsonMatchesJsonPath('$.availableProfiles[0].legacy');
|
||||
$I->canSeeResponseJsonMatchesJsonPath('$.selectedProfile.id');
|
||||
$I->canSeeResponseJsonMatchesJsonPath('$.selectedProfile.name');
|
||||
$I->canSeeResponseJsonMatchesJsonPath('$.selectedProfile.legacy');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,23 +9,33 @@ use Ramsey\Uuid\Uuid;
|
||||
|
||||
class RefreshCest {
|
||||
|
||||
public function refresh(AuthserverSteps $I) {
|
||||
/**
|
||||
* @example [true]
|
||||
* @example [false]
|
||||
*/
|
||||
public function refresh(AuthserverSteps $I, Example $case) {
|
||||
$I->wantTo('refresh accessToken');
|
||||
[$accessToken, $clientToken] = $I->amAuthenticated();
|
||||
$I->sendPOST('/api/authserver/authentication/refresh', [
|
||||
'accessToken' => $accessToken,
|
||||
'clientToken' => $clientToken,
|
||||
'requestUser' => $case[0],
|
||||
]);
|
||||
$this->assertSuccessResponse($I);
|
||||
$this->assertSuccessResponse($I, $case[0]);
|
||||
}
|
||||
|
||||
public function refreshLegacyAccessToken(AuthserverSteps $I) {
|
||||
/**
|
||||
* @example [true]
|
||||
* @example [false]
|
||||
*/
|
||||
public function refreshLegacyAccessToken(AuthserverSteps $I, Example $case) {
|
||||
$I->wantTo('refresh legacy accessToken');
|
||||
$I->sendPOST('/api/authserver/authentication/refresh', [
|
||||
'accessToken' => 'e7bb6648-2183-4981-9b86-eba5e7f87b42',
|
||||
'clientToken' => '6f380440-0c05-47bd-b7c6-d011f1b5308f',
|
||||
'requestUser' => $case[0],
|
||||
]);
|
||||
$this->assertSuccessResponse($I);
|
||||
$this->assertSuccessResponse($I, $case[0]);
|
||||
}
|
||||
|
||||
public function refreshWithInvalidClientToken(AuthserverSteps $I) {
|
||||
@ -63,7 +73,7 @@ class RefreshCest {
|
||||
'accessToken' => $example['accessToken'],
|
||||
'clientToken' => $example['clientToken'],
|
||||
]);
|
||||
$this->assertSuccessResponse($I);
|
||||
$this->assertSuccessResponse($I, false);
|
||||
}
|
||||
|
||||
public function wrongArguments(AuthserverSteps $I) {
|
||||
@ -119,15 +129,36 @@ class RefreshCest {
|
||||
]);
|
||||
}
|
||||
|
||||
private function assertSuccessResponse(AuthserverSteps $I) {
|
||||
private function assertSuccessResponse(AuthserverSteps $I, bool $requestUser) {
|
||||
$I->seeResponseCodeIs(200);
|
||||
$I->seeResponseIsJson();
|
||||
$I->canSeeResponseJsonMatchesJsonPath('$.accessToken');
|
||||
$I->canSeeResponseJsonMatchesJsonPath('$.clientToken');
|
||||
$I->canSeeResponseContainsJson([
|
||||
'selectedProfile' => [
|
||||
'id' => 'df936908b2e1544d96f82977ec213022',
|
||||
'name' => 'Admin',
|
||||
],
|
||||
]);
|
||||
$I->canSeeResponseJsonMatchesJsonPath('$.selectedProfile.id');
|
||||
$I->canSeeResponseJsonMatchesJsonPath('$.selectedProfile.name');
|
||||
$I->canSeeResponseJsonMatchesJsonPath('$.selectedProfile.legacy');
|
||||
$I->cantSeeResponseJsonMatchesJsonPath('$.availableProfiles');
|
||||
if ($requestUser) {
|
||||
$I->canSeeResponseContainsJson([
|
||||
'user' => [
|
||||
'id' => 'df936908b2e1544d96f82977ec213022',
|
||||
'username' => 'Admin',
|
||||
'properties' => [
|
||||
[
|
||||
'name' => 'preferredLanguage',
|
||||
'value' => 'en',
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
} else {
|
||||
$I->cantSeeResponseJsonMatchesJsonPath('$.user');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -31,11 +31,24 @@ class AuthenticationFormTest extends TestCase {
|
||||
$this->assertSame($authForm->clientToken, $result['clientToken']);
|
||||
$this->assertSame('df936908b2e1544d96f82977ec213022', $result['selectedProfile']['id']);
|
||||
$this->assertSame('Admin', $result['selectedProfile']['name']);
|
||||
$this->assertFalse($result['selectedProfile']['legacy']);
|
||||
$this->assertTrue(OauthSession::find()->andWhere([
|
||||
'account_id' => 1,
|
||||
'client_id' => OauthClient::UNAUTHORIZED_MINECRAFT_GAME_LAUNCHER,
|
||||
])->exists());
|
||||
$this->assertArrayNotHasKey('user', $result);
|
||||
|
||||
$authForm->requestUser = true;
|
||||
$result = $authForm->authenticate()->getResponseData();
|
||||
$this->assertSame([
|
||||
'id' => 'df936908b2e1544d96f82977ec213022',
|
||||
'username' => 'Admin',
|
||||
'properties' => [
|
||||
[
|
||||
'name' => 'preferredLanguage',
|
||||
'value' => 'en',
|
||||
],
|
||||
],
|
||||
], $result['user']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user