diff --git a/www/admin/class_test.login.php b/www/admin/class_test.login.php
new file mode 100644
index 00000000..294a0d4a
--- /dev/null
+++ b/www/admin/class_test.login.php
@@ -0,0 +1,61 @@
+ BASE . LOG,
+ 'file_id' => $LOG_FILE_ID,
+ // add file date
+ 'print_file_date' => true,
+ // set debug and print flags
+ 'debug_all' => $DEBUG_ALL ?? false,
+ 'echo_all' => $ECHO_ALL ?? false,
+ 'print_all' => $PRINT_ALL ?? false,
+]);
+$db = new CoreLibs\DB\IO(DB_CONFIG, $log);
+$login = new CoreLibs\ACL\Login($db, $log);
+ob_end_flush();
+
+print "";
+print "
TEST CLASS: LOGIN";
+print "";
+print '';
+
+echo "CHECK PERMISSION: " . ($login->loginCheckPermissions() ? 'OK' : 'BAD') . "
";
+echo "IS ADMIN: " . ($login->loginIsAdmin() ? 'OK' : 'BAD') . "
";
+echo "MIN ACCESS BASE: " . ($login->loginCheckAccessBase('admin') ? 'OK' : 'BAD') . "
";
+echo "MIN ACCESS PAGE: " . ($login->loginCheckAccessPage('admin') ? 'OK' : 'BAD') . "
";
+
+echo "ACL: " . \CoreLibs\Debug\Support::printAr($login->loginGetAcl()) . "
";
+echo "ACL (MIN): " . \CoreLibs\Debug\Support::printAr($login->loginGetAcl()['min']) . "
";
+
+// error message
+print $log->printErrorMsg();
+
+print "";
diff --git a/www/admin/class_test.php b/www/admin/class_test.php
index ca90c81a..3ea4bb8f 100644
--- a/www/admin/class_test.php
+++ b/www/admin/class_test.php
@@ -82,6 +82,7 @@ print '';
print '';
print '';
+print '';
print '';
print '';
print '';
diff --git a/www/includes/edit_base.php b/www/includes/edit_base.php
index 7439658d..2e5bbf7b 100644
--- a/www/includes/edit_base.php
+++ b/www/includes/edit_base.php
@@ -446,16 +446,15 @@ if ($form->my_page_name == 'edit_order') {
$t_q = '';
foreach ($output as $output_file) {
// split the ouput into folder and file
- // eg ../admin/test.php is ../admin/ and test.php
- preg_match("/([\.\/\w]+\/)+(\w+\.\w{1,})$/", $output_file, $matches);
- // if named config.php, skip
- if ($matches[2] != 'config.php') {
- if ($t_q) {
- $t_q .= ', ';
- }
- $t_q .= "('" . $form->dbEscapeString($matches[1]) . "', '"
- . $form->dbEscapeString($matches[2]) . "')";
+ $pathinfo = pathinfo($output_file);
+ if (!empty($pathinfo['dirname'])) {
+ $pathinfo['dirname'] .= DIRECTORY_SEPARATOR;
}
+ if ($t_q) {
+ $t_q .= ', ';
+ }
+ $t_q .= "('" . $form->dbEscapeString($pathinfo['dirname']) . "', '"
+ . $form->dbEscapeString($pathinfo['basename']) . "')";
}
$form->dbExec($q . $t_q, 'NULL');
$elements[] = $form->formCreateElement('filename');
diff --git a/www/lib/CoreLibs/ACL/Login.php b/www/lib/CoreLibs/ACL/Login.php
index a8d0a868..c51fd0fb 100644
--- a/www/lib/CoreLibs/ACL/Login.php
+++ b/www/lib/CoreLibs/ACL/Login.php
@@ -164,7 +164,9 @@ class Login
public $l;
/**
- * constructor, does ALL, opens db, works through connection checks, closes itself
+ * constructor, does ALL, opens db, works through connection checks,
+ * finishes itself
+ *
* @param \CoreLibs\DB\IO $db Database connection class
* @param \CoreLibs\Debug\Logging $log Logging class
*/
@@ -201,12 +203,10 @@ class Login
// pre-check that password min/max lengths are inbetween 1 and 255;
if ($this->password_max_length > 255) {
- echo 'Settings problem PMaL
';
- exit;
+ $this->password_max_length = 255;
}
if ($this->password_min_length < 1) {
- echo 'Settings problem PMiL
';
- exit;
+ $this->password_min_length = 1;
}
// set global is ajax page for if we show the data directly,
@@ -268,7 +268,8 @@ class Login
// init default ACL list array
$_SESSION['DEFAULT_ACL_LIST'] = [];
// read the current edit_access_right list into an array
- $q = "SELECT level, type, name FROM edit_access_right WHERE level >= 0 ORDER BY level";
+ $q = "SELECT level, type, name FROM edit_access_right "
+ . "WHERE level >= 0 ORDER BY level";
while (is_array($res = $this->db->dbReturn($q))) {
// level to description format (numeric)
$this->default_acl_list[$res['level']] = [
@@ -287,7 +288,10 @@ class Login
$this->loginLogoutUser();
// ** LANGUAGE SET AFTER LOGIN **
// set the locale
- if (Session::getSessionId() !== false && !empty($_SESSION['DEFAULT_LANG'])) {
+ if (
+ Session::getSessionId() !== false &&
+ !empty($_SESSION['DEFAULT_LANG'])
+ ) {
$locale = $_SESSION['DEFAULT_LOCALE'] ?? '';
} else {
$locale = defined('SITE_LOCALE') && !empty(SITE_LOCALE) ?
@@ -315,7 +319,8 @@ class Login
$this->login_html = $this->loginPrintLogin();
// closing all connections, depending on error status, exit
if (!$this->loginCloseClass()) {
- // if variable AJAX flag is not set, show output, else pass through for ajax work
+ // if variable AJAX flag is not set, show output
+ // else pass through for ajax work
if ($this->login_is_ajax_page !== true) {
// the login screen if we hav no login permission & login screen html data
if ($this->login_html !== null) {
@@ -361,8 +366,13 @@ class Login
// NO OP
}
+ // *************************************************************************
+ // **** PRIVATE INTERNAL
+ // *************************************************************************
+
/**
* checks if password is valid, sets internal error login variable
+ *
* @param string $hash password hash
* @param string $password submitted password
* @return bool true or false on password ok or not
@@ -419,7 +429,9 @@ class Login
}
/**
- * if user pressed login button this script is called, but only if there is no preview euid set]
+ * if user pressed login button this script is called,
+ * but only if there is no preview euid set
+ *
* @return void has not return
*/
private function loginLoginUser(): void
@@ -703,88 +715,6 @@ class Login
}
}
- /**
- * for every page the user access this script checks if he is allowed to do so
- * @return bool permission okay as true/false
- */
- public function loginCheckPermissions(): bool
- {
- if ($this->euid && $this->login_error != 103) {
- $q = "SELECT filename "
- . "FROM edit_page ep, edit_page_access epa, edit_group eg, edit_user eu "
- . "WHERE ep.edit_page_id = epa.edit_page_id "
- . "AND eg.edit_group_id = epa.edit_group_id "
- . "AND eg.edit_group_id = eu.edit_group_id "
- . "AND eu.edit_user_id = " . $this->euid . " "
- . "AND filename = '" . $this->page_name . "' "
- . "AND eg.enabled = 1 AND epa.enabled = 1";
- $res = $this->db->dbReturnRow($q);
- if (!is_array($res)) {
- $this->login_error = 109;
- $this->permission_okay = false;
- return $this->permission_okay;
- }
- if (isset($res['filename']) && $res['filename'] == $this->page_name) {
- $this->permission_okay = true;
- } else {
- $this->login_error = 103;
- $this->permission_okay = false;
- }
- }
- // if called from public, so we can check if the permissions are ok
- return $this->permission_okay;
- }
-
- /**
- * if a user pressed on logout, destroyes session and unsets all global vars
- * @return void has no return
- */
- public function loginLogoutUser(): void
- {
- // must be either logout or error
- if (!$this->logout && !$this->login_error) {
- return;
- }
- // unregister and destroy session vars
- foreach (
- // TODO move this into some global array for easier update
- [
- 'ADMIN',
- 'BASE_ACL_LEVEL',
- 'DB_DEBUG',
- 'DEBUG_ALL',
- 'DEFAULT_ACL_LIST',
- 'DEFAULT_CHARSET',
- 'DEFAULT_LANG',
- 'DEFAULT_LOCALE',
- 'EAID',
- 'EUID',
- 'GROUP_ACL_LEVEL',
- 'GROUP_ACL_TYPE',
- 'GROUP_NAME',
- 'HEADER_COLOR',
- 'LANG',
- 'PAGES_ACL_LEVEL',
- 'PAGES',
- 'TEMPLATE',
- 'UNIT_ACL_LEVEL',
- 'UNIT_DEFAULT',
- 'UNIT',
- 'USER_ACL_LEVEL',
- 'USER_ACL_TYPE',
- 'USER_NAME',
- ] as $session_var
- ) {
- unset($_SESSION[$session_var]);
- }
- // final unset all
- session_unset();
- // final destroy session
- session_destroy();
- // then prints the login screen again
- $this->permission_okay = false;
- }
-
/**
* sets all the basic ACLs
* init set the basic acl the user has, based on the following rules
@@ -800,6 +730,7 @@ class Login
* - if an account ACL is set, set this parallel, account ACL overrides user ACL if it applies
* - if edit access ACL level is set, use this, else use page
* set all base ACL levels as a list keyword -> ACL number
+ *
* @return void has no return
*/
private function loginSetAcl(): void
@@ -898,25 +829,32 @@ class Login
}
/**
- * checks if this edit access id is valid
- * @param int|null $edit_access_id access id pk to check
- * @return bool true/false: if the edit access is not
- * in the valid list: false
+ * Check if source (page, base) is matching to the given min access string
+ * min access string must be valid access level string (eg read, mod, write)
+ * This does not take in account admin flag set
+ *
+ * @param string $source a valid base level string eg base, page
+ * @param string $min_access a valid min level string, eg read, mod, siteadmin
+ * @return bool True for valid access, False for invalid
*/
- public function loginCheckEditAccess($edit_access_id): bool
+ public function loginCheckAccess(string $source, string $min_access): bool
{
- if ($edit_access_id === null) {
+ $source = 'base';
+ if (
+ empty($this->acl['min'][$min_access]) ||
+ empty($this->acl[$source])
+ ) {
return false;
}
- if (array_key_exists($edit_access_id, $this->acl['unit'])) {
+ if ($this->acl[$source] >= $this->acl['min'][$min_access]) {
return true;
- } else {
- return false;
}
+ return false;
}
/**
* checks if the password is in a valid format
+ *
* @param string $password the new password
* @return bool true or false if valid password or not
*/
@@ -940,6 +878,7 @@ class Login
/**
* dummy declare for password forget
+ *
* @return void has no return
*/
private function loginPasswordForgot(): void
@@ -947,25 +886,9 @@ class Login
// will do some password recovert, eg send email
}
- /**
- * sets the minium length and checks on valid
- * @param int $length set the minimum length
- * @return bool true/false on success
- */
- public function loginSetPasswordMinLength(int $length): bool
- {
- // check that numeric, positive numeric, not longer than max input string lenght
- // and not short than min password length
- if (is_numeric($length) && $length >= PASSWORD_MIN_LENGTH && $length <= $this->password_max_length) {
- $this->password_min_length = $length;
- return true;
- } else {
- return false;
- }
- }
-
/**
* changes a user password
+ *
* @return void has no return
*/
private function loginPasswordChange(): void
@@ -1066,6 +989,7 @@ class Login
/**
* prints out login html part if no permission (error) is set
+ *
* @return string|null html data for login page, or null for nothing
*/
private function loginPrintLogin()
@@ -1171,6 +1095,7 @@ class Login
/**
* last function called, writes log and prints out error msg and
* exists script if permission 0
+ *
* @return bool true on permission ok, false on permission wrong
*/
private function loginCloseClass(): bool
@@ -1209,6 +1134,7 @@ class Login
/**
* checks if there are external templates, if not uses internal fallback ones
+ *
* @return void has no return
*/
private function loginSetTemplates(): void
@@ -1390,6 +1316,7 @@ EOM;
/**
* writes detailed data into the edit user log table (keep log what user does)
+ *
* @param string $event string of what has been done
* @param string $data data information (id, etc)
* @param string|int $error error id (mostly an int)
@@ -1450,8 +1377,186 @@ EOM;
$this->db->dbExec($q, 'NULL');
}
+ // *************************************************************************
+ // **** PUBLIC INTERNAL
+ // *************************************************************************
+
+ /**
+ * sets the minium length and checks on valid
+ *
+ * @param int $length set the minimum length
+ * @return bool true/false on success
+ */
+ public function loginSetPasswordMinLength(int $length): bool
+ {
+ // check that numeric, positive numeric, not longer than max input string lenght
+ // and not short than min password length
+ if (is_numeric($length) && $length >= PASSWORD_MIN_LENGTH && $length <= $this->password_max_length) {
+ $this->password_min_length = $length;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * if a user pressed on logout, destroyes session and unsets all global vars
+ *
+ * @return void has no return
+ */
+ public function loginLogoutUser(): void
+ {
+ // must be either logout or error
+ if (!$this->logout && !$this->login_error) {
+ return;
+ }
+ // unregister and destroy session vars
+ foreach (
+ // TODO move this into some global array for easier update
+ [
+ 'ADMIN',
+ 'BASE_ACL_LEVEL',
+ 'DB_DEBUG',
+ 'DEBUG_ALL',
+ 'DEFAULT_ACL_LIST',
+ 'DEFAULT_CHARSET',
+ 'DEFAULT_LANG',
+ 'DEFAULT_LOCALE',
+ 'EAID',
+ 'EUID',
+ 'GROUP_ACL_LEVEL',
+ 'GROUP_ACL_TYPE',
+ 'GROUP_NAME',
+ 'HEADER_COLOR',
+ 'LANG',
+ 'PAGES_ACL_LEVEL',
+ 'PAGES',
+ 'TEMPLATE',
+ 'UNIT_ACL_LEVEL',
+ 'UNIT_DEFAULT',
+ 'UNIT',
+ 'USER_ACL_LEVEL',
+ 'USER_ACL_TYPE',
+ 'USER_NAME',
+ ] as $session_var
+ ) {
+ unset($_SESSION[$session_var]);
+ }
+ // final unset all
+ session_unset();
+ // final destroy session
+ session_destroy();
+ // then prints the login screen again
+ $this->permission_okay = false;
+ }
+
+ /**
+ * for every page the user access this script checks if he is allowed to do so
+ *
+ * @return bool permission okay as true/false
+ */
+ public function loginCheckPermissions(): bool
+ {
+ // start with not allowed
+ $this->permission_okay = false;
+ // bail for no euid (no login)
+ if (!$this->euid) {
+ return $this->permission_okay;
+ }
+ // bail for previous wrong page match, eg if method is called twice
+ if ($this->login_error == 103) {
+ return $this->permission_okay;
+ }
+ // if ($this->euid && $this->login_error != 103) {
+ $q = "SELECT filename "
+ . "FROM edit_page ep, edit_page_access epa, edit_group eg, edit_user eu "
+ . "WHERE ep.edit_page_id = epa.edit_page_id "
+ . "AND eg.edit_group_id = epa.edit_group_id "
+ . "AND eg.edit_group_id = eu.edit_group_id "
+ . "AND eu.edit_user_id = " . $this->euid . " "
+ . "AND filename = '" . $this->page_name . "' "
+ . "AND eg.enabled = 1 AND epa.enabled = 1";
+ $res = $this->db->dbReturnRow($q);
+ if (!is_array($res)) {
+ $this->login_error = 109;
+ return $this->permission_okay;
+ }
+ if (isset($res['filename']) && $res['filename'] == $this->page_name) {
+ $this->permission_okay = true;
+ } else {
+ $this->login_error = 103;
+ }
+ // if called from public, so we can check if the permissions are ok
+ return $this->permission_okay;
+ }
+
+ /**
+ * Return ACL array as is
+ *
+ * @return array
+ */
+ public function loginGetAcl(): array
+ {
+ return $this->acl;
+ }
+
+ /**
+ * checks if this edit access id is valid
+ *
+ * @param int|null $edit_access_id access id pk to check
+ * @return bool true/false: if the edit access is not
+ * in the valid list: false
+ */
+ public function loginCheckEditAccess($edit_access_id): bool
+ {
+ if ($edit_access_id === null) {
+ return false;
+ }
+ if (array_key_exists($edit_access_id, $this->acl['unit'])) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Check if admin flag is set
+ *
+ * @return bool True if admin flag set
+ */
+ public function loginIsAdmin(): bool
+ {
+ if (!empty($this->acl['admin'])) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * check if min accesss string (eg, read, mod, etc) is matchable
+ * EQUAL to BASE set right
+ *
+ * @param string $min_access
+ * @return bool
+ */
+ public function loginCheckAccessBase(string $min_access): bool
+ {
+ return $this->loginCheckAccess('base', $min_access);
+ }
+
+ /**
+ * check if min accesss string (eg, read, mod, etc) is matchable
+ * EQUAL to PAGE set right
+ *
+ * @param string $min_access
+ * @return bool
+ */
+ public function loginCheckAccessPage(string $min_access): bool
+ {
+ return $this->loginCheckAccess('page', $min_access);
+ }
+
/**
* checks that the given edit access id is valid for this user
+ *
* @param int|null $edit_access_id edit access id to check
* @return int|null same edit access id if ok
* or the default edit access id
@@ -1466,14 +1571,14 @@ EOM;
!array_key_exists($edit_access_id, $_SESSION['UNIT'])
) {
return $_SESSION['UNIT_DEFAULT'] ?? null;
- } else {
- return $edit_access_id;
}
+ return $edit_access_id;
}
/**
* retunrn a set entry from the UNIT session for an edit access_id
* if not found return false
+ *
* @param int $edit_access_id edit access id
* @param string|int $data_key key value to search for
* @return bool|string false for not found or string for found data
@@ -1482,9 +1587,8 @@ EOM;
{
if (!isset($_SESSION['UNIT'][$edit_access_id]['data'][$data_key])) {
return false;
- } else {
- return $_SESSION['UNIT'][$edit_access_id]['data'][$data_key];
}
+ return $_SESSION['UNIT'][$edit_access_id]['data'][$data_key];
}
// close class
}
diff --git a/www/lib/CoreLibs/DB/Extended/ArrayIO.php b/www/lib/CoreLibs/DB/Extended/ArrayIO.php
index f6643293..f12cc8aa 100644
--- a/www/lib/CoreLibs/DB/Extended/ArrayIO.php
+++ b/www/lib/CoreLibs/DB/Extended/ArrayIO.php
@@ -43,7 +43,7 @@ class ArrayIO extends \CoreLibs\DB\IO
/** @var string */
public $table_name; // the table_name
/** @var string */
- public $pk_name; // the primary key from this table
+ public $pk_name = ''; // the primary key from this table
/** @var int|string|null */
public $pk_id; // the PK id