Find this useful? Enter your email to receive occasional updates for securing PHP code.
Signing you up...
Thank you for signing up!
PHP Decode
<?php declare(strict_types=1); /** * Passbolt ~ Open source password manager for teams ..
Decoded Output download
<?php
declare(strict_types=1);
/**
* Passbolt ~ Open source password manager for teams
* Copyright (c) Passbolt SA (https://www.passbolt.com)
*
* Licensed under GNU Affero General Public License version 3 of the or any later version.
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Passbolt SA (https://www.passbolt.com)
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
* @link https://www.passbolt.com Passbolt(tm)
* @since 2.13.0
*/
namespace Passbolt\Folders\Service\Folders;
use App\Model\Entity\Permission;
use App\Model\Table\PermissionsTable;
use App\Service\Permissions\PermissionsGetUsersIdsHavingAccessToService;
use App\Service\Permissions\UserHasPermissionService;
use App\Utility\UserAccessControl;
use Cake\Datasource\Exception\RecordNotFoundException;
use Cake\Event\EventDispatcherTrait;
use Cake\Http\Exception\ForbiddenException;
use Cake\Http\Exception\NotFoundException;
use Cake\ORM\TableRegistry;
use Passbolt\Folders\Model\Entity\Folder;
use Passbolt\Folders\Model\Entity\FoldersRelation;
class FoldersDeleteService
{
use EventDispatcherTrait;
public const FOLDERS_DELETE_FOLDER_EVENT = 'folders.folder.delete';
/**
* @var \Passbolt\Folders\Model\Table\FoldersTable
*/
private $foldersTable;
/**
* @var \Passbolt\Folders\Model\Table\FoldersRelationsTable
*/
private $foldersRelationsTable;
/**
* @var \App\Service\Permissions\PermissionsGetUsersIdsHavingAccessToService
*/
private $getUsersIdsHavingAccessToService;
/**
* @var \App\Model\Table\PermissionsTable
*/
private $permissionsTable;
/**
* @var \App\Model\Table\ResourcesTable
*/
private $resourcesTable;
/**
* @var \App\Service\Permissions\UserHasPermissionService
*/
private $userHasPermissionService;
/**
* Instantiate the service.
*/
public function __construct()
{
$this->foldersTable = TableRegistry::getTableLocator()->get('Passbolt/Folders.Folders');
$this->foldersRelationsTable = TableRegistry::getTableLocator()->get('Passbolt/Folders.FoldersRelations');
$this->permissionsTable = TableRegistry::getTableLocator()->get('Permissions');
$this->resourcesTable = TableRegistry::getTableLocator()->get('Resources');
$this->getUsersIdsHavingAccessToService = new PermissionsGetUsersIdsHavingAccessToService();
$this->userHasPermissionService = new UserHasPermissionService();
}
/**
* Delete a folder for the current user.
*
* @param \App\Utility\UserAccessControl $uac The current user
* @param string $id The folder to delete
* @param bool $cascade (optional) Delete also the folder content. Default false.
* @return void
* @throws \Exception If an unexpected error occurred
*/
public function delete(UserAccessControl $uac, string $id, bool $cascade = false): void
{
$folder = $this->getFolder($id);
if (!$this->checkUserCanDelete($uac, PermissionsTable::FOLDER_ACO, $id)) {
throw new ForbiddenException(__('You are not allowed to delete this folder.'));
}
$this->foldersTable->getConnection()->transactional(function () use ($uac, $folder, $cascade) {
$usersIds = $this->getUsersIdsHavingAccessToService->getUsersIdsHavingAccessTo($folder->id);
$this->deleteFolder($uac, $folder, $cascade);
$this->dispatchEvent(self::FOLDERS_DELETE_FOLDER_EVENT, [
'uac' => $uac,
'folder' => $folder,
'users' => $usersIds,
]);
});
}
/**
* Retrieve the folder.
*
* @param string $folderId The folder identifier to retrieve.
* @return \Passbolt\Folders\Model\Entity\Folder
* @throws \Cake\Http\Exception\NotFoundException If the folder does not exist.
*/
private function getFolder(string $folderId): Folder
{
try {
return $this->foldersTable->get($folderId);
} catch (RecordNotFoundException $e) {
throw new NotFoundException(__('The folder does not exist.'));
}
}
/**
* Assert that the current user can update the destination folder.
*
* @param \App\Utility\UserAccessControl $uac The current user
* @param string $itemModel The target item model
* @param string $itemId The target item
* @return bool
*/
private function checkUserCanDelete(UserAccessControl $uac, string $itemModel, string $itemId): bool
{
$userId = $uac->getId();
return $this->userHasPermissionService->check($itemModel, $itemId, $userId, Permission::UPDATE);
}
/**
* Delete a folder.
*
* @param \App\Utility\UserAccessControl $uac The operator
* @param \Passbolt\Folders\Model\Entity\Folder $folder The target folder
* @param bool $cascade Should delete the content
* @return void
* @throws \Exception
*/
private function deleteFolder(UserAccessControl $uac, Folder $folder, bool $cascade): void
{
if ($cascade) {
$this->deleteFolderChildrenOrMoveToRoot($uac, $folder);
} else {
$this->moveFolderContentToRoot($folder);
}
$this->foldersTable->delete($folder, ['atomic' => false]);
$this->foldersRelationsTable->deleteAll(['foreign_id' => $folder->id]);
$this->permissionsTable->deleteAll(['aco_foreign_key' => $folder->id]);
}
/**
* Delete the content of a folder if possible, otherwise move it to the root.
*
* @param \App\Utility\UserAccessControl $uac The current user.
* @param \Passbolt\Folders\Model\Entity\Folder $folder The target folder
* @return void
* @throws \Exception
*/
private function deleteFolderChildrenOrMoveToRoot(UserAccessControl $uac, Folder $folder): void
{
$children = $this->foldersRelationsTable->findByFolderParentId($folder->id);
foreach ($children as $folderRelation) {
$this->deleteFolderChildOrMoveToRoot(
$uac,
$folderRelation->foreign_model,
$folderRelation->foreign_id,
$folder->id
);
}
}
/**
* Delete a folder child if possible, otherwise move it to the root.
*
* @param \App\Utility\UserAccessControl $uac The operator
* @param string $foreignModel The type of child
* @param string $foreignId The child identifier
* @param string $folderParentId The parent folder identifier
* @return void
* @throws \Exception
*/
private function deleteFolderChildOrMoveToRoot(
UserAccessControl $uac,
string $foreignModel,
string $foreignId,
string $folderParentId
): void {
$canDelete = $this->checkUserCanDelete($uac, $foreignModel, $foreignId);
if ($canDelete) {
switch ($foreignModel) {
case FoldersRelation::FOREIGN_MODEL_FOLDER:
$folder = $this->getFolder($foreignId);
$this->deleteFolder($uac, $folder, true);
break;
case FoldersRelation::FOREIGN_MODEL_RESOURCE:
$this->deleteResource($uac, $foreignId);
break;
}
} else {
$this->foldersRelationsTable->moveItemFrom($foreignId, [$folderParentId], null);
}
}
/**
* Delete a child resource
*
* @param \App\Utility\UserAccessControl $uac The current user.
* @param string $resourceId The resource to delete
* @return void
*/
private function deleteResource(UserAccessControl $uac, string $resourceId): void
{
$userId = $uac->getId();
$canDelete = $this->userHasPermissionService
->check(PermissionsTable::RESOURCE_ACO, $resourceId, $userId, Permission::UPDATE);
if (!$canDelete) {
throw new ForbiddenException(__('You cannot delete this resource'));
}
$resource = $this->resourcesTable->get($resourceId);
// The soft delete function will trigger an event that once caught will remove the resource from the users
// folders trees.
$this->resourcesTable->softDelete($uac->getId(), $resource);
}
/**
* Move folder content to root.
*
* @param \Passbolt\Folders\Model\Entity\Folder $folder The target folder
* @return void
* @throws \Exception
*/
private function moveFolderContentToRoot(Folder $folder): void
{
$this->foldersRelationsTable->updateAll(['folder_parent_id' => null], ['folder_parent_id' => $folder->id]);
}
}
?>
Did this file decode correctly?
Original Code
<?php
declare(strict_types=1);
/**
* Passbolt ~ Open source password manager for teams
* Copyright (c) Passbolt SA (https://www.passbolt.com)
*
* Licensed under GNU Affero General Public License version 3 of the or any later version.
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Passbolt SA (https://www.passbolt.com)
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
* @link https://www.passbolt.com Passbolt(tm)
* @since 2.13.0
*/
namespace Passbolt\Folders\Service\Folders;
use App\Model\Entity\Permission;
use App\Model\Table\PermissionsTable;
use App\Service\Permissions\PermissionsGetUsersIdsHavingAccessToService;
use App\Service\Permissions\UserHasPermissionService;
use App\Utility\UserAccessControl;
use Cake\Datasource\Exception\RecordNotFoundException;
use Cake\Event\EventDispatcherTrait;
use Cake\Http\Exception\ForbiddenException;
use Cake\Http\Exception\NotFoundException;
use Cake\ORM\TableRegistry;
use Passbolt\Folders\Model\Entity\Folder;
use Passbolt\Folders\Model\Entity\FoldersRelation;
class FoldersDeleteService
{
use EventDispatcherTrait;
public const FOLDERS_DELETE_FOLDER_EVENT = 'folders.folder.delete';
/**
* @var \Passbolt\Folders\Model\Table\FoldersTable
*/
private $foldersTable;
/**
* @var \Passbolt\Folders\Model\Table\FoldersRelationsTable
*/
private $foldersRelationsTable;
/**
* @var \App\Service\Permissions\PermissionsGetUsersIdsHavingAccessToService
*/
private $getUsersIdsHavingAccessToService;
/**
* @var \App\Model\Table\PermissionsTable
*/
private $permissionsTable;
/**
* @var \App\Model\Table\ResourcesTable
*/
private $resourcesTable;
/**
* @var \App\Service\Permissions\UserHasPermissionService
*/
private $userHasPermissionService;
/**
* Instantiate the service.
*/
public function __construct()
{
$this->foldersTable = TableRegistry::getTableLocator()->get('Passbolt/Folders.Folders');
$this->foldersRelationsTable = TableRegistry::getTableLocator()->get('Passbolt/Folders.FoldersRelations');
$this->permissionsTable = TableRegistry::getTableLocator()->get('Permissions');
$this->resourcesTable = TableRegistry::getTableLocator()->get('Resources');
$this->getUsersIdsHavingAccessToService = new PermissionsGetUsersIdsHavingAccessToService();
$this->userHasPermissionService = new UserHasPermissionService();
}
/**
* Delete a folder for the current user.
*
* @param \App\Utility\UserAccessControl $uac The current user
* @param string $id The folder to delete
* @param bool $cascade (optional) Delete also the folder content. Default false.
* @return void
* @throws \Exception If an unexpected error occurred
*/
public function delete(UserAccessControl $uac, string $id, bool $cascade = false): void
{
$folder = $this->getFolder($id);
if (!$this->checkUserCanDelete($uac, PermissionsTable::FOLDER_ACO, $id)) {
throw new ForbiddenException(__('You are not allowed to delete this folder.'));
}
$this->foldersTable->getConnection()->transactional(function () use ($uac, $folder, $cascade) {
$usersIds = $this->getUsersIdsHavingAccessToService->getUsersIdsHavingAccessTo($folder->id);
$this->deleteFolder($uac, $folder, $cascade);
$this->dispatchEvent(self::FOLDERS_DELETE_FOLDER_EVENT, [
'uac' => $uac,
'folder' => $folder,
'users' => $usersIds,
]);
});
}
/**
* Retrieve the folder.
*
* @param string $folderId The folder identifier to retrieve.
* @return \Passbolt\Folders\Model\Entity\Folder
* @throws \Cake\Http\Exception\NotFoundException If the folder does not exist.
*/
private function getFolder(string $folderId): Folder
{
try {
return $this->foldersTable->get($folderId);
} catch (RecordNotFoundException $e) {
throw new NotFoundException(__('The folder does not exist.'));
}
}
/**
* Assert that the current user can update the destination folder.
*
* @param \App\Utility\UserAccessControl $uac The current user
* @param string $itemModel The target item model
* @param string $itemId The target item
* @return bool
*/
private function checkUserCanDelete(UserAccessControl $uac, string $itemModel, string $itemId): bool
{
$userId = $uac->getId();
return $this->userHasPermissionService->check($itemModel, $itemId, $userId, Permission::UPDATE);
}
/**
* Delete a folder.
*
* @param \App\Utility\UserAccessControl $uac The operator
* @param \Passbolt\Folders\Model\Entity\Folder $folder The target folder
* @param bool $cascade Should delete the content
* @return void
* @throws \Exception
*/
private function deleteFolder(UserAccessControl $uac, Folder $folder, bool $cascade): void
{
if ($cascade) {
$this->deleteFolderChildrenOrMoveToRoot($uac, $folder);
} else {
$this->moveFolderContentToRoot($folder);
}
$this->foldersTable->delete($folder, ['atomic' => false]);
$this->foldersRelationsTable->deleteAll(['foreign_id' => $folder->id]);
$this->permissionsTable->deleteAll(['aco_foreign_key' => $folder->id]);
}
/**
* Delete the content of a folder if possible, otherwise move it to the root.
*
* @param \App\Utility\UserAccessControl $uac The current user.
* @param \Passbolt\Folders\Model\Entity\Folder $folder The target folder
* @return void
* @throws \Exception
*/
private function deleteFolderChildrenOrMoveToRoot(UserAccessControl $uac, Folder $folder): void
{
$children = $this->foldersRelationsTable->findByFolderParentId($folder->id);
foreach ($children as $folderRelation) {
$this->deleteFolderChildOrMoveToRoot(
$uac,
$folderRelation->foreign_model,
$folderRelation->foreign_id,
$folder->id
);
}
}
/**
* Delete a folder child if possible, otherwise move it to the root.
*
* @param \App\Utility\UserAccessControl $uac The operator
* @param string $foreignModel The type of child
* @param string $foreignId The child identifier
* @param string $folderParentId The parent folder identifier
* @return void
* @throws \Exception
*/
private function deleteFolderChildOrMoveToRoot(
UserAccessControl $uac,
string $foreignModel,
string $foreignId,
string $folderParentId
): void {
$canDelete = $this->checkUserCanDelete($uac, $foreignModel, $foreignId);
if ($canDelete) {
switch ($foreignModel) {
case FoldersRelation::FOREIGN_MODEL_FOLDER:
$folder = $this->getFolder($foreignId);
$this->deleteFolder($uac, $folder, true);
break;
case FoldersRelation::FOREIGN_MODEL_RESOURCE:
$this->deleteResource($uac, $foreignId);
break;
}
} else {
$this->foldersRelationsTable->moveItemFrom($foreignId, [$folderParentId], null);
}
}
/**
* Delete a child resource
*
* @param \App\Utility\UserAccessControl $uac The current user.
* @param string $resourceId The resource to delete
* @return void
*/
private function deleteResource(UserAccessControl $uac, string $resourceId): void
{
$userId = $uac->getId();
$canDelete = $this->userHasPermissionService
->check(PermissionsTable::RESOURCE_ACO, $resourceId, $userId, Permission::UPDATE);
if (!$canDelete) {
throw new ForbiddenException(__('You cannot delete this resource'));
}
$resource = $this->resourcesTable->get($resourceId);
// The soft delete function will trigger an event that once caught will remove the resource from the users
// folders trees.
$this->resourcesTable->softDelete($uac->getId(), $resource);
}
/**
* Move folder content to root.
*
* @param \Passbolt\Folders\Model\Entity\Folder $folder The target folder
* @return void
* @throws \Exception
*/
private function moveFolderContentToRoot(Folder $folder): void
{
$this->foldersRelationsTable->updateAll(['folder_parent_id' => null], ['folder_parent_id' => $folder->id]);
}
}
Function Calls
None |
Stats
MD5 | a9601d988c1816fda255604b3b7ccae2 |
Eval Count | 0 |
Decode Time | 79 ms |