cs = $cs; $this->groupRoleManager = $groupRoleManager; $this->ts = $ts; $this->em = $em; $this->aliasedUser = null; } /** * @param FolderGroupPermission $element * @return bool */ public function updateFolderGroupPermission(FolderGroupPermission $element) { return $this->quickUpdateFolderGroupPermission($element); } /** * @param FolderGroupPermission $element * @return bool */ public function quickUpdateFolderGroupPermission(FolderGroupPermission $element) { try { if(!$this->em->contains($element)){ $this->em->persist($element); } $this->em->flush(); } catch (OptimisticLockException $e) { //die('Exception : '.$e->getMessage()); //throw new Exception('Exception : '.$e->getMessage()); return false; } catch (ORMException $e) { return false; } return true; } /** * @param FileGroupPermission $element * @return bool */ public function updateFileGroupPermission(FileGroupPermission $element) { return $this->quickUpdateFileGroupPermission($element); } /** * @param FileGroupPermission $element * @return bool */ public function quickUpdateFileGroupPermission(FileGroupPermission $element) { try { if(!$this->em->contains($element)){ $this->em->persist($element); } $this->em->flush(); } catch (OptimisticLockException $e) { //die('Exception : '.$e->getMessage()); //throw new Exception('Exception : '.$e->getMessage()); return false; } catch (ORMException $e) { return false; } return true; } /** * @param FolderOwner $element * @return bool */ public function update(FolderOwner $element) { return $this->quickUpdate($element); } /** * @param FolderOwner $element * @return bool */ public function quickUpdate(FolderOwner $element) { try { if(!$this->em->contains($element)){ $this->em->persist($element); } $this->em->flush(); } catch (OptimisticLockException $e) { //die('Exception : '.$e->getMessage()); //throw new Exception('Exception : '.$e->getMessage()); return false; } catch (ORMException $e) { return false; } return true; } /** * @param FileOwner $element * @return bool */ public function updateFileOwner(FileOwner $element) { return $this->quickUpdateFileOwner($element); } /** * @param FileOwner $element * @return bool */ public function quickUpdateFileOwner(FileOwner $element) { try { if(!$this->em->contains($element)){ $this->em->persist($element); } $this->em->flush(); } catch (OptimisticLockException $e) { //die('Exception : '.$e->getMessage()); //throw new Exception('Exception : '.$e->getMessage()); return false; } catch (ORMException $e) { return false; } return true; } /** * @return bool */ public function isLogged(){ $u = $this->ts->getToken()->getUser(); if(!is_null($this->aliasedUser)) $u = $this->aliasedUser; if($u instanceof CustomUserInterface) return true; else return false; } /** * Add guid so users can delete their own files event if they r'nt logged * * @param string $guid */ public function anonymousAddFileInWallet($guid){ $baseVal = $this->cs->get('FILE_WALLET',array()); $baseVal[] = $guid; $this->cs->update('FILE_WALLET',$baseVal); } /** * check if $guid is in wallet return true, false otherwise * * @param string $guid * @return bool */ public function anonymousIsFileInWallet($guid):bool { $baseVal = $this->cs->get('FILE_WALLET',array()); foreach($baseVal as $fGuid){ if($fGuid == $guid) return true; } return false; } /** * @param CustomUserGroupInterface $group * @param FolderItemBase $folderItem * @return FolderGroupPermission|null */ public function getGroupPermissionFolder(CustomUserGroupInterface $group, FolderItemBase $folderItem){ $repo = $this->em->getRepository('FileManagerBundle:FolderGroupPermission'); $r = $repo->findOneBy(['userGroup' => $group, 'folder' => $folderItem]); if(!$r instanceof FolderGroupPermission) return null; return $r; } /** * @param CustomUserGroupInterface $group * @param FileItem $fileItem * @return FileGroupPermission|null */ public function getGroupPermissionFile(CustomUserGroupInterface $group, FileItem $fileItem){ $repo = $this->em->getRepository('FileManagerBundle:FileGroupPermission'); $r = $repo->findOneBy(['userGroup' => $group, 'file' => $fileItem]); if(!$r instanceof FileGroupPermission) return null; return $r; } /** * update or create permission for given user on given folder * * * @param CustomUserInterface $user * @param FolderItemBase $folderItem * @param int|null $right * @param bool $applyRight * @return bool */ public function setUserAccessOnFolder(CustomUserInterface $user, FolderItemBase $folderItem, ?int $right = 100, bool $applyRight = true){ if($applyRight && !$this->canDeleteFolder($folderItem)) return false; $repo = $this->em->getRepository('FileManagerBundle:FolderOwner'); $p = $repo->findOneBy(['userFileOwnerInterface' => $user, 'folder' => $folderItem]); if(!$p instanceof FolderOwner){ $p = new FolderOwner($user,$folderItem, $right); } else { $p->setPermission((int)$right); } return $this->quickUpdate($p); } /** * @param CustomUserGroupInterface $group * @param FolderItemBase $folderItem * @param int|null $right * @param bool $applyRight * @return bool */ public function setGroupAccessOnFolder(CustomUserGroupInterface $group, FolderItemBase $folderItem, ?int $right = 100, bool $applyRight = true){ if($applyRight && !$this->canDeleteFolder($folderItem)) return false; $repo = $this->em->getRepository('FileManagerBundle:FolderGroupPermission'); $p = $repo->findOneBy(['userGroup' => $group, 'folder' => $folderItem]); if(!$p instanceof FolderOwner){ $p = new FolderGroupPermission(); $p->setDefault($group,$folderItem, $right); } else { $p->setPermission((int)$right); } return $this->quickUpdate($p); } /** * update or create permission for given user on given file * * * @param CustomUserInterface $user * @param FileItem $fileItem * @param int|null $right * @param bool $applyRight * @return bool */ public function setUserAccessOnFile(CustomUserInterface $user, FileItem $fileItem, ?int $right = 100, bool $applyRight = true){ if($applyRight && !$this->canDelete($fileItem)) return false; $repo = $this->em->getRepository('FileManagerBundle:FileOwner'); $p = $repo->findOneBy(['userFileOwnerInterface' => $user, 'file' => $fileItem]); if(!$p instanceof FileOwner){ $p = new FileOwner($user,$fileItem, $right); } else { $p->setPermission((int)$right); } return $this->quickUpdateFileOwner($p); } /** * update or create permission for given user on given folder, recursively * * @param CustomUserInterface $user * @param FolderItemBase $folderItem * @param int|null $folderRight set to null to do not change * @param int|null $fileRight set to null to do not change * @param bool $applyRight * @return int return the number of error, 0 is ok */ public function setPermissionRecursively(CustomUserInterface $user, FolderItemBase $folderItem, ?int $folderRight = 100, ?int $fileRight = 100, bool $applyRight = true){ $errors = 0 ; if(!is_null($folderRight)){ $this->setUserAccessOnFolder($user, $folderItem, $folderRight,$applyRight); } //files if(!is_null($fileRight)){ foreach($folderItem->getFiles() as $file){ if($file instanceof FileItem){ $r = $this->setUserAccessOnFile($user,$file,$fileRight,$applyRight); if(!$r) $errors++; } } } //sub-folders foreach($folderItem->getChildren() as $folder){ if($folder instanceof FolderItemBase){ $er = $this->setPermissionRecursively($user,$folder,$folderRight,$fileRight,$applyRight);//recursive $errors += (int)$er; } } return $errors; } /** * operation : delete,move,rename * * @param FileItem $file * @return bool */ public function canDelete(FileItem $file):bool { $ret = $this->getPermissionFor('delete',$file); /** * to prevent file from being locked in an non-existent folder * folder permission override file permissions */ if(!$ret){ $p = $file->getParentFolder(); if($p instanceof FolderItemBase){ return $this->canDeleteFolder($p); } } return $ret; } /** * operation : edit content * * @param FileItem $file * @return bool */ public function canEdit(FileItem $file):bool { $ret = $this->getPermissionFor('edit',$file); /** * to prevent file from being locked in an non-existent folder * folder permission override file permissions */ if(!$ret){ $p = $file->getParentFolder(); if($p instanceof FolderItemBase){ return $this->canDeleteFolder($p); } } return $ret; } /** * operation : read * * @param FileItem $file * @return bool */ public function canRead(FileItem $file):bool { return $this->getPermissionFor('read',$file); } /** * @param $action * @param $file * @return bool */ protected function getPermissionFor($action, FileItem $file){ if($file->getPermission() == FileWebPermission::PUBLIC && $action == 'read') return true; if($file->getPermission() == FileWebPermission::LOGGED_ONLY && $action == 'read' && $this->isLogged()) return true; if(($p = $this->getPermissionForFile($file)) !== false){ $pa = FilePermission::getPermissionFor($p); if(isset($pa[$action]) && $pa[$action] == true) return true; } return false; } /** * Get permission on $file for actual user|anonymous * * @param FileItem $file * @return bool|int */ public function getPermissionForFile(FileItem $file){ /** * @var User $user */ $user = $this->ts->getToken()->getUser(); if(!is_null($this->aliasedUser)) $user = $this->aliasedUser; if(!$user instanceof UserInterface){ if($this->anonymousIsFileInWallet($file->getGuid())) return FilePermission::OWNER; else return false; } $repo = $this->em->getRepository('FileManagerBundle:FileOwner'); /** * @var FileOwner $obj */ $obj = $repo->findOneBy(array('userFileOwnerInterface' => $user,'file' => $file)); if(is_null($obj)){ //check for group access $access = FilePermission::NOBODY; $groups = $this->groupRoleManager->getGroupForUser($user); foreach($groups as $groupRole){ $permissionGroup = $this->getGroupPermissionFile($groupRole->getGroup(), $file); if($permissionGroup instanceof FileGroupPermission){ if($access > $permissionGroup->getPermission()) $access = $permissionGroup->getPermission(); } } if($access < FilePermission::NOBODY) return $access; return false; } return $obj->getPermission(); } /** * @param FolderItemBase $folder * @return bool|int */ public function getPermissionForFolder(FolderItemBase $folder){ /** * @var User $user */ $user = $this->ts->getToken()->getUser(); if(!is_null($this->aliasedUser)) $user = $this->aliasedUser; if(!$user instanceof UserInterface){ return false; } if(!($user == $this->isLogged())){ return false; } $repo = $this->em->getRepository('FileManagerBundle:FolderOwner'); /** * @var FolderOwner $obj */ $obj = $repo->findOneBy(['userFileOwnerInterface' => $user,'folder' => $folder]); if(is_null($obj)){ //check for group access $access = FilePermission::NOBODY; $groups = $this->groupRoleManager->getGroupForUser($user); foreach($groups as $groupRole){ $permissionGroup = $this->getGroupPermissionFolder($groupRole->getGroup(),$folder); if($permissionGroup instanceof FolderGroupPermission){ if($access > $permissionGroup->getPermission()) $access = $permissionGroup->getPermission(); } } if($access < FilePermission::NOBODY) return $access; return false; } return $obj->getPermission(); } public function canDeleteFolder(FolderItemBase $folder):bool { return $this->getFolderPermissionFor('delete',$folder); } public function canEditFolder(FolderItemBase $folder):bool { return $this->getFolderPermissionFor('edit',$folder); } public function canReadFolder(FolderItemBase $folder):bool { return $this->getFolderPermissionFor('read',$folder); } /** * @param $action * @param FolderItemBase $folder * @return bool */ protected function getFolderPermissionFor($action, FolderItemBase $folder){ if(!$folder->isVisible()) return false; if($folder->getPermission() == FileWebPermission::PUBLIC && $action == 'read') return true; if($folder->getPermission() == FileWebPermission::LOGGED_ONLY && $action == 'read' && $this->isLogged()) return true; $p = $this->getPermissionForFolder($folder); if($p !== false){ $pa = FilePermission::getPermissionFor($p); if(isset($pa[$action]) && $pa[$action] == true) return true; } return false; } /** * get viewable files in folder * * @param FolderItemBase $folder * @param bool $applyPermission * @return array */ public function getFilesInFolder(FolderItemBase $folder, $applyPermission = true){ $ret = array(); if($folder->getFiles()->count() == 0) return $ret; foreach($folder->getFiles() as $file){ if($applyPermission){ if($this->canRead($file)){ $ret[] = $file; } } else $ret[] = $file; } return $ret; } /** * same for folders, with access rights applied by default * * @param FolderItemBase $folder * @param bool $applyPermission * @return array */ public function getFoldersInFolder(FolderItemBase $folder, $applyPermission = true){ $ret = array(); if($folder->getChildren()->count() == 0) return $ret; foreach($folder->getChildren() as $folder){ if($applyPermission){ if($this->canReadFolder($folder)) $ret[] = $folder; } else $ret[] = $folder; } return $ret; } /** * @param CustomUserInterface|UserFileOwnerInterface|null $aliasedUser * @return FileManagerPermissionService */ public function setAliasedUser($aliasedUser) { $this->aliasedUser = $aliasedUser; return $this; } /** * @return CustomUserInterface|null */ public function getAliasedUser() { return $this->aliasedUser; } }