- Timestamp:
- 01/20/26 17:28:10 (6 months ago)
- Branches:
- master
- Children:
- 505f39a
- Parents:
- 640ed89
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
server.py
r640ed89 r2058e5c 17 17 from openai import OpenAI 18 18 from openai import OpenAI 19 from dotenv import load_dotenv 20 load_dotenv() 19 21 20 22 OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY") … … 25 27 26 28 27 28 29 30 29 app = Flask(__name__) 31 30 32 31 DB_FILE = "lan_logs_sysmon.db" 33 32 LOG_DIR = "received_data_sysmon" 33 34 import secrets 35 36 ADMIN_KEY = os.environ.get("ADMIN_KEY", "") 37 ADMIN_KEY = os.environ.get("ADMIN_KEY", "") 38 39 40 def init_admin_tables(): 41 conn = sqlite3.connect(DB_FILE) 42 c = conn.cursor() 43 44 c.execute('''CREATE TABLE IF NOT EXISTS environments( 45 id INTEGER PRIMARY KEY AUTOINCREMENT, 46 name TEXT UNIQUE, 47 created_at TEXT 48 )''') 49 50 c.execute('''CREATE TABLE IF NOT EXISTS env_tokens( 51 id INTEGER PRIMARY KEY AUTOINCREMENT, 52 env_name TEXT, 53 token TEXT UNIQUE, 54 created_at TEXT, 55 expires_at TEXT 56 )''') 57 58 # migration ако табелата веќе постои 59 c.execute("PRAGMA table_info(env_tokens)") 60 cols = [r[1] for r in c.fetchall()] 61 if "expires_at" not in cols: 62 c.execute("ALTER TABLE env_tokens ADD COLUMN expires_at TEXT") 63 64 c.execute('''CREATE TABLE IF NOT EXISTS admin_sessions( 65 id INTEGER PRIMARY KEY AUTOINCREMENT, 66 token TEXT UNIQUE, 67 created_at TEXT 68 )''') 69 70 # default env 71 c.execute("INSERT OR IGNORE INTO environments(name, created_at) VALUES('default', datetime('now'))") 72 73 conn.commit() 74 conn.close() 75 76 def require_admin_session(): 77 tok = request.headers.get("X-Admin-Session", "") 78 if not tok: 79 return False 80 conn = sqlite3.connect(DB_FILE) 81 c = conn.cursor() 82 c.execute("SELECT 1 FROM admin_sessions WHERE token = ?", (tok,)) 83 ok = c.fetchone() is not None 84 conn.close() 85 return ok 86 87 def get_env_from_token(req): 88 tok = req.headers.get("X-Env-Token", "") 89 if not tok: 90 return None 91 92 conn = sqlite3.connect(DB_FILE) 93 c = conn.cursor() 94 c.execute(""" 95 SELECT env_name 96 FROM env_tokens 97 WHERE token = ? 98 AND (expires_at IS NULL OR expires_at > datetime('now')) 99 """, (tok,)) 100 row = c.fetchone() 101 conn.close() 102 return row[0] if row else None 34 103 35 104 … … 51 120 last_seen TIMESTAMP, 52 121 sysmon_available BOOLEAN DEFAULT 0)''') 122 # --- MIGRATION: add env_name column if missing --- 123 c.execute("PRAGMA table_info(computers)") 124 cols = [r[1] for r in c.fetchall()] 125 if "env_name" not in cols: 126 c.execute("ALTER TABLE computers ADD COLUMN env_name TEXT DEFAULT 'default'") 127 # --- END MIGRATION --- 53 128 54 129 # Табела за историја … … 124 199 if not data: 125 200 return jsonify({"error": "No data"}), 400 201 env_name = get_env_from_token(request) 202 if not env_name: 203 return jsonify({"error": "Missing or invalid X-Env-Token"}), 401 126 204 127 205 info = data['info'] … … 141 219 computer_id = result[0] 142 220 c.execute('''UPDATE computers 143 SET user = ?, ip = ?, os = ?, last_seen = ?, sysmon_available = ? 221 SET user = ?, ip = ?, os = ?, last_seen = ?, sysmon_available = ?, env_name = ? 144 222 WHERE id = ?''', 145 223 (info['user'], info['ip_address'], info['os'], 146 224 timestamp.isoformat(), info.get('is_sysmon_available', 0), 147 computer_id))225 env_name, computer_id)) 148 226 else: 149 227 # Нов компјутер - додади го 150 228 c.execute('''INSERT INTO computers 151 (name, user, ip, os, first_seen, last_seen, sysmon_available )152 VALUES (?, ?, ?, ?, ?, ?, ? )''',229 (name, user, ip, os, first_seen, last_seen, sysmon_available, env_name) 230 VALUES (?, ?, ?, ?, ?, ?, ?, ?)''', 153 231 (computer_name, info['user'], info['ip_address'], 154 232 info['os'], timestamp.isoformat(), timestamp.isoformat(), 155 info.get('is_sysmon_available', 0))) 233 info.get('is_sysmon_available', 0), env_name)) 234 156 235 computer_id = c.lastrowid 157 236 … … 270 349 271 350 # Земaj ги сите компјутери 272 c.execute('''SELECT name, user, ip, os, first_seen, last_seen, sysmon_available 273 FROM computers 351 c.execute('''SELECT name, user, ip, os, first_seen, last_seen, sysmon_available, env_name 352 FROM computers 274 353 ORDER BY last_seen DESC''') 275 354 … … 331 410 'avg_ram': round(avg_ram, 1), 332 411 'status': status, 333 'status_color': status_color 412 'status_color': status_color, 413 'env_name': row[7], 334 414 }) 335 415 … … 772 852 <i>🌐</i> {{ comp.ip }} 773 853 </div> 854 <div class="computer-info"> 855 <i>🏷️</i> Env: {{ comp.env_name }}</div> 856 774 857 775 858 <div class="computer-info"> … … 1324 1407 conn = sqlite3.connect(DB_FILE) 1325 1408 c = conn.cursor() 1409 env = request.headers.get("X-Env", "default") 1326 1410 1327 1411 c.execute('''SELECT name, user, ip, os, first_seen, last_seen, sysmon_available 1328 1412 FROM computers 1329 ORDER BY last_seen DESC''') 1413 WHERE env_name = ? 1414 ORDER BY last_seen DESC''', (env,)) 1330 1415 1331 1416 computers = [] … … 1866 1951 'count': len(detailed_processes) 1867 1952 }) 1953 @app.route("/api/admin/login", methods=["POST"]) 1954 def admin_login(): 1955 data = request.get_json(force=True) or {} 1956 key = (data.get("admin_key") or "").strip() 1957 if not ADMIN_KEY or key != ADMIN_KEY: 1958 return jsonify({"error": "Unauthorized"}), 401 1959 1960 session_token = secrets.token_urlsafe(32) 1961 conn = sqlite3.connect(DB_FILE) 1962 c = conn.cursor() 1963 c.execute("INSERT INTO admin_sessions(token, created_at) VALUES(?, datetime('now'))", (session_token,)) 1964 conn.commit() 1965 conn.close() 1966 1967 return jsonify({"ok": True, "session": session_token}) 1968 1969 1970 @app.route("/api/admin/environments", methods=["GET"]) 1971 def admin_list_envs(): 1972 if not require_admin_session(): 1973 return jsonify({"error": "Unauthorized"}), 401 1974 1975 conn = sqlite3.connect(DB_FILE) 1976 c = conn.cursor() 1977 c.execute("SELECT name FROM environments ORDER BY name") 1978 envs = [r[0] for r in c.fetchall()] 1979 conn.close() 1980 1981 return jsonify({"environments": envs}) 1982 1983 1984 @app.route("/api/admin/environments", methods=["POST"]) 1985 def admin_create_env(): 1986 if not require_admin_session(): 1987 return jsonify({"error": "Unauthorized"}), 401 1988 1989 data = request.get_json(force=True) or {} 1990 name = (data.get("name") or "").strip() 1991 if not name: 1992 return jsonify({"error": "Missing env name"}), 400 1993 1994 conn = sqlite3.connect(DB_FILE) 1995 c = conn.cursor() 1996 try: 1997 c.execute("INSERT INTO environments(name, created_at) VALUES(?, datetime('now'))", (name,)) 1998 conn.commit() 1999 except Exception as e: 2000 conn.close() 2001 return jsonify({"error": str(e)}), 400 2002 conn.close() 2003 2004 return jsonify({"ok": True, "name": name}) 2005 2006 2007 @app.route("/api/admin/tokens", methods=["POST"]) 2008 def admin_generate_token(): 2009 if not require_admin_session(): 2010 return jsonify({"error": "Unauthorized"}), 401 2011 2012 data = request.get_json(force=True) or {} 2013 env = (data.get("env") or "").strip() 2014 if not env: 2015 return jsonify({"error": "Missing env"}), 400 2016 2017 conn = sqlite3.connect(DB_FILE) 2018 c = conn.cursor() 2019 2020 c.execute("SELECT 1 FROM environments WHERE name = ?", (env,)) 2021 if not c.fetchone(): 2022 conn.close() 2023 return jsonify({"error": "Environment not found"}), 404 2024 2025 token = secrets.token_urlsafe(32) 2026 c.execute(""" 2027 INSERT INTO env_tokens(env_name, token, created_at, expires_at) 2028 VALUES(?, ?, datetime('now'), datetime('now', '+15 minutes')) 2029 """, (env, token)) 2030 2031 conn.commit() 2032 conn.close() 2033 2034 return jsonify({"ok": True, "env": env, "token": token}) 2035 1868 2036 if __name__ == '__main__': 1869 2037 init_database() 2038 init_admin_tables() 2039 1870 2040 1871 2041 # Стартувај cleanup thread
Note:
See TracChangeset
for help on using the changeset viewer.
