1
0
mirror of https://github.com/typemill/typemill.git synced 2025-08-06 14:16:46 +02:00

Version 1.5.1: File restrictions, download controller, noindex, fix youtube, cyanine third teaser

This commit is contained in:
trendschau
2021-11-01 21:11:59 +01:00
parent 2e12e184d3
commit 7d662daf86
16 changed files with 422 additions and 122 deletions

View File

@@ -180,7 +180,7 @@ class ControllerAuthorArticleApi extends ControllerAuthor
# check if it is a folder and if the folder has published pages.
$message = false;
if($this->item->elementType == 'folder')
if($this->item->elementType == 'folder' && isset($this->item->folderContent))
{
foreach($this->item->folderContent as $folderContent)
{

View File

@@ -6,6 +6,7 @@ use Slim\Http\Request;
use Slim\Http\Response;
use Typemill\Models\ProcessImage;
use Typemill\Models\ProcessFile;
use Typemill\Models\WriteYaml;
use Typemill\Controllers\ControllerAuthorBlockApi;
class ControllerAuthorMediaApi extends ControllerAuthor
@@ -92,6 +93,69 @@ class ControllerAuthorMediaApi extends ControllerAuthor
return $response->withJson(['errors' => 'file not found or file name invalid'],404);
}
public function getFileRestrictions(Request $request, Response $response, $args)
{
# get params from call
$this->params = $request->getParams();
$this->uri = $request->getUri()->withUserInfo('');
$restriction = 'all';
$userroles = $this->c->acl->getRoles();
if(isset($this->params['filename']) && $this->params['filename'] != '')
{
$writeYaml = new WriteYaml();
$restrictions = $writeYaml->getYaml('media' . DIRECTORY_SEPARATOR . 'files', 'filerestrictions.yaml');
if(isset($restrictions[$this->params['filename']]))
{
$restriction = $restrictions[$this->params['filename']];
}
}
return $response->withJson(['userroles' => $userroles, 'restriction' => $restriction]);
}
public function updateFileRestrictions(Request $request, Response $response, $args)
{
# get params from call
$this->params = $request->getParams();
$this->uri = $request->getUri()->withUserInfo('');
$filename = isset($this->params['filename']) ? $this->params['filename'] : false;
$role = isset($this->params['role']) ? $this->params['role'] : false;
if(!$filename OR !$role)
{
return $response->withJson(['errors' => ['message' => 'Filename or userrole is missing.']], 422);
}
$userroles = $this->c->acl->getRoles();
if($role != 'all' AND !in_array($role, $userroles))
{
return $response->withJson(['errors' => ['message' => 'Userrole is unknown.']], 422);
}
$writeYaml = new WriteYaml();
$restrictions = $writeYaml->getYaml('media' . DIRECTORY_SEPARATOR . 'files', 'filerestrictions.yaml');
if(!$restrictions)
{
$restrictions = [];
}
if($role == 'all')
{
unset($restrictions[$filename]);
}
else
{
$restrictions[$filename] = $role;
}
$writeYaml->updateYaml('media' . DIRECTORY_SEPARATOR . 'files', 'filerestrictions.yaml', $restrictions);
return $response->withJson(['restrictions' => $restrictions]);
}
public function createImage(Request $request, Response $response, $args)
{
# get params from call
@@ -382,14 +446,14 @@ class ControllerAuthorMediaApi extends ControllerAuthor
return $response->withJson(['errors' => ['message' => 'Please check if your media-folder exists and all folders inside are writable.']], 500);
}
$tmpImage = $imageProcessor->createImage($imageData64, $desiredSizes);
$tmpImage = $imageProcessor->createImage($imageData64, $videoID, $desiredSizes);
if(!$tmpImage)
{
return $response->withJson(array('errors' => 'could not create temporary image'));
}
$imageUrl = $imageProcessor->publishImage($desiredSizes, $videoID);
$imageUrl = $imageProcessor->publishImage();
if($imageUrl)
{
$this->params['markdown'] = '![' . $class . '-video](' . $imageUrl . ' "click to load video"){#' . $videoID. ' .' . $class . '}';

View File

@@ -313,6 +313,7 @@ class ControllerAuthorMetaApi extends ControllerAuthor
# normalize the meta-input
$metaInput['navtitle'] = (isset($metaInput['navtitle']) && $metaInput['navtitle'] !== null )? $metaInput['navtitle'] : '';
$metaInput['hide'] = (isset($metaInput['hide']) && $metaInput['hide'] !== null) ? $metaInput['hide'] : false;
$metaInput['noindex'] = (isset($metaInput['noindex']) && $metaInput['noindex'] !== null) ? $metaInput['noindex'] : false;
# input values are empty but entry in structure exists
if(!$metaInput['hide'] && $metaInput['navtitle'] == "" && isset($extended[$this->item->urlRelWoF]))
@@ -327,10 +328,12 @@ class ControllerAuthorMetaApi extends ControllerAuthor
($this->hasChanged($metaInput, $metaPage['meta'], 'navtitle'))
OR
($this->hasChanged($metaInput, $metaPage['meta'], 'hide'))
OR
($this->hasChanged($metaInput, $metaPage['meta'], 'noindex'))
)
{
# add new file data. Also makes sure that the value is set.
$extended[$this->item->urlRelWoF] = ['hide' => $metaInput['hide'], 'navtitle' => $metaInput['navtitle']];
$extended[$this->item->urlRelWoF] = ['hide' => $metaInput['hide'], 'navtitle' => $metaInput['navtitle'], 'noindex' => $metaInput['noindex']];
$structure = true;
}

View File

@@ -0,0 +1,144 @@
<?php
namespace Typemill\Controllers;
use Typemill\Models\WriteYaml;
class ControllerDownload extends ControllerShared
{
public function download($request, $response, $args)
{
$filename = isset($args['params']) ? $args['params'] : false;
$root = $this->c->get('settings')['rootPath'];
$mediapath = 'media/files/';
$filepath = $root . $mediapath;
if(!$filename)
{
die('the requested file does not exist.');
}
# validate
$allowedFiletypes = [];
if(!$this->validate($filepath, $filename, $allowedFiletypes))
{
die('the requested file is not allowed.');
}
$writeYaml = new WriteYaml();
$restrictions = $writeYaml->getYaml('media' . DIRECTORY_SEPARATOR . 'files', 'filerestrictions.yaml');
if($restrictions && isset($restrictions[$mediapath . $filename]))
{
$allowedrole = $restrictions[$mediapath . $filename];
if(!isset($_SESSION['role']))
{
die("You have to be an authenticated $allowedrole to download this file.");
}
elseif(
$_SESSION['role'] != 'administrator'
AND $_SESSION['role'] != $allowedrole
AND !$this->c->acl->inheritsRole($_SESSION['role'], $allowedrole)
)
{
die("You have to be a $allowedrole to download this file.");
}
}
$file = $filepath . $filename;
# for now we only allow one download
$this->sendDownload($file);
exit;
}
/**
* Validate if the file exists and if
* there is a permission (download dir) to download this file
*
* You should ALWAYS call this method if you don't want
* somebody to download files not intended to be for the public.
*
* @param string $file GET parameter
* @param array $allowedFiletypes (defined in the head of this file)
* @return bool true if validation was successfull
*/
private function validate($path, $file, $allowedFiletypes)
{
$filepath = $path . $file;
# check if file exists
if (!isset($filepath) || empty($filepath) || !file_exists($filepath))
{
return false;
}
# check allowed filetypes
if(!empty($allowedFiletypes))
{
$fileAllowed = false;
foreach ($allowedFiletypes as $filetype)
{
if (strpos($file, $filetype) === (strlen($file) - strlen($filetype)))
{
$fileAllowed = true; //ends with $filetype
}
}
if (!$fileAllowed) return false;
}
# check download directory
if (strpos($file, '..') !== false)
{
return false;
}
return true;
}
/**
* Download function.
* Sets the HTTP header and supplies the given file
* as a download to the browser.
*
* @param string $file path to file
*/
private function sendDownload($file)
{
# Parse information
$pathinfo = pathinfo($file);
$extension = strtolower($pathinfo['extension']);
$mimetype = null;
# Get mimetype for extension
# This list can be extended as you need it.
# A good start to find mimetypes is the apache mime.types list
# http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
switch ($extension) {
case 'zip': $mimetype = "application/zip"; break;
default: $mimetype = "application/force-download";
}
# Required for some browsers like Safari and IE
if (ini_get('zlib.output_compression'))
{
ini_set('zlib.output_compression', 'Off');
}
header('Pragma: public');
header('Content-Encoding: none');
header('Expires: 0');
header('Accept-Ranges: bytes'); # Allow support for download resume
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($file)) . ' GMT');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private', false); # required for some browsers
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="'.basename($file).'";'); # Make the browser display the Save As dialog
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($file));
ob_end_flush();
readfile($file); # This is necessary in order to get it to actually download the file, otherwise it will be 0Kb
}
}

