102 lines
3.5 KiB
Python
102 lines
3.5 KiB
Python
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"))
|