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
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')
|