mirror of
https://github.com/verdigado/organization_folders.git
synced 2024-11-23 05:00:27 +01:00
215 lines
8.3 KiB
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());
|
|
}
|
|
|
|
}
|