Skip to content

Commit

Permalink
Multiple ESI Tokens #32
Browse files Browse the repository at this point in the history
- Add role check during login.
  • Loading branch information
tkhamez committed Aug 29, 2021
1 parent d759c40 commit 703545f
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 11 deletions.
7 changes: 6 additions & 1 deletion backend/src/Controller/User/AuthController.php
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,13 @@ public function callback(
$eveLogin = $this->repositoryFactory->getEveLoginRepository()->find($loginId);
if (!$eveLogin) {
$errorMessage = 'Invalid login link.';
} elseif (!$esiData->verifyRoles(
$eveLogin->getEveRoles(),
$eveAuth->getCharacterId(),
$eveAuth->getToken()->getToken()
)) {
$errorMessage = 'Character does not have required role(s).';
} else {
# TODO check in-game roles (scopes were already checked above)
if ($userAuth->addToken($eveLogin, $eveAuth)) {
$success = true;
} else {
Expand Down
19 changes: 14 additions & 5 deletions backend/src/Entity/EveLogin.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public function jsonSerialize(): array
'name' => $this->name,
'description' => $this->description,
'esiScopes' => $this->esiScopes,
'eveRoles' => $this->eveRoles,
'eveRoles' => $this->getEveRoles(),
];
}

Expand Down Expand Up @@ -177,15 +177,24 @@ public function getEsiScopes(): string
return $this->esiScopes;
}

public function setEveRoles(string $eveRoles): self
/**
* @param string[] $eveRoles
*/
public function setEveRoles(array $eveRoles): self
{
$this->eveRoles = $eveRoles;
$this->eveRoles = implode(',', $eveRoles);
return $this;
}

public function getEveRoles(): string
/**
* @return string[]
*/
public function getEveRoles(): array
{
return $this->eveRoles;
if (empty($this->eveRoles)) {
return [];
}
return explode(',', $this->eveRoles);
}

public function addEsiToken(EsiToken $token): self
Expand Down
46 changes: 44 additions & 2 deletions backend/tests/Functional/Controller/User/AuthControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,45 @@ public function testCallback_CustomLogin_CharacterNotOnAccount()
);
}

public function testCallback_CustomLogin_RoleError()
{
// add EveLogin
$loginId = 'custom1';
$charId = 123; // the ID used in Helper::generateToken
$this->helper->getEm()->persist(
(new EveLogin())->setId($loginId)->setEsiScopes('scope1')->setEveRoles(['Auditor'])
);
$this->helper->addCharacterMain('Test User', $charId, [Role::USER], [], false); // without ESI token
$this->loginUser($charId);

list($token, $keySet) = Helper::generateToken(['scope1']);
$state = AuthController::getStatePrefix($loginId) . self::$state;
$_SESSION['auth_state'] = $state;

$this->client->setResponse(
new Response(200, [], // for getAccessToken()
'{"access_token": ' . json_encode($token) . ',
"expires_in": 1200,
"refresh_token": "gEy...fM0"}'),
new Response(200, [], '{"keys": ' . \json_encode($keySet) . '}'), // for JWT key set
new Response(200, [], '{"roles": []}') // getCharactersCharacterIdRoles
);

$response = $this->runApp(
'GET',
'/login-callback?state='.$state,
null,
null,
[ClientInterface::class => $this->client]
);

$this->assertSame(302, $response->getStatusCode());
$this->assertSame(
['success' => false, 'message' => 'Character does not have required role(s).'],
$_SESSION['auth_result']
);
}

/**
* @throws \Exception
*/
Expand All @@ -303,7 +342,9 @@ public function testCallback_CustomLogin_Success()
// add EveLogin
$loginId = 'custom1';
$charId = 123; // the ID used in Helper::generateToken
$this->helper->getEm()->persist((new EveLogin())->setId($loginId)->setEsiScopes('scope1'));
$this->helper->getEm()->persist(
(new EveLogin())->setId($loginId)->setEsiScopes('scope1')->setEveRoles(['Auditor'])
);
$this->helper->addCharacterMain('Test User', $charId, [Role::USER], [], false); // without ESI token
$this->loginUser($charId);

Expand All @@ -316,7 +357,8 @@ public function testCallback_CustomLogin_Success()
'{"access_token": ' . json_encode($token) . ',
"expires_in": 1200,
"refresh_token": "gEy...fM0"}'),
new Response(200, [], '{"keys": ' . \json_encode($keySet) . '}') // for JWT key set
new Response(200, [], '{"keys": ' . \json_encode($keySet) . '}'), // for JWT key set
new Response(200, [], '{"roles": ["Auditor"]}') // getCharactersCharacterIdRoles
);

$response = $this->runApp(
Expand Down
6 changes: 3 additions & 3 deletions backend/tests/Unit/Entity/EveLoginTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ public function testJsonSerialize()
$login->setName('the name');
$login->setDescription('desc');
$login->setEsiScopes('scope1 scope2');
$login->setEveRoles('role1,role2');
$login->setEveRoles(['role1', 'role2']);
$login->addEsiToken(new EsiToken());

$this->assertSame([
'id' => 'the-id',
'name' => 'the name',
'description' => 'desc',
'esiScopes' => 'scope1 scope2',
'eveRoles' => 'role1,role2',
'eveRoles' => ['role1', 'role2'],
], json_decode((string) json_encode($login), true));
}

Expand Down Expand Up @@ -57,7 +57,7 @@ public function testSetGetEsiScopes()
public function testSetGetEveRoles()
{
$login = new EveLogin();
$this->assertSame('role1,role2', $login->setEveRoles('role1,role2')->getEveRoles());
$this->assertSame(['role1', 'role2'], $login->setEveRoles(['role1', 'role2'])->getEveRoles());
}

/** @noinspection DuplicatedCode */
Expand Down

0 comments on commit 703545f

Please sign in to comment.