diff --git a/uffd/selfservice/templates/forgot_password.html b/uffd/selfservice/templates/forgot_password.html index 673eec16e1f368c895b5c798af94b8290cc00bcf..835b41bfc531d08c021b7c45d45578b94ebe8b2b 100644 --- a/uffd/selfservice/templates/forgot_password.html +++ b/uffd/selfservice/templates/forgot_password.html @@ -11,11 +11,11 @@ <h2 class="text-center">Forgot password</h2> </div> <div class="form-group col-12"> - <label for="user-loginname">login name</label> + <label for="user-loginname">Login Name</label> <input type="text" class="form-control" id="user-loginname" name="loginname" required="required" tabindex = "1"> </div> <div class="form-group col-12"> - <label for="user-mail">mail address</label> + <label for="user-mail">Mail Address</label> <input type="text" class="form-control" id="user-mail" name="mail" required="required" tabindex = "2"> </div> <div class="form-group col-12"> diff --git a/uffd/selfservice/templates/mailverification.mail.txt b/uffd/selfservice/templates/mailverification.mail.txt index 24a5b5d8b21f9a980aa7ee361d6efd7bc44d6c14..9718bba68ca4e0a4bca1aad226d8360287ca08e6 100644 --- a/uffd/selfservice/templates/mailverification.mail.txt +++ b/uffd/selfservice/templates/mailverification.mail.txt @@ -1,10 +1,8 @@ Hi {{ user.displayname }}, you have requested to change your mail address. -To do so, visit this url: {{ url_for('selfservice.self_token_mail', token=token, _external=True) }} +To confirm the change, please 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. - Kind regards, uffd diff --git a/uffd/selfservice/templates/self.html b/uffd/selfservice/templates/self.html index aadc2e96754ff960d8fae61fe622bd3d675648ed..0924117438a4915af0c753966d7312b08d84487c 100644 --- a/uffd/selfservice/templates/self.html +++ b/uffd/selfservice/templates/self.html @@ -1,37 +1,39 @@ {% extends 'base.html' %} {% block body %} -<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' : '')"> +<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 || password1.value.length == 0) ? 'Password is too short' : '') "> <div class="align-self-center row"> <div class="form-group col-md-6"> - <label for="user-uid">uid</label> + <label for="user-uid">Uid</label> <input type="number" class="form-control" id="user-uid" name="uid" value="{{ user.uid }}" readonly> </div> <div class="form-group col-md-6"> - <label for="user-loginname">login name</label> + <label for="user-loginname">Login Name</label> <input type="text" class="form-control" id="user-loginname" name="loginname" value="{{ user.loginname }}" readonly> </div> <div class="form-group col-md-6"> - <label for="user-displayname">display name</label> + <label for="user-displayname">Display Name</label> <input type="text" class="form-control" id="user-displayname" name="displayname" value="{{ user.displayname }}"> </div> <div class="form-group col-md-6"> - <label for="user-mail">mail</label> + <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"> + We will sent you a confirmation mail to set a new mail address. </small> </div> <div class="form-group col-md-6"> - <label for="user-password1">password</label> - <input type="password" class="form-control" id="user-password1" name="password1" placeholder="do not change"> + <label for="user-password1">Password</label> + <input type="password" class="form-control" id="user-password1" name="password1" placeholder="â—â—â—â—â—â—â—â—"> <small class="form-text text-muted"> At least 8 characters, no other special requirements. But please don't be stupid and use a password manager. </small> </div> <div class="form-group col-md-6"> - <label for="user-password2">password repeat</label> - <input type="password" class="form-control" id="user-password2" name="password2" placeholder="do not change"> + <label for="user-password2">Password Repeat</label> + <input type="password" class="form-control" id="user-password2" name="password2" placeholder="â—â—â—â—â—â—â—â—"> </div> <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> diff --git a/uffd/selfservice/templates/set_password.html b/uffd/selfservice/templates/set_password.html index 990a542f2752b7105c20254f20d1006e3934ba02..ca6a764d2cfe1c3705a1c4c7bda0fd0f7b99601a 100644 --- a/uffd/selfservice/templates/set_password.html +++ b/uffd/selfservice/templates/set_password.html @@ -11,15 +11,14 @@ <h2 class="text-center">Reset password</h2> </div> <div class="form-group col-12"> - <label for="user-loginname">login name</label> - <input type="text" class="form-control" id="user-loginname" name="loginname" required="required" tabindex = "1"> - </div> - <div class="form-group col-12"> - <label for="user-password1">new password</label> + <label for="user-password1">New Password</label> <input type="password" class="form-control" id="user-password1" name="password1" required="required" tabindex = "2"> + <small class="form-text text-muted"> + At least 8 characters, no other special requirements. But please don't be stupid and use a password manager. + </small> </div> <div class="form-group col-12"> - <label for="user-password2">new password again</label> + <label for="user-password2">Repeat Password</label> <input type="password" class="form-control" id="user-password2" name="password2" required="required" tabindex = "2"> </div> <div class="form-group col-12"> diff --git a/uffd/selfservice/views.py b/uffd/selfservice/views.py index 6ace04dd40f49368702e5016dc8ac28e0497c958..c8be89e5a9e1a116a1988cbd08e98675a91cd6e9 100644 --- a/uffd/selfservice/views.py +++ b/uffd/selfservice/views.py @@ -2,6 +2,7 @@ import datetime import smtplib from email.message import EmailMessage +import email.utils from flask import Blueprint, render_template, request, url_for, redirect, flash, current_app @@ -68,19 +69,18 @@ def self_token_password(token): session.delete(dbtoken) session.commit() return redirect(url_for('session.login')) - if not 'loginname' in request.values: - flash('Please set a new password.') + if request.method == 'GET': return render_template('set_password.html', token=token) - if not request.values['loginname'] == dbtoken.loginname: - flash('That is not the correct login name for this token. Your token is now invalide. Please start the password reset process again') - session.delete(dbtoken) - session.commit() - return redirect(url_for('session.login')) if not request.values['password1']: - flash('Please specify a new password.') + flash('You need to set a password, please try again.') + return render_template('set_password.html', token=token) + if not request.values['password1'] == request.values['password2']: + flash('Passwords do not match, please try again.') return render_template('set_password.html', token=token) user = User.from_ldap_dn(loginname_to_dn(dbtoken.loginname)) - user.set_password(request.values['password1']) + if not user.set_password(request.values['password1']): + flash('Password ist not valid, please try again.') + return render_template('set_password.html', token=token) user.to_ldap() flash('New password set') session.delete(dbtoken) @@ -149,5 +149,7 @@ def send_mail(to_address, msg): server.login(current_app.config['MAIL_USERNAME'], current_app.config['MAIL_PASSWORD']) msg['From'] = current_app.config['MAIL_FROM_ADDRESS'] msg['To'] = to_address + msg['Date'] = email.utils.formatdate(localtime = 1) + msg['Message-ID'] = email.utils.make_msgid() server.send_message(msg) server.quit() diff --git a/uffd/session/templates/login.html b/uffd/session/templates/login.html index 4ca476e2161f191d0927a4ea0600b99e64a2ddb6..501d7eeb1a8ec85ed4b8847fac7758e644d395d2 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") }}" method="POST"> +<form action="{{ url_for(".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"> @@ -11,11 +11,11 @@ <h2 class="text-center">Login</h2> </div> <div class="form-group col-12"> - <label for="user-loginname">login name</label> + <label for="user-loginname">Login Name</label> <input type="text" class="form-control" id="user-loginname" name="loginname" required="required" tabindex = "1"> </div> <div class="form-group col-12"> - <label for="user-password1">password</label> + <label for="user-password1">Password</label> <input type="password" class="form-control" id="user-password1" name="password" required="required" tabindex = "2"> </div> <div class="form-group col-12"> diff --git a/uffd/session/views.py b/uffd/session/views.py index ba20dc748d227c26e3edc2bb4c5ce374301cbbd6..5cb275bbc412e93192e2e3477f4c2cdda5e591d0 100644 --- a/uffd/session/views.py +++ b/uffd/session/views.py @@ -17,7 +17,7 @@ def logout(): @bp.route("/login", methods=('GET', 'POST')) def login(): if request.method == 'GET': - return render_template('login.html') + return render_template('login.html', ref=request.values.get('ref')) username = request.form['loginname'] password = request.form['password'] @@ -28,11 +28,11 @@ def login(): conn.search(conn.user, '(objectClass=person)') if not len(conn.entries) == 1: flash('Login name or password is wrong') - return redirect(url_for('.login')) + return render_template('login.html', ref=request.values.get('ref')) user = User.from_ldap(conn.entries[0]) if not user.is_in_group(current_app.config['ACL_SELFSERVICE_GROUP']): flash('You do not have access to this service') - return redirect(url_for('.login')) + return render_template('login.html', ref=request.values.get('ref')) session['user_uid'] = user.uid session['logintime'] = datetime.datetime.now().timestamp() session['_csrf_token'] = secrets.token_hex(128) diff --git a/uffd/user/templates/user.html b/uffd/user/templates/user.html index c1f8855dc4a29cf0bd00fd56ee7576570634d13a..30ba64353dde33d09b62aec7d06539c422d24b6d 100644 --- a/uffd/user/templates/user.html +++ b/uffd/user/templates/user.html @@ -12,30 +12,30 @@ {% endif %} </div> <div class="form-group col"> - <label for="user-loginname">login name</label> + <label for="user-loginname">Login Name</label> <input type="text" class="form-control" id="user-loginname" name="loginname" value="{{ user.loginname }}" {% if user.uid %}readonly{% endif %}> <small class="form-text text-muted"> Only letters, numbers and underscore ("_") are allowed. At most 32, at least 2 characters. There is a word blacklist. Musst be unique. </small> </div> <div class="form-group col"> - <label for="user-loginname">display name</label> + <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"> 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> + <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"> - <label for="user-loginname">password</label> + <label for="user-loginname">Password</label> {% if user.uid %} - <input type="password" class="form-control" id="user-password" name="password" placeholder="do not change"> + <input type="password" class="form-control" id="user-password" name="password" placeholder="â—â—â—â—â—â—â—â—"> {% else %} <input type="password" class="form-control" id="user-password" name="password" placeholder="mail to set it will be sent" readonly> {% endif %} @@ -95,7 +95,7 @@ {% 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> + <a href="{{ url_for(".user_list") }}" 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> {% else %} diff --git a/uffd/user/templates/user_list.html b/uffd/user/templates/user_list.html index e897ebb0c5c52435dd88d39a626803b0da955c76..c1683da2b2b385804946607c33afc416e845f6e1 100644 --- a/uffd/user/templates/user_list.html +++ b/uffd/user/templates/user_list.html @@ -37,9 +37,6 @@ <a href="{{ url_for(".user_show", uid=user.uid) }}" class="btn btn-primary"> <i class="fa fa-edit" aria-hidden="true"></i> Edit </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> </p> </td> </tr> diff --git a/uffd/user/views.py b/uffd/user/views.py index 067807ca5d5684a862c9a48c74725cc9b384bf3f..cf6ff18e4b9fce4636505afdb1ff07287c5256f9 100644 --- a/uffd/user/views.py +++ b/uffd/user/views.py @@ -53,16 +53,18 @@ def user_update(uid=False): user = User() if not user.set_loginname(request.form['loginname']): flash('Login name does not meet requirements') - return 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 user = User.from_ldap(conn.entries[0]) - user.mail = request.form['mail'] + if not user.set_mail(request.form['mail']): + flash('Mail is invalide.') + return redirect(url_for('.user_show')) 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') + return redirect(url_for('.user_show')) new_password = request.form.get('password') if new_password and not is_newuser: user.set_password(new_password)