From 44ef7891bbb2932077b0363f77d3f3d85030bdda Mon Sep 17 00:00:00 2001 From: aynsix Date: Thu, 27 Feb 2020 17:51:57 +0300 Subject: [PATCH 1/9] add command application:app to create edit delete and list application in phraseanet --- bin/console | 3 + .../Application/ApplicationAppCommand.php | 281 ++++++++++++++++++ 2 files changed, 284 insertions(+) create mode 100644 lib/Alchemy/Phrasea/Command/Application/ApplicationAppCommand.php diff --git a/bin/console b/bin/console index c973195ff6..1dfa643be2 100755 --- a/bin/console +++ b/bin/console @@ -31,6 +31,7 @@ use Alchemy\Phrasea\Command\Compile\Configuration; use Alchemy\Phrasea\Command\RecordAdd; use Alchemy\Phrasea\Command\RescanTechnicalDatas; use Alchemy\Phrasea\CLI; +use Alchemy\Phrasea\Command\Application\ApplicationAppCommand; use Alchemy\Phrasea\Command\Plugin\AddPlugin; use Alchemy\Phrasea\Command\Plugin\RemovePlugin; use Alchemy\Phrasea\Command\CheckConfig; @@ -112,6 +113,8 @@ $cli->command(new \module_console_fieldsDelete('fields:delete')); $cli->command(new \module_console_fieldsRename('fields:rename')); $cli->command(new \module_console_fieldsMerge('fields:merge')); +$cli->command(new ApplicationAppCommand('application:app')); + $cli->command(new CreateCollection('collection:create')); $cli->command(new ListCollectionCommand('collection:list')); diff --git a/lib/Alchemy/Phrasea/Command/Application/ApplicationAppCommand.php b/lib/Alchemy/Phrasea/Command/Application/ApplicationAppCommand.php new file mode 100644 index 0000000000..5494c4f73b --- /dev/null +++ b/lib/Alchemy/Phrasea/Command/Application/ApplicationAppCommand.php @@ -0,0 +1,281 @@ +setDescription('Create, edit, delete application in Phraseanet (experimental)') + ->addOption('user_id', 'u', InputOption::VALUE_REQUIRED, 'The desired login for created user.') + ->addOption('app_id', 'a', InputOption::VALUE_REQUIRED, 'The application ID') + ->addOption('name', null, InputOption::VALUE_REQUIRED, 'The desired name for application user.') + ->addOption('type', 't', InputOption::VALUE_OPTIONAL, 'The desired name for application user.',ApiApplication::WEB_TYPE) + ->addOption('description', 'd', InputOption::VALUE_REQUIRED, 'The desired description for application user.') + ->addOption('website', 'w', InputOption::VALUE_OPTIONAL, 'The desired url for application user.') + ->addOption('callback', 'c', InputOption::VALUE_OPTIONAL, 'The desired url for application user.') + ->addOption('webhook_url', null, InputOption::VALUE_REQUIRED, 'Define a webhook url on edit') + ->addOption('create_token', null, InputOption::VALUE_NONE, 'Generate an access token when app is created') + ->addOption('activate_password', null, InputOption::VALUE_OPTIONAL, 'Activate password OAuth2 grant type , values true or false', 'false') + ->addOption('create', null, InputOption::VALUE_NONE, 'Create application for user in Phraseanet') + ->addOption('edit', null, InputOption::VALUE_NONE, 'Edit application in Phraseanet work only if app_id and user_id are set') + ->addOption('delete', null, InputOption::VALUE_NONE, 'Delete application in Phraseanet, need app_id') + ->addOption('list', null, InputOption::VALUE_NONE, 'List all application or user application if --user_id is set') + ->addOption('jsonformat', null, InputOption::VALUE_NONE, 'Output in json format') + + ->setHelp(''); + + return $this; + } + + protected function doExecute(InputInterface $input, OutputInterface $output) + { + $userId = $input->getOption('user_id'); + $appId = $input->getOption('app_id'); + $name = $input->getOption('name'); + $type = $input->getOption('type'); + $description = $input->getOption('description'); + $website = $input->getOption('website'); + $urlCallback = $input->getOption('callback'); + $webhookUrl = $input->getOption('webhook_url'); + $createToken = $input->getOption('create_token'); + $activatePassword = $input->getOption('activate_password'); + $create = $input->getOption('create'); + $edit = $input->getOption('edit'); + $delete = $input->getOption('delete'); + $list = $input->getOption('list'); + $jsonformat = $input->getOption('jsonformat'); + + $applicationManipulator = $this->container['manipulator.api-application']; + $apiOauthTokenManipulator = $this->container['manipulator.api-oauth-token']; + $accountRepository = $this->container['repo.api-accounts']; + $apiApllicationConverter = $this->container['converter.api-application']; + $userRepository = $this->container['repo.users']; + $apiOauthRepository = $this->container['repo.api-oauth-tokens']; + + if ($create) { + if (null === $user = $userRepository->find($userId)) { + $output->writeln('User not found'); + return 0; + } + + if (!$name) { + $output->writeln('Name of application must be provide with option --name.'); + return 0; + } + + if (!$description) { + $output->writeln('Desciption of application must be provide.'); + + return 0; + } + + try { + $application = $applicationManipulator + ->create( + $name, + $type, + $description, + $website, + $user, + $urlCallback + ); + + $apiAccountManipulator = $this->container['manipulator.api-account']; + $apiAccountManipulator->create($application, $user, V2::VERSION); + + $account = $accountRepository->findByUserAndApplication($user, $application); + + if ($createToken) { + $apiOauthTokenManipulator->create($account); + } + + if ($activatePassword) { + if (in_array($activatePassword, ['true', 'false'])) { + $application->setGrantPassword(($activatePassword == 'true') ? true : false); + $applicationManipulator->update($application); + } else { + $output->writeln(' Value of option --activate_password should be "true" or "false"'); + + return 0; + } + } + + $this->showApllicationInformation($apiOauthRepository, $account, $application, $jsonformat, $output); + } catch (\Exception $e) { + $output->writeln('Create an application for user failed : '.$e->getMessage().''); + } + } elseif ($edit) { + if (!$appId) { + $output->writeln('ID of the application must be provided with option --app_id to edit the application.'); + + return 0; + } + + if (null === $user = $userRepository->find($userId)) { + $output->writeln('User not found'); + return 0; + } + + $application = $apiApllicationConverter->convert($appId); + $account = $accountRepository->findByUserAndApplication($user, $application); + + if (!$account) { + $output->writeln('ApiAccount not found!Check the given user_id and app_id!'); + + return 0; + } + + if ($name) { + $application->setName($name); + } + if ($type) { + $applicationManipulator->setType($application, $type); + } + if ($description) { + $application->setDescription($description); + } + if ($website) { + $applicationManipulator->setWebsiteUrl($application, $website); + } + if ($urlCallback) { + $applicationManipulator->setRedirectUri($application, $urlCallback); + } + if ($createToken) { + $apiOauthTokenManipulator->create($account); + } + if ($activatePassword) { + if (in_array($activatePassword, ['true', 'false'])) { + $application->setGrantPassword(($activatePassword == 'true') ? true : false); + } else { + $output->writeln(' Value of option --activate_password should be "true" or "false"'); + + return 0; + } + } + if ($webhookUrl) { + $applicationManipulator->setWebhookUrl($application, $webhookUrl); + } + + $applicationManipulator->update($application); + + $this->showApllicationInformation($apiOauthRepository, $account, $application, $jsonformat, $output); + } elseif ($list) { + if ($userId) { + if (null === $user = $userRepository->find($userId)) { + $output->writeln('User not found'); + + return 0; + } + + $accounts = $accountRepository->findByUser($user); + } else { + $accounts = $accountRepository->findAll(); + } + + $applicationList = []; + + foreach ($accounts as $account) { + $application = $account->getApplication(); + $token = $apiOauthRepository->findDeveloperToken($account); + + $applicationList[] = [ + $application->getId(), + $account->getUser()->getId(), + $application->getName(), + $application->getClientId(), + $application->getRedirectUri(), + ($token) ? $token->getOauthToken() : '-', + $application->isPasswordGranted() ? "true": "false" + ]; + } + + $applicationTable = $this->getHelperSet()->get('table'); + $headers = ['ID', 'user ID', 'Name', 'client ID', 'Callback Url', 'generated token', 'activate_password status']; + + if ($jsonformat ) { + foreach ($applicationList as $appList) { + $appInfo[] = array_combine($headers, $appList); + } + + echo json_encode($appInfo); + } else { + $applicationTable = $this->getHelperSet()->get('table'); + $applicationTable + ->setHeaders($headers) + ->setRows($applicationList) + ->render($output) + ; + } + } elseif ($delete) { + if (!$appId) { + $output->writeln('ID of the application must be provided with option --app_id to delete the app.'); + + return 0; + } + + $application = $apiApllicationConverter->convert($appId); + + $applicationManipulator->delete($application); + + $output->writeln("Application ID $appId deleted successfully !"); + } + + return 0; + } + + private function showApllicationInformation($apiOauthRepository, ApiAccount $account, ApiApplication $application, $jsonformat, $output) + { + $token = $account ? $apiOauthRepository->findDeveloperToken($account) : null; + + $applicationCreated = [ + $application->getClientSecret(), + $application->getClientId(), + $this->container["conf"]->get("servername") . "api/oauthv2/authorize", + $this->container["conf"]->get("servername") . "api/oauthv2/token", + ($token) ? $token->getOauthToken() : '-', + $application->isPasswordGranted() ? "true": "false" + ]; + + $headers = ['client secret', 'client ID', 'Authorize endpoint url', 'Access endpoint', 'generated token', 'activate_password status']; + if ($jsonformat ) { + $createdAppInfo = array_combine($headers, $applicationCreated); + echo json_encode($createdAppInfo); + } else { + $table = $this->getHelperSet()->get('table'); + $table + ->setHeaders($headers) + ->setRows([$applicationCreated]) + ->render($output) + ; + } + } +} From 45ab79f5065c251be6176a28999195d4a7f9fd75 Mon Sep 17 00:00:00 2001 From: Nicolas Maillat Date: Thu, 27 Feb 2020 16:09:09 +0100 Subject: [PATCH 2/9] Change in application help --- .../Command/Application/ApplicationAppCommand.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/Alchemy/Phrasea/Command/Application/ApplicationAppCommand.php b/lib/Alchemy/Phrasea/Command/Application/ApplicationAppCommand.php index 5494c4f73b..7ac9a1d7a0 100644 --- a/lib/Alchemy/Phrasea/Command/Application/ApplicationAppCommand.php +++ b/lib/Alchemy/Phrasea/Command/Application/ApplicationAppCommand.php @@ -34,17 +34,17 @@ class ApplicationAppCommand extends Command { parent::__construct('application:app'); - $this->setDescription('Create, edit, delete application in Phraseanet (experimental)') - ->addOption('user_id', 'u', InputOption::VALUE_REQUIRED, 'The desired login for created user.') + $this->setDescription('List, Create, Edit, Delete application in Phraseanet (experimental)') + ->addOption('user_id', 'u', InputOption::VALUE_REQUIRED, 'The id of user.') ->addOption('app_id', 'a', InputOption::VALUE_REQUIRED, 'The application ID') ->addOption('name', null, InputOption::VALUE_REQUIRED, 'The desired name for application user.') - ->addOption('type', 't', InputOption::VALUE_OPTIONAL, 'The desired name for application user.',ApiApplication::WEB_TYPE) + ->addOption('type', 't', InputOption::VALUE_OPTIONAL, 'The kind of application user Desktop or Web.',ApiApplication::WEB_TYPE) ->addOption('description', 'd', InputOption::VALUE_REQUIRED, 'The desired description for application user.') ->addOption('website', 'w', InputOption::VALUE_OPTIONAL, 'The desired url for application user.') - ->addOption('callback', 'c', InputOption::VALUE_OPTIONAL, 'The desired url for application user.') - ->addOption('webhook_url', null, InputOption::VALUE_REQUIRED, 'Define a webhook url on edit') - ->addOption('create_token', null, InputOption::VALUE_NONE, 'Generate an access token when app is created') - ->addOption('activate_password', null, InputOption::VALUE_OPTIONAL, 'Activate password OAuth2 grant type , values true or false', 'false') + ->addOption('callback', 'c', InputOption::VALUE_OPTIONAL, 'The desired callback endpoint for application user.') + ->addOption('webhook_url', null, InputOption::VALUE_REQUIRED, 'The desired webhook url for application') + ->addOption('create_token', null, InputOption::VALUE_NONE, 'Generate or regenerate an access token') + ->addOption('activate_password', null, InputOption::VALUE_OPTIONAL, 'Activateor deactivate password OAuth2 grant type , values true or false', 'false') ->addOption('create', null, InputOption::VALUE_NONE, 'Create application for user in Phraseanet') ->addOption('edit', null, InputOption::VALUE_NONE, 'Edit application in Phraseanet work only if app_id and user_id are set') ->addOption('delete', null, InputOption::VALUE_NONE, 'Delete application in Phraseanet, need app_id') From c1c69670b2e5967d7f0e40bb1b7c9e3b91150b3f Mon Sep 17 00:00:00 2001 From: aynsix Date: Thu, 27 Feb 2020 18:29:56 +0300 Subject: [PATCH 3/9] change command to user:applications --- bin/console | 4 ++-- .../UserApplicationsCommand.php} | 11 ++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) rename lib/Alchemy/Phrasea/Command/{Application/ApplicationAppCommand.php => User/UserApplicationsCommand.php} (97%) diff --git a/bin/console b/bin/console index 1dfa643be2..96ae294af0 100755 --- a/bin/console +++ b/bin/console @@ -31,7 +31,7 @@ use Alchemy\Phrasea\Command\Compile\Configuration; use Alchemy\Phrasea\Command\RecordAdd; use Alchemy\Phrasea\Command\RescanTechnicalDatas; use Alchemy\Phrasea\CLI; -use Alchemy\Phrasea\Command\Application\ApplicationAppCommand; +use Alchemy\Phrasea\Command\User\UserApplicationsCommand; use Alchemy\Phrasea\Command\Plugin\AddPlugin; use Alchemy\Phrasea\Command\Plugin\RemovePlugin; use Alchemy\Phrasea\Command\CheckConfig; @@ -113,7 +113,7 @@ $cli->command(new \module_console_fieldsDelete('fields:delete')); $cli->command(new \module_console_fieldsRename('fields:rename')); $cli->command(new \module_console_fieldsMerge('fields:merge')); -$cli->command(new ApplicationAppCommand('application:app')); +$cli->command(new UserApplicationsCommand('user:applications')); $cli->command(new CreateCollection('collection:create')); $cli->command(new ListCollectionCommand('collection:list')); diff --git a/lib/Alchemy/Phrasea/Command/Application/ApplicationAppCommand.php b/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php similarity index 97% rename from lib/Alchemy/Phrasea/Command/Application/ApplicationAppCommand.php rename to lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php index 7ac9a1d7a0..8163992433 100644 --- a/lib/Alchemy/Phrasea/Command/Application/ApplicationAppCommand.php +++ b/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Alchemy\Phrasea\Command\Application; +namespace Alchemy\Phrasea\Command\User; use Alchemy\Phrasea\Command\Command; use Alchemy\Phrasea\Core\LazyLocator; @@ -24,7 +24,7 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Input\InputOption; -class ApplicationAppCommand extends Command +class UserApplicationsCommand extends Command { /** @@ -32,7 +32,7 @@ class ApplicationAppCommand extends Command */ public function __construct($name = null) { - parent::__construct('application:app'); + parent::__construct('user:applications'); $this->setDescription('List, Create, Edit, Delete application in Phraseanet (experimental)') ->addOption('user_id', 'u', InputOption::VALUE_REQUIRED, 'The id of user.') @@ -129,6 +129,11 @@ class ApplicationAppCommand extends Command } } + if ($webhookUrl) { + $applicationManipulator->setWebhookUrl($application, $webhookUrl); + $applicationManipulator->update($application); + } + $this->showApllicationInformation($apiOauthRepository, $account, $application, $jsonformat, $output); } catch (\Exception $e) { $output->writeln('Create an application for user failed : '.$e->getMessage().''); From 52c5e5052fd54a5cc9850c70f8dc2f20e12b3455 Mon Sep 17 00:00:00 2001 From: Nicolas Maillat Date: Thu, 27 Feb 2020 17:15:07 +0100 Subject: [PATCH 4/9] update cmd help --- .../Command/User/UserApplicationsCommand.php | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php b/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php index 8163992433..2f8f46dfd4 100644 --- a/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php +++ b/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php @@ -35,20 +35,20 @@ class UserApplicationsCommand extends Command parent::__construct('user:applications'); $this->setDescription('List, Create, Edit, Delete application in Phraseanet (experimental)') - ->addOption('user_id', 'u', InputOption::VALUE_REQUIRED, 'The id of user.') - ->addOption('app_id', 'a', InputOption::VALUE_REQUIRED, 'The application ID') - ->addOption('name', null, InputOption::VALUE_REQUIRED, 'The desired name for application user.') - ->addOption('type', 't', InputOption::VALUE_OPTIONAL, 'The kind of application user Desktop or Web.',ApiApplication::WEB_TYPE) - ->addOption('description', 'd', InputOption::VALUE_REQUIRED, 'The desired description for application user.') - ->addOption('website', 'w', InputOption::VALUE_OPTIONAL, 'The desired url for application user.') - ->addOption('callback', 'c', InputOption::VALUE_OPTIONAL, 'The desired callback endpoint for application user.') - ->addOption('webhook_url', null, InputOption::VALUE_REQUIRED, 'The desired webhook url for application') + ->addOption('user_id', 'u', InputOption::VALUE_REQUIRED, 'The owner id (user id), required for Create Edit and Delete.') + ->addOption('app_id', 'a', InputOption::VALUE_REQUIRED, 'The application ID, required for Edit and Delete') + ->addOption('name', null, InputOption::VALUE_REQUIRED, 'The desired name for application, required for Create and Edit.') + ->addOption('type', 't', InputOption::VALUE_OPTIONAL, 'The kind of application, Desktop or Web.',ApiApplication::WEB_TYPE) + ->addOption('description', 'd', InputOption::VALUE_REQUIRED, 'The desired description for application.') + ->addOption('website', 'w', InputOption::VALUE_OPTIONAL, 'The desired url.') + ->addOption('callback', 'c', InputOption::VALUE_OPTIONAL, 'The desired endpoint for callback, required for web kind') + ->addOption('webhook_url', null, InputOption::VALUE_REQUIRED, 'The webhook url') ->addOption('create_token', null, InputOption::VALUE_NONE, 'Generate or regenerate an access token') - ->addOption('activate_password', null, InputOption::VALUE_OPTIONAL, 'Activateor deactivate password OAuth2 grant type , values true or false', 'false') + ->addOption('activate_password', null, InputOption::VALUE_OPTIONAL, 'Activate or deactivate password OAuth2 grant type , values true or false', 'false') ->addOption('create', null, InputOption::VALUE_NONE, 'Create application for user in Phraseanet') ->addOption('edit', null, InputOption::VALUE_NONE, 'Edit application in Phraseanet work only if app_id and user_id are set') - ->addOption('delete', null, InputOption::VALUE_NONE, 'Delete application in Phraseanet, need app_id') - ->addOption('list', null, InputOption::VALUE_NONE, 'List all application or user application if --user_id is set') + ->addOption('delete', null, InputOption::VALUE_NONE, 'Delete application in Phraseanet, require an app_id') + ->addOption('list', null, InputOption::VALUE_NONE, 'List all applications or user applications if --user_id is set') ->addOption('jsonformat', null, InputOption::VALUE_NONE, 'Output in json format') ->setHelp(''); From a99c23c59e2de25e58ae09ecb3f349788f0d6d67 Mon Sep 17 00:00:00 2001 From: aynsix Date: Fri, 28 Feb 2020 12:30:56 +0300 Subject: [PATCH 5/9] fix command --- .../Command/User/UserApplicationsCommand.php | 81 +++++++++++++------ 1 file changed, 55 insertions(+), 26 deletions(-) diff --git a/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php b/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php index 2f8f46dfd4..d51065dbc6 100644 --- a/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php +++ b/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php @@ -12,6 +12,7 @@ namespace Alchemy\Phrasea\Command\User; use Alchemy\Phrasea\Command\Command; +use Alchemy\Phrasea\ControllerProvider\Api\V2; use Alchemy\Phrasea\Core\LazyLocator; use Alchemy\Phrasea\Model\Entities\ApiApplication; use Alchemy\Phrasea\Model\Entities\ApiAccount; @@ -35,6 +36,10 @@ class UserApplicationsCommand extends Command parent::__construct('user:applications'); $this->setDescription('List, Create, Edit, Delete application in Phraseanet (experimental)') + ->addOption('list', null, InputOption::VALUE_NONE, 'List all applications or user applications if --user_id is set') + ->addOption('create', null, InputOption::VALUE_NONE, 'Create application for user in Phraseanet') + ->addOption('edit', null, InputOption::VALUE_NONE, 'Edit application in Phraseanet work only if app_id is set') + ->addOption('delete', null, InputOption::VALUE_NONE, 'Delete application in Phraseanet, require an app_id') ->addOption('user_id', 'u', InputOption::VALUE_REQUIRED, 'The owner id (user id), required for Create Edit and Delete.') ->addOption('app_id', 'a', InputOption::VALUE_REQUIRED, 'The application ID, required for Edit and Delete') ->addOption('name', null, InputOption::VALUE_REQUIRED, 'The desired name for application, required for Create and Edit.') @@ -43,12 +48,9 @@ class UserApplicationsCommand extends Command ->addOption('website', 'w', InputOption::VALUE_OPTIONAL, 'The desired url.') ->addOption('callback', 'c', InputOption::VALUE_OPTIONAL, 'The desired endpoint for callback, required for web kind') ->addOption('webhook_url', null, InputOption::VALUE_REQUIRED, 'The webhook url') - ->addOption('create_token', null, InputOption::VALUE_NONE, 'Generate or regenerate an access token') - ->addOption('activate_password', null, InputOption::VALUE_OPTIONAL, 'Activate or deactivate password OAuth2 grant type , values true or false', 'false') - ->addOption('create', null, InputOption::VALUE_NONE, 'Create application for user in Phraseanet') - ->addOption('edit', null, InputOption::VALUE_NONE, 'Edit application in Phraseanet work only if app_id and user_id are set') - ->addOption('delete', null, InputOption::VALUE_NONE, 'Delete application in Phraseanet, require an app_id') - ->addOption('list', null, InputOption::VALUE_NONE, 'List all applications or user applications if --user_id is set') + ->addOption('active', null, InputOption::VALUE_OPTIONAL, 'Activate or unactive the app, values true or false', 'true') + ->addOption('generate_token', null, InputOption::VALUE_NONE, 'Generate or regenerate an access token') + ->addOption('activate_password', null, InputOption::VALUE_OPTIONAL, 'Activate or deactivate password OAuth2 grant type , values true or false', 'false') ->addOption('jsonformat', null, InputOption::VALUE_NONE, 'Output in json format') ->setHelp(''); @@ -58,15 +60,16 @@ class UserApplicationsCommand extends Command protected function doExecute(InputInterface $input, OutputInterface $output) { - $userId = $input->getOption('user_id'); - $appId = $input->getOption('app_id'); - $name = $input->getOption('name'); - $type = $input->getOption('type'); - $description = $input->getOption('description'); - $website = $input->getOption('website'); - $urlCallback = $input->getOption('callback'); - $webhookUrl = $input->getOption('webhook_url'); - $createToken = $input->getOption('create_token'); + $userId = $input->getOption('user_id'); + $appId = $input->getOption('app_id'); + $name = $input->getOption('name'); + $type = $input->getOption('type'); + $description = $input->getOption('description'); + $website = $input->getOption('website'); + $urlCallback = $input->getOption('callback'); + $webhookUrl = $input->getOption('webhook_url'); + $active = $input->getOption('active'); + $generateToken = $input->getOption('generate_token'); $activatePassword = $input->getOption('activate_password'); $create = $input->getOption('create'); $edit = $input->getOption('edit'); @@ -114,7 +117,7 @@ class UserApplicationsCommand extends Command $account = $accountRepository->findByUserAndApplication($user, $application); - if ($createToken) { + if ($generateToken) { $apiOauthTokenManipulator->create($account); } @@ -134,6 +137,20 @@ class UserApplicationsCommand extends Command $applicationManipulator->update($application); } + if ($active) { + if (in_array($active, ['true', 'false'])) { + $application->setActivated(($active == 'true') ? true : false); + $applicationManipulator->update($application); + } else { + $output->writeln('Value of option --active should be "true" or "false"'); + + return 0; + } + } else { + $application->setActivated(true); + $applicationManipulator->update($application); + } + $this->showApllicationInformation($apiOauthRepository, $account, $application, $jsonformat, $output); } catch (\Exception $e) { $output->writeln('Create an application for user failed : '.$e->getMessage().''); @@ -145,16 +162,11 @@ class UserApplicationsCommand extends Command return 0; } - if (null === $user = $userRepository->find($userId)) { - $output->writeln('User not found'); - return 0; - } - $application = $apiApllicationConverter->convert($appId); - $account = $accountRepository->findByUserAndApplication($user, $application); + $account = $accountRepository->findByUserAndApplication($application->getCreator(), $application); if (!$account) { - $output->writeln('ApiAccount not found!Check the given user_id and app_id!'); + $output->writeln('ApiAccount not found!'); return 0; } @@ -164,6 +176,9 @@ class UserApplicationsCommand extends Command } if ($type) { $applicationManipulator->setType($application, $type); + if ($type == ApiApplication::DESKTOP_TYPE) { + $applicationManipulator->setRedirectUri($application, ApiApplication::NATIVE_APP_REDIRECT_URI); + } } if ($description) { $application->setDescription($description); @@ -174,8 +189,12 @@ class UserApplicationsCommand extends Command if ($urlCallback) { $applicationManipulator->setRedirectUri($application, $urlCallback); } - if ($createToken) { - $apiOauthTokenManipulator->create($account); + if ($generateToken) { + if (null !== $devToken = $apiOauthRepository->findDeveloperToken($account)) { + $apiOauthTokenManipulator->renew($devToken); + } else { + $apiOauthTokenManipulator->create($account); + } } if ($activatePassword) { if (in_array($activatePassword, ['true', 'false'])) { @@ -190,6 +209,16 @@ class UserApplicationsCommand extends Command $applicationManipulator->setWebhookUrl($application, $webhookUrl); } + if ($active) { + if (in_array($active, ['true', 'false'])) { + $application->setActivated(($active == 'true') ? true : false); + } else { + $output->writeln('Value of option --active should be "true" or "false"'); + + return 0; + } + } + $applicationManipulator->update($application); $this->showApllicationInformation($apiOauthRepository, $account, $application, $jsonformat, $output); @@ -224,7 +253,7 @@ class UserApplicationsCommand extends Command } $applicationTable = $this->getHelperSet()->get('table'); - $headers = ['ID', 'user ID', 'Name', 'client ID', 'Callback Url', 'generated token', 'activate_password status']; + $headers = ['app_id', 'user_id', 'name', 'client_id', 'callback_url', 'generated token', 'activate_password status']; if ($jsonformat ) { foreach ($applicationList as $appList) { From 05b31a5881898c0576e4c142417e163abbc5624f Mon Sep 17 00:00:00 2001 From: aynsix Date: Fri, 28 Feb 2020 15:00:34 +0300 Subject: [PATCH 6/9] confirmation on delete --- .../Command/User/UserApplicationsCommand.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php b/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php index d51065dbc6..0f7b3fb8fc 100644 --- a/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php +++ b/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php @@ -12,6 +12,7 @@ namespace Alchemy\Phrasea\Command\User; use Alchemy\Phrasea\Command\Command; +use Symfony\Component\Console\Helper\DialogHelper; use Alchemy\Phrasea\ControllerProvider\Api\V2; use Alchemy\Phrasea\Core\LazyLocator; use Alchemy\Phrasea\Model\Entities\ApiApplication; @@ -278,6 +279,19 @@ class UserApplicationsCommand extends Command $application = $apiApllicationConverter->convert($appId); + if (is_null($application->getCreator())) { + /** @var DialogHelper $dialog */ + $dialog = $this->getHelperSet()->get('dialog'); + + $continue = $dialog->askConfirmation($output, "It's a special phraseanet application, do you want really to delete it? (N/y)", false); + + if (!$continue) { + $output->writeln("See you later !"); + + return 0; + } + } + $applicationManipulator->delete($application); $output->writeln("Application ID $appId deleted successfully !"); From d2a899ab4f134001da66e9b37b4d65b63c587c4c Mon Sep 17 00:00:00 2001 From: Nicolas Maillat Date: Fri, 28 Feb 2020 13:31:36 +0100 Subject: [PATCH 7/9] change in help --- .../Phrasea/Command/User/UserApplicationsCommand.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php b/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php index 0f7b3fb8fc..082cc1f074 100644 --- a/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php +++ b/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php @@ -41,13 +41,13 @@ class UserApplicationsCommand extends Command ->addOption('create', null, InputOption::VALUE_NONE, 'Create application for user in Phraseanet') ->addOption('edit', null, InputOption::VALUE_NONE, 'Edit application in Phraseanet work only if app_id is set') ->addOption('delete', null, InputOption::VALUE_NONE, 'Delete application in Phraseanet, require an app_id') - ->addOption('user_id', 'u', InputOption::VALUE_REQUIRED, 'The owner id (user id), required for Create Edit and Delete.') + ->addOption('user_id', 'u', InputOption::VALUE_REQUIRED, 'The Id of user owner of application (user_id), required to Create, Edit and Delete.') ->addOption('app_id', 'a', InputOption::VALUE_REQUIRED, 'The application ID, required for Edit and Delete') ->addOption('name', null, InputOption::VALUE_REQUIRED, 'The desired name for application, required for Create and Edit.') ->addOption('type', 't', InputOption::VALUE_OPTIONAL, 'The kind of application, Desktop or Web.',ApiApplication::WEB_TYPE) ->addOption('description', 'd', InputOption::VALUE_REQUIRED, 'The desired description for application.') - ->addOption('website', 'w', InputOption::VALUE_OPTIONAL, 'The desired url.') - ->addOption('callback', 'c', InputOption::VALUE_OPTIONAL, 'The desired endpoint for callback, required for web kind') + ->addOption('website', 'w', InputOption::VALUE_OPTIONAL, 'The desired url, eg: -w "https://www.alchemy.fr".') + ->addOption('callback', 'c', InputOption::VALUE_OPTIONAL, 'The desired endpoint for callback, required for web kind eg: -c "https://www.alchemy.fr/callback"') ->addOption('webhook_url', null, InputOption::VALUE_REQUIRED, 'The webhook url') ->addOption('active', null, InputOption::VALUE_OPTIONAL, 'Activate or unactive the app, values true or false', 'true') ->addOption('generate_token', null, InputOption::VALUE_NONE, 'Generate or regenerate an access token') From d3b4d78b725f4939bd394821a0f5e5f451fe6b6f Mon Sep 17 00:00:00 2001 From: aynsix Date: Fri, 28 Feb 2020 16:06:58 +0300 Subject: [PATCH 8/9] change activate_password to password_oauth2_gt --- .../Command/User/UserApplicationsCommand.php | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php b/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php index 082cc1f074..7e047555c6 100644 --- a/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php +++ b/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php @@ -25,7 +25,6 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Input\InputOption; - class UserApplicationsCommand extends Command { @@ -51,7 +50,7 @@ class UserApplicationsCommand extends Command ->addOption('webhook_url', null, InputOption::VALUE_REQUIRED, 'The webhook url') ->addOption('active', null, InputOption::VALUE_OPTIONAL, 'Activate or unactive the app, values true or false', 'true') ->addOption('generate_token', null, InputOption::VALUE_NONE, 'Generate or regenerate an access token') - ->addOption('activate_password', null, InputOption::VALUE_OPTIONAL, 'Activate or deactivate password OAuth2 grant type , values true or false', 'false') + ->addOption('password_oauth2_gt', null, InputOption::VALUE_OPTIONAL, 'Activate or deactivate password OAuth2 grant type , values true or false', 'false') ->addOption('jsonformat', null, InputOption::VALUE_NONE, 'Output in json format') ->setHelp(''); @@ -71,7 +70,7 @@ class UserApplicationsCommand extends Command $webhookUrl = $input->getOption('webhook_url'); $active = $input->getOption('active'); $generateToken = $input->getOption('generate_token'); - $activatePassword = $input->getOption('activate_password'); + $passwordOauth2Gt = $input->getOption('password_oauth2_gt'); $create = $input->getOption('create'); $edit = $input->getOption('edit'); $delete = $input->getOption('delete'); @@ -122,12 +121,12 @@ class UserApplicationsCommand extends Command $apiOauthTokenManipulator->create($account); } - if ($activatePassword) { - if (in_array($activatePassword, ['true', 'false'])) { - $application->setGrantPassword(($activatePassword == 'true') ? true : false); + if ($passwordOauth2Gt) { + if (in_array($passwordOauth2Gt, ['true', 'false'])) { + $application->setGrantPassword(($passwordOauth2Gt == 'true') ? true : false); $applicationManipulator->update($application); } else { - $output->writeln(' Value of option --activate_password should be "true" or "false"'); + $output->writeln(' Value of option --password_oauth2_gt should be "true" or "false"'); return 0; } @@ -197,11 +196,11 @@ class UserApplicationsCommand extends Command $apiOauthTokenManipulator->create($account); } } - if ($activatePassword) { - if (in_array($activatePassword, ['true', 'false'])) { - $application->setGrantPassword(($activatePassword == 'true') ? true : false); + if ($passwordOauth2Gt) { + if (in_array($passwordOauth2Gt, ['true', 'false'])) { + $application->setGrantPassword(($passwordOauth2Gt == 'true') ? true : false); } else { - $output->writeln(' Value of option --activate_password should be "true" or "false"'); + $output->writeln(' Value of option --password_oauth2_gt should be "true" or "false"'); return 0; } @@ -254,7 +253,7 @@ class UserApplicationsCommand extends Command } $applicationTable = $this->getHelperSet()->get('table'); - $headers = ['app_id', 'user_id', 'name', 'client_id', 'callback_url', 'generated token', 'activate_password status']; + $headers = ['app_id', 'user_id', 'name', 'client_id', 'callback_url', 'generated token', 'grant_password status']; if ($jsonformat ) { foreach ($applicationList as $appList) { @@ -313,7 +312,7 @@ class UserApplicationsCommand extends Command $application->isPasswordGranted() ? "true": "false" ]; - $headers = ['client secret', 'client ID', 'Authorize endpoint url', 'Access endpoint', 'generated token', 'activate_password status']; + $headers = ['client secret', 'client ID', 'Authorize endpoint url', 'Access endpoint', 'generated token', 'grant_password status']; if ($jsonformat ) { $createdAppInfo = array_combine($headers, $applicationCreated); echo json_encode($createdAppInfo); From f3e97aaec33d43c47385b1ba960643eba785e1d5 Mon Sep 17 00:00:00 2001 From: Nicolas Maillat Date: Fri, 28 Feb 2020 19:14:46 +0100 Subject: [PATCH 9/9] update help --- lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php b/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php index 7e047555c6..cbef2cb103 100644 --- a/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php +++ b/lib/Alchemy/Phrasea/Command/User/UserApplicationsCommand.php @@ -48,8 +48,8 @@ class UserApplicationsCommand extends Command ->addOption('website', 'w', InputOption::VALUE_OPTIONAL, 'The desired url, eg: -w "https://www.alchemy.fr".') ->addOption('callback', 'c', InputOption::VALUE_OPTIONAL, 'The desired endpoint for callback, required for web kind eg: -c "https://www.alchemy.fr/callback"') ->addOption('webhook_url', null, InputOption::VALUE_REQUIRED, 'The webhook url') - ->addOption('active', null, InputOption::VALUE_OPTIONAL, 'Activate or unactive the app, values true or false', 'true') - ->addOption('generate_token', null, InputOption::VALUE_NONE, 'Generate or regenerate an access token') + ->addOption('active', null, InputOption::VALUE_OPTIONAL, 'Activate or deactivate the app, values true or false', 'true') + ->addOption('generate_token', null, InputOption::VALUE_NONE, 'Generate or regenerate the access token') ->addOption('password_oauth2_gt', null, InputOption::VALUE_OPTIONAL, 'Activate or deactivate password OAuth2 grant type , values true or false', 'false') ->addOption('jsonformat', null, InputOption::VALUE_NONE, 'Output in json format')