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.label }}
{{ form.picture }} {{ form.picture }}
<input type="submit" value="Update"> {{ form.submit }}
</form> </form>
{% endblock content %} {% endblock content %}

View File

@ -9,11 +9,12 @@ from flask import (
from PIL import Image, UnidentifiedImageError from PIL import Image, UnidentifiedImageError
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed 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 from wtforms.validators import InputRequired, Email, EqualTo
import lumi2.ldap as ldap import lumi2.ldap as ldap
from lumi2.usermodel import User, Group from lumi2.usermodel import User, Group
from lumi2.exceptions import InvalidStringFormatException, InvalidImageException
bp = Blueprint('usermanager', __name__) bp = Blueprint('usermanager', __name__)
@ -26,11 +27,31 @@ def index():
return render_template('usermanager/index.html') return render_template('usermanager/index.html')
class UserEditForm(FlaskForm): class UserUpdateForm(FlaskForm):
@staticmethod @staticmethod
def validate_name(form, field) -> None: def validate_name(form, field) -> None:
if not User.is_valid_person_name(field.data): try:
raise ValidationError("Invalid name.") 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 = StringField(
'Email', 'Email',
@ -50,7 +71,10 @@ class UserEditForm(FlaskForm):
) )
password = PasswordField( password = PasswordField(
'Password', 'Password',
[EqualTo('password_confirmation', message='Passwords must match')], [
EqualTo('password_confirmation', message='Passwords must match'),
validate_password,
],
) )
password_confirmation = PasswordField( password_confirmation = PasswordField(
'Password (repeat)', 'Password (repeat)',
@ -59,11 +83,14 @@ class UserEditForm(FlaskForm):
'Picture', 'Picture',
[FileAllowed(['jpg', 'jpeg'], 'JPEG images only.')] [FileAllowed(['jpg', 'jpeg'], 'JPEG images only.')]
) )
submit = SubmitField(
'Update',
)
@bp.route("/user/<string:username>", methods=("GET", "POST")) @bp.route("/user/update/<string:username>", methods=("GET", "POST"))
def user_detail(username: str): def user_update(username: str):
"""Detail view for a specific User.""" """Update view for a specific User."""
try: try:
conn = ldap.get_connection() conn = ldap.get_connection()
@ -78,19 +105,41 @@ def user_detail(username: str):
user._generate_static_images() user._generate_static_images()
# data = { if request.method == 'GET':
# "email": user.email, form = UserUpdateForm(obj=user)
# "first_name": user.first_name, else:
# "last_name": user.last_name, form = UserUpdateForm(request.form)
# "display_name": user.display_name, 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) ldap.update_user(conn, user)
if form.validate_on_submit(): if picture_updated:
conn.unbind() user._generate_static_images(force=True)
conn.unbind()
# TODO update user # TODO redirect to user detail view
return redirect(request.url) return redirect(request.url)
conn.unbind() 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 binascii import Error as Base64DecodeError
from pathlib import Path 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 flask import current_app
from lumi2.exceptions import InvalidStringFormatException, InvalidImageException from lumi2.exceptions import InvalidStringFormatException, InvalidImageException
@ -297,7 +298,7 @@ class User:
@staticmethod @staticmethod
def _get_default_picture() -> Image.Image: def _get_default_picture() -> Image:
"""Returns the default user picture as a PIL Image object. """Returns the default user picture as a PIL Image object.
Returns Returns