Move auth.settings to a new package (profile) as profile.index

This commit is contained in:
Patrick Jentsch 2019-09-23 16:11:01 +02:00
parent 5da5e402c0
commit 783b8c7e82
10 changed files with 125 additions and 118 deletions

View File

@ -23,16 +23,19 @@ def create_app(config_name):
mail.init_app(app) mail.init_app(app)
socketio.init_app(app, message_qeue='redis://') 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 from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint, url_prefix='/auth') 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 from .main import main as main_blueprint
app.register_blueprint(main_blueprint) app.register_blueprint(main_blueprint)
from .admin import admin as admin_blueprint from .profile import profile as profile_blueprint
app.register_blueprint(admin_blueprint, url_prefix='/admin') 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 return app

View File

@ -61,41 +61,3 @@ class PasswordResetForm(FlaskForm):
class PasswordResetRequestForm(FlaskForm): class PasswordResetRequestForm(FlaskForm):
email = StringField('Email', validators=[DataRequired(), Email()]) email = StringField('Email', validators=[DataRequired(), Email()])
submit = SubmitField('Reset Password') 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!')

View File

@ -1,14 +1,11 @@
from flask import (flash, redirect, render_template, request, url_for, from flask import flash, redirect, render_template, request, url_for
current_app)
from flask_login import current_user, login_required, login_user, logout_user from flask_login import current_user, login_required, login_user, logout_user
from . import auth from . import auth
from .. import db from .. import db
from .forms import (ChangePasswordForm, LoginForm, PasswordResetForm, from .forms import (LoginForm, PasswordResetForm, PasswordResetRequestForm,
PasswordResetRequestForm, RegistrationForm, EditProfileForm) RegistrationForm)
from ..email import send_email from ..email import send_email
from ..models import User from ..models import User
import threading
from app.utils import background_delete_user
@auth.route('/login', methods=['GET', 'POST']) @auth.route('/login', methods=['GET', 'POST'])
@ -133,46 +130,3 @@ def password_reset(token):
return redirect(url_for('main.index')) return redirect(url_for('main.index'))
return render_template('auth/reset_password.html.j2', form=form, return render_template('auth/reset_password.html.j2', form=form,
title='Password Reset') 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'))

View File

@ -1,23 +1,18 @@
from flask_wtf import FlaskForm 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 from wtforms.validators import DataRequired, Length
class CreateCorpusForm(FlaskForm): class CreateCorpusForm(FlaskForm):
description = StringField( description = StringField('Description',
'Description', validators=[DataRequired(), Length(1, 64)])
validators=[DataRequired(), Length(1, 64)]
)
files = MultipleFileField('Files', validators=[DataRequired()]) files = MultipleFileField('Files', validators=[DataRequired()])
submit = SubmitField('Create corpus') submit = SubmitField('Create corpus')
title = StringField( title = StringField('Title', validators=[DataRequired(), Length(1, 32)])
'Title',
validators=[DataRequired(), Length(1, 32)]
)
def validate_files(form, field): def validate_files(form, field):
for file in field.data: for file in field.data:
if not file.filename.lower().endswith('.vrt'): if not file.filename.lower().endswith('.vrt'):
raise ValidationError( raise ValidationError('File does not have an approved '
'File does not have an approved extension: .vrt' 'extension: .vrt')
)

View File

@ -1,14 +1,13 @@
from app.utils import background_delete_job
from flask import (abort, current_app, flash, redirect, request, from flask import (abort, current_app, flash, redirect, request,
render_template, url_for, send_from_directory) render_template, url_for, send_from_directory)
from flask_login import current_user, login_required from flask_login import current_user, login_required
from . import main from . import main
from .forms import CreateCorpusForm from .forms import CreateCorpusForm
from .. import db from .. import db
from ..models import Corpus, Job from ..models import Corpus
import os import os
import logging
import threading import threading
from app.utils import background_delete_job
@main.route('/') @main.route('/')
@ -84,11 +83,9 @@ def dashboard():
flash('Corpus created!') flash('Corpus created!')
return redirect(url_for('main.dashboard')) return redirect(url_for('main.dashboard'))
return render_template( return render_template('main/dashboard.html.j2',
'main/dashboard.html.j2', create_corpus_form=create_corpus_form,
title='Dashboard', title='Dashboard')
create_corpus_form=create_corpus_form
)
@main.route('/jobs/<int:job_id>') @main.route('/jobs/<int:job_id>')
@ -145,9 +142,10 @@ def job_download(job_id):
@main.route('/jobs/<int:job_id>/delete') @main.route('/jobs/<int:job_id>/delete')
@login_required @login_required
def delete_job(job_id): def delete_job(job_id):
delete_thread = threading.Thread(target=background_delete_job, delete_thread = threading.Thread(
args=(current_app._get_current_object(), target=background_delete_job,
job_id)) args=(current_app._get_current_object(), job_id)
)
delete_thread.start() delete_thread.start()
flash('Job has been deleted!') flash('Job has been deleted!')
return redirect(url_for('main.dashboard')) return redirect(url_for('main.dashboard'))

8
app/profile/__init__.py Normal file
View File

@ -0,0 +1,8 @@
from flask import Blueprint
profile = Blueprint('profile', __name__)
from . import views
from ..models import Permission

38
app/profile/forms.py Normal file
View File

@ -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!')

49
app/profile/views.py Normal file
View File

@ -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'))

View File

@ -114,7 +114,7 @@
</div> </div>
<ul id="nav-account-dropdown" class="dropdown-content"> <ul id="nav-account-dropdown" class="dropdown-content">
{% if current_user.is_authenticated %} {% 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> <li><a href="{{ url_for('auth.logout') }}"><i class="material-icons">power_settings_new</i>Log out</a></li>
{% else %} {% else %}
<li><a href="{{ url_for('auth.login') }}"><i class="material-icons">person</i>Log in</a></li> <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><div class="divider"></div></li>
<li><a class="subheader">Account</a></li> <li><a class="subheader">Account</a></li>
{% if current_user.is_authenticated %} {% 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> <li><a href="{{ url_for('auth.logout') }}"><i class="material-icons">power_settings_new</i>Log out</a></li>
{% else %} {% else %}
<li><a href="{{ url_for('auth.login') }}"><i class="material-icons">person</i>Log in</a></li> <li><a href="{{ url_for('auth.login') }}"><i class="material-icons">person</i>Log in</a></li>

View File

@ -89,7 +89,7 @@
</p> </p>
</div> </div>
<div class="modal-footer"> <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> </div>
</div> </div>