diff --git a/advlabdb/modelViews.py b/advlabdb/modelViews.py index 0cfe2ee..1150316 100644 --- a/advlabdb/modelViews.py +++ b/advlabdb/modelViews.py @@ -2,7 +2,7 @@ from flask import flash, request, url_for from flask_admin.contrib.sqla.filters import BaseSQLAFilter from flask_admin.menu import MenuLink from flask_admin.model.template import EndpointLinkRowAction -from flask_security import current_user, hash_password +from flask_security import current_user, hash_password, admin_change_password from sqlalchemy import func from wtforms import Form, BooleanField, SelectField, TextField, RadioField from wtforms.validators import DataRequired, Email, Optional, URL @@ -38,23 +38,52 @@ from advlabdb.exceptions import ModelViewException class UserView(SecureModelView): + class CreateForm(Form): + def roleQueryFactory(): + return Role.query + + def semesterQueryFactory(): + return Semester.query + + email = TextField("Email", validators=[DataRequired(), Email()]) + roles = QuerySelectMultipleField( + "Roles", + query_factory=roleQueryFactory, + validators=[DataRequired()], + default=[Role.query.filter(Role.name == "assistant").first()], + ) + active = BooleanField("Active", default=True) + active_semester = QuerySelectField( + "Active Semester", + query_factory=semesterQueryFactory, + allow_blank=True, + blank_text="-", + ) + + generate_new_password = None + + class EditForm(CreateForm): + generate_new_password = BooleanField("Generate new random password", default=False) + + form = EditForm + can_view_details = True column_list = ["email", "active", "roles", "assistant", "active_semester"] column_searchable_list = ["email"] column_filters = ["active", "active_semester", "assistant"] - form_columns = ["email", "active", "roles", "active_semester"] column_editable_list = ["active"] - form_args = { - "email": {"validators": [Email()]}, - "active": {"default": True}, - "roles": {"default": [Role.query.filter(Role.name == "assistant").first()], "validators": [DataRequired()]}, - } + def create_form(self, obj=None): + form = self.CreateForm + return form(get_form_data(), obj=obj) + + def flashPassword(password): + flash(f"Random password: {password}", category="warning") def create_model(self, form): password = randomPassword() - passwordHash = hash_password(password) + hashedPassword = hash_password(password) email = form.email.data.lower() @@ -64,7 +93,7 @@ class UserView(SecureModelView): try: model = user_datastore.create_user( - email=email, password=passwordHash, roles=roles, active_semester=form.active_semester.data + email=email, password=hashedPassword, roles=roles, active_semester=form.active_semester.data ) self.on_model_change(form, model, True) @@ -78,7 +107,10 @@ class UserView(SecureModelView): f"{email} registered with roles: {', '.join([role.name for role in form.roles.data])}.", category="success", ) - flash(f"Random password: {password}", category="warning") + + UserView.flashPassword(password) + + self.after_model_change(form, model, True) return model def on_model_delete(self, model): @@ -89,6 +121,13 @@ class UserView(SecureModelView): if model == current_user and not form.active.data: raise ModelViewException("Tried to deactiavte yourself as user!") + if form.generate_new_password and form.generate_new_password.data: + password = randomPassword() + + UserView.flashPassword(password) + + admin_change_password(model, password, notify=False) # Password is automatically hashed with this method + class RoleView(SecureModelView): can_create = False