mirror of
https://github.com/smittix/intercept.git
synced 2026-04-24 06:40:00 -07:00
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:
@@ -15,6 +15,7 @@ venv/
|
||||
.eggs/
|
||||
*.egg-info/
|
||||
*.egg
|
||||
.uv
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
|
||||
31
app.py
31
app.py
@@ -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
82
templates/login.html
Normal 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>
|
||||
Reference in New Issue
Block a user