فهرست منبع

convert field customers.Login to lowercase
small fix in timeformat for user_auth record in backend

Dmitriev Roman 3 ماه پیش
والد
کامیت
e4b2fba377

+ 1 - 1
docs/databases/mysql/en/create_db.sql

@@ -63,7 +63,7 @@ CREATE TABLE `connections` (
 
 CREATE TABLE `customers` (
   `id` int(11) NOT NULL,
-  `Login` varchar(20) DEFAULT 'NULL',
+  `login` varchar(20) DEFAULT 'NULL',
   `description` varchar(100) DEFAULT NULL,
   `password` varchar(255) DEFAULT 'NULL',
   `api_key` varchar(255) DEFAULT NULL,

+ 1 - 1
docs/databases/mysql/ru/create_db.sql

@@ -63,7 +63,7 @@ CREATE TABLE `connections` (
 
 CREATE TABLE `customers` (
   `id` int(11) NOT NULL,
-  `Login` varchar(20) DEFAULT 'NULL',
+  `login` varchar(20) DEFAULT 'NULL',
   `description` varchar(100) DEFAULT NULL,
   `password` varchar(255) DEFAULT 'NULL',
   `api_key` varchar(255) DEFAULT NULL,

+ 2 - 2
docs/databases/postgres/en/create_db.sql

@@ -88,14 +88,14 @@ COMMENT ON COLUMN connections.last_found IS 'Last connection activity time';
 -- System users
 CREATE TABLE customers (
 id SERIAL PRIMARY KEY,
-Login VARCHAR(20),
+login VARCHAR(20),
 description VARCHAR(100),
 password VARCHAR(255),
 api_key VARCHAR(255),
 rights SMALLINT NOT NULL DEFAULT 3
 );
 COMMENT ON TABLE customers IS 'System users/administrators';
-COMMENT ON COLUMN customers.Login IS 'User login';
+COMMENT ON COLUMN customers.login IS 'User login';
 COMMENT ON COLUMN customers.rights IS 'Access level: 0=view, 1=operator, 2=admin, 3=superadmin';
 
 -- Network devices

+ 2 - 2
docs/databases/postgres/ru/create_db.sql

@@ -88,14 +88,14 @@ COMMENT ON COLUMN connections.last_found IS 'Время последней ак
 -- Пользователи системы
 CREATE TABLE customers (
 id SERIAL PRIMARY KEY,
-Login VARCHAR(20),
+login VARCHAR(20),
 description VARCHAR(100),
 password VARCHAR(255),
 api_key VARCHAR(255),
 rights SMALLINT NOT NULL DEFAULT 3
 );
 COMMENT ON TABLE customers IS 'Пользователи/администраторы системы';
-COMMENT ON COLUMN customers.Login IS 'Логин пользователя';
+COMMENT ON COLUMN customers.login IS 'Логин пользователя';
 COMMENT ON COLUMN customers.rights IS 'Уровень прав доступа: 0=просмотр, 1=оператор, 2=админ, 3=суперадмин';
 
 -- Сетевые устройства

+ 2 - 2
html/admin/customers/editcustom.php

@@ -7,7 +7,7 @@ $msg_error = "";
 
 if (isset($_POST["edituser"])) {
     global $salt;
-    $new['Login'] = substr(trim($_POST["login"]), 0, 20);
+    $new['login'] = substr(trim($_POST["login"]), 0, 20);
     $new['description'] = substr(trim($_POST["description"]), 0, 100);
     if (isset($_POST["pass"]) and (strlen(trim($_POST["pass"])) > 0)) {
         $new['password'] = password_hash($_POST["pass"], PASSWORD_BCRYPT);
@@ -37,7 +37,7 @@ $customer=get_record($db_link,'customers',"id=".$id);
 		<table class="data">
 			<tr>
 				<td><?php echo WEB_customer_login; ?></td>
-				<td><input type="text" name="login" value="<?php print $customer['Login']; ?>" size=20></td>
+				<td><input type="text" name="login" value="<?php print $customer['login']; ?>" size=20></td>
 			</tr>
 			<tr>
 				<td><?php echo WEB_cell_description; ?></td>

+ 4 - 4
html/admin/customers/index.php

@@ -7,13 +7,13 @@ $msg_error = "";
 if (isset($_POST["create"])) {
     $login = $_POST["newlogin"];
     if ($login) {
-	$customer = get_record_sql($db_link,"Select * from customers WHERE LCase(Login)=LCase('$login')");
+	$customer = get_record_sql($db_link,"Select * from customers WHERE LCase(login)=LCase('$login')");
         if (!empty($customer)) {
             $msg_error = "Login $login already exists!";
             LOG_ERROR($db_link, $msg_error);
             unset($_POST);
         } else {
-            $new['Login'] = $login;
+            $new['login'] = $login;
 	    $new['api_key'] = randomPassword(20);
             $new['rights'] = 3;
             LOG_INFO($db_link, "Create new login: $login");
@@ -54,13 +54,13 @@ print_control_submenu($page_url);
 <td><b><?php echo WEB_customer_mode;?></b></td>
 </tr>
 <?php
-$users = get_records($db_link,'customers','True ORDER BY Login');
+$users = get_records($db_link,'customers','True ORDER BY login');
 foreach ($users as $row) {
     $cl = "data";
     $acl = get_record_sql($db_link,'SELECT * FROM acl WHERE id='.$row['rights']);
     print "<tr align=center>\n";
     print "<td class=\"$cl\" style='padding:0'><input type=checkbox name=fid[] value=".$row['id']."></td>\n";
-    print "<td class=\"$cl\" align=left width=200><a href=editcustom.php?id=".$row['id'].">" . $row['Login'] . "</a></td>\n";
+    print "<td class=\"$cl\" align=left width=200><a href=editcustom.php?id=".$row['id'].">" . $row['login'] . "</a></td>\n";
     print "<td class=\"$cl\" >". $row['description']. "</a></td>\n";
     print "<td class=\"$cl\" >". $acl['name']. "</a></td>\n";
 }

+ 1 - 1
html/admin/users/editauth.php

@@ -298,7 +298,7 @@ if ($auth_info['mac_found'] == '0000-00-00 00:00:00') { $auth_info['mac_found']
 if ($auth_info['arp_found'] == '0000-00-00 00:00:00') { $auth_info['arp_found'] = ''; }
 
 $now = DateTime::createFromFormat("Y-m-d H:i:s",date('Y-m-d H:i:s'));
-$created = DateTime::createFromFormat("Y-m-d H:i:s",$auth_info['ts']);
+$created = new DateTime($auth_info['ts']);
 
 if (empty($auth_info['end_life']) or $auth_info['end_life'] == '0000-00-00 00:00:00') { 
     $now->modify('+1 day');

+ 66 - 42
html/inc/auth.utils.php

@@ -231,10 +231,6 @@ function login($db) {
         if (authenticate_by_credentials($db, $_POST['login'], $_POST['password'])) {
             LOG_INFO($db, "Logged in customer id: ".$_SESSION['user_id']." name: ".$_SESSION['login']." from ".$_SESSION['ip']." with acl: ".$_SESSION['acl']." url: ".$redirect_url);
             log_session_debug($db, "Login successful via credentials");
-
-            session_write_close();
-            session_start();
-
             return true;
         }
         log_session_debug($db, "Login failed via credentials");
@@ -252,7 +248,7 @@ function authenticate_by_credentials($db, $login, $password) {
     log_session_debug($db, "Authenticating by credentials", ['login' => $login]);
 
     $login = trim($login);
-    $stmt = $db->prepare("SELECT * FROM customers WHERE Login = ?");
+    $stmt = $db->prepare("SELECT * FROM customers WHERE login = ?");
     $stmt->execute([$login]);
     $user = $stmt->fetch(PDO::FETCH_ASSOC);
 
@@ -272,54 +268,64 @@ function authenticate_by_credentials($db, $login, $password) {
 
     log_session_debug($db, "Password verified, creating session");
 
-    $regenerate_result = session_regenerate_id(true);
-    log_session_debug($db, "Session regenerate result", ['success' => $regenerate_result, 'new_sid' => session_id()]);
+    $old_session_id = session_id();
+    session_regenerate_id(true);
+    $new_session_id = session_id();
 
+    // Обновляем данные сессии
     $_SESSION = [
         'user_id'    => $user['id'],
-        'login'      => $user['Login'],
+        'login'      => $user['login'],
         'acl'        => $user['rights'],
         'ip'         => get_client_ip(),
         'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
         'created'    => time()
     ];
 
-    log_session_debug($db, "Session data populated", $_SESSION);
-
-    $sessionId = session_id();
-    $ip = $_SESSION['ip'];
-    $userAgent = $_SESSION['user_agent'];
-    $time = time();
+    // Обновляем запись в user_sessions (удаляем старую, создаём новую)
+    $stmt = $db->prepare("DELETE FROM " . USER_SESSIONS_TABLE . " WHERE session_id = ?");
+    $stmt->execute([$old_session_id]);
 
     $stmt = $db->prepare("INSERT INTO " . USER_SESSIONS_TABLE . "
         (session_id, user_id, ip_address, user_agent, created_at, last_activity)
         VALUES (?, ?, ?, ?, ?, ?)");
+    $stmt->execute([$new_session_id, $user['id'], $_SESSION['ip'], $_SESSION['user_agent'], time(), time()]);
 
-    $success = $stmt->execute([$sessionId, $user['id'], $ip, $userAgent, $time, $time]);
-
-    if (!$success) {
-        $error = $stmt->errorInfo();
-        LOG_DEBUG($db, "Session DB error: " . print_r($error, true));
-        log_session_debug($db, "User session insert failed", $error);
-        return false;
-    }
-
-    log_session_debug($db, "User session record created successfully");
     return true;
 }
 
 function validate_session($db) {
-    log_session_debug($db, "Validating session", [
+    // Подготовка данных для логирования
+    $log_context = [
         'session_data' => $_SESSION,
         'current_ip' => get_client_ip(),
         'current_ua' => ($_SERVER['HTTP_USER_AGENT'] ?? '')
-    ]);
+    ];
+    
+    log_session_debug($db, "Validating session", $log_context);
+
+    // Проверка наличия обязательных данных в сессии
+    if (!isset($_SESSION['user_id']) || 
+        !isset($_SESSION['ip']) || 
+        !isset($_SESSION['user_agent'])) {
+        log_session_debug($db, "Session validation failed - missing required session data");
+        logout($db);
+        return false;
+    }
 
-    if ($_SESSION['ip'] !== get_client_ip() ||
-        $_SESSION['user_agent'] !== ($_SERVER['HTTP_USER_AGENT'] ?? '')) {
-        log_session_debug($db, "Session validation failed - IP or User-Agent mismatch", [
+    // Проверка соответствия IP-адреса
+    if ($_SESSION['ip'] !== get_client_ip()) {
+        log_session_debug($db, "Session validation failed - IP mismatch", [
             'session_ip' => $_SESSION['ip'],
-            'current_ip' => get_client_ip(),
+            'current_ip' => get_client_ip()
+        ]);
+        logout($db);
+        return false;
+    }
+
+    // Проверка соответствия User-Agent
+    if ($_SESSION['user_agent'] !== ($_SERVER['HTTP_USER_AGENT'] ?? '')) {
+        log_session_debug($db, "Session validation failed - User-Agent mismatch", [
             'session_ua' => $_SESSION['user_agent'],
             'current_ua' => ($_SERVER['HTTP_USER_AGENT'] ?? '')
         ]);
@@ -327,21 +333,39 @@ function validate_session($db) {
         return false;
     }
 
-    $sessionId = session_id();
-    $stmt = $db->prepare("SELECT 1
-        FROM " . USER_SESSIONS_TABLE . "
-        WHERE session_id = ? AND user_id = ? AND is_active = 1
-        LIMIT 1");
-
-    $stmt->execute([$sessionId, $_SESSION['user_id']]);
-    if ($stmt->rowCount() === 0) {
-        log_session_debug($db, "Session validation failed - no active session in database");
+    // Проверка наличия активной записи в user_sessions
+    try {
+        $sessionId = session_id();
+        $stmt = $db->prepare("SELECT 1
+            FROM " . USER_SESSIONS_TABLE . "
+            WHERE session_id = ? AND user_id = ? AND is_active = 1
+            LIMIT 1");
+        
+        $stmt->execute([$sessionId, $_SESSION['user_id']]);
+        
+        if ($stmt->rowCount() === 0) {
+            log_session_debug($db, "Session validation failed - no active session record in database");
+            logout($db);
+            return false;
+        }
+        
+    } catch (PDOException $e) {
+        LOG_ERROR($db, "Session validation DB error: " . $e->getMessage());
+        log_session_debug($db, "Session validation failed - database error", ['error' => $e->getMessage()]);
         logout($db);
         return false;
     }
 
-    $stmt = $db->prepare("UPDATE " . USER_SESSIONS_TABLE . " SET last_activity = ? WHERE session_id = ?");
-    $stmt->execute([time(), $sessionId]);
+    // Обновление времени последней активности
+    try {
+        $stmt = $db->prepare("UPDATE " . USER_SESSIONS_TABLE . " 
+            SET last_activity = ? WHERE session_id = ?");
+        $stmt->execute([time(), $sessionId]);
+        
+    } catch (PDOException $e) {
+        // Не критично - продолжаем работу
+        LOG_DEBUG($db, "Failed to update last_activity: " . $e->getMessage());
+    }
 
     log_session_debug($db, "Session validation successful");
     return true;
@@ -392,7 +416,7 @@ function IsSilentAuthenticated($db) {
         return false;
     }
 
-    $stmt = $db->prepare("SELECT id, rights FROM customers WHERE Login = ? AND api_key = ? LIMIT 1");
+    $stmt = $db->prepare("SELECT id, rights FROM customers WHERE login = ? AND api_key = ? LIMIT 1");
     $stmt->execute([$login, $api_key]);
 
     if ($stmt->rowCount() === 0) {

+ 2 - 2
html/inc/common.php

@@ -1745,7 +1745,7 @@ function get_auth_count($db, $user_id)
 function print_login_select($db, $login_name, $current_login)
 {
     print "<select id=\"$login_name\" name=\"$login_name\" class=\"js-select-single\">\n";
-    $t_login = get_records_sql($db, "SELECT id,login FROM user_list ORDER BY Login");
+    $t_login = get_records_sql($db, "SELECT id,login FROM user_list ORDER BY login");
     print_select_item('None', 0, $current_login);
     foreach ($t_login as $row) {
         print_select_item($row['login'], $row['id'], $current_login);
@@ -2391,7 +2391,7 @@ function new_auth($db, $ip, $mac, $user_id)
         $auth['user_id'] = $user_id;
         $auth['ip'] = $ip;
         $auth['ip_int'] = $ip_aton;
-        $auth['mac'] = $mac;
+        if (!empty($mac)) { $auth['mac'] = $mac; }
         $auth['save_traf'] = $save_traf * 1;
         $resurrection_id = insert_record($db, "user_auth", $auth);
     }

+ 51 - 41
html/inc/sql.php

@@ -594,72 +594,80 @@ function set_changed($db, $id)
     update_record($db, "user_auth", "id=" . $id, $auth);
 }
 
-//action: add,update,del
 function allow_update($table, $action = 'update', $field = '')
 {
-    //always allow modification for tables
-    if (preg_match('/(variables|dns_cache|worklog|sessions)/i', $table)) {
+    // 1. Таблицы с полным доступом (регистронезависимо, но без regex)
+    static $full_access_tables = [
+        'variables' => true,
+        'dns_cache' => true,
+        'worklog' => true,
+        'sessions' => true
+    ];
+    if (isset($full_access_tables[strtolower($table)])) {
         return 1;
     }
 
-    if (isset($_SESSION['login'])) {
-        $work_user = $_SESSION['login'];
-    }
-    if (isset($_SESSION['user_id'])) {
-        $work_id = $_SESSION['user_id'];
-    }
-    if (isset($_SESSION['acl'])) {
-        $user_level = $_SESSION['acl'];
-    }
-    if (!isset($work_user) or !isset($work_id) or empty($user_level)) {
+    // 2. Получение данных сессии (единая точка)
+    $login = $_SESSION['login'] ?? null;
+    $user_id = $_SESSION['user_id'] ?? null;
+    $acl = $_SESSION['acl'] ?? null;
+
+    // Проверка аутентификации
+    if (!$login || !$user_id || !$acl) {
         return 0;
     }
 
-    //always allow Administrator
-    if ($user_level == 1) {
+    // Приведение ACL к целому числу
+    $user_level = (int)$acl;
+
+    // 3. Права по уровням
+    if ($user_level === 1) {        // Администратор
         return 1;
     }
-
-    //always forbid ViewOnly
-    if ($user_level == 3) {
+    if ($user_level === 3) {        // ViewOnly
         return 0;
     }
 
-    //allow tables for Operator
-    if (preg_match('/(dns_queue|user_auth_alias)/i', $table)) {
+    // 4. Таблицы с полным доступом для оператора
+    static $operator_tables = [
+        'dns_queue' => true,
+        'user_auth_alias' => true
+    ];
+    if (isset($operator_tables[strtolower($table)])) {
         return 1;
     }
 
-    if ($action == 'update') {
-        $operator_acl = [
+    // 5. Проверка полей для оператора (только при update)
+    if ($action === 'update') {
+        static $operator_acl = [
             'user_auth' => [
-                'description' => '1',
-                'dns_name' => '1',
-                'dns_ptr_only' => '1',
-                'firmware' => '1',
-                'link_check' => '1',
-                'nagios' => '1',
-                'nagios_handler' => '1',
-                'Wikiname' => '1'
+                'description' => true,
+                'dns_name' => true,
+                'dns_ptr_only' => true,
+                'firmware' => true,
+                'link_check' => true,
+                'nagios' => true,
+                'nagios_handler' => true,
+                'Wikiname' => true
             ],
             'user_list' => [
-                'fio' => '1',
-                'login' => '1',
-            ],
+                'fio' => true,
+                'login' => true
+            ]
         ];
+
+        // Проверка существования таблицы в ACL
         if (!isset($operator_acl[$table])) {
             return 0;
         }
-        if (isset($operator_acl[$table]) and empty($field)) {
+
+        // Если поле не указано — разрешаем (полный доступ к таблице)
+        if ($field === '') {
             return 1;
         }
-        if (!isset($operator_acl[$table][$field])) {
-            return 0;
-        }
-        if (empty($operator_acl[$table][$field]) or $operator_acl[$table][$field] == '0') {
-            return 0;
-        }
-        return 1;
+
+        // Проверка прав на конкретное поле
+        return $operator_acl[$table][$field] ?? 0;
     }
 
     return 0;
@@ -667,6 +675,7 @@ function allow_update($table, $action = 'update', $field = '')
 
 function update_record($db, $table, $filter, $newvalue)
 {
+
     if (!isset($table)) {
 #        LOG_WARNING($db, "Change record for unknown table! Skip command.");
         return;
@@ -684,6 +693,7 @@ function update_record($db, $table, $filter, $newvalue)
         return;
     }
 
+
     if (!allow_update($table, 'update')) {
         LOG_INFO($db, "Access denied: $table [ $filter ]");
         return 1;

+ 1 - 0
install-eye.sh

@@ -1733,6 +1733,7 @@ eye_upgrade() {
     install_packages
     install_source_code
     import_mac_database
+    /opt/Eye/scripts/updates/upgrade.pl
     show_final_upgrade
 }
 

+ 2 - 0
scripts/updates/3-0-1/migration.msql

@@ -22,6 +22,8 @@ ALTER TABLE group_filters CHANGE COLUMN `order` rule_order INTEGER NOT NULL DEFA
 
 ALTER TABLE user_auth CHANGE COLUMN `client-id` client_id VARCHAR(250);
 
+ALTER TABLE customers CHANGE COLUMN `Login` login VARCHAR(20) DEFAULT 'NULL';
+
 -- Переименовываем eof → end_life в user_auth
 ALTER TABLE user_auth CHANGE COLUMN `eof` end_life TIMESTAMP NULL DEFAULT NULL;
 

+ 3 - 0
scripts/updates/3-0-1/migration.psql

@@ -25,6 +25,9 @@ ALTER TABLE group_filters RENAME COLUMN "order" TO rule_order;
 -- user_auth: client-id → client_id
 ALTER TABLE user_auth RENAME COLUMN "client-id" TO client_id;
 
+-- customers: Login to lower case
+ALTER TABLE customers RENAME COLUMN Login TO login;
+
 -- Переименовываем eof → end_life в user_auth
 ALTER TABLE user_auth RENAME COLUMN eof TO end_life;