Move over to Entity/EntityMapper
* Use the AppFrameworks entities * Use the query builder * Pass Entities (with types) around * Remove old classes Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
This commit is contained in:
Родитель
c6ce323857
Коммит
958d1fe279
|
@ -22,10 +22,12 @@
|
|||
namespace OCA\Richdocuments\Controller;
|
||||
|
||||
use OC\Files\View;
|
||||
use OCA\Richdocuments\Db\WopiMapper;
|
||||
use OCA\Richdocuments\TokenManager;
|
||||
use OCA\Richdocuments\Db\Wopi;
|
||||
use OCA\Richdocuments\Helper;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\Files\File;
|
||||
|
@ -43,10 +45,12 @@ class WopiController extends Controller {
|
|||
private $urlGenerator;
|
||||
/** @var IConfig */
|
||||
private $config;
|
||||
/** @var ITokenManager */
|
||||
/** @var TokenManager */
|
||||
private $tokenManager;
|
||||
/** @var IUserManager */
|
||||
private $userManager;
|
||||
/** @var WopiMapper */
|
||||
private $wopiMapper;
|
||||
|
||||
// Signifies LOOL that document has been changed externally in this storage
|
||||
const LOOL_STATUS_DOC_CHANGED = 1010;
|
||||
|
@ -58,8 +62,9 @@ class WopiController extends Controller {
|
|||
* @param IRootFolder $rootFolder
|
||||
* @param IURLGenerator $urlGenerator
|
||||
* @param IConfig $config
|
||||
* @param ITokenManager $tokenManager
|
||||
* @param TokenManager $tokenManager
|
||||
* @param IUserManager $userManager
|
||||
* @param WopiMapper $wopiMapper
|
||||
*/
|
||||
public function __construct($appName,
|
||||
$UserId,
|
||||
|
@ -68,13 +73,15 @@ class WopiController extends Controller {
|
|||
IURLGenerator $urlGenerator,
|
||||
IConfig $config,
|
||||
TokenManager $tokenManager,
|
||||
IUserManager $userManager) {
|
||||
IUserManager $userManager,
|
||||
WopiMapper $wopiMapper) {
|
||||
parent::__construct($appName, $request);
|
||||
$this->rootFolder = $rootFolder;
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
$this->config = $config;
|
||||
$this->tokenManager = $tokenManager;
|
||||
$this->userManager = $userManager;
|
||||
$this->wopiMapper = $wopiMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -91,16 +98,17 @@ class WopiController extends Controller {
|
|||
$token = $this->request->getParam('access_token');
|
||||
|
||||
list($fileId, , $version) = Helper::parseFileId($fileId);
|
||||
$db = new Wopi();
|
||||
$res = $db->getPathForToken($fileId, $token);
|
||||
if ($res === false) {
|
||||
|
||||
try {
|
||||
$wopi = $this->wopiMapper->getPathForToken($token);
|
||||
} catch (DoesNotExistException $e) {
|
||||
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
||||
}
|
||||
|
||||
// Login the user to see his mount locations
|
||||
try {
|
||||
/** @var File $file */
|
||||
$userFolder = $this->rootFolder->getUserFolder($res['owner']);
|
||||
$userFolder = $this->rootFolder->getUserFolder($wopi->getOwnerUid());
|
||||
$file = $userFolder->getById($fileId)[0];
|
||||
} catch (\Exception $e) {
|
||||
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
||||
|
@ -114,23 +122,23 @@ class WopiController extends Controller {
|
|||
'BaseFileName' => $file->getName(),
|
||||
'Size' => $file->getSize(),
|
||||
'Version' => $version,
|
||||
'UserId' => !is_null($res['editor']) ? $res['editor'] : 'guest',
|
||||
'OwnerId' => $res['owner'],
|
||||
'UserFriendlyName' => !is_null($res['editor']) ? \OC_User::getDisplayName($res['editor']) : 'Guest user',
|
||||
'UserId' => !is_null($wopi->getEditorUid()) ? $wopi->getEditorUid() : 'guest',
|
||||
'OwnerId' => $wopi->getOwnerUid(),
|
||||
'UserFriendlyName' => !is_null($wopi->getEditorUid()) ? \OC_User::getDisplayName($wopi->getEditorUid()) : 'Guest user',
|
||||
'UserExtraInfo' => [
|
||||
],
|
||||
'UserCanWrite' => $res['canwrite'] ? true : false,
|
||||
'UserCanNotWriteRelative' => \OC::$server->getEncryptionManager()->isEnabled() ? true : is_null($res['editor']),
|
||||
'PostMessageOrigin' => $res['server_host'],
|
||||
'UserCanWrite' => $wopi->getCanwrite(),
|
||||
'UserCanNotWriteRelative' => \OC::$server->getEncryptionManager()->isEnabled() ? true : is_null($wopi->getEditorUid()),
|
||||
'PostMessageOrigin' => $wopi->getServerHost(),
|
||||
'LastModifiedTime' => Helper::toISO8601($file->getMtime())
|
||||
];
|
||||
|
||||
$serverVersion = $this->config->getSystemValue('version');
|
||||
if (version_compare($serverVersion, '13', '>=')) {
|
||||
$user = $this->userManager->get($res['editor']);
|
||||
$user = $this->userManager->get($wopi->getEditorUid());
|
||||
if($user !== null) {
|
||||
if($user->getAvatarImage(32) !== null) {
|
||||
$response['UserExtraInfo']['avatar'] = $this->urlGenerator->linkToRouteAbsolute('core.avatar.getAvatar', ['userId' => $res['editor'], 'size' => 32]);
|
||||
$response['UserExtraInfo']['avatar'] = $this->urlGenerator->linkToRouteAbsolute('core.avatar.getAvatar', ['userId' => $wopi->getEditorUid(), 'size' => 32]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -152,20 +160,18 @@ class WopiController extends Controller {
|
|||
public function getFile($fileId,
|
||||
$access_token) {
|
||||
list($fileId, , $version) = Helper::parseFileId($fileId);
|
||||
$row = new Wopi();
|
||||
$row->loadBy('token', $access_token);
|
||||
$res = $row->getPathForToken($fileId, $access_token);
|
||||
|
||||
$wopi = $this->wopiMapper->getPathForToken($access_token);
|
||||
try {
|
||||
/** @var File $file */
|
||||
$userFolder = $this->rootFolder->getUserFolder($res['owner']);
|
||||
$userFolder = $this->rootFolder->getUserFolder($wopi->getOwnerUid());
|
||||
$file = $userFolder->getById($fileId)[0];
|
||||
\OC_User::setIncognitoMode(true);
|
||||
if ($version !== '0')
|
||||
{
|
||||
$view = new View('/' . $res['owner'] . '/files');
|
||||
if ($version !== '0') {
|
||||
$view = new View('/' . $wopi->getOwnerUid() . '/files');
|
||||
$relPath = $view->getRelativePath($file->getPath());
|
||||
$versionPath = '/files_versions/' . $relPath . '.v' . $version;
|
||||
$view = new View('/' . $res['owner']);
|
||||
$view = new View('/' . $wopi->getOwnerUid());
|
||||
if ($view->file_exists($versionPath)){
|
||||
$response = new StreamResponse($view->fopen($versionPath, 'rb'));
|
||||
}
|
||||
|
@ -201,17 +207,14 @@ class WopiController extends Controller {
|
|||
list($fileId, , $version) = Helper::parseFileId($fileId);
|
||||
$isPutRelative = ($this->request->getHeader('X-WOPI-Override') === 'PUT_RELATIVE');
|
||||
|
||||
$row = new Wopi();
|
||||
$row->loadBy('token', $access_token);
|
||||
|
||||
$res = $row->getPathForToken($fileId, $access_token);
|
||||
if (!$res['canwrite']) {
|
||||
$wopi = $this->wopiMapper->getPathForToken($access_token);
|
||||
if (!$wopi->getCanwrite()) {
|
||||
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
||||
}
|
||||
|
||||
try {
|
||||
/** @var File $file */
|
||||
$userFolder = $this->rootFolder->getUserFolder($res['owner']);
|
||||
$userFolder = $this->rootFolder->getUserFolder($wopi->getOwnerUid());
|
||||
$file = $userFolder->getById($fileId)[0];
|
||||
|
||||
if ($isPutRelative) {
|
||||
|
@ -263,10 +266,10 @@ class WopiController extends Controller {
|
|||
$content = fopen('php://input', 'rb');
|
||||
// Setup the FS which is needed to emit hooks (versioning).
|
||||
\OC_Util::tearDownFS();
|
||||
\OC_Util::setupFS($res['owner']);
|
||||
\OC_Util::setupFS($wopi->getOwnerUid());
|
||||
|
||||
// Set the user to register the change under his name
|
||||
$editor = \OC::$server->getUserManager()->get($res['editor']);
|
||||
$editor = \OC::$server->getUserManager()->get($wopi->getEditorUid());
|
||||
if (!is_null($editor)) {
|
||||
\OC::$server->getUserSession()->setUser($editor);
|
||||
}
|
||||
|
|
|
@ -1,220 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* ownCloud - Richdocuments App
|
||||
*
|
||||
* @author Victor Dubiniuk
|
||||
* @copyright 2013 Victor Dubiniuk victor.dubiniuk@gmail.com
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
*/
|
||||
|
||||
namespace OCA\Richdocuments\Db;
|
||||
|
||||
/**
|
||||
* Generic DB class
|
||||
*/
|
||||
|
||||
abstract class DbBase {
|
||||
|
||||
protected $data;
|
||||
|
||||
protected $tableName;
|
||||
|
||||
protected $insertStatement;
|
||||
|
||||
protected $loadStatement;
|
||||
|
||||
public function __construct($data = array()){
|
||||
$this->setData($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert current object data into database
|
||||
* @return mixed
|
||||
*/
|
||||
public function insert(){
|
||||
$result = $this->execute($this->insertStatement);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get id of the recently inserted record
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLastInsertId(){
|
||||
return \OC::$server->getDatabaseConnection()->lastInsertId($this->tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get single record by primary key
|
||||
* @param int $value primary key value
|
||||
* @return \OCA\Richdocuments\Db
|
||||
*/
|
||||
public function load($value){
|
||||
if (!is_array($value)){
|
||||
$value = array($value);
|
||||
}
|
||||
|
||||
$result = $this->execute($this->loadStatement, $value);
|
||||
$data = $result->fetch();
|
||||
if (!is_array($data)){
|
||||
$data = array();
|
||||
}
|
||||
$this->data = $data;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get single record matching condition
|
||||
* @param string $field for WHERE condition
|
||||
* @param mixed $value matching value(s)
|
||||
* @return \OCA\Richdocuments\Db
|
||||
* @throws Exception
|
||||
*/
|
||||
public function loadBy($field, $value){
|
||||
if (!is_array($value)){
|
||||
$value = array($value);
|
||||
}
|
||||
$result = $this->execute('SELECT * FROM ' . $this->tableName . ' WHERE `'. $field .'` =?', $value);
|
||||
$data = $result->fetchAll();
|
||||
if (!is_array($data) || !count($data)){
|
||||
$this->data = array();
|
||||
} elseif (count($data) !== 1) {
|
||||
throw new Exception('Duplicate ' . $value . ' for the filed ' . $field);
|
||||
} else {
|
||||
$this->data = $data[0];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete records matching the condition
|
||||
* @param string $field for WHERE condition
|
||||
* @param mixed $value matching value(s)
|
||||
*/
|
||||
public function deleteBy($field, $value){
|
||||
if (!is_array($value)){
|
||||
$value = array($value);
|
||||
}
|
||||
$count = count($value);
|
||||
if ($count===0){
|
||||
return;
|
||||
} elseif ($count===1){
|
||||
$this->execute('DELETE FROM ' . $this->tableName . ' WHERE `'. $field .'` =?', $value);
|
||||
} else {
|
||||
$stmt = $this->buildInQuery($field, $value);
|
||||
$this->execute('DELETE FROM ' . $this->tableName . ' WHERE ' . $stmt, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all records from the table
|
||||
* @return array
|
||||
*/
|
||||
public function getCollection(){
|
||||
$result = $this->execute('SELECT * FROM ' . $this->tableName);
|
||||
$data = $result->fetchAll();
|
||||
if (!is_array($data)){
|
||||
$data = array();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array of matching records
|
||||
* @param string $field for WHERE condition
|
||||
* @param mixed $value matching value(s)
|
||||
* @return array
|
||||
*/
|
||||
public function getCollectionBy($field, $value){
|
||||
if (!is_array($value)){
|
||||
$value = array($value);
|
||||
}
|
||||
$count = count($value);
|
||||
if ($count===0){
|
||||
return array();
|
||||
} elseif ($count===1){
|
||||
$result = $this->execute('SELECT * FROM ' . $this->tableName . ' WHERE `'. $field .'` =?', $value);
|
||||
} else {
|
||||
$stmt = $this->buildInQuery($field, $value);
|
||||
$result = $this->execute('SELECT * FROM ' . $this->tableName . ' WHERE '. $stmt , $value);
|
||||
}
|
||||
|
||||
$data = $result->fetchAll();
|
||||
if (!is_array($data)){
|
||||
$data = array();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get object data
|
||||
* @return Array
|
||||
*/
|
||||
public function getData(){
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set object data
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData($data){
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there are any data in current object
|
||||
* @return bool
|
||||
*/
|
||||
public function hasData(){
|
||||
return count($this->data)>0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build placeholders for the query with variable input data
|
||||
* @param string $field field name
|
||||
* @param Array $array data
|
||||
* @return String `field` IN (?, ?...) placeholders matching the number of elements in array
|
||||
*/
|
||||
protected function buildInQuery($field, $array){
|
||||
$count = count($array);
|
||||
$placeholders = array_fill(0, $count, '?');
|
||||
$stmt = implode(', ', $placeholders);
|
||||
return '`' . $field . '` IN (' . $stmt . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a query on database
|
||||
* @param string $statement query to be executed
|
||||
* @param mixed $args value(s) for the query.
|
||||
* If omited the query will be run on the current object $data
|
||||
* @return mixed (array/false)
|
||||
*/
|
||||
protected function execute($statement, $args = null){
|
||||
$query = \OC::$server->getDatabaseConnection()->prepare($statement);
|
||||
|
||||
if (!is_null($args)){
|
||||
$result = $query->execute($args);
|
||||
} elseif (count($this->data)){
|
||||
$result = $query->execute($this->data);
|
||||
} else {
|
||||
$result = $query->execute();
|
||||
}
|
||||
|
||||
return $result ? $query : false;
|
||||
}
|
||||
|
||||
public function __call($name, $arguments){
|
||||
if (substr($name, 0, 3) === 'get'){
|
||||
$requestedProperty = substr($name, 3);
|
||||
$property = strtolower(preg_replace('/(.)([A-Z])/', "$1_$2", $requestedProperty));
|
||||
if (isset($this->data[$property])){
|
||||
return $this->data[$property];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
130
lib/Db/Wopi.php
130
lib/Db/Wopi.php
|
@ -1,83 +1,85 @@
|
|||
<?php
|
||||
/**
|
||||
* ownCloud - Richdocuments App
|
||||
* @copyright 2018, Roeland Jago Douma <roeland@famdouma.nl>
|
||||
*
|
||||
* @author Ashod Nakashian
|
||||
* @copyright 2016 Ashod Nakashian ashod.nakashian@collabora.co.uk
|
||||
* @author Roeland Jago Douma <roeland@famdouma.nl>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
*/
|
||||
|
||||
namespace OCA\Richdocuments\Db;
|
||||
|
||||
class Wopi extends DbBase {
|
||||
use OCP\AppFramework\Db\Entity;
|
||||
|
||||
const DB_TABLE = '`*PREFIX*richdocuments_wopi`';
|
||||
/**
|
||||
* Class WopiEntity
|
||||
*
|
||||
* @package OCA\Richdocuments\Db
|
||||
*
|
||||
* @method void setOwnerUid(string $uid)
|
||||
* @method string getOwnerUid()
|
||||
* @method void setEditorUid(string $uid)
|
||||
* @method string getEditorUid()
|
||||
* @method void setFileid(int $fileid)
|
||||
* @method int getFileid()
|
||||
* @method void setVersion(int $version)
|
||||
* @method int getVersion()
|
||||
* @method void setCanwrite(bool $canwrite)
|
||||
* @method bool getCanwrite()
|
||||
* @method void setServerHost(string $host)
|
||||
* @method string getServerHost()
|
||||
* @method void setToken(string $token)
|
||||
* @method string getToken()
|
||||
* @method void setExpiry(int $expiry)
|
||||
* @method int getExpiry()
|
||||
*/
|
||||
class Wopi extends Entity {
|
||||
/** @var string */
|
||||
protected $ownerUid;
|
||||
|
||||
// Tokens expire after this many seconds (not defined by WOPI specs).
|
||||
const TOKEN_LIFETIME_SECONDS = 1800;
|
||||
/** @var string */
|
||||
protected $editorUid;
|
||||
|
||||
protected $tableName = '`*PREFIX*richdocuments_wopi`';
|
||||
/** @var int */
|
||||
protected $fileid;
|
||||
|
||||
protected $insertStatement = 'INSERT INTO `*PREFIX*richdocuments_wopi` (`fileid`, `owner_uid`, `editor_uid`, `version`, `canwrite`, `server_host`, `token`, `expiry`)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)';
|
||||
/** @var int */
|
||||
protected $version;
|
||||
|
||||
protected $loadStatement = 'SELECT * FROM `*PREFIX*richdocuments_wopi` WHERE `token`= ?';
|
||||
/** @var bool */
|
||||
protected $canwrite;
|
||||
|
||||
public function generateFileToken($fileId, $owner, $editor, $version, $updatable, $serverHost) {
|
||||
$token = \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate(32,
|
||||
\OCP\Security\ISecureRandom::CHAR_LOWER . \OCP\Security\ISecureRandom::CHAR_UPPER .
|
||||
\OCP\Security\ISecureRandom::CHAR_DIGITS);
|
||||
/** @var string */
|
||||
protected $serverHost;
|
||||
|
||||
$wopi = new \OCA\Richdocuments\Db\Wopi([
|
||||
$fileId,
|
||||
$owner,
|
||||
$editor,
|
||||
$version,
|
||||
$updatable,
|
||||
$serverHost,
|
||||
$token,
|
||||
time() + self::TOKEN_LIFETIME_SECONDS
|
||||
]);
|
||||
/** @var string */
|
||||
protected $token;
|
||||
|
||||
if (!$wopi->insert()) {
|
||||
throw new \Exception('Failed to add wopi token into database');
|
||||
}
|
||||
/** @var int */
|
||||
protected $expiry;
|
||||
|
||||
return $token;
|
||||
public function __construct() {
|
||||
$this->addType('owner_uid', 'string');
|
||||
$this->addType('editor_uid', 'string');
|
||||
$this->addType('fileid', 'int');
|
||||
$this->addType('version', 'int');
|
||||
$this->addType('canwrite', 'bool');
|
||||
$this->addType('server_host', 'string');
|
||||
$this->addType('token', 'string');
|
||||
$this->addType('expiry', 'int');
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 ]);
|
||||
if (count($row) === 0)
|
||||
{
|
||||
// Invalid token.
|
||||
http_response_code(401);
|
||||
return false;
|
||||
}
|
||||
|
||||
//TODO: validate.
|
||||
if ($row['expiry'] > time()){
|
||||
// Expired token!
|
||||
//http_response_code(404);
|
||||
//$wopi->deleteBy('id', $row['id']);
|
||||
//return false;
|
||||
}
|
||||
|
||||
return array(
|
||||
'owner' => $row['owner_uid'],
|
||||
'editor' => $row['editor_uid'],
|
||||
'canwrite' => $row['canwrite'],
|
||||
'server_host' => $row['server_host']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright 2018, Roeland Jago Douma <roeland@famdouma.nl>
|
||||
*
|
||||
* @author Roeland Jago Douma <roeland@famdouma.nl>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
namespace OCA\Richdocuments\Db;
|
||||
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Db\Mapper;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\ILogger;
|
||||
use OCP\Security\ISecureRandom;
|
||||
|
||||
class WopiMapper extends Mapper {
|
||||
// Tokens expire after this many seconds (not defined by WOPI specs).
|
||||
const TOKEN_LIFETIME_SECONDS = 1800;
|
||||
|
||||
/** @var ISecureRandom */
|
||||
private $random;
|
||||
|
||||
/** @var ILogger */
|
||||
private $logger;
|
||||
|
||||
/** @var ITimeFactory */
|
||||
private $timeFactory;
|
||||
|
||||
public function __construct(IDBConnection $db,
|
||||
ISecureRandom $random,
|
||||
ILogger $logger,
|
||||
ITimeFactory $timeFactory) {
|
||||
parent::__construct($db, 'richdocuments_wopi', Wopi::class);
|
||||
|
||||
$this->random = $random;
|
||||
$this->logger = $logger;
|
||||
$this->timeFactory = $timeFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $fileId
|
||||
* @param string $owner
|
||||
* @param string$editor
|
||||
* @param int $version
|
||||
* @param bool $updatable
|
||||
* @param string $serverHost
|
||||
* @return Wopi
|
||||
*/
|
||||
public function generateFileToken($fileId, $owner, $editor, $version, $updatable, $serverHost) {
|
||||
$token = $this->random->generate(32, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS);
|
||||
|
||||
$wopi = Wopi::fromParams([
|
||||
'fileid' => $fileId,
|
||||
'ownerUid' => $owner,
|
||||
'editorUid' => $editor,
|
||||
'version' => $version,
|
||||
'canwrite' => $updatable,
|
||||
'serverHost' => $serverHost,
|
||||
'token' => $token,
|
||||
'expiry' => $this->timeFactory->getTime() + self::TOKEN_LIFETIME_SECONDS,
|
||||
]);
|
||||
|
||||
/** @var Wopi $wopi */
|
||||
$wopi = $this->insert($wopi);
|
||||
|
||||
return $wopi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a token, validates it and
|
||||
* constructs and validates the path.
|
||||
* Returns the path, if valid, else false.
|
||||
*
|
||||
* @param string $token
|
||||
* @throws DoesNotExistException
|
||||
* @return Wopi
|
||||
*/
|
||||
public function getPathForToken($token) {
|
||||
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('*')
|
||||
->from('richdocuments_wopi')
|
||||
->where(
|
||||
$qb->expr()->eq('token', $qb->createNamedParameter($token))
|
||||
);
|
||||
$result = $qb->execute();
|
||||
$row = $result->fetch();
|
||||
$result->closeCursor();
|
||||
|
||||
$this->logger->debug('Loaded WOPI Token record: {row}.', [ 'row' => $row ]);
|
||||
if ($row === false) {
|
||||
throw new DoesNotExistException('Could not find token.');
|
||||
}
|
||||
|
||||
/** @var Wopi $wopi */
|
||||
$wopi = Wopi::fromRow($row);
|
||||
|
||||
//TODO: validate.
|
||||
if ($wopi->getExpiry() > $this->timeFactory->getTime()){
|
||||
// Expired token!
|
||||
//http_response_code(404);
|
||||
//$wopi->deleteBy('id', $row['id']);
|
||||
//return false;
|
||||
}
|
||||
|
||||
return $wopi;
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@
|
|||
namespace OCA\Richdocuments;
|
||||
|
||||
use OC\Share\Constants;
|
||||
use OCA\Richdocuments\Db\WopiMapper;
|
||||
use OCA\Richdocuments\Helper;
|
||||
use OCA\Richdocuments\Db\Wopi;
|
||||
use OCA\Richdocuments\WOPI\Parser;
|
||||
|
@ -39,25 +40,36 @@ class TokenManager {
|
|||
private $urlGenerator;
|
||||
/** @var Parser */
|
||||
private $wopiParser;
|
||||
/** @var AppConfig */
|
||||
private $appConfig;
|
||||
/** @var string */
|
||||
private $userId;
|
||||
/** @var WopiMapper */
|
||||
private $wopiMapper;
|
||||
|
||||
/**
|
||||
* @param IRootFolder $rootFolder
|
||||
* @param IManager $shareManager
|
||||
* @param IURLGenerator $urlGenerator
|
||||
* @param Parser $wopiParser
|
||||
* @param AppConfig $appConfig
|
||||
* @param string $UserId
|
||||
* @param WopiMapper $wopiMapper
|
||||
*/
|
||||
public function __construct(IRootFolder $rootFolder,
|
||||
IManager $shareManager,
|
||||
IURLGenerator $urlGenerator,
|
||||
Parser $wopiParser,
|
||||
AppConfig $appConfig,
|
||||
$UserId) {
|
||||
$UserId,
|
||||
WopiMapper $wopiMapper) {
|
||||
$this->rootFolder = $rootFolder;
|
||||
$this->shareManager = $shareManager;
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
$this->wopiParser = $wopiParser;
|
||||
$this->appConfig = $appConfig;
|
||||
$this->userId = $UserId;
|
||||
$this->wopiMapper = $wopiMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -112,15 +124,14 @@ class TokenManager {
|
|||
if (is_null($owneruid)) {
|
||||
$owneruid = $file->getOwner()->getUID();
|
||||
}
|
||||
$row = new Wopi();
|
||||
$serverHost = $this->urlGenerator->getAbsoluteURL('/');//$this->request->getServerProtocol() . '://' . $this->request->getServerHost();
|
||||
$token = $row->generateFileToken($fileId, $owneruid, $this->userId, $version, (int)$updatable, $serverHost);
|
||||
$wopi = $this->wopiMapper->generateFileToken($fileId, $owneruid, $this->userId, $version, (int)$updatable, $serverHost);
|
||||
|
||||
try {
|
||||
|
||||
return [
|
||||
$this->wopiParser->getUrlSrc($file->getMimeType())['urlsrc'],
|
||||
$token,
|
||||
$wopi->getToken(),
|
||||
];
|
||||
} catch (\Exception $e){
|
||||
throw $e;
|
||||
|
|
Загрузка…
Ссылка в новой задаче