Create a dummy memory session before signing in as user

Since this WOPI Put method is executed when loolwsd hits owncloud
server, it has no session or probably invalid session data. Even
though WOPI Put file operation initiated by loolwsd succeds, i.e
file is successfully put into owncloud storage and versioned, it
returns an HTTP 500 Internal server error as response to loolwsd
which causes problem on loolwsd side messing up its state.

Following trace can be observed in webserver's error logs after
HTTP 500 is returned:

PHP Fatal error:  Uncaught exception 'Exception' with message 'Session has been closed - no further changes to the session are allowed'
in /var/www/html/owncloud9/lib/private/session/internal.php:135
Stack trace:
 #0 /var/www/html/owncloud9/lib/private/session/internal.php(60): OC\\Session\\Internal->validateSession()
 #1 /var/www/html/owncloud9/lib/private/session/cryptosessiondata.php(150): OC\\Session\\Internal->set('encrypted_sessi...', 'e747091469b9905...')
 #2 /var/www/html/owncloud9/lib/private/session/cryptosessiondata.php(64): OC\\Session\\CryptoSessionData->close()
 #3 [internal function]: OC\\Session\\CryptoSessionData->__destruct()
 #4 {main}\n  thrown in /var/www/html/owncloud9/lib/private/session/internal.php on line 135

Creating a dummy memory session, setting it as current session,
and then setting the desired user session seems to address this
problem and does not emit HTTP 500 anymore.
pull/1/head
Pranav Kant 8 years ago
parent 5fde788a9e
commit e0da6fa8d1

@ -79,6 +79,37 @@ class DocumentController extends Controller {
return null;
}
/**
* Log the user with given $userid.
* This function should only be used from public controller methods where no
* existing session exists, for example, when loolwsd is directly calling a
* public method with its own access token. After validating the access
* token, and retrieving the correct user with help of access token, it can
* be set as current user with help of this method.
*
* @param string $userid
*/
private function loginUser($userid) {
$users = \OC::$server->getUserManager()->search($userid, 1, 0);
if (count($users) > 0) {
$user = array_shift($users);
if (strcasecmp($user->getUID(), $userid) === 0) {
// clear the existing sessions, if any
\OC::$server->getSession()->close();
// initialize a dummy memory session
$session = new \OC\Session\Memory('');
// wrap it
$cryptoWrapper = \OC::$server->getSessionCryptoWrapper();
$session = $cryptoWrapper->wrapSession($session);
// set our session
\OC::$server->setSession($session);
\OC::$server->getUserSession()->setUser($user);
}
}
}
private function responseError($message, $hint = ''){
$errors = array('errors' => array(array('error' => $message, 'hint' => $hint)));
$response = new TemplateResponse('', 'error', $errors, 'error');
@ -355,8 +386,6 @@ class DocumentController extends Controller {
\OC::$server->getLogger()->debug('Generating WOPI Token for file {fileId}, version {version}.', [ 'app' => $this->appName, 'fileId' => $fileId, 'version' => $version ]);
$row = new Db\Wopi();
$token = $row->generateFileToken($fileId, $version);
@ -503,15 +532,11 @@ class DocumentController extends Controller {
// Log-in as the user to regiser the change under her name.
$editorid = $res['editor'];
$users = \OC::$server->getUserManager()->search($editorid, 1, 0);
if (count($users) > 0)
{
$user = array_shift($users);
if (strcasecmp($user->getUID(),$editorid) === 0)
{
\OC::$server->getUserSession()->setUser($user);
}
}
// This call is made from loolwsd, so we need to initialize the
// session before we can make the user who opened the document
// login. This is necessary to make activity app register the
// change made to this file under this user's (editorid) name.
$this->loginUser($editorid);
// Set up the filesystem view for the owner (where the file actually is).
$userid = $res['owner'];
@ -530,6 +555,9 @@ class DocumentController extends Controller {
\OC_Util::tearDownFS();
// clear any session created before
\OC::$server->getSession()->close();
return array(
'status' => 'success'
);

Loading…
Cancel
Save