diff --git a/config.py b/config.py index ff36ab7..afb2671 100644 --- a/config.py +++ b/config.py @@ -14,6 +14,7 @@ class Config: class DevelopmentConfig(Config): DEBUG = True + DEBUG_TB_ENABLED = True MAIL_SERVER = 'localhost' MAIL_PORT = 25 MAIL_USE_TLS = True diff --git a/dash/admin/forms.py b/dash/admin/forms.py index 751769b..b525f07 100644 --- a/dash/admin/forms.py +++ b/dash/admin/forms.py @@ -5,7 +5,7 @@ from wtforms import StringField, PasswordField, BooleanField, SubmitField, \ from wtforms.validators import Required, Length, Email, Regexp, EqualTo from ..models import User, Role -class EditProfileAdminForm(Form): +class EditUserAdminForm(Form): email = StringField('Email', validators=[Required(), Length(1, 128), Email()]) username = StringField('Username', validators=[ @@ -13,19 +13,48 @@ class EditProfileAdminForm(Form): 'Usernames must have only letters, ' 'numbers, dots or underscores')]) full_name = StringField('Full name', validators=[Required(), Length(1, 255)]) - role_id = SelectField('Role', coerce=int) + role = SelectField('Role', coerce=int) confirmed = BooleanField('Confirmed') def __init__(self, user, *args, **kwargs): - super(EditProfileAdminForm, self).__init__(*args, **kwargs) - self.role_id.choices = [(role.id, role.name) + super(EditUserAdminForm, self).__init__(*args, **kwargs) + self.role.choices = [(role.id, role.name) for role in Role.query.order_by(Role.name).all()] 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.') + + def validate_username(self, field): + if field.data != self.user.username and \ + User.query.filter_by(username=field.data).first(): + raise ValidationError('Username already in use.') + + +class CreateUserAdminForm(Form): + email = StringField('Email', validators=[Required(), Length(1, 128), + Email()]) + username = StringField('Username', validators=[ + Required(), Length(1, 64), Regexp('^[A-Za-z][A-Za-z0-9_.]*$', 0, + 'Usernames must have only letters, ' + 'numbers, dots or underscores')]) + full_name = StringField('Full name', validators=[Required(), Length(1, 255)]) + password = PasswordField('Password', validators=[ + Required(), EqualTo('password2', message='Passwords must match.')]) + password2 = PasswordField('Confirm password', validators=[Required()]) + confirmed = BooleanField('Confirmed') + def validate_email(self, field): if User.query.filter_by(email=field.data).first(): raise ValidationError('Email already registered.') def validate_username(self, field): if User.query.filter_by(username=field.data).first(): - raise ValidationError('Username already in use.') \ No newline at end of file + raise ValidationError('Username already in use.') + + +class DeleteUserAdminForm(Form): + confirm = BooleanField('Confirmed', validators=[Required(message='You must confirm to delete.')]) + \ No newline at end of file diff --git a/dash/admin/views.py b/dash/admin/views.py index 8207732..896099c 100644 --- a/dash/admin/views.py +++ b/dash/admin/views.py @@ -4,14 +4,15 @@ from flask import render_template, redirect, request, url_for, flash from flask_login import login_user, logout_user, login_required, \ current_user from flask_principal import Identity, AnonymousIdentity, \ - identity_changed + identity_changed from . import admin from .. import db from ..models import User, Role from ..email import send_email from ..decorators import requires_roles -from .forms import EditProfileAdminForm +from .forms import EditUserAdminForm, CreateUserAdminForm, CreateUserAdminForm, \ + DeleteUserAdminForm @admin.route('/') @login_required @@ -27,22 +28,62 @@ def list_users(): return render_template('admin/list_users.html', users=users, title="List Users", block_description = "list, edit and delete users") - + +@admin.route('/create-user', methods=['GET', 'POST']) +@login_required +@requires_roles("admin") +def create_user_admin(): + form = CreateUserAdminForm() + if form.validate_on_submit(): + r = Role.query.filter_by(default=True).first() + user = User(email=form.email.data, + username=form.username.data, + full_name=form.full_name.data, + password=form.password.data, + avatar="/static/img/user2-160x160.jpg", + created_at=datetime.datetime.now(), + role_id=r.id, + confirmed=form.confirmed.data) + db.session.add(user) + db.session.commit() + flash('New user created.') + return redirect(url_for('.edit_user_admin', id=user.id)) + return render_template('admin/create_user.html', form=form, + title="Create New User", + block_description = "fill all the fields to create new user") + @admin.route('/edit-user/', methods=['GET', 'POST']) @login_required @requires_roles("admin") def edit_user_admin(id): user = User.query.get_or_404(id) - form = EditProfileAdminForm(user=user) + roles = Role.query.filter_by().all() + form = EditUserAdminForm(user=user) if form.validate_on_submit(): user.email = form.email.data user.username = form.username.data user.full_name = form.full_name.data - user.role_id = Role.query.get(form.role.data) + user.role = Role.query.get(form.role.data) user.confirmed = form.confirmed.data db.session.add(user) flash('The profile has been updated.') - return redirect(url_for('.user', username=user.username)) + return redirect(url_for('.edit_user_admin', id=user.id)) return render_template('admin/edit_user.html', user=user, form=form, + roles=roles, title="Edit User", - block_description = "edit and update user info") \ No newline at end of file + block_description = "edit and update user info") + +@admin.route('/delete-user/', methods=['GET', 'POST']) +@login_required +@requires_roles("admin") +def delete_user_admin(id): + user = User.query.get_or_404(id) + form = DeleteUserAdminForm(user=user) + if form.validate_on_submit(): + db.session.delete(user) + db.session.commit() + flash('The user has been deleted.') + return redirect(url_for('.index')) + return render_template('admin/delete_user.html', user=user, form=form, + title="Delete User", + block_description = "delete user confirmation") \ No newline at end of file diff --git a/dash/templates/admin/create_user.html b/dash/templates/admin/create_user.html new file mode 100644 index 0000000..5c477f8 --- /dev/null +++ b/dash/templates/admin/create_user.html @@ -0,0 +1,98 @@ +{% extends "adminlte/base.html" %} +{% import "adminlte/layout.html" as layout with context %} +{% import "adminlte/widgets.html" as widgets with context %} +{% from "_formhelpers.html" import render_field %} + +{% block title %}Admin - {{ title }}{% endblock %} +{% block description %}{{ block_description }}{% endblock %} + +{% block navbar %} + + {% include "navbar.html" %} + +{%- endblock navbar %} + + +{% block sidebar -%} + + {% include 'sidebar.html' %} + + {% include 'admin/sidebar_menu.html' %} + +{%- endblock sidebar %} + + +{% block content_header -%} + {% include 'admin/content_header.html' %} +{%- endblock content_header %} + +{% block content -%} + +
+
+
+ +
+
+ {{ form.hidden_tag() }} +
+ + + {% if form.email.errors %} + {% for error in form.email.errors %} {{ error }} {% endfor %} + {% endif %} +
+
+ + + {% if form.username.errors %} + {% for error in form.username.errors %} {{ error }} {% endfor %} + {% endif %} +
+
+ + +
+
+ + + {% if form.password.errors %} + {% for error in form.password.errors %} {{ error }} {% endfor %} + {% endif %} +
+
+ + + {% if form.password2.errors %} + {% for error in form.password2.errors %} {{ error }} {% endfor %} + {% endif %} +
+
+
+
+ + {% if form.confirmed.errors %} +
+ {% for error in form.confirmed.errors %} {{ error }} {% endfor %} + {% endif %} +
+
+ +
+ +
+ +
+
+
+ +
+ +
+ +
+ + +{%- endblock content %} \ No newline at end of file diff --git a/dash/templates/admin/delete_user.html b/dash/templates/admin/delete_user.html new file mode 100644 index 0000000..cf90501 --- /dev/null +++ b/dash/templates/admin/delete_user.html @@ -0,0 +1,84 @@ +{% extends "adminlte/base.html" %} +{% import "adminlte/layout.html" as layout with context %} +{% import "adminlte/widgets.html" as widgets with context %} +{% from "_formhelpers.html" import render_field %} + +{% block title %}Admin - {{ title }}{% endblock %} +{% block description %}{{ block_description }}{% endblock %} + +{% block navbar %} + + {% include "navbar.html" %} + +{%- endblock navbar %} + + +{% block sidebar -%} + + {% include 'sidebar.html' %} + + {% include 'admin/sidebar_menu.html' %} + +{%- endblock sidebar %} + + +{% block content_header -%} + {% include 'admin/content_header.html' %} +{%- endblock content_header %} + +{% block content -%} + +
+
+
+ +
+ + +

You are Warned

+
+ +
+
+

User Delete Alert!

+ Your are about to delete user "{{ user.username }}" from database. + You will not able to undo this action. +
+ Are you sure you want to delete this user? +
+
+ +
+ +
+
+ {{ form.hidden_tag() }} +
+
+
+ + {% if form.confirm.errors %} +
+ {% for error in form.confirm.errors %} {{ error }} {% endfor %} + {% endif %} +
+
+ +
+ +
+ +
+
+
+ +
+ +
+ + + + +{%- endblock content %} \ No newline at end of file diff --git a/dash/templates/admin/edit_user.html b/dash/templates/admin/edit_user.html index 2951e39..74a945d 100644 --- a/dash/templates/admin/edit_user.html +++ b/dash/templates/admin/edit_user.html @@ -36,40 +36,40 @@
{{ form.hidden_tag() }}
- + {% if form.email.errors %} {% for error in form.email.errors %} {{ error }} {% endfor %} {% endif %}
- + {% if form.username.errors %} {% for error in form.username.errors %} {{ error }} {% endfor %} {% endif %}
- +
- + {% for role in roles %} + + {% endfor %} - {% if form.role_id.errors %} - {% for error in form.role_id.errors %} {{ error }} {% endfor %} + {% if form.role.errors %} + {% for error in form.role.errors %} {{ error }} {% endfor %} {% endif %}
{% if form.confirmed.errors %}
diff --git a/dash/templates/admin/list_users.html b/dash/templates/admin/list_users.html index f7fb8cb..809bffa 100644 --- a/dash/templates/admin/list_users.html +++ b/dash/templates/admin/list_users.html @@ -53,6 +53,8 @@ {{ user.role.name }} Edit + | + Delete {% endfor %} diff --git a/dash/templates/admin/sidebar_menu.html b/dash/templates/admin/sidebar_menu.html index 397941e..73ce766 100644 --- a/dash/templates/admin/sidebar_menu.html +++ b/dash/templates/admin/sidebar_menu.html @@ -14,7 +14,7 @@