Skip to content

Commit

Permalink
Merge pull request #861 from nextcloud/enh/noid/contexts-api
Browse files Browse the repository at this point in the history
Contexts API
  • Loading branch information
blizzz authored Mar 12, 2024
2 parents 990c5ca + dd896ac commit b9e9e42
Show file tree
Hide file tree
Showing 24 changed files with 3,501 additions and 29 deletions.
2 changes: 2 additions & 0 deletions appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ Have a good time and manage whatever you want.
<command>OCA\Tables\Command\RemoveTable</command>
<command>OCA\Tables\Command\RenameTable</command>
<command>OCA\Tables\Command\ChangeOwnershipTable</command>
<command>OCA\Tables\Command\ListContexts</command>
<command>OCA\Tables\Command\ShowContext</command>
<command>OCA\Tables\Command\Clean</command>
<command>OCA\Tables\Command\CleanLegacy</command>
<command>OCA\Tables\Command\TransferLegacyRows</command>
Expand Down
8 changes: 8 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,5 +128,13 @@

['name' => 'ApiFavorite#create', 'url' => '/api/2/favorites/{nodeType}/{nodeId}', 'verb' => 'POST', 'requirements' => ['nodeType' => '(\d+)', 'nodeId' => '(\d+)']],
['name' => 'ApiFavorite#destroy', 'url' => '/api/2/favorites/{nodeType}/{nodeId}', 'verb' => 'DELETE', 'requirements' => ['nodeType' => '(\d+)', 'nodeId' => '(\d+)']],
['name' => 'Context#index', 'url' => '/api/2/contexts', 'verb' => 'GET'],
['name' => 'Context#show', 'url' => '/api/2/contexts/{contextId}', 'verb' => 'GET'],
['name' => 'Context#create', 'url' => '/api/2/contexts', 'verb' => 'POST'],
['name' => 'Context#update', 'url' => '/api/2/contexts/{contextId}', 'verb' => 'PUT'],
['name' => 'Context#transfer', 'url' => '/api/2/contexts/{contextId}/transfer', 'verb' => 'PUT'],
['name' => 'Context#addNode', 'url' => '/api/2/contexts/{contextId}/nodes', 'verb' => 'POST'],
['name' => 'Context#removeNode', 'url' => '/api/2/contexts/{contextId}/nodes/{nodeRelId}', 'verb' => 'DELETE'],
['name' => 'Context#updateContentOrder', 'url' => '/api/2/contexts/{contextId}/pages/{pageId}', 'verb' => 'PUT'],
]
];
5 changes: 5 additions & 0 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use OCA\Tables\Listener\LoadAdditionalListener;
use OCA\Tables\Listener\TablesReferenceListener;
use OCA\Tables\Listener\UserDeletedListener;
use OCA\Tables\Middleware\PermissionMiddleware;
use OCA\Tables\Reference\ContentReferenceProvider;
use OCA\Tables\Reference\LegacyReferenceProvider;
use OCA\Tables\Reference\ReferenceProvider;
Expand All @@ -32,6 +33,8 @@ class Application extends App implements IBootstrap {
public const NODE_TYPE_TABLE = 0;
public const NODE_TYPE_VIEW = 1;

public const OWNER_TYPE_USER = 0;

public function __construct() {
parent::__construct(self::APP_ID);
}
Expand Down Expand Up @@ -65,6 +68,8 @@ public function register(IRegistrationContext $context): void {
}

$context->registerCapability(Capabilities::class);

$context->registerMiddleware(PermissionMiddleware::class);
}

