From 65769bd861adb9daf8b393e1b0451f52b796d726 Mon Sep 17 00:00:00 2001 From: Pranav Kant Date: Tue, 6 Jun 2017 21:31:47 +0530 Subject: [PATCH] Include support for X-LOOL-WOPI-Timestamp See for more detailed message: https://github.com/owncloud/richdocuments/pull/178 --- lib/Controller/WopiController.php | 23 ++++++++++++++++++++--- lib/helper.php | 16 ++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/lib/Controller/WopiController.php b/lib/Controller/WopiController.php index 537818b5..51425ea2 100644 --- a/lib/Controller/WopiController.php +++ b/lib/Controller/WopiController.php @@ -38,6 +38,9 @@ class WopiController extends Controller { /** @var IRootFolder */ private $rootFolder; + // Signifies LOOL that document has been changed externally in this storage + const LOOL_STATUS_DOC_CHANGED = 1010; + /** * @param string $appName * @param IRequest $request @@ -95,6 +98,7 @@ class WopiController extends Controller { 'UserFriendlyName' => $res['editor'] !== '' ? \OC_User::getDisplayName($res['editor']) : 'Guest user', 'UserCanWrite' => $res['canwrite'] ? true : false, 'PostMessageOrigin' => $res['server_host'], + 'LastModifiedTime' => Helper::toISO8601($file->getMtime()) ] ); } @@ -169,10 +173,23 @@ class WopiController extends Controller { return new JSONResponse([], Http::STATUS_FORBIDDEN); } + + try { /** @var File $file */ $userFolder = $this->rootFolder->getUserFolder($res['owner']); $file = $userFolder->getById($fileId)[0]; + + $wopiHeaderTime = $this->request->getHeader('X-LOOL-WOPI-Timestamp'); + if (!is_null($wopiHeaderTime) && $wopiHeaderTime != Helper::toISO8601($file->getMTime())) { + \OC::$server->getLogger()->debug('Document timestamp mismatch ! WOPI client says mtime {headerTime} but storage says {storageTime}', [ + 'headerTime' => $wopiHeaderTime, + 'storageTime' => Helper::toISO8601($file->getMtime()) + ]); + // Tell WOPI client about this conflict. + return new JSONResponse(['LOOLStatusCode' => self::LOOL_STATUS_DOC_CHANGED], Http::STATUS_CONFLICT); + } + $content = fopen('php://input', 'rb'); // Setup the FS which is needed to emit hooks (versioning). \OC_Util::tearDownFS(); @@ -181,11 +198,11 @@ class WopiController extends Controller { // Set the user to register the change under his name $editor = \OC::$server->getUserManager()->get($res['editor']); if (!is_null($editor)) { - \OC::$server->getUserSession()->setUser($editor); - } + \OC::$server->getUserSession()->setUser($editor); + } $file->putContent($content); - return new JSONResponse(); + return new JSONResponse(['LastModifiedTime' => Helper::toISO8601($file->getMtime())]); } catch (\Exception $e) { return new JSONResponse([], Http::STATUS_INTERNAL_SERVER_ERROR); } diff --git a/lib/helper.php b/lib/helper.php index d6632ae7..11c76b8e 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -11,6 +11,9 @@ namespace OCA\Richdocuments; +use \DateTime; +use \DateTimeZone; + class Helper { const APP_ID = 'richdocuments'; @@ -41,6 +44,19 @@ class Helper { ]; } + /** + * WOPI helper function to convert to ISO 8601 round-trip format. + * @param integer $time Must be seconds since unix epoch + */ + public static function toISO8601($time) + { + // TODO: Be more precise and don't ignore milli, micro seconds ? + $datetime = DateTime::createFromFormat('U', $time, new DateTimeZone('UTC')); + if ($datetime) + return $datetime->format('Y-m-d\TH:i:s.u\Z'); + + return false; + } public static function getNewFileName($view, $path, $prepend = ' '){ $fileNum = 1;