Merge branch 'develop'

This commit is contained in:
ErickSkrauch 2017-04-10 14:55:06 +03:00
commit e12f391df1
12 changed files with 124 additions and 69 deletions

View File

@ -24,6 +24,7 @@ use yii\web\User as YiiUserComponent;
* @property AccountIdentity|null $identity
*
* @method AccountIdentity|null loginByAccessToken($token, $type = null)
* @method AccountIdentity|null getIdentity($autoRenew = true)
*/
class Component extends YiiUserComponent {
@ -44,8 +45,6 @@ class Component extends YiiUserComponent {
public $sessionTimeout = 'P7D';
private $_identity;
public function init() {
parent::init();
if (!$this->secret) {
@ -53,24 +52,6 @@ class Component extends YiiUserComponent {
}
}
/**
* @param bool $autoRenew
* @return null|AccountIdentity
*/
public function getIdentity($autoRenew = true) {
$result = parent::getIdentity($autoRenew);
if ($result === null && $this->_identity !== false) {
$bearer = $this->getBearerToken();
if ($bearer !== null) {
$result = $this->loginByAccessToken($bearer);
}
$this->_identity = $result ?: false;
}
return $result;
}
/**
* @param IdentityInterface $identity
* @param bool $rememberMe

View File

@ -24,7 +24,7 @@ return [
'/mojang/profiles/<uuid>/names' => 'mojang/api/usernames-by-uuid',
'POST /mojang/profiles' => 'mojang/api/uuids-by-usernames',
"<protocol:http|https>://{$params['authserverHost']}/mojang/api/users/profiles/minecraft/<username>" => 'mojang/api/uuid-by-username',
"<protocol:http|https>://{$params['authserverHost']}/mojang/api/user/profiles/<uuid>/names" => 'mojang/api/usernames-by-uuid',
"POST <protocol:http|https>://{$params['authserverHost']}/mojang/api/profiles/minecraft" => 'mojang/api/uuids-by-usernames',
"//{$params['authserverHost']}/mojang/api/users/profiles/minecraft/<username>" => 'mojang/api/uuid-by-username',
"//{$params['authserverHost']}/mojang/api/user/profiles/<uuid>/names" => 'mojang/api/usernames-by-uuid',
"POST //{$params['authserverHost']}/mojang/api/profiles/minecraft" => 'mojang/api/uuids-by-usernames',
];

View File

@ -10,7 +10,7 @@ class FeedbackController extends Controller {
public function behaviors() {
return ArrayHelper::merge(parent::behaviors(), [
'authenticator' => [
'except' => ['index'],
'optional' => ['index'],
],
]);
}

View File

@ -39,7 +39,7 @@ class Module extends \yii\base\Module implements BootstrapInterface {
*/
public function bootstrap($app) {
$app->getUrlManager()->addRules([
"<protocol:http|https>://$this->host/$this->id/auth/<action>" => "$this->id/authentication/<action>",
"//$this->host/$this->id/auth/<action>" => "$this->id/authentication/<action>",
], false);
}

View File

@ -9,6 +9,7 @@ use common\models\Account;
use common\models\OauthScope as S;
use Yii;
use yii\helpers\ArrayHelper;
use yii\web\BadRequestHttpException;
use yii\web\NotFoundHttpException;
class AccountsController extends Controller {
@ -26,6 +27,11 @@ class AccountsController extends Controller {
'allow' => true,
'roles' => [S::ACCOUNT_BLOCK],
],
[
'actions' => ['info'],
'allow' => true,
'roles' => [S::INTERNAL_ACCOUNT_INFO],
],
],
],
]);
@ -34,6 +40,7 @@ class AccountsController extends Controller {
public function verbs() {
return [
'ban' => ['POST', 'DELETE'],
'info' => ['GET'],
];
}
@ -46,6 +53,29 @@ class AccountsController extends Controller {
}
}
public function actionInfo(int $id = null, string $username = null, string $uuid = null) {
if ($id !== null) {
$account = Account::findOne($id);
} elseif ($username !== null) {
$account = Account::findOne(['username' => $username]);
} elseif ($uuid !== null) {
$account = Account::findOne(['uuid' => $uuid]);
} else {
throw new BadRequestHttpException('One of the required get params must be presented.');
}
if ($account === null) {
throw new NotFoundHttpException('User by provided param not found.');
}
return [
'id' => $account->id,
'uuid' => $account->uuid,
'email' => $account->email,
'username' => $account->username,
];
}
private function banAccount(Account $account) {
$model = new BanForm($account);
$model->load(Yii::$app->request->post());

View File

@ -1,6 +1,6 @@
<?php
return [
'version' => '1.1.8',
'version' => '1.1.9',
'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
'components' => [
'cache' => [

View File

@ -28,6 +28,11 @@ class OauthScope {
* @owner machine
*/
const ACCOUNT_BLOCK = 'account_block';
/**
* @internal
* @owner machine
*/
const INTERNAL_ACCOUNT_INFO = 'internal_account_info';
public static function find(): OauthScopeQuery {
return new OauthScopeQuery(static::queryScopes());

View File

@ -15,7 +15,7 @@
"minimum-stability": "stable",
"require": {
"php": "^7.1",
"yiisoft/yii2": "2.0.10",
"yiisoft/yii2": "2.0.11.2",
"yiisoft/yii2-swiftmailer": "*",
"ramsey/uuid": "^3.5.0",
"league/oauth2-server": "dev-improvements#fbaa9b0bd3d8050235ba7dde90f731764122bc20",

View File

@ -17,8 +17,8 @@ class CleanupController extends Controller {
];
}
/** @var EmailActivation[] $expiredEmails */
$expiredEmails = $query->andWhere($conditions)->all();
/** @var \yii\db\BatchQueryResult|EmailActivation[] $expiredEmails */
$expiredEmails = $query->andWhere($conditions)->each();
foreach ($expiredEmails as $email) {
$email->delete();
}

View File

@ -18,4 +18,9 @@ class InternalRoute extends BasePage {
$this->actor->sendDELETE($this->getUrl());
}
public function info(string $param, string $value) {
$this->route = '/internal/accounts/info';
$this->actor->sendGET($this->getUrl(), [$param => $value]);
}
}

View File

@ -0,0 +1,74 @@
<?php
namespace tests\codeception\api\functional\internal;
use common\models\OauthScope as S;
use tests\codeception\api\_pages\InternalRoute;
use tests\codeception\api\functional\_steps\OauthSteps;
use tests\codeception\api\FunctionalTester;
class InfoCest {
/**
* @var InternalRoute
*/
private $route;
public function _before(FunctionalTester $I) {
$this->route = new InternalRoute($I);
}
public function testGetInfoById(OauthSteps $I) {
$accessToken = $I->getAccessTokenByClientCredentialsGrant([S::INTERNAL_ACCOUNT_INFO]);
$I->amBearerAuthenticated($accessToken);
$this->route->info('id', 1);
$this->expectSuccessResponse($I);
}
public function testGetInfoByUuid(OauthSteps $I) {
$accessToken = $I->getAccessTokenByClientCredentialsGrant([S::INTERNAL_ACCOUNT_INFO]);
$I->amBearerAuthenticated($accessToken);
$this->route->info('uuid', 'df936908-b2e1-544d-96f8-2977ec213022');
$this->expectSuccessResponse($I);
}
public function testGetInfoByUsername(OauthSteps $I) {
$accessToken = $I->getAccessTokenByClientCredentialsGrant([S::INTERNAL_ACCOUNT_INFO]);
$I->amBearerAuthenticated($accessToken);
$this->route->info('username', 'admin');
$this->expectSuccessResponse($I);
}
public function testInvalidParams(OauthSteps $I) {
$accessToken = $I->getAccessTokenByClientCredentialsGrant([S::INTERNAL_ACCOUNT_INFO]);
$I->amBearerAuthenticated($accessToken);
$this->route->info('', '');
$I->canSeeResponseCodeIs(400);
}
public function testAccountNotFound(OauthSteps $I) {
$accessToken = $I->getAccessTokenByClientCredentialsGrant([S::INTERNAL_ACCOUNT_INFO]);
$I->amBearerAuthenticated($accessToken);
$this->route->info('username', 'this-user-not-exists');
$I->canSeeResponseCodeIs(404);
}
/**
* @param OauthSteps $I
*/
private function expectSuccessResponse(OauthSteps $I): void {
$I->canSeeResponseCodeIs(200);
$I->canSeeResponseIsJson();
$I->canSeeResponseContainsJson([
'id' => 1,
'uuid' => 'df936908-b2e1-544d-96f8-2977ec213022',
'email' => 'admin@ely.by',
'username' => 'Admin',
]);
}
}

View File

@ -41,46 +41,6 @@ class ComponentTest extends TestCase {
];
}
public function testGetIdentity() {
$this->specify('getIdentity should return null, if not authorization header', function() {
$this->mockAuthorizationHeader(null);
$this->assertNull($this->component->getIdentity());
});
$this->specify('getIdentity should return null, if passed bearer token don\'t return any account', function() {
$this->mockAuthorizationHeader('some-auth');
/** @var Component|\PHPUnit_Framework_MockObject_MockObject $component */
$component = $this->getMockBuilder(Component::class)
->setMethods(['loginByAccessToken'])
->setConstructorArgs([$this->getComponentArguments()])
->getMock();
$component
->expects($this->once())
->method('loginByAccessToken')
->willReturn(null);
$this->assertNull($component->getIdentity());
});
$this->specify('getIdentity should return identity from loginByAccessToken method', function() {
$identity = new AccountIdentity();
$this->mockAuthorizationHeader('some-auth');
/** @var Component|\PHPUnit_Framework_MockObject_MockObject $component */
$component = $this->getMockBuilder(Component::class)
->setMethods(['loginByAccessToken'])
->setConstructorArgs([$this->getComponentArguments()])
->getMock();
$component
->expects($this->once())
->method('loginByAccessToken')
->willReturn($identity);
$this->assertEquals($identity, $component->getIdentity());
});
}
public function testLogin() {
$this->mockRequest();
$this->specify('success get LoginResult object without session value', function() {