canaille-globuzma/canaille/oidc/consents.py

132 lines
3.4 KiB
Python
Raw Normal View History

import datetime
import uuid
2023-04-09 13:52:55 +00:00
from canaille.app.flask import user_needed
2022-01-11 18:49:06 +00:00
from canaille.oidc.models import Client
from canaille.oidc.models import Consent
2021-12-20 22:57:27 +00:00
from flask import Blueprint
from flask import flash
from flask import redirect
from flask import url_for
from flask_babel import gettext as _
2021-12-20 22:57:27 +00:00
from flask_themer import render_template
2020-09-17 10:01:21 +00:00
from .utils import SCOPE_DETAILS
2020-09-17 10:01:21 +00:00
2022-01-11 18:49:06 +00:00
bp = Blueprint("consents", __name__, url_prefix="/consent")
2020-09-17 10:01:21 +00:00
@bp.route("/")
@user_needed()
def consents(user):
consents = Consent.query(subject=user)
clients = {t.client for t in consents}
2023-03-15 16:38:32 +00:00
nb_consents = len(consents)
nb_preconsents = sum(
1 for client in Client.query() if client.preconsent and client not in clients
)
return render_template(
"oidc/user/consent_list.html",
consents=consents,
menuitem="consents",
scope_details=SCOPE_DETAILS,
ignored_scopes=["openid"],
nb_consents=nb_consents,
nb_preconsents=nb_preconsents,
)
@bp.route("/pre-consents")
@user_needed()
def pre_consents(user):
consents = Consent.query(subject=user)
clients = {t.client for t in consents}
preconsented = [
client
for client in Client.query()
if client.preconsent and client not in clients
]
2023-03-15 16:38:32 +00:00
nb_consents = len(consents)
nb_preconsents = len(preconsented)
2020-10-21 10:14:35 +00:00
return render_template(
2023-03-15 16:38:32 +00:00
"oidc/user/preconsent_list.html",
2022-01-11 18:49:06 +00:00
menuitem="consents",
scope_details=SCOPE_DETAILS,
ignored_scopes=["openid"],
preconsented=preconsented,
2023-03-15 16:38:32 +00:00
nb_consents=nb_consents,
nb_preconsents=nb_preconsents,
2020-10-21 10:14:35 +00:00
)
2020-09-17 10:01:21 +00:00
2023-02-14 17:43:43 +00:00
@bp.route("/revoke/<consent_id>")
2020-09-17 10:01:21 +00:00
@user_needed()
2023-02-14 17:43:43 +00:00
def revoke(user, consent_id):
2020-09-17 10:01:21 +00:00
consent = Consent.get(consent_id)
if not consent or consent.subject != user:
2023-02-14 17:43:43 +00:00
flash(_("Could not revoke this access"), "error")
elif consent.revokation_date:
flash(_("The access is already revoked"), "error")
2020-09-17 10:01:21 +00:00
else:
consent.revoke()
2023-02-14 17:43:43 +00:00
flash(_("The access has been revoked"), "success")
return redirect(url_for("oidc.consents.consents"))
@bp.route("/restore/<consent_id>")
@user_needed()
def restore(user, consent_id):
consent = Consent.get(consent_id)
if not consent or consent.subject != user:
2023-02-14 17:43:43 +00:00
flash(_("Could not restore this access"), "error")
elif not consent.revokation_date:
flash(_("The access is not revoked"), "error")
else:
consent.restore()
if not consent.issue_date:
2023-03-17 23:38:56 +00:00
consent.issue_date = datetime.datetime.now(datetime.timezone.utc)
consent.save()
2023-02-14 17:43:43 +00:00
flash(_("The access has been restored"), "success")
2020-09-17 10:01:21 +00:00
2022-01-11 18:49:06 +00:00
return redirect(url_for("oidc.consents.consents"))
@bp.route("/revoke-preconsent/<client_id>")
@user_needed()
def revoke_preconsent(user, client_id):
client = Client.get(client_id)
if not client or not client.preconsent:
flash(_("Could not revoke this access"), "error")
return redirect(url_for("oidc.consents.consents"))
consent = Consent.get(client=client, subject=user)
if consent:
2023-03-09 23:38:16 +00:00
return redirect(
url_for("oidc.consents.revoke", consent_id=consent.consent_id[0])
)
consent = Consent(
cn=str(uuid.uuid4()),
client=client,
subject=user,
scope=client.scope,
)
consent.revoke()
consent.save()
flash(_("The access has been revoked"), "success")
return redirect(url_for("oidc.consents.consents"))