View File

@@ -177,7 +177,7 @@ abstract class ControllerShared
$pagetreeLive = Folder::scanFolder($this->settings['rootPath'] . $this->settings['contentFolder'], $draft = false );
# if there is content, then get the content details
if(count($pagetreeLive) > 0)
if($pagetreeLive && count($pagetreeLive) > 0)
{
# get the extended structure files with changes like navigation title or hidden pages
$yaml = new writeYaml();
@@ -295,28 +295,37 @@ abstract class ControllerShared
$opts = array(
'http'=>array(
'method'=>"GET",
'ignore_errors' => true,
'timeout' => 5
)
);
$context = stream_context_create($opts);
$context = stream_context_create($opts);
$resultBing = file_get_contents($pingBingUrl, false, $context);
$resultGoogle = file_get_contents($pingGoogleUrl, false, $context);
$responseBing = file_get_contents($pingBingUrl, false, $context);
$responseGoogle = file_get_contents($pingGoogleUrl, false, $context);
}
}
public function generateUrlSets($structureLive)
{
{
$urlset = '';
foreach($structureLive as $item)
{
if($item->elementType == 'folder')
if($item->elementType == 'folder' && isset($item->noindex) && $item->noindex === true)
{
$urlset .= $this->generateUrlSets($item->folderContent, $urlset);
}
elseif($item->elementType == 'folder')
{
$urlset = $this->addUrlSet($urlset, $item->urlAbs);
$urlset .= $this->generateUrlSets($item->folderContent, $urlset);
$urlset .= $this->generateUrlSets($item->folderContent, $urlset);
}
elseif(isset($item->noindex) && $item->noindex === true )
{
continue;
}
else
{