Draft for a 'my accesses' page

This commit is contained in:
Éloi Rivard 2020-08-26 17:23:53 +02:00
parent f2da1e87db
commit 5ab64429de
19 changed files with 123 additions and 64 deletions

View file

@ -2,20 +2,20 @@ from web.models import Client
def test_no_logged_no_access(testclient):
testclient.get("/client", status=403)
testclient.get("/admin/client", status=403)
def test_no_admin_no_access(testclient, logged_user):
testclient.get("/client", status=403)
testclient.get("/admin/client", status=403)
def test_client_list(testclient, client, logged_admin):
res = testclient.get("/client")
res = testclient.get("/admin/client")
assert client.oauthClientName in res.text
def test_client_add(testclient, logged_admin, slapd_connection):
res = testclient.get("/client/add")
res = testclient.get("/admin/client/add")
data = {
"oauthClientName": "foobar",
"oauthClientContact": "foo@bar.com",
@ -52,7 +52,7 @@ def test_client_add(testclient, logged_admin, slapd_connection):
def test_client_edit(testclient, client, logged_admin, slapd_connection):
res = testclient.get("/client/edit/" + client.oauthClientID)
res = testclient.get("/admin/client/edit/" + client.oauthClientID)
data = {
"oauthClientName": "foobar",
"oauthClientContact": "foo@bar.com",

View file

@ -1,17 +1,17 @@
def test_no_logged_no_access(testclient):
testclient.get("/authorization", status=403)
testclient.get("/admin/authorization", status=403)
def test_no_admin_no_access(testclient, logged_user):
testclient.get("/authorization", status=403)
testclient.get("/admin/authorization", status=403)
def test_authorizaton_list(testclient, authorization, logged_admin):
res = testclient.get("/authorization")
res = testclient.get("/admin/authorization")
assert authorization.oauthCode in res.text
def test_authorizaton_view(testclient, authorization, logged_admin):
res = testclient.get("/authorization/" + authorization.oauthCode)
res = testclient.get("/admin/authorization/" + authorization.oauthCode)
for attr in authorization.may + authorization.must:
assert attr in res.text

View file

@ -1,17 +1,17 @@
def test_no_logged_no_access(testclient):
testclient.get("/token", status=403)
testclient.get("/admin/token", status=403)
def test_no_admin_no_access(testclient, logged_user):
testclient.get("/token", status=403)
testclient.get("/admin/token", status=403)
def test_token_list(testclient, token, logged_admin):
res = testclient.get("/token")
res = testclient.get("/admin/token")
assert token.oauthAccessToken in res.text
def test_token_view(testclient, token, logged_admin):
res = testclient.get("/token/" + token.oauthAccessToken)
res = testclient.get("/admin/token/" + token.oauthAccessToken)
for attr in token.may + token.must:
assert attr in res.text

View file

@ -1,11 +1,15 @@
import ldap
import os
import toml
from . import routes, clients, oauth, tokens, authorizations
from flask import Flask, g, request, render_template
from flask_babel import Babel
import web.tokens
import web.admin.tokens
import web.admin.authorizations
import web.admin.clients
import web.routes
import web.oauth
from .flaskutils import current_user
from .ldaputils import LDAPObjectHelper
from .oauth2utils import config_oauth
@ -35,11 +39,14 @@ def setup_app(app):
app.url_map.strict_slashes = False
config_oauth(app)
app.register_blueprint(routes.bp)
app.register_blueprint(oauth.bp, url_prefix="/oauth")
app.register_blueprint(clients.bp, url_prefix="/client")
app.register_blueprint(tokens.bp, url_prefix="/token")
app.register_blueprint(authorizations.bp, url_prefix="/authorization")
app.register_blueprint(web.routes.bp)
app.register_blueprint(web.oauth.bp, url_prefix="/oauth")
app.register_blueprint(web.tokens.bp, url_prefix="/token")
app.register_blueprint(web.admin.tokens.bp, url_prefix="/admin/token")
app.register_blueprint(
web.admin.authorizations.bp, url_prefix="/admin/authorization"
)
app.register_blueprint(admin.clients.bp, url_prefix="/admin/client")
babel = Babel(app)

0
web/admin/__init__.py Normal file
View file

View file

@ -1,6 +1,6 @@
from flask import Blueprint, render_template
from .models import AuthorizationCode
from .flaskutils import admin_needed
from web.models import AuthorizationCode
from web.flaskutils import admin_needed
bp = Blueprint(__name__, "authorizations")
@ -10,11 +10,11 @@ bp = Blueprint(__name__, "authorizations")
@admin_needed()
def index():
authorizations = AuthorizationCode.filter()
return render_template("authorization_list.html", authorizations=authorizations)
return render_template("admin/authorization_list.html", authorizations=authorizations)
@bp.route("/<authorization_id>", methods=["GET", "POST"])
@admin_needed()
def view(authorization_id):
authorization = AuthorizationCode.get(authorization_id)
return render_template("authorization_view.html", authorization=authorization)
return render_template("admin/authorization_view.html", authorization=authorization)

View file

@ -5,8 +5,8 @@ from flask import Blueprint, render_template, request, flash, redirect, url_for
from flask_wtf import FlaskForm
from flask_babel import gettext
from werkzeug.security import gen_salt
from .models import Client
from .flaskutils import admin_needed
from web.models import Client
from web.flaskutils import admin_needed
bp = Blueprint(__name__, "clients")
@ -16,7 +16,7 @@ bp = Blueprint(__name__, "clients")
@admin_needed()
def index():
clients = Client.filter()
return render_template("client_list.html", clients=clients)
return render_template("admin/client_list.html", clients=clients)
class ClientAdd(FlaskForm):
@ -117,14 +117,14 @@ def add():
form = ClientAdd(request.form or None)
if not request.form:
return render_template("client_add.html", form=form)
return render_template("admin/client_add.html", form=form)
if not form.validate():
flash(
gettext("The client has not been added. Please check your information."),
"error",
)
return render_template("client_add.html", form=form)
return render_template("admin/client_add.html", form=form)
client_id = gen_salt(24)
client_id_issued_at = datetime.datetime.now().strftime("%Y%m%d%H%M%SZ")
@ -155,7 +155,7 @@ def add():
gettext("The client has been created."), "success",
)
return redirect(url_for("web.clients.edit", client_id=client_id))
return redirect(url_for("web.admin.clients.edit", client_id=client_id))
@bp.route("/edit/<client_id>", methods=["GET", "POST"])
@ -168,7 +168,7 @@ def edit(client_id):
form = ClientAdd(request.form or None, data=data, client=client)
if not request.form:
return render_template("client_edit.html", form=form, client=client)
return render_template("admin/client_edit.html", form=form, client=client)
if not form.validate():
flash(
@ -199,4 +199,4 @@ def edit(client_id):
gettext("The client has been edited."), "success",
)
return render_template("client_edit.html", form=form, client=client)
return render_template("admin/client_edit.html", form=form, client=client)

20
web/admin/tokens.py Normal file
View file

@ -0,0 +1,20 @@
from flask import Blueprint, render_template
from web.models import Token
from web.flaskutils import admin_needed
bp = Blueprint(__name__, "tokens")
@bp.route("/")
@admin_needed()
def index():
tokens = Token.filter()
return render_template("admin/token_list.html", tokens=tokens)
@bp.route("/<token_id>", methods=["GET", "POST"])
@admin_needed()
def view(token_id):
token = Token.get(token_id)
return render_template("admin/token_view.html", token=token)

View file

@ -1,4 +1,4 @@
from flask import Blueprint, request, session, flash, url_for
from flask import Blueprint, request, flash, url_for
from flask import render_template, redirect, jsonify
from flask_babel import gettext

View file

@ -22,8 +22,8 @@
</thead>
{% for authorization in authorizations %}
<tr>
<td><a href="{{ url_for('web.authorizations.view', authorization_id=authorization.oauthCode) }}">{{ authorization.oauthCode }}</a></td>
<td><a href="{{ url_for('web.clients.edit', client_id=authorization.oauthClientID) }}">{{ authorization.oauthClientID }}</a></td>
<td><a href="{{ url_for('web.admin.authorizations.view', authorization_id=authorization.oauthCode) }}">{{ authorization.oauthCode }}</a></td>
<td><a href="{{ url_for('web.admin.clients.edit', client_id=authorization.oauthClientID) }}">{{ authorization.oauthClientID }}</a></td>
<td>{{ authorization.oauthSubject }}</td>
<td>{{ authorization.issue_date }}</td>
</tr>

View file

@ -14,7 +14,7 @@
{% block content %}
<div class="ui segment">
<a class="ui primary button" href="{{ url_for('web.clients.add') }}">{% trans %}Add client{% endtrans %}</a>
<a class="ui primary button" href="{{ url_for('web.admin.clients.add') }}">{% trans %}Add client{% endtrans %}</a>
</div>
<table class="ui table">
@ -25,7 +25,7 @@
</thead>
{% for client in clients %}
<tr>
<td><a href="{{ url_for('web.clients.edit', client_id=client.oauthClientID) }}">{{ client.oauthClientName }}</a></td>
<td><a href="{{ url_for('web.admin.clients.edit', client_id=client.oauthClientID) }}">{{ client.oauthClientName }}</a></td>
<td><a href="{{ client.oauthClientURI }}">{{ client.oauthClientURI }}</a></td>
<td>{{ client.issue_date }}</td>
</tr>

View file

@ -0,0 +1,33 @@
{% extends 'base.html' %}
{% block style %}
<link href="/static/datatables/jquery.dataTables.min.css" rel="stylesheet">
<link href="/static/datatables/dataTables.semanticui.min.css" rel="stylesheet">
{% endblock %}
{% block script %}
<script src="/static/datatables/jquery.dataTables.min.js"></script>
<script src="/static/datatables/dataTables.semanticui.min.js"></script>
<script src="/static/js/users.js"></script>
{% endblock %}
{% block content %}
<table class="ui table">
<thead>
<th>{% trans %}Token{% endtrans %}</th>
<th>{% trans %}Client{% endtrans %}</th>
<th>{% trans %}Subject{% endtrans %}</th>
<th>{% trans %}Created{% endtrans %}</th>
</thead>
{% for token in tokens %}
<tr>
<td><a href="{{ url_for('web.admin.tokens.view', token_id=token.oauthAccessToken) }}">{{ token.oauthAccessToken }}</a></td>
<td><a href="{{ url_for('web.admin.clients.edit', client_id=token.oauthClientID) }}">{{ token.oauthClientID }}</a></td>
<td>{{ token.oauthSubject }}</td>
<td>{{ token.issue_date }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}

View file

@ -7,9 +7,7 @@
<title>{% block title %}{% trans %}OpenID Connect LDAP Bridge{% endtrans %}{% endblock %}</title>
<link href="/static/fomanticui/semantic.min.css" rel="stylesheet">
<link href="/static/css/base.css" rel="stylesheet">
{% if logo_url %}
<link rel="icon" href="{{ logo_url }}">
{% endif %}
{% if logo_url %}<link rel="icon" href="{{ logo_url }}">{% endif %}
{% block style %}{% endblock %}
<!--[if lt IE 9]>
@ -32,19 +30,29 @@
</a>
</div>
{% endif %}
<a class="item" href="{{ url_for('web.tokens.tokens') }}">
<i class="key icon"></i>
{% trans %}My accesses{% endtrans %}
</a>
{% if user.admin %}
<a class="item" href="{{ url_for('web.clients.index') }}">
<div class="ui dropdown item">
<i class="settings icon"></i>
Admin
<div class="menu">
<a class="item" href="{{ url_for('web.admin.clients.index') }}">
<i class="plug icon"></i>
{% trans %}Clients{% endtrans %}
</a>
<a class="item" href="{{ url_for('web.tokens.index') }}">
<a class="item" href="{{ url_for('web.admin.tokens.index') }}">
<i class="key icon"></i>
{% trans %}Tokens{% endtrans %}
</a>
<a class="item" href="{{ url_for('web.authorizations.index') }}">
<a class="item" href="{{ url_for('web.admin.authorizations.index') }}">
<i class="user secret icon"></i>
{% trans %}Codes{% endtrans %}
</a>
</div>
</div>
{% endif %}
<a class="item" href="{{ url_for('web.routes.logout') }}">
<i class="sign out alternate icon"></i>

View file

@ -22,8 +22,8 @@
</thead>
{% for token in tokens %}
<tr>
<td><a href="{{ url_for('web.tokens.view', token_id=token.oauthAccessToken) }}">{{ token.oauthAccessToken }}</a></td>
<td><a href="{{ url_for('web.clients.edit', client_id=token.oauthClientID) }}">{{ token.oauthClientID }}</a></td>
<td><a href="{{ url_for('web.admin.tokens.view', token_id=token.oauthAccessToken) }}">{{ token.oauthAccessToken }}</a></td>
<td><a href="{{ url_for('web.admin.clients.edit', client_id=token.oauthClientID) }}">{{ token.oauthClientID }}</a></td>
<td>{{ token.oauthSubject }}</td>
<td>{{ token.issue_date }}</td>
</tr>

View file

@ -1,20 +1,11 @@
from flask import Blueprint, render_template
from .models import Token
from .flaskutils import admin_needed
from web.models import Token
bp = Blueprint(__name__, "tokens")
@bp.route("/")
@admin_needed()
def index():
def tokens():
tokens = Token.filter()
return render_template("token_list.html", tokens=tokens)
@bp.route("/<token_id>", methods=["GET", "POST"])
@admin_needed()
def view(token_id):
token = Token.get(token_id)
return render_template("token_view.html", token=token)