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:
102
server.py
102
server.py
@@ -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)
|
||||
Reference in New Issue
Block a user