From fb733077eea161814c682b9c7a97e602aa93df8d Mon Sep 17 00:00:00 2001 From: Abel Hoogeveen Date: Fri, 15 Feb 2019 19:30:11 +0100 Subject: [PATCH] Updated minor changes. Creates version 1.2.0-RC1 --- composer.json | 8 ++-- src/Config/config.security.php | 48 +------------------ src/FuzeWorks/Input.php | 80 ++++++++++++++++++++++++++----- src/FuzeWorks/Output.php | 4 +- src/FuzeWorks/Security.php | 3 +- src/FuzeWorks/URI.php | 2 - src/FuzeWorks/WebComponent.php | 85 ++++++++++++++++++++++++--------- src/FuzeWorks/WebController.php | 29 +---------- src/FuzeWorks/WebModel.php | 27 +---------- src/FuzeWorks/WebView.php | 8 +++- 10 files changed, 150 insertions(+), 144 deletions(-) diff --git a/composer.json b/composer.json index d630e82..954b4a0 100644 --- a/composer.json +++ b/composer.json @@ -14,12 +14,12 @@ ], "require": { "php": ">=7.1.0", - "fuzeworks/core": "dev-development", - "fuzeworks/mvcr": "dev-master" + "fuzeworks/mvcr": "1.2.0-RC2", + "fuzeworks/core": "1.2.0-RC2" }, + "minimum-stability": "RC", "require-dev": { - "phpunit/phpunit": "^7", - "fuzeworks/tracycomponent": "dev-master" + "phpunit/phpunit": "^7" }, "autoload": { "psr-4": { diff --git a/src/Config/config.security.php b/src/Config/config.security.php index 891cda4..47749b9 100644 --- a/src/Config/config.security.php +++ b/src/Config/config.security.php @@ -49,56 +49,10 @@ return [ | 'csrf_regenerate' = Regenerate token on every submission | 'csrf_exclude_uris' = Array of URIs which ignore CSRF checks */ - 'csrf_protection' => false, + 'csrf_protection' => true, 'csrf_token_name' => 'fw_csrf_token', 'csrf_cookie_name' => 'fw_csrf_cookie', 'csrf_expire' => 7200, 'csrf_regenerate' => TRUE, 'csrf_exclude_uris' => array(), - - /* - |-------------------------------------------------------------------------- - | Standardize newlines - |-------------------------------------------------------------------------- - | - | Determines whether to standardize newline characters in input data, - | meaning to replace \r\n, \r, \n occurrences with the PHP_EOL value. - | - | This is particularly useful for portability between UNIX-based OSes, - | (usually \n) and Windows (\r\n). - | - */ - 'standardize_newlines' => FALSE, - - /* - |-------------------------------------------------------------------------- - | Global XSS Filtering - |-------------------------------------------------------------------------- - | - | Determines whether the XSS filter is always active when GET, POST or - | COOKIE data is encountered - | - | WARNING: This feature is DEPRECATED and currently available only - | for backwards compatibility purposes! - | - */ - 'global_xss_filtering' => FALSE, - - /* - |-------------------------------------------------------------------------- - | Reverse Proxy IPs - |-------------------------------------------------------------------------- - | - | If your server is behind a reverse proxy, you must whitelist the proxy - | IP addresses from which CodeIgniter should trust headers such as - | HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify - | the visitor's IP address. - | - | You can use both an array or a comma-separated list of proxy addresses, - | as well as specifying whole subnets. Here are a few examples: - | - | Comma-separated: '10.0.1.200,192.168.5.0/24' - | Array: array('10.0.1.200', '192.168.5.0/24') - */ - 'proxy_ips' => '' ]; \ No newline at end of file diff --git a/src/FuzeWorks/Input.php b/src/FuzeWorks/Input.php index f354262..463eef8 100644 --- a/src/FuzeWorks/Input.php +++ b/src/FuzeWorks/Input.php @@ -40,6 +40,9 @@ namespace FuzeWorks; use FuzeWorks\ConfigORM\ConfigORM; use Tracy\Debugger; +/** + * @todo Implement remaining methods from OldInput + */ class Input { /** @@ -69,6 +72,10 @@ class Input // Set the configuration $this->webConfig = Factory::getInstance()->config->getConfig('web'); + // If not handling requests, do not continue + if (!WebComponent::$willHandleRequest) + return; + // Sanitize all global arrays $this->sanitizeGlobals(); @@ -116,6 +123,11 @@ class Input Debugger::errorHandler($severity, $message, $file, $line, $context); } + /** + * Restores global arrays before handling by processes outside of FuzeWorks + * + * @internal + */ public function restoreGlobalArrays() { Logger::logInfo('Restoring global $_GET, $_POST, $_SERVER, $_COOKIE arrays'); @@ -235,6 +247,8 @@ class Input } /** + * Used to fetch variables from the global arrays + * * @param string $arrayName * @param null $index * @param bool $xssClean @@ -266,55 +280,97 @@ class Input return ($xssClean === true ? $this->security->xss_clean($value) : $value); } + /** + * Fetch variables from the global $_GET array + * + * @param string|array|null $index + * @param bool $xssClean + * @return mixed + */ public function get($index = null, bool $xssClean = true) { return $this->getFromInputArray('get', $index, $xssClean); } + /** + * Fetch variables from the global $_POST array + * + * @param string|array|null $index + * @param bool $xssClean + * @return mixed + */ public function post($index = null, bool $xssClean = true) { return $this->getFromInputArray('post', $index, $xssClean); } + /** + * Fetch variables from the global $_POST or $_GET array. Tries POST first + * + * @param string|array|null $index + * @param bool $xssClean + * @return mixed + */ public function postGet($index, bool $xssClean = true) { return isset($this->inputArray['post'][$index]) ? $this->post($index, $xssClean) : $this->get($index, $xssClean); } + /** + * Fetch variables from the global $_GET or $_POST array. Tries GET first + * + * @param string|array|null $index + * @param bool $xssClean + * @return mixed + */ public function getPost($index, bool $xssClean = true) { return isset($this->inputArray['get'][$index]) ? $this->get($index, $xssClean) : $this->post($index, $xssClean); } + /** + * Fetch variables from the global $_COOKIE array + * + * @param string|array|null $index + * @param bool $xssClean + * @return mixed + */ public function cookie($index = null, bool $xssClean = true) { return $this->getFromInputArray('cookie', $index, $xssClean); } + /** + * Fetch variables from the global $_SERVER array + * + * @param string|array|null $index + * @param bool $xssClean + * @return mixed + */ public function server($index = null, bool $xssClean = true) { return $this->getFromInputArray('server', $index, $xssClean); } /** - * @todo Extend with OldInput functionality + * Fetch the HTTP_USER_AGENT variable from the $_SERVER array + * + * @param string|array|null $index + * @param bool $xssClean + * @return mixed */ - public function ip() - { - $ip = ''; - // Validate IP - - $valid = ( - (bool)filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) || - (bool)filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) - ); - } - public function userAgent(bool $xssClean = true): string { return $this->getFromInputArray('server', 'HTTP_USER_AGENT', $xssClean); } + /** + * Fetch the REQUEST_METHOD variable from the $_SERVER array + * + * @param string|array|null $index + * @param bool $xssClean + * @return mixed + */ public function method(bool $xssClean = true): string { return $this->getFromInputArray('server', 'REQUEST_METHOD', $xssClean); diff --git a/src/FuzeWorks/Output.php b/src/FuzeWorks/Output.php index 16797c9..cfd66e7 100644 --- a/src/FuzeWorks/Output.php +++ b/src/FuzeWorks/Output.php @@ -38,9 +38,11 @@ namespace FuzeWorks; use FuzeWorks\ConfigORM\ConfigORM; -use FuzeWorks\Event\HelperLoadEvent; use FuzeWorks\Exception\OutputException; +/** + * @todo Implement caching + */ class Output { diff --git a/src/FuzeWorks/Security.php b/src/FuzeWorks/Security.php index d42036c..8398f80 100644 --- a/src/FuzeWorks/Security.php +++ b/src/FuzeWorks/Security.php @@ -45,6 +45,7 @@ use FuzeWorks\Exception\{ConfigException, SecurityException, Exception}; * @author EllisLab Dev Team * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/) * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/) + * @todo Complete rewrite */ class Security { @@ -200,7 +201,7 @@ class Security { $this->_csrf_set_hash(); } - $this->charset = strtoupper(Factory::getInstance()->config->get('web')->charset); + $this->charset = strtoupper(Factory::getInstance()->config->get('web')->get('charset')); } // -------------------------------------------------------------------- diff --git a/src/FuzeWorks/URI.php b/src/FuzeWorks/URI.php index 1763575..d135c5c 100644 --- a/src/FuzeWorks/URI.php +++ b/src/FuzeWorks/URI.php @@ -68,9 +68,7 @@ class URI $this->input = Factory::getInstance()->input; $this->config = Factory::getInstance()->config->getConfig('web'); if (WebComponent::$willHandleRequest) - { $this->determineUri(); - } } public function determineUri() diff --git a/src/FuzeWorks/WebComponent.php b/src/FuzeWorks/WebComponent.php index 451ec8e..a87a443 100644 --- a/src/FuzeWorks/WebComponent.php +++ b/src/FuzeWorks/WebComponent.php @@ -38,12 +38,14 @@ namespace FuzeWorks; use FuzeWorks\Exception\EventException; use FuzeWorks\Exception\Exception; +use FuzeWorks\Exception\HaltException; use FuzeWorks\Exception\NotFoundException; +use FuzeWorks\Exception\OutputException; +use FuzeWorks\Exception\RouterException; use FuzeWorks\Exception\WebException; class WebComponent implements iComponent { - /** * Whether WebComponent is configured to handle a web request * @@ -67,10 +69,6 @@ class WebComponent implements iComponent ]; } - /** - * @param Configurator $configurator - * @todo WebComponent will not always be running when added to FuzeWorks, move this into a separate method - */ public function onAddComponent(Configurator $configurator) { // Add dependencies @@ -95,23 +93,41 @@ class WebComponent implements iComponent { } + /** + * On initializing, Initialize UTF8 first, since it's a dependency for other componentClasses + */ public function init() { // First init UTF8 UTF8::init(); } + /** + * Enable the WebComponent to prepare for handling requests + */ public function enableComponent() { self::$willHandleRequest = true; } + /** + * Disable the WebComponent so it won't prepare for handling requests + */ public function disableComponent() { self::$willHandleRequest = false; } /** + * Handle a Web request. + * + * Retrieves URI string, routes this URI using the provided routes, + * appends output and adds listener to view output on shutdown. + * + * @return bool + * @throws HaltException + * @throws OutputException + * @throws RouterException * @throws WebException */ public function routeWebRequest(): bool @@ -119,31 +135,32 @@ class WebComponent implements iComponent if (!self::$willHandleRequest) throw new WebException("Could not route web request. WebComponent is not configured to handle requests"); - // Set the output to display when shutting down try { + // Set the output to display when shutting down Events::addListener(function () { /** @var Output $output */ Logger::logInfo("Parsing output..."); $output = Factory::getInstance()->output; $output->display(); }, 'coreShutdownEvent', Priority::NORMAL); + + // Create an error 500 page when a haltEvent is fired + Events::addListener([$this, 'haltEventListener'], 'haltExecutionEvent', Priority::NORMAL); } catch (EventException $e) { throw new WebException("Could not route web request. coreShutdownEvent threw EventException: '".$e->getMessage()."'"); } /** @var Router $router */ - $router = Factory::getInstance()->router; - - /** @var URI $uriObject */ - $uriObject = Factory::getInstance()->uri; - $uri = $uriObject->uriString(); - + /** @var URI $uri */ /** @var Output $output */ + $router = Factory::getInstance()->router; + $uri = Factory::getInstance()->uri; $output = Factory::getInstance()->output; // Attempt to load the requested page try { - $viewOutput = $router->route($uri); + $uriString = $uri->uriString(); + $viewOutput = $router->route($uriString); } catch (NotFoundException $e) { Logger::logWarning("Requested page not found. Requesting Error/error404 View"); $output->setStatusHeader(404); @@ -158,15 +175,6 @@ class WebComponent implements iComponent Logger::exceptionHandler($e, false); $viewOutput = 'ERROR 404. Page was not found.'; } - } catch (Exception $e) { - Logger::exceptionHandler($e, false); - $output->setStatusHeader(500); - try { - $viewOutput = $router->route('Error/error500'); - } catch (Exception $error500Exception) { - Logger::exceptionHandler($error500Exception, false); - $viewOutput = 'ERROR 500. Page could not be loaded.'; - } } // Append the output @@ -175,4 +183,37 @@ class WebComponent implements iComponent return true; } + + /** + * Listener for haltExecutionEvent + * + * Fired when FuzeWorks halts it's execution. Loads an error 500 page. + * + * @param $event + */ + public function haltEventListener($event) + { + // Dependencies + /** @var Output $output */ + /** @var Router $router */ + /** @var Event $event */ + $output = Factory::getInstance()->output; + $router = Factory::getInstance()->router; + + // Cancel event + $event->setCancelled(true); + + try { + // And handle consequences + Logger::logError("Execution halted. Providing error 500 page."); + $output->setStatusHeader(500); + $viewOutput = $router->route('Error/error500'); + } catch (Exception $error500Exception) { + Logger::exceptionHandler($error500Exception, false); + $viewOutput = 'ERROR 500. Page could not be loaded.'; + } + + // Finally append output and shutdown + $output->appendOutput($viewOutput); + } } \ No newline at end of file diff --git a/src/FuzeWorks/WebController.php b/src/FuzeWorks/WebController.php index bc0dbec..00734b7 100644 --- a/src/FuzeWorks/WebController.php +++ b/src/FuzeWorks/WebController.php @@ -36,33 +36,6 @@ namespace FuzeWorks; -class WebController extends Controller +abstract class WebController extends Controller { - - /** - * @var Input - */ - protected $input; - - /** - * @var Output - */ - protected $output; - - /** - * @var URI - */ - protected $uri; - - /** - * WebView constructor. - */ - public function __construct() - { - parent::__construct(); - $this->input = Factory::getInstance()->input; - $this->output = Factory::getInstance()->output; - $this->uri = Factory::getInstance()->uri; - } - } \ No newline at end of file diff --git a/src/FuzeWorks/WebModel.php b/src/FuzeWorks/WebModel.php index 92207e5..75c20a2 100644 --- a/src/FuzeWorks/WebModel.php +++ b/src/FuzeWorks/WebModel.php @@ -36,31 +36,6 @@ namespace FuzeWorks; -class WebModel extends Model +abstract class WebModel extends Model { - /** - * @var Input - */ - protected $input; - - /** - * @var Output - */ - protected $output; - - /** - * @var URI - */ - protected $uri; - - /** - * WebView constructor. - */ - public function __construct() - { - parent::__construct(); - $this->input = Factory::getInstance()->input; - $this->output = Factory::getInstance()->output; - $this->uri = Factory::getInstance()->uri; - } } \ No newline at end of file diff --git a/src/FuzeWorks/WebView.php b/src/FuzeWorks/WebView.php index 02fc2fd..6e4bd78 100644 --- a/src/FuzeWorks/WebView.php +++ b/src/FuzeWorks/WebView.php @@ -36,7 +36,7 @@ namespace FuzeWorks; -class WebView extends View +abstract class WebView extends View { /** * @var Input @@ -53,6 +53,11 @@ class WebView extends View */ protected $uri; + /** + * @var Security + */ + protected $security; + /** * WebView constructor. */ @@ -62,5 +67,6 @@ class WebView extends View $this->input = Factory::getInstance()->input; $this->output = Factory::getInstance()->output; $this->uri = Factory::getInstance()->uri; + $this->security = Factory::getInstance()->security; } } \ No newline at end of file