Changeset 2058e5c for server.py


Ignore:
Timestamp:
01/20/26 17:28:10 (6 months ago)
Author:
istevanoska <ilinastevanoska@…>
Branches:
master
Children:
505f39a
Parents:
640ed89
Message:

Working / before login

File:
1 edited

Legend:

Unmodified
Added
Removed
  • server.py

    r640ed89 r2058e5c  
    1717from openai import OpenAI
    1818from openai import OpenAI
     19from dotenv import load_dotenv
     20load_dotenv()
    1921
    2022OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
     
    2527
    2628
    27 
    28 
    29 
    3029app = Flask(__name__)
    3130
    3231DB_FILE = "lan_logs_sysmon.db"
    3332LOG_DIR = "received_data_sysmon"
     33
     34import secrets
     35
     36ADMIN_KEY = os.environ.get("ADMIN_KEY", "")
     37ADMIN_KEY = os.environ.get("ADMIN_KEY", "")
     38
     39
     40def 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
     76def 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
     87def 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
    34103
    35104
     
    51120                  last_seen TIMESTAMP,
    52121                  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 ---
    53128
    54129    # Табела за историја
     
    124199        if not data:
    125200            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
    126204
    127205        info = data['info']
     
    141219            computer_id = result[0]
    142220            c.execute('''UPDATE computers
    143                         SET user = ?, ip = ?, os = ?, last_seen = ?, sysmon_available = ?
     221                        SET user = ?, ip = ?, os = ?, last_seen = ?, sysmon_available = ?, env_name = ?
    144222                        WHERE id = ?''',
    145223                      (info['user'], info['ip_address'], info['os'],
    146224                       timestamp.isoformat(), info.get('is_sysmon_available', 0),
    147                        computer_id))
     225                       env_name, computer_id))
    148226        else:
    149227            # Нов компјутер - додади го
    150228            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 (?, ?, ?, ?, ?, ?, ?, ?)''',
    153231                      (computer_name, info['user'], info['ip_address'],
    154232                       info['os'], timestamp.isoformat(), timestamp.isoformat(),
    155                        info.get('is_sysmon_available', 0)))
     233                       info.get('is_sysmon_available', 0), env_name))
     234
    156235            computer_id = c.lastrowid
    157236
     
    270349
    271350    # Зем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
    274353                 ORDER BY last_seen DESC''')
    275354
     
    331410            'avg_ram': round(avg_ram, 1),
    332411            'status': status,
    333             'status_color': status_color
     412            'status_color': status_color,
     413            'env_name': row[7],
    334414        })
    335415
     
    772852                            <i>🌐</i> {{ comp.ip }}
    773853                        </div>
     854                        <div class="computer-info">
     855                        <i>🏷️</i> Env: {{ comp.env_name }}</div>
     856
    774857
    775858                        <div class="computer-info">
     
    13241407    conn = sqlite3.connect(DB_FILE)
    13251408    c = conn.cursor()
     1409    env = request.headers.get("X-Env", "default")
    13261410
    13271411    c.execute('''SELECT name, user, ip, os, first_seen, last_seen, sysmon_available
    13281412                 FROM computers
    1329                  ORDER BY last_seen DESC''')
     1413                 WHERE env_name = ?
     1414                 ORDER BY last_seen DESC''', (env,))
    13301415
    13311416    computers = []
     
    18661951        'count': len(detailed_processes)
    18671952    })
     1953@app.route("/api/admin/login", methods=["POST"])
     1954def 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"])
     1971def 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"])
     1985def 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"])
     2008def 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
    18682036if __name__ == '__main__':
    18692037    init_database()
     2038    init_admin_tables()
     2039
    18702040
    18712041    # Стартувај cleanup thread
Note: See TracChangeset for help on using the changeset viewer.