forked from Github-Mirrors/canaille
Split the consent page in two
This commit is contained in:
parent
69c67345c2
commit
0f93029d2a
4 changed files with 143 additions and 75 deletions
|
@ -22,11 +22,11 @@ bp = Blueprint("consents", __name__, url_prefix="/consent")
|
||||||
def consents(user):
|
def consents(user):
|
||||||
consents = Consent.query(subject=user)
|
consents = Consent.query(subject=user)
|
||||||
clients = {t.client for t in consents}
|
clients = {t.client for t in consents}
|
||||||
preconsented = [
|
|
||||||
client
|
nb_consents = len(consents)
|
||||||
for client in Client.query()
|
nb_preconsents = sum(
|
||||||
if client.preconsent and client not in clients
|
1 for client in Client.query() if client.preconsent and client not in clients
|
||||||
]
|
)
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"oidc/user/consent_list.html",
|
"oidc/user/consent_list.html",
|
||||||
|
@ -34,7 +34,33 @@ def consents(user):
|
||||||
menuitem="consents",
|
menuitem="consents",
|
||||||
scope_details=SCOPE_DETAILS,
|
scope_details=SCOPE_DETAILS,
|
||||||
ignored_scopes=["openid"],
|
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
|
||||||
|
]
|
||||||
|
|
||||||
|
nb_consents = len(consents)
|
||||||
|
nb_preconsents = len(preconsented)
|
||||||
|
|
||||||
|
return render_template(
|
||||||
|
"oidc/user/preconsent_list.html",
|
||||||
|
menuitem="consents",
|
||||||
|
scope_details=SCOPE_DETAILS,
|
||||||
|
ignored_scopes=["openid"],
|
||||||
preconsented=preconsented,
|
preconsented=preconsented,
|
||||||
|
nb_consents=nb_consents,
|
||||||
|
nb_preconsents=nb_preconsents,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,23 @@
|
||||||
<script src="/static/js/users.js"></script>
|
<script src="/static/js/users.js"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block submenu %}
|
||||||
|
<nav class="ui bottom attached two item borderless menu">
|
||||||
|
<a class="active item" href="{{ url_for('oidc.consents.consents') }}">
|
||||||
|
<i class="handshake icon"></i>
|
||||||
|
{% trans %}My consents{% endtrans %}
|
||||||
|
{% if nb_consents %}<div class="ui mini label">{{ nb_consents }}</div>{% endif %}
|
||||||
|
</a>
|
||||||
|
<a class="item" href="{{ url_for('oidc.consents.pre_consents') }}">
|
||||||
|
<i class="stamp icon"></i>
|
||||||
|
{% trans %}Pre-authorized applications{% endtrans %}
|
||||||
|
{% if nb_preconsents %}<div class="ui mini label">{{ nb_preconsents }}</div>{% endif %}
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="ui segment">
|
<div class="ui bottom attached segment">
|
||||||
<h2 class="ui center aligned header">
|
<h2 class="ui center aligned header">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
{{ _("My consents") }}
|
{{ _("My consents") }}
|
||||||
|
@ -101,72 +116,5 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if preconsented %}
|
|
||||||
<h2 class="ui center aligned header">
|
|
||||||
<div class="content">
|
|
||||||
{{ _("Pre-authorized applications") }}
|
|
||||||
</div>
|
|
||||||
<div class="sub header">
|
|
||||||
{% trans %}Those applications automatically have authorizations to access you data.{% endtrans %}
|
|
||||||
</div>
|
|
||||||
</h2>
|
|
||||||
<div class="ui centered cards">
|
|
||||||
{% for client in preconsented %}
|
|
||||||
<div class="ui card">
|
|
||||||
<div class="content">
|
|
||||||
{% if client.logo_uri %}
|
|
||||||
<img class="right floated mini ui image" src="{{ client.logo_uri }}">
|
|
||||||
{% endif %}
|
|
||||||
{% if client.client_uri %}
|
|
||||||
<a href="{{ client.client_uri }}" class="header">{{ client.client_name }}</a>
|
|
||||||
{% else %}
|
|
||||||
<div class="header">{{ client.client_name }}</div>
|
|
||||||
{% endif %}
|
|
||||||
<div class="description">
|
|
||||||
<p>
|
|
||||||
{% trans %}Has access to:{% endtrans %}
|
|
||||||
</p>
|
|
||||||
<div class="ui list">
|
|
||||||
{% for scope in client.scope %}
|
|
||||||
{% if scope not in ignored_scopes %}
|
|
||||||
{% if scope not in scope_details %}
|
|
||||||
<div class="item" title="{{ scope }}">{{ scope }}</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="item" title="{{ scope }}">
|
|
||||||
<i class="{{ scope_details[scope][0] }} icon"></i>
|
|
||||||
<div class="content">{{ scope_details[scope][1] }}</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% if client.policy_uri %}
|
|
||||||
<div class="extra content">
|
|
||||||
<span>
|
|
||||||
<i class="mask icon"></i>
|
|
||||||
<a href="{{ client.policy_uri }}">{% trans %}Policy{% endtrans %}</a>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% if client.tos_uri %}
|
|
||||||
<div class="extra content">
|
|
||||||
<span>
|
|
||||||
<i class="file signature icon"></i>
|
|
||||||
<a href="{{ client.tos_uri }}">{% trans %}Terms of service{% endtrans %}</a>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<a class="ui bottom attached button" href="{{ url_for('oidc.consents.revoke_preconsent', client_id=client.client_id ) }}">
|
|
||||||
<i class="remove icon"></i>
|
|
||||||
{% trans %}Revoke access{% endtrans %}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
94
canaille/templates/oidc/user/preconsent_list.html
Normal file
94
canaille/templates/oidc/user/preconsent_list.html
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
{% extends theme('base.html') %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
{% trans %}My consents{% endtrans %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block script %}
|
||||||
|
<script src="/static/js/users.js"></script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block submenu %}
|
||||||
|
<nav class="ui bottom attached two item borderless menu">
|
||||||
|
<a class="item" href="{{ url_for('oidc.consents.consents') }}">
|
||||||
|
<i class="handshake icon"></i>
|
||||||
|
{% trans %}My consents{% endtrans %}
|
||||||
|
{% if nb_consents %}<div class="ui mini label">{{ nb_consents }}</div>{% endif %}
|
||||||
|
</a>
|
||||||
|
<a class="active item" href="{{ url_for('oidc.consents.pre_consents') }}">
|
||||||
|
<i class="stamp icon"></i>
|
||||||
|
{% trans %}Pre-authorized applications{% endtrans %}
|
||||||
|
{% if nb_preconsents %}<div class="ui mini label">{{ nb_preconsents }}</div>{% endif %}
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="ui bottom attached segment">
|
||||||
|
{% if preconsented %}
|
||||||
|
<h2 class="ui center aligned header">
|
||||||
|
<div class="content">
|
||||||
|
{{ _("Pre-authorized applications") }}
|
||||||
|
</div>
|
||||||
|
<div class="sub header">
|
||||||
|
{% trans %}Those applications automatically have authorizations to access you data.{% endtrans %}
|
||||||
|
</div>
|
||||||
|
</h2>
|
||||||
|
<div class="ui centered cards">
|
||||||
|
{% for client in preconsented %}
|
||||||
|
<div class="ui card">
|
||||||
|
<div class="content">
|
||||||
|
{% if client.logo_uri %}
|
||||||
|
<img class="right floated mini ui image" src="{{ client.logo_uri }}">
|
||||||
|
{% endif %}
|
||||||
|
{% if client.client_uri %}
|
||||||
|
<a href="{{ client.client_uri }}" class="header">{{ client.client_name }}</a>
|
||||||
|
{% else %}
|
||||||
|
<div class="header">{{ client.client_name }}</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="description">
|
||||||
|
<p>
|
||||||
|
{% trans %}Has access to:{% endtrans %}
|
||||||
|
</p>
|
||||||
|
<div class="ui list">
|
||||||
|
{% for scope in client.scope %}
|
||||||
|
{% if scope not in ignored_scopes %}
|
||||||
|
{% if scope not in scope_details %}
|
||||||
|
<div class="item" title="{{ scope }}">{{ scope }}</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="item" title="{{ scope }}">
|
||||||
|
<i class="{{ scope_details[scope][0] }} icon"></i>
|
||||||
|
<div class="content">{{ scope_details[scope][1] }}</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% if client.policy_uri %}
|
||||||
|
<div class="extra content">
|
||||||
|
<span>
|
||||||
|
<i class="mask icon"></i>
|
||||||
|
<a href="{{ client.policy_uri }}">{% trans %}Policy{% endtrans %}</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% if client.tos_uri %}
|
||||||
|
<div class="extra content">
|
||||||
|
<span>
|
||||||
|
<i class="file signature icon"></i>
|
||||||
|
<a href="{{ client.tos_uri }}">{% trans %}Terms of service{% endtrans %}</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<a class="ui bottom attached button" href="{{ url_for('oidc.consents.revoke_preconsent', client_id=client.client_id ) }}">
|
||||||
|
<i class="remove icon"></i>
|
||||||
|
{% trans %}Revoke access{% endtrans %}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -145,13 +145,13 @@ def test_oidc_authorization_after_revokation(
|
||||||
|
|
||||||
def test_preconsented_client_appears_in_consent_list(testclient, client, logged_user):
|
def test_preconsented_client_appears_in_consent_list(testclient, client, logged_user):
|
||||||
assert not client.preconsent
|
assert not client.preconsent
|
||||||
res = testclient.get("/consent")
|
res = testclient.get("/consent/pre-consents")
|
||||||
res.mustcontain(no=client.client_name)
|
res.mustcontain(no=client.client_name)
|
||||||
|
|
||||||
client.preconsent = True
|
client.preconsent = True
|
||||||
client.save()
|
client.save()
|
||||||
|
|
||||||
res = testclient.get("/consent")
|
res = testclient.get("/consent/pre-consents")
|
||||||
res.mustcontain(client.client_name)
|
res.mustcontain(client.client_name)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue