feat(usermanager): implement user update form
This commit is contained in:
parent
001e80977e
commit
cd7233f566
@ -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 %}
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user