forked from Github-Mirrors/canaille
121 lines
3.6 KiB
Python
121 lines
3.6 KiB
Python
from urllib.parse import urlsplit
|
|
from urllib.parse import urlunsplit
|
|
|
|
from authlib.common.errors import AuthlibBaseError
|
|
from authlib.integrations.flask_client import OAuth
|
|
from authlib.oidc.discovery import get_well_known_url
|
|
from flask import Flask
|
|
from flask import current_app
|
|
from flask import flash
|
|
from flask import redirect
|
|
from flask import render_template
|
|
from flask import session
|
|
from flask import url_for
|
|
|
|
oauth = OAuth()
|
|
|
|
|
|
def setup_routes(app):
|
|
@app.route("/")
|
|
@app.route("/tos")
|
|
@app.route("/policy")
|
|
def index():
|
|
return render_template(
|
|
"index.html", user=session.get("user"), name=app.config["NAME"]
|
|
)
|
|
|
|
@app.route("/register")
|
|
def register():
|
|
return oauth.canaille.authorize_redirect(
|
|
url_for("register_callback", _external=True), prompt="create"
|
|
)
|
|
|
|
@app.route("/register_callback")
|
|
def register_callback():
|
|
try:
|
|
token = oauth.canaille.authorize_access_token()
|
|
session["user"] = token.get("userinfo")
|
|
session["id_token"] = token["id_token"]
|
|
flash("You account has been successfully created.", "success")
|
|
except AuthlibBaseError as exc:
|
|
flash(f"An error happened during registration: {exc.description}", "error")
|
|
|
|
return redirect(url_for("index"))
|
|
|
|
@app.route("/login")
|
|
def login():
|
|
return oauth.canaille.authorize_redirect(
|
|
url_for("login_callback", _external=True)
|
|
)
|
|
|
|
@app.route("/login_callback")
|
|
def login_callback():
|
|
try:
|
|
token = oauth.canaille.authorize_access_token()
|
|
session["user"] = token.get("userinfo")
|
|
session["id_token"] = token["id_token"]
|
|
flash("You have been successfully logged in.", "success")
|
|
except AuthlibBaseError as exc:
|
|
flash(f"An error happened during login: {exc.description}", "error")
|
|
|
|
return redirect(url_for("index"))
|
|
|
|
@app.route("/logout")
|
|
def logout():
|
|
oauth.canaille.load_server_metadata()
|
|
end_session_endpoint = oauth.canaille.server_metadata.get(
|
|
"end_session_endpoint"
|
|
)
|
|
end_session_url = set_parameter_in_url_query(
|
|
end_session_endpoint,
|
|
client_id=current_app.config["OAUTH_CLIENT_ID"],
|
|
id_token_hint=session["id_token"],
|
|
post_logout_redirect_uri=url_for("logout_callback", _external=True),
|
|
)
|
|
return redirect(end_session_url)
|
|
|
|
@app.route("/logout_callback")
|
|
def logout_callback():
|
|
try:
|
|
del session["user"]
|
|
except KeyError:
|
|
pass
|
|
|
|
flash("You have been successfully logged out", "success")
|
|
return redirect(url_for("index"))
|
|
|
|
|
|
def setup_oauth(app):
|
|
oauth.init_app(app)
|
|
oauth.register(
|
|
name="canaille",
|
|
client_id=app.config["OAUTH_CLIENT_ID"],
|
|
client_secret=app.config["OAUTH_CLIENT_SECRET"],
|
|
server_metadata_url=get_well_known_url(
|
|
app.config["OAUTH_AUTH_SERVER"], external=True
|
|
),
|
|
client_kwargs={"scope": "openid profile email phone address groups"},
|
|
)
|
|
|
|
|
|
def create_app():
|
|
app = Flask(__name__)
|
|
app.config.from_envvar("CONFIG")
|
|
app.static_folder = "../../canaille/static"
|
|
|
|
setup_routes(app)
|
|
setup_oauth(app)
|
|
return app
|
|
|
|
|
|
def set_parameter_in_url_query(url, **kwargs):
|
|
split = list(urlsplit(url))
|
|
|
|
parameters = "&".join(f"{key}={value}" for key, value in kwargs.items())
|
|
|
|
if split[3]:
|
|
split[3] = f"{split[3]}&{parameters}"
|
|
else:
|
|
split[3] = parameters
|
|
|
|
return urlunsplit(split)
|