From 5decd18747e1f7964f3cb6f32756cffb0b232b85 Mon Sep 17 00:00:00 2001 From: nd <git@notandy.de> Date: Sat, 18 Jul 2020 12:35:27 +0200 Subject: [PATCH] more consistent view nameing in blueprints --- uffd/__init__.py | 2 +- .../templates/forgot_password.html | 2 +- .../templates/mailverification.mail.txt | 2 +- uffd/selfservice/templates/self.html | 2 +- uffd/selfservice/templates/set_password.html | 2 +- uffd/selfservice/views.py | 16 ++--- uffd/session/templates/login.html | 4 +- uffd/user/__init__.py | 4 +- uffd/user/templates/group.html | 4 +- uffd/user/templates/group_list.html | 2 +- uffd/user/templates/user.html | 8 +-- uffd/user/templates/user_list.html | 6 +- uffd/user/views_group.py | 36 ++++++++++ uffd/user/{views.py => views_user.py} | 66 ++++++------------- 14 files changed, 84 insertions(+), 72 deletions(-) create mode 100644 uffd/user/views_group.py rename uffd/user/{views.py => views_user.py} (60%) diff --git a/uffd/__init__.py b/uffd/__init__.py index 43ab85f6..c14c1bd8 100644 --- a/uffd/__init__.py +++ b/uffd/__init__.py @@ -47,7 +47,7 @@ def create_app(test_config=None): @app.route("/") def index(): #pylint: disable=unused-variable - return redirect(url_for('selfservice.self_index')) + return redirect(url_for('selfservice.index')) return app diff --git a/uffd/selfservice/templates/forgot_password.html b/uffd/selfservice/templates/forgot_password.html index 835b41bf..641f7dcb 100644 --- a/uffd/selfservice/templates/forgot_password.html +++ b/uffd/selfservice/templates/forgot_password.html @@ -1,7 +1,7 @@ {% extends 'base.html' %} {% block body %} -<form action="{{ url_for(".self_forgot_password") }}" method="POST"> +<form action="{{ url_for("selfservice.forgot_password") }}" method="POST"> <div class="row mt-2 justify-content-center"> <div class="col-lg-6 col-md-10" style="background: #f7f7f7; box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); padding: 30px;"> <div class="text-center"> diff --git a/uffd/selfservice/templates/mailverification.mail.txt b/uffd/selfservice/templates/mailverification.mail.txt index 9718bba6..bd9a0b58 100644 --- a/uffd/selfservice/templates/mailverification.mail.txt +++ b/uffd/selfservice/templates/mailverification.mail.txt @@ -1,7 +1,7 @@ Hi {{ user.displayname }}, you have requested to change your mail address. -To confirm the change, please visit this URL: {{ url_for('selfservice.self_token_mail', token=token, _external=True) }} +To confirm the change, please visit this URL: {{ url_for('selfservice.token_mail', token=token, _external=True) }} **Please note this link is only valid for 48h** Kind regards, diff --git a/uffd/selfservice/templates/self.html b/uffd/selfservice/templates/self.html index 09241174..c5d4695e 100644 --- a/uffd/selfservice/templates/self.html +++ b/uffd/selfservice/templates/self.html @@ -1,7 +1,7 @@ {% extends 'base.html' %} {% block body %} -<form action="{{ url_for(".self_update") }}" method="POST" onInput=" +<form action="{{ url_for("selfservice.update") }}" method="POST" onInput=" password2.setCustomValidity(password1.value != password2.value ? 'Passwords do not match.' : ''); password1.setCustomValidity((password1.value.length < 8 || password1.value.length == 0) ? 'Password is too short' : '') "> <div class="align-self-center row"> diff --git a/uffd/selfservice/templates/set_password.html b/uffd/selfservice/templates/set_password.html index ca6a764d..a60cfe0d 100644 --- a/uffd/selfservice/templates/set_password.html +++ b/uffd/selfservice/templates/set_password.html @@ -1,7 +1,7 @@ {% extends 'base.html' %} {% block body %} -<form action="{{ url_for(".self_token_password", token=token) }}" method="POST" onInput="password2.setCustomValidity(password1.value != password2.value ? 'Passwords do not match.' : '') "> +<form action="{{ url_for("selfservice.token_password", token=token) }}" method="POST" onInput="password2.setCustomValidity(password1.value != password2.value ? 'Passwords do not match.' : '') "> <div class="row mt-2 justify-content-center"> <div class="col-lg-6 col-md-10" style="background: #f7f7f7; box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); padding: 30px;"> <div class="text-center"> diff --git a/uffd/selfservice/views.py b/uffd/selfservice/views.py index 64233e8a..73980178 100644 --- a/uffd/selfservice/views.py +++ b/uffd/selfservice/views.py @@ -19,13 +19,13 @@ bp = Blueprint("selfservice", __name__, template_folder='templates', url_prefix= @bp.route("/") @register_navbar('Selfservice', icon='portrait', blueprint=bp, visible=is_valid_session) @login_required() -def self_index(): +def index(): return render_template('self.html', user=get_current_user()) @bp.route("/update", methods=(['POST'])) @csrf_protect(blueprint=bp) @login_required() -def self_update(): +def update(): user = get_current_user() if request.values['displayname'] != user.displayname: if user.set_displayname(request.values['displayname']): @@ -44,10 +44,10 @@ def self_update(): send_mail_verification(user.loginname, request.values['mail']) flash('We sent you an email, please verify your mail address.') user.to_ldap() - return redirect(url_for('.self_index')) + return redirect(url_for('selfservice.index')) @bp.route("/passwordreset", methods=(['GET', 'POST'])) -def self_forgot_password(): +def forgot_password(): if request.method == 'GET': return render_template('forgot_password.html') @@ -60,7 +60,7 @@ def self_forgot_password(): return redirect(url_for('session.login')) @bp.route("/token/password/<token>", methods=(['POST', 'GET'])) -def self_token_password(token): +def token_password(token): session = db.session dbtoken = PasswordToken.query.get(token) if not dbtoken or dbtoken.created < (datetime.datetime.now() - datetime.timedelta(days=2)): @@ -89,7 +89,7 @@ def self_token_password(token): @bp.route("/token/mail_verification/<token>") @login_required() -def self_token_mail(token): +def token_mail(token): session = db.session dbtoken = MailToken.query.get(token) if not dbtoken or dbtoken.created < (datetime.datetime.now() - datetime.timedelta(days=2)): @@ -97,7 +97,7 @@ def self_token_mail(token): if dbtoken: session.delete(dbtoken) session.commit() - return redirect(url_for('.self_index')) + return redirect(url_for('selfservice.index')) user = User.from_ldap_dn(loginname_to_dn(dbtoken.loginname)) user.set_mail(dbtoken.newmail) @@ -105,7 +105,7 @@ def self_token_mail(token): flash('New mail set') session.delete(dbtoken) session.commit() - return redirect(url_for('.self_index')) + return redirect(url_for('selfservice.index')) def send_mail_verification(loginname, newmail): session = db.session diff --git a/uffd/session/templates/login.html b/uffd/session/templates/login.html index 501d7eeb..9dfd5ae6 100644 --- a/uffd/session/templates/login.html +++ b/uffd/session/templates/login.html @@ -1,7 +1,7 @@ {% extends 'base.html' %} {% block body %} -<form action="{{ url_for(".login", ref=ref) }}" method="POST"> +<form action="{{ url_for("session.login", ref=ref) }}" method="POST"> <div class="row mt-2 justify-content-center"> <div class="col-lg-6 col-md-10" style="background: #f7f7f7; box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); padding: 30px;"> <div class="text-center"> @@ -23,7 +23,7 @@ </div> <div class="clearfix col-12"> <a href="#" class="float-left">Register</a> - <a href="{{ url_for("selfservice.self_forgot_password") }}" class="float-right">Forgot Password?</a> + <a href="{{ url_for("selfservice.forgot_password") }}" class="float-right">Forgot Password?</a> </div> </div> </div> diff --git a/uffd/user/__init__.py b/uffd/user/__init__.py index fc51d02b..130d312f 100644 --- a/uffd/user/__init__.py +++ b/uffd/user/__init__.py @@ -1,3 +1,5 @@ -from .views import bp_user, bp_group +from .views_user import bp as bp_user +from .views_group import bp as bp_group +from .models import User, Group bp = [bp_user, bp_group] diff --git a/uffd/user/templates/group.html b/uffd/user/templates/group.html index 4d9b4e1a..6ca116ea 100644 --- a/uffd/user/templates/group.html +++ b/uffd/user/templates/group.html @@ -1,7 +1,7 @@ {% extends 'base.html' %} {% block body %} -<form action="{{ url_for(".group_show", gid=group.gid) }}" method="POST"> +<form action="{{ url_for("group.show", gid=group.gid) }}" method="POST"> <div class="align-self-center"> <div class="form-group col"> <label for="group-gid">gid</label> @@ -15,7 +15,7 @@ <span>Members:</span> <ul class="list-group"> {% for member in group.get_members() %} - <li class="list-group-item"><a href="{{ url_for("user.user_show", uid=member.uid) }}">{{ member.loginname }}</a></li> + <li class="list-group-item"><a href="{{ url_for("user.show", uid=member.uid) }}">{{ member.loginname }}</a></li> {% endfor %} </ul> </div> diff --git a/uffd/user/templates/group_list.html b/uffd/user/templates/group_list.html index d6566d60..eca01e42 100644 --- a/uffd/user/templates/group_list.html +++ b/uffd/user/templates/group_list.html @@ -18,7 +18,7 @@ {{ group.gid }} </th> <td> - <a href="{{ url_for(".group_show", gid=group.gid) }}"> + <a href="{{ url_for("group.show", gid=group.gid) }}"> {{ group.name }} </a> </td> diff --git a/uffd/user/templates/user.html b/uffd/user/templates/user.html index 30ba6435..a2084400 100644 --- a/uffd/user/templates/user.html +++ b/uffd/user/templates/user.html @@ -1,7 +1,7 @@ {% extends 'base.html' %} {% block body %} -<form action="{{ url_for(".user_update", uid=user.uid) }}" method="POST"> +<form action="{{ url_for("user.update", uid=user.uid) }}" method="POST"> <div class="align-self-center"> <div class="form-group col"> <label for="user-uid">uid</label> @@ -71,7 +71,7 @@ <div class="card-body"> <ul class="list-group"> {% for group in user.get_groups() %} - <li class="list-group-item"><a href="{{ url_for("group.group_show", gid=group.gid) }}">{{ group.name }}</a></li> + <li class="list-group-item"><a href="{{ url_for("group.show", gid=group.gid) }}">{{ group.name }}</a></li> {% endfor %} </ul> </div> @@ -95,9 +95,9 @@ {% endif %} <div class="form-group col"> <button type="submit" class="btn btn-primary"><i class="fa fa-save" aria-hidden="true"></i> Save</button> - <a href="{{ url_for(".user_list") }}" class="btn btn-secondary">Cancel</a> + <a href="{{ url_for("user.index") }}" class="btn btn-secondary">Cancel</a> {% if user.uid %} - <a href="{{ url_for(".user_delete", uid=user.uid) }}" class="btn btn-danger"><i class="fa fa-trash" aria-hidden="true"></i> Delete</a> + <a href="{{ url_for("user.delete", uid=user.uid) }}" class="btn btn-danger"><i class="fa fa-trash" aria-hidden="true"></i> Delete</a> {% else %} <a href="#" class="btn btn-danger disabled"><i class="fa fa-trash" aria-hidden="true"></i> Delete</a> {% endif %} diff --git a/uffd/user/templates/user_list.html b/uffd/user/templates/user_list.html index c1683da2..bd5766fa 100644 --- a/uffd/user/templates/user_list.html +++ b/uffd/user/templates/user_list.html @@ -11,7 +11,7 @@ <th scope="col">display name</th> <th scope="col"> <p class="text-right"> - <a type="button" class="btn btn-primary" href="{{ url_for(".user_show") }}"> + <a type="button" class="btn btn-primary" href="{{ url_for("user.show") }}"> <i class="fa fa-plus" aria-hidden="true"></i> New </a> </p> @@ -25,7 +25,7 @@ {{ user.uid }} </th> <td> - <a href="{{ url_for(".user_show", uid=user.uid) }}"> + <a href="{{ url_for("user.show", uid=user.uid) }}"> {{ user.loginname }} </a> </td> @@ -34,7 +34,7 @@ </td> <td> <p class="text-right"> - <a href="{{ url_for(".user_show", uid=user.uid) }}" class="btn btn-primary"> + <a href="{{ url_for("user.show", uid=user.uid) }}" class="btn btn-primary"> <i class="fa fa-edit" aria-hidden="true"></i> Edit </a> </p> diff --git a/uffd/user/views_group.py b/uffd/user/views_group.py new file mode 100644 index 00000000..04351d41 --- /dev/null +++ b/uffd/user/views_group.py @@ -0,0 +1,36 @@ +from flask import Blueprint, render_template, url_for, redirect, flash, current_app + +from uffd.navbar import register_navbar +from uffd.ldap import get_conn, escape_filter_chars +from uffd.session import login_required, is_valid_session, get_current_user + +from .models import Group + +bp = Blueprint("group", __name__, template_folder='templates', url_prefix='/group/') +@bp.before_request +@login_required() +def group_acl(): #pylint: disable=inconsistent-return-statements + if not group_acl_check(): + flash('Access denied') + return redirect(url_for('index')) + +def group_acl_check(): + return is_valid_session() and get_current_user().is_in_group(current_app.config['ACL_ADMIN_GROUP']) + +@bp.route("/") +@register_navbar('Groups', icon='layer-group', blueprint=bp, visible=group_acl_check) +def index(): + conn = get_conn() + conn.search(current_app.config["LDAP_BASE_GROUPS"], '(objectclass=groupOfUniqueNames)') + groups = [] + for i in conn.entries: + groups.append(Group.from_ldap(i)) + return render_template('group_list.html', groups=groups) + +@bp.route("/<int:gid>") +def show(gid): + conn = get_conn() + conn.search(current_app.config["LDAP_BASE_GROUPS"], '(&(objectclass=groupOfUniqueNames)(gidNumber={}))'.format((escape_filter_chars(gid)))) + assert len(conn.entries) == 1 + group = Group.from_ldap(conn.entries[0]) + return render_template('group.html', group=group) diff --git a/uffd/user/views.py b/uffd/user/views_user.py similarity index 60% rename from uffd/user/views.py rename to uffd/user/views_user.py index cf6ff18e..08547f9b 100644 --- a/uffd/user/views.py +++ b/uffd/user/views_user.py @@ -6,10 +6,10 @@ from uffd.selfservice import send_passwordreset from uffd.ldap import get_conn, escape_filter_chars from uffd.session import login_required, is_valid_session, get_current_user -from .models import User, Group +from .models import User -bp_user = Blueprint("user", __name__, template_folder='templates', url_prefix='/user/') -@bp_user.before_request +bp = Blueprint("user", __name__, template_folder='templates', url_prefix='/user/') +@bp.before_request @login_required() def user_acl(): #pylint: disable=inconsistent-return-statements if not user_acl_check(): @@ -19,9 +19,9 @@ def user_acl(): #pylint: disable=inconsistent-return-statements def user_acl_check(): return is_valid_session() and get_current_user().is_in_group(current_app.config['ACL_ADMIN_GROUP']) -@bp_user.route("/") -@register_navbar('Users', icon='users', blueprint=bp_user, visible=user_acl_check) -def user_list(): +@bp.route("/") +@register_navbar('Users', icon='users', blueprint=bp, visible=user_acl_check) +def index(): conn = get_conn() conn.search(current_app.config["LDAP_BASE_USER"], '(objectclass=person)') users = [] @@ -29,9 +29,9 @@ def user_list(): users.append(User.from_ldap(i)) return render_template('user_list.html', users=users) -@bp_user.route("/<int:uid>") -@bp_user.route("/new") -def user_show(uid=None): +@bp.route("/<int:uid>") +@bp.route("/new") +def show(uid=None): if not uid: user = User() ldif = '<none yet>' @@ -43,17 +43,17 @@ def user_show(uid=None): ldif = conn.entries[0].entry_to_ldif() return render_template('user.html', user=user, user_ldif=ldif) -@bp_user.route("/<int:uid>/update", methods=['POST']) -@bp_user.route("/new", methods=['POST']) -@csrf_protect(blueprint=bp_user) -def user_update(uid=False): +@bp.route("/<int:uid>/update", methods=['POST']) +@bp.route("/new", methods=['POST']) +@csrf_protect(blueprint=bp) +def update(uid=False): conn = get_conn() is_newuser = bool(not uid) if is_newuser: user = User() if not user.set_loginname(request.form['loginname']): flash('Login name does not meet requirements') - return redirect(url_for('.user_show')) + return redirect(url_for('user.show')) else: conn.search(current_app.config["LDAP_BASE_USER"], '(&(objectclass=person)(uidNumber={}))'.format((escape_filter_chars(uid)))) assert len(conn.entries) == 1 @@ -64,7 +64,7 @@ def user_update(uid=False): new_displayname = request.form['displayname'] if request.form['displayname'] else request.form['loginname'] if not user.set_displayname(new_displayname): flash('Display name does not meet requirements') - return redirect(url_for('.user_show')) + return redirect(url_for('user.show')) new_password = request.form.get('password') if new_password and not is_newuser: user.set_password(new_password) @@ -76,11 +76,11 @@ def user_update(uid=False): flash('User updated') else: flash('Error updating user: {}'.format(conn.result['message'])) - return redirect(url_for('.user_list')) + return redirect(url_for('user.index')) -@bp_user.route("/<int:uid>/del") -@csrf_protect(blueprint=bp_user) -def user_delete(uid): +@bp.route("/<int:uid>/del") +@csrf_protect(blueprint=bp) +def delete(uid): conn = get_conn() conn.search(current_app.config["LDAP_BASE_USER"], '(&(objectclass=person)(uidNumber={}))'.format((escape_filter_chars(uid)))) assert len(conn.entries) == 1 @@ -88,30 +88,4 @@ def user_delete(uid): flash('Deleted user') else: flash('Could not delete user: {}'.format(conn.result['message'])) - return redirect(url_for('.user_list')) - -bp_group = Blueprint("group", __name__, template_folder='templates', url_prefix='/group/') -@bp_group.before_request -@login_required() -def group_acl(): #pylint: disable=inconsistent-return-statements - if not user_acl_check(): - flash('Access denied') - return redirect(url_for('index')) - -@bp_group.route("/") -@register_navbar('Groups', icon='layer-group', blueprint=bp_group, visible=user_acl_check) -def group_list(): - conn = get_conn() - conn.search(current_app.config["LDAP_BASE_GROUPS"], '(objectclass=groupOfUniqueNames)') - groups = [] - for i in conn.entries: - groups.append(Group.from_ldap(i)) - return render_template('group_list.html', groups=groups) - -@bp_group.route("/<int:gid>") -def group_show(gid): - conn = get_conn() - conn.search(current_app.config["LDAP_BASE_GROUPS"], '(&(objectclass=groupOfUniqueNames)(gidNumber={}))'.format((escape_filter_chars(gid)))) - assert len(conn.entries) == 1 - group = Group.from_ldap(conn.entries[0]) - return render_template('group.html', group=group) + return redirect(url_for('user.index')) -- GitLab