Пример #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;
     }
 }
Пример #2
0
function __shutdown_test()
{
    try {
        // We need to be root to delete test principals
        $myUManager = UMManager::getInstance();
        $subject = new Subject();
        $loginContext = new LoginContext('init', $subject);
        $subject->getPrivateCredentials()->append(new EyeosPasswordCredential('root', 'root'));
        $loginContext->login();
        // we need a fake shutdown process
        $procManager = ProcManager::getInstance();
        $myProcess = new Process('shutdown');
        $procManager->execute($myProcess);
        $procManager->setProcessLoginContext($myProcess->getPid(), $loginContext);
        // clean deletion of users
        foreach (UMManager::getInstance()->getAllUsers() as $user) {
            UMManager::getInstance()->deletePrincipal($user);
        }
        AdvancedPathLib::rmdirs(USERS_PATH, true);
    } catch (Exception $e) {
        echo 'Uncaught exception on shutdown!' . "\n";
        ExceptionStackUtil::printStackTrace($e, false);
    }
}
Пример #3
0
 public function __toString()
 {
     return ExceptionStackUtil::getStackTrace($this, false);
 }
Пример #4
0
    MMapManager::getInstance()->processRequest($request, new MMapResponse());
    // Temporary - Should be moved into a function
    $__endRequestTime = microtime(true);
    $__endRequestMemory = memory_get_usage();
    $logger = Logger::getLogger('root.metrics');
    if ($logger->isInfoEnabled()) {
        $logger->info('Time: ' . sprintf('%01.2f', $__endRequestTime - $__startTime) . 's / Mem.: ' . sprintf('%01.2f', ($__endRequestMemory - $__startMemory) / 1024) . 'KB (Bootstrap Time: ' . sprintf('%01.2f', $__endBootstrapTime - $__startTime) . 's / Mem: ' . sprintf('%01.2f', ($__endBootstrapMemory - $__startMemory) / 1024) . 'KB) [' . $request->getUrl() . ']');
    }
} catch (Exception $e) {
    // Log and display the exception that reached this section
    // (this should normally *not* happen in a fully set-up production environment)
    // Log with log4php if available
    if (class_exists('Logger')) {
        $logger = Logger::getRootLogger();
        $logger->fatal('Uncaught exception detected in the root page! It is likely to come from the bootstrap.');
        $logger->fatal(ExceptionStackUtil::getStackTrace($e, false));
    }
    echo 'There is an error in this eyeOS installation, please contact the system administrator';
    exit;
}
//shutdown
Bootstrap::end();
/*
 *Changes the current work directory to EYE_ROOT
 */
