From bca8c51e0a3a43f90063a7a6b2c8111cba0d761d Mon Sep 17 00:00:00 2001 From: crose <carsten.rose@math.uzh.ch> Date: Fri, 22 Feb 2019 13:38:15 +0100 Subject: [PATCH] Start refactor to extend HTTP_STATUS Code in exception. --- extension/Documentation/Manual.rst | 78 +++++++++++++------ extension/Source/api/rest.php | 20 ++++- extension/Source/core/Constants.php | 3 + extension/Source/core/QuickFormQuery.php | 37 ++++++--- .../core/exceptions/AbstractException.php | 31 ++++++-- .../Source/core/exceptions/CodeException.php | 8 +- .../Source/core/exceptions/DbException.php | 7 ++ .../core/exceptions/DownloadException.php | 9 ++- .../NotAcceptableResponseException.php | 52 +++++++++++++ .../Source/core/exceptions/RestException.php | 52 +++++++++++++ .../Source/core/exceptions/ShellException.php | 9 ++- .../core/exceptions/UserFormException.php | 9 ++- .../core/exceptions/UserReportException.php | 9 ++- extension/Source/core/helper/Logger.php | 1 + 14 files changed, 263 insertions(+), 62 deletions(-) create mode 100644 extension/Source/core/exceptions/NotAcceptableResponseException.php create mode 100644 extension/Source/core/exceptions/RestException.php diff --git a/extension/Documentation/Manual.rst b/extension/Documentation/Manual.rst index 316b49009..50993de54 100644 --- a/extension/Documentation/Manual.rst +++ b/extension/Documentation/Manual.rst @@ -9,6 +9,9 @@ .. .. -------------------------------------------------- .. Best Practice T3 reST https://docs.typo3.org/typo3cms/drafts/github/xperseguers/RstPrimer/ +.. Italic *italic* +.. Bold **bold** +.. Code ``text`` .. External Links: `Bootstrap <http://getbootstrap.com/>`_ .. Add Images: https://wiki.typo3.org/ReST_Syntax#Images ... .. @@ -7459,7 +7462,7 @@ To define a QFQ form becomes a REST form by enable one or more of: Form: Access > Permit REST: get / insert / update / delete Endpoint -^^^^^^^^ +-------- .. tip:: @@ -7498,7 +7501,7 @@ Only the last <level> of an URI will be processed. The former ones are just to f GET - Read -^^^^^^^^^^ +---------- A REST (GET) form has two modes: :: @@ -7524,39 +7527,69 @@ Form: +-------------------+------------------------------------------------------------------------------+ | Attribute | Description | +===================+==============================================================================+ -| name=<level> | Level name in URI | +| name | *<level>* Mandatory. Level name (Endpoint) in URI. | +-------------------+------------------------------------------------------------------------------+ -| permitNew=rest | The form can be loaded in REST mode with mising parameter 'id' or 'id=0' | +| table | Mandatory. Name of the primary table | +-------------------+------------------------------------------------------------------------------+ -| permitEdit=rest | The form can be loaded in REST mode with parameter 'id' > 0 | +| Permit REST | *get* Mandatory. The form can be loaded in REST mode. | +-------------------+------------------------------------------------------------------------------+ Form.parameter: ++-------------------+----------------------------------------------------------------------------------+ +| Attribute | Description | ++===================+==================================================================================+ +| restSqlData | Mandatory. SQL query selects content shown in data mode. | +| | | ``restSqlData={{!SELECT id, name, gender FROM Person WHERE id='{{r:T0}}'' }}`` | ++-------------------+----------------------------------------------------------------------------------+ +| restSqlList | Mandatory. SQL query selects content shown in data mode. | +| | | ``restSqlData={{!SELECT id, name FROM Person }}`` | ++-------------------+----------------------------------------------------------------------------------+ +| restParam | Optional. CSV list of variable names. E.g.: ``restParam=pId,adrId`` | ++-------------------+----------------------------------------------------------------------------------+ +| restToken | Optional. User defined string or dynamic token (see below). | ++-------------------+----------------------------------------------------------------------------------+ + +.. note: + + There are no `special-column-names`_ available in `restSqlData` or `restSqlList`. Also there are no + SIPs possible, cause REST typically does not offer sessions/cookies (which are necessary for SIPs). + + +POST - Insert +------------- + +Form: + +-------------------+------------------------------------------------------------------------------+ | Attribute | Description | +===================+==============================================================================+ -| restSqlData | SQL query selects content shown in data mode. | -| | `restSqlData={{!SELECT id, name, gender FROM Person WHERE id='{{r:T0}}'' }}` | -+-------------------+------------------------------------------------------------------------------+ -| restSqlList | SQL query selects content shown in data mode. | -| | `restSqlData={{!SELECT id, name FROM Person }}` | +| name | *<level>* Mandatory. Level name (Endpoint) in URI. | +-------------------+------------------------------------------------------------------------------+ -| restParam | Optional. CSV list of variable names. E.g.: `restParam=pId,adrId` | +| table | Mandatory. Name of the primary table | +-------------------+------------------------------------------------------------------------------+ -| restToken | Optional. User defined string. For dynamic token see below. | +| Permit REST | *insert* Mandatory. The form can be loaded in REST mode. | +-------------------+------------------------------------------------------------------------------+ +| id | Missing or '0'. -.. note: +PUT - Update +------------ + +DELETE - Delete +--------------- - There are no `special-column-names`_ available in `restSqlData` or `restSqlList`. Also there are no - SIPs possible, cause REST typically does not offer sessions/cookies (which are necessary for SIPs). Authorization ------------- -By default, the REST API is public accessible. +A QFQ form is only acessible via REST API, if ``Form.permitREST`` enables the HTTP Method (get, post, put, delete) + +``Permit New`` or ``Permit Edit`` don't apply to QFQ forms called via REST. + +.. important:: + + By default, the REST API is public accessible. If this is not wished, HTTP AUTH might be used (configured via webserver) or the QFQ internal 'HTTP header token based authorization'. @@ -7564,10 +7597,9 @@ QFQ internal 'HTTP header token based authorization'. Token based authorization ^^^^^^^^^^^^^^^^^^^^^^^^^ -A form will require a 'token based authorization', as soon as there is a `form.parameter.restToken` defined. -Therefore the HTTP Header 'Authorization' has to be set with `token=<secret token>`. The 'secret token' will -be checked against the server. Using HTTPS, such token can't be sniffed and will typically not be logged in -any server logs. +A form will require a 'token based authorization', as soon as there is a ``form.parameter.restToken`` defined. +Therefore the HTTP Header 'Authorization' has to be set with ``token=<secret token>``. The 'secret token' will +be checked against the server. Example: :: @@ -7578,9 +7610,11 @@ Example: :: The static setup with `form.parameter.restToken=myCrypticString0123456789 is fine, as long as only one token exist. In case of multiple tokens, replace the static string against a SQL query. -General: The HTML Header Authorization token is available in STORE_CLIENT via '`{{Authorization:C:alnumx}}`. +.. tip:: + + The HTML Header Authorization token is available in STORE_CLIENT via '`{{Authorization:C:alnumx}}`. -For example all created tokens are saved in a table 'Auth' with a column 'token'. Define: :: +Best Practice: For example all created tokens are saved in a table 'Auth' with a column 'token'. Define:: form.parameter.restToken={{SELECT a.token FROM Auth AS a WHERE a.token='{{Authorization:C:alnumx}}' }} diff --git a/extension/Source/api/rest.php b/extension/Source/api/rest.php index 4aca469d8..250e219d6 100644 --- a/extension/Source/api/rest.php +++ b/extension/Source/api/rest.php @@ -19,6 +19,7 @@ $restId = array(); $restForm = array(); $status = 'HTTP/1.0 409 Bad Request'; +$data = array(); try { try { @@ -39,13 +40,13 @@ try { if ($id != 0) { throw new UserFormException('Method POST needs no id or id=0', ERROR_REST_INVALID_ID); } - $_POST = json_decode(file_get_contents('php://input'), true); + $data = json_decode(file_get_contents('php://input'), true); break; case REQUEST_METHOD_PUT: if ($id == 0) { throw new UserFormException('Method PUT needs an id>0', ERROR_REST_INVALID_ID); } - $_POST = json_decode(file_get_contents('php://input'), true); + $data = json_decode(file_get_contents('php://input'), true); break; case REQUEST_METHOD_DELETE: if ($id == 0) { @@ -56,20 +57,33 @@ try { break; } + if ($data === null) { + throw new NotAcceptableResponseException( + json_encode([ERROR_MESSAGE_TO_USER => 'Invalid JSON', + ERROR_MESSAGE_SUPPORT => json_last_error_msg()]), ERROR_INVALID_VALUE); + } + + if(!empty($data)){ + $_POST = $data; + } + $qfq = new QuickFormQuery(['bodytext' => $bodytext]); $answer = $qfq->rest($restId, $restForm); $status = 'HTTP/1.0 200 OK'; } catch (qfq\CodeException $e) { $answer[API_MESSAGE] = $e->formatMessage(); + $status=$e->getHttpStatus(); } catch (qfq\UserFormException $e) { $answer[API_MESSAGE] = $e->formatMessage(); + $status=$e->getHttpStatus(); } catch (qfq\DbException $e) { $answer[API_MESSAGE] = $e->formatMessage(); - + $status=$e->getHttpStatus(); } + } catch (\Exception $e) { $answer[API_MESSAGE] = "Generic Exception: " . $e->getMessage(); } diff --git a/extension/Source/core/Constants.php b/extension/Source/core/Constants.php index 3f8c29427..75e4f9ef7 100644 --- a/extension/Source/core/Constants.php +++ b/extension/Source/core/Constants.php @@ -141,6 +141,7 @@ const KVP_VALUE_GIVEN = 'value_given'; const ERROR_MESSAGE_TO_USER = 'toUser'; // always shown to the user. const ERROR_MESSAGE_SUPPORT = 'support'; // Message to help the developer to understand the problem. const ERROR_MESSAGE_OS = 'os'; // Error message from the OS - like 'file not found' or specific SQL problem +const ERROR_MESSAGE_HTTP_STATUS = 'httpStatus'; // HTTP Status Code to report // QFQ Error Codes const ERROR_UNKNOW_SANITIZE_CLASS = 1001; @@ -1762,3 +1763,5 @@ const ATTRIBUTE_DATA_REFERENCE = 'data-reference'; // REST const HTTP_HEADER_AUTHORIZATION = 'Authorization'; +const HTTP_401 = '401 Unauthorized'; +const HTTP_403 = '403 Forbidden'; \ No newline at end of file diff --git a/extension/Source/core/QuickFormQuery.php b/extension/Source/core/QuickFormQuery.php index c9654862d..98bc51a5e 100644 --- a/extension/Source/core/QuickFormQuery.php +++ b/extension/Source/core/QuickFormQuery.php @@ -546,7 +546,7 @@ class QuickFormQuery { if ($formMode == FORM_REST) { $data = ['id' => $rc]; - $flagApiStructureReGroup=false; + $flagApiStructureReGroup = false; break; } @@ -588,7 +588,7 @@ class QuickFormQuery { break; case FORM_REST: - $flagApiStructureReGroup=false; + $flagApiStructureReGroup = false; $data = $this->doRestGet(); break; @@ -596,7 +596,7 @@ class QuickFormQuery { throw new CodeException("This statement should never be reached", ERROR_CODE_SHOULD_NOT_HAPPEN); } - if ($flagApiStructureReGroup && is_array($data) ) { + if ($flagApiStructureReGroup && is_array($data)) { // $data['element-update']=... $data = $this->groupElementUpdateEntries($data); } @@ -632,6 +632,7 @@ class QuickFormQuery { * If not: throw an exception. * * @param string|array $serverToken + * @throws RestException * @throws CodeException * @throws UserFormException */ @@ -642,7 +643,8 @@ class QuickFormQuery { return; } - if ($serverToken === $this->store::getVar(HTTP_HEADER_AUTHORIZATION, STORE_CLIENT . STORE_EMPTY, SANITIZE_ALLOW_ALL)) { + $clientToken = $this->store::getVar(HTTP_HEADER_AUTHORIZATION, STORE_CLIENT, SANITIZE_ALLOW_ALL); + if ($serverToken === $clientToken) { return; } @@ -650,7 +652,17 @@ class QuickFormQuery { $seconds = $this->store::getVar(SYSTEM_SECURITY_FAILED_AUTH_DELAY, STORE_SYSTEM); sleep($seconds); - throw new UserFormException('Missing or wrong authorization token', ERROR_REST_AUTHORIZATION); + if ($clientToken == false) { + throw new RestException(json_encode([ERROR_MESSAGE_TO_USER => 'Missing authorization token', + ERROR_MESSAGE_SUPPORT => "Missing HTTP Header: " . HTTP_HEADER_AUTHORIZATION, + ERROR_MESSAGE_HTTP_STATUS => HTTP_401 + ]), ERROR_REST_AUTHORIZATION); + } + + throw new RestException(json_encode([ERROR_MESSAGE_TO_USER => 'Authorization token not accepted', + ERROR_MESSAGE_SUPPORT => "Missing HTTP Header: " . HTTP_HEADER_AUTHORIZATION, + ERROR_MESSAGE_HTTP_STATUS => HTTP_401 + ]), ERROR_REST_AUTHORIZATION); } /** @@ -1423,9 +1435,9 @@ class QuickFormQuery { * @param string $formMode * * @return bool 'true' if SIP exists, else 'false' - * @throws \qfq\CodeException - * @throws \qfq\UserFormException - * @internal param $foundInStore + * @throws RestException + * @throws CodeException + * @throws UserFormException */ private function validateForm($formNameFoundInStore, $formMode, &$formModeNew) { @@ -1458,7 +1470,7 @@ class QuickFormQuery { $method = $this->store::getVar(CLIENT_REQUEST_METHOD, STORE_CLIENT); if (false === Support::findInSet(strtolower($method), $this->formSpec[F_REST_METHOD])) { - throw new UserFormException("Form '" . $this->formSpec[F_NAME] . "' is not allowed with method '$method'", ERROR_FORM_REST); + throw new RestException("Endpoint '" . $this->formSpec[F_NAME] . "' is not allowed with method '$method'", ERROR_FORM_REST); } $this->restCheckAuthToken($this->formSpec[F_REST_TOKEN] ?? ''); @@ -1467,6 +1479,11 @@ class QuickFormQuery { case REQUEST_METHOD_GET: break; case REQUEST_METHOD_POST: + if ($r != 0) { + throw new RestException('Mode GET with id>0 is forbidden', ERROR_UNKNOWN_MODE); + } + $formModeNew = FORM_SAVE; + break; case REQUEST_METHOD_PUT: $formModeNew = FORM_SAVE; break; @@ -1474,7 +1491,7 @@ class QuickFormQuery { $formModeNew = FORM_DELETE; break; default: - throw new CodeException('Unknown Request Method: ' . $method, ERROR_UNKNOWN_MODE); + throw new RestException('Unknown Request Method: ' . $method, ERROR_UNKNOWN_MODE); } } else { diff --git a/extension/Source/core/exceptions/AbstractException.php b/extension/Source/core/exceptions/AbstractException.php index cb0243ba3..dc03ca98e 100644 --- a/extension/Source/core/exceptions/AbstractException.php +++ b/extension/Source/core/exceptions/AbstractException.php @@ -29,10 +29,11 @@ require_once(__DIR__ . '/../helper/Support.php'); * * Throw with message for User and message for Support. * - * throw new UserFormException( json_encode( - * [ERROR_MESSAGE_TO_USER => 'Failed: chmod', - * ERROR_MESSAGE_SUPPORT => "Failed: chmod $mode '$pathFileName'"]), - * ERROR_IO_CHMOD); + throw new UserFormException( json_encode( + [ERROR_MESSAGE_TO_USER => 'Failed: chmod', + ERROR_MESSAGE_SUPPORT => "Failed: chmod $mode '$pathFileName'", + ERROR_MESSAGE_HTTP_STATUS => 'HTTP/1.0 409 Bad Request' ]), + ERROR_IO_CHMOD); * * @package qfq */ @@ -46,6 +47,8 @@ class AbstractException extends \Exception { protected $file = ''; protected $line = ''; + protected $httpStatusCode = '400 Bad Request'; + /** * $this->getMessage() might give * a) a simple string, or @@ -92,10 +95,17 @@ class AbstractException extends \Exception { $msg = $this->getMessage(); $arrMsg = json_decode($msg, true); if ($arrMsg === null) { + $arrShow[EXCEPTION_MESSAGE] = $msg; $arrMsg[ERROR_MESSAGE_TO_USER] = $msg; + } else { $arrShow[EXCEPTION_MESSAGE] = $arrMsg[ERROR_MESSAGE_TO_USER]; + + if (isset($arrMsg[ERROR_MESSAGE_HTTP_STATUS])) { + $this->httpStatusCode = $arrMsg[ERROR_MESSAGE_HTTP_STATUS]; + } + } $arrDebugHidden[EXCEPTION_FILE] = $this->getFile(); @@ -137,7 +147,7 @@ class AbstractException extends \Exception { if (!empty($os = $arrMerged[ERROR_MESSAGE_OS] ?? '')) { // [ mysqli: 1146 ] Table 'qfq_db.UNKNOWN_TABLE' doesn't exist - $before=$this->getTableToken( html_entity_decode($arrMerged[ERROR_MESSAGE_OS],ENT_QUOTES)); + $before = $this->getTableToken(html_entity_decode($arrMerged[ERROR_MESSAGE_OS], ENT_QUOTES)); $arrMerged[EXCEPTION_SQL_FINAL] = $this->sqlHighlightError($arrMerged[ERROR_MESSAGE_OS], 'mysqli: 1146', $arrMerged[EXCEPTION_SQL_FINAL], $before, "' doesn't exist"); $arrMerged[EXCEPTION_SQL_FINAL] = $this->sqlHighlightError($arrMerged[ERROR_MESSAGE_OS], 'mysqli: 1064', $arrMerged[EXCEPTION_SQL_FINAL], "the right syntax to use near '", "' at line [0-9]*$"); // [ mysqli: 1054 ] Unknown column "noPsp.pspElement' in 'field list" | "... in 'order clause'" @@ -173,6 +183,13 @@ class AbstractException extends \Exception { } + /** + * @return string + */ + public function getHttpStatus() { + return $this->$this->httpStatusCode; + } + /** * Extract 'beforeMatch', incl. dynamic db name as token to do underlining later. * E.g.: "[ mysqli: 1146 ] Table 'qfq_db.UNKNOWN_TABLE' doesn't exist" @@ -184,8 +201,8 @@ class AbstractException extends \Exception { private function getTableToken($os) { $subject = "Table '.*' "; $arr = preg_match("/$subject/", $os, $matches); - $arr= explode('.', $matches[0]??''); - return ($arr[0]??'') . '.'; + $arr = explode('.', $matches[0] ?? ''); + return ($arr[0] ?? '') . '.'; } /** diff --git a/extension/Source/core/exceptions/CodeException.php b/extension/Source/core/exceptions/CodeException.php index 125a96331..cea02cc25 100644 --- a/extension/Source/core/exceptions/CodeException.php +++ b/extension/Source/core/exceptions/CodeException.php @@ -21,10 +21,10 @@ require_once(__DIR__ . '/AbstractException.php'); * * Throw with message for User and message for Support. * - * throw new UserFormException( json_encode( - * [ERROR_MESSAGE_TO_USER => 'Failed: chmod', - * ERROR_MESSAGE_SUPPORT => "Failed: chmod $mode '$pathFileName'"]), - * ERROR_IO_CHMOD); + throw new UserFormException( json_encode( + [ERROR_MESSAGE_TO_USER => 'Failed: chmod', + ERROR_MESSAGE_SUPPORT => "Failed: chmod $mode '$pathFileName'"]), + ERROR_IO_CHMOD); * * @package qfq\exceptions */ diff --git a/extension/Source/core/exceptions/DbException.php b/extension/Source/core/exceptions/DbException.php index b9d07e098..bfbbfae13 100644 --- a/extension/Source/core/exceptions/DbException.php +++ b/extension/Source/core/exceptions/DbException.php @@ -38,6 +38,13 @@ class DbException extends AbstractException { * [ERROR_MESSAGE_TO_USER] 'toUser' - shown in the client to the user - no details here!!! * [ERROR_MESSAGE_SUPPORT] 'support' - help for the developer * [ERROR_MESSAGE_OS] 'os' - message from the OS, like 'file not found' + * + throw new UserFormException( json_encode( + [ERROR_MESSAGE_TO_USER => 'Failed: chmod', + ERROR_MESSAGE_SUPPORT => "Failed: chmod $mode '$pathFileName'", + ERROR_MESSAGE_OS => 'os' - message from the OS, like 'file not found' + ERROR_MESSAGE_HTTP_STATUS => 'HTTP/1.0 409 Bad Request' ]), + ERROR_IO_CHMOD); * * @return string HTML formatted error string * @return string diff --git a/extension/Source/core/exceptions/DownloadException.php b/extension/Source/core/exceptions/DownloadException.php index 15c3d767a..cb9a76def 100644 --- a/extension/Source/core/exceptions/DownloadException.php +++ b/extension/Source/core/exceptions/DownloadException.php @@ -21,10 +21,11 @@ require_once(__DIR__ . '/AbstractException.php'); * * Throw with message for User and message for Support. * - * throw new UserFormException( json_encode( - * [ERROR_MESSAGE_TO_USER => 'Failed: chmod', - * ERROR_MESSAGE_SUPPORT => "Failed: chmod $mode '$pathFileName'"]), - * ERROR_IO_CHMOD); + throw new UserFormException( json_encode( + [ERROR_MESSAGE_TO_USER => 'Failed: chmod', + ERROR_MESSAGE_SUPPORT => "Failed: chmod $mode '$pathFileName'", + ERROR_MESSAGE_HTTP_STATUS => 'HTTP/1.0 409 Bad Request' ]), + ERROR_IO_CHMOD); * * @package qfq\exceptions */ diff --git a/extension/Source/core/exceptions/NotAcceptableResponseException.php b/extension/Source/core/exceptions/NotAcceptableResponseException.php new file mode 100644 index 000000000..26ec07062 --- /dev/null +++ b/extension/Source/core/exceptions/NotAcceptableResponseException.php @@ -0,0 +1,52 @@ +<?php +/** + * Created by PhpStorm. + * User: crose + * Date: 21.02.19 + * Time: 23:47 + */ + +namespace qfq; + +require_once(__DIR__ . '/AbstractException.php'); + +/** + * Class NotAcceptableResponseException + * + * Thrown by API call with bad content type + * + * Throw with ONE message + * + * throw new UserFormException('Failed: chmod ....', ERROR_IO_CHMOD); + * + * Throw with message for User and message for Support. + * + * throw new UserFormException( json_encode( + * [ERROR_MESSAGE_TO_USER => 'Failed: chmod', + * ERROR_MESSAGE_SUPPORT => "Failed: chmod $mode '$pathFileName'"]), + * ERROR_IO_CHMOD); + * + * @package qfq\exceptions + */ + +class NotAcceptableResponseException extends AbstractException { + + /** + * $this->getMessage() might give a) a simple string or b) an JSON String. + * + * JSON String: There are 3+1 different messages: + * [ERROR_MESSAGE_TO_USER] 'toUser' - shown in the client to the user - no details here!!! + * [ERROR_MESSAGE_SUPPORT] 'support' - help for the developer + * [ERROR_MESSAGE_OS] 'os' - message from the OS, like 'file not found' + * + * @return string HTML formatted error string + * @throws CodeException + * @throws UserFormException + */ + public function formatMessage() { + + $this->messageArrayDebug[EXCEPTION_TYPE] = 'Not Acceptable Response'; + + return parent::formatException(); + } +} \ No newline at end of file diff --git a/extension/Source/core/exceptions/RestException.php b/extension/Source/core/exceptions/RestException.php new file mode 100644 index 000000000..5135943b2 --- /dev/null +++ b/extension/Source/core/exceptions/RestException.php @@ -0,0 +1,52 @@ +<?php +/** + * Created by PhpStorm. + * User: crose + * Date: 21.02.19 + * Time: 23:47 + */ + +namespace qfq; + +require_once(__DIR__ . '/AbstractException.php'); + +/** + * Class RestException + * + * Thrown by API call with violated access rules + * + * Throw with ONE message + * + * throw new UserFormException('Failed: chmod ....', ERROR_IO_CHMOD); + * + * Throw with message for User and message for Support. + * + * throw new UserFormException( json_encode( + * [ERROR_MESSAGE_TO_USER => 'Failed: chmod', + * ERROR_MESSAGE_SUPPORT => "Failed: chmod $mode '$pathFileName'"]), + * ERROR_IO_CHMOD); + * + * @package qfq\exceptions + */ + +class RestException extends AbstractException { + + /** + * $this->getMessage() might give a) a simple string or b) an JSON String. + * + * JSON String: There are 3+1 different messages: + * [ERROR_MESSAGE_TO_USER] 'toUser' - shown in the client to the user - no details here!!! + * [ERROR_MESSAGE_SUPPORT] 'support' - help for the developer + * [ERROR_MESSAGE_OS] 'os' - message from the OS, like 'file not found' + * + * @return string HTML formatted error string + * @throws CodeException + * @throws UserFormException + */ + public function formatMessage() { + + $this->messageArrayDebug[EXCEPTION_TYPE] = 'Access Forbidden Exception'; + + return parent::formatException(); + } +} \ No newline at end of file diff --git a/extension/Source/core/exceptions/ShellException.php b/extension/Source/core/exceptions/ShellException.php index 4b98a6daa..77e131852 100644 --- a/extension/Source/core/exceptions/ShellException.php +++ b/extension/Source/core/exceptions/ShellException.php @@ -21,10 +21,11 @@ require_once(__DIR__ . '/AbstractException.php'); * * Throw with message for User and message for Support. * - * throw new UserFormException( json_encode( - * [ERROR_MESSAGE_TO_USER => 'Failed: chmod', - * ERROR_MESSAGE_SUPPORT => "Failed: chmod $mode '$pathFileName'"]), - * ERROR_IO_CHMOD); + throw new UserFormException( json_encode( + [ERROR_MESSAGE_TO_USER => 'Failed: chmod', + ERROR_MESSAGE_SUPPORT => "Failed: chmod $mode '$pathFileName'", + ERROR_MESSAGE_HTTP_STATUS => 'HTTP/1.0 409 Bad Request' ]), + ERROR_IO_CHMOD); * * @package qfq\exceptions */ diff --git a/extension/Source/core/exceptions/UserFormException.php b/extension/Source/core/exceptions/UserFormException.php index f2711d62f..855baacd3 100644 --- a/extension/Source/core/exceptions/UserFormException.php +++ b/extension/Source/core/exceptions/UserFormException.php @@ -22,10 +22,11 @@ require_once(__DIR__ . '/AbstractException.php'); * * Throw with message for User and message for Support. * - * throw new UserFormException( json_encode( - * [ERROR_MESSAGE_TO_USER => 'Failed: chmod', - * ERROR_MESSAGE_SUPPORT => "Failed: chmod $mode '$pathFileName'"]), - * ERROR_IO_CHMOD); + throw new UserFormException( json_encode( + [ERROR_MESSAGE_TO_USER => 'Failed: chmod', + ERROR_MESSAGE_SUPPORT => "Failed: chmod $mode '$pathFileName'", + ERROR_MESSAGE_HTTP_STATUS => 'HTTP/1.0 409 Bad Request' ]), + ERROR_IO_CHMOD); * * Call * diff --git a/extension/Source/core/exceptions/UserReportException.php b/extension/Source/core/exceptions/UserReportException.php index c3f5bdc1b..3f10a32f9 100644 --- a/extension/Source/core/exceptions/UserReportException.php +++ b/extension/Source/core/exceptions/UserReportException.php @@ -21,10 +21,11 @@ require_once(__DIR__ . '/AbstractException.php'); * * Throw with message for User and message for Support. * - * throw new UserFormException( json_encode( - * [ERROR_MESSAGE_TO_USER => 'Failed: chmod', - * ERROR_MESSAGE_SUPPORT => "Failed: chmod $mode '$pathFileName'"]), - * ERROR_IO_CHMOD); + throw new UserFormException( json_encode( + [ERROR_MESSAGE_TO_USER => 'Failed: chmod', + ERROR_MESSAGE_SUPPORT => "Failed: chmod $mode '$pathFileName'", + ERROR_MESSAGE_HTTP_STATUS => 'HTTP/1.0 409 Bad Request' ]), + ERROR_IO_CHMOD); * * @package qfq\exceptions */ diff --git a/extension/Source/core/helper/Logger.php b/extension/Source/core/helper/Logger.php index 4812e92f0..b2d4c7609 100644 --- a/extension/Source/core/helper/Logger.php +++ b/extension/Source/core/helper/Logger.php @@ -40,6 +40,7 @@ class Logger { * * @param string $mode * @param bool $recursion + * @throws CodeException * @throws UserFormException */ public static function logMessage($msg, $filename, $mode = FILE_MODE_APPEND, $recursion = false) { -- GitLab