3require_once dirname(__DIR__, 2) .
'/vendor/autoload.php';
4require_once dirname(__DIR__) .
'/dbxKernel.php';
6$fail =
static function (
string $message,
int $code): void {
7 fwrite(STDERR,
"FAIL: $message\n");
15dbx()->set_system_var(
'dbx_modul',
'testModule');
16dbx()->set_system_var(
'dbx_run1',
'list');
17dbx()->set_system_var(
'dbx_run2',
'');
18dbx()->set_system_var(
'dbx_run3',
'');
22$navigation =
'?dbx_modul=testModule&dbx_run1=list&dbx_page=admin';
24 $fail(
'Normale GET-Navigation wurde tokenisiert.', 1);
39 $fail(
'delete plus rid wurde nicht automatisch tokenisiert.', 18);
52 $fail(
'save plus rid wurde nicht automatisch tokenisiert.', 19);
58 $fail(
'delete als Aktionsbestandteil wurde nicht erkannt.', 25);
63 $fail(
'undelete wurde faelschlich als delete erkannt.', 26);
68 $fail(
'delete ohne RID wurde unnoetig tokenisiert.', 20);
73 $fail(
'Normale RID-Navigation wurde tokenisiert.', 21);
77 '?dbx_modul=testModule&dbx_run1=delete&rid=18'
83 $fail(
'Automatisches Delete-Token ist nicht an die RID gebunden.', 22);
88dbx()->set_system_var(
'dbx_modul',
'testModule');
89dbx()->set_system_var(
'dbx_run1',
'delete');
90dbx()->set_system_var(
'dbx_run2',
'');
91dbx()->set_system_var(
'dbx_run3',
'');
95 $fail(
'Automatischer RID-Request wird vor dem Modulstart nicht akzeptiert.', 23);
97unset(
$_GET[
'dbx_token']);
100 $fail(
'Automatischer RID-Request ohne Token wird zentral akzeptiert.', 24);
104dbx()->set_system_var(
'dbx_run1',
'list');
106$deleteUrl =
'?dbx_modul=testModule&dbx_run1=list&dbx_do=row_delete&rid=17';
113 || (
string)(
$deletePolicy[
'action'] ??
'') !==
'dbxReport.row_delete'
115 $fail(
'Standard-Row-Delete wurde nicht kanonisch tokenisiert.', 2);
121 $fail(
'Ein Row-Delete-Token ist nicht an die RID gebunden.', 3);
126 $fail(
'Neue Tokens verwenden weiterhin einen Sessioneintrag je Scope.', 4);
129for ($rid = 1; $rid <= 200; $rid++) {
130 dbx()->action_token(
'test.dynamic.' . $rid);
134 $fail(
'Dynamische Scopes vergroessern weiterhin die Sessionablage.', 5);
139 $fail(
'Ein leerer Action-Token wurde akzeptiert.', 6);
141if (isset(
$_SESSION[
'dbx'][
'session'][
'dbx'][
'security'][
'action_token_secret'])) {
142 $fail(
'Eine leere Token-Pruefung schreibt unnoetig eine Session.', 7);
147 $fail(
'Ein unbekannter Action-Token wurde akzeptiert.', 30);
149if (isset(
$_SESSION[
'dbx'][
'session'][
'dbx'][
'security'][
'action_token_secret'])) {
150 $fail(
'Eine ungueltige Token-Pruefung erzeugt ein neues Session-Secret.', 31);
154dbx()->set_session_var(
161 $fail(
'Ein bereits gerenderter Legacy-Link ist nicht mehr kompatibel.', 8);
168 'custom_delete' => array(
170 'dbx_run1' =>
'test_action',
171 'dbx_do' =>
'remove',
173 'bind' => array(
'id'),
178$customUrl =
'?dbx_modul=dbx&dbx_run1=test_action&dbx_do=remove&id=44';
183 || (
string)(
$customPolicy[
'action'] ??
'') !==
'dbx.custom_delete'
188 $fail(
'Deklarierte Modulaktion wird nicht automatisch tokenisiert.', 9);
196dbx()->set_system_var(
'dbx_modul',
'testModule');
197dbx()->set_system_var(
'dbx_run1',
'list');
198dbx()->set_system_var(
'dbx_run2',
'');
199dbx()->set_system_var(
'dbx_run3',
'');
203 $fail(
'Ein gueltiger aktueller Action-Request wird zentral abgewiesen.', 10);
206$_GET[
'dbx_token'] = str_repeat(
'0', 64);
209 $fail(
'Ein falscher aktueller Action-Token wird zentral akzeptiert.', 11);
212dbx()->get_system_obj(
'dbxReport',
'load');
216 $this->_action = $action;
217 $this->_fid =
'action-token-report';
230 return (array)($this->_report_multi_actions[$code] ?? array());
234 $this->_grid_read_url = (string)($urls[
'read'] ??
'');
235 $this->_grid_save_url = (string)($urls[
'save'] ??
'');
236 $this->_grid_insert_url = (string)($urls[
'insert'] ??
'');
237 $this->_grid_delete_url = (string)($urls[
'delete'] ??
'');
238 $this->_grid_sort_url = (string)($urls[
'sort'] ??
'');
239 $this->_grid_sync_url = (string)($urls[
'sync'] ??
'');
246 $this->
init(
'action-token-form');
247 $this->_action = $action;
255dbx()->set_system_var(
'dbx_modul',
'testModule');
256dbx()->set_system_var(
'dbx_run1',
'list');
257dbx()->set_system_var(
'dbx_run2',
'');
258dbx()->set_system_var(
'dbx_run3',
'');
262 '?dbx_modul=testModule&dbx_run1=edit&dbx_run2=save_record&rid=31'
272 $fail(
'dbxForm tokenisiert erkannte RID-Actions nicht automatisch.', 27);
276$report->configure(
'?dbx_modul=testModule&dbx_run1=list');
280if ((
string)(
$rowRoute[
'params'][
'dbx_do'] ??
'') !==
'row_delete'
281 || (
string)(
$rowRoute[
'params'][
'rid'] ??
'') !==
'23'
284 (
string)(
$rowRoute[
'params'][
'dbx_token'] ??
'')
286 $fail(
'dbxReport tokenisiert die Row-Delete-URL nicht automatisch.', 12);
289$report->enable_delete_tab(
'dbxMissing');
293 $fail(
'dbxReport tokenisiert delete_tab nicht automatisch.', 13);
296$adminDeleteUrl =
'?dbx_modul=dbxAdmin&dbx_run1=trace&dbx_run2=list_trace&dbx_do=delete_tab';
305 $fail(
'dbxAdmin-Reports verwenden nicht den zentralen delete_tab-Scope.', 28);
309 dirname(__DIR__, 2) .
'/modules/dbxAdmin/include/dbxTrace.class.php',
310 dirname(__DIR__, 2) .
'/modules/dbxAdmin/include/dbxMissing.class.php',
311 dirname(__DIR__, 2) .
'/modules/dbxAdmin/include/dbxSession.class.php',
312 dirname(__DIR__, 2) .
'/modules/dbxAdmin/include/dbxSysMsg.class.php',
313) as $adminReportSourceFile) {
314 $adminReportSource = (string)file_get_contents($adminReportSourceFile);
315 if (strpos($adminReportSource,
'enable_delete_tab(') ===
false
316 || strpos($adminReportSource,
'check_action_token(') !==
false
317 || strpos($adminReportSource,
'action_token(') !==
false) {
318 $fail(
'dbxAdmin-Report dupliziert die zentrale dbxReport-Tokenpruefung.', 29);
323 dirname(__DIR__, 2) .
'/modules/dbxAdmin/include/dbxSysMsg.class.php'
327 $fail(
'Das Loeschen des PHP-Error-Logs ist nicht automatisch RID-gebunden signiert.', 34);
330require_once dirname(__DIR__, 2) .
'/modules/dbxAdmin/include/dbxUser.class.php';
336 array(
'dbx_do' =>
'row_delete',
'rid' => 9)
345 $fail(
'dbxAdmin-Benutzerloeschung verwendet nicht den zentralen Row-Delete-Scope.', 35);
351 array(
'dbx_do' =>
'verify',
'rid' => 9)
356 array(
'dbx_do' =>
'verify',
'rid' => 10)
367 $fail(
'dbxAdmin-Sonderaktionen sind nicht an Aktion und RID gebunden.', 40);
370require_once dirname(__DIR__, 2) .
'/modules/dbxShop_admin/include/dbxShopAdmin.class.php';
375 '?dbx_modul=dbxShop_admin&dbx_run1=products&dbx_do=row_delete&rid=11'
384 $fail(
'dbxShop-Produktloeschung verwendet nicht den zentralen Row-Delete-Scope.', 36);
387$report->add_action(
'rows_delete',
'action_button_delete',
'&dbx_run2=multi_delete');
395 $fail(
'dbxReport tokenisiert Multi-Delete nicht automatisch.', 14);
400 'read' =>
$gridBase .
'&dbx_run2=records_grid_read',
401 'save' =>
$gridBase .
'&dbx_run2=records_grid_save',
402 'insert' =>
$gridBase .
'&dbx_run2=records_grid_insert',
403 'delete' =>
$gridBase .
'&dbx_run2=records_grid_delete',
404 'sort' =>
$gridBase .
'&dbx_run2=records_grid_sort',
405 'sync' =>
$gridBase .
'&dbx_run2=records_grid_sync',
407if ((
string)(
$gridUrls[
'read_url'] ??
'') !==
$gridBase .
'&dbx_run2=records_grid_read') {
408 $fail(
'Die lesende Grid-URL wurde unnoetig veraendert.', 32);
410foreach (array(
'save',
'insert',
'delete',
'sort',
'sync') as $gridAction) {
411 $gridUrl = (string)(
$gridUrls[$gridAction .
'_url'] ??
'');
412 $gridRoute =
$web->parse_route_url($gridUrl);
413 $gridPolicy =
$web->action_policy_for_url($gridUrl);
414 if (isset($gridRoute[
'params'][
'dbx_do'])
415 || (
string)($gridPolicy[
'action'] ??
'') !==
'dbxReport.grid_' . $gridAction
417 (
string)($gridPolicy[
'scope'] ??
''),
418 (
string)($gridRoute[
'params'][
'dbx_token'] ??
'')
420 $fail(
'dbxReport tokenisiert Grid-' . $gridAction .
' nicht zentral.', 33);
425 'save' =>
'?dbx_modul=testModule&dbx_run1=grid&dbx_run2=write',
428 $fail(
'Eine nicht erkennbare schreibende Grid-Route wurde unsigniert ausgegeben.', 39);
432 $gridBase .
'&dbx_run2=records_grid_delete'
435$_POST = array(
'id' => 77);
436dbx()->set_system_var(
'dbx_modul',
'testModule');
437dbx()->set_system_var(
'dbx_run1',
'grid');
438dbx()->set_system_var(
'dbx_run2',
'records_grid_delete');
442 $fail(
'Eine direkt konstruierte Grid-Delete-Anfrage ohne Token wird nicht abgewiesen.', 37);
448 '?dbx_modul=dbxAdmin&dbx_run1=dd&dbx_run2=data_save&rid=dbx%7CdbxUser' =>
449 'dbxReport.grid_save',
450 '?dbx_modul=dbxAdmin&dbx_run1=dd&dbx_run2=fields_insert&modul=dbx&dd=dbxUser' =>
451 'dbxReport.grid_insert',
452 '?dbx_modul=dbxContent_admin&dbx_run1=content&dbx_run2=content_grid_sync' =>
453 'dbxReport.grid_sync',
454 '?dbx_modul=dbxUser_admin&dbx_run1=user&dbx_run2=user_grid_delete' =>
455 'dbxReport.grid_delete',
458 $realGridPolicy =
$web->action_policy_for_url($realGridUrl);
459 if ((
string)($realGridPolicy[
'action'] ??
'') !== $expectedGridAction) {
460 $fail(
'Reale Grid-Route wird nicht erkannt: ' . $realGridUrl, 38);
465dbx()->invalidate_action_tokens();
470 $fail(
'Ein Action-Token ueberlebt den Sicherheitskontextwechsel.', 15);
474 dirname(__DIR__) .
'/dbxSession.class.php'
476if (substr_count(
$sessionSource,
'dbx()->invalidate_action_tokens();') < 2) {
477 $fail(
'Login und Logout invalidieren Action-Tokens nicht beide.', 16);
481 dirname(__DIR__) .
'/dbxWebApp.class.php'
493 $fail(
'Die zentrale Action-Pruefung laeuft nicht vor dem Modulcode.', 17);
496echo
"OK dbx action token automation\n";
rowDeleteData(array $record)
configure(string $action)
multiAction(string $code)
get_delete_tab_button()
Rendert den Button fuer {db:delete_tab}.
get_table_row_action_data($type, array $record)
Baut das Standard-Datenarray für Row-Aktions-Templates.
$automaticSecuredDeleteUrl
if((string)($automaticSavePolicy['source'] ?? '') !=='automatic'||(string)($automaticSavePolicy['action'] ?? '') !=='dbxAction.save'||!dbx() ->check_action_token((string)($automaticSavePolicy['scope'] ?? ''),(string)($automaticSaveRoute['params']['dbx_token'] ?? ''))) $namedDeleteUrl
if(dbx() ->action_url($navigation) !==$navigation) $automaticDeleteUrl
if(dbx() ->check_action_token((string)($changedRidPolicy['scope'] ?? ''), $deleteToken)) $securityStore
if((string)( $gridUrls[ 'read_url'] ?? '') !==$gridBase . '&dbx_run2=records_grid_read') foreach(array('save', 'insert', 'delete', 'sort', 'sync') as $gridAction) $unrecognizedGridUrls
if(!preg_match('/^[a-f0-9]{64}$/', $deleteToken)||(string)($deletePolicy['action'] ?? '') !=='dbxReport.row_delete'||!dbx() ->check_action_token((string)($deletePolicy['scope'] ?? ''), $deleteToken)) $changedRidUrl
if(strpos($deleteTableHtml, 'dbx_do=delete_tab')===false||strpos($deleteTableHtml, 'dbx_token=')===false) $adminDeleteUrl
if(substr_count($sessionSource, 'dbx() ->invalidate_action_tokens();')< 2) $webAppSource
if(dbx() ->check_action_token( 'missing.scope', $unknownToken)) if(isset($_SESSION['dbx']['session']['dbx']['security']['action_token_secret'])) $legacyToken
if((string)( $adminDeletePolicy[ 'action'] ?? '') !=='dbxReport.delete_tab'||!dbx() ->check_action_token((string)( $adminDeletePolicy[ 'scope'] ?? ''),(string)( $adminDeleteRoute[ 'params'][ 'dbx_token'] ?? ''))) foreach(array(dirname(__DIR__, 2) . '/modules/dbxAdmin/include/dbxTrace.class.php', dirname(__DIR__, 2) . '/modules/dbxAdmin/include/dbxMissing.class.php', dirname(__DIR__, 2) . '/modules/dbxAdmin/include/dbxSession.class.php', dirname(__DIR__, 2) . '/modules/dbxAdmin/include/dbxSysMsg.class.php',) as $adminReportSourceFile) $sysMsgSource
if($tokenBeforeAuthChange===$tokenAfterAuthChange||dbx() ->check_action_token('auth.boundary', $tokenBeforeAuthChange)) $sessionSource
if((string)($adminUserDeletePolicy['action'] ?? '') !=='dbxReport.row_delete'||!dbx() ->check_action_token((string)($adminUserDeletePolicy['scope'] ?? ''),(string)($adminUserDeleteRoute['params']['dbx_token'] ?? ''))) $adminVerifyUrl9
if(dbx() ->action_url($deleteWithoutRid) !==$deleteWithoutRid) $navigationWithRid
if((string)($namedDeletePolicy['action'] ?? '') !=='dbxAction.delete') $undeleteUrl
if((string)($automaticDeletePolicy['source'] ?? '') !=='automatic'||(string)($automaticDeletePolicy['action'] ?? '') !=='dbxAction.delete'||(string)($automaticDeletePolicy['bindings']['rid'] ?? '') !=='17'||!dbx() ->check_action_token((string)($automaticDeletePolicy['scope'] ?? ''), $automaticDeleteToken)) $automaticSaveUrl
if((string)($customPolicy['source'] ?? '') !=='module'||(string)($customPolicy['action'] ?? '') !=='dbx.custom_delete'||!dbx() ->check_action_token((string)($customPolicy['scope'] ?? ''),(string)($customRoute['params']['dbx_token'] ?? ''))) $currentSecuredUrl
if(dbx() ->action_url($undeleteUrl) !==$undeleteUrl) $deleteWithoutRid
if(!dbx() ->check_action_token((string)($multiPolicy['scope'] ?? ''),(string)($multiRoute['params']['dbx_token'] ?? ''))) $gridBase
if((string)($formActionPolicy['action'] ?? '') !=='dbxAction.save'||!dbx() ->check_action_token((string)($formActionPolicy['scope'] ?? ''),(string)($formActionRoute['params']['dbx_token'] ?? ''))) $report
if((string)($unrecognizedGridUrls['save_url'] ?? '') !=='') $directGridRoute
if(dbx() ->check_action_token( 'missing.scope', '')) if(isset($_SESSION['dbx']['session']['dbx']['security']['action_token_secret'])) $unknownToken
foreach($realGridRoutes as $realGridUrl=> $expectedGridAction) $tokenBeforeAuthChange
if(dbx() ->action_url($navigationWithRid) !==$navigationWithRid) $changedAutomaticDeletePolicy
if(!dbx() ->check_action_token('legacy.scope', $legacyToken)) $dbxConfig
action_url(string $url, string $action='', array $bindings=array())
Tokenisiert eine automatisch erkannte zustandsaendernde Route.
check_action_token(string $scope='global', string $token='')
Prueft ein sessiongebundenes Aktions-Token.
DBX schema administration.