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