diff options
author | Ashod Nakashian <ashod.nakashian@collabora.co.uk> | 2016-03-09 05:15:44 +0300 |
---|---|---|
committer | Ashod Nakashian <ashod.nakashian@collabora.co.uk> | 2016-03-09 16:40:48 +0300 |
commit | be97780451e103d4b8faf28202d51998ec1d742e (patch) | |
tree | a040ae144883a7c756207ffd9bab573bcfd9214b | |
parent | 789d0050fb1da8c15bb5114dd217a3d77287284a (diff) |
WOPI Token table and database plumbing added
-rw-r--r-- | appinfo/database.xml | 49 | ||||
-rw-r--r-- | appinfo/info.xml | 2 | ||||
-rw-r--r-- | lib/db/wopi.php | 101 |
3 files changed, 151 insertions, 1 deletions
diff --git a/appinfo/database.xml b/appinfo/database.xml index 443a4f54..7d7c9fce 100644 --- a/appinfo/database.xml +++ b/appinfo/database.xml @@ -274,4 +274,53 @@ </declaration> </table> + <table> + <name>*dbprefix*richdocuments_wopi</name> + <declaration> + <field> + <name>id</name> + <type>integer</type> + <notnull>true</notnull> + <autoincrement>1</autoincrement> + <unsigned>true</unsigned> + <length>4</length> + <comments>Unique per token</comments> + </field> + <field> + <name>uid</name> + <type>text</type> + <length>64</length> + <comments>UserId - a textual user identifier (unique?)</comments> + </field> + <field> + <name>fileid</name> + <type>integer</type> + <notnull>true</notnull> + <length>4</length> + <comments>The unique ID of the file authorized</comments> + </field> + <field> + <name>path</name> + <type>text</type> + <notnull>true</notnull> + <length>512</length> + <comments>Relative to storage e.g. /welcome.odt</comments> + </field> + <field> + <name>token</name> + <type>text</type> + <default></default> + <notnull>true</notnull> + <length>32</length> + <comments>File access token</comments> + </field> + <field> + <name>expiry</name> + <type>integer</type> + <unsigned>true</unsigned> + <length>4</length> + <comments>Expiration time of the token</comments> + </field> + </declaration> + </table> </database> diff --git a/appinfo/info.xml b/appinfo/info.xml index 5d9b74a5..4db1815e 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -4,7 +4,7 @@ <name>Collabora Online Development Edition</name> <description>An ownCloud app to work with office documents</description> <licence>AGPL</licence> - <version>0.12.0</version> + <version>0.13.0</version> <author>Collabora Productivity based on work of Frank Karlitschek, Victor Dubiniuk</author> <bugs>https://www.collaboraoffice.com/</bugs> <repository type="git">git://gerrit.libreoffice.org/online.git</repository> diff --git a/lib/db/wopi.php b/lib/db/wopi.php new file mode 100644 index 00000000..306204d3 --- /dev/null +++ b/lib/db/wopi.php @@ -0,0 +1,101 @@ +<?php + +/** + * ownCloud - Richdocuments App + * + * @author Ashod Nakashian + * @copyright 2016 Ashod Nakashian ashod.nakashian@collabora.co.uk + * + * This file is licensed under the Affero General Public License version 3 or + * later. + */ + +namespace OCA\Richdocuments\Db; + +use \OCA\Richdocuments\Download; +use \OCA\Richdocuments\DownloadResponse; + +/** + * @method string generateFileToken() + * @method string getPathForToken() + */ + +class Wopi extends \OCA\Richdocuments\Db{ + + const DB_TABLE = '`*PREFIX*richdocuments_wopi`'; + + // Tokens expire after this many seconds (not defined by WOPI specs). + const TOKEN_LIFETIME_SECONDS = 30 * 60; + + protected $tableName = '`*PREFIX*richdocuments_wopi`'; + + protected $insertStatement = 'INSERT INTO `*PREFIX*richdocuments_wopi` (`uid`, `fileid`, `path`, `token`, `expiry`) + VALUES (?, ?, ?, ?, ?)'; + + protected $loadStatement = 'SELECT * FROM `*PREFIX*richdocuments_wopi` WHERE `token`= ?'; + + /* + * Given a fileId, generates a token + * and stores in the database. + * Returns the token. + */ + public function generateFileToken($fileId){ + $user = \OC_User::getUser(); + $view = new \OC\Files\View('/' . $user . '/'); + $path = $view->getPath($fileId); + + if (!$view->is_file($path)) { + throw new \Exception('Invalid fileId.'); + } + + $token = \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate(32, + \OCP\Security\ISecureRandom::CHAR_LOWER . \OCP\Security\ISecureRandom::CHAR_UPPER . + \OCP\Security\ISecureRandom::CHAR_DIGITS); + + \OC::$server->getLogger()->debug('Issuing token for {user} file {fileId}: {token}', + [ 'user' => $user, 'fileId' => $fileId, 'token' => $token ]); + + $wopi = new \OCA\Richdocuments\Db\Wopi([ + $user, + $fileId, + $path, + $token, + time() + self::TOKEN_LIFETIME_SECONDS + ]); + + if (!$wopi->insert()){ + throw new \Exception('Failed to add wopi token into database'); + } + + return $token; + } + + /* + * Given a token, validates it and + * constructs and validates the path. + * Returns the path, if valid, else false. + */ + public function getPathForToken($fileId, $token){ + + $wopi = new Wopi(); + $row = $wopi->loadBy('token', $token)->getData(); + \OC::$server->getLogger()->debug('Loaded WOPI Token record: {row}.', [ 'row' => $row ]); + + //TODO: validate. + if ($row['expiry'] > time() || $row['fileid'] !== $fileId){ + // Expired token! + //$wopi->deleteBy('id', $row['id']); + //return false; + } + + $user = $row['uid']; + $view = new \OC\Files\View('/' . $user . '/'); + $path = $row['path']; + + if (!$view->is_file($path)) { + throw new \Exception('Invalid file path.'); + } + + return array('user' => $user, 'path' => $path); + } +} |