You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
2.9 KiB

import os
import time
from base64 import b64decode, b64encode
from typing import Union
from urllib.parse import quote, unquote
from flask import (Flask, flash, redirect, render_template, request,
send_from_directory, url_for)
from flask_login import LoginManager, login_required, login_user, logout_user
from auth import Auth
from forms import LoginForm
from latosa import LaToSa
from user import User
app = Flask(__name__)
app.config.update(
SECRET_KEY=os.urandom(32),
SESSION_COOKIE_HTTPONLY=True,
REMEMBER_COOKIE_HTTPONLY=True,
SESSION_COOKIE_SAMESITE="Strict",
)
login_manager = LoginManager()
login_manager.init_app(app)
latosa = LaToSa(app)
@login_manager.user_loader
def load_user(user_id) -> Union[User, None]:
for user in latosa.get_users():
if user.uid == user_id:
return user
return None
@app.route('/', methods=['GET', 'POST'])
def index():
i18n = latosa.get_i18n(request)
session = request.args.get('session', None)
client_id = request.args.get('client_id', None)
form = LoginForm()
form.session.data = session
form.session.data = client_id
if request.method == 'POST':
username = form.username.data
password = form.password.data
redirect_to = url_for('admin')
user = latosa.login_user(username, password)
if user:
login_user(user)
client_id = form.client_id.data
session = form.session.data
if session:
session = unquote(b64decode(session))
if session and client_id:
session_auth = Auth()
session_data = session_auth.decrypt(client_id, session)
session_key = session_data['session_key']
if 'redirect_to' in session_data:
response_data = {
'status': 'success',
'uid': user.uid,
'email': user.email,
'display_name': user.display_name,
'groups': user.groups,
'timestamp': time.time()
}
cyphertext = session_auth.encrypt(session_key, response_data)
b64 = quote(b64encode(cyphertext).decode('utf-8'))
url = session_data['redirect_to']
redirect_to = f'{url}?session={b64}'
return redirect(redirect_to)
flash(i18n['login']['failed'])
return render_template('index.html', i18n=i18n, form=form)
@app.route('/admin', methods=['GET'])
@login_required
def admin():
i18n = latosa.get_i18n(request)
return render_template('admin.html', i18n=i18n)
@app.route('/favicon.ico')
def favicon():
return send_from_directory(os.path.join(app.root_path, 'static'),
'favicon.ico',
mimetype='image/vnd.microsoft.icon')