/** * 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 Process) { throw new EyeInvalidArgumentException('$object must be a Process.'); } $objectEyeosUser = null; try { $objectLoginContext = $object->getLoginContext(); if ($objectLoginContext !== null) { $objectEyeosUser = $objectLoginContext->getEyeosUser(); } } catch (EyeNullPointerException $e) { } // The process has no eyeos user associated to it: access granted if ($objectEyeosUser === null) { return true; } if (in_array('kill', $permission->getActions())) { foreach ($context->getSubject()->getPrincipals() as $principal) { if ($principal instanceof AbstractEyeosUser && $principal->getId() == $objectEyeosUser->getId()) { return true; } } throw new EyeAccessControlException('Cannot kill process "' . $object->getName() . '"[' . $object->getPid() . '](' . $objectEyeosUser->getName() . ') as ' . $context->getEyeosUser()->getName() . ': not the owner.'); } return true; }
/** * Executed once before each test method. */ public function setUp() { if (self::$InitProcessToRestore === null) { self::$InitProcessToRestore = ProcManager::getInstance()->getCurrentProcess(); } $this->fixture_file1_path = USERS_PATH . '/john/' . USERS_FILES_DIR . '/myHomeFile.ext'; $this->fixture_metafile1_path = USERS_PATH . '/john/' . USERS_METAFILES_DIR . '/' . USERS_FILES_DIR . '/myHomeFile.ext.xml'; $this->fixture_file2_path = EYEOS_TESTS_TMP_PATH . '/mySysFile.ext'; $this->fixture_dir1_path = USERS_PATH . '/john/' . USERS_FILES_DIR . '/myHomeDir'; $this->fixture_dir2_path = EYEOS_TESTS_TMP_PATH . '/mySysDir'; $this->group = UMManager::getGroupByName(SERVICE_UM_DEFAULTUSERSGROUP); if (!self::$AliceCreated) { try { //create group "wonderland" $wonderland = UMManager::getInstance()->getNewGroupInstance(); $wonderland->setName('wonderland'); UMManager::getInstance()->createGroup($wonderland); } catch (EyeGroupAlreadyExistsException $e) { } try { //create user "alice" $alice = UMManager::getInstance()->getNewUserInstance(); $alice->setName('alice'); $alice->setPassword('alice', true); $alice->setPrimaryGroupId($wonderland->getId()); UMManager::getInstance()->createUser($alice); } catch (EyeUserAlreadyExistsException $e) { } self::$AliceCreated = true; } AdvancedPathLib::rmdirs(USERS_PATH . '/john/' . USERS_FILES_DIR, true); AdvancedPathLib::rmdirs(USERS_PATH . '/john/' . USERS_METAFILES_DIR, true); if (!is_dir(EYEOS_TESTS_TMP_PATH)) { mkdir(EYEOS_TESTS_TMP_PATH, 0777, true); } AdvancedPathLib::rmdirs(EYEOS_TESTS_TMP_PATH, true); $this->fixture_file1 = FSI::getFile('home://~john/myHomeFile.ext'); file_put_contents($this->fixture_file1_path, 'some content'); $this->fixture_file2 = FSI::getFile('sys:///tests/tmp/mySysFile.ext'); file_put_contents($this->fixture_file2_path, 'some other content'); $this->fixture_dir1 = FSI::getFile('home://~john/myHomeDir'); if (!is_dir($this->fixture_dir1_path)) { mkdir($this->fixture_dir1_path); } $this->fixture_dir2 = FSI::getFile('sys:///tests/tmp/mySysDir'); if (!is_dir($this->fixture_dir2_path)) { mkdir($this->fixture_dir2_path); } $proc = new Process('example'); $loginContext = new LoginContext('example', new Subject()); $loginContext->getSubject()->getPrivateCredentials()->append(new EyeosPasswordCredential('john', 'john')); $loginContext->login(); $proc->setLoginContext($loginContext); ProcManager::getInstance()->execute($proc); self::$MyProcPid = $proc->getPid(); }
/** * 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) { $contextGroupsNames = array(); foreach ($context->getSubject()->getPrincipals() as $principal) { if ($principal instanceof EyeosGroup) { $contextGroupsNames[] = $principal->getName(); } } foreach ($this->groups as $refGroup) { if (!in_array($refGroup, $contextGroupsNames, true)) { throw new EyeAccessControlException('The specified action requires privileges of group "' . $refGroup . '".'); } } return true; }
/** * Test if the callback constructor works as expected. * * @return void */ public function testConstructor() { // prepare the login module configuration mock $loginModuleConfigurationMock = $this->getMockBuilder('AppserverIo\\Psr\\Security\\Auth\\Login\\LoginModuleConfigurationInterface')->setMethods(get_class_methods('AppserverIo\\Psr\\Security\\Auth\\Login\\LoginModuleConfigurationInterface'))->getMock(); $loginModuleConfigurationMock->expects($this->once())->method('getType')->willReturn('LoginModules\\MyLoginModuleImpl'); $loginModuleConfigurationMock->expects($this->once())->method('getParamsAsArray')->willReturn(array('principalClass' => 'Principals\\MyPrincipalImp')); $loginModuleConfigurationMock->expects($this->once())->method('getFlag')->willReturn(LoginModuleConfigurationInterface::REQUIRED); // prepare the auth configuration mock $authConfigurationMock = $this->getMockBuilder('AppserverIo\\Psr\\Security\\Auth\\Login\\AuthConfigurationInterface')->setMethods(get_class_methods('AppserverIo\\Psr\\Security\\Auth\\Login\\AuthConfigurationInterface'))->getMock(); $authConfigurationMock->expects($this->once())->method('getLoginModules')->willReturn(array($loginModuleConfigurationMock)); // prepare the mocks for the login context $subjectMock = $this->getMock('AppserverIo\\Psr\\Security\\Auth\\Subject'); $callbackHandlerMock = $this->getMock('AppserverIo\\Psr\\Security\\Auth\\Callback\\CallbackHandlerInterface'); $configurationMock = $this->getMockBuilder('AppserverIo\\Psr\\Security\\Auth\\Login\\SecurityDomainConfigurationInterface')->setMethods(get_class_methods('AppserverIo\\Psr\\Security\\Auth\\Login\\SecurityDomainConfigurationInterface'))->getMock(); $configurationMock->expects($this->once())->method('getAuthConfig')->willReturn($authConfigurationMock); // initialize a new test instance $loginContext = new LoginContext($subjectMock, $callbackHandlerMock, $configurationMock); // test the subject $this->assertSame($loginContext->getSubject(), $subjectMock); }
/** * 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 WorkgroupMetaData) { throw new EyeInvalidArgumentException('$object must be a PrincipalMetaData.'); } if (!$permission instanceof MetaDataPermission) { throw new EyeInvalidArgumentException('$permission must be a MetaDataPermission.'); } $reqActions = $permission->getActions(); // WRITE and DELETE require special privileges (owner or admin) if (in_array('delete', $reqActions) || in_array('write', $reqActions)) { $workgroup = $permission->getRelatedObject(); try { $eyeosUser = $context->getEyeosUser(); } catch (EyeNullPointerException $e) { $this->failureException = new EyeHandlerFailureException('No eyeos user found in login context.'); return false; } // The current user is not the owner, search for the assignation to find his role if ($workgroup->getOwnerId() != $eyeosUser->getId()) { // First of all, is the current user member of the workgroup? if (!$context->getSubject()->getPrincipals()->contains($workgroup)) { throw new EyeAccessControlException('Access denied to the metadata of workgroup "' . $workgroup->getName() . '": not a member.'); } $assignation = UMManager::getInstance()->getNewUserWorkgroupAssignationInstance(); $assignation->setUserId($eyeosUser->getId()); $assignation->setWorkgroupId($workgroup->getId()); $assignation = current(UMManager::getInstance()->getAllUserWorkgroupAssignations($assignation)); if ($assignation === false) { throw new EyeUnexpectedValueException('Wrong assignation.'); } if ($assignation->getRole() != WorkgroupConstants::ROLE_ADMIN) { throw new EyeAccessControlException('Access denied: Only the owner or the admin of the workgroup can write or delete specified resource.'); } } } return true; }
public function setUp() { if (self::$InitProcessToRestore === null) { self::$InitProcessToRestore = ProcManager::getInstance()->getCurrentProcess(); } try { UMManager::getInstance()->deletePrincipal(UMManager::getInstance()->getUserByName('fakeUser')); } catch (EyeNoSuchUserException $e) { } try { UMManager::getInstance()->deletePrincipal(UMManager::getInstance()->getGroupByName('fakeGroup')); } catch (EyeNoSuchGroupException $e) { } $this->group = UMManager::getInstance()->getNewGroupInstance(); $this->group->setName('fakeGroup'); UMManager::getInstance()->createGroup($this->group); $this->idGroup = $this->group->getId(); $this->user = UMManager::getInstance()->getNewUserInstance(); $this->user->setName('fakeUser'); $this->user->setPassword('fakePassword', true); $this->user->setPrimaryGroupId($this->group->getId()); UMManager::getInstance()->createUser($this->user); $this->idUser = $this->user->getId(); $proc = new Process('example'); $loginContext = new LoginContext('example', new Subject()); $loginContext->getSubject()->getPrivateCredentials()->append(new EyeosPasswordCredential('fakeUser', 'fakePassword')); $loginContext->login(); $proc->setLoginContext($loginContext); ProcManager::getInstance()->execute($proc); self::$MyProcPid = $proc->getPid(); $this->fixture_file_path = USERS_PATH . '/fakeUser/' . USERS_FILES_DIR . '/testFile.txt'; $this->fixture_newFile_path = USERS_PATH . '/fakeUser/' . USERS_FILES_DIR . '/testDir/testFile2.txt'; $this->fixture_file = FSI::getFile('home://~fakeUser/testFile.txt'); $this->fixture_dir_path = USERS_PATH . '/fakeUser/' . USERS_FILES_DIR . '/testDir'; $this->fixture_dir = FSI::getFile('home://~fakeUser/testDir'); }
/** * 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; }
public function testSetProcessLoginContext() { $proc = new Process('example'); $this->fixture->execute($proc); $this->pids[] = $pid = $proc->getPid(); $this->loginContext = new LoginContext('init'); $this->fixture->setProcessLoginContext($pid, $this->loginContext); try { $this->fixture->setProcessLoginContext(ProcManager::MINPIDNUMBER - 1, $this->loginContext); $this->fail(); } catch (EyeProcException $e) { // normal situation } $processTable = $this->fixture->getProcessesTable(); $this->assertNotNull($processTable[$pid]->getLoginContext()); $this->fixture->setProcessLoginContext($pid, $this->loginContext); $processTable = $this->fixture->getProcessesTable(); $this->assertEquals($this->loginContext, $processTable[$pid]->getLoginContext()); $this->assertSame($this->loginContext, $processTable[$pid]->getLoginContext()); $this->tearDown(); $this->setUp(); /**** execute another process then change to a different login context ****/ $this->fixture->setCurrentProcess(self::$InitProcess); $initLoginContext = clone self::$InitProcess->getLoginContext(); $proc = new Process('example2'); $this->fixture->execute($proc); $this->pids[] = $pid2 = $proc->getPid(); $processTable = $this->fixture->getProcessesTable(); //check some necessary conditions before proceeding $this->assertTrue(is_array($processTable)); $this->assertTrue(isset($processTable[$pid2])); $this->assertTrue($processTable[$pid2] instanceof Process); $this->assertEquals('example2', $processTable[$pid2]->getName()); $pid = $processTable[$pid2]->getPid(); $this->assertNotNull($pid); $this->assertTrue(ProcManager::MINPIDNUMBER <= $pid); $this->assertTrue($pid <= ProcManager::MAXPIDNUMBER); $this->assertEquals($initLoginContext, $processTable[$pid2]->getLoginContext()); $this->assertNotNull($processTable[$pid2]->getLoginContext()->getEyeosUser()); $checknum = $processTable[$pid2]->getChecknum(); $this->assertNotNull($checknum); $this->assertTrue(ProcManager::MINCHECKNUMNUMBER <= $checknum); $this->assertTrue($checknum <= ProcManager::MAXCHECKNUMNUMBER); $this->assertNotNull($processTable[$pid2]->getTime()); //create a new login context with another user $subject = new Subject(); $newLoginContext = new LoginContext('example', $subject, $this->authConfig); $cred = new EyeosPasswordCredential('john', 'john'); $this->assertEquals(0, $newLoginContext->getSubject()->getPrivateCredentials()->count()); $newLoginContext->getSubject()->getPrivateCredentials()->append($cred); $newLoginContext->login(); $this->assertNotEquals($initLoginContext, $newLoginContext); $this->fixture->setProcessLoginContext($pid2, $newLoginContext); $this->assertNotEquals($initLoginContext, $proc->getLoginContext()); $this->assertEquals($newLoginContext, $proc->getLoginContext()); $this->assertSame($newLoginContext, $proc->getLoginContext()); $initUser = $this->fixture->getProcessByPid(self::$InitPid)->getLoginContext()->getEyeosUser(); $newUser = $this->fixture->getProcessByPid($pid2)->getLoginContext()->getEyeosUser(); $this->assertEquals('root', $initUser->getName()); $this->assertEquals('john', $newUser->getName()); }
/** * 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() . ')'); }
/** * 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) { // Retrieve the related workgroup in a "hard" way // ## DEPRECATED ## $workgroup = null; /*try { if (method_exists($object, 'getOwnerId')) { $workgroup = UMManager::getInstance()->getPrincipalById($object->getOwnerId()); } } catch (EyeNoSuchPrincipalException $e) {} try { if (!method_exists($object, 'getOwner')) { $workgroup = $object->getOwner(); if (!$workgroup instanceof AbstractEyeosWorkgroup) { $workgroup = UMManager::getInstance()->getPrincipalByName($workgroup); } } } catch (EyeNoSuchPrincipalException $e) {}*/ if (!$workgroup instanceof AbstractEyeosWorkgroup) { $this->failureException = new EyeHandlerFailureException(''); return false; } // Check if the current context contains our workgroup $wgIdx = $context->getSubject()->getPrincipals()->getIndex($workgroup); if ($wgIdx === false) { throw new EyeAccessControlException('The specified action requires privileges of workgroup "' . $workgroup->getName . '".'); } try { $eyeosUser = $context->getEyeosUser(); } catch (EyeNullPointerException $e) { self::$Logger->warn('Can\'t check permissions for object of class' . get_class($object) . ': no EyeosUser found in login context. Operation cancelled.'); return false; } // The current user is member of the workgroup, retrieve his permissions $assignation = UMManager::getInstance()->getNewUserWorkgroupAssignationInstance(); $assignation->setUserId($eyeosUser->getId()); $assignation->setWorkgroupId($workgroup->getId()); $assignation = current(UMManager::getInstance()->getAllUserWorkgroupAssignations($assignation)); if (!$assignation instanceof EyeosUserWorkgroupAssignation) { return false; } //if (in_array('')) //{ // TODO //} return true; }