Skip to content

Commit

Permalink
Multiple ESI Tokens #32
Browse files Browse the repository at this point in the history
- Allow to rename the login "id" (change id to autoincrement and name to an unique name)
  • Loading branch information
tkhamez committed Jul 25, 2021
1 parent 39e04ca commit 8154cd2
Show file tree
Hide file tree
Showing 19 changed files with 258 additions and 206 deletions.
6 changes: 3 additions & 3 deletions backend/config/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
use Neucore\Controller\User\WatchlistController;

return [
'/login/{id}' => ['GET', [AuthController::class, 'login']],
'/login/{name}' => ['GET', [AuthController::class, 'login']],
'/login-callback' => ['GET', [AuthController::class, 'callback']],

'/api/user/auth/callback' => ['GET', [AuthController::class, 'callback']], // only for backwards compatibility
Expand Down Expand Up @@ -158,8 +158,8 @@
'/api/user/settings/system/validate-director/{name}' => ['PUT', [SettingsController::class, 'validateDirector']],
'/api/user/settings/eve-login/list' => ['GET' => [SettingsEveLoginController::class, 'list']],
'/api/user/settings/eve-login' => ['PUT' => [SettingsEveLoginController::class, 'update']],
'/api/user/settings/eve-login/{id}' => ['POST' => [SettingsEveLoginController::class, 'create'],
'DELETE' => [SettingsEveLoginController::class, 'delete']],
'/api/user/settings/eve-login/{name}' => ['POST' => [SettingsEveLoginController::class, 'create']],
'/api/user/settings/eve-login/{id}' => ['DELETE' => [SettingsEveLoginController::class, 'delete']],

'/api/user/watchlist/create' => ['POST', [WatchlistController::class, 'create']],
'/api/user/watchlist/{id}/rename' => ['PUT', [WatchlistController::class, 'rename']],
Expand Down
2 changes: 1 addition & 1 deletion backend/src/Command/AutoAllowlist.php
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ private function getAccountData(array $players, array $watchedCorporationIds)
$accountsData[$playerId][$corporationId] = [self::KEY_IDS => [], self::KEY_TOKEN => null];
}
$accountsData[$playerId][$corporationId][self::KEY_IDS][] = $character->getId();
$esiToken = $character->getEsiToken(EveLogin::ID_DEFAULT);
$esiToken = $character->getEsiToken(EveLogin::NAME_DEFAULT);
if (
$accountsData[$playerId][$corporationId][self::KEY_TOKEN] === null &&
$esiToken !== null &&
Expand Down
2 changes: 1 addition & 1 deletion backend/src/Command/RevokeToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
return 0;
}

