From 783b8c7e8288ebb0d0eacc29a16ed33fa8052943 Mon Sep 17 00:00:00 2001 From: Patrick Jentsch <p.jentsch@uni-bielefeld.de> Date: Mon, 23 Sep 2019 16:11:01 +0200 Subject: [PATCH] Move auth.settings to a new package (profile) as profile.index --- app/__init__.py | 13 +++-- app/auth/forms.py | 38 -------------- app/auth/views.py | 52 ++----------------- app/main/forms.py | 19 +++---- app/main/views.py | 20 ++++--- app/profile/__init__.py | 8 +++ app/profile/forms.py | 38 ++++++++++++++ app/profile/views.py | 49 +++++++++++++++++ app/templates/base.html.j2 | 4 +- .../index.html.j2} | 2 +- 10 files changed, 125 insertions(+), 118 deletions(-) create mode 100644 app/profile/__init__.py create mode 100644 app/profile/forms.py create mode 100644 app/profile/views.py rename app/templates/{auth/settings.html.j2 => profile/index.html.j2} (95%) diff --git a/app/__init__.py b/app/__init__.py index bd42c79c..dfa0a249 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -23,16 +23,19 @@ def create_app(config_name): mail.init_app(app) socketio.init_app(app, message_qeue='redis://') + from .admin import admin as admin_blueprint + app.register_blueprint(admin_blueprint, url_prefix='/admin') + from .auth import auth as auth_blueprint app.register_blueprint(auth_blueprint, url_prefix='/auth') - from .services import services as services_blueprint - app.register_blueprint(services_blueprint, url_prefix='/services') - from .main import main as main_blueprint app.register_blueprint(main_blueprint) - from .admin import admin as admin_blueprint - app.register_blueprint(admin_blueprint, url_prefix='/admin') + from .profile import profile as profile_blueprint + app.register_blueprint(profile_blueprint, url_prefix='/profile') + + from .services import services as services_blueprint + app.register_blueprint(services_blueprint, url_prefix='/services') return app diff --git a/app/auth/forms.py b/app/auth/forms.py index 02658b62..8594007f 100644 --- a/app/auth/forms.py +++ b/app/auth/forms.py @@ -61,41 +61,3 @@ class PasswordResetForm(FlaskForm): class PasswordResetRequestForm(FlaskForm): email = StringField('Email', validators=[DataRequired(), Email()]) submit = SubmitField('Reset Password') - - -class ChangePasswordForm(FlaskForm): - """ - Form to change information of currently logged in User. User can change - informations about him on his own. - """ - old_password = PasswordField('Old password', validators=[DataRequired()]) - new_password = PasswordField( - 'New password', - validators=[ - DataRequired(), - EqualTo('new_password2', message='Passwords must match.') - ] - ) - new_password2 = PasswordField( - 'Confirm new password', - validators=[ - DataRequired(), - EqualTo('new_password', message='Passwords must match.') - ] - ) - submit = SubmitField('Update Password') - - -class EditProfileForm(FlaskForm): - email = StringField('Change Email', - validators=[Length(0, 254), DataRequired()]) - submit = SubmitField('Change Email') - - def __init__(self, user, *args, **kwargs): - super(EditProfileForm, self).__init__(*args, **kwargs) - self.user = user - - def validate_email(self, field): - if field.data != self.user.email and \ - User.query.filter_by(email=field.data).first(): - raise ValidationError('Email already registered!') diff --git a/app/auth/views.py b/app/auth/views.py index ade94357..b62190b8 100644 --- a/app/auth/views.py +++ b/app/auth/views.py @@ -1,14 +1,11 @@ -from flask import (flash, redirect, render_template, request, url_for, - current_app) +from flask import flash, redirect, render_template, request, url_for from flask_login import current_user, login_required, login_user, logout_user from . import auth from .. import db -from .forms import (ChangePasswordForm, LoginForm, PasswordResetForm, - PasswordResetRequestForm, RegistrationForm, EditProfileForm) +from .forms import (LoginForm, PasswordResetForm, PasswordResetRequestForm, + RegistrationForm) from ..email import send_email from ..models import User -import threading -from app.utils import background_delete_user @auth.route('/login', methods=['GET', 'POST']) @@ -133,46 +130,3 @@ def password_reset(token): return redirect(url_for('main.index')) return render_template('auth/reset_password.html.j2', form=form, title='Password Reset') - - -@auth.route('/settings', methods=['GET', 'POST']) -@login_required -def settings(): - """ - View where loged in User can change own User information like Password etc. - """ - change_password_form = ChangePasswordForm() - if change_password_form.validate_on_submit(): - if current_user.verify_password(change_password_form.old_password.data): - current_user.password = change_password_form.new_password.data - db.session.add(current_user) - db.session.commit() - flash('Your password has been updated.') - return redirect(url_for('auth.settings')) - else: - flash('Invalid password.') - change_profile_form = EditProfileForm(user=current_user) - if change_profile_form.validate_on_submit(): - current_user.email = change_profile_form.email.data - db.session.add(current_user._get_current_object()) - db.session.commit() - flash('Your email has been updated.') - change_profile_form.email.data = current_user.email - return render_template( - 'auth/settings.html.j2', - change_password_form=change_password_form, - change_profile_form=change_profile_form, - title='Settings' - ) - - -@auth.route('/settings/delete_self', methods=['GET', 'POST']) -@login_required -def delete_self(): - delete_thread = threading.Thread(target=background_delete_user, - args=(current_app._get_current_object(), - current_user.id)) - delete_thread.start() - logout_user() - flash('Your account has been deleted!') - return redirect(url_for('main.index')) diff --git a/app/main/forms.py b/app/main/forms.py index 316be954..cd2c1b23 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -1,23 +1,18 @@ from flask_wtf import FlaskForm -from wtforms import MultipleFileField, StringField, SubmitField, ValidationError +from wtforms import (MultipleFileField, StringField, SubmitField, + ValidationError) from wtforms.validators import DataRequired, Length class CreateCorpusForm(FlaskForm): - description = StringField( - 'Description', - validators=[DataRequired(), Length(1, 64)] - ) + description = StringField('Description', + validators=[DataRequired(), Length(1, 64)]) files = MultipleFileField('Files', validators=[DataRequired()]) submit = SubmitField('Create corpus') - title = StringField( - 'Title', - validators=[DataRequired(), Length(1, 32)] - ) + title = StringField('Title', validators=[DataRequired(), Length(1, 32)]) def validate_files(form, field): for file in field.data: if not file.filename.lower().endswith('.vrt'): - raise ValidationError( - 'File does not have an approved extension: .vrt' - ) + raise ValidationError('File does not have an approved ' + 'extension: .vrt') diff --git a/app/main/views.py b/app/main/views.py index 13a64be3..9160434b 100644 --- a/app/main/views.py +++ b/app/main/views.py @@ -1,14 +1,13 @@ +from app.utils import background_delete_job from flask import (abort, current_app, flash, redirect, request, render_template, url_for, send_from_directory) from flask_login import current_user, login_required from . import main from .forms import CreateCorpusForm from .. import db -from ..models import Corpus, Job +from ..models import Corpus import os -import logging import threading -from app.utils import background_delete_job @main.route('/') @@ -84,11 +83,9 @@ def dashboard(): flash('Corpus created!') return redirect(url_for('main.dashboard')) - return render_template( - 'main/dashboard.html.j2', - title='Dashboard', - create_corpus_form=create_corpus_form - ) + return render_template('main/dashboard.html.j2', + create_corpus_form=create_corpus_form, + title='Dashboard') @main.route('/jobs/<int:job_id>') @@ -145,9 +142,10 @@ def job_download(job_id): @main.route('/jobs/<int:job_id>/delete') @login_required def delete_job(job_id): - delete_thread = threading.Thread(target=background_delete_job, - args=(current_app._get_current_object(), - job_id)) + delete_thread = threading.Thread( + target=background_delete_job, + args=(current_app._get_current_object(), job_id) + ) delete_thread.start() flash('Job has been deleted!') return redirect(url_for('main.dashboard')) diff --git a/app/profile/__init__.py b/app/profile/__init__.py new file mode 100644 index 00000000..5b7be466 --- /dev/null +++ b/app/profile/__init__.py @@ -0,0 +1,8 @@ +from flask import Blueprint + + +profile = Blueprint('profile', __name__) + + +from . import views +from ..models import Permission diff --git a/app/profile/forms.py b/app/profile/forms.py new file mode 100644 index 00000000..ab4f985b --- /dev/null +++ b/app/profile/forms.py @@ -0,0 +1,38 @@ +from flask_wtf import FlaskForm +from wtforms import PasswordField, StringField, SubmitField, ValidationError +from wtforms.validators import DataRequired, EqualTo, Length +from ..models import User + + +class ChangePasswordForm(FlaskForm): + """ + Form to change information of currently logged in User. User can change + informations about him on his own. + """ + old_password = PasswordField('Old password', validators=[DataRequired()]) + new_password = PasswordField( + 'New password', + validators=[DataRequired(), + EqualTo('new_password2', message='Passwords must match.')] + ) + new_password2 = PasswordField( + 'Confirm new password', + validators=[DataRequired(), + EqualTo('new_password', message='Passwords must match.')] + ) + submit = SubmitField('Update Password') + + +class EditProfileForm(FlaskForm): + email = StringField('Change Email', + validators=[Length(0, 254), DataRequired()]) + submit = SubmitField('Change Email') + + def __init__(self, user, *args, **kwargs): + super(EditProfileForm, self).__init__(*args, **kwargs) + self.user = user + + def validate_email(self, field): + if field.data != self.user.email and \ + User.query.filter_by(email=field.data).first(): + raise ValidationError('Email already registered!') diff --git a/app/profile/views.py b/app/profile/views.py new file mode 100644 index 00000000..cf963606 --- /dev/null +++ b/app/profile/views.py @@ -0,0 +1,49 @@ +from app.utils import background_delete_user +from flask import current_app, flash, redirect, render_template, url_for +from flask_login import current_user, login_required, logout_user +from . import profile +from .forms import ChangePasswordForm, EditProfileForm +from .. import db +import threading + + +@profile.route('/', methods=['GET', 'POST']) +@login_required +def index(): + """ + View where loged in User can change own User information like Password etc. + """ + change_password_form = ChangePasswordForm() + if change_password_form.validate_on_submit(): + if current_user.verify_password(change_password_form.old_password.data): + current_user.password = change_password_form.new_password.data + db.session.add(current_user) + db.session.commit() + flash('Your password has been updated.') + return redirect(url_for('profile.index')) + else: + flash('Invalid password.') + change_profile_form = EditProfileForm(user=current_user) + if change_profile_form.validate_on_submit(): + current_user.email = change_profile_form.email.data + db.session.add(current_user._get_current_object()) + db.session.commit() + flash('Your email has been updated.') + change_profile_form.email.data = current_user.email + return render_template('profile/index.html.j2', + change_password_form=change_password_form, + change_profile_form=change_profile_form, + title='Profile') + + +@profile.route('/delete_self', methods=['GET', 'POST']) +@login_required +def delete_self(): + delete_thread = threading.Thread( + target=background_delete_user, + args=(current_app._get_current_object(), current_user.id) + ) + delete_thread.start() + logout_user() + flash('Your account has been deleted!') + return redirect(url_for('main.index')) diff --git a/app/templates/base.html.j2 b/app/templates/base.html.j2 index ec519865..68a609e6 100644 --- a/app/templates/base.html.j2 +++ b/app/templates/base.html.j2 @@ -114,7 +114,7 @@ </div> <ul id="nav-account-dropdown" class="dropdown-content"> {% if current_user.is_authenticated %} - <li><a href="{{ url_for('auth.settings') }}"><i class="material-icons">settings</i>Settings</a></li> + <li><a href="{{ url_for('profile.index') }}"><i class="material-icons">settings</i>Settings</a></li> <li><a href="{{ url_for('auth.logout') }}"><i class="material-icons">power_settings_new</i>Log out</a></li> {% else %} <li><a href="{{ url_for('auth.login') }}"><i class="material-icons">person</i>Log in</a></li> @@ -159,7 +159,7 @@ <li><div class="divider"></div></li> <li><a class="subheader">Account</a></li> {% if current_user.is_authenticated %} - <li><a href="{{ url_for('auth.settings') }}"><i class="material-icons">settings</i>Settings</a></li> + <li><a href="{{ url_for('profile.index') }}"><i class="material-icons">settings</i>Settings</a></li> <li><a href="{{ url_for('auth.logout') }}"><i class="material-icons">power_settings_new</i>Log out</a></li> {% else %} <li><a href="{{ url_for('auth.login') }}"><i class="material-icons">person</i>Log in</a></li> diff --git a/app/templates/auth/settings.html.j2 b/app/templates/profile/index.html.j2 similarity index 95% rename from app/templates/auth/settings.html.j2 rename to app/templates/profile/index.html.j2 index ab4dff9a..bb4e8bb7 100644 --- a/app/templates/auth/settings.html.j2 +++ b/app/templates/profile/index.html.j2 @@ -89,7 +89,7 @@ </p> </div> <div class="modal-footer"> - <a href="{{url_for('auth.delete_self', user_id=current_user.id)}}" class="modal-close waves-effect waves-green btn red"><i class="material-icons left">delete</i>Delete User</a></a> + <a href="{{url_for('profile.delete_self', user_id=current_user.id)}}" class="modal-close waves-effect waves-green btn red"><i class="material-icons left">delete</i>Delete User</a></a> </div> </div> </div> -- GitLab