Add configuration, utilities, and update server with enhanced monitoring features

- Add config.py for environment configuration management
- Add utils.py with utility functions
- Add .env.example for environment variable reference
- Add routes_example.py as route reference
- Add login.html template for authentication
- Update server.py with enhancements
- Update all dashboard and log templates
- Move documentation to 'explanations and old code' directory
- Update database schema
This commit is contained in:
Developer
2025-12-18 09:11:11 +02:00
parent 87a51c7950
commit 376240fb06
19 changed files with 3903 additions and 51 deletions

102
server.py
View File

@@ -1,4 +1,6 @@
from flask import Flask, request, render_template, jsonify, redirect, url_for
from flask import Flask, request, render_template, jsonify, redirect, url_for, session
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user
from werkzeug.security import generate_password_hash, check_password_hash
import sqlite3
from datetime import datetime
from urllib.parse import unquote
@@ -6,7 +8,92 @@ import requests
import threading
app = Flask(__name__)
app.secret_key = 'your-secret-key-change-this' # Change this to a random secret key
DATABASE = 'data/database.db' # Updated path for the database
# Initialize Flask-Login
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
# User class for Flask-Login
class User(UserMixin):
def __init__(self, id, username):
self.id = id
self.username = username
@login_manager.user_loader
def load_user(user_id):
with sqlite3.connect(DATABASE) as conn:
cursor = conn.cursor()
cursor.execute('SELECT id, username FROM users WHERE id = ?', (user_id,))
user = cursor.fetchone()
if user:
return User(user[0], user[1])
return None
# Initialize users table if it doesn't exist
def init_users_table():
with sqlite3.connect(DATABASE) as conn:
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password TEXT NOT NULL,
created_at TEXT NOT NULL
)
''')
conn.commit()
# Create default admin user if no users exist
cursor.execute('SELECT COUNT(*) FROM users')
if cursor.fetchone()[0] == 0:
admin_password = generate_password_hash('admin123')
cursor.execute('''
INSERT INTO users (username, password, created_at)
VALUES (?, ?, ?)
''', ('admin', admin_password, datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
conn.commit()
print("Default admin user created - username: admin, password: admin123")
# Login route
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
if not username or not password:
return render_template('login.html', error='Username and password are required'), 400
with sqlite3.connect(DATABASE) as conn:
cursor = conn.cursor()
cursor.execute('SELECT id, username, password FROM users WHERE username = ?', (username,))
user_data = cursor.fetchone()
if user_data and check_password_hash(user_data[2], password):
user = User(user_data[0], user_data[1])
login_user(user)
return redirect(url_for('dashboard'))
else:
return render_template('login.html', error='Invalid username or password'), 401
return render_template('login.html')
# Logout route
@app.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('login'))
# Redirect root to dashboard
@app.route('/')
def index():
if current_user.is_authenticated:
return redirect(url_for('dashboard'))
return redirect(url_for('login'))
# Route to handle log submissions
@app.route('/logs', methods=['POST'])
@app.route('/log', methods=['POST'])
@@ -55,6 +142,7 @@ def log_event():
# Route to display the dashboard (excluding server logs)
@app.route('/dashboard', methods=['GET'])
@login_required
def dashboard():
with sqlite3.connect(DATABASE) as conn:
cursor = conn.cursor()
@@ -70,6 +158,7 @@ def dashboard():
return render_template('dashboard.html', logs=logs)
# Route to display logs for a specific device (excluding server logs)
@app.route('/device_logs/<nume_masa>', methods=['GET'])
@login_required
def device_logs(nume_masa):
nume_masa = unquote(nume_masa) # Decode URL-encoded value
with sqlite3.connect(DATABASE) as conn:
@@ -85,6 +174,7 @@ def device_logs(nume_masa):
return render_template('device_logs.html', logs=logs, nume_masa=nume_masa)
@app.route('/unique_devices', methods=['GET'])
@login_required
def unique_devices():
with sqlite3.connect(DATABASE) as conn:
cursor = conn.cursor()
@@ -100,6 +190,7 @@ def unique_devices():
return render_template('unique_devices.html', devices=devices)
@app.route('/hostname_logs/<hostname>', methods=['GET'])
@login_required
def hostname_logs(hostname):
with sqlite3.connect(DATABASE) as conn:
cursor = conn.cursor()
@@ -115,6 +206,7 @@ def hostname_logs(hostname):
# Route to display server logs only
@app.route('/server_logs', methods=['GET'])
@login_required
def server_logs():
with sqlite3.connect(DATABASE) as conn:
cursor = conn.cursor()
@@ -172,6 +264,7 @@ def get_device_status(device_ip):
# Route to display device management page (excluding server)
@app.route('/device_management', methods=['GET'])
@login_required
def device_management():
with sqlite3.connect(DATABASE) as conn:
cursor = conn.cursor()
@@ -188,6 +281,7 @@ def device_management():
# Route to execute command on a specific device
@app.route('/execute_command', methods=['POST'])
@login_required
def execute_command():
try:
data = request.json
@@ -221,12 +315,14 @@ def execute_command():
# Route to get device status
@app.route('/device_status/<device_ip>', methods=['GET'])
@login_required
def device_status(device_ip):
result = get_device_status(device_ip)
return jsonify(result), 200 if result['success'] else 400
# Route to execute command on multiple devices
@app.route('/execute_command_bulk', methods=['POST'])
@login_required
def execute_command_bulk():
try:
data = request.json
@@ -273,6 +369,7 @@ def execute_command_bulk():
return jsonify({"error": f"Server error: {str(e)}"}), 500
@app.route('/auto_update_devices', methods=['POST'])
@login_required
def auto_update_devices():
"""
Trigger auto-update on selected devices
@@ -367,6 +464,7 @@ def auto_update_devices():
# Route to clear and reset the database
@app.route('/reset_database', methods=['POST'])
@login_required
def reset_database():
"""
Clear all data from the database and reinitialize with fresh schema
@@ -423,6 +521,7 @@ def reset_database():
# Route to get database statistics
@app.route('/database_stats', methods=['GET'])
@login_required
def database_stats():
"""
Get database statistics including log count
@@ -459,4 +558,5 @@ def database_stats():
}), 500
if __name__ == '__main__':
init_users_table()
app.run(host='0.0.0.0', port=80)