-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
<?php | ||
|
||
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 { | ||
Check failure on line 17 in lib/Command/ListContexts.php GitHub Actions / static-psalm-analysis dev-masterUndefinedClass
Check failure on line 17 in lib/Command/ListContexts.php GitHub Actions / static-psalm-analysis dev-stable28UndefinedClass
|
||
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; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<?php | ||
|
||
namespace OCA\Tables\Controller; | ||
|
||
use OCA\Tables\Db\Context; | ||
use OCA\Tables\Errors\InternalError; | ||
use OCA\Tables\ResponseDefinitions; | ||
use OCA\Tables\Service\ContextService; | ||
use OCP\AppFramework\Http\DataResponse; | ||
use OCP\DB\Exception; | ||
use OCP\IL10N; | ||
use OCP\IRequest; | ||
use Psr\Log\LoggerInterface; | ||
|
||
/** | ||
* @psalm-import-type TablesContext from ResponseDefinitions | ||
*/ | ||
|
||
class ContextsController extends AOCSController { | ||
private ContextService $contextService; | ||
|
||
public function __construct( | ||
IRequest $request, | ||
LoggerInterface $logger, | ||
IL10N $n, | ||
string $userId, | ||
ContextService $contextService | ||
) { | ||
parent::__construct($request, $logger, $n, $userId); | ||
$this->contextService = $contextService; | ||
$this->userId = $userId; | ||
} | ||
|
||
/** | ||
* [api v3] Get all contexts available to the requesting person | ||
* | ||
* Return an empty array if no contexts were found | ||
* | ||
* @return DataResponse<Http::STATUS_OK, TablesContext[], array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR, array{message: string}, array{}> | ||
Check failure on line 39 in lib/Controller/ContextsController.php GitHub Actions / static-psalm-analysis dev-masterInvalidTemplateParam
Check failure on line 39 in lib/Controller/ContextsController.php GitHub Actions / static-psalm-analysis dev-masterUndefinedDocblockClass
Check failure on line 39 in lib/Controller/ContextsController.php GitHub Actions / static-psalm-analysis dev-masterInvalidTemplateParam
Check failure on line 39 in lib/Controller/ContextsController.php GitHub Actions / static-psalm-analysis dev-stable28InvalidTemplateParam
Check failure on line 39 in lib/Controller/ContextsController.php GitHub Actions / static-psalm-analysis dev-stable28UndefinedDocblockClass
Check failure on line 39 in lib/Controller/ContextsController.php GitHub Actions / static-psalm-analysis dev-stable28InvalidTemplateParam
|
||
* | ||
* 200: reporting in available contexts | ||
* | ||
* @NoAdminRequired | ||
*/ | ||
public function index(): DataResponse { | ||
try { | ||
$contexts = $this->contextService->findAll($this->userId); | ||
return new DataResponse($this->contextsToArray($contexts)); | ||
} catch (InternalError|Exception $e) { | ||
return $this->handleError($e); | ||
} | ||
} | ||
|
||
/** | ||
* @param Context[] $contexts | ||
* @return array | ||
*/ | ||
protected function contextsToArray(array $contexts): array { | ||
$result = []; | ||
foreach ($contexts as $context) { | ||
$result[] = $context->jsonSerialize(); | ||
} | ||
return $result; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<?php | ||
|
||
namespace OCA\Tables\Db; | ||
|
||
use JsonSerializable; | ||
use OCP\AppFramework\Db\Entity; | ||
|
||
/** | ||
* @method getName(): string | ||
* @method setName(string $value): void | ||
* @method getIcon(): string | ||
* @method setIcon(string $value): void | ||
* @method getDescription(): string | ||
* @method setDescription(string $value): void | ||
* @method getOwnerId(): string | ||
* @method setOwnerId(string $value): void | ||
* @method getOwnerType(): int | ||
* @method setOwnerType(int $value): void | ||
*/ | ||
class Context extends Entity implements JsonSerializable { | ||
protected ?string $name = null; | ||
protected ?string $icon = null; | ||
protected ?string $description = null; | ||
protected ?string $ownerId = null; | ||
protected ?int $ownerType = null; | ||
|
||
public function __construct() { | ||
$this->addType('id', 'integer'); | ||
} | ||
|
||
public function jsonSerialize(): array { | ||
return [ | ||
'id' => $this->getId(), | ||
'name' => $this->getName(), | ||
'iconName' => $this->getIcon(), | ||
'description' => $this->getDescription(), | ||
'owner' => $this->getOwnerId(), | ||
'ownerType' => $this->getOwnerType() | ||
]; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
<?php | ||
|
||
namespace OCA\Tables\Db; | ||
|
||
use OCA\Tables\Helper\UserHelper; | ||
use OCP\AppFramework\Db\QBMapper; | ||
use OCP\DB\Exception; | ||
use OCP\DB\QueryBuilder\IQueryBuilder; | ||
use OCP\IDBConnection; | ||
|
||
class ContextMapper extends QBMapper { | ||
Check failure on line 11 in lib/Db/ContextMapper.php GitHub Actions / static-psalm-analysis dev-masterMissingTemplateParam
Check failure on line 11 in lib/Db/ContextMapper.php GitHub Actions / static-psalm-analysis dev-stable28MissingTemplateParam
|
||
protected string $table = 'tables_contexts_context'; | ||
private UserHelper $userHelper; | ||
|
||
public function __construct(IDBConnection $db, UserHelper $userHelper) { | ||
$this->userHelper = $userHelper; | ||
parent::__construct($db, $this->table, Context::class); | ||
} | ||
|
||
/** | ||
* @return Context[] | ||
* @throws Exception | ||
*/ | ||
public function findAll(?string $userId = null): array { | ||
$qb = $this->db->getQueryBuilder(); | ||
$qb->select('c.*') | ||
->from($this->table, 'c'); | ||
if ($userId !== null) { | ||
$sharedToConditions = $qb->expr()->orX(); | ||
|
||
// shared to user clause | ||
$userShare = $qb->expr()->andX( | ||
$qb->expr()->eq('s.receiver_type', $qb->createNamedParameter('user')), | ||
$qb->expr()->eq('s.receiver', $qb->createNamedParameter($userId)), | ||
); | ||
$sharedToConditions->add($userShare); | ||
|
||
// shared to group clause | ||
$groupIDs = $this->userHelper->getGroupIdsForUser($userId); | ||
if (!empty($groupIDs)) { | ||
$groupShares = $qb->expr()->andX( | ||
$qb->expr()->eq('s.receiver_type', $qb->createNamedParameter('group')), | ||
$qb->expr()->in('s.receiver', $qb->createNamedParameter($groupIDs, IQueryBuilder::PARAM_STR_ARRAY)), | ||
); | ||
$sharedToConditions->add($groupShares); | ||
} | ||
|
||
// owned contexts + apply share conditions | ||
$qb->leftJoin('c', 'tables_shares', 's', $qb->expr()->andX( | ||
$qb->expr()->eq('c.id', 's.node_id'), | ||
$qb->expr()->eq('s.node_type', $qb->createNamedParameter('context')), | ||
$sharedToConditions, | ||
)); | ||
|
||
$qb->where($qb->expr()->orX( | ||
$qb->expr()->eq('owner_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)), | ||
$qb->expr()->isNotNull('s.receiver'), | ||
)); | ||
} | ||
|
||
return $this->findEntities($qb); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?php | ||
|
||
namespace OCA\Tables\Service; | ||
|
||
use OCA\Tables\Db\Context; | ||
use OCA\Tables\Db\ContextMapper; | ||
use OCA\Tables\Errors\InternalError; | ||
use OCP\DB\Exception; | ||
use Psr\Log\LoggerInterface; | ||
|
||
class ContextService { | ||
|
||
private ContextMapper $mapper; | ||
private bool $isCLI; | ||
private LoggerInterface $logger; | ||
|
||
public function __construct( | ||
ContextMapper $mapper, | ||
LoggerInterface $logger, | ||
bool $isCLI, | ||
) { | ||
$this->mapper = $mapper; | ||
$this->isCLI = $isCLI; | ||
$this->logger = $logger; | ||
} | ||
|
||
/** | ||
* @throws InternalError | ||
* @throws Exception | ||
* @return Context[] | ||
*/ | ||
public function findAll(?string $userId): array { | ||
if ($userId !== null && trim($userId) === '') { | ||
$userId = null; | ||
} | ||
if ($userId === null && !$this->isCLI) { | ||
$error = 'Try to set no user in context, but request is not allowed.'; | ||
$this->logger->warning($error); | ||
throw new InternalError($error); | ||
} | ||
return $this->mapper->findAll($userId); | ||
} | ||
} |