Ejemplo n.º 1
0
 public function updateCollaboratorPermission(IShareable $object, AbstractEyeosPrincipal $collaborator, IPermission $permission)
 {
     try {
         if ($object->getId() === null) {
             throw new EyeNullPointerException('$object ID cannot be null.');
         }
         $handlerClassName = null;
         foreach (self::getAllShareableObjectsHandlers() as $handler) {
             if ($handler->checkType($object)) {
                 $handlerClassName = get_class($handler);
                 break;
             }
         }
         if ($handlerClassName === null) {
             throw new EyeHandlerNotFoundException('Unable to find a ShareableObjectHandler for object of class ' . get_class($object) . '.');
         }
         $owner = $object->getShareOwner();
         SecurityManager::getInstance()->checkPermission($object, new SharePermission(array('updatecollaborator'), $collaborator));
         //prepare query array
         $shareInfoQuery = array(self::SHAREINFO_KEY_OWNERID => $owner->getId(), self::SHAREINFO_KEY_SHAREABLEID => $object->getId(), self::SHAREINFO_KEY_COLLABORATORID => $collaborator->getId(), self::SHAREINFO_KEY_PERMISSIONACTIONS => $permission->getActionsAsString(), self::SHAREINFO_KEY_HANDLERCLASSNAME => $handlerClassName);
         $this->getProvider()->updateShareInfo($owner, $shareInfoQuery);
         // TODO: we could also add the ShareInfo object containing the old permission as a
         // "related source" of the event
         $event = new SharingEvent(new BasicShareInfo($owner, $object, $collaborator, $permission, $handlerClassName));
         foreach ($this->listeners as $listener) {
             $listener->collaboratorPermissionUpdated($event);
         }
     } catch (Exception $e) {
         self::$Logger->warn('Unable to update collaborator ' . $collaborator->getName() . ' permissions for object of class ' . get_class($object) . '.');
         if (self::$Logger->isDebugEnabled()) {
             self::$Logger->debug(ExceptionStackUtil::getStackTrace($e, false));
         }
         throw $e;
     }
 }
 /**
  * TODO
  *
  * @param mixed $object
  * @param IPermission $permission
  * @param LoginContext $context
  * @return bool TRUE if the handler performed the permission check successfully, FALSE otherwise.
  *
  * @throws EyeInvalidArgumentException
  * @throws EyeUnexpectedValueException
  * @throws EyeAccessControlException
  */
 public function checkPermission($object, IPermission $permission, LoginContext $context)
 {
     if (!$object instanceof IFile) {
         throw new EyeInvalidArgumentException('$object must be an IFile.');
     }
     if ($object instanceof EyeUserFile) {
         $name = $object->getName();
         if ($name == '.htaccess') {
             throw new EyeAccessControlException('You cannot access that kind of file (.HTACCESS).');
         }
         if ('' == $name) {
             throw new EyeAccessControlException('Empty filename not allowed');
         }
         if (strstr($name, '?')) {
             throw new EyeAccessControlException('Invalid character ? on filename');
         }
         if (strstr($name, '#')) {
             throw new EyeAccessControlException('Invalid character # on filename');
         }
         if (strstr($name, '&')) {
             throw new EyeAccessControlException('Invalid character & on filename');
         }
         if (strstr($name, '<')) {
             throw new EyeAccessControlException('Invalid character < on filename');
         }
         if (strstr($name, '>')) {
             throw new EyeAccessControlException('Invalid character > on filename');
         }
     }
     // If the target file does not exist or we are requesting a deletion permission,
     // we must check write permissions on the parent folder, to know whether the current
     // user is allowed or not to manipulate files within it.
     if (!$object->exists() || in_array('delete', $permission->getActions())) {
         $parentFolder = $object->getParentFile();
         if (!$parentFolder->equals($object)) {
             $parentFolder->checkWritePermission();
             return true;
         }
     }
     try {
         $eyeosUser = $context->getEyeosUser();
     } catch (EyeNullPointerException $e) {
         $this->failureException = new EyeHandlerFailureException('No eyeos user found in login context.');
         return false;
     }
     $objectPermissions = $object->getPermissions(true);
     if (!is_int($objectPermissions)) {
         $this->failureException = new EyeHandlerFailureException('"' . $objectPermissions . '" is not a valid octal UNIX permission for file ' . $object->getPath() . '.');
         return false;
     }
     try {
         $owner = UMManager::getInstance()->getUserByName($object->getOwner());
     } catch (EyeNoSuchUserException $e) {
         //This is a workaround: when the owner of a workgroup file not longer exist
         //we have to set a new owner for that file, otherwise we have an exception
         //when we try to access to load owner informations.
         if (get_class($object) == 'EyeWorkgroupFile') {
             $object->fixOwner();
             $owner = UMManager::getInstance()->getUserByName($object->getOwner());
         } else {
             throw $e;
         }
     }
     $group = UMManager::getInstance()->getGroupByName($object->getGroup());
     $accessGranted = false;
     $actionText = '';
     foreach ($permission->getActions() as $action) {
         if ($action == 'admin') {
             if ($eyeosUser->getName() != $object->getOwner()) {
                 throw new EyeAccessControlException('Only the owner ' . $object->getOwner() . ' has admin rights for file ' . $object->getPath() . '.');
             }
             continue;
         } else {
             if ($action == 'read') {
                 $ref = 0400;
                 $actionText = 'Read';
             } else {
                 if ($action == 'write') {
                     $ref = 0200;
                     $actionText = 'Write';
                 } else {
                     if ($action == 'execute') {
                         $ref = 0100;
                         $actionText = 'Execution';
                     } else {
                         // the given action is not supported by this handler
                         $this->failureException = new EyeHandlerFailureException('Unknown action received: ' . $action . '. Wrong configuration?');
                         return false;
                     }
                 }
             }
         }
         //owner
         if ($eyeosUser->getId() == $owner->getId()) {
             if ($ref & $objectPermissions) {
                 $accessGranted = true;
                 continue;
             } else {
                 throw new EyeAccessControlException($actionText . ' access denied to user ' . $eyeosUser->getName() . ' for file ' . $object->getPath() . ' (insufficient permissions).');
             }
         } else {
             $ref = $ref >> 3;
             //group
             if ($context->getSubject()->getPrincipals()->contains($group)) {
                 if ($ref & $objectPermissions) {
                     $accessGranted = true;
                     continue;
                 } else {
                     throw new EyeAccessControlException($actionText . ' access denied to user ' . $eyeosUser->getName() . ' for file ' . $object->getPath() . ' (insufficient permissions).');
                 }
             } else {
                 $ref = $ref >> 3;
                 //others
                 if ($ref & $objectPermissions) {
                     $accessGranted = true;
                     continue;
                 } else {
                     throw new EyeAccessControlException($actionText . ' access denied to user ' . $eyeosUser->getName() . ' for file ' . $object->getPath() . ' (insufficient permissions).');
                 }
             }
         }
     }
     if (self::$Logger->isInfoEnabled()) {
         self::$Logger->info('Access granted to user ' . $eyeosUser->getName() . ' for actions "' . $permission->getActionsAsString() . '" on file ' . $object->getPath() . '.');
     }
     return true;
 }
 /**
  * TODO
  * 
  * @param mixed $object
  * @param IPermission $permission
  * @param LoginContext $context
  * @return bool TRUE if the handler performed the permission check successfully, FALSE otherwise.
  * 
  * @throws EyeInvalidArgumentException
  * @throws EyeUnexpectedValueException
  * @throws EyeAccessControlException
  */
 public function checkPermission($object, IPermission $permission, LoginContext $context)
 {
     if (!$object instanceof IShareable) {
         throw new EyeInvalidArgumentException('$object must be an IShareable.');
     }
     if ($object->getId(false) === null) {
         $this->failureException = new EyeHandlerFailureException('$object has no ID and though is probably not currently shared.');
         return false;
     }
     try {
         $eyeosUser = $context->getEyeosUser();
     } catch (EyeNullPointerException $e) {
         $this->failureException = new EyeHandlerFailureException('No eyeos user found in login context.');
         return false;
     }
     // General sharing actions (addCollaborator, removeCollaborator, updateCollaborator)
     $actions = $permission->getActions();
     if (in_array('addcollaborator', $actions) || in_array('removecollaborator', $actions) || in_array('updatecollaborator', $actions)) {
         // currently, only the owner can perform those actions
         if ($eyeosUser->getId() != $object->getShareOwner()->getId()) {
             self::$Logger->info('Access denied to non-owner user ' . $eyeosUser->getName() . ' for actions "' . $permission->getActionsAsString() . '" on object ' . $object->getId() . '.');
             throw new EyeAccessControlException('Only the owner of the object can perform that kind of actions (' . $permission->getActionsAsString() . ').');
         }
         self::$Logger->debug('Access granted to owner ' . $eyeosUser->getName() . ' for actions "' . $permission->getActionsAsString() . '" on object ' . $object->getId() . '.');
         return true;
     }
     // Object-dependant sharing actions
     try {
         $shareInfos = SharingManager::getInstance()->getAllShareInfo($object);
     } catch (Exception $e) {
         $logger = Logger::getLogger('system.services.Security.ShareableObjectSecurityHandler');
         $logger->warn('Cannot retrieve shareinfo on object with ID: ' . $object->getId(false));
         if ($logger->isDebugEnabled()) {
             $logger->debug(ExceptionStackUtil::getStackTrace($e, false));
         } else {
             $logger->warn('Exception message: ' . $e->getMessage());
         }
         $this->failureException = new EyeHandlerFailureException('Cannot retrieve shareinfo on object with ID: ' . $object->getId(false) . ': ' . $e->getMessage());
         return false;
     }
     foreach ($shareInfos as $shareInfo) {
         $collaborator = $shareInfo->getCollaborator();
         //$collaborator is a group
         if ($collaborator instanceof IGroup) {
             // "is the subject in the current login context representative of the group collaborator?"
             if (in_array($collaborator, $context->getSubject()->getPrincipals())) {
                 if ($shareInfo->getPermissions()->implies($permission)) {
                     return true;
                 } else {
                     throw new EyeAccessControlException('$object permission actions (' . $shareInfo->getPermissions()->getActionsAsString() . ') ' . 'do not imply requested permission (' . $permission->getActionsAsString() . ') for collaborator ' . $eyeosUser->getName() . '');
                 }
             }
         } else {
             if ($shareInfo->getCollaborator()->getId() == $eyeosUser->getId()) {
                 if ($shareInfo->getPermissions()->implies($permission)) {
                     return true;
                 } else {
                     throw new EyeAccessControlException('$object permission actions (' . $shareInfo->getPermissions()->getActionsAsString() . ') ' . 'do not imply requested permission (' . $permission->getActionsAsString() . ') for collaborator ' . $eyeosUser->getName() . '');
                 }
             }
         }
     }
     // No matching collaborator found => this module is not applicable to the current check => set it as FAILED
     $this->failureException = new EyeHandlerFailureException('No matching collaborator found for object with ID ' . $object->getId(false) . '.');
     return false;
 }
 /**
  * TODO
  * 
  * @param mixed $object
  * @param IPermission $permission
  * @param LoginContext $context
  * @return bool TRUE if the handler performed the permission check successfully, FALSE otherwise.
  * 
  * @throws EyeInvalidArgumentException
  * @throws EyeAccessControlException
  */
 public function checkPermission($object, IPermission $permission, LoginContext $context)
 {
     if (!$object instanceof AbstractEyeosWorkgroup && !$object instanceof EyeosUserWorkgroupAssignation) {
         throw new EyeInvalidArgumentException('$object must be an AbstractEyeosWorkgroup or an EyeosUserWorkgroupAssignation.');
     }
     // $object is a Workgroup => check for actions: Create, Update, Delete
     if ($object instanceof AbstractEyeosWorkgroup) {
         $wgManagersGroups = UMManager::getInstance()->getGroupByName('wg-managers');
         // The user must be member of the system group "wg-managers"
         if (!$context->getSubject()->getPrincipals()->contains($wgManagersGroups)) {
             throw new EyeAccessControlException('The specified action requires privileges of group "wg-managers".');
         }
         // Update or Delete? Must be owner
         if (in_array('update', $permission->getActions()) || in_array('delete', $permission->getActions())) {
             try {
                 $eyeosUser = $context->getEyeosUser();
             } catch (EyeNullPointerException $e) {
                 $this->failureException = new EyeHandlerFailureException('No eyeos user found in login context.');
                 return false;
             }
             if ($object->getOwnerId() != $eyeosUser->getId()) {
                 throw new EyeAccessControlException('Only the owner of the workgroup can perform the requested action(s): ' . $permission->getActionsAsString() . '.');
             }
         }
         return true;
     } else {
         try {
             $eyeosUser = $context->getEyeosUser();
         } catch (EyeNullPointerException $e) {
             $this->failureException = new EyeHandlerFailureException('No eyeos user found in login context.');
             return false;
         }
         try {
             $workgroup = UMManager::getInstance()->getWorkgroupById($object->getWorkgroupId());
         } catch (EyeNoSuchWorkgroupException $e) {
             throw new EyeAccessControlException('Unknown workgroup with ID "' . $object->getWorkgroupId() . '".', 0, $e);
         }
         // Retrieve the role of the current user in the workgroup
         $currentUserAssignation = UMManager::getInstance()->getNewUserWorkgroupAssignationInstance();
         $currentUserAssignation->setUserId($eyeosUser->getId());
         $currentUserAssignation->setWorkgroupId($object->getWorkgroupId());
         $currentUserAssignation = current(UMManager::getInstance()->getAllUserWorkgroupAssignations($currentUserAssignation));
         foreach ($permission->getActions() as $action) {
             // Add to workgroup
             if ($action == 'addtoworkgroup') {
                 // If the workgroup's privacy mode is OPEN
                 if ($workgroup->getPrivacyMode() === WorkgroupConstants::PRIVACY_OPEN) {
                     // If the current user is the one joining the workgroup
                     if ($eyeosUser->getId() == $object->getUserId()) {
                         // Check for illegal role
                         if ($object->getRole() === WorkgroupConstants::ROLE_OWNER && $workgroup->getOwnerId() != $object->getUserId() || $object->getRole() === WorkgroupConstants::ROLE_ADMIN) {
                             throw new EyeAccessControlException('Access denied to non-member of workgroup "' . $workgroup->getName() . '": cannot join a workgroup as owner or admin.');
                         }
                         return true;
                     } else {
                         // If the current user is not a member, exit here
                         if ($currentUserAssignation === false) {
                             throw new EyeAccessControlException('Access denied to non-member of workgroup "' . $workgroup->getName() . '" for action(s): ' . $permission->getActionsAsString() . '.');
                         }
                         // If the current user is the owner or an admin, he has the right to INVITE
                         if ($currentUserAssignation->getRole() !== WorkgroupConstants::ROLE_OWNER && $currentUserAssignation->getRole() !== WorkgroupConstants::ROLE_ADMIN) {
                             throw new EyeAccessControlException('Access denied to non-admin of workgroup "' . $workgroup->getName() . '" for action(s): ' . $permission->getActionsAsString() . '.');
                         }
                         if ($object->getStatus() !== WorkgroupConstants::STATUS_INVITED) {
                             throw new EyeAccessControlException('Access denied to admin of workgroup "' . $workgroup->getName() . '": can only invite a member into the workgroup.');
                         }
                         return true;
                     }
                 } else {
                     if ($workgroup->getPrivacyMode() === WorkgroupConstants::PRIVACY_ONREQUEST) {
                         // If the current user is the one joining the workgroup
                         if ($eyeosUser->getId() == $object->getUserId()) {
                             // Check for illegal role
                             if ($object->getRole() === WorkgroupConstants::ROLE_OWNER && $workgroup->getOwnerId() != $object->getUserId() || $object->getRole() === WorkgroupConstants::ROLE_ADMIN) {
                                 throw new EyeAccessControlException('Access denied to non-member of workgroup "' . $workgroup->getName() . '": cannot apply for membership of workgroup ' . $workgroup->getName() . ' as owner or admin.');
                             }
                             // The status must be PENDING
                             if ($workgroup->getOwnerId() != $object->getUserId() && $object->getStatus() !== WorkgroupConstants::STATUS_PENDING) {
                                 throw new EyeAccessControlException('Access denied to non-member of workgroup "' . $workgroup->getName() . '": can only apply for membership of workgroup ' . $workgroup->getName() . '.');
                             }
                             return true;
                         } else {
                             // If the current user is not a member, exit here
                             if ($currentUserAssignation === false) {
                                 throw new EyeAccessControlException('Access denied to non-member of workgroup "' . $workgroup->getName() . '" for action(s): ' . $permission->getActionsAsString() . '.');
                             }
                             // If the current user is the owner or an admin, he has the right to INVITE
                             if ($currentUserAssignation->getRole() !== WorkgroupConstants::ROLE_OWNER && $currentUserAssignation->getRole() !== WorkgroupConstants::ROLE_ADMIN) {
                                 throw new EyeAccessControlException('Access denied to non-admin of workgroup "' . $workgroup->getName() . '" for action(s): ' . $permission->getActionsAsString() . '.');
                             }
                             if ($object->getStatus() !== WorkgroupConstants::STATUS_INVITED) {
                                 throw new EyeAccessControlException('Access denied to admin of workgroup "' . $workgroup->getName() . '": can only invite a member into the workgroup.');
                             }
                             return true;
                         }
                     } else {
                         if ($workgroup->getPrivacyMode() === WorkgroupConstants::PRIVACY_ONINVITATION) {
                             // If the current user is the one joining the workgroup
                             if ($eyeosUser->getId() == $object->getUserId()) {
                                 // If the owner joins his workgroup (at creation), access granted
                                 if ($eyeosUser->getId() == $workgroup->getOwnerId()) {
                                     return true;
                                 }
                                 throw new EyeAccessControlException('Access denied to non-member of workgroup "' . $workgroup->getName() . '": cannot apply for membership of workgroup ' . $workgroup->getName() . ', access is on invitation only.');
                             } else {
                                 // If the current user is not a member, exit here
                                 if ($currentUserAssignation === false) {
                                     throw new EyeAccessControlException('Access denied to non-member of workgroup "' . $workgroup->getName() . '" for action(s): ' . $permission->getActionsAsString() . '.');
                                 }
                                 // If the current user is the owner or an admin, he has the right to INVITE
                                 if ($currentUserAssignation->getRole() !== WorkgroupConstants::ROLE_OWNER && $currentUserAssignation->getRole() !== WorkgroupConstants::ROLE_ADMIN) {
                                     throw new EyeAccessControlException('Access denied to non-admin of workgroup "' . $workgroup->getName() . '" for action(s): ' . $permission->getActionsAsString() . '.');
                                 }
                                 if ($object->getStatus() !== WorkgroupConstants::STATUS_INVITED) {
                                     throw new EyeAccessControlException('Access denied to admin of workgroup "' . $workgroup->getName() . '": can only invite a member into the workgroup.');
                                 }
                                 return true;
                             }
                         }
                     }
                 }
             } else {
                 if ($action == 'removefromworkgroup') {
                     // If the current user is the one leaving the workgroup
                     if ($eyeosUser->getId() == $object->getUserId()) {
                         return true;
                     }
                     // if the user is not a member, exit here
                     if ($currentUserAssignation === false) {
                         throw new EyeAccessControlException('Access denied to non-member of workgroup "' . $workgroup->getName() . '" for action(s): ' . $permission->getActionsAsString() . '.');
                     }
                     if ($currentUserAssignation->getRole() !== WorkgroupConstants::ROLE_OWNER && $currentUserAssignation->getRole() !== WorkgroupConstants::ROLE_ADMIN) {
                         throw new EyeAccessControlException('Access denied to non-admin of workgroup "' . $workgroup->getName() . '" for action(s): ' . $permission->getActionsAsString() . '.');
                     }
                     return true;
                 } else {
                     if ($action == 'update') {
                         // if the user is not a member, exit here
                         if ($currentUserAssignation === false) {
                             throw new EyeAccessControlException('Access denied to non-member of workgroup "' . $workgroup->getName() . '" for action(s): ' . $permission->getActionsAsString() . '.');
                         }
                         // Current user is the one from the assignation $object,
                         // and the transition is from "invited" to "member" => access granted
                         if ($eyeosUser->getId() == $currentUserAssignation->getUserId() && $currentUserAssignation->getStatus() === WorkgroupConstants::STATUS_INVITED && $object->getStatus() === WorkgroupConstants::STATUS_MEMBER) {
                             return true;
                         } else {
                             if ($currentUserAssignation->getRole() !== WorkgroupConstants::ROLE_OWNER && $currentUserAssignation->getRole() !== WorkgroupConstants::ROLE_ADMIN) {
                                 throw new EyeAccessControlException('Access denied to non-admin of workgroup "' . $workgroup->getName() . '" for action(s): ' . $permission->getActionsAsString() . '.');
                             }
                             return true;
                         }
                     } else {
                         // Unknown action
                         $this->failureException = new EyeHandlerFailureException('Unknown action specified: ' . $action);
                         return false;
                     }
                 }
             }
         }
     }
 }
 /**
  * TODO
  * 
  * @param mixed $object
  * @param IPermission $permission
  * @param LoginContext $context
  * @return bool TRUE if the handler performed the permission check successfully, FALSE otherwise.
  * 
  * @throws EyeInvalidArgumentException
  * @throws EyeUnexpectedValueException
  * @throws EyeAccessControlException
  */
 public function checkPermission($object, IPermission $permission, LoginContext $context)
 {
     if (!$object instanceof EyeosApplicationDescriptor) {
         throw new EyeInvalidArgumentException('$object must be an EyeosApplicationDescriptor.');
     }
     try {
         $eyeosUser = $context->getEyeosUser();
     } catch (EyeNullPointerException $e) {
         $this->failureException = new EyeHandlerFailureException('No eyeos user found in login context.');
         return false;
     }
     $meta = $object->getMeta();
     if ($meta === null) {
         throw new EyeNullPointerException('$meta cannot be null.');
     }
     $sysParams = $meta->get('eyeos.application.systemParameters');
     // Extract owner, group and permissions from application's metadata
     try {
         $owner = UMManager::getInstance()->getUserByName($sysParams['owner']);
     } catch (EyeNoSuchPrincipalException $e) {
         $this->failureException = new EyeHandlerFailureException('Unknown owner "' . $owner . '".');
         return false;
     }
     try {
         $group = UMManager::getInstance()->getGroupByName($sysParams['group']);
     } catch (EyeNoSuchPrincipalException $e) {
         $this->failureException = new EyeHandlerFailureException('Unknown group "' . $group . '".');
         return false;
     }
     try {
         $perms = AdvancedPathLib::permsToOctal($sysParams['permissions']);
     } catch (Exception $e) {
         $this->failureException = new EyeHandlerFailureException('"' . $perms . '" is not a valid octal UNIX permission for application ' . $object->getName() . '.');
         return false;
     }
     // Loop on actions (but here we currently know the action "execute" only)
     $accessGranted = false;
     $actionText = '';
     foreach ($permission->getActions() as $action) {
         if ($action == 'execute') {
             $ref = 0100;
             $actionText = 'Execution';
         } else {
             // the given action is not supported by this handler
             $this->failureException = new EyeHandlerFailureException('Unknown action received: ' . $action . '.');
             return false;
         }
         //owner
         if ($eyeosUser->getId() == $owner->getId()) {
             if ($ref & $perms) {
                 $accessGranted = true;
                 continue;
             } else {
                 throw new EyeAccessControlException($actionText . ' access denied to user ' . $eyeosUser->getName() . ' for application ' . $object->getName() . ' (insufficient permissions).');
             }
         } else {
             $ref = $ref >> 3;
             //group
             if ($context->getSubject()->getPrincipals()->contains($group)) {
                 if ($ref & $perms) {
                     $accessGranted = true;
                     continue;
                 } else {
                     throw new EyeAccessControlException($actionText . ' access denied to user ' . $eyeosUser->getName() . ' for application ' . $object->getName() . ' (insufficient permissions).');
                 }
             } else {
                 $ref = $ref >> 3;
                 //others
                 if ($ref & $perms) {
                     $accessGranted = true;
                     continue;
                 } else {
                     throw new EyeAccessControlException($actionText . ' access denied to user ' . $eyeosUser->getName() . ' for application ' . $object->getName() . ' (insufficient permissions).');
                 }
             }
         }
     }
     if (self::$Logger->isInfoEnabled()) {
         self::$Logger->info('Access granted to user ' . $eyeosUser->getName() . ' for actions "' . $permission->getActionsAsString() . '" on application ' . $object->getName() . '.');
     }
     return true;
 }
 /**
  * TODO
  * 
  * @param mixed $object
  * @param IPermission $permission
  * @param LoginContext $context
  * @return bool TRUE if the handler performed the permission check successfully, FALSE otherwise.
  * 
  * @throws EyeInvalidArgumentException
  * @throws EyeUnexpectedValueException
  * @throws EyeAccessControlException
  */
 public function checkPermission($object, IPermission $permission, LoginContext $context)
 {
     if (!$object instanceof EyeosPrincipalGroupAssignation) {
         throw new EyeInvalidArgumentException('$object must be a EyeosPrincipalGroupAssignation.');
     }
     try {
         $eyeosUser = $context->getEyeosUser();
     } catch (EyeNullPointerException $e) {
         $this->failureException = new EyeHandlerFailureException('No eyeos user found in login context.');
         return false;
     }
     try {
         $principal = UMManager::getInstance()->getPrincipalById($object->getPrincipalId());
     } catch (EyeNoSuchPrincipalException $e) {
         $actions = $permission->getActions();
         if (in_array('removefromgroup', $actions)) {
             // The principal we want to remove from the group is not found
             // => we can delete assignation safely, whoever we are
             return true;
         }
     }
     $group = UMManager::getInstance()->getPrincipalById($object->getGroupId());
     // Special processing for workgroup/master group assignations
     if ($principal instanceof IWorkgroup) {
         foreach ($permission->getActions() as $action) {
             switch ($action) {
                 case 'addtogroup':
                     if (!$context->getSubject()->getPrincipals()->contains($group)) {
                         throw new EyeAccessControlException('Cannot add workgroup "' . $principal->getName() . '" to group ' . $group->getName() . ': insufficient permissions.)');
                     }
                     break;
                 case 'removefromgroup':
                     if ($principal->getOwnerId() != $eyeosUser->getId()) {
                         throw new EyeAccessControlException('Cannot remove workgroup "' . $principal->getName() . '" from group ' . $group->getName() . ': insufficient permissions.)');
                     }
                     break;
             }
         }
         return true;
     }
     throw new EyeAccessControlException('Access denied to UM assignation (actions: ' . $permission->getActionsAsString() . ')');
 }