-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This PR introduces API for registering OCC commands for ExApps. Note: **Passing file contents as the input argument is not supported** --------- Signed-off-by: Andrey Borysenko <[email protected]> Co-authored-by: Alexander Piskun <[email protected]>
- Loading branch information
1 parent
4e1313d
commit 052e3a0
Showing
15 changed files
with
736 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
use Psr\Container\ContainerExceptionInterface; | ||
use Psr\Container\ContainerInterface; | ||
use Psr\Container\NotFoundExceptionInterface; | ||
use Symfony\Component\Console\Application as SymfonyApplication; | ||
|
||
use OCP\Server; | ||
use OCP\IConfig; | ||
use OCA\AppAPI\Service\ExAppOccService; | ||
use OCA\AppAPI\Db\Console\ExAppOccCommand; | ||
|
||
try { | ||
$config = Server::get(IConfig::class); | ||
$serverContainer = Server::get(ContainerInterface::class); | ||
if ($config->getSystemValueBool('installed', false)) { | ||
$exAppOccService = Server::get(ExAppOccService::class); | ||
/** | ||
* @var ExAppOccCommand $occCommand | ||
* @var SymfonyApplication $application | ||
*/ | ||
foreach ($exAppOccService->getOccCommands() as $occCommand) { | ||
$application->add($exAppOccService->buildCommand( | ||
$occCommand, | ||
$serverContainer | ||
)); | ||
} | ||
} | ||
} catch (NotFoundExceptionInterface|ContainerExceptionInterface $e) { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
.. _occ_command: | ||
|
||
=========== | ||
OCC Command | ||
=========== | ||
|
||
This API allows you to register the occ (CLI) commands. | ||
The principal is similar to the regular Nextcloud OCC command for PHP apps, that are working in context of the Nextcloud instance, | ||
but for ExApps it is a trigger via Nextcloud OCC interface to perform some action on the External App side. | ||
|
||
|
||
.. note:: | ||
|
||
Passing files directly as an input argument to the occ command is not supported. | ||
|
||
Register | ||
^^^^^^^^ | ||
|
||
OCS endpoint: ``POST /apps/app_api/api/v1/occ_command`` | ||
|
||
Params | ||
****** | ||
|
||
.. code-block:: json | ||
{ | ||
"name": "appid:unique:command:name", | ||
"description": "Description of the command", | ||
"hidden": "true/false", | ||
"arguments": [ | ||
{ | ||
"name": "argument_name", | ||
"mode": "required/optional/array", | ||
"description": "Description of the argument", | ||
"default": "default_value" | ||
} | ||
], | ||
"options": [ | ||
{ | ||
"name": "option_name", | ||
"shortcut": "s", | ||
"mode": "required/optional/none/array/negatable", | ||
"description": "Description of the option", | ||
"default": "default_value" | ||
} | ||
], | ||
"usages": [ | ||
"occ appid:unique:command:name argument_name --option_name", | ||
"occ appid:unique:command:name argument_name -s" | ||
], | ||
"execute_handler": "handler_route" | ||
} | ||
For more details on the command arguments and options modes, | ||
see the original docs for the Symfony console input parameters, which are actually being built from the provided data: | ||
`https://symfony.com/doc/current/console/input.html#using-command-arguments <https://symfony.com/doc/current/console/input.html#using-command-arguments>`_ | ||
|
||
|
||
Example | ||
******* | ||
|
||
Lets assume we have a command `ping` that takes an argument `test_arg` and has an option `test-option`: | ||
|
||
.. code-block:: json | ||
{ | ||
"name": "my_app_id:ping", | ||
"description": "Test ping command", | ||
"hidden": "false", | ||
"arguments": [ | ||
{ | ||
"name": "test_arg", | ||
"mode": "required", | ||
"description": "Test argument", | ||
"default": 123 | ||
} | ||
], | ||
"options": [ | ||
{ | ||
"name": "test-option", | ||
"shortcut": "t", | ||
"mode": "none", | ||
"description": "Test option", | ||
} | ||
], | ||
"usages": [ | ||
"occ my_app_id:ping 12345", | ||
"occ my_app_id:ping 12345 --test-option", | ||
"occ my_app_id:ping 12345 -t" | ||
], | ||
"execute_handler": "handler_route" | ||
} | ||
Unregister | ||
^^^^^^^^^^ | ||
|
||
OCS endpoint: ``DELETE /apps/app_api/api/v1/occ_command`` | ||
|
||
Params | ||
****** | ||
|
||
To unregister OCC Command, you just need to provide a command `name`: | ||
|
||
.. code-block:: json | ||
{ | ||
"name": "occ_command_name" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace OCA\AppAPI\Controller; | ||
|
||
use OCA\AppAPI\AppInfo\Application; | ||
use OCA\AppAPI\Attribute\AppAPIAuth; | ||
use OCA\AppAPI\Service\ExAppOccService; | ||
use OCP\AppFramework\Http; | ||
use OCP\AppFramework\Http\Attribute\NoCSRFRequired; | ||
use OCP\AppFramework\Http\Attribute\PublicPage; | ||
use OCP\AppFramework\Http\DataResponse; | ||
use OCP\AppFramework\OCSController; | ||
use OCP\IRequest; | ||
|
||
class OccCommandController extends OCSController { | ||
protected $request; | ||
|
||
public function __construct( | ||
IRequest $request, | ||
private readonly ExAppOccService $service, | ||
) { | ||
parent::__construct(Application::APP_ID, $request); | ||
|
||
$this->request = $request; | ||
} | ||
|
||
#[NoCSRFRequired] | ||
#[PublicPage] | ||
#[AppAPIAuth] | ||
public function registerCommand( | ||
string $name, | ||
string $description, | ||
string $execute_handler, | ||
bool $hidden = false, | ||
array $arguments = [], | ||
array $options = [], | ||
array $usages = [], | ||
): DataResponse { | ||
$command = $this->service->registerCommand( | ||
$this->request->getHeader('EX-APP-ID'), $name, | ||
$description, $hidden, $arguments, $options, $usages, $execute_handler | ||
); | ||
if ($command === null) { | ||
return new DataResponse([], Http::STATUS_BAD_REQUEST); | ||
} | ||
return new DataResponse(); | ||
} | ||
|
||
#[NoCSRFRequired] | ||
#[PublicPage] | ||
#[AppAPIAuth] | ||
public function unregisterCommand(string $name): DataResponse { | ||
$unregistered = $this->service->unregisterCommand($this->request->getHeader('EX-APP-ID'), $name); | ||
if (!$unregistered) { | ||
return new DataResponse([], Http::STATUS_NOT_FOUND); | ||
} | ||
return new DataResponse(); | ||
} | ||
|
||
#[AppAPIAuth] | ||
#[PublicPage] | ||
#[NoCSRFRequired] | ||
public function getCommand(string $name): DataResponse { | ||
$result = $this->service->getOccCommand($this->request->getHeader('EX-APP-ID'), $name); | ||
if (!$result) { | ||
return new DataResponse([], Http::STATUS_NOT_FOUND); | ||
} | ||
return new DataResponse($result, Http::STATUS_OK); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace OCA\AppAPI\Db\Console; | ||
|
||
use JsonSerializable; | ||
use OCP\AppFramework\Db\Entity; | ||
|
||
/** | ||
* Class ExAppOccCommand | ||
* | ||
* @package OCA\AppAPI\Db\Console | ||
* | ||
* @method string getAppid() | ||
* @method string getName() | ||
* @method string getDescription() | ||
* @method bool getHidden() | ||
* @method array getArguments() | ||
* @method array getOptions() | ||
* @method array getUsages() | ||
* @method string getExecuteHandler() | ||
* @method void setAppid(string $appid) | ||
* @method void setName(string $name) | ||
* @method void setDescription(string $description) | ||
* @method void setHidden(bool $hidden) | ||
* @method void setArguments(array $arguments) | ||
* @method void setOptions(array $options) | ||
* @method void setUsages(array $usages) | ||
* @method void setExecuteHandler(string $executeHandler) | ||
*/ | ||
class ExAppOccCommand extends Entity implements JsonSerializable { | ||
protected $appid; | ||
protected $name; | ||
protected $description; | ||
protected $hidden; | ||
protected $arguments; | ||
protected $options; | ||
protected $usages; | ||
protected $executeHandler; | ||
|
||
/** | ||
* @param array $params | ||
*/ | ||
public function __construct(array $params = []) { | ||
$this->addType('appid', 'string'); | ||
$this->addType('name', 'string'); | ||
$this->addType('description', 'string'); | ||
$this->addType('hidden', 'bool'); | ||
$this->addType('arguments', 'json'); | ||
$this->addType('options', 'json'); | ||
$this->addType('usages', 'json'); | ||
$this->addType('executeHandler', 'string'); | ||
|
||
if (isset($params['id'])) { | ||
$this->setId($params['id']); | ||
} | ||
if (isset($params['appid'])) { | ||
$this->setAppid($params['appid']); | ||
} | ||
if (isset($params['name'])) { | ||
$this->setName($params['name']); | ||
} | ||
if (isset($params['description'])) { | ||
$this->setDescription($params['description']); | ||
} | ||
if (isset($params['hidden'])) { | ||
$this->setHidden($params['hidden']); | ||
} | ||
if (isset($params['arguments'])) { | ||
$this->setArguments($params['arguments']); | ||
} | ||
if (isset($params['options'])) { | ||
$this->setOptions($params['options']); | ||
} | ||
if (isset($params['usages'])) { | ||
$this->setUsages($params['usages']); | ||
} | ||
if (isset($params['execute_handler'])) { | ||
$this->setExecuteHandler($params['execute_handler']); | ||
} | ||
} | ||
|
||
public function jsonSerialize(): array { | ||
return [ | ||
'id' => $this->getId(), | ||
'appid' => $this->getAppid(), | ||
'name' => $this->getName(), | ||
'description' => $this->getDescription(), | ||
'hidden' => $this->getHidden(), | ||
'arguments' => $this->getArguments(), | ||
'options' => $this->getOptions(), | ||
'usages' => $this->getUsages(), | ||
'execute_handler' => $this->getExecuteHandler(), | ||
]; | ||
} | ||
} |
Oops, something went wrong.