Commit 446e7e7f authored by Carsten  Rose's avatar Carsten Rose
Browse files

Refactor to use form.restMethod instead of form.permNew|edit=rest. Next step...

Refactor to use form.restMethod instead of form.permNew|edit=rest. Next step will be to eliminate formMode=FORM_REST
parent 3e2d2805
......@@ -24,11 +24,38 @@ try {
try {
$form = OnString::splitPathInfoToIdForm($_SERVER['PATH_INFO'], $restId, $restForm);
// get latest `ìd`
$id=end($restId);
// Fake Bodytext setup
// Fake Bodytext setup
$bodytext = TYPO3_RECORD_ID . '=' . $id . PHP_EOL;
$bodytext .= TYPO3_FORM . '=' . $form . PHP_EOL;
$method=$_SERVER['REQUEST_METHOD'];
switch($method){
case REQUEST_METHOD_GET:
break;
case REQUEST_METHOD_POST:
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);
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);
break;
case REQUEST_METHOD_DELETE:
if($id==0){
throw new UserFormException('Method DELETE needs an id>0', ERROR_REST_INVALID_ID);
}
break;
default:
break;
}
$qfq = new QuickFormQuery(['bodytext' => $bodytext]);
$answer = $qfq->rest($restId, $restForm);
$status='HTTP/1.0 200 OK';
......@@ -50,4 +77,3 @@ try {
header($status);
header("Content-Type: application/json");
echo json_encode($answer);
......@@ -365,6 +365,7 @@ const ERROR_IMPORT_LIST_SHEET_NAMES = 2901;
// REST
const ERROR_FORM_REST = 3000;
const ERROR_REST_AUTHORIZATION = 3001;
const ERROR_REST_INVALID_ID = 3002;
//
// Store Names: Identifier
//
......@@ -420,12 +421,18 @@ const CLIENT_SERVER_ADDRESS = 'SERVER_ADDR';
const CLIENT_SERVER_PORT = 'SERVER_PORT';
const CLIENT_REMOTE_ADDRESS = 'REMOTE_ADDR';
const CLIENT_REQUEST_SCHEME = 'REQUEST_SCHEME';
const CLIENT_REQUEST_METHOD = 'REQUEST_METHOD';
const CLIENT_SCRIPT_FILENAME = 'SCRIPT_FILENAME';
const CLIENT_QUERY_STRING = 'QUERY_STRING';
const CLIENT_REQUEST_URI = 'REQUEST_URI';
const CLIENT_SCRIPT_NAME = 'SCRIPT_NAME';
const CLIENT_PHP_SELF = 'PHP_SELF';
const REQUEST_METHOD_GET = 'GET';
const REQUEST_METHOD_POST = 'POST';
const REQUEST_METHOD_PUT = 'PUT';
const REQUEST_METHOD_DELETE = 'DELETE';
// _COOKIE
const CLIENT_COOKIE_QFQ = 'cookieQfq';
......@@ -879,6 +886,7 @@ const F_TITLE = 'title';
const F_TABLE_NAME = 'tableName';
const F_PRIMARY_KEY = 'primaryKey';
const F_PRIMARY_KEY_DEFAULT = 'id';
const F_REST_METHOD = 'restMethod';
const F_REQUIRED_PARAMETER_NEW = 'requiredParameterNew';
const F_REQUIRED_PARAMETER_EDIT = 'requiredParameterEdit';
const F_EXTRA_DELETE_FORM = 'extraDeleteForm';
......
......@@ -172,7 +172,7 @@ class QuickFormQuery {
Session::checkSessionExpired($timeout);
// If an FE user logs out and a different user logs in (same browser session) - the old values has to be destroyed!
if (Session::getAndDestroyFlagFeUserHasChanged() ) {
if (Session::getAndDestroyFlagFeUserHasChanged()) {
$this->store->unsetStore(STORE_USER);
}
......@@ -371,7 +371,6 @@ class QuickFormQuery {
// Check 'session expire' happens quite late, cause it can be configured per form.
Session::checkSessionExpired($this->formSpec[F_SESSION_TIMEOUT_SECONDS]);
if ($formName !== false) {
// Validate only if there is a 'real' form (not a FORM_DELETE with only a tablename).
$sipFound = $this->validateForm($foundInStore, $formMode);
......@@ -984,13 +983,10 @@ class QuickFormQuery {
HelperFormElement::explodeParameter($form, F_PARAMETER);
unset($form[F_PARAMETER]);
if (isset($form[FE_FILL_STORE_VAR])) {
$fillStoreVar = $form[FE_FILL_STORE_VAR];
unset($form[FE_FILL_STORE_VAR]);
}
// Save specific elements to be expanded later.
$parseLater = OnArray::getArrayItems($form, [F_FORWARD_PAGE, F_REST_SQL_LIST, F_REST_SQL_DATA]);
$parseLater = OnArray::getArrayItems($form, [F_FORWARD_PAGE, FE_FILL_STORE_VAR, F_REST_SQL_LIST, F_REST_SQL_DATA]);
$form[FE_FILL_STORE_VAR] = '';
$form[F_FORWARD_PAGE] = '';
$form[F_REST_SQL_LIST] = '';
$form[F_REST_SQL_DATA] = '';
......@@ -1054,8 +1050,11 @@ class QuickFormQuery {
!empty($form[FORM_LOG_ACTIVE]) && Logger::logFormLine($form, "F:$mode:evaluated:" . date('Y-m-d H:i:s'), $form, true);
// Fire FE_FILL_STORE_VAR after the primary form record has been loaded
if (!empty($fillStoreVar)) {
$rows = $this->evaluate->parse($fillStoreVar, ROW_EXPECT_0_1);
if (!empty($formSpec[FE_FILL_STORE_VAR])) {
$rows = $this->evaluate->parse($formSpec[FE_FILL_STORE_VAR], ROW_EXPECT_0_1);
unset($formSpec[FE_FILL_STORE_VAR]);
if (is_array($rows)) {
$this->store->appendToStore($rows, STORE_VAR);
// LOG
......@@ -1422,10 +1421,10 @@ class QuickFormQuery {
*/
private function validateForm($formNameFoundInStore, $formMode) {
// Retrieve record_id either from SIP (prefered) or via URL
// Retrieve record_id either from SIP (preferred) or via URL
$r = $this->store->getVar(SIP_RECORD_ID, STORE_SIP . STORE_TYPO3 . STORE_CLIENT, '', $recordIdFoundInStore);
// If not found: Fake a definition in STORE_TYPO3.
// no record id: Fake a definition in STORE_TYPO3.
if ($r === false) {
$r = 0;
$this->store->setVar(TYPO3_RECORD_ID, $r, STORE_TYPO3);
......@@ -1466,22 +1465,23 @@ class QuickFormQuery {
case FORM_PERMISSION_NEVER:
throw new UserFormException("Loading form forbidden.", ERROR_FORM_FORBIDDEN);
break;
case FORM_PERMISSION_REST:
if ($formMode != FORM_REST) {
throw new UserFormException("Try to load a REST form", ERROR_FORM_REST);
}
break;
// case FORM_PERMISSION_REST:
// if ($formMode != FORM_REST) {
// throw new UserFormException("Try to load a REST form", ERROR_FORM_REST);
// }
// break;
default:
throw new CodeException("Unknown permission mode: '" . $permitMode . "'", ERROR_FORM_UNKNOWN_PERMISSION_MODE);
}
if ($formMode == FORM_REST) {
$this->restCheckAuthToken($this->formSpec[F_REST_TOKEN] ?? '');
if ($permitMode != FORM_PERMISSION_REST) {
throw new UserFormException("Try to load a non-REST form in REST mode", ERROR_FORM_REST);
$method = strtolower($this->store::getVar(CLIENT_REQUEST_METHOD, STORE_CLIENT));
if (false === Support::findInSet($method, $this->formSpec[F_REST_METHOD])) {
throw new UserFormException("Form '". $this->formSpec[F_NAME]. "' is not allowed with method '$method'", ERROR_FORM_REST);
}
$this->restCheckAuthToken($this->formSpec[F_REST_TOKEN] ?? '');
}
// Form Definition valid?
......@@ -1871,7 +1871,7 @@ EOF;
/**
* @param array $restId
* @param array $restForm
* @param string $method
* @return array|string
* @throws CodeException
* @throws DbException
......
......@@ -136,7 +136,11 @@ $UPDATE_ARRAY = array(
"ALTER TABLE `Form` ADD `labelAlign` ENUM('default','left','center','right') NOT NULL DEFAULT 'default' AFTER `forwardPage`;",
"ALTER TABLE `FormElement` ADD `labelAlign` ENUM('default','left','center','right') NOT NULL DEFAULT 'default' AFTER `maxLength`;",
],
'19.2.3' => [
"ALTER TABLE `Form` ADD `restMethod` SET('get','post','put','delete') NOT NULL DEFAULT '' AFTER `permitEdit`; ",
],
);
......
......@@ -319,7 +319,7 @@ class Support {
/**
* Search for the parameter $needle in $haystack. The arguments has to be separated by ','.
*
* Returns false if not found or index of found place. Be careful: use unary operator to compare for 'false'
* Returns false if not found, or index (starting with 0) of found place. Be careful: use unary operator to compare for 'false'
*
* @param string $needle
* @param string $haystack
......
......@@ -42,14 +42,12 @@ class Client {
if (isset($_POST)) {
$post = $_POST;
// Logger::logMessage(var_export($post, true) . PHP_EOL . PHP_EOL,'post.txt');
}
if (isset($_COOKIE[SESSION_NAME])) {
$cookie[CLIENT_COOKIE_QFQ] = $_COOKIE[SESSION_NAME];
}
// It's important to merge the SERVER array last: those entries shall overwrite client values.
if (isset($_SERVER)) {
$server = Sanitize::htmlentitiesArr($_SERVER); // $_SERVER values might be compromised.
}
......@@ -59,6 +57,7 @@ class Client {
$server[CLIENT_REMOTE_ADDRESS] = '0.0.0.0';
}
// It's important to merge the SERVER array last: those entries shall overwrite client values.
$arr = array_merge($header, $get, $post, $cookie, $server);
return Sanitize::normalize($arr);
......
......@@ -124,6 +124,7 @@ class Store {
CLIENT_SERVER_PORT => SANITIZE_ALLOW_DIGIT,
CLIENT_REMOTE_ADDRESS => SANITIZE_ALLOW_ALNUMX,
CLIENT_REQUEST_SCHEME => SANITIZE_ALLOW_ALNUMX,
CLIENT_REQUEST_METHOD => SANITIZE_ALLOW_ALNUMX,
CLIENT_SCRIPT_FILENAME => SANITIZE_ALLOW_ALNUMX,
CLIENT_QUERY_STRING => SANITIZE_ALLOW_ALL,
CLIENT_REQUEST_URI => SANITIZE_ALLOW_ALL,
......
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment