0
0
Fork 0
mirror of https://github.com/verdigado/organization_folders.git synced 2024-11-21 20:28:11 +01:00

added user-has-manager-permissions dav prop; added principal model and simplified the ACL code with it

This commit is contained in:
Jonathan Treffler 2024-11-12 15:36:07 +01:00
parent 72fbc9e20e
commit 8bfa9dfa29
11 changed files with 172 additions and 114 deletions

View file

@ -14,14 +14,17 @@ use OCA\GroupFolders\Folder\FolderManager;
use OCA\GroupFolders\Mount\GroupMountPoint; use OCA\GroupFolders\Mount\GroupMountPoint;
use OCA\OrganizationFolders\Service\ResourceService; use OCA\OrganizationFolders\Service\ResourceService;
use OCA\OrganizationFolders\Security\AuthorizationService;
class PropFindPlugin extends ServerPlugin { class PropFindPlugin extends ServerPlugin {
public const ORGANIZATION_FOLDER_ID_PROPERTYNAME = '{http://verdigado.com/ns}organization-folder-id'; public const ORGANIZATION_FOLDER_ID_PROPERTYNAME = '{http://verdigado.com/ns}organization-folder-id';
public const ORGANIZATION_FOLDER_RESOURCE_ID_PROPERTYNAME = '{http://verdigado.com/ns}organization-folder-resource-id'; public const ORGANIZATION_FOLDER_RESOURCE_ID_PROPERTYNAME = '{http://verdigado.com/ns}organization-folder-resource-id';
public const ORGANIZATION_FOLDER_RESOURCE_MANAGER_PERMISSIONS_PROPERTYNAME = '{http://verdigado.com/ns}organization-folder-resource-user-has-manager-permissions';
public function __construct( public function __construct(
private FolderManager $folderManager, private FolderManager $folderManager,
private ResourceService $resourceService, private ResourceService $resourceService,
private AuthorizationService $authorizationService,
) { ) {
} }
@ -41,6 +44,7 @@ class PropFindPlugin extends ServerPlugin {
return; return;
} }
$propFind->handle(self::ORGANIZATION_FOLDER_ID_PROPERTYNAME, function () use ($fileInfo): int { $propFind->handle(self::ORGANIZATION_FOLDER_ID_PROPERTYNAME, function () use ($fileInfo): int {
return $this->folderManager->getFolderByPath($fileInfo->getPath()); return $this->folderManager->getFolderByPath($fileInfo->getPath());
}); });
@ -52,5 +56,14 @@ class PropFindPlugin extends ServerPlugin {
return null; return null;
} }
}); });
$propFind->handle(self::ORGANIZATION_FOLDER_RESOURCE_MANAGER_PERMISSIONS_PROPERTYNAME, function () use ($node) {
try {
$resource = $this->resourceService->findByFileId($node->getId());
return $this->authorizationService->isGranted(["READ"], $resource) ? 'true' : 'false';
} catch (\Exception $e) {
return null;
}
});
} }
} }

View file

