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

215 lines
8.3 KiB
PHP

<?php
declare(strict_types=1);
namespace OCA\OrganizationFolders\Service;
use Psr\Container\ContainerInterface;
use OCP\AppFramework\Db\TTransactional;
use OCP\IDBConnection;
use OCA\GroupFolders\Folder\FolderManager;
use OCA\GroupfolderTags\Service\TagService;
use OCA\GroupFolders\ACL\UserMapping\UserMappingManager;
use OCA\GroupFolders\ACL\Rule;
use OCA\OrganizationFolders\Errors\OrganizationFolderNotFound;
use OCA\OrganizationFolders\Model\OrganizationFolder;
use OCA\OrganizationFolders\OrganizationProvider\OrganizationProviderManager;
use OCA\OrganizationFolders\Manager\PathManager;
use OCA\OrganizationFolders\Manager\GroupfolderManager;
use OCA\OrganizationFolders\Manager\ACLManager;
class OrganizationFolderService {
use TTransactional;
public function __construct(
protected IDBConnection $db,
protected FolderManager $folderManager,
protected UserMappingManager $userMappingManager,
protected TagService $tagService,
protected OrganizationProviderManager $organizationProviderManager,
protected PathManager $pathManager,
protected GroupfolderManager $groupfolderManager,
protected ACLManager $aclManager,
protected ContainerInterface $container,
) {
}
public function findAll() {
$result = [];
$groupfolders = $this->tagService->findGroupfoldersWithTagsGenerator([
["key" => "organization_folder"],
], ["organization_provider", "organization_id"]);
foreach ($groupfolders as $groupfolder) {
$result[] = new OrganizationFolder(
id: $groupfolder["id"],
name: $groupfolder["mount_point"],
quota: $groupfolder["quota"],
organizationProvider: $groupfolder["organization_provider"],
organizationId: (int)$groupfolder["organization_id"],
);
}
return $result;
}
public function find(int $id): OrganizationFolder {
$groupfolder = $this->tagService->findGroupfolderWithTags($id,[
["key" => "organization_folder"],
], ["organization_provider", "organization_id"]);
if(is_null($groupfolder)) {
throw new OrganizationFolderNotFound($id);
}
return new OrganizationFolder(
id: $groupfolder["id"],
name: $groupfolder["mount_point"],
quota: $groupfolder["quota"],
organizationProvider: $groupfolder["organization_provider"],
organizationId: (int)$groupfolder["organization_id"],
);
}
public function create(string $name, int $quota, ?string $organizationProvider = null,?int $organizationId = null): OrganizationFolder {
return $this->atomic(function () use ($name, $quota, $organizationProvider, $organizationId) {
$groupfolderId = $this->folderManager->createFolder($name);
$this->folderManager->setFolderQuota($groupfolderId, $quota);
$this->folderManager->setFolderACL($groupfolderId, true);
$this->tagService->update($groupfolderId, "organization_folder");
if(isset($organizationProvider) && $this->organizationProviderManager->hasOrganizationProvider($organizationProvider) && isset($organizationId)) {
$organization = $this->organizationProviderManager->getOrganizationProvider($organizationProvider)->getOrganization($organizationId);
$this->tagService->update($groupfolderId, "organization_provider", $organizationProvider);
$this->tagService->update($groupfolderId, "organization_id", (string)$organization->getId());
}
$organizationFolder = new OrganizationFolder(
id: $groupfolderId,
name: $name,
quota: $quota,
organizationProvider: $organizationProvider,
organizationId: $organizationId,
);
$this->applyPermissions($groupfolderId);
return $organizationFolder;
}, $this->db);
}
public function update(
int $id,
?string $name = null,
?int $quota = null,
?string $organizationProviderId = null,
?int $organizationId = null
): OrganizationFolder {
$this->atomic(function () use ($id, $name, $quota, $organizationProviderId, $organizationId) {
if(isset($name)) {
$this->folderManager->renameFolder($id, $name);
}
if(isset($quota)) {
$this->folderManager->setFolderQuota($id, $quota);
}
if(isset($organizationProviderId) || isset($organizationId)) {
if(!isset($organizationProviderId)) {
$organizationProviderId = $this->tagService->find($id, "organization_provider")->getTagValue();
}
if(!$this->organizationProviderManager->hasOrganizationProvider($organizationProviderId)) {
throw new \Exception("organization provider not found");
}
$organizationProvider = $this->organizationProviderManager->getOrganizationProvider($organizationProviderId);
if(!isset($organizationId)) {
$organizationId = (int)$this->tagService->find($id, "organization_id")->getTagValue();
}
$organization = $organizationProvider->getOrganization($organizationId);
$this->tagService->update($id, "organization_provider", $organizationProviderId);
$this->tagService->update($id, "organization_id", (string)$organization->getId());
}
}, $this->db);
$this->applyPermissions($id);
return $this->find($id);
}
public function applyPermissions(int $id) {
$organizationFolder = $this->find($id);
$memberGroups = $this->getMemberGroups($organizationFolder);
$this->setGroupsAsGroupfolderMembers($organizationFolder->getId(), $memberGroups);
$this->setRootFolderACLs($organizationFolder, $memberGroups);
/** @var ResourceService */
$resourceService = $this->container->get(ResourceService::class);
return $resourceService->setAllFolderResourceAclsInOrganizationFolder($organizationFolder, $memberGroups);
}
protected function getMemberGroups(OrganizationFolder $organizationFolder) {
// TODO: fetch member groups, for now only use organization members
$memberGroups = [];
if(!is_null($organizationFolder->getOrganizationProvider()) && !is_null($organizationFolder->getOrganizationId())) {
$organizationProvider = $this->organizationProviderManager->getOrganizationProvider($organizationFolder->getOrganizationProvider());
$organization = $organizationProvider->getOrganization($organizationFolder->getOrganizationId());
$memberGroups[] = $organization->getMembersGroup();
}
return $memberGroups;
}
protected function setGroupsAsGroupfolderMembers($groupfolderId, array $groups) {
$groupfolderMembers = [];
foreach($groups as $group) {
$groupfolderMembers[] = [
"group_id" => $group,
"permissions" => \OCP\Constants::PERMISSION_ALL,
];
}
return $this->groupfolderManager->overwriteMemberGroups($groupfolderId, $groupfolderMembers);
}
/**
* In the root folder of an organization folder only resource folders can exist
* To prevent adding files there all member groups of the groupfolder need to have a read-only ACL rule on the root folder
*/
protected function setRootFolderACLs(OrganizationFolder $organizationFolder, $groups) {
$folderNode = $this->pathManager->getOrganizationFolderNode($organizationFolder);
$fileId = $folderNode->getId();
$acls = [];
foreach($groups as $group) {
$acls[] = new Rule(
userMapping: $this->userMappingManager->mappingFromId("group", $group),
fileId: $fileId,
mask: 31,
permissions: 1,
);
}
$this->aclManager->overwriteACLsForFileId($fileId, $acls);
}
public function remove($id): void {
$organizationFolder = $this->find($id);
$this->folderManager->removeFolder($organizationFolder->getId());
}
}