Add login system with authentication and login page

Introduced a login system to restrict access to the application. Added session-based authentication in app.py, including login and logout routes, and a new login.html template for the login form. Updated .dockerignore to exclude .uv directory.
This commit is contained in:
Jon Ander Oribe
2026-01-11 14:06:55 +01:00
parent 7967b71405
commit 6da8b11301
3 changed files with 113 additions and 1 deletions

View File

@@ -15,6 +15,7 @@ venv/
.eggs/
*.egg-info/
*.egg
.uv
# IDE
.idea/

31
app.py
View File

@@ -23,7 +23,7 @@ import subprocess
from typing import Any
from flask import Flask, render_template, jsonify, send_file, Response, request
from flask import Flask, render_template, jsonify, send_file, Response, request,redirect, url_for, flash, session
from config import VERSION
from utils.dependencies import check_tool, check_all_dependencies, TOOL_DEPENDENCIES
@@ -44,6 +44,7 @@ _app_start_time = _time.time()
# Create Flask app
app = Flask(__name__)
app.secret_key = "signals_intelligence_secret" # Required for flash messages
# Disable Werkzeug debugger PIN (not needed for local development tool)
os.environ['WERKZEUG_DEBUG_PIN'] = 'off'
@@ -141,6 +142,34 @@ cleanup_manager.register(adsb_aircraft)
# MAIN ROUTES
# ============================================
@app.before_request
def require_login():
# Lista de rutas que NO requieren login (para evitar un bucle infinito)
allowed_routes = ['login', 'static', 'favicon']
# Si el usuario no está logueado y la ruta actual no está permitida...
if 'logged_in' not in session and request.endpoint not in allowed_routes:
return redirect(url_for('login'))
@app.route('/logout')
def logout():
session.pop('logged_in', None)
return redirect(url_for('login'))
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
if username == "admin" and password == "intercept2026":
session['logged_in'] = True
return redirect(url_for('index'))
else:
flash("ACCESS DENIED: INVALID CREDENTIALS", "error")
return render_template('login.html', version=VERSION)
@app.route('/')
def index() -> str:
tools = {

82
templates/login.html Normal file
View File

@@ -0,0 +1,82 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>iNTERCEPT // Restricted Access</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/index.css') }}">
<style>
/* Specific overrides for login layout */
.login-box {
background: rgba(10, 10, 26, 0.9);
border: 1px solid var(--accent-cyan);
padding: 30px;
border-radius: 4px;
box-shadow: 0 0 20px rgba(0, 212, 255, 0.2);
width: 100%;
max-width: 400px;
margin-top: 20px;
}
.form-input {
width: 100%;
background: #050510;
border: 1px solid #1a1a40;
color: var(--accent-cyan);
padding: 12px;
margin: 10px 0;
font-family: 'JetBrains Mono', monospace;
outline: none;
}
.form-input:focus {
border-color: var(--accent-green);
box-shadow: 0 0 10px rgba(0, 255, 136, 0.2);
}
.flash-error {
color: var(--accent-red);
font-size: 11px;
margin-bottom: 15px;
text-transform: uppercase;
border: 1px solid var(--accent-red);
padding: 8px;
background: rgba(255, 0, 0, 0.1);
}
</style>
</head>
<body>
<div class="landing-overlay">
<div class="landing-content">
<div class="landing-logo">
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="22" r="6" fill="#00ff88" class="logo-dot"/>
<rect x="44" y="35" width="12" height="45" rx="2" fill="#00d4ff"/>
</svg>
</div>
<h1 class="landing-title" style="font-size: 2.5rem;">SECURE LOGIN</h1>
<p class="landing-tagline">// Restricted Terminal Access</p>
<div class="login-box">
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="flash-error">{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
<form method="POST">
<input type="text" name="username" placeholder="OPERATOR ID" class="form-input" required autofocus>
<input type="password" name="password" placeholder="ENCRYPTION KEY" class="form-input" required>
<button type="submit" class="landing-enter-btn" style="width: 100%; margin-top: 20px;">
<span class="btn-text">INITIALIZE SESSION</span>
</button>
</form>
</div>
<p class="landing-version">SYSTEM AUTH v{{ version }}</p>
</div>
<div class="landing-scanline"></div>
</div>
</body>
</html>