public function boot(IBootContext $context): void {
Expand Down
89 changes: 89 additions & 0 deletions lib/Command/ListContexts.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php

declare(strict_types=1);

namespace OCA\Tables\Command;

use OC\Core\Command\Base;
use OCA\Tables\Errors\InternalError;
use OCA\Tables\Service\ContextService;
use OCP\DB\Exception;
use OCP\IConfig;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use function json_decode;
use function json_encode;

class ListContexts extends Base {
protected ContextService $contextService;
protected LoggerInterface $logger;
private IConfig $config;

public function __construct(
ContextService $contextService,
LoggerInterface $logger,
IConfig $config,
) {
parent::__construct();
$this->contextService = $contextService;
$this->logger = $logger;
$this->config = $config;
}

protected function configure(): void {
parent::configure();
$this
->setName('tables:contexts:list')
->setDescription('Get all contexts or contexts available to a specified user')
->addArgument(
'user-id',
InputArgument::OPTIONAL,
'User ID of the user'
)
;
}

protected function execute(InputInterface $input, OutputInterface $output): int {
$userId = trim($input->getArgument('user-id'));
if ($userId === '') {
$userId = null;
}

try {
$contexts = $this->contextService->findAll($userId);
} catch (InternalError|Exception $e) {
$output->writeln('Error while reading contexts from DB.');
$this->logger->warning('Following error occurred during executing occ command "{class}"',
[
'app' => 'tables',
'class' => self::class,
'exception' => $e,
]
);
if ($this->config->getSystemValueBool('debug', false)) {
$output->writeln(sprintf('<warning>%s</warning>', $e->getMessage()));
$output->writeln('<error>');
debug_print_backtrace();
$output->writeln('</error>');
}
return 1;
}

foreach ($contexts as $context) {
$contextArray = json_decode(json_encode($context), true);

$contextArray['ownerType'] = match ($contextArray['ownerType']) {
1 => 'group',
default => 'user',
};

$out = ['ID ' . $contextArray['id'] => $contextArray];
unset($out[$contextArray['id']]['id']);
$this->writeArrayInOutputFormat($input, $output, $out);
}

return 0;
}
}
98 changes: 98 additions & 0 deletions lib/Command/ShowContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

declare(strict_types=1);

namespace OCA\Tables\Command;

use OC\Core\Command\Base;
use OCA\Tables\Errors\InternalError;
use OCA\Tables\Service\ContextService;
use OCP\DB\Exception;
use OCP\IConfig;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use function json_decode;
use function json_encode;

class ShowContext extends Base {
protected ContextService $contextService;
protected LoggerInterface $logger;
private IConfig $config;

public function __construct(
ContextService $contextService,
LoggerInterface $logger,
IConfig $config,
) {
parent::__construct();
$this->contextService = $contextService;
$this->logger = $logger;
$this->config = $config;
}

protected function configure(): void {
parent::configure();
$this
->setName('tables:contexts:show')
->setDescription('Get all contexts or contexts available to a specified user')
->addArgument(
'context-id',
InputArgument::REQUIRED,
'The ID of the context to show'
)
->addArgument(
'user-id',
InputArgument::OPTIONAL,
'Optionally, showing the context from the perspective of the given user'
)
;
}

protected function execute(InputInterface $input, OutputInterface $output): int {
$contextId = trim($input->getArgument('context-id'));
if ($contextId === '' || !is_numeric($contextId)) {
$output->writeln('<error>Invalid Context ID</error>');
return 1;
}

$userId = trim($input->getArgument('user-id'));
if ($userId === '') {
$userId = null;
}

try {
$context = $this->contextService->findById($contextId, $userId);
} catch (InternalError|Exception $e) {
$output->writeln('Error while reading contexts from DB.');
$this->logger->warning('Following error occurred during executing occ command "{class}"',
[
'app' => 'tables',
'class' => self::class,
'exception' => $e,
]
);
if ($this->config->getSystemValueBool('debug', false)) {
$output->writeln(sprintf('<warning>%s</warning>', $e->getMessage()));
$output->writeln('<error>');
debug_print_backtrace();
$output->writeln('</error>');
}
return 1;
}

$contextArray = json_decode(json_encode($context), true);

$contextArray['ownerType'] = match ($contextArray['ownerType']) {
1 => 'group',
default => 'user',
};

$out = ['ID ' . $contextArray['id'] => $contextArray];
unset($out[$contextArray['id']]['id']);
$this->writeArrayInOutputFormat($input, $output, $out);

return 0;
}
}
10 changes: 10 additions & 0 deletions lib/Controller/AOCSController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Exception;
use OCA\Tables\AppInfo\Application;
use OCA\Tables\Errors\BadRequestError;
use OCA\Tables\Errors\InternalError;
use OCA\Tables\Errors\NotFoundError;
use OCA\Tables\Errors\PermissionError;
Expand Down Expand Up @@ -59,4 +60,13 @@ protected function handleNotFoundError(NotFoundError $e): DataResponse {
return new DataResponse(['message' => $this->n->t('A not found error occurred. More details can be found in the logs. Please reach out to your administration.')], Http::STATUS_NOT_FOUND);
}

/**
* @param BadRequestError $e
* @return DataResponse<Http::STATUS_BAD_REQUEST, array{message: string}, array{}>
*/
protected function handleBadRequestError(BadRequestError $e): DataResponse {
$this->logger->warning('An bad request was encountered: ['. $e->getCode() . ']' . $e->getMessage());
return new DataResponse(['message' => $this->n->t('An error caused by an invalid request occurred. More details can be found in the logs. Please reach out to your administration.')], Http::STATUS_BAD_REQUEST);
}

}
Loading

0 comments on commit b9e9e42

Please sign in to comment.