implemented dynamic content controller loading, enabling whitelisting of content types. closes #87

This commit is contained in:
Chris
2020-06-06 13:27:47 +02:00
parent a2b7feb6f9
commit 5861e73848
9 changed files with 69 additions and 49 deletions

View File

@@ -10,10 +10,7 @@ include_once(ROOT.DS.'inc'.DS.'config.inc.php');
//loading core and controllers
include_once(ROOT . DS . 'inc' . DS. 'core.php');
require_once(ROOT . DS . 'content-controllers' . DS. 'image'. DS . 'image.controller.php');
require_once(ROOT . DS . 'content-controllers' . DS. 'text'. DS . 'text.controller.php');
require_once(ROOT . DS . 'content-controllers' . DS. 'url'. DS . 'url.controller.php');
require_once(ROOT . DS . 'content-controllers' . DS. 'video'. DS . 'video.controller.php');
loadAllContentControllers();
// check write permissions first
if(!isFolderWritable(ROOT.DS.'data'))

View File

@@ -10,10 +10,7 @@ include_once(ROOT.DS.'inc'.DS.'config.inc.php');
//loading core and controllers
include_once(ROOT . DS . 'inc' . DS. 'core.php');
require_once(ROOT . DS . 'content-controllers' . DS. 'image'. DS . 'image.controller.php');
require_once(ROOT . DS . 'content-controllers' . DS. 'text'. DS . 'text.controller.php');
require_once(ROOT . DS . 'content-controllers' . DS. 'url'. DS . 'url.controller.php');
require_once(ROOT . DS . 'content-controllers' . DS. 'video'. DS . 'video.controller.php');
loadAllContentControllers();
// check write permissions first
if(!isFolderWritable(ROOT.DS.'data'))

View File

@@ -10,7 +10,7 @@ include_once(ROOT.DS.'inc'.DS.'config.inc.php');
//loading core and controllers
include_once(ROOT . DS . 'inc' . DS. 'core.php');
require_once(ROOT . DS . 'content-controllers' . DS. 'video'. DS . 'video.controller.php');
loadAllContentControllers();
$hash = $_REQUEST['hash'];

View File

@@ -10,7 +10,9 @@ include_once(ROOT.DS.'inc'.DS.'config.inc.php');
//loading core and controllers
include_once(ROOT . DS . 'inc' . DS. 'core.php');
require_once(ROOT . DS . 'content-controllers' . DS. 'text'. DS . 'text.controller.php');
$controllers = loadAllContentControllers();
if(!in_array('TextController',$controllers))
exit(json_encode(array('status'=>'err','reason'=>'Text controller not enabled')));
// check write permissions first
if(!isFolderWritable(ROOT.DS.'data'))

View File

@@ -10,10 +10,7 @@ include_once(ROOT.DS.'inc'.DS.'config.inc.php');
//loading core and controllers
include_once(ROOT . DS . 'inc' . DS. 'core.php');
require_once(ROOT . DS . 'content-controllers' . DS. 'image'. DS . 'image.controller.php');
require_once(ROOT . DS . 'content-controllers' . DS. 'text'. DS . 'text.controller.php');
require_once(ROOT . DS . 'content-controllers' . DS. 'url'. DS . 'url.controller.php');
require_once(ROOT . DS . 'content-controllers' . DS. 'video'. DS . 'video.controller.php');
$allowedcontentcontrollers = loadAllContentControllers();
// check write permissions first
if(!isFolderWritable(ROOT.DS.'data'))
@@ -42,10 +39,22 @@ if ($_FILES['file']["error"] == UPLOAD_ERR_OK)
//cross check filetype for controllers
//
//image?
foreach($allowedcontentcontrollers as $cc)
{
if(in_array($type,(new $cc)->getRegisteredExtensions()))
{
$answer = (new $cc())->handleUpload($_FILES['file']['tmp_name'],$hash);
break;
}
}
/*
if(in_array($type,(new ImageController)->getRegisteredExtensions()))
{
$answer = (new ImageController())->handleUpload($_FILES['file']['tmp_name'],$hash);
}
//or, a text
else if($type=='text')
{
@@ -56,7 +65,7 @@ if ($_FILES['file']["error"] == UPLOAD_ERR_OK)
{
$answer = (new VideoController())->handleUpload($_FILES['file']['tmp_name'],$hash);
}
*/
if(!$answer)
$answer = array('status'=>'err','reason'=>'Unsupported filetype: '.$type,'filetype'=>$type);

View File

