Added public page controller
Signed-off-by: Arne Hamann <git@arne.email>
This commit is contained in:
Родитель
f739970d9e
Коммит
81edfbc6aa
|
@ -14,6 +14,9 @@ return [
|
|||
['name' => 'page#do_echo', 'url' => '/echo', 'verb' => 'POST'],
|
||||
['name' => 'page#openGeoLink', 'url' => '/openGeoLink/{url}', 'verb' => 'GET'],
|
||||
['name' => 'public_favorite_page#sharedFavoritesCategory', 'url' => '/s/favorites/{token}', 'verb' => 'GET'],
|
||||
['name' => 'PublicPage#showShare', 'url' => '/s/{token}', 'verb' => 'GET'],
|
||||
['name' => 'PublicPage#showAuthenticate', 'url' => '/s/{token}/authenticate/{redirect}', 'verb' => 'GET'],
|
||||
['name' => 'PublicPage#authenticate', 'url' => '/s/{token}/authenticate/{redirect}', 'verb' => 'POST'],
|
||||
|
||||
|
||||
// utils
|
||||
|
@ -21,6 +24,10 @@ return [
|
|||
['name' => 'utils#saveOptionValue', 'url' => '/saveOptionValue', 'verb' => 'POST'],
|
||||
['name' => 'utils#setRoutingSettings', 'url' => '/setRoutingSettings', 'verb' => 'POST'],
|
||||
['name' => 'utils#getTrafficStyle', 'url' => '/style/traffic', 'verb' => 'GET'],
|
||||
['name' => 'PublicUtils#getOptionsValues', 'url' => '/s/{token}/getOptionsValues', 'verb' => 'GET'],
|
||||
['name' => 'PublicUtils#saveOptionValue', 'url' => '/s/{token}/saveOptionValue', 'verb' => 'POST'],
|
||||
['name' => 'PublicUtils#setRoutingSettings', 'url' => '/s/{token}/setRoutingSettings', 'verb' => 'POST'],
|
||||
['name' => 'PublicUtils#getTrafficStyle', 'url' => '/s/{token}/style/traffic', 'verb' => 'GET'],
|
||||
|
||||
// photos
|
||||
['name' => 'photos#getPhotosFromDb', 'url' => '/photos', 'verb' => 'GET'],
|
||||
|
|
|
@ -0,0 +1,257 @@
|
|||
<?php
|
||||
/**
|
||||
* Nextcloud - maps
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @authorVinzenz Rosenkranz <vinzenz.rosenkranz@gmail.com>
|
||||
* @copyright Vinzenz Rosenkranz 2017
|
||||
*/
|
||||
|
||||
namespace OCA\Maps\Controller;
|
||||
|
||||
use OC\InitialStateService;
|
||||
use OC\Security\CSP\ContentSecurityPolicy;
|
||||
use OCA\Files\Event\LoadSidebar;
|
||||
use OCA\Files_Sharing\Event\BeforeTemplateRenderedEvent;
|
||||
use OCA\Viewer\Event\LoadViewer;
|
||||
use OCP\AppFramework\AuthPublicShareController;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\IConfig;
|
||||
use OCP\ILogger;
|
||||
use OCP\IRequest;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\IInitialStateService;
|
||||
use OCP\ISession;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Share\Exceptions\ShareNotFound;
|
||||
use OCP\Share\IManager as ShareManager;
|
||||
|
||||
class PublicPageController extends AuthPublicShareController {
|
||||
protected InitialStateService $initialStateService;
|
||||
protected IConfig $config;
|
||||
protected ILogger $logger;
|
||||
protected \OCP\Activity\IManager $activityManager;
|
||||
protected IEventDispatcher $eventDispatcher;
|
||||
protected ShareManager $shareManager;
|
||||
protected IUserManager $userManager;
|
||||
|
||||
public function __construct($AppName,
|
||||
IRequest $request,
|
||||
IEventDispatcher $eventDispatcher,
|
||||
IConfig $config,
|
||||
IInitialStateService $initialStateService,
|
||||
IURLGenerator $urlGenerator,
|
||||
ShareManager $shareManager,
|
||||
IUserManager $userManager,
|
||||
ISession $session
|
||||
) {
|
||||
parent::__construct($AppName, $request, $session, $urlGenerator);
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
$this->config = $config;
|
||||
$this->initialStateService = $initialStateService;
|
||||
$this->shareManager = $shareManager;
|
||||
$this->userManager = $userManager;
|
||||
}
|
||||
|
||||
public function isValidToken(): bool {
|
||||
try {
|
||||
$this->share = $this->shareManager->getShareByToken($this->getToken());
|
||||
} catch (ShareNotFound $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getPasswordHash(): string {
|
||||
return $this->share->getPassword();
|
||||
}
|
||||
|
||||
protected function isPasswordProtected(): bool {
|
||||
return $this->share->getPassword() !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the permissions of the share
|
||||
*
|
||||
* @param Share\IShare $share
|
||||
* @return bool
|
||||
*/
|
||||
private function validateShare(\OCP\Share\IShare $share) {
|
||||
// If the owner is disabled no access to the link is granted
|
||||
$owner = $this->userManager->get($share->getShareOwner());
|
||||
if ($owner === null || !$owner->isEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the initiator of the share is disabled no access is granted
|
||||
$initiator = $this->userManager->get($share->getSharedBy());
|
||||
if ($initiator === null || !$initiator->isEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $share->getNode()->isReadable() && $share->getNode()->isShareable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \OCP\Files\File|\OCP\Files\Folder
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
private function getShareNode() {
|
||||
\OC_User::setIncognitoMode(true);
|
||||
|
||||
// Check whether share exists
|
||||
try {
|
||||
$share = $this->shareManager->getShareByToken($this->getToken());
|
||||
} catch (ShareNotFound $e) {
|
||||
// The share does not exists, we do not emit an ShareLinkAccessedEvent
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
if (!$this->validateShare($share)) {
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
return $share->getNode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @PublicPage
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function showShare(): TemplateResponse {
|
||||
$shareNode = $this->getShareNode();
|
||||
|
||||
$this->eventDispatcher->dispatch(LoadSidebar::class, new LoadSidebar());
|
||||
$this->eventDispatcher->dispatch(LoadViewer::class, new LoadViewer());
|
||||
|
||||
$params = array('user' => Null);
|
||||
$this->initialStateService->provideInitialState($this->appName, 'photos', $this->config->getAppValue('photos', 'enabled', 'no') === 'yes');
|
||||
$response = new TemplateResponse('maps', 'main', $params);
|
||||
|
||||
$this->addCsp($response);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @PublicPage
|
||||
* @NoCSRFRequired
|
||||
*
|
||||
* Show the authentication page
|
||||
* The form has to submit to the authenticate method route
|
||||
*/
|
||||
public function showAuthenticate(): TemplateResponse {
|
||||
$templateParameters = ['share' => $this->share];
|
||||
|
||||
$this->eventDispatcher->dispatchTyped(new BeforeTemplateRenderedEvent($this->share, BeforeTemplateRenderedEvent::SCOPE_PUBLIC_SHARE_AUTH));
|
||||
|
||||
$response = new TemplateResponse('core', 'publicshareauth', $templateParameters, 'guest');
|
||||
if ($this->share->getSendPasswordByTalk()) {
|
||||
$csp = new ContentSecurityPolicy();
|
||||
$csp->addAllowedConnectDomain('*');
|
||||
$csp->addAllowedMediaDomain('blob:');
|
||||
$response->setContentSecurityPolicy($csp);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* The template to show when authentication failed
|
||||
*/
|
||||
protected function showAuthFailed(): TemplateResponse {
|
||||
$templateParameters = ['share' => $this->share, 'wrongpw' => true];
|
||||
|
||||
$this->eventDispatcher->dispatchTyped(new BeforeTemplateRenderedEvent($this->share, BeforeTemplateRenderedEvent::SCOPE_PUBLIC_SHARE_AUTH));
|
||||
|
||||
$response = new TemplateResponse('core', 'publicshareauth', $templateParameters, 'guest');
|
||||
if ($this->share->getSendPasswordByTalk()) {
|
||||
$csp = new ContentSecurityPolicy();
|
||||
$csp->addAllowedConnectDomain('*');
|
||||
$csp->addAllowedMediaDomain('blob:');
|
||||
$response->setContentSecurityPolicy($csp);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* The template to show after user identification
|
||||
*/
|
||||
protected function showIdentificationResult(bool $success = false): TemplateResponse {
|
||||
$templateParameters = ['share' => $this->share, 'identityOk' => $success];
|
||||
|
||||
$this->eventDispatcher->dispatchTyped(new BeforeTemplateRenderedEvent($this->share, BeforeTemplateRenderedEvent::SCOPE_PUBLIC_SHARE_AUTH));
|
||||
|
||||
$response = new TemplateResponse('core', 'publicshareauth', $templateParameters, 'guest');
|
||||
if ($this->share->getSendPasswordByTalk()) {
|
||||
$csp = new ContentSecurityPolicy();
|
||||
$csp->addAllowedConnectDomain('*');
|
||||
$csp->addAllowedMediaDomain('blob:');
|
||||
$response->setContentSecurityPolicy($csp);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $response
|
||||
* @return void
|
||||
*/
|
||||
private function addCsp($response): void {
|
||||
if (class_exists('OCP\AppFramework\Http\ContentSecurityPolicy')) {
|
||||
$csp = new \OCP\AppFramework\Http\ContentSecurityPolicy();
|
||||
// map tiles
|
||||
$csp->addAllowedImageDomain('https://*.tile.openstreetmap.org');
|
||||
$csp->addAllowedImageDomain('https://server.arcgisonline.com');
|
||||
$csp->addAllowedImageDomain('https://*.cartocdn.com');
|
||||
$csp->addAllowedImageDomain('https://*.opentopomap.org');
|
||||
$csp->addAllowedImageDomain('https://*.cartocdn.com');
|
||||
$csp->addAllowedImageDomain('https://*.ssl.fastly.net');
|
||||
$csp->addAllowedImageDomain('https://*.openstreetmap.se');
|
||||
|
||||
// default routing engine
|
||||
$csp->addAllowedConnectDomain('https://*.project-osrm.org');
|
||||
$csp->addAllowedConnectDomain('https://api.mapbox.com');
|
||||
$csp->addAllowedConnectDomain('https://events.mapbox.com');
|
||||
$csp->addAllowedConnectDomain('https://graphhopper.com');
|
||||
|
||||
$csp->addAllowedChildSrcDomain('blob:');
|
||||
$csp->addAllowedWorkerSrcDomain('blob:');
|
||||
$csp->addAllowedScriptDomain('https://unpkg.com');
|
||||
// allow connections to custom routing engines
|
||||
$urlKeys = [
|
||||
'osrmBikeURL',
|
||||
'osrmCarURL',
|
||||
'osrmFootURL',
|
||||
'graphhopperURL'
|
||||
];
|
||||
foreach ($urlKeys as $key) {
|
||||
$url = $this->config->getAppValue('maps', $key);
|
||||
if ($url !== '') {
|
||||
$scheme = parse_url($url, PHP_URL_SCHEME);
|
||||
$host = parse_url($url, PHP_URL_HOST);
|
||||
$port = parse_url($url, PHP_URL_PORT);
|
||||
$cleanUrl = $scheme . '://' . $host;
|
||||
if ($port && $port !== '') {
|
||||
$cleanUrl .= ':' . $port;
|
||||
}
|
||||
$csp->addAllowedConnectDomain($cleanUrl);
|
||||
}
|
||||
}
|
||||
|
||||
// poi images
|
||||
$csp->addAllowedImageDomain('https://nominatim.openstreetmap.org');
|
||||
// search and geocoder
|
||||
$csp->addAllowedConnectDomain('https://nominatim.openstreetmap.org');
|
||||
$response->setContentSecurityPolicy($csp);
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче