digitaldemocratic/docker/nextcloud/custom_apps/ownpad/lib/Controller/DisplayController.php

201 lines
6.9 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
/**
* Nextcloud - Ownpad
*
* This file is licensed under the Affero General Public License
* version 3 or later. See the COPYING file.
*
* @author Olivier Tétard <olivier.tetard@miskin.fr>
* @copyright Olivier Tétard <olivier.tetard@miskin.fr>, 2017
*/
namespace OCA\Ownpad\Controller;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\ContentSecurityPolicy;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\IUserSession;
use OCP\IConfig;
use EtherpadLite\Client;
class DisplayController extends Controller {
/** @var IURLGenerator */
private $urlGenerator;
/** @var IUserSession */
private $userSession;
/** @var IConfig */
private $config;
/** @var Client */
private $eplInstance;
/**
* @param string $AppName
* @param IRequest $request
* @param IURLGenerator $urlGenerator
*/
public function __construct(
$AppName,
IRequest $request,
IURLGenerator $urlGenerator,
IUserSession $userSession,
IConfig $config
) {
parent::__construct($AppName, $request);
$this->urlGenerator = $urlGenerator;
$this->userSession = $userSession;
$this->config = $config;
if($this->config->getAppValue('ownpad', 'ownpad_etherpad_enable', 'no') !== 'no' AND
$this->config->getAppValue('ownpad', 'ownpad_etherpad_useapi', 'no') !== 'no')
{
$eplHost = $this->config->getAppValue('ownpad', 'ownpad_etherpad_host', '');
$eplApiKey = $this->config->getAppValue('ownpad', 'ownpad_etherpad_apikey', '');
$this->eplInstance = new Client($eplApiKey, $eplHost . "/api");
}
}
/**
* @PublicPage
* @NoCSRFRequired
*
* @return TemplateResponse
*/
public function showPad($file, $dir) {
/*
* Filesystem is not setup per default on normal route since
* Nextcloud 21. More information:
* - https://github.com/nextcloud/server/issues/23210
* - https://github.com/nextcloud/server/pull/23821
*/
\OC_Util::setupFS();
/* Retrieve file content to find pads URL */
$path = \OC\Files\Filesystem::normalizePath($dir."/".$file);
$content = \OC\Files\Filesystem::file_get_contents($path);
preg_match('/URL=(.*)$/', $content, $matches);
$url = $matches[1];
$title = $file;
$eplHost = $this->config->getAppValue('ownpad', 'ownpad_etherpad_host', '');
$eplHost = rtrim($eplHost, '/');
$protectedPadRegex = sprintf('/%s\/p\/(g\.\w{16})\\$(.*)$/', preg_quote($eplHost, '/'));
$match = preg_match($protectedPadRegex, $url, $matches);
/*
* We are facing a “protected” pad. Call for Etherpad API to
* create the session and then properly configure the cookie.
*/
if($match) {
$groupID = $matches[1];
$username = $this->userSession->getUser()->getUID();
$displayName = $this->userSession->getUser()->getDisplayName();
$author = $this->eplInstance->createAuthorIfNotExistsFor($username, $displayName);
$session = $this->eplInstance->createSession($groupID, $author->authorID, time() + 3600);
$cookieDomain = $this->config->getAppValue('ownpad', 'ownpad_etherpad_cookie_domain', '');
setcookie('sessionID', $session->sessionID, 0, '/', $cookieDomain, true, false);
}
/*
* Not totally sure that this is the right way to proceed…
*
* First we decode the URL (to avoid double encode), then we
* replace spaces with underscore (as they are converted as
* such by Etherpad), then we encode the URL properly (and we
* avoid to urlencode() the protocol scheme).
*
* Magic urlencode() function was stolen from this answer on
* StackOverflow: <http://stackoverflow.com/a/7974253>.
*/
$url = urldecode($url);
$url = str_replace(' ', '_', $url);
$url = preg_replace_callback('#://([^/]+)/(=)?([^?]+)#', function ($match) {
return '://' . $match[1] . '/' . $match[2] . join('/', array_map('rawurlencode', explode('/', $match[3])));
}, $url);
$params = [
'urlGenerator' => $this->urlGenerator,
'url' => $url,
'title' => $title,
];
// Check for valid URL
// Get File-Ending
$split = explode(".", $file);
$fileending = $split[count($split)-1];
// Get Host-URL
if($fileending === "calc") {
$host = \OC::$server->getConfig()->getAppValue('ownpad', 'ownpad_ethercalc_host', false);
}
elseif($fileending === "pad") {
$host = \OC::$server->getConfig()->getAppValue('ownpad', 'ownpad_etherpad_host', false);
}
if(substr($host, -1, 1) !== '/') {
$host .= '/';
}
// Escape all RegEx-Characters
$hostreg = preg_quote($host);
// Escape all Slashes in URL to use in RegEx
$hostreg = preg_replace("/\//", "\/", $host);
// Final Regex-String
if($fileending === "calc") {
/*
* Ethercalc documents with “multisheet” support starts
* with a `=`.
*/
$regex = "/^".$hostreg."=?[^\/]+$/";
}
elseif($fileending === "pad") {
/*
* Etherpad documents can contain special characters, for
* “protected pads” for example.
*/
$regex = "/^".$hostreg."p\/[^\/]+$/";
}
// Show the Pad, if URL is valid
if (preg_match($regex, $url) === 1) {
$response = new TemplateResponse($this->appName, 'viewer', $params, 'blank');
}
else { // Show Error-Page
$response = new TemplateResponse($this->appName, 'noviewer', $params, 'blank');
}
/*
* Allow Etherpad and Ethercalc domains to the
* Content-Security-frame- list.
*
* This feature was introduced in ownCloud 8.1.
*/
$policy = new ContentSecurityPolicy();
if($this->config->getAppValue('ownpad', 'ownpad_etherpad_enable', 'no') !== 'no') {
$policy->addAllowedFrameDomain($this->config->getAppValue('ownpad', 'ownpad_etherpad_host', ''));
$policy->addAllowedChildSrcDomain($this->config->getAppValue('ownpad', 'ownpad_etherpad_host', ''));
}
if($this->config->getAppValue('ownpad', 'ownpad_ethercalc_enable', 'no') !== 'no') {
$policy->addAllowedFrameDomain($this->config->getAppValue('ownpad', 'ownpad_ethercalc_host', ''));
$policy->addAllowedChildSrcDomain($this->config->getAppValue('ownpad', 'ownpad_ethercalc_host', ''));
}
$response->setContentSecurityPolicy($policy);
return $response;
}
}