@ -67,8 +67,13 @@ class ResourceMapper extends QBMapper {
/** /**
* @param int $organizationFolderId * @param int $organizationFolderId
* @param int $parentResourceId * @psalm-param int $organizationFolderId
* @param int|null $parentResourceId
* @psalm-param int|null $parentResourceId
* @param array $filters
* @psalm-param array $filters
* @return array * @return array
* @psalm-return Resource[]
*/ */
public function findAll(int $organizationFolderId, ?int $parentResourceId = null, array $filters = []): array { public function findAll(int $organizationFolderId, ?int $parentResourceId = null, array $filters = []): array {
/* @var $qb IQueryBuilder */ /* @var $qb IQueryBuilder */

View file

@ -8,31 +8,39 @@ use OCA\OrganizationFolders\Interface\TableSerializable;
use OCP\AppFramework\Db\Entity; use OCP\AppFramework\Db\Entity;
use OCA\OrganizationFolders\Enum\MemberPermissionLevel; use OCA\OrganizationFolders\Enum\MemberPermissionLevel;
use OCA\OrganizationFolders\Enum\MemberType; use OCA\OrganizationFolders\Enum\PrincipalType;
use OCA\OrganizationFolders\Model\Principal;
class ResourceMember extends Entity implements JsonSerializable, TableSerializable { class ResourceMember extends Entity implements JsonSerializable, TableSerializable {
protected $resourceId; protected $resourceId;
protected $permissionLevel; protected $permissionLevel;
protected $type; protected $principalType;
protected $principal; protected $principalId;
protected $createdTimestamp; protected $createdTimestamp;
protected $lastUpdatedTimestamp; protected $lastUpdatedTimestamp;
public function __construct() { public function __construct() {
$this->addType('resourceId','integer'); $this->addType('resourceId','integer');
$this->addType('permissionLevel','integer'); $this->addType('permissionLevel','integer');
$this->addType('type','integer'); $this->addType('principalType','integer');
$this->addType('createdTimestamp','integer'); $this->addType('createdTimestamp','integer');
$this->addType('lastUpdatedTimestamp','integer'); $this->addType('lastUpdatedTimestamp','integer');
} }
public function getPrincipal(): Principal {
return new Principal(PrincipalType::from($this->principalType), $this->principalId);
}
public function setPrincipal(Principal $principal) {
$this->setPrincipalType($principal->getType()->value);
$this->setPrincipalId($principal->getId());
}
public function jsonSerialize(): array { public function jsonSerialize(): array {
return [ return [
'id' => $this->id, 'id' => $this->id,
'resourceId' => $this->resourceId, 'resourceId' => $this->resourceId,
'permissionLevel' => $this->permissionLevel, 'permissionLevel' => $this->permissionLevel,
'type' => $this->type, 'principal' => $this->getPrincipal(),
'principal' => $this->principal,
'createdTimestamp' => $this->createdTimestamp, 'createdTimestamp' => $this->createdTimestamp,
'lastUpdatedTimestamp' => $this->lastUpdatedTimestamp, 'lastUpdatedTimestamp' => $this->lastUpdatedTimestamp,
]; ];
@ -43,29 +51,10 @@ class ResourceMember extends Entity implements JsonSerializable, TableSerializab
'Id' => $this->id, 'Id' => $this->id,
'Resource Id' => $this->resourceId, 'Resource Id' => $this->resourceId,
'Permission Level' => MemberPermissionLevel::from($this->permissionLevel)->name, 'Permission Level' => MemberPermissionLevel::from($this->permissionLevel)->name,
'Type' => MemberType::from($this->type)->name, 'Principal Type' => PrincipalType::from($this->principalType)->name,
'Principal' => $this->principal, 'Principal Id' => $this->principalId,
'Created' => $this->createdTimestamp, 'Created' => $this->createdTimestamp,
'LastUpdated' => $this->lastUpdatedTimestamp, 'LastUpdated' => $this->lastUpdatedTimestamp,
]; ];
} }
public function getParsedPrincipal() {
if($this->type === MemberType::USER->value) {
return [
"userId" => $this->principal,
];
} else if($this->type === MemberType::GROUP->value) {
return [
"groupId" => $this->principal,
];
} else if($this->type === MemberType::ROLE->value) {
[$organizationProviderId, $roleId] = explode(":", $this->principal, 2);
return [
"organizationProviderId" => $organizationProviderId,
"roleId" => $roleId,
];
}
}
} }

View file

@ -34,7 +34,9 @@ class ResourceMemberMapper extends QBMapper {
/** /**
* @param int $resourceId * @param int $resourceId
* @psalm-param int $resourceId
* @return array * @return array
* @psalm-return ResourceMember[]
*/ */
public function findAll(int $resourceId): array { public function findAll(int $resourceId): array {
/* @var $qb IQueryBuilder */ /* @var $qb IQueryBuilder */

View file

@ -2,7 +2,7 @@
namespace OCA\OrganizationFolders\Enum; namespace OCA\OrganizationFolders\Enum;
enum MemberType: int { enum PrincipalType: int {
use FromNameEnum; use FromNameEnum;
case USER = 1; case USER = 1;

View file

@ -8,16 +8,22 @@ use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection; use OCP\IDBConnection;
use OCA\GroupFolders\ACL\Rule; use OCA\GroupFolders\ACL\Rule;
use OCA\GroupFolders\ACL\UserMapping\IUserMapping;
use OCA\GroupFolders\ACL\UserMapping\IUserMappingManager; use OCA\GroupFolders\ACL\UserMapping\IUserMappingManager;
use OCA\GroupFolders\ACL\RuleManager; use OCA\GroupFolders\ACL\RuleManager;
use OCA\GroupFolders\Folder\FolderManager; use OCA\GroupFolders\Folder\FolderManager;
use OCA\OrganizationFolders\OrganizationProvider\OrganizationProviderManager;
use OCA\OrganizationFolders\Model\Principal;
use OCA\OrganizationFolders\Enum\PrincipalType;
class ACLManager { class ACLManager {
public function __construct( public function __construct(
protected IDBConnection $db, protected IDBConnection $db,
protected FolderManager $folderManager, protected FolderManager $folderManager,
protected IUserMappingManager $userMappingManager, protected IUserMappingManager $userMappingManager,
protected RuleManager $ruleManager, protected RuleManager $ruleManager,
protected OrganizationProviderManager $organizationProviderManager
) { ) {
} }
@ -48,6 +54,38 @@ class ACLManager {
return array_map($this->createRuleEntityFromRow(...), $rows); return array_map($this->createRuleEntityFromRow(...), $rows);
} }
public function getMappingForPrincipal(Principal $principal): IUserMapping {
if($principal->getType() === PrincipalType::USER) {
return $this->userMappingManager->mappingFromId("user", $principal->getId());
} else if($principal->getType() === PrincipalType::GROUP) {
return $this->userMappingManager->mappingFromId("group", $principal->getId());
} else if($principal->getType() === PrincipalType::ROLE) {
[$organizationProviderId, $roleId] = explode(":", $principal->getId(), 2);
$organizationProvider = $this->organizationProviderManager->getOrganizationProvider($organizationProviderId);
$role = $organizationProvider->getRole($roleId);
return $this->userMappingManager->mappingFromId("group", $role->getMembersGroup());
} else {
throw new \Exception("invalid resource member type");
}
}
public function createAclRuleForPrincipal(Principal $principal, int $fileId, int $mask, int $permissions): ?Rule {
$mapping = $this->getMappingForPrincipal($principal);
if(is_null($mapping)) {
return null;
}
return new Rule(
userMapping: $mapping,
fileId: $fileId,
mask: $mask,
permissions: $permissions,
);
}
protected function ruleMappingComparison(Rule $rule1, Rule $rule2): int { protected function ruleMappingComparison(Rule $rule1, Rule $rule2): int {
$mapping1 = $rule1->getUserMapping(); $mapping1 = $rule1->getUserMapping();
$mapping2 = $rule2->getUserMapping(); $mapping2 = $rule2->getUserMapping();

View file

@ -42,13 +42,13 @@ class Version000000Date20241025120000 extends SimpleMigrationStep {
// 0: user // 0: user
// 1: group // 1: group
// 2: role // 2: role
$table->addColumn('type', Types::INTEGER, [ $table->addColumn('principal_type', Types::INTEGER, [
'notnull' => true, 'notnull' => true,
]); ]);
// for type user: "[user_id]" // for principal type user: "[user_id]"
// for type group: "[group_name]" // for principal type group: "[group_name]"
// for type role: "[organization_provider_id]:[role_id]" // for principal type role: "[organization_provider_id]:[role_id]"
$table->addColumn('principal', Types::STRING, [ $table->addColumn('principal_id', Types::STRING, [
'length' => 128, 'length' => 128,
'notnull' => true, 'notnull' => true,
]); ]);

29
lib/Model/Principal.php Normal file
View file

@ -0,0 +1,29 @@
<?php
namespace OCA\OrganizationFolders\Model;
use OCA\OrganizationFolders\Enum\PrincipalType;
class Principal implements \JsonSerializable {
public function __construct(
private PrincipalType $type,
private string $id,
) {
// check if id fits format
}
public function getType(): PrincipalType {
return $this->type;
}
public function getId(): string {
return $this->id;
}
public function jsonSerialize(): array {
return [
'type' => $this->type->value,
'id' => $this->id,
];
}
}

View file

@ -9,7 +9,7 @@ use OCA\OrganizationFolders\Db\Resource;
use OCA\OrganizationFolders\Service\ResourceService; use OCA\OrganizationFolders\Service\ResourceService;
use OCA\OrganizationFolders\Service\ResourceMemberService; use OCA\OrganizationFolders\Service\ResourceMemberService;
use OCA\OrganizationFolders\Enum\MemberPermissionLevel; use OCA\OrganizationFolders\Enum\MemberPermissionLevel;
use OCA\OrganizationFolders\Enum\MemberType; use OCA\OrganizationFolders\Enum\PrincipalType;
use OCA\OrganizationFolders\OrganizationProvider\OrganizationProviderManager; use OCA\OrganizationFolders\OrganizationProvider\OrganizationProviderManager;
class ResourceVoter extends Voter { class ResourceVoter extends Voter {
@ -38,6 +38,7 @@ class ResourceVoter extends Voter {
'READ' => $this->isGranted($user, $resource), 'READ' => $this->isGranted($user, $resource),
'UPDATE' => $this->isGranted($user, $resource), 'UPDATE' => $this->isGranted($user, $resource),
'DELETE' => $this->isGranted($user, $resource), 'DELETE' => $this->isGranted($user, $resource),
'UPDATE_MEMBERS' => $this->isGranted($user, $resource),
default => throw new \LogicException('This code should not be reached!') default => throw new \LogicException('This code should not be reached!')
}; };
} }
@ -59,19 +60,22 @@ class ResourceVoter extends Voter {
foreach($resourceMembers as $resourceMember) { foreach($resourceMembers as $resourceMember) {
if($resourceMember->getPermissionLevel() === MemberPermissionLevel::MANAGER->value) { if($resourceMember->getPermissionLevel() === MemberPermissionLevel::MANAGER->value) {
if($resourceMember->getType() === MemberType::USER->value) { $principal = $resourceMember->getPrincipal();
if($resourceMember->getPrincipal() === $user->getUID()) {
if($principal->getType() === PrincipalType::USER) {
if($principal->getId() === $user->getUID()) {
return true; return true;
} }
} else if($resourceMember->getType() === MemberType::GROUP->value) { } else if($principal->getType() === PrincipalType::GROUP) {
if($this->groupManager->isInGroup($user->getUID(), $resourceMember->getPrincipal())) { if($this->groupManager->isInGroup($user->getUID(), $principal->getId())) {
return true; return true;
} }
} else if($resourceMember->getType() === MemberType::ROLE->value) { } else if($principal->getType() === PrincipalType::ROLE) {
['organizationProviderId' => $organizationProviderId, 'roleId' => $roleId] = $resourceMember->getParsedPrincipal(); [$organizationProviderId, $roleId] = explode(":", $principal->getId(), 2);
$organizationProvider = $this->organizationProviderManager->getOrganizationProvider($organizationProviderId); $organizationProvider = $this->organizationProviderManager->getOrganizationProvider($organizationProviderId);
$role = $organizationProvider->getRole($roleId); $role = $organizationProvider->getRole($roleId);
if($this->groupManager->isInGroup($user->getUID(), $role->getMembersGroup())) { if($this->groupManager->isInGroup($user->getUID(), $role->getMembersGroup())) {
return true; return true;
} }

View file

@ -13,7 +13,7 @@ use OCA\OrganizationFolders\Db\ResourceMember;
use OCA\OrganizationFolders\Db\ResourceMemberMapper; use OCA\OrganizationFolders\Db\ResourceMemberMapper;
use OCA\OrganizationFolders\Enum\MemberPermissionLevel; use OCA\OrganizationFolders\Enum\MemberPermissionLevel;
use OCA\OrganizationFolders\Enum\MemberType; use OCA\OrganizationFolders\Model\Principal;
class ResourceMemberService { class ResourceMemberService {
public function __construct( public function __construct(
@ -23,6 +23,12 @@ class ResourceMemberService {
) { ) {
} }
/**
* @param int $resourceId
* @psalm-param int $resourceId
* @return array
* @psalm-return ResourceMember[]
*/
public function findAll(int $resourceId): array { public function findAll(int $resourceId): array {
return $this->mapper->findAll($resourceId); return $this->mapper->findAll($resourceId);
} }
@ -47,8 +53,7 @@ class ResourceMemberService {
public function create( public function create(
int $resourceId, int $resourceId,
MemberPermissionLevel $permissionLevel, MemberPermissionLevel $permissionLevel,
MemberType $type, Principal $principal,
string $principal
): ResourceMember { ): ResourceMember {
$resource = $this->resourceService->find($resourceId); $resource = $this->resourceService->find($resourceId);
@ -56,10 +61,7 @@ class ResourceMemberService {
$member->setResourceId($resource->getId()); $member->setResourceId($resource->getId());
$member->setPermissionLevel($permissionLevel->value); $member->setPermissionLevel($permissionLevel->value);
$member->setType($type->value); $member->setPrincipal($principal);
// TODO: check if principal fits format
$member->setPrincipal($principal);
$member->setCreatedTimestamp(time()); $member->setCreatedTimestamp(time());
$member->setLastUpdatedTimestamp(time()); $member->setLastUpdatedTimestamp(time());
@ -70,7 +72,7 @@ class ResourceMemberService {
return $member; return $member;
} }
public function update(int $id, ?MemberPermissionLevel $permissionLevel = null, ?MemberType $type = null, ?string $principal = null): ResourceMember { public function update(int $id, ?MemberPermissionLevel $permissionLevel = null, ?Principal $principal = null): ResourceMember {
try { try {
$member = $this->mapper->find($id); $member = $this->mapper->find($id);
@ -78,12 +80,8 @@ class ResourceMemberService {
$member->setPermissionLevel($permissionLevel->value); $member->setPermissionLevel($permissionLevel->value);
} }
if(isset($type)) {
$member->setType($type->value);
}
if(isset($principal)) { if(isset($principal)) {
$member->setPrincipal($principal); $member->setPrincipal($principal);
} }
if(count($member->getUpdatedFields()) > 0) { if(count($member->getUpdatedFields()) > 0) {

View file

@ -16,8 +16,9 @@ use OCA\OrganizationFolders\Db\Resource;
use OCA\OrganizationFolders\Db\FolderResource; use OCA\OrganizationFolders\Db\FolderResource;
use OCA\OrganizationFolders\Db\ResourceMapper; use OCA\OrganizationFolders\Db\ResourceMapper;
use OCA\OrganizationFolders\Model\OrganizationFolder; use OCA\OrganizationFolders\Model\OrganizationFolder;
use \OCA\OrganizationFolders\Model\Principal;
use OCA\OrganizationFolders\Enum\MemberPermissionLevel; use OCA\OrganizationFolders\Enum\MemberPermissionLevel;
use OCA\OrganizationFolders\Enum\MemberType; use OCA\OrganizationFolders\Enum\PrincipalType;
use OCA\OrganizationFolders\Errors\InvalidResourceType; use OCA\OrganizationFolders\Errors\InvalidResourceType;
use OCA\OrganizationFolders\Errors\ResourceNotFound; use OCA\OrganizationFolders\Errors\ResourceNotFound;
use OCA\OrganizationFolders\Errors\ResourceNameNotUnique; use OCA\OrganizationFolders\Errors\ResourceNameNotUnique;
@ -37,7 +38,16 @@ class ResourceService {
) { ) {
} }
public function findAll(int $organizationFolderId, int $parentResourceId = null, array $filters = []) { /**
* @param int $organizationFolderId
* @psalm-param int $organizationFolderId
* @param int|null $parentResourceId
* @psalm-param int|null $parentResourceId
* @param array $filters
* @psalm-param array $filters
* @psalm-return Resource[]
*/
public function findAll(int $organizationFolderId, ?int $parentResourceId = null, array $filters = []): array {
return $this->mapper->findAll($organizationFolderId, $parentResourceId, $filters); return $this->mapper->findAll($organizationFolderId, $parentResourceId, $filters);
} }
@ -93,7 +103,11 @@ class ResourceService {
$parentResource = $this->find($parentResourceId); $parentResource = $this->find($parentResourceId);
if($parentResource->getOrganizationFolderId() === $organizationFolderId) { if($parentResource->getOrganizationFolderId() === $organizationFolderId) {
$resource->setParentResource($parentResource->getId()); if($parentResource->getType() !== "folder") {
throw new Exception("Only folder resources can have sub-resources");
} else {
$resource->setParentResource($parentResource->getId());
}
} else { } else {
throw new Exception("Cannot create child-resource of parent in different organizationId"); throw new Exception("Cannot create child-resource of parent in different organizationId");
} }
@ -136,7 +150,6 @@ class ResourceService {
int $id, int $id,
?string $name = null, ?string $name = null,
?int $parentResource = null,
?bool $active = null, ?bool $active = null,
?bool $inheritManagers = null, ?bool $inheritManagers = null,
@ -146,10 +159,6 @@ class ResourceService {
): Resource { ): Resource {
$resource = $this->find($id); $resource = $this->find($id);
if(isset($parentResource)) {
$resource->setParentResource($parentResource);
}
if(isset($name)) { if(isset($name)) {
if($this->mapper->existsWithName($resource->getOrganizationFolderId(), $resource->getParentResource(), $name)) { if($this->mapper->existsWithName($resource->getOrganizationFolderId(), $resource->getParentResource(), $name)) {
throw new ResourceNameNotUnique(); throw new ResourceNameNotUnique();
@ -206,10 +215,7 @@ class ResourceService {
$inheritingPrincipals = []; $inheritingPrincipals = [];
foreach($inheritingGroups as $inheritingGroup) { foreach($inheritingGroups as $inheritingGroup) {
$inheritingPrincipals[] = [ $inheritingPrincipals[] = new Principal(PrincipalType::GROUP, $inheritingGroup);
"type" => "group",
"groupId" => $inheritingGroup,
];
} }
return $this->recursivelySetFolderResourceALCs($topLevelFolderResources, "", $inheritingPrincipals); return $this->recursivelySetFolderResourceALCs($topLevelFolderResources, "", $inheritingPrincipals);
@ -222,8 +228,8 @@ class ResourceService {
* @psalm-param FolderResource[] $folderResources * @psalm-param FolderResource[] $folderResources
* @param string $path * @param string $path
* @psalm-param string $path * @psalm-param string $path
* @param array $inheritingGroups * @param array $inheritingPrincipals
* @psalm-param string[] $inheritingGroups * @psalm-param Principal[] $inheritingPrincipals
*/ */
public function recursivelySetFolderResourceALCs(array $folderResources, string $path, array $inheritingPrincipals) { public function recursivelySetFolderResourceALCs(array $folderResources, string $path, array $inheritingPrincipals) {
foreach($folderResources as $folderResource) { foreach($folderResources as $folderResource) {
@ -232,20 +238,16 @@ class ResourceService {
// inherit ACLs // inherit ACLs
foreach($inheritingPrincipals as $inheritingPrincipal) { foreach($inheritingPrincipals as $inheritingPrincipal) {
if($inheritingPrincipal["type"] === "group") { $newACL = $this->aclManager->createAclRuleForPrincipal(
$acls[] = new Rule( principal: $inheritingPrincipal,
userMapping: $this->userMappingManager->mappingFromId("group", $inheritingPrincipal["groupId"]), fileId: $resourceFileId,
fileId: $resourceFileId, mask: 31,
mask: 31, permissions: $folderResource->getInheritedAclPermission(),
permissions: $folderResource->getInheritedAclPermission(), );
);
} else if($inheritingPrincipal["type"] === "user") { // if mapping for principal could not be created, skip creating rule for it
$acls[] = new Rule( if(!is_null($newACL)) {
userMapping: $this->userMappingManager->mappingFromId("user", $inheritingPrincipal["userId"]), $acls[] = $newACL;
fileId: $resourceFileId,
mask: 31,
permissions: $folderResource->getInheritedAclPermission(),
);
} }
} }
@ -260,6 +262,7 @@ class ResourceService {
/** @var ResourceService */ /** @var ResourceService */
$resourceMemberService = $this->container->get(ResourceMemberService::class); $resourceMemberService = $this->container->get(ResourceMemberService::class);
$resourceMembers = $resourceMemberService->findAll($folderResource->getId()); $resourceMembers = $resourceMemberService->findAll($folderResource->getId());
foreach($resourceMembers as $resourceMember) { foreach($resourceMembers as $resourceMember) {
if($resourceMember->getPermissionLevel() === MemberPermissionLevel::MANAGER->value) { if($resourceMember->getPermissionLevel() === MemberPermissionLevel::MANAGER->value) {
$resourceMemberPermissions = $folderResource->getManagersAclPermission(); $resourceMemberPermissions = $folderResource->getManagersAclPermission();
@ -270,43 +273,20 @@ class ResourceService {
} }
if($resourceMemberPermissions !== 0) { if($resourceMemberPermissions !== 0) {
if($resourceMember->getType() === MemberType::USER->value) { $resourceMemberPrincipal = $resourceMember->getPrincipal();
$mapping = $this->userMappingManager->mappingFromId("user", $resourceMember->getPrincipal());
$nextInheritingPrincipals[] = [
"type" => "user",
"userId" => $resourceMember->getPrincipal(),
];
} else if($resourceMember->getType() === MemberType::GROUP->value) {
$mapping = $this->userMappingManager->mappingFromId("group", $resourceMember->getPrincipal());
$nextInheritingPrincipals[] = [
"type" => "group",
"groupId" => $resourceMember->getPrincipal(),
];
} else if($resourceMember->getType() === MemberType::ROLE->value) {
['organizationProviderId' => $organizationProviderId, 'roleId' => $roleId] = $resourceMember->getParsedPrincipal();
$organizationProvider = $this->organizationProviderManager->getOrganizationProvider($organizationProviderId); $newACL = $this->aclManager->createAclRuleForPrincipal(
$role = $organizationProvider->getRole($roleId); principal: $resourceMemberPrincipal,
$mapping = $this->userMappingManager->mappingFromId("group", $role->getMembersGroup());
$nextInheritingPrincipals[] = [
"type" => "group",
"groupId" => $role->getMembersGroup(),
];
} else {
throw new Exception("invalid resource member type");
}
if(is_null($mapping)) {
// TODO: skip member instead of crashing
throw new Exception(message: "invalid mapping, likely non-existing group");
}
$acls[] = new Rule(
userMapping: $mapping,
fileId: $resourceFileId, fileId: $resourceFileId,
mask: 31, mask: 31,
permissions: $resourceMemberPermissions, permissions: $resourceMemberPermissions,
); );
// if mapping for principal could not be created, skip creating rule for it
if(!is_null($newACL)) {
$acls[] = $newACL;
$nextInheritingPrincipals[] = $resourceMemberPrincipal;
}
} }
} }