|
|
@@ -1,9 +1,119 @@
|
|
|
-from flask import Blueprint, render_template, request, redirect, url_for, flash
|
|
|
+from flask import Blueprint, render_template, request, redirect, url_for, flash, session
|
|
|
from models import db, CatalogoPaneles, DatosSolaresCiudad, ProyectosUsuario, Casa, Configuracion
|
|
|
from datetime import datetime
|
|
|
+from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
|
|
|
+from extensions import socketio, login_manager
|
|
|
+import paramiko
|
|
|
+import threading
|
|
|
+import time
|
|
|
+import os
|
|
|
|
|
|
main = Blueprint('main', __name__)
|
|
|
|
|
|
+# --- Auth Setup ---
|
|
|
+class User(UserMixin):
|
|
|
+ def __init__(self, id):
|
|
|
+ self.id = id
|
|
|
+
|
|
|
+@login_manager.user_loader
|
|
|
+def load_user(user_id):
|
|
|
+ if user_id == '1':
|
|
|
+ return User(id='1')
|
|
|
+ return None
|
|
|
+
|
|
|
+@main.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 == 'solaradmin':
|
|
|
+ user = User(id='1')
|
|
|
+ login_user(user)
|
|
|
+ return redirect(url_for('main.admin'))
|
|
|
+ else:
|
|
|
+ flash('Credenciales inválidas', 'danger')
|
|
|
+ return render_template('login.html')
|
|
|
+
|
|
|
+@main.route('/logout')
|
|
|
+@login_required
|
|
|
+def logout():
|
|
|
+ logout_user()
|
|
|
+ return redirect(url_for('main.index'))
|
|
|
+
|
|
|
+@main.route('/admin')
|
|
|
+@login_required
|
|
|
+def admin():
|
|
|
+ return render_template('admin.html')
|
|
|
+
|
|
|
+# --- SSH Logic ---
|
|
|
+ssh_sessions = {}
|
|
|
+
|
|
|
+@socketio.on('connect', namespace='/ssh')
|
|
|
+def connect_ssh():
|
|
|
+ if not current_user.is_authenticated:
|
|
|
+ return False
|
|
|
+ # Start a new SSH session
|
|
|
+ # WARNING: Hardcoded credentials for demo purposes. EXTREMELY INSECURE.
|
|
|
+ # In a real app, use keys or prompt for credentials.
|
|
|
+ # Using the server's own credentials or a specific user.
|
|
|
+ # For this demo, we'll try to connect to localhost if possible, or just echo.
|
|
|
+ # But the user asked for "SSH console".
|
|
|
+ # Let's assume we want to connect to the machine running this app.
|
|
|
+ # We need credentials. The user asked for "dialogo que indique credenciales".
|
|
|
+ # So we will expect the user to provide them via the UI, but for the initial connection
|
|
|
+ # we might need to wait for a 'start_ssh' event with credentials.
|
|
|
+ pass
|
|
|
+
|
|
|
+@socketio.on('start_ssh', namespace='/ssh')
|
|
|
+def start_ssh(data):
|
|
|
+ if not current_user.is_authenticated:
|
|
|
+ return
|
|
|
+
|
|
|
+ host = data.get('host', 'localhost')
|
|
|
+ port = int(data.get('port', 22))
|
|
|
+ username = data.get('username')
|
|
|
+ password = data.get('password')
|
|
|
+
|
|
|
+ sid = request.sid
|
|
|
+
|
|
|
+ try:
|
|
|
+ client = paramiko.SSHClient()
|
|
|
+ client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
|
+ client.connect(host, port=port, username=username, password=password)
|
|
|
+
|
|
|
+ channel = client.invoke_shell()
|
|
|
+ ssh_sessions[sid] = {'client': client, 'channel': channel}
|
|
|
+
|
|
|
+ def listen_to_ssh():
|
|
|
+ while True:
|
|
|
+ if channel.recv_ready():
|
|
|
+ data = channel.recv(1024).decode('utf-8')
|
|
|
+ socketio.emit('ssh_output', {'data': data}, room=sid, namespace='/ssh')
|
|
|
+ socketio.sleep(0.1)
|
|
|
+ if not channel.active:
|
|
|
+ break
|
|
|
+
|
|
|
+ socketio.start_background_task(listen_to_ssh)
|
|
|
+
|
|
|
+ socketio.emit('ssh_status', {'status': 'connected'}, room=sid, namespace='/ssh')
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ socketio.emit('ssh_status', {'status': 'error', 'message': str(e)}, room=sid, namespace='/ssh')
|
|
|
+
|
|
|
+@socketio.on('ssh_input', namespace='/ssh')
|
|
|
+def ssh_input(data):
|
|
|
+ sid = request.sid
|
|
|
+ if sid in ssh_sessions:
|
|
|
+ channel = ssh_sessions[sid]['channel']
|
|
|
+ channel.send(data['data'])
|
|
|
+
|
|
|
+@socketio.on('disconnect', namespace='/ssh')
|
|
|
+def disconnect_ssh():
|
|
|
+ sid = request.sid
|
|
|
+ if sid in ssh_sessions:
|
|
|
+ ssh_sessions[sid]['client'].close()
|
|
|
+ del ssh_sessions[sid]
|
|
|
+
|
|
|
@main.route('/')
|
|
|
def index():
|
|
|
return render_template('index.html')
|