function changeCWD()
{
    //since index.php is always below eyeROOT, we can do this instead to be includable from third party code
    $basedir = dirname(__FILE__) . '/';
    //change directory to EYE_ROOT
    chdir($basedir . REAL_EYE_ROOT);
Пример #5
0
 private static function loadService($service)
 {
     try {
         $servicePath = SERVICES_PATH . '/' . $service . '/';
         Bootstrap::load($servicePath . 'interface.php');
         $implementationsPath = $servicePath . '/' . IMPLEMENTATIONS_DIR . '/';
         $directory = new DirectoryIterator($implementationsPath);
         foreach ($directory as $fileInfo) {
             if ($fileInfo->isFile()) {
                 //					self::$Logger->debug('Loading service "' . $fileInfo->getFilename() . '"...');
                 Bootstrap::load($implementationsPath . $fileInfo->getFilename());
             }
         }
     } catch (Exception $e) {
         self::$Logger->error('Cannot load service "' . $service . '"');
         if (self::$Logger->isDebugEnabled()) {
             self::$Logger->debug(ExceptionStackUtil::getStackTrace($e, false));
         }
         throw new EyeBootstrapException('Cannot load service "' . $service . '".', 0, $e);
     }
 }
Пример #6
0
 public function processRequest(MMapRequest $request, MMapResponse $response, AppExecutionContext $appContext = null)
 {
     $status = ob_get_status();
     $response->getHeaders()->append('Content-type:text/javascript');
     if (isset($status['name']) && $status['name'] != 'ob_gzhandler') {
         ob_start("ob_gzhandler");
     }
     try {
         MMapManager::startSession();
         if (!$appContext instanceof AppExecutionContext) {
             $appContext = new AppExecutionContext();
             $appContext->initFromRequest($request);
         }
         $appDesc = $appContext->getApplicationDescriptor();
         // Check if the session has expired only if the application we want to execute is not "init" nor "logout"
         // FIXME: Not sure this way for checking session is the best here (maybe a flag in the metadata instead?)
         if ($appDesc->getName() != 'init' && $appDesc->getName() != 'logout') {
             MMapManager::checkSessionExpiration();
         }
         // Restore parent process if available
         try {
             $checknum = (int) $request->getGET('checknum');
             $procFather = ProcManager::getInstance()->getProcessByChecknum($checknum);
             ProcManager::getInstance()->setCurrentProcess($procFather);
             // Access control is based on current user, contained in the login context of
             // the current process, so we can only perform security checks when a process
             // is active.
             // In case no login context is defined, we can be sure that almost nothing unsafe
             // will be done, because this element is required in most of the operations.
             if ($procFather->getLoginContext() !== null) {
                 SecurityManager::getInstance()->checkExecute($appDesc);
             }
         } catch (EyeProcException $e) {
         }
         // Start process (PHP)
         $this->startProcess($appContext);
         // Append necessary scripts and execute JS code (actually, only append it to the $response body)
         $appDesc->executeJavascript($appContext, $response);
     } catch (Exception $e) {
         self::$Logger->error('Uncaught exception while processing request: ' . $request);
         self::$Logger->error('Exception message: ' . $e->getMessage());
         if (self::$Logger->isDebugEnabled()) {
             self::$Logger->debug(ExceptionStackUtil::getStackTrace($e, false));
         }
         // Special processing on session expiration
         if ($e instanceof EyeSessionExpiredException) {
             $controlMessageBodyRenderer = new ControlMessageBodyRenderer(ControlMessageBodyRenderer::TYPE_SESSION_EXPIRED);
         } else {
             // Remove incomplete process
             $proc = $appContext->getProcess();
             if ($proc instanceof Process) {
                 try {
                     ProcManager::getInstance()->kill($proc);
                 } catch (Exception $e) {
                     self::$Logger->error('Cannot kill incomplete process: ' . $proc);
                     self::$Logger->error('Exception message: ' . $e->getMessage());
                 }
             }
             $controlMessageBodyRenderer = new ControlMessageBodyRenderer(ControlMessageBodyRenderer::TYPE_EXCEPTION, $e);
         }
         // When using qx.io.ScriptLoader on the JS side, no callback proxy is available
         // to intercept control messages, so we're using a little workaround here by
         // calling directly eyeos._callbackProxyWithContent() with the exception summary
         // in argument.
         $responseContent = $controlMessageBodyRenderer->getRenderedBody();
         $response->setBody('eyeos._callbackProxyWithContent(null, null, null, ' . $responseContent . ');');
     }
     $this->handleClientMessageQueue($response);
 }
Пример #7
0
 private static final function getNextId()
 {
     try {
         $mutex = new MutexCompat();
         $mutex->init(LIB_IDGEN_SEMAPHORE_KEY, LIB_IDGEN_CONFIGURATION_PATH . '/idGen.lock');
         $mutex->acquire();
         if (file_exists(LIB_IDGEN_CONFIGURATION_PATH . '/idGen.txt')) {
             $id = (string) file_get_contents(LIB_IDGEN_CONFIGURATION_PATH . '/idGen.txt');
             if ('' !== $id) {
                 $intVal = hexdec($id);
             } else {
                 $intVal = 1;
             }
         } else {
             $intVal = 1;
         }
         if ($intVal == PHP_INT_MAX) {
             throw new EyeOverflowException('Cannot generate ID: integer limit reached!');
         }
         $newId = dechex($intVal + 1);
         file_put_contents(LIB_IDGEN_CONFIGURATION_PATH . '/idGen.txt', $newId);
         $mutex->release();
         unset($mutex);
         return $newId;
     } catch (Exception $e) {
         $logger = Logger::getLogger('system.libs.idGen');
         $logger->fatal('Unable to generate eyeID');
         $logger->fatal(ExceptionStackUtil::getStackTrace($e, false));
         throw $e;
     }
 }
Пример #8
0
 public function checkPermission($object, IPermission $perm, LoginContext $context = null)
 {
     try {
         if ($object === null) {
             throw new EyeNullPointerException('$object cannot be null.');
         }
         if ($perm === null) {
             throw new EyeNullPointerException('$perm cannot be null.');
         }
         if ($context === null) {
             $currentProcess = ProcManager::getInstance()->getCurrentProcess();
             if ($currentProcess === null) {
                 self::$Logger->warn('Cannot check permission on object of class ' . get_class($object) . ': No current process.');
                 throw new EyeAccessControlException('Access denied: No current process.');
             }
             $context = $currentProcess->getLoginContext();
             if ($context === null) {
                 //self::$Logger->warn('Cannot check permission on object of class ' . get_class($object) . ': No LoginContext found in current process.');
                 //throw new EyeAccessControlException('Access denied: No LoginContext found in current process.');
                 self::$Logger->info('Initializing blank login context for permission check on object of class ' . get_class($object) . '.');
                 $context = new LoginContext('eyeos-login', new Subject());
             }
         }
         $checker = new SecurityChecker();
         $checker->doCheck($object, $perm, $context);
     } catch (Exception $e) {
         self::$Logger->error('Cannot perform permission check: ' . $e->getMessage());
         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 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;
 }
 public function listen($manager)
 {
     $userId = ProcManager::getInstance()->getCurrentProcess()->getLoginContext()->getEyeosUser()->getId();
     $username = ProcManager::getInstance()->getCurrentProcess()->getLoginContext()->getEyeosUser()->getName();
     $subscriptionProvider = new SqlSubscriptionProvider();
     if ($subscriptionProvider->getSubscriptions($userId) == false) {
         /**
          * User try to listen message, but for same reason (connection problem, logout)
          * netSync delete subscriptions to this user.
          *
          * Stop LongPolling and notify client
          */
         echo "forceRefresh";
         exit;
     }
     //$myPressence = new Pressence();
     //$myPressence->markOnline($username, $manager);
     session_write_close();
     set_time_limit(0);
     ignore_user_abort(1);
     header('Cache-Control: no-cache, must-revalidate');
     header('Content-type: application/json');
     $Logger = Logger::getLogger('system.Frameworks.EyeosModules.NetSync');
     //one of every 20 loops, will update the pressence time
     //but the first one, should do it ever
     $loop = 20;
     while (1) {
         try {
             echo "\n";
             ob_flush();
             flush();
             if (connection_status() != CONNECTION_NORMAL) {
                 //Maybe user gone offline
                 sleep(35);
                 //Check if user is still connected
                 if (!$subscriptionProvider->isUserConnected($userId)) {
                     // if not notify to all contacts
                     $contacts = PeopleController::getInstance()->getAllContacts($userId);
                     $ids = array();
                     $myCometSender = new CometSenderLongPolling();
                     foreach ($contacts as $contact) {
                         $id = $contact->getRelation()->getSourceId();
                         if ($id == $userId) {
                             $id = $contact->getRelation()->getTargetId();
                         }
                         $message = new NetSyncMessage('status', 'offline', $id, $userId);
                         //TODO24 ultra hardcoded, we need some kind of php listeners here!
                         $myCometSender->send($message);
                     }
                     shell_exec('rm -rf ' . escapeshellarg(EYE_ROOT . '/' . USERS_DIR . '/' . utf8_basename($username) . '/files/.office/'));
                     $subscriptionProvider->removeAllSubscriptions($userId);
                 }
                 exit;
             }
             if ($loop == 20) {
                 $mySubscriptionProvider = new SqlSubscriptionProvider();
                 $mySubscriptionProvider->refreshPressence($userId);
                 $loop = 0;
             } else {
                 $loop++;
             }
             $mySubscriptionProvider = new SqlSubscriptionProvider();
             $channels = $mySubscriptionProvider->getSubscriptions($userId);
             $messageProvider = new CometSqlMessageProvider();
             if (is_array($channels)) {
                 $messages = $messageProvider->read($channels, $userId, $this->lastId);
                 if (is_array($messages) && count($messages) > 0) {
                     @session_start();
                     usort($messages, "customMessageComparation");
                     $_SESSION['comet']['lastid'] = $messages[count($messages) - 1]['id'];
                     //$Logger->debug("last message id: " . $_SESSION['comet']['lastid']);
                     //@todo use pseudo-random-related-to-tableid or something as transaction ID, no a id of table
                     return $messages;
                 }
             }
             sleep(1);
         } catch (Exception $e) {
             $logger = Logger::getLogger('netsync');
             $logger->fatal('Exception in netsync!');
             $logger->fatal(ExceptionStackUtil::getStackTrace($e, false));
             exit;
         }
     }
 }
Пример #11
0
 private function renderResponse(MMapResponse $response)
 {
     if (!$response->isValid()) {
         if (self::$Logger->isInfoEnabled()) {
             self::$Logger->info('Skipping invalid response: ' . $response);
         }
         return;
     }
     try {
         // headers
         foreach ($response->getHeaders() as $headerField) {
             self::$Logger->info($headerField);
             if (is_array($headerField)) {
                 if (isset($headerField[1])) {
                     if (isset($headerField[2])) {
                         header($headerField[0], $headerField[1], $headerField[2]);
                     } else {
                         header($headerField[0], $headerField[1]);
                     }
                 } else {
                     header($headerField[0]);
                 }
             } else {
                 //if ( !ob_get_status() ) {
                 header($headerField);
                 //}
             }
         }
         // body
         $bodyRenderer = $response->getBodyRenderer();
         if ($bodyRenderer !== null) {
             self::$Logger->info('Using BodyRenderer: ' . $bodyRenderer);
             $bodyRenderer->doRender();
         } else {
             self::$Logger->info('Using raw body');
             echo $response->getBody();
         }
     } catch (Exception $e) {
         self::$Logger->error('Exception caught while rendering response!');
         self::$Logger->error('Exception message: ' . $e->getMessage());
         if (self::$Logger->isDebugEnabled()) {
             self::$Logger->debug(ExceptionStackUtil::getStackTrace($e, false));
             self::$Logger->debug((string) $response);
         }
         // the exception will be finally caught by the general try/catch block in index.php
         throw $e;
     }
 }
Пример #12
0
 public function updateTag(ITag $tag, ITag $newTag)
 {
     SecurityManager::getInstance()->checkPermission($tag, new SimplePermission(null, array('update')));
     try {
         $this->getProvider()->updateTag($tag, $newTag);
     } catch (Exception $e) {
         self::$Logger->error('Unable to update tag "' . $tag . '": ' . $e->getMessage());
         if (self::$Logger->isDebugEnabled()) {
             self::$Logger->debug(ExceptionStackUtil::getStackTrace($e, false));
         }
         throw $e;
     }
 }
Пример #13
0
 /**
  * Kill a process, and remove it from the process table.
  *
  * @param Process $proc the process to be killed, the attribute <b>pid</b> should be filled with the process pid to kill
  * @throws EyeInvalidArgumentException If the arguments are incorrect
  * @throws EyeProcException If there is no such process with the given pid
  */
 public function kill(Process $proc)
 {
     try {
         $processTable = $this->getProcessesTable();
         $pid = $proc->getPid();
         if (!isset($processTable[$pid])) {
             throw new EyeProcException('Process $proc with PID ' . $pid . ' not found.');
         }
         SecurityManager::getInstance()->checkPermission($proc, new SimplePermission('', array('kill')));
         unset($processTable[$pid]);
         Kernel::enterSystemMode();
         $this->memoryManager->set('processTable', $processTable);
         Kernel::exitSystemMode();
         if ($this->currentProcess->getPid() == $pid) {
             $this->currentProcess = null;
         }
         $this->logger->debug('Process killed: ' . $proc);
         $this->fireEvent('processKilled', new ProcEvent($proc));
     } catch (Exception $e) {
         $this->logger->warn('Error killing process: ' . $proc . ' (' . $e->getMessage() . ')');
         if ($this->logger->isDebugEnabled()) {
             $this->logger->debug(ExceptionStackUtil::getStackTrace($e, false));
         }
         throw $e;
     }
 }