$esiToken = $character->getEsiToken(EveLogin::ID_DEFAULT);
$esiToken = $character->getEsiToken(EveLogin::NAME_DEFAULT);
if ($esiToken === null) {
$output->writeln('Character has no default token.');
return 0;
Expand Down
58 changes: 29 additions & 29 deletions backend/src/Controller/User/AuthController.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,19 +116,19 @@ public function __construct(
/**
* Eve logins, redirects to EVE SSO login page or fails with a 404 or 403 status code.
*/
public function login(string $id): ResponseInterface
public function login(string $name): ResponseInterface
{
// validate login ID
$loginId = null;
if (in_array($id, EveLogin::INTERNAL_LOGINS)) {
$loginId = $id;
$loginName = null;
if (in_array($name, EveLogin::INTERNAL_LOGIN_NAMES)) {
$loginName = $name;
} else {
$eveLogin = $this->repositoryFactory->getEveLoginRepository()->find($id);
$eveLogin = $this->repositoryFactory->getEveLoginRepository()->findOneBy(['name' => $name]);
if ($eveLogin) {
$loginId = $eveLogin->getId();
$loginName = $eveLogin->getName();
}
}
if (empty($loginId)) {
if (empty($loginName)) {
$this->response->getBody()->write(
'Login not found.<br><br>' .
'<a href="/">Home</a>'
Expand All @@ -137,7 +137,7 @@ public function login(string $id): ResponseInterface
}

// check "allow managed login" settings
if (in_array($loginId, [EveLogin::ID_MANAGED, EveLogin::ID_MANAGED_ALT])) {
if (in_array($loginName, [EveLogin::NAME_MANAGED, EveLogin::NAME_MANAGED_ALT])) {
$allowLoginManaged = $this->repositoryFactory->getSystemVariableRepository()
->findOneBy(['name' => SystemVariable::ALLOW_LOGIN_MANAGED]);
if (!$allowLoginManaged || $allowLoginManaged->getValue() !== '1') {
Expand All @@ -146,7 +146,7 @@ public function login(string $id): ResponseInterface
}
}

return $this->redirectToLoginUrl($loginId);
return $this->redirectToLoginUrl($loginName);
}

/**
Expand Down Expand Up @@ -182,29 +182,29 @@ public function callback(
}

// handle login
$loginId = $this->getLoginIdFromState($state);
$loginName = $this->getLoginNameFromState($state);
$success = false;
switch ($loginId) {
case EveLogin::ID_DEFAULT:
case EveLogin::ID_MANAGED:
switch ($loginName) {
case EveLogin::NAME_DEFAULT:
case EveLogin::NAME_MANAGED:
$success = $userAuth->authenticate($eveAuth);
$successMessage = 'Login successful.';
$errorMessage = 'Failed to authenticate user.';
break;
case EveLogin::ID_ALT:
case EveLogin::ID_MANAGED_ALT:
case EveLogin::NAME_ALT:
case EveLogin::NAME_MANAGED_ALT:
$success = $userAuth->addAlt($eveAuth);
$successMessage = 'Character added to player account.';
$errorMessage = 'Failed to add alt to account.';
break;
case EveLogin::ID_MAIL:
case EveLogin::NAME_MAIL:
if (in_array(Role::SETTINGS, $userAuth->getRoles())) {
$success = $mailService->storeMailCharacter($eveAuth);
}
$successMessage = 'Mail character authenticated.';
$errorMessage = 'Failed to store character.';
break;
case EveLogin::ID_DIRECTOR:
case EveLogin::NAME_DIRECTOR:
$successMessage = 'Character with director roles added.';
$errorMessage = 'Error adding character with director roles.';
if ($esiData->verifyRoles(
Expand All @@ -218,7 +218,7 @@ public function callback(
default:
$successMessage = 'ESI token added.';
$errorMessage = '';
$eveLogin = $this->repositoryFactory->getEveLoginRepository()->find($loginId);
$eveLogin = $this->repositoryFactory->getEveLoginRepository()->findOneBy(['name' => $loginName]);
if (!$eveLogin) {
$errorMessage = 'Invalid login link.';
} elseif (!$esiData->verifyRoles(
Expand Down Expand Up @@ -329,13 +329,13 @@ public function csrfToken(SessionData $sessionData): ResponseInterface

private function getRedirectUrl(string $loginId): string
{
if (in_array($loginId, [EveLogin::ID_DEFAULT, EveLogin::ID_MANAGED, EveLogin::ID_MANAGED_ALT])) {
if (in_array($loginId, [EveLogin::NAME_DEFAULT, EveLogin::NAME_MANAGED, EveLogin::NAME_MANAGED_ALT])) {
return '/#login';
} elseif ($loginId === EveLogin::ID_ALT) {
} elseif ($loginId === EveLogin::NAME_ALT) {
return '/#login-alt';
} elseif ($loginId === EveLogin::ID_MAIL) {
} elseif ($loginId === EveLogin::NAME_MAIL) {
return '/#login-mail';
} elseif ($loginId === EveLogin::ID_DIRECTOR) {
} elseif ($loginId === EveLogin::NAME_DIRECTOR) {
return '/#login-director';
}
return '/#login-custom';
Expand All @@ -361,20 +361,20 @@ private function redirectToLoginUrl(string $loginId): ResponseInterface

private function getLoginScopes(string $state): array
{
$loginId = $this->getLoginIdFromState($state);
if (in_array($loginId, [EveLogin::ID_MANAGED, EveLogin::ID_MANAGED_ALT])) {
$loginName = $this->getLoginNameFromState($state);
if (in_array($loginName, [EveLogin::NAME_MANAGED, EveLogin::NAME_MANAGED_ALT])) {
return [];
} elseif ($loginId === EveLogin::ID_MAIL) {
} elseif ($loginName === EveLogin::NAME_MAIL) {
return [EveLogin::SCOPE_MAIL];
} elseif ($loginId === EveLogin::ID_DIRECTOR) {
} elseif ($loginName === EveLogin::NAME_DIRECTOR) {
return [EveLogin::SCOPE_ROLES, EveLogin::SCOPE_TRACKING, EveLogin::SCOPE_STRUCTURES];
}

$scopes = '';
if (in_array($loginId, [EveLogin::ID_DEFAULT, EveLogin::ID_ALT])) {
if (in_array($loginName, [EveLogin::NAME_DEFAULT, EveLogin::NAME_ALT])) {
$scopes = $this->config['eve']['scopes'];
} else {
$eveLogin = $this->repositoryFactory->getEveLoginRepository()->find($loginId);
$eveLogin = $this->repositoryFactory->getEveLoginRepository()->findOneBy(['name' => $loginName]);
if ($eveLogin) {
$scopes = $eveLogin->getEsiScopes();
}
Expand All @@ -388,7 +388,7 @@ private function getLoginScopes(string $state): array
return $scopes;
}

private function getLoginIdFromState(string $state): string
private function getLoginNameFromState(string $state): string
{
if (strpos($state, self::STATE_PREFIX_SEPARATOR) === false) {
return '';
Expand Down
45 changes: 26 additions & 19 deletions backend/src/Controller/User/SettingsEveLoginController.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@ class SettingsEveLoginController extends BaseController
/**
* @var string
*/
private $idPattern = "/^[-._a-zA-Z0-9]+$/";
private $namePattern = "/^[-._a-zA-Z0-9]+$/";

/**
* @OA\Post(
* path="/user/settings/eve-login/{id}",
* path="/user/settings/eve-login/{name}",
* operationId="userSettingsEveLoginCreate",
* summary="Create a new login.",
* description="Needs role: settings",
* tags={"Settings"},
* security={{"Session"={}, "CSRF"={}}},
* @OA\Parameter(
* name="id",
* name="name",
* in="path",
* required=true,
* description="The new login ID.",
* description="The new login name.",
* @OA\Schema(type="string", maxLength=20, pattern="^[-._a-zA-Z0-9]+$")
* ),
* @OA\Response(
Expand All @@ -38,7 +38,7 @@ class SettingsEveLoginController extends BaseController
* ),
* @OA\Response(
* response="400",
* description="Login ID is invalid."
* description="Login name is invalid."
* ),
* @OA\Response(
* response="403",
Expand All @@ -50,18 +50,18 @@ class SettingsEveLoginController extends BaseController
* )
* )
*/
public function create(string $id): ResponseInterface
public function create(string $name): ResponseInterface
{
if (!preg_match($this->idPattern, $id) || strpos($id, EveLogin::INTERNAL_LOGINS_PREFIX) === 0) {
if (!preg_match($this->namePattern, $name) || strpos($name, EveLogin::INTERNAL_LOGIN_PREFIX) === 0) {
return $this->response->withStatus(400);
}

$existingLogin = $this->repositoryFactory->getEveLoginRepository()->find($id);
$existingLogin = $this->repositoryFactory->getEveLoginRepository()->findOneBy(['name' => $name]);
if ($existingLogin) {
return $this->response->withStatus(409);
}

$login = (new EveLogin())->setId($id);
$login = (new EveLogin())->setName($name);
$this->objectManager->persist($login);

return $this->flushAndReturn(201, $login);
Expand All @@ -88,7 +88,7 @@ public function create(string $id): ResponseInterface
* ),
* @OA\Response(
* response="400",
* description="Protected login ID."
* description="Protected login."
* ),
* @OA\Response(
* response="403",
Expand All @@ -102,15 +102,15 @@ public function create(string $id): ResponseInterface
*/
public function delete(string $id): ResponseInterface
{
if (in_array($id, EveLogin::INTERNAL_LOGINS)) {
return $this->response->withStatus(400);
}

$login = $this->repositoryFactory->getEveLoginRepository()->find($id);
$login = $this->repositoryFactory->getEveLoginRepository()->find((int)$id);
if (!$login) {
return $this->response->withStatus(404);
}

if (in_array($login->getName(), EveLogin::INTERNAL_LOGIN_NAMES)) {
return $this->response->withStatus(400);
}

$this->objectManager->remove($login);

return $this->flushAndReturn(204);
Expand All @@ -133,7 +133,7 @@ public function delete(string $id): ResponseInterface
*/
public function list(): ResponseInterface
{
$logins = $this->repositoryFactory->getEveLoginRepository()->findBy([]);
$logins = $this->repositoryFactory->getEveLoginRepository()->findBy([], ['name' => 'ASC']);
return $this->withJson($logins);
}

Expand All @@ -157,7 +157,7 @@ public function list(): ResponseInterface
* ),
* @OA\Response(
* response="400",
* description="Invalid body."
* description="Invalid body or invalid login name."
* ),
* @OA\Response(
* response="403",
Expand All @@ -172,15 +172,22 @@ public function list(): ResponseInterface
public function update(ServerRequestInterface $request): ResponseInterface
{
$data = $request->getParsedBody();
if (!$data instanceof \stdClass || !EveLogin::isValidObject($data) || empty($data->id)) {
if (!$data instanceof \stdClass || !EveLogin::isValidObject($data) || empty($data->id) || empty($data->name)) {
return $this->response->withStatus(400);
}

$login = $this->repositoryFactory->getEveLoginRepository()->find($data->id);
$login = $this->repositoryFactory->getEveLoginRepository()->find((int)$data->id);
if (!$login) {
return $this->response->withStatus(404);
}

if (
!preg_match($this->namePattern, $data->name) ||
strpos($data->name, EveLogin::INTERNAL_LOGIN_PREFIX) === 0
) {
return $this->response->withStatus(400);
}

$login->setName($data->name);
$login->setDescription($data->description);
$login->setEsiScopes($data->esiScopes);
Expand Down
4 changes: 2 additions & 2 deletions backend/src/Entity/Character.php
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,10 @@ public function getEsiTokens(): array
return $this->esiTokens->toArray();
}

public function getEsiToken(string $eveLoginId): ?EsiToken
public function getEsiToken(string $eveLoginName): ?EsiToken
{
foreach ($this->getEsiTokens() as $esiToken) {
if ($esiToken->getEveLogin() !== null && $esiToken->getEveLogin()->getId() === $eveLoginId) {
if ($esiToken->getEveLogin() !== null && $esiToken->getEveLogin()->getName() === $eveLoginName) {
return $esiToken;
}
}
Expand Down
Loading

0 comments on commit 8154cd2

Please sign in to comment.