diff --git a/uffd/selfservice/__init__.py b/uffd/selfservice/__init__.py index 671578662f91c82cb987ffe679c1f102dc493d1f..69a1df974cdf718d8d51c2672d3d43611b3bbe03 100644 --- a/uffd/selfservice/__init__.py +++ b/uffd/selfservice/__init__.py @@ -1,3 +1,3 @@ -from .views import bp as bp_ui +from .views import bp as bp_ui, send_passwordreset bp = [bp_ui] diff --git a/uffd/selfservice/templates/mailverification.mail.txt b/uffd/selfservice/templates/mailverification.mail.txt index e9ff7e3134e0a3484098bf8c72bea4f4d6190fcc..24a5b5d8b21f9a980aa7ee361d6efd7bc44d6c14 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 do so, visit this url: {{ url_for('.self_token_mail', token=token, _external=True) }} +To do so, visit this url: {{ url_for('selfservice.self_token_mail', token=token, _external=True) }} **Please note this link is only valid for 48h** If you did not request a mail address change, you should change your password asap because somebody else logged in and requested this. diff --git a/uffd/selfservice/templates/passwordreset.mail.txt b/uffd/selfservice/templates/passwordreset.mail.txt index 9560ff86ed72d01120d5f160a1480a71648b77e6..2cc66e913b3a8c9851afe630ee17933f0a8b8226 100644 --- a/uffd/selfservice/templates/passwordreset.mail.txt +++ b/uffd/selfservice/templates/passwordreset.mail.txt @@ -1,7 +1,7 @@ Hi {{ user.displayname }}, you have requested a password reset. -To reset your password, visit this url: {{ url_for('.self_token_password', token=token, _external=True) }} +To reset your password, visit this url: {{ url_for('selfservice.self_token_password', token=token, _external=True) }} **Please note this link is only valid for 48h** If you did not request a password reset, you do not need to do anything. diff --git a/uffd/selfservice/templates/self.html b/uffd/selfservice/templates/self.html index 4f9756d0d724f636e90413e2589bd967fde2d809..aadc2e96754ff960d8fae61fe622bd3d675648ed 100644 --- a/uffd/selfservice/templates/self.html +++ b/uffd/selfservice/templates/self.html @@ -1,7 +1,8 @@ {% extends 'base.html' %} {% block body %} -<form action="{{ url_for(".self_update") }}" method="POST" onInput="password2.setCustomValidity(password1.value != password2.value ? 'Passwords do not match.' : '')"> +<form action="{{ url_for(".self_update") }}" method="POST" + onInput="password2.setCustomValidity(password1.value != password2.value ? 'Passwords do not match.' : ''); password1.setCustomValidity(password1.value.length < 8 ? 'Password is too short' : '')"> <div class="align-self-center row"> <div class="form-group col-md-6"> <label for="user-uid">uid</label> @@ -35,40 +36,6 @@ <div class="form-group col-md-12"> <button type="submit" class="btn btn-primary float-right"><i class="fa fa-save" aria-hidden="true"></i> Save</button> </div> - <div class="form-group col-md-12" "id="accordion"> - <div class="card"> - <div class="card-header" id="user-group"> - <h5 class="mb-0"> - <a class="btn btn-link collapsed" data-toggle="collapse" data-target="#user-group-body" aria-expanded="false" aria-controls="user-group"> - groups - </a> - </h5> - </div> - <div id="user-group-body" class="collapse" aria-labelledby="user-group" data-parent="#accordion"> - <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> - {% endfor %} - </ul> - </div> - </div> - </div> - <div class="card"> - <div class="card-header" id="user-role"> - <h5 class="mb-0"> - <a class="btn btn-link" data-toggle="collapse" data-target="#user-role-body" aria-expanded="true" aria-controls="user-role"> - roles - </a> - </h5> - </div> - <div id="user-role-body" class="collapse show" aria-labelledby="user-role" data-parent="#accordion"> - <div class="card-body"> - roles. - </div> - </div> - </div> - </div> </div> </form> {% endblock %} diff --git a/uffd/selfservice/views.py b/uffd/selfservice/views.py index 0ef6f8a0bd68ed29ccee388347bf0c35fa865691..6ace04dd40f49368702e5016dc8ac28e0497c958 100644 --- a/uffd/selfservice/views.py +++ b/uffd/selfservice/views.py @@ -46,7 +46,6 @@ def self_update(): return redirect(url_for('.self_index')) @bp.route("/passwordreset", methods=(['GET', 'POST'])) -@csrf_protect(blueprint=bp) def self_forgot_password(): if request.method == 'GET': return render_template('forgot_password.html') diff --git a/uffd/user/templates/user.html b/uffd/user/templates/user.html index 0fa6163c122f05658609168c1773d6f456ea939a..c1f8855dc4a29cf0bd00fd56ee7576570634d13a 100644 --- a/uffd/user/templates/user.html +++ b/uffd/user/templates/user.html @@ -22,13 +22,14 @@ <label for="user-loginname">display name</label> <input type="text" class="form-control" id="user-displayname" name="displayname" value="{{ user.displayname }}"> <small class="form-text text-muted"> - At most 128, at least 2 characters. No character restrictions. + If you leave this empty it will be set to the login name. At most 128, at least 2 characters. No character restrictions. </small> </div> <div class="form-group col"> <label for="user-mail">mail</label> <input type="email" class="form-control" id="user-mail" name="mail" value="{{ user.mail }}"> <small class="form-text text-muted"> + Do a sanity check here. A user can take over another account if both have the same mail address set. </small> </div> <div class="form-group col"> @@ -42,6 +43,7 @@ At least 8 characters, no other special requirements. But please don't be stupid and use a password manager. </small> </div> + {% if user.uid %} <div class="form-group col "id="accordion"> <div class="card"> <div class="card-header" id="user-ldif"> @@ -90,6 +92,7 @@ </div> </div> </div> + {% 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">Cancle</a> diff --git a/uffd/user/views.py b/uffd/user/views.py index 4906cdbbfae5bd6922703322e92f82b40e22019b..067807ca5d5684a862c9a48c74725cc9b384bf3f 100644 --- a/uffd/user/views.py +++ b/uffd/user/views.py @@ -2,6 +2,7 @@ from flask import Blueprint, render_template, request, url_for, redirect, flash, from uffd.navbar import register_navbar from uffd.csrf import csrf_protect +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 @@ -47,25 +48,30 @@ def user_show(uid=None): @csrf_protect(blueprint=bp_user) def user_update(uid=False): conn = get_conn() - if uid: - conn.search(current_app.config["LDAP_BASE_USER"], '(&(objectclass=person)(uidNumber={}))'.format((escape_filter_chars(uid)))) - assert len(conn.entries) == 1 - user = User.from_ldap(conn.entries[0]) - else: - # new user + 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 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 + user = User.from_ldap(conn.entries[0]) user.mail = request.form['mail'] - if not user.set_displayname(request.form['displayname']): + 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 url_for('.user_show') new_password = request.form.get('password') - if new_password: + if new_password and not is_newuser: user.set_password(new_password) - if user.to_ldap(new=(not uid)): - flash('User updated') + if user.to_ldap(new=is_newuser): + if is_newuser: + send_passwordreset(user.loginname) + flash('User created. We sent the user a password reset link by mail') + else: + flash('User updated') else: flash('Error updating user: {}'.format(conn.result['message'])) return redirect(url_for('.user_list'))