Coverage for heritrace/routes/auth.py: 100%
46 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-18 11:10 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-18 11:10 +0000
1import os
2from datetime import timedelta
4from flask import Blueprint, current_app, flash, redirect, request, session, url_for
5from flask_babel import gettext
6from flask_login import current_user, login_required, login_user, logout_user
7from heritrace.models import User
8from requests_oauthlib import OAuth2Session
10auth_bp = Blueprint("auth", __name__)
13@auth_bp.route("/login")
14def login():
15 if current_user.is_authenticated:
16 return redirect(url_for("main.catalogue"))
18 callback_url = url_for("auth.callback", _external=True, _scheme="https")
19 orcid = OAuth2Session(
20 current_app.config["ORCID_CLIENT_ID"],
21 redirect_uri=callback_url,
22 scope=[current_app.config["ORCID_SCOPE"], "openid"],
23 )
24 authorization_url, state = orcid.authorization_url(
25 current_app.config["ORCID_AUTHORIZE_URL"],
26 prompt="login", # Forza il re-login
27 nonce=os.urandom(16).hex(), # Aggiungiamo un nonce per sicurezza
28 )
29 session["oauth_state"] = state
30 return redirect(authorization_url)
33@auth_bp.route("/callback")
34def callback():
35 if request.url.startswith("http://"):
36 secure_url = request.url.replace("http://", "https://", 1)
37 else:
38 secure_url = request.url
40 orcid = OAuth2Session(
41 current_app.config["ORCID_CLIENT_ID"], state=session["oauth_state"]
42 )
43 try:
44 token = orcid.fetch_token(
45 current_app.config["ORCID_TOKEN_URL"],
46 client_secret=current_app.config["ORCID_CLIENT_SECRET"],
47 authorization_response=secure_url,
48 )
49 except Exception as e:
50 flash(
51 gettext("An error occurred during authentication. Please try again"),
52 "danger",
53 )
54 return redirect(url_for("auth.login"))
55 orcid_id = token["orcid"]
57 if orcid_id not in current_app.config["ORCID_WHITELIST"]:
58 flash(
59 gettext("Your ORCID is not authorized to access this application"), "danger"
60 )
61 return redirect(url_for("auth.login"))
62 session["user_name"] = token["name"]
63 user = User(id=orcid_id, name=token["name"], orcid=orcid_id)
64 session.permanent = True
65 current_app.permanent_session_lifetime = timedelta(days=30)
66 login_user(user)
67 flash(gettext("Welcome back %(name)s!", name=current_user.name), "success")
68 return redirect(url_for("main.catalogue"))
71@auth_bp.route("/logout")
72def logout():
73 if not current_user.is_authenticated:
74 return "", 401
75 logout_user()
76 flash(gettext("You have been logged out"), "info")
77 return redirect(url_for("main.index"))