2024-11-06 22:11:16 +01:00
< ? php
namespace OCA\OrganizationFolders\Controller ;
use OCP\AppFramework\Http\JSONResponse ;
use OCP\AppFramework\Http\Attribute\NoAdminRequired ;
2024-11-16 03:10:27 +01:00
use OCA\OrganizationFolders\Db\Resource ;
2024-11-06 22:11:16 +01:00
use OCA\OrganizationFolders\Service\ResourceService ;
2024-11-16 03:10:27 +01:00
use OCA\OrganizationFolders\Service\ResourceMemberService ;
2024-11-25 15:28:40 +01:00
use OCA\OrganizationFolders\Service\OrganizationFolderService ;
2024-11-16 03:10:27 +01:00
use OCA\OrganizationFolders\Traits\ApiObjectController ;
2024-11-06 22:11:16 +01:00
class ResourceController extends BaseController {
use Errors ;
2024-11-16 03:10:27 +01:00
use ApiObjectController ;
public const MEMBERS_INCLUDE = 'members' ;
2024-11-25 15:28:40 +01:00
public const SUBRESOURCES_INCLUDE = 'subresources' ;
2024-11-06 22:11:16 +01:00
public function __construct (
private ResourceService $service ,
2024-11-16 03:10:27 +01:00
private ResourceMemberService $memberService ,
2024-11-25 15:28:40 +01:00
private OrganizationFolderService $organizationFolderService ,
2024-11-06 22:11:16 +01:00
private string $userId ,
) {
parent :: __construct ();
}
2024-11-16 03:10:27 +01:00
private function getApiObjectFromEntity ( Resource $resource , ? string $include ) : array {
$includes = $this -> parseIncludesString ( $include );
$result = [];
if ( $this -> shouldInclude ( self :: MODEL_INCLUDE , $includes )) {
$result = $resource -> jsonSerialize ();
}
if ( $this -> shouldInclude ( self :: MEMBERS_INCLUDE , $includes )) {
$result [ " members " ] = $this -> memberService -> findAll ( $resource -> getId ());
}
2024-11-25 15:28:40 +01:00
if ( $this -> shouldInclude ( self :: SUBRESOURCES_INCLUDE , $includes )) {
$result [ " subresources " ] = $this -> getSubResources ( $resource -> getId ());
}
2024-11-16 03:10:27 +01:00
return $result ;
}
2024-11-06 22:11:16 +01:00
#[NoAdminRequired]
2024-11-16 03:10:27 +01:00
public function show ( int $resourceId , ? string $include ) : JSONResponse {
return $this -> handleNotFound ( function () use ( $resourceId , $include ) {
2024-11-06 22:11:16 +01:00
$resource = $this -> service -> find ( $resourceId );
$this -> denyAccessUnlessGranted ([ 'READ' ], $resource );
2024-11-16 03:10:27 +01:00
return $this -> getApiObjectFromEntity ( $resource , $include );
2024-11-06 22:11:16 +01:00
});
}
#[NoAdminRequired]
public function create (
int $organizationFolderId ,
string $type ,
string $name ,
? int $parentResourceId = null ,
bool $active = true ,
bool $inheritManagers = true ,
// for type folder
? int $membersAclPermission = null ,
? int $managersAclPermission = null ,
? int $inheritedAclPermission = null ,
2024-11-16 03:10:27 +01:00
? string $include ,
2024-11-06 22:11:16 +01:00
) : JSONResponse {
2024-11-16 03:10:27 +01:00
return $this -> handleErrors ( function () use ( $organizationFolderId , $type , $name , $parentResourceId , $active , $inheritManagers , $membersAclPermission , $managersAclPermission , $inheritedAclPermission , $include ) {
2024-11-25 15:28:40 +01:00
$organizationFolder = $this -> organizationFolderService -> find ( $organizationFolderId );
2024-11-16 03:10:27 +01:00
if ( ! is_null ( $parentResourceId )) {
$parentResource = $this -> service -> find ( $parentResourceId );
2024-11-06 22:11:16 +01:00
2024-11-16 03:10:27 +01:00
$this -> denyAccessUnlessGranted ([ 'CREATE_SUBRESOURCE' ], $parentResource );
} else {
2024-11-25 15:28:40 +01:00
$this -> denyAccessUnlessGranted ([ 'CREATE_RESOURCE' ], $organizationFolder );
2024-11-16 03:10:27 +01:00
}
$resource = $this -> service -> create (
2024-11-25 15:28:40 +01:00
organizationFolderId : $organizationFolder -> getId (),
2024-11-06 22:11:16 +01:00
type : $type ,
name : $name ,
parentResourceId : $parentResourceId ,
active : $active ,
inheritManagers : $inheritManagers ,
membersAclPermission : $membersAclPermission ,
managersAclPermission : $managersAclPermission ,
inheritedAclPermission : $inheritedAclPermission ,
);
2024-11-16 03:10:27 +01:00
return $this -> getApiObjectFromEntity ( $resource , $include );
});
}
#[NoAdminRequired]
public function update (
int $resourceId ,
? string $name = null ,
? bool $active = null ,
? bool $inheritManagers = null ,
// for type folder
? int $membersAclPermission = null ,
? int $managersAclPermission = null ,
? int $inheritedAclPermission = null ,
? string $include ,
) : JSONResponse {
return $this -> handleErrors ( function () use ( $resourceId , $name , $active , $inheritManagers , $membersAclPermission , $managersAclPermission , $inheritedAclPermission , $include ) {
$resource = $this -> service -> find ( $resourceId );
$this -> denyAccessUnlessGranted ([ 'UPDATE' ], $resource );
$resource = $this -> service -> update (
id : $resourceId ,
name : $name ,
active : $active ,
inheritManagers : $inheritManagers ,
membersAclPermission : $membersAclPermission ,
managersAclPermission : $managersAclPermission ,
inheritedAclPermission : $inheritedAclPermission ,
);
return $this -> getApiObjectFromEntity ( $resource , $include );
2024-11-06 22:11:16 +01:00
});
}
2024-11-25 15:28:40 +01:00
#[NoAdminRequired]
public function subResources ( int $resourceId ) : JSONResponse {
return $this -> handleNotFound ( function () use ( $resourceId ) {
return $this -> getSubResources ( $resourceId );
});
}
protected function getSubResources ( int $resourceId ) : array {
$resource = $this -> service -> find ( $resourceId );
$organizationFolder = $this -> organizationFolderService -> find ( $resource -> getOrganizationFolderId ());
$subresources = $this -> service -> getSubResources ( $resource );
$result = [];
if ( $this -> authorizationService -> isGranted ([ 'MANAGE_ALL_RESOURCES' ], $organizationFolder )) {
/* fastpath: access to all subresources */
$result = $subresources ;
} else {
foreach ( $subresources as $subresource ) {
// Future optimization potential 1: the following will potentially check the permissions of each of these subresources all the way up the resource tree.
// As sibling resources these subresources share the same resources above them in the tree.
// So if access to the parent resource is granted, all subresources with inheritManagers can be granted immediately.
// For all other subresources only a check if user has direct (non-inherited) manager rights is neccessary.
// Future optimization potential 2: READ permission check checks MANAGE_ALL_RESOURCES again, at this point we know this to be false, because of the fastpath.
// Could be replaced with something like a READ_DIRECT (name TBD) permission check, which does not check this again.
if ( $this -> authorizationService -> isGranted ([ 'READ' ], $resource )) {
$result [] = $subresource ;
} else if ( $this -> authorizationService -> isGranted ([ 'READ_LIMITED' ], $resource )) {
$result [] = $subresource -> limitedJsonSerialize ();
}
}
}
return $result ;
}
2024-11-06 22:11:16 +01:00
}