mirror of
https://github.com/verdigado/organization_folders.git
synced 2024-11-21 20:28:11 +01:00
added resource members
This commit is contained in:
parent
851fa0a1cc
commit
92c431e856
14 changed files with 311 additions and 20 deletions
|
@ -23,5 +23,7 @@
|
||||||
<command>OCA\OrganizationFolders\Command\OrganizationFolder\CreateOrganizationFolder</command>
|
<command>OCA\OrganizationFolders\Command\OrganizationFolder\CreateOrganizationFolder</command>
|
||||||
<command>OCA\OrganizationFolders\Command\Resource\CreateResource</command>
|
<command>OCA\OrganizationFolders\Command\Resource\CreateResource</command>
|
||||||
<command>OCA\OrganizationFolders\Command\Resource\ListResources</command>
|
<command>OCA\OrganizationFolders\Command\Resource\ListResources</command>
|
||||||
|
<command>OCA\OrganizationFolders\Command\ResourceMember\CreateResourceMember</command>
|
||||||
|
<command>OCA\OrganizationFolders\Command\ResourceMember\ListResourceMembers</command>
|
||||||
</commands>
|
</commands>
|
||||||
</info>
|
</info>
|
|
@ -8,6 +8,7 @@ use OCP\IDateTimeFormatter;
|
||||||
use OCA\OrganizationFolders\Model\OrganizationFolder;
|
use OCA\OrganizationFolders\Model\OrganizationFolder;
|
||||||
use OCA\OrganizationFolders\Service\OrganizationFolderService;
|
use OCA\OrganizationFolders\Service\OrganizationFolderService;
|
||||||
use OCA\OrganizationFolders\Service\ResourceService;
|
use OCA\OrganizationFolders\Service\ResourceService;
|
||||||
|
use OCA\OrganizationFolders\Service\ResourceMemberService;
|
||||||
use OCA\OrganizationFolders\Interface\TableSerializable;
|
use OCA\OrganizationFolders\Interface\TableSerializable;
|
||||||
|
|
||||||
abstract class BaseCommand extends Base {
|
abstract class BaseCommand extends Base {
|
||||||
|
@ -16,19 +17,20 @@ abstract class BaseCommand extends Base {
|
||||||
private readonly IDateTimeFormatter $dateTimeFormatter,
|
private readonly IDateTimeFormatter $dateTimeFormatter,
|
||||||
protected readonly OrganizationFolderService $organizationFolderService,
|
protected readonly OrganizationFolderService $organizationFolderService,
|
||||||
protected ResourceService $resourceService,
|
protected ResourceService $resourceService,
|
||||||
|
protected ResourceMemberService $resourceMemberService,
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function formatTableSerializable(TableSerializable $serializable): array {
|
protected function formatTableSerializable(TableSerializable $serializable, ?array $params = null): array {
|
||||||
return $serializable->tableSerialize();
|
return $serializable->tableSerialize($params);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function formatOrganizationFolders(array $organizationFolders) {
|
protected function formatTableSerializables(array $serializables, ?array $params = null): array {
|
||||||
return array_map($this->formatTableSerializable(...), $organizationFolders);
|
$result = [];
|
||||||
}
|
foreach($serializables as $serializable) {
|
||||||
|
$result[] = $serializable->tableSerialize($params);
|
||||||
protected function formatResources(array $resources): array {
|
}
|
||||||
return array_map($this->formatTableSerializable(...), $resources);
|
return $result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ class ListOrganizationFolders extends BaseCommand {
|
||||||
try {
|
try {
|
||||||
$organizationFolderGroupfolders = $this->organizationFolderService->getAll();
|
$organizationFolderGroupfolders = $this->organizationFolderService->getAll();
|
||||||
|
|
||||||
$this->writeTableInOutputFormat($input, $output, $this->formatOrganizationFolders($organizationFolderGroupfolders));
|
$this->writeTableInOutputFormat($input, $output, $this->formatTableSerializables($organizationFolderGroupfolders));
|
||||||
return 0;
|
return 0;
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$output->writeln("<error>Exception \"{$e->getMessage()}\" at {$e->getFile()} line {$e->getLine()}</error>");
|
$output->writeln("<error>Exception \"{$e->getMessage()}\" at {$e->getFile()} line {$e->getLine()}</error>");
|
||||||
|
|
|
@ -27,7 +27,7 @@ class ListResources extends BaseCommand {
|
||||||
|
|
||||||
$resources = $this->resourceService->findAll($organizationFolderId, $parentResourceId);
|
$resources = $this->resourceService->findAll($organizationFolderId, $parentResourceId);
|
||||||
|
|
||||||
$this->writeTableInOutputFormat($input, $output, $this->formatResources($resources));
|
$this->writeTableInOutputFormat($input, $output, $this->formatTableSerializables($resources));
|
||||||
return 0;
|
return 0;
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$output->writeln("<error>Exception \"{$e->getMessage()}\" at {$e->getFile()} line {$e->getLine()}</error>");
|
$output->writeln("<error>Exception \"{$e->getMessage()}\" at {$e->getFile()} line {$e->getLine()}</error>");
|
||||||
|
|
48
lib/Command/ResourceMember/CreateResourceMember.php
Normal file
48
lib/Command/ResourceMember/CreateResourceMember.php
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OCA\OrganizationFolders\Command\ResourceMember;
|
||||||
|
|
||||||
|
use OCP\DB\Exception;
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
use OCA\OrganizationFolders\Command\BaseCommand;
|
||||||
|
use OCA\OrganizationFolders\Enum\MemberType;
|
||||||
|
use OCA\OrganizationFolders\Enum\MemberPermissionLevel;
|
||||||
|
|
||||||
|
class CreateResourceMember extends BaseCommand {
|
||||||
|
protected function configure(): void {
|
||||||
|
$this
|
||||||
|
->setName('organization-folders:create-resource-member')
|
||||||
|
->setDescription('Create a new member of resource')
|
||||||
|
->addOption('resource-id', null, InputOption::VALUE_REQUIRED, 'Id of resource to create member of')
|
||||||
|
->addOption('permission-level', null, InputOption::VALUE_REQUIRED, 'Permissions level of member (valid values: MEMBER, MANAGER)')
|
||||||
|
->addOption('type', null, InputOption::VALUE_REQUIRED, 'Type of principal (valid values: USER, GROUP, ROLE)')
|
||||||
|
->addOption('principal', null, InputOption::VALUE_OPTIONAL, 'For type user: "[user_id]", for group: "[group_name]", for role: "[organization_provider_id]:[role_id]"');
|
||||||
|
|
||||||
|
parent::configure();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output): int {
|
||||||
|
$resourceId = $input->getOption('resource-id');
|
||||||
|
$permissionLevel = MemberPermissionLevel::fromNameOrValue($input->getOption('permission-level'));
|
||||||
|
$type = MemberType::fromNameOrValue($input->getOption('type'));
|
||||||
|
$principal = $input->getOption('principal');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$resource = $this->resourceMemberService->create(
|
||||||
|
resourceId: $resourceId,
|
||||||
|
permissionLevel: $permissionLevel,
|
||||||
|
type: $type,
|
||||||
|
principal: $principal,
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->writeTableInOutputFormat($input, $output, [$this->formatTableSerializable($resource)]);
|
||||||
|
return 0;
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$output->writeln("<error>Exception \"{$e->getMessage()}\" at {$e->getFile()} line {$e->getLine()}</error>");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
lib/Command/ResourceMember/ListResourceMembers.php
Normal file
35
lib/Command/ResourceMember/ListResourceMembers.php
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OCA\OrganizationFolders\Command\ResourceMember;
|
||||||
|
|
||||||
|
use OCP\DB\Exception;
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
use OCA\OrganizationFolders\Command\BaseCommand;
|
||||||
|
|
||||||
|
class ListResourceMembers extends BaseCommand {
|
||||||
|
protected function configure(): void {
|
||||||
|
$this
|
||||||
|
->setName('organization-folders:list-resource-members')
|
||||||
|
->addArgument('resource-id', InputArgument::REQUIRED, 'Id of Resource')
|
||||||
|
->setDescription('List all members of resource.');
|
||||||
|
|
||||||
|
parent::configure();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output): int {
|
||||||
|
try {
|
||||||
|
$resourceId = $input->getArgument('resource-id');
|
||||||
|
|
||||||
|
$members = $this->resourceMemberService->findAll($resourceId);
|
||||||
|
|
||||||
|
$this->writeTableInOutputFormat($input, $output, $this->formatTableSerializables($members));
|
||||||
|
return 0;
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$output->writeln("<error>Exception \"{$e->getMessage()}\" at {$e->getFile()} line {$e->getLine()}</error>");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -48,7 +48,7 @@ class FolderResource extends Resource {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tableSerialize(): array {
|
public function tableSerialize(?array $params = null): array {
|
||||||
return [
|
return [
|
||||||
'Id' => $this->id,
|
'Id' => $this->id,
|
||||||
'Name' => $this->name,
|
'Name' => $this->name,
|
||||||
|
|
50
lib/Db/ResourceMember.php
Normal file
50
lib/Db/ResourceMember.php
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OCA\OrganizationFolders\Db;
|
||||||
|
|
||||||
|
use JsonSerializable;
|
||||||
|
use OCA\OrganizationFolders\Interface\TableSerializable;
|
||||||
|
|
||||||
|
use OCP\AppFramework\Db\Entity;
|
||||||
|
|
||||||
|
use OCA\OrganizationFolders\Enum\MemberPermissionLevel;
|
||||||
|
use OCA\OrganizationFolders\Enum\MemberType;
|
||||||
|
|
||||||
|
class ResourceMember extends Entity implements JsonSerializable, TableSerializable {
|
||||||
|
protected $resourceId;
|
||||||
|
protected $permissionLevel;
|
||||||
|
protected $type;
|
||||||
|
protected $principal;
|
||||||
|
protected $createdTimestamp;
|
||||||
|
protected $lastUpdatedTimestamp;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->addType('resourceId','integer');
|
||||||
|
$this->addType('permissionLevel','integer');
|
||||||
|
$this->addType('type','integer');
|
||||||
|
$this->addType('createdTimestamp','integer');
|
||||||
|
$this->addType('lastUpdatedTimestamp','integer');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function jsonSerialize(): array {
|
||||||
|
return [
|
||||||
|
'resourceId' => $this->resourceId,
|
||||||
|
'permissionLevel' => $this->permissionLevel,
|
||||||
|
'type' => $this->type,
|
||||||
|
'principal' => $this->principal,
|
||||||
|
'createdTimestamp' => $this->createdTimestamp,
|
||||||
|
'lastUpdatedTimestamp' => $this->lastUpdatedTimestamp,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function tableSerialize(?array $params = null): array {
|
||||||
|
return [
|
||||||
|
'Resource Id' => $this->resourceId,
|
||||||
|
'Permission Level' => MemberPermissionLevel::from($this->permissionLevel)->name,
|
||||||
|
'Type' => MemberType::from($this->type)->name,
|
||||||
|
'Principal' => $this->principal,
|
||||||
|
'Created' => $this->createdTimestamp,
|
||||||
|
'LastUpdated' => $this->lastUpdatedTimestamp,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
49
lib/Db/ResourceMemberMapper.php
Normal file
49
lib/Db/ResourceMemberMapper.php
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OCA\OrganizationFolders\Db;
|
||||||
|
|
||||||
|
use OCP\AppFramework\Db\DoesNotExistException;
|
||||||
|
use OCP\AppFramework\Db\Entity;
|
||||||
|
use OCP\AppFramework\Db\QBMapper;
|
||||||
|
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||||
|
use OCP\IDBConnection;
|
||||||
|
|
||||||
|
class ResourceMemberMapper extends QBMapper {
|
||||||
|
public const RESOURCE_MEMBERS_TABLE = "organizationfolders_resource_members";
|
||||||
|
|
||||||
|
public function __construct(IDBConnection $db) {
|
||||||
|
parent::__construct($db, self::RESOURCE_MEMBERS_TABLE, ResourceMember::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $id
|
||||||
|
* @return Entity|ResourceMember
|
||||||
|
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
|
||||||
|
* @throws DoesNotExistException
|
||||||
|
*/
|
||||||
|
public function find(int $id): ResourceMember {
|
||||||
|
/* @var $qb IQueryBuilder */
|
||||||
|
$qb = $this->db->getQueryBuilder();
|
||||||
|
|
||||||
|
$qb->select('*')
|
||||||
|
->from(self::RESOURCE_MEMBERS_TABLE)
|
||||||
|
->where($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
|
||||||
|
|
||||||
|
return $this->findEntity($qb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $resourceId
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function findAll(int $resourceId): array {
|
||||||
|
/* @var $qb IQueryBuilder */
|
||||||
|
$qb = $this->db->getQueryBuilder();
|
||||||
|
|
||||||
|
$qb->select('*')
|
||||||
|
->from(self::RESOURCE_MEMBERS_TABLE)
|
||||||
|
->where($qb->expr()->eq('resource_id', $qb->createNamedParameter($resourceId, IQueryBuilder::PARAM_INT)));
|
||||||
|
|
||||||
|
return $this->findEntities($qb);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,12 +3,20 @@
|
||||||
namespace OCA\OrganizationFolders\Enum;
|
namespace OCA\OrganizationFolders\Enum;
|
||||||
|
|
||||||
trait FromNameEnum {
|
trait FromNameEnum {
|
||||||
public static function fromName(string $name): string {
|
public static function fromName(string $name) {
|
||||||
foreach (self::cases() as $status) {
|
foreach(self::cases() as $status) {
|
||||||
if( $name === $status->name ){
|
if($name === $status->name){
|
||||||
return $status->value;
|
return $status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new \ValueError("$name is not a valid value for enum " . self::class );
|
throw new \ValueError("$name is not a valid value for enum " . self::class );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function fromNameOrValue(int|string $scalar) {
|
||||||
|
if(gettype($scalar) == "integer") {
|
||||||
|
return self::tryFrom($scalar);
|
||||||
|
} else {
|
||||||
|
return self::fromName($scalar);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -7,5 +7,5 @@ interface TableSerializable {
|
||||||
* Serializes the object to a dict array to be rendered into a occ command output table
|
* Serializes the object to a dict array to be rendered into a occ command output table
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
function tableSerialize();
|
function tableSerialize(?array $params = null);
|
||||||
}
|
}
|
|
@ -33,7 +33,7 @@ class OrganizationFolder implements JsonSerializable, TableSerializable {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tableSerialize(): array {
|
public function tableSerialize(?array $params = null): array {
|
||||||
return [
|
return [
|
||||||
'Id' => $this->id,
|
'Id' => $this->id,
|
||||||
'Name' => $this->name,
|
'Name' => $this->name,
|
||||||
|
|
97
lib/Service/ResourceMemberService.php
Normal file
97
lib/Service/ResourceMemberService.php
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OCA\OrganizationFolders\Service;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
use OCP\AppFramework\Db\DoesNotExistException;
|
||||||
|
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
|
||||||
|
|
||||||
|
use OCA\OrganizationFolders\Errors\ResourceMemberNotFound;
|
||||||
|
|
||||||
|
use OCA\OrganizationFolders\Db\ResourceMember;
|
||||||
|
use OCA\OrganizationFolders\Db\ResourceMemberMapper;
|
||||||
|
|
||||||
|
use OCA\OrganizationFolders\Enum\MemberPermissionLevel;
|
||||||
|
use OCA\OrganizationFolders\Enum\MemberType;
|
||||||
|
|
||||||
|
class ResourceMemberService {
|
||||||
|
public function __construct(
|
||||||
|
private ResourceMemberMapper $mapper
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findAll(int $resourceId): array {
|
||||||
|
return $this->mapper->findAll($resourceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function handleException(Exception $e): void {
|
||||||
|
if ($e instanceof DoesNotExistException ||
|
||||||
|
$e instanceof MultipleObjectsReturnedException) {
|
||||||
|
throw new ResourceMemberNotFound($e->getMessage());
|
||||||
|
} else {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function find(int $id): ResourceMember {
|
||||||
|
try {
|
||||||
|
return $this->mapper->find($id);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->handleException($e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create(
|
||||||
|
int $resourceId,
|
||||||
|
MemberPermissionLevel $permissionLevel,
|
||||||
|
MemberType $type,
|
||||||
|
string $principal
|
||||||
|
): ResourceMember {
|
||||||
|
$member = new ResourceMember();
|
||||||
|
$member->setResourceId($resourceId);
|
||||||
|
$member->setPermissionLevel($permissionLevel->value);
|
||||||
|
$member->setType($type->value);
|
||||||
|
$member->setPrincipal($principal);
|
||||||
|
$member->setCreatedTimestamp(time());
|
||||||
|
$member->setLastUpdatedTimestamp(time());
|
||||||
|
|
||||||
|
return $this->mapper->insert($member);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(int $id, ?MemberPermissionLevel $permissionLevel = null, ?MemberType $type = null, ?string $principal = null): ResourceMember {
|
||||||
|
try {
|
||||||
|
$member = $this->mapper->find($id);
|
||||||
|
|
||||||
|
if(isset($permissionLevel)) {
|
||||||
|
$member->setPermissionLevel($permissionLevel->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($type)) {
|
||||||
|
$member->setType($type->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($principal)) {
|
||||||
|
$member->setPrincipal($principal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(count($member->getUpdatedFields()) > 0) {
|
||||||
|
$member->setLastUpdatedTimestamp(time());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->mapper->update($member);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->handleException($e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete(int $id): ResourceMember {
|
||||||
|
try {
|
||||||
|
$member = $this->mapper->find($id);
|
||||||
|
$this->mapper->delete($member);
|
||||||
|
return $member;
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->handleException($e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,8 +20,8 @@ class ResourceService {
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function findAll(int $groupfolderId, int $parentResourceId = null) {
|
public function findAll(int $organizationFolderId, int $parentResourceId = null) {
|
||||||
return $this->mapper->findAll($groupfolderId, $parentResourceId);
|
return $this->mapper->findAll($organizationFolderId, $parentResourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function handleException(Exception $e, int $id): void {
|
private function handleException(Exception $e, int $id): void {
|
||||||
|
@ -60,7 +60,7 @@ class ResourceService {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$this->mapper->existsWithName($organizationFolderId, $parentResource, $name)) {
|
if(!$this->mapper->existsWithName($organizationFolderId, $parentResource, $name)) {
|
||||||
$resource->setGroupFolderId($organizationFolderId);
|
$resource->setOrganizationFolderId($organizationFolderId);
|
||||||
$resource->setName($name);
|
$resource->setName($name);
|
||||||
$resource->setParentResource($parentResource);
|
$resource->setParentResource($parentResource);
|
||||||
$resource->setActive($active);
|
$resource->setActive($active);
|
||||||
|
|
Loading…
Reference in a new issue