@@ -3,7 +3,7 @@
class TextController implements ContentController
{
//returns all extensions registered by this type of content
public function getRegisteredExtensions(){return array('txt');}
public function getRegisteredExtensions(){return array('txt','text','csv');}
public function handleHash($hash,$url)
{

View File

@@ -109,33 +109,17 @@ function architect($url)
$extension = pathinfo($hash, PATHINFO_EXTENSION);
//First, check if URL is an image
if(in_array($extension,(new ImageController)->getRegisteredExtensions()))
foreach(loadAllContentControllers() as $cc)
{
(new ImageController())->handleHash($hash,$u);
if(in_array($extension,(new $cc)->getRegisteredExtensions()))
{
(new $cc())->handleHash($hash,$u);
return;
}
//or, a url
else if(in_array($extension,(new UrlController)->getRegisteredExtensions()))
{
var_dump("Url");
}
//or, a text
else if(in_array($extension,(new TextController)->getRegisteredExtensions()))
{
(new TextController())->handleHash($hash,$u);
}
//or, a video
else if(in_array($extension,(new VideoController)->getRegisteredExtensions()))
{
(new VideoController())->handleHash($hash,$u);
}
//very odd. We know it's a valid hash but no controller says it's one of their kids
//oh well
else
{
var_dump("odd err");
}
http_response_code(404);
die("404");
}
//var_dump($u);
@@ -227,8 +211,6 @@ function mightBeAHash($string)
function autoload($className)
{
if (file_exists(ROOT . DS . 'content-controllers' . DS . strtolower($className) . '.php'))
require_once(ROOT . DS . 'content-controllers' . DS . strtolower($className) . '.php');
if (file_exists(ROOT . DS . 'interfaces' . DS . strtolower($className) . '.interface.php'))
require_once(ROOT . DS . 'interfaces' . DS . strtolower($className) . '.interface.php');
if ($className=='Encryption')
@@ -491,13 +473,18 @@ function getStorageControllers()
return $controllers;
}
function getAllContentControllers()
function loadAllContentControllers()
{
$allowedcontrollers = false;
if(defined('CONTENTCONTROLLERS') && CONTENTCONTROLLERS != '')
{
$allowedcontrollers = array_map('strtolower', explode(',',CONTENTCONTROLLERS));
}
$controllers = array();
if ($handle = opendir(ROOT.DS.'content-controllers')) {
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
if(is_dir(ROOT.DS.'content-controllers'.DS.$entry) && file_exists(ROOT.DS.'content-controllers'.DS.$entry.DS."$entry.controller.php"))
if(is_dir(ROOT.DS.'content-controllers'.DS.$entry) && file_exists(ROOT.DS.'content-controllers'.DS.$entry.DS."$entry.controller.php") && ( ($allowedcontrollers!==false && in_array($entry,$allowedcontrollers) ) || $allowedcontrollers===false))
{
$controllers[] = ucfirst($entry).'Controller';
include_once(ROOT.DS.'content-controllers'.DS.$entry.DS."$entry.controller.php");
@@ -513,7 +500,7 @@ function getAllContentControllers()
function getAllContentFiletypes()
{
$types = array();
$controllers = getAllContentControllers(true);
$controllers = loadAllContentControllers();
foreach($controllers as $c)
{
$types = array_merge($types,(new $c)->getRegisteredExtensions());
@@ -617,3 +604,19 @@ function isIPInRange( $ip, $range ) {
$netmask_decimal = ~ $wildcard_decimal;
return ( ( $ip_decimal & $netmask_decimal ) == ( $range_decimal & $netmask_decimal ) );
}
function loadContentControllers()
{
if(defined('CONTENTCONTROLLERS') && CONTENTCONTROLLERS != '')
{
$controllers = explode(',',CONTENTCONTROLLERS);
foreach($controllers as $controller)
{
$controller = strtolower($controller);
if(@file_exists(ROOT . DS . 'content-controllers' . DS. $controller. DS . $controller.'.controller.php'))
require_once(ROOT . DS . 'content-controllers' . DS. $controller. DS . $controller.'.controller.php');
}
}
else
loadAllContentControllers();
}

View File

@@ -10,10 +10,7 @@ include_once(ROOT.DS.'inc'.DS.'config.inc.php');
//loading core and controllers
include_once(ROOT.DS.'inc'.DS.'core.php');
require_once(ROOT . DS . 'content-controllers' . DS. 'image'. DS . 'image.controller.php');
require_once(ROOT . DS . 'content-controllers' . DS. 'text'. DS . 'text.controller.php');
require_once(ROOT . DS . 'content-controllers' . DS. 'url'. DS . 'url.controller.php');
require_once(ROOT . DS . 'content-controllers' . DS. 'video'. DS . 'video.controller.php');
loadAllContentControllers();
//send the URL to the architect. It'll know what to do

View File

@@ -22,6 +22,21 @@ In this file you can set the following options. For a simple working example con
| UPLOAD_CODE (NOT IMPLEMENTED | string | If set, all uploads require this code via GET or POST variable "uploadcode" or upload will fail |
| MAX_RESIZED_IMAGES (NOT IMPLEMENTED | string | If set, limits count of resized images/videos per file on server |
# Content controllers
PictShare is not limited to handling just images. Various content types including txt,mp4 and even url shortenings are supported.
By default all of these are enabled but if you only need one or more, you can whitelist them and all others won't be accessible.
|Option | value type | What it does|
|--- | --- | ---|
| CONTENTCONTROLLERS | CSV string | If set, will whitelist content controllers for your instance. Must be uppercase and can be comma separated. Example: Only Pictures: `IMAGE`, Pictures and Videos: `IMAGE,VIDEO` |
Available values for the `CONTENTCONTROLLERS` setting are:
- IMAGE
- TEXT
- VIDEO
- URL
# Storage controllers
PictShare has an extention system that allows handling of multiple storage solutions or backends. If a requested file is not found locally, PictShare will ask all configured storage controllers if they have it, then download and serve it to the user.