From 87798f47813f8ddeb9fe9154274810df986b56ba Mon Sep 17 00:00:00 2001 From: Patrick Jentsch <p.jentsch@uni-bielefeld.de> Date: Mon, 3 Apr 2023 16:34:03 +0200 Subject: [PATCH] completly move settings logic to users package --- app/admin/routes.py | 12 +-- app/settings/routes.py | 88 ++---------------- .../{ => users}/settings/settings.html.j2 | 0 app/users/settings/__init__.py | 2 +- app/{ => users}/settings/forms.py | 8 +- app/users/settings/json_routes.py | 20 ++-- app/users/settings/routes.py | 93 +++++++++++++++++++ 7 files changed, 124 insertions(+), 99 deletions(-) rename app/templates/{ => users}/settings/settings.html.j2 (100%) rename app/{ => users}/settings/forms.py (94%) create mode 100644 app/users/settings/routes.py diff --git a/app/admin/routes.py b/app/admin/routes.py index 3822dc28..67739edc 100644 --- a/app/admin/routes.py +++ b/app/admin/routes.py @@ -2,7 +2,7 @@ from flask import abort, flash, redirect, render_template, url_for from flask_breadcrumbs import register_breadcrumb from app import db, hashids from app.models import Avatar, Corpus, Role, User -from app.settings.forms import ( +from app.users.settings.forms import ( UpdateAvatarForm, UpdatePasswordForm, UpdateNotificationsForm, @@ -63,12 +63,12 @@ def user(user_id): @register_breadcrumb(bp, '.users.entity.settings', '<i class="material-icons left">settings</i>Settings') def user_settings(user_id): user = User.query.get_or_404(user_id) - update_account_information_form = UpdateAccountInformationForm(user=user) - update_profile_information_form = UpdateProfileInformationForm(user=user) + update_account_information_form = UpdateAccountInformationForm(user) + update_profile_information_form = UpdateProfileInformationForm(user) update_avatar_form = UpdateAvatarForm() - update_password_form = UpdatePasswordForm(user=user) - update_notifications_form = UpdateNotificationsForm(user=user) - update_user_form = UpdateUserForm(user=user) + update_password_form = UpdatePasswordForm(user) + update_notifications_form = UpdateNotificationsForm(user) + update_user_form = UpdateUserForm(user) # region handle update profile information form if update_profile_information_form.submit.data and update_profile_information_form.validate(): diff --git a/app/settings/routes.py b/app/settings/routes.py index 70b69d6c..9496e6fd 100644 --- a/app/settings/routes.py +++ b/app/settings/routes.py @@ -1,88 +1,14 @@ -from flask import abort, flash, redirect, render_template, url_for +from flask import url_for from flask_breadcrumbs import register_breadcrumb -from flask_login import current_user, login_required -from app import db -from app.models import Avatar +from flask_login import current_user +from app.users.settings.routes import settings as settings_route from . import bp -from .forms import ( - UpdateAvatarForm, - UpdatePasswordForm, - UpdateNotificationsForm, - UpdateAccountInformationForm, - UpdateProfileInformationForm -) -@bp.route('', methods=['GET', 'POST']) +@bp.route('/settings', methods=['GET', 'POST']) @register_breadcrumb(bp, '.', '<i class="material-icons left">settings</i>Settings') -@login_required def settings(): - user = current_user - update_account_information_form = UpdateAccountInformationForm() - update_profile_information_form = UpdateProfileInformationForm() - update_avatar_form = UpdateAvatarForm() - update_password_form = UpdatePasswordForm() - update_notifications_form = UpdateNotificationsForm() - - # region handle update profile information form - if update_profile_information_form.submit.data and update_profile_information_form.validate(): - user.about_me = update_profile_information_form.about_me.data - user.location = update_profile_information_form.location.data - user.organization = update_profile_information_form.organization.data - user.website = update_profile_information_form.website.data - user.full_name = update_profile_information_form.full_name.data - db.session.commit() - flash('Your changes have been saved') - return redirect(url_for('.settings')) - # endregion handle update profile information form - - # region handle update avatar form - if update_avatar_form.submit.data and update_avatar_form.validate(): - try: - Avatar.create( - update_avatar_form.avatar.data, - user=user - ) - except (AttributeError, OSError): - abort(500) - db.session.commit() - flash('Your changes have been saved') - return redirect(url_for('.settings')) - # endregion handle update avatar form - - # region handle update account information form - if update_account_information_form.submit.data and update_account_information_form.validate(): - user.email = update_account_information_form.email.data - user.username = update_account_information_form.username.data - db.session.commit() - flash('Profile settings updated') - return redirect(url_for('.settings')) - # endregion handle update account information form - - # region handle update password form - if update_password_form.submit.data and update_password_form.validate(): - user.password = update_password_form.new_password.data - db.session.commit() - flash('Your changes have been saved') - return redirect(url_for('.settings')) - # endregion handle update password form - - # region handle update notifications form - if update_notifications_form.submit.data and update_notifications_form.validate(): - user.setting_job_status_mail_notification_level = \ - update_notifications_form.job_status_mail_notification_level.data - db.session.commit() - flash('Your changes have been saved') - return redirect(url_for('.settings')) - # endregion handle update notifications form - - return render_template( - 'settings/settings.html.j2', - title='Settings', - update_account_information_form=update_account_information_form, - update_avatar_form=update_avatar_form, - update_notifications_form=update_notifications_form, - update_password_form=update_password_form, - update_profile_information_form=update_profile_information_form, - user=user + return settings_route( + current_user.id, + redirect_location_on_post=url_for('.settings') ) diff --git a/app/templates/settings/settings.html.j2 b/app/templates/users/settings/settings.html.j2 similarity index 100% rename from app/templates/settings/settings.html.j2 rename to app/templates/users/settings/settings.html.j2 diff --git a/app/users/settings/__init__.py b/app/users/settings/__init__.py index 1dbe44f0..e06bada9 100644 --- a/app/users/settings/__init__.py +++ b/app/users/settings/__init__.py @@ -1,2 +1,2 @@ from .. import bp -from . import json_routes +from . import json_routes, routes diff --git a/app/settings/forms.py b/app/users/settings/forms.py similarity index 94% rename from app/settings/forms.py rename to app/users/settings/forms.py index 77c8687c..71c29456 100644 --- a/app/settings/forms.py +++ b/app/users/settings/forms.py @@ -41,7 +41,7 @@ class UpdateAccountInformationForm(FlaskForm): ) submit = SubmitField() - def __init__(self, *args, user=current_user, **kwargs): + def __init__(self, user, *args, **kwargs): if 'data' not in kwargs: kwargs['data'] = user.to_json_serializeable() if 'prefix' not in kwargs: @@ -91,7 +91,7 @@ class UpdateProfileInformationForm(FlaskForm): ) submit = SubmitField() - def __init__(self, *args, user=current_user, **kwargs): + def __init__(self, user, *args, **kwargs): if 'data' not in kwargs: kwargs['data'] = user.to_json_serializeable() if 'prefix' not in kwargs: @@ -132,7 +132,7 @@ class UpdatePasswordForm(FlaskForm): ) submit = SubmitField() - def __init__(self, *args, user=current_user, **kwargs): + def __init__(self, user, *args, **kwargs): if 'prefix' not in kwargs: kwargs['prefix'] = 'update-password-form' super().__init__(*args, **kwargs) @@ -154,7 +154,7 @@ class UpdateNotificationsForm(FlaskForm): ) submit = SubmitField() - def __init__(self, *args, user=current_user, **kwargs): + def __init__(self, user, *args, **kwargs): if 'data' not in kwargs: kwargs['data'] = user.to_json_serializeable() if 'prefix' not in kwargs: diff --git a/app/users/settings/json_routes.py b/app/users/settings/json_routes.py index acc7dbc9..7fdfa7fc 100644 --- a/app/users/settings/json_routes.py +++ b/app/users/settings/json_routes.py @@ -1,5 +1,5 @@ from flask import abort, current_app, request -from flask_login import login_required +from flask_login import current_user, login_required from threading import Thread import os from app import db @@ -20,6 +20,8 @@ def delete_user_avatar(user_id): user = User.query.get_or_404(user_id) if user.avatar is None: abort(404) + if not (user == current_user or current_user.is_administrator()): + abort(403) thread = Thread( target=_delete_avatar, args=(current_app._get_current_object(), user.avatar.id) @@ -36,10 +38,12 @@ def delete_user_avatar(user_id): @content_negotiation(consumes='application/json', produces='application/json') def update_user_profile_privacy_setting_is_public(user_id): user = User.query.get_or_404(user_id) - is_public = request.json - if not isinstance(is_public, bool): + if not (user == current_user or current_user.is_administrator()): + abort(403) + enabled = request.json + if not isinstance(enabled, bool): abort(400) - user.is_public = is_public + user.is_public = enabled db.session.commit() response_data = { 'message': 'Profile privacy settings updated', @@ -53,13 +57,15 @@ def update_user_profile_privacy_setting_is_public(user_id): @content_negotiation(consumes='application/json', produces='application/json') def update_user_profile_privacy_settings(user_id, profile_privacy_setting_name): user = User.query.get_or_404(user_id) - enabled = request.json - if not isinstance(enabled, bool): - abort(400) try: profile_privacy_setting = ProfilePrivacySettings[profile_privacy_setting_name] except KeyError: abort(404) + if not (user == current_user or current_user.is_administrator()): + abort(403) + enabled = request.json + if not isinstance(enabled, bool): + abort(400) if enabled: user.add_profile_privacy_setting(profile_privacy_setting) else: diff --git a/app/users/settings/routes.py b/app/users/settings/routes.py new file mode 100644 index 00000000..f023bf00 --- /dev/null +++ b/app/users/settings/routes.py @@ -0,0 +1,93 @@ +from flask import abort, flash, redirect, render_template, url_for +from flask_breadcrumbs import register_breadcrumb +from flask_login import current_user, login_required +from app import db +from app.models import Avatar, User +from ..utils import user_endpoint_arguments_constructor as user_eac +from . import bp +from .forms import ( + UpdateAvatarForm, + UpdatePasswordForm, + UpdateNotificationsForm, + UpdateAccountInformationForm, + UpdateProfileInformationForm +) + + +@bp.route('/<hashid:user_id>/settings', methods=['GET', 'POST']) +@register_breadcrumb(bp, '.entity.settings', '<i class="material-icons left">settings</i>Settings', endpoint_arguments_constructor=user_eac) +@login_required +def settings(user_id, redirect_location_on_post=None): + user = User.query.get_or_404(user_id) + if not (user == current_user or current_user.is_administrator()): + abort(403) + if redirect_location_on_post is None: + redirect_location_on_post = url_for('.settings', user_id=user_id) + update_account_information_form = UpdateAccountInformationForm(user) + update_profile_information_form = UpdateProfileInformationForm(user) + update_avatar_form = UpdateAvatarForm() + update_password_form = UpdatePasswordForm(user) + update_notifications_form = UpdateNotificationsForm(user) + + # region handle update profile information form + if update_profile_information_form.submit.data and update_profile_information_form.validate(): + user.about_me = update_profile_information_form.about_me.data + user.location = update_profile_information_form.location.data + user.organization = update_profile_information_form.organization.data + user.website = update_profile_information_form.website.data + user.full_name = update_profile_information_form.full_name.data + db.session.commit() + flash('Your changes have been saved') + return redirect(redirect_location_on_post) + # endregion handle update profile information form + + # region handle update avatar form + if update_avatar_form.submit.data and update_avatar_form.validate(): + try: + Avatar.create( + update_avatar_form.avatar.data, + user=user + ) + except (AttributeError, OSError): + abort(500) + db.session.commit() + flash('Your changes have been saved') + return redirect(redirect_location_on_post) + # endregion handle update avatar form + + # region handle update account information form + if update_account_information_form.submit.data and update_account_information_form.validate(): + user.email = update_account_information_form.email.data + user.username = update_account_information_form.username.data + db.session.commit() + flash('Profile settings updated') + return redirect(redirect_location_on_post) + # endregion handle update account information form + + # region handle update password form + if update_password_form.submit.data and update_password_form.validate(): + user.password = update_password_form.new_password.data + db.session.commit() + flash('Your changes have been saved') + return redirect(redirect_location_on_post) + # endregion handle update password form + + # region handle update notifications form + if update_notifications_form.submit.data and update_notifications_form.validate(): + user.setting_job_status_mail_notification_level = \ + update_notifications_form.job_status_mail_notification_level.data + db.session.commit() + flash('Your changes have been saved') + return redirect(redirect_location_on_post) + # endregion handle update notifications form + + return render_template( + 'users/settings/settings.html.j2', + title='Settings', + update_account_information_form=update_account_information_form, + update_avatar_form=update_avatar_form, + update_notifications_form=update_notifications_form, + update_password_form=update_password_form, + update_profile_information_form=update_profile_information_form, + user=user + ) -- GitLab