feat(usermanager): implement user update form

This commit is contained in:
Julian Lobbes 2022-11-17 19:07:56 +01:00
parent 001e80977e
commit cd7233f566
3 changed files with 74 additions and 24 deletions

View File

@ -27,6 +27,6 @@
{{ form.picture.label }}
{{ form.picture }}
<input type="submit" value="Update">
{{ form.submit }}
</form>
{% endblock content %}

View File

@ -9,11 +9,12 @@ from flask import (
from PIL import Image, UnidentifiedImageError
from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed
from wtforms import ValidationError, StringField, PasswordField
from wtforms import ValidationError, StringField, PasswordField, SubmitField
from wtforms.validators import InputRequired, Email, EqualTo
import lumi2.ldap as ldap
from lumi2.usermodel import User, Group
from lumi2.exceptions import InvalidStringFormatException, InvalidImageException
bp = Blueprint('usermanager', __name__)
@ -26,11 +27,31 @@ def index():
return render_template('usermanager/index.html')
class UserEditForm(FlaskForm):
class UserUpdateForm(FlaskForm):
@staticmethod
def validate_name(form, field) -> None:
if not User.is_valid_person_name(field.data):
raise ValidationError("Invalid name.")
try:
User.assert_is_valid_name(field.data)
except InvalidStringFormatException as e:
raise ValidationError from e
@staticmethod
def validate_password(form, field) -> None:
try:
User.assert_is_valid_password(field.data)
except InvalidStringFormatException as e:
raise ValidationError from e
@staticmethod
def validate_picture(form, field) -> None:
if field.data:
try:
with TemporaryDirectory() as temp_dir:
temp_file = Path(temp_dir) / "upload.jpg"
field.data.save(temp_file)
Image.open(temp_file, formats=['JPEG'])
except UnidentifiedImageError as e:
raise ValidationError from e
email = StringField(
'Email',
@ -50,7 +71,10 @@ class UserEditForm(FlaskForm):
)
password = PasswordField(
'Password',
[EqualTo('password_confirmation', message='Passwords must match')],
[
EqualTo('password_confirmation', message='Passwords must match'),
validate_password,
],
)
password_confirmation = PasswordField(
'Password (repeat)',
@ -59,11 +83,14 @@ class UserEditForm(FlaskForm):
'Picture',
[FileAllowed(['jpg', 'jpeg'], 'JPEG images only.')]
)
submit = SubmitField(
'Update',
)
@bp.route("/user/<string:username>", methods=("GET", "POST"))
def user_detail(username: str):
"""Detail view for a specific User."""
@bp.route("/user/update/<string:username>", methods=("GET", "POST"))
def user_update(username: str):
"""Update view for a specific User."""
try:
conn = ldap.get_connection()
@ -78,19 +105,41 @@ def user_detail(username: str):
user._generate_static_images()
# data = {
# "email": user.email,
# "first_name": user.first_name,
# "last_name": user.last_name,
# "display_name": user.display_name,
# }
if request.method == 'GET':
form = UserUpdateForm(obj=user)
else:
form = UserUpdateForm(request.form)
if form.validate():
if form.email.data:
user.email = form.email.data
print("Email updated.")
if form.first_name.data:
user.first_name = form.first_name.data
print("First Name updated.")
if form.last_name.data:
user.last_name = form.last_name.data
print("Last Name updated.")
if form.display_name.data:
user.display_name = form.display_name.data
print("Display Name updated.")
if form.password.data:
user.password_hash = User.generate_password_hash(form.password.data)
print("Password updated.")
picture_updated = False
if form.picture.data:
with TemporaryDirectory() as temp_dir:
temp_file = Path(temp_dir) / "upload.jpg"
form.picture.data.save(temp_file)
user.picture = Image.open(temp_file, formats=['JPEG'])
picture_updated = True
print("Picture updated.")
form = UserEditForm(obj=user)
if form.validate_on_submit():
conn.unbind()
# TODO update user
return redirect(request.url)
ldap.update_user(conn, user)
if picture_updated:
user._generate_static_images(force=True)
conn.unbind()
# TODO redirect to user detail view
return redirect(request.url)
conn.unbind()
return render_template('usermanager/user_detail.html', form=form, user=user)
return render_template('usermanager/user_update.html', form=form, user=user)

View File

@ -6,7 +6,8 @@ import hashlib
from binascii import Error as Base64DecodeError
from pathlib import Path
from PIL.Image import JpegImageFile, Image
from PIL.Image import Image
from PIL.JpegImagePlugin import JpegImageFile
from flask import current_app
from lumi2.exceptions import InvalidStringFormatException, InvalidImageException
@ -297,7 +298,7 @@ class User:
@staticmethod
def _get_default_picture() -> Image.Image:
def _get_default_picture() -> Image:
"""Returns the default user picture as a PIL Image object.
Returns