2013-09-02 19:54:23 +03:00
< ? php
/**
2015-12-16 17:57:44 +03:00
* ownCloud - Richdocuments App
2013-09-02 19:54:23 +03:00
*
* @ author Victor Dubiniuk
2014-10-23 23:08:55 +03:00
* @ copyright 2014 Victor Dubiniuk victor . dubiniuk @ gmail . com
2013-09-02 19:54:23 +03:00
*
* This file is licensed under the Affero General Public License version 3 or
* later .
*/
2015-12-16 17:57:44 +03:00
namespace OCA\Richdocuments\Controller ;
2014-10-23 23:08:55 +03:00
use \OCP\AppFramework\Controller ;
use \OCP\IRequest ;
use \OCP\IConfig ;
use \OCP\IL10N ;
2015-10-26 11:00:25 +01:00
use \OCP\AppFramework\Http\ContentSecurityPolicy ;
2014-10-23 23:08:55 +03:00
use \OCP\AppFramework\Http\JSONResponse ;
2015-10-26 11:00:25 +01:00
use \OCP\AppFramework\Http\TemplateResponse ;
2014-10-23 23:08:55 +03:00
2016-09-14 11:47:24 +05:30
use \OCA\Richdocuments\AppConfig ;
2015-12-16 17:57:44 +03:00
use \OCA\Richdocuments\Db ;
use \OCA\Richdocuments\Helper ;
use \OCA\Richdocuments\Storage ;
use \OCA\Richdocuments\Download ;
use \OCA\Richdocuments\DownloadResponse ;
use \OCA\Richdocuments\File ;
2016-03-08 10:51:49 -04:00
use \OCA\Richdocuments\Genesis ;
2014-11-11 03:22:31 +03:00
use \OC\Files\View ;
2016-03-08 10:51:49 -04:00
use \OCP\ICacheFactory ;
2016-03-08 18:35:44 -04:00
use \OCP\ILogger ;
2013-09-02 19:54:23 +03:00
2016-04-12 20:16:04 +02:00
class ResponseException extends \Exception {
private $hint ;
public function __construct ( $description , $hint = '' ) {
parent :: __construct ( $description );
$this -> hint = $hint ;
}
public function getHint () {
return $this -> hint ;
}
}
class DocumentController extends Controller {
2016-01-12 15:20:38 +01:00
2014-10-23 23:08:55 +03:00
private $uid ;
private $l10n ;
private $settings ;
2016-08-29 14:43:29 +05:30
private $appConfig ;
2016-03-08 10:51:49 -04:00
private $cache ;
2016-03-08 18:35:44 -04:00
private $logger ;
2015-11-04 16:58:18 +01:00
const ODT_TEMPLATE_PATH = '/assets/odttemplate.odt' ;
2016-01-12 15:20:38 +01:00
2016-09-14 11:47:24 +05:30
public function __construct ( $appName , IRequest $request , IConfig $settings , AppConfig $appConfig , IL10N $l10n , $uid , ICacheFactory $cache , ILogger $logger ){
2014-10-23 23:08:55 +03:00
parent :: __construct ( $appName , $request );
$this -> uid = $uid ;
$this -> l10n = $l10n ;
$this -> settings = $settings ;
2016-08-29 14:43:29 +05:30
$this -> appConfig = $appConfig ;
2016-03-08 10:51:49 -04:00
$this -> cache = $cache -> create ( $appName );
2016-03-08 18:35:44 -04:00
$this -> logger = $logger ;
2014-10-23 23:08:55 +03:00
}
2016-01-12 15:20:38 +01:00
2016-03-10 08:00:52 -04:00
/**
* @ param \SimpleXMLElement $discovery
* @ param string $mimetype
*/
2016-10-04 15:52:13 +02:00
private function getWopiSrcUrl ( $discovery_parsed , $mimetype ) {
2016-04-12 20:16:04 +02:00
if ( is_null ( $discovery_parsed ) || $discovery_parsed == false ) {
2016-03-10 08:00:52 -04:00
return null ;
}
2016-10-04 15:52:13 +02:00
$result = $discovery_parsed -> xpath ( sprintf ( '/wopi-discovery/net-zone/app[@name=\'%s\']/action' , $mimetype ));
2016-03-10 08:00:52 -04:00
if ( $result && count ( $result ) > 0 ) {
2016-10-04 15:52:13 +02:00
return array (
'urlsrc' => ( string ) $result [ 0 ][ 'urlsrc' ],
'action' => ( string ) $result [ 0 ][ 'name' ]
);
2016-03-10 08:00:52 -04:00
}
return null ;
}
2016-07-16 23:54:56 +05:30
/**
* 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 );
}
}
}
2016-03-16 23:46:13 -04:00
private function responseError ( $message , $hint = '' ){
$errors = array ( 'errors' => array ( array ( 'error' => $message , 'hint' => $hint )));
$response = new TemplateResponse ( '' , 'error' , $errors , 'error' );
return $response ;
2016-03-10 08:00:52 -04:00
}
2016-04-12 20:16:04 +02:00
/** Return the content of discovery . xml - either from cache , or download it .
2015-08-26 19:09:34 +03:00
*/
2016-04-12 20:16:04 +02:00
private function getDiscovery (){
\OC :: $server -> getLogger () -> debug ( 'getDiscovery(): Getting discovery.xml from the cache.' );
2016-08-29 14:43:29 +05:30
$wopiRemote = $this -> appConfig -> getAppValue ( 'wopi_url' );
2016-03-16 09:04:35 -04:00
2016-04-12 20:16:04 +02:00
// Provides access to information about the capabilities of a WOPI client
// and the mechanisms for invoking those abilities through URIs.
$wopiDiscovery = $wopiRemote . '/hosting/discovery' ;
2016-03-16 23:46:13 -04:00
2016-04-12 20:16:04 +02:00
// Read the memcached value (if the memcache is installed)
2016-03-16 23:46:13 -04:00
$discovery = $this -> cache -> get ( 'discovery.xml' );
2016-04-12 20:16:04 +02:00
2016-03-16 23:46:13 -04:00
if ( is_null ( $discovery )) {
2016-04-12 20:16:04 +02:00
$contact_admin = $this -> l10n -> t ( 'Please contact the "%s" administrator.' , array ( $wopiRemote ));
2016-03-16 23:46:13 -04:00
try {
$wopiClient = \OC :: $server -> getHTTPClientService () -> newClient ();
2016-04-12 20:16:04 +02:00
$discovery = $wopiClient -> get ( $wopiDiscovery ) -> getBody ();
2016-03-16 23:46:13 -04:00
}
catch ( \Exception $e ) {
2016-04-12 15:18:02 +02:00
$error_message = $e -> getMessage ();
if ( preg_match ( '/^cURL error ([0-9]*):/' , $error_message , $matches )) {
$admin_check = $this -> l10n -> t ( 'Please ask your administrator to check the Collabora Online server setting. The exact error message was: ' ) . $error_message ;
$curl_error = $matches [ 1 ];
switch ( $curl_error ) {
case '1' :
2016-04-12 20:16:04 +02:00
throw new ResponseException ( $this -> l10n -> t ( 'Collabora Online: The protocol specified in "%s" is not allowed.' , array ( $wopiRemote )), $admin_check );
2016-04-12 15:18:02 +02:00
case '3' :
2016-04-12 20:16:04 +02:00
throw new ResponseException ( $this -> l10n -> t ( 'Collabora Online: Malformed URL "%s".' , array ( $wopiRemote )), $admin_check );
2016-04-12 15:18:02 +02:00
case '6' :
2016-04-12 20:16:04 +02:00
throw new ResponseException ( $this -> l10n -> t ( 'Collabora Online: Cannot resolve the host "%s".' , array ( $wopiRemote )), $admin_check );
2016-04-15 16:55:15 +02:00
case '7' :
throw new ResponseException ( $this -> l10n -> t ( 'Collabora Online: Cannot connect to the host "%s".' , array ( $wopiRemote )), $admin_check );
2016-04-12 15:18:02 +02:00
case '60' :
2016-07-28 14:35:54 +02:00
throw new ResponseException ( $this -> l10n -> t ( 'Collabora Online: SSL certificate is not installed.' ), $this -> l10n -> t ( 'Please ask your administrator to add ca-chain.cert.pem to the ca-bundle.crt, for example "cat /etc/loolwsd/ca-chain.cert.pem >> <server-installation>/resources/config/ca-bundle.crt" . The exact error message was: ' ) . $error_message );
2016-04-12 15:18:02 +02:00
}
}
2016-04-12 20:16:04 +02:00
throw new ResponseException ( $this -> l10n -> t ( 'Collabora Online unknown error: ' ) . $error_message , $contact_admin );
2016-03-16 23:46:13 -04:00
}
2016-04-12 20:16:04 +02:00
if ( ! $discovery ) {
throw new ResponseException ( $this -> l10n -> t ( 'Collabora Online: Unable to read discovery.xml from "%s".' , array ( $wopiRemote )), $contact_admin );
2016-03-17 09:58:11 -04:00
}
2016-04-12 20:16:04 +02:00
\OC :: $server -> getLogger () -> debug ( 'Storing the discovery.xml to the cache.' );
$this -> cache -> set ( 'discovery.xml' , $discovery , 3600 );
}
return $discovery ;
}
2016-06-09 00:39:17 +05:30
/** Prepare document ( s ) structure
*/
private function prepareDocuments ( $rawDocuments ){
$discovery_parsed = null ;
try {
$discovery = $this -> getDiscovery ();
$loadEntities = libxml_disable_entity_loader ( true );
$discovery_parsed = simplexml_load_string ( $discovery );
libxml_disable_entity_loader ( $loadEntities );
if ( $discovery_parsed === false ) {
$this -> cache -> remove ( 'discovery.xml' );
2016-08-29 14:43:29 +05:30
$wopiRemote = $this -> appConfig -> getAppValue ( 'wopi_url' );
2016-06-09 00:39:17 +05:30
return array (
'status' => 'error' ,
'message' => $this -> l10n -> t ( 'Collabora Online: discovery.xml from "%s" is not a well-formed XML string.' , array ( $wopiRemote )),
'hint' => $this -> l10n -> t ( 'Please contact the "%s" administrator.' , array ( $wopiRemote ))
);
}
}
catch ( ResponseException $e ) {
return array (
'status' => 'error' ,
'message' => $e -> getMessage (),
'hint' => $e -> getHint ()
);
}
$fileIds = array ();
$documents = array ();
$lolang = strtolower ( str_replace ( '_' , '-' , $this -> settings -> getUserValue ( $this -> uid , 'core' , 'lang' , 'en' )));
foreach ( $rawDocuments as $key => $document ) {
if ( is_object ( $document )){
$documents [] = $document -> getData ();
} else {
$documents [ $key ] = $document ;
}
$documents [ $key ][ 'icon' ] = preg_replace ( '/\.png$/' , '.svg' , \OCP\Template :: mimetype_icon ( $document [ 'mimetype' ]));
$documents [ $key ][ 'hasPreview' ] = \OC :: $server -> getPreviewManager () -> isMimeSupported ( $document [ 'mimetype' ]);
2016-10-04 15:52:13 +02:00
$ret = $this -> getWopiSrcUrl ( $discovery_parsed , $document [ 'mimetype' ]);
$documents [ $key ][ 'urlsrc' ] = $ret [ 'urlsrc' ];
$documents [ $key ][ 'action' ] = $ret [ 'action' ];
2016-06-09 00:39:17 +05:30
$documents [ $key ][ 'lolang' ] = $lolang ;
$fileIds [] = $document [ 'fileid' ];
}
usort ( $documents , function ( $a , $b ){
return @ $b [ 'mtime' ] -@ $a [ 'mtime' ];
});
$session = new Db\Session ();
$sessions = $session -> getCollectionBy ( 'file_id' , $fileIds );
$members = array ();
$member = new Db\Member ();
foreach ( $sessions as $session ) {
$members [ $session [ 'es_id' ]] = $member -> getActiveCollection ( $session [ 'es_id' ]);
}
return array (
'status' => 'success' , 'documents' => $documents , 'sessions' => $sessions , 'members' => $members
);
}
2016-04-12 20:16:04 +02:00
/**
* @ NoAdminRequired
* @ NoCSRFRequired
*/
public function index (){
2016-08-29 14:43:29 +05:30
$wopiRemote = $this -> appConfig -> getAppValue ( 'wopi_url' );
2016-04-15 16:55:15 +02:00
if (( $parts = parse_url ( $wopiRemote )) && isset ( $parts [ 'scheme' ]) && isset ( $parts [ 'host' ])) {
2016-04-12 20:16:04 +02:00
$webSocketProtocol = " ws:// " ;
if ( $parts [ 'scheme' ] == " https " ) {
$webSocketProtocol = " wss:// " ;
2016-03-17 09:58:11 -04:00
}
2016-04-12 20:16:04 +02:00
$webSocket = sprintf (
" %s%s%s " ,
$webSocketProtocol ,
2016-04-15 16:55:15 +02:00
$parts [ 'host' ],
2016-04-12 20:16:04 +02:00
isset ( $parts [ 'port' ]) ? " : " . $parts [ 'port' ] : " " );
}
else {
return $this -> responseError ( $this -> l10n -> t ( 'Collabora Online: Invalid URL "%s".' , array ( $wopiRemote )), $this -> l10n -> t ( 'Please ask your administrator to check the Collabora Online server setting.' ));
2016-03-16 23:46:13 -04:00
}
\OC :: $server -> getNavigationManager () -> setActiveEntry ( 'richdocuments_index' );
$maxUploadFilesize = \OCP\Util :: maxUploadFilesize ( " / " );
2015-12-16 17:57:44 +03:00
$response = new TemplateResponse ( 'richdocuments' , 'documents' , [
2015-08-26 19:09:34 +03:00
'enable_previews' => $this -> settings -> getSystemValue ( 'enable_previews' , true ),
'uploadMaxFilesize' => $maxUploadFilesize ,
'uploadMaxHumanFilesize' => \OCP\Util :: humanFileSize ( $maxUploadFilesize ),
'allowShareWithLink' => $this -> settings -> getAppValue ( 'core' , 'shareapi_allow_links' , 'yes' ),
2016-03-16 09:04:35 -04:00
'wopi_url' => $webSocket ,
2015-08-26 19:09:34 +03:00
]);
2015-10-26 11:00:25 +01:00
$policy = new ContentSecurityPolicy ();
2016-03-08 18:35:44 -04:00
$policy -> addAllowedScriptDomain ( '\'self\' http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js http://cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.12/jquery.mousewheel.min.js \'unsafe-eval\' ' . $wopiRemote );
2016-04-18 15:16:15 +02:00
/* frame-src is deprecated on Firefox, but Safari wants it! */
$policy -> addAllowedFrameDomain ( '\'self\' http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js http://cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.12/jquery.mousewheel.min.js \'unsafe-eval\' ' . $wopiRemote );
2016-04-12 20:17:00 +02:00
$policy -> addAllowedChildSrcDomain ( '\'self\' http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js http://cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.12/jquery.mousewheel.min.js \'unsafe-eval\' ' . $wopiRemote );
2016-03-16 09:04:35 -04:00
$policy -> addAllowedConnectDomain ( $webSocket );
2015-10-26 11:00:25 +01:00
$policy -> addAllowedImageDomain ( '*' );
$policy -> allowInlineScript ( true );
$policy -> addAllowedFontDomain ( 'data:' );
$response -> setContentSecurityPolicy ( $policy );
return $response ;
2015-08-26 19:09:34 +03:00
}
2016-01-12 15:20:38 +01:00
2014-10-23 23:08:55 +03:00
/**
* @ NoAdminRequired
*/
public function create (){
2015-11-04 21:49:23 +01:00
$mimetype = $this -> request -> post [ 'mimetype' ];
2016-06-15 22:36:14 +05:30
$filename = $this -> request -> post [ 'filename' ];
$dir = $this -> request -> post [ 'dir' ];
2015-11-04 21:49:23 +01:00
2014-11-11 03:22:31 +03:00
$view = new View ( '/' . $this -> uid . '/files' );
2016-06-15 22:36:14 +05:30
if ( ! $dir ){
2016-09-12 19:38:01 +02:00
$dir = '/' ;
2014-04-02 23:18:39 +03:00
}
2015-11-04 21:49:23 +01:00
$basename = $this -> l10n -> t ( 'New Document.odt' );
switch ( $mimetype ) {
case 'application/vnd.oasis.opendocument.spreadsheet' :
$basename = $this -> l10n -> t ( 'New Spreadsheet.ods' );
break ;
case 'application/vnd.oasis.opendocument.presentation' :
$basename = $this -> l10n -> t ( 'New Presentation.odp' );
break ;
default :
// to be safe
$mimetype = 'application/vnd.oasis.opendocument.text' ;
break ;
}
2016-06-15 22:36:14 +05:30
if ( ! $filename ){
$path = Helper :: getNewFileName ( $view , $dir . '/' . $basename );
} else {
$path = $dir . '/' . $filename ;
}
2016-01-12 15:20:38 +01:00
2014-11-05 17:07:46 +03:00
$content = '' ;
2013-10-03 20:34:17 +03:00
if ( class_exists ( '\OC\Files\Type\TemplateManager' )){
$manager = \OC_Helper :: getFileTemplateManager ();
2015-11-04 21:49:23 +01:00
$content = $manager -> getTemplate ( $mimetype );
2014-11-05 17:07:46 +03:00
}
2016-01-12 15:20:38 +01:00
2014-11-05 17:07:46 +03:00
if ( ! $content ){
$content = file_get_contents ( dirname ( __DIR__ ) . self :: ODT_TEMPLATE_PATH );
2013-10-03 20:34:17 +03:00
}
2016-01-12 15:20:38 +01:00
2016-04-16 17:41:43 -04:00
$discovery_parsed = null ;
try {
$discovery = $this -> getDiscovery ();
$loadEntities = libxml_disable_entity_loader ( true );
$discovery_parsed = simplexml_load_string ( $discovery );
libxml_disable_entity_loader ( $loadEntities );
if ( $discovery_parsed === false ) {
$this -> cache -> remove ( 'discovery.xml' );
2016-08-29 14:43:29 +05:30
$wopiRemote = $this -> appConfig -> getAppValue ( 'wopi_url' );
2016-04-16 17:41:43 -04:00
return array (
'status' => 'error' ,
'message' => $this -> l10n -> t ( 'Collabora Online: discovery.xml from "%s" is not a well-formed XML string.' , array ( $wopiRemote )),
'hint' => $this -> l10n -> t ( 'Please contact the "%s" administrator.' , array ( $wopiRemote ))
);
}
}
catch ( ResponseException $e ) {
return array (
'status' => 'error' ,
2016-04-18 15:18:20 +02:00
'message' => $e -> getMessage (),
'hint' => $e -> getHint ()
2016-04-16 17:41:43 -04:00
);
}
2014-11-05 17:07:46 +03:00
if ( $content && $view -> file_put_contents ( $path , $content )){
2014-04-02 23:18:39 +03:00
$info = $view -> getFileInfo ( $path );
2016-10-04 15:52:13 +02:00
$ret = $this -> getWopiSrcUrl ( $discovery_parsed , $mimetype );
2014-10-23 23:08:55 +03:00
$response = array (
'status' => 'success' ,
2016-04-16 17:41:43 -04:00
'fileid' => $info [ 'fileid' ],
2016-10-04 15:52:13 +02:00
'urlsrc' => $ret [ 'urlsrc' ],
'action' => $ret [ 'action' ],
2016-06-15 22:36:14 +05:30
'lolang' => $this -> settings -> getUserValue ( $this -> uid , 'core' , 'lang' , 'en' ),
'data' => \OCA\Files\Helper :: formatFileInfo ( $info )
2014-10-23 23:08:55 +03:00
);
2014-04-02 23:18:39 +03:00
} else {
2014-10-23 23:08:55 +03:00
$response = array (
'status' => 'error' ,
2014-10-26 15:47:56 +03:00
'message' => ( string ) $this -> l10n -> t ( 'Can\'t create document' )
2014-04-02 23:18:39 +03:00
);
}
2014-10-23 23:08:55 +03:00
return $response ;
2013-09-13 13:18:45 +03:00
}
2016-03-08 21:16:19 -05:00
/**
2016-03-23 21:57:22 -04:00
* @ NoAdminRequired
2016-03-08 21:16:19 -05:00
* Generates and returns an access token for a given fileId .
* Only for authenticated users !
*/
public function wopiGetToken ( $fileId ){
2016-06-26 20:51:06 +05:30
$arr = explode ( '_' , $fileId , 2 );
$version = '0' ;
if ( count ( $arr ) == 2 ) {
$fileId = $arr [ 0 ];
$version = $arr [ 1 ];
}
\OC :: $server -> getLogger () -> debug ( 'Generating WOPI Token for file {fileId}, version {version}.' , [ 'app' => $this -> appName , 'fileId' => $fileId , 'version' => $version ]);
2016-03-08 21:16:19 -05:00
$row = new Db\Wopi ();
2016-06-26 20:51:06 +05:30
$token = $row -> generateFileToken ( $fileId , $version );
2016-03-08 21:16:19 -05:00
// Return the token.
return array (
'status' => 'success' ,
'token' => $token
);
}
2016-03-23 21:56:06 -04:00
/**
* @ NoAdminRequired
* @ NoCSRFRequired
* @ PublicPage
* Returns general info about a file .
*/
public function wopiCheckFileInfo ( $fileId ){
$token = $this -> request -> getParam ( 'access_token' );
2016-06-26 20:51:06 +05:30
$arr = explode ( '_' , $fileId , 2 );
$version = '0' ;
if ( count ( $arr ) == 2 ) {
$fileId = $arr [ 0 ];
$version = $arr [ 1 ];
}
\OC :: $server -> getLogger () -> debug ( 'Getting info about file {fileId}, version {version} by token {token}.' , [ 'app' => $this -> appName , 'fileId' => $fileId , 'version' => $version , 'token' => $token ]);
2016-03-23 21:56:06 -04:00
$row = new Db\Wopi ();
$row -> loadBy ( 'token' , $token );
2016-06-26 20:51:06 +05:30
$res = $row -> getPathForToken ( $fileId , $version , $token );
2016-03-23 21:57:22 -04:00
if ( $res == false || http_response_code () != 200 )
{
return false ;
}
2016-03-23 21:56:06 -04:00
2016-07-18 16:10:59 +05:30
// Login the user to see his mount locations
$this -> loginUser ( $res [ 'owner' ]);
2016-06-18 20:43:00 -04:00
$view = new \OC\Files\View ( '/' . $res [ 'owner' ] . '/files' );
2016-03-23 21:56:06 -04:00
$info = $view -> getFileInfo ( $res [ 'path' ]);
2016-07-18 16:10:59 +05:30
// Close the session created for user login
\OC :: $server -> getSession () -> close ();
2016-03-23 21:56:06 -04:00
2016-07-18 16:10:59 +05:30
if ( ! $info ) {
http_response_code ( 404 );
return false ;
}
2016-08-23 19:42:12 +05:30
$editorName = \OC :: $server -> getUserManager () -> get ( $res [ 'editor' ]) -> getDisplayName ();
2016-07-18 16:10:59 +05:30
\OC :: $server -> getLogger () -> debug ( 'File info: {info}.' , [ 'app' => $this -> appName , 'info' => $info ]);
2016-03-23 21:56:06 -04:00
return array (
2016-07-18 16:10:59 +05:30
'BaseFileName' => $info [ 'name' ],
'Size' => $info [ 'size' ],
2016-08-23 19:42:12 +05:30
'Version' => $version ,
'UserId' => $res [ 'editor' ],
'UserFriendlyName' => $editorName
2016-03-23 21:56:06 -04:00
);
}
2016-03-08 21:16:19 -05:00
/**
* @ NoAdminRequired
* @ NoCSRFRequired
* @ PublicPage
* Given an access token and a fileId , returns the contents of the file .
* Expects a valid token in access_token parameter .
*/
public function wopiGetFile ( $fileId ){
$token = $this -> request -> getParam ( 'access_token' );
2016-06-26 20:51:06 +05:30
$arr = explode ( '_' , $fileId , 2 );
$version = '0' ;
if ( count ( $arr ) == 2 ) {
$fileId = $arr [ 0 ];
$version = $arr [ 1 ];
}
\OC :: $server -> getLogger () -> debug ( 'Getting contents of file {fileId}, version {version} by token {token}.' , [ 'app' => $this -> appName , 'fileId' => $fileId , 'version' => $version , 'token' => $token ]);
2016-03-08 21:16:19 -05:00
$row = new Db\Wopi ();
$row -> loadBy ( 'token' , $token );
//TODO: Support X-WOPIMaxExpectedSize header.
2016-06-26 20:51:06 +05:30
$res = $row -> getPathForToken ( $fileId , $version , $token );
2016-07-18 17:02:38 +05:30
$ownerid = $res [ 'owner' ];
2016-06-26 20:51:06 +05:30
2016-07-18 16:10:59 +05:30
// Login the user to see his mount locations
2016-07-18 17:02:38 +05:30
$this -> loginUser ( $ownerid );
2016-07-18 16:10:59 +05:30
2016-07-18 17:02:38 +05:30
$filename = '' ;
2016-06-26 20:51:06 +05:30
// If some previous version is requested, fetch it from Files_Version app
if ( $version !== '0' ) {
\OCP\JSON :: checkAppEnabled ( 'files_versions' );
// Setup the FS
\OC_Util :: tearDownFS ();
2016-07-17 00:53:12 +05:30
\OC_Util :: setupFS ( $ownerid , '/' . $ownerid . '/files' );
2016-06-26 20:51:06 +05:30
2016-07-18 17:02:38 +05:30
list ( $ownerid , $filename ) = \OCA\Files_Versions\Storage :: getUidAndFilename ( $res [ 'path' ]);
$filename = '/files_versions/' . $filename . '.v' . $version ;
2016-06-26 20:51:06 +05:30
\OC_Util :: tearDownFS ();
2016-07-18 17:02:38 +05:30
} else {
$filename = '/files' . $res [ 'path' ];
2016-06-26 20:51:06 +05:30
}
2016-07-18 17:02:38 +05:30
// Close the session created for user login
\OC :: $server -> getSession () -> close ();
return new DownloadResponse ( $this -> request , $ownerid , $filename );
2016-03-08 21:16:19 -05:00
}
/**
* @ NoAdminRequired
* @ NoCSRFRequired
* @ PublicPage
* Given an access token and a fileId , replaces the files with the request body .
* Expects a valid token in access_token parameter .
*/
public function wopiPutFile ( $fileId ){
$token = $this -> request -> getParam ( 'access_token' );
2016-06-26 20:51:06 +05:30
$arr = explode ( '_' , $fileId , 2 );
$version = '0' ;
if ( count ( $arr ) == 2 ) {
$fileId = $arr [ 0 ];
$version = $arr [ 1 ];
}
// Changing a previous version of the file is not possible
// Ignore WOPI put if such a request is encountered
if ( $version !== '0' ) {
return array (
'status' => 'success'
);
}
\OC :: $server -> getLogger () -> debug ( 'Putting contents of file {fileId}, version {version} by token {token}.' , [ 'app' => $this -> appName , 'fileId' => $fileId , 'version' => $version , 'token' => $token ]);
2016-03-08 21:16:19 -05:00
$row = new Db\Wopi ();
$row -> loadBy ( 'token' , $token );
2016-06-26 20:51:06 +05:30
$res = $row -> getPathForToken ( $fileId , $version , $token );
2016-06-18 20:06:02 -04:00
// Log-in as the user to regiser the change under her name.
2016-06-18 20:43:00 -04:00
$editorid = $res [ 'editor' ];
2016-07-16 23:54:56 +05:30
// 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 );
2016-06-18 20:06:02 -04:00
2016-06-18 20:43:00 -04:00
// Set up the filesystem view for the owner (where the file actually is).
$userid = $res [ 'owner' ];
2016-06-18 20:06:02 -04:00
$root = '/' . $userid . '/files' ;
2016-06-17 10:27:35 -04:00
$view = new \OC\Files\View ( $root );
2016-03-08 21:16:19 -05:00
// Read the contents of the file from the POST body and store.
2016-06-17 10:27:35 -04:00
$content = fopen ( 'php://input' , 'r' );
2016-06-18 20:43:00 -04:00
\OC :: $server -> getLogger () -> debug ( 'Storing file {fileId} by {editor} owned by {owner}.' , [ 'app' => $this -> appName , 'fileId' => $fileId , 'editor' => $editorid , 'owner' => $userid ]);
2016-03-13 23:23:57 -04:00
2016-06-17 10:27:35 -04:00
// Setup the FS which is needed to emit hooks (versioning).
\OC_Util :: tearDownFS ();
2016-06-18 20:06:02 -04:00
\OC_Util :: setupFS ( $userid , $root );
2016-06-17 10:27:35 -04:00
2016-03-08 21:16:19 -05:00
$view -> file_put_contents ( $res [ 'path' ], $content );
2016-06-17 10:27:35 -04:00
\OC_Util :: tearDownFS ();
2016-07-16 23:54:56 +05:30
// clear any session created before
\OC :: $server -> getSession () -> close ();
2016-03-08 21:16:19 -05:00
return array (
'status' => 'success'
);
}
2014-01-21 21:18:53 +03:00
/**
2014-10-23 23:08:55 +03:00
* @ NoAdminRequired
* @ PublicPage
2013-09-02 19:54:23 +03:00
* Process partial / complete file download
*/
2014-10-23 23:08:55 +03:00
public function serve ( $esId ){
2014-08-04 20:51:50 +03:00
$session = new Db\Session ();
2014-10-23 23:08:55 +03:00
$session -> load ( $esId );
2016-01-12 15:20:38 +01:00
2014-04-11 23:12:23 +03:00
$filename = $session -> getGenesisUrl () ? $session -> getGenesisUrl () : '' ;
2014-10-29 00:52:43 +03:00
return new DownloadResponse ( $this -> request , $session -> getOwner (), $filename );
2013-09-02 19:54:23 +03:00
}
2016-01-12 15:20:38 +01:00
2014-10-28 01:59:49 +03:00
/**
* @ NoAdminRequired
*/
public function download ( $path ){
2014-11-04 20:55:52 +03:00
if ( ! $path ){
$response = new JSONResponse ();
$response -> setStatus ( Http :: STATUS_BAD_REQUEST );
return $response ;
}
2016-01-12 15:20:38 +01:00
2014-11-04 20:55:52 +03:00
$fullPath = '/files' . $path ;
$fileInfo = \OC\Files\Filesystem :: getFileInfo ( $path );
if ( $fileInfo ){
2016-03-14 23:34:29 +01:00
$file = new File ( $fileInfo -> getId ());
$genesis = new Genesis ( $file );
$fullPath = $genesis -> getPath ();
2014-10-28 01:59:49 +03:00
}
2014-11-04 20:55:52 +03:00
return new DownloadResponse ( $this -> request , $this -> uid , $fullPath );
2014-10-28 01:59:49 +03:00
}
2016-01-12 15:20:38 +01:00
2014-10-29 00:52:43 +03:00
2014-10-23 23:08:55 +03:00
/**
* @ NoAdminRequired
*/
public function rename ( $fileId ){
$name = $this -> request -> post [ 'name' ];
2014-04-09 18:54:22 +03:00
2014-04-08 22:12:08 +03:00
$view = \OC\Files\Filesystem :: getView ();
$path = $view -> getPath ( $fileId );
2013-12-19 00:07:17 +03:00
2014-10-23 23:08:55 +03:00
if ( $name && $view -> is_file ( $path ) && $view -> isUpdatable ( $path )) {
2014-04-08 22:12:08 +03:00
$newPath = dirname ( $path ) . '/' . $name ;
if ( $view -> rename ( $path , $newPath )) {
2014-10-23 23:08:55 +03:00
return array ( 'status' => 'success' );
2013-12-19 00:07:17 +03:00
}
}
2014-10-23 23:08:55 +03:00
return array (
'status' => 'error' ,
2014-10-26 15:47:56 +03:00
'message' => ( string ) $this -> l10n -> t ( 'You don\'t have permission to rename this document' )
2014-10-23 23:08:55 +03:00
);
2013-12-19 00:07:17 +03:00
}
2013-09-02 19:54:23 +03:00
/**
2014-10-23 23:08:55 +03:00
* @ NoAdminRequired
2016-06-09 00:39:17 +05:30
* Get file information about single document with fileId
2013-09-02 19:54:23 +03:00
*/
2016-06-09 00:39:17 +05:30
public function get ( $fileId ){
2016-06-26 20:51:06 +05:30
$documents = array ();
2016-06-09 00:39:17 +05:30
$documents [ 0 ] = Storage :: getDocumentById ( $fileId );
2016-04-12 20:16:04 +02:00
2016-06-09 00:39:17 +05:30
return $this -> prepareDocuments ( $documents );
}
2013-09-02 19:54:23 +03:00
2016-06-09 00:39:17 +05:30
/**
* @ NoAdminRequired
* lists the documents the user has access to ( including shared files , once the code in core has been fixed )
* also adds session and member info for these files
*/
public function listAll (){
return $this -> prepareDocuments ( Storage :: getDocuments ());
2013-09-02 19:54:23 +03:00
}
2013-11-08 15:46:30 +00:00
}