from flask import Flask, render_template, jsonify, redirect, url_for, request, session from .db import init_db, engine from . import config, auth from sqlmodel import Session, select from .models import User app = Flask(__name__) app.secret_key = config.WEB_SECRET # Для подписи куки-сессий # Инициализация БД with app.app_context(): init_db() @app.route("/healthz") def healthz(): return jsonify({"status": "ok", "service": "morozovka-portal"}) @app.route("/") def index(): # Если юзер уже в сессии, показываем имя current_user = session.get("username") return render_template("index.html", username=current_user) # 1. Редирект на Gitea для авторизации @app.route("/login") def login(): gitea_auth_url = ( f"{config.GITEA_PUBLIC_URL}/login/oauth/authorize" f"?client_id={config.GITEA_CLIENT_ID}&response_type=code" f"&redirect_uri=https://portal.morozovka.space/auth/callback" f"&scope=read:user" ) return redirect(gitea_auth_url) # 2. Колбэк от Gitea @app.route("/auth/callback") def auth_callback(): code = request.args.get("code") if not code: return "Ошибка: Gitea не передала код авторизации.", 400 # Меняем код на токен token = auth.get_gitea_token(code) if not token: return "Ошибка: не удалось получить токен от Gitea.", 400 # Получаем юзера из Gitea gitea_user = auth.get_gitea_user(token) if not gitea_user: return "Ошибка: не удалось получить профиль пользователя.", 400 # Сохраняем или обновляем в БД with Session(engine) as db_session: user = db_session.exec(select(User).where(User.gitea_id == gitea_user["id"])).first() if not user: # Создаем нового new_user = User( gitea_id=gitea_user["id"], username=gitea_user["login"], full_name=gitea_user.get("full_name"), email=gitea_user.get("email"), role="admin" if gitea_user["login"] == "git_admin" else "student" # Первому дадим админа ) db_session.add(new_user) db_session.commit() user = new_user else: # Обновляем данные, если изменились в Gitea user.username = gitea_user["login"] user.full_name = gitea_user.get("full_name") user.email = gitea_user.get("email") db_session.add(user) db_session.commit() # Пишем в сессию Flask session["user_id"] = user.id session["username"] = user.username return redirect(url_for("profile")) # 3. Страница профиля (только для авторизованных) @app.route("/profile") def profile(): user_id = session.get("user_id") if not user_id: return redirect(url_for("login")) with Session(engine) as db_session: user = db_session.get(User, user_id) if not user: session.clear() return redirect(url_for("login")) return render_template("profile.html", user=user) # 4. Выход @app.route("/logout") def logout(): session.clear() return redirect(url_for("index"))