from flask import Blueprint, render_template, request, jsonify, redirect, url_for, flash from flask_login import login_user, logout_user, login_required, current_user from werkzeug.security import generate_password_hash, check_password_hash from db import get_db, generate_clan_key from datetime import datetime auth = Blueprint('auth', __name__) # ------------------------------------------------------------------ # Helper — resolve the User class from app (avoid circular import) # ------------------------------------------------------------------ def _make_user(row): from app import User return User(row['id'], row['username']) # ------------------------------------------------------------------ # GET/POST /auth/login # ------------------------------------------------------------------ @auth.route('/auth/login', methods=['GET', 'POST']) def login(): if current_user.is_authenticated: return redirect(url_for('dashboard.index')) error = None if request.method == 'POST': username = request.form.get('username', '').strip() password = request.form.get('password', '') conn = get_db() row = conn.execute( 'SELECT id, username, password_hash FROM users WHERE username = ?', (username,) ).fetchone() conn.close() if row and check_password_hash(row['password_hash'], password): user = _make_user(row) login_user(user, remember=True) return redirect(url_for('dashboard.index')) else: error = 'Λάθος όνομα χρήστη ή κωδικός.' return render_template('login.html', error=error) # ------------------------------------------------------------------ # GET/POST /auth/register # ------------------------------------------------------------------ @auth.route('/auth/register', methods=['GET', 'POST']) def register(): if current_user.is_authenticated: return redirect(url_for('dashboard.index')) error = None if request.method == 'POST': username = request.form.get('username', '').strip() password = request.form.get('password', '') confirm = request.form.get('confirm', '') if not username or not password: error = 'Συμπλήρωσε όνομα χρήστη και κωδικό.' elif password != confirm: error = 'Οι κωδικοί δεν ταιριάζουν.' elif len(password) < 6: error = 'Ο κωδικός πρέπει να έχει τουλάχιστον 6 χαρακτήρες.' else: conn = get_db() existing = conn.execute( 'SELECT id FROM users WHERE username = ?', (username,) ).fetchone() if existing: error = 'Το όνομα χρήστη χρησιμοποιείται ήδη.' conn.close() else: pw_hash = generate_password_hash(password) conn.execute( 'INSERT INTO users (username, password_hash) VALUES (?, ?)', (username, pw_hash) ) conn.commit() row = conn.execute( 'SELECT id, username, password_hash FROM users WHERE username = ?', (username,) ).fetchone() conn.close() user = _make_user(row) login_user(user, remember=True) return redirect(url_for('auth.options')) return render_template('register.html', error=error) # ------------------------------------------------------------------ # GET /auth/logout # ------------------------------------------------------------------ @auth.route('/auth/logout') @login_required def logout(): logout_user() return redirect(url_for('auth.login')) # ------------------------------------------------------------------ # GET/POST /auth/options — Clan management page # ------------------------------------------------------------------ @auth.route('/auth/options', methods=['GET', 'POST']) @login_required def options(): conn = get_db() # Load this user's clan (one clan per user for now) clan = conn.execute( 'SELECT * FROM clans WHERE owner_id = ?', (current_user.id,) ).fetchone() members = [] if clan: members = conn.execute( '''SELECT cm.id, cm.player_id, cm.player_name, cm.joined_at, ts.updated_at FROM clan_members cm LEFT JOIN town_state ts ON ts.player_id = cm.player_id WHERE cm.clan_id = ? GROUP BY cm.player_id ORDER BY cm.joined_at DESC''', (clan['id'],) ).fetchall() conn.close() return render_template('options.html', clan=clan, members=members) # ------------------------------------------------------------------ # POST /auth/clan/create # ------------------------------------------------------------------ @auth.route('/auth/clan/create', methods=['POST']) @login_required def create_clan(): clan_name = request.form.get('clan_name', '').strip() if not clan_name: return redirect(url_for('auth.options')) conn = get_db() existing = conn.execute( 'SELECT id FROM clans WHERE owner_id = ?', (current_user.id,) ).fetchone() if not existing: key = generate_clan_key() conn.execute( 'INSERT INTO clans (owner_id, name, clan_key) VALUES (?, ?, ?)', (current_user.id, clan_name, key) ) conn.commit() conn.close() return redirect(url_for('auth.options')) # ------------------------------------------------------------------ # POST /auth/clan/regenerate-key # ------------------------------------------------------------------ @auth.route('/auth/clan/regenerate-key', methods=['POST']) @login_required def regenerate_key(): new_key = generate_clan_key() conn = get_db() conn.execute( 'UPDATE clans SET clan_key = ? WHERE owner_id = ?', (new_key, current_user.id) ) conn.commit() conn.close() return redirect(url_for('auth.options')) # ------------------------------------------------------------------ # POST /auth/clan/remove-member/ # ------------------------------------------------------------------ @auth.route('/auth/clan/remove-member/', methods=['POST']) @login_required def remove_member(player_id): conn = get_db() clan = conn.execute( 'SELECT id FROM clans WHERE owner_id = ?', (current_user.id,) ).fetchone() if clan: conn.execute( 'DELETE FROM clan_members WHERE clan_id = ? AND player_id = ?', (clan['id'], player_id) ) conn.commit() conn.close() return redirect(url_for('auth.options'))