Correct functions for creating new users, confirming email, resetting password and forgot password.

This commit is contained in:
Josako
2024-08-21 14:59:56 +02:00
parent 6219d11e56
commit 9757830bc4
20 changed files with 291 additions and 43 deletions

View File

@@ -10,6 +10,7 @@ from common.extensions import (db, migrate, bootstrap, security, mail, login_man
minio_client, simple_encryption)
from common.models.user import User, Role, Tenant, TenantDomain
import common.models.interaction
from common.utils.nginx_utils import prefixed_url_for
from config.logging_config import LOGGING
from common.utils.security import set_tenant_session_data
from .errors import register_error_handlers

View File

@@ -0,0 +1,13 @@
<!doctype html>
<html>
<head>
<title>Reset Your Password</title>
</head>
<body>
<p>Hi,</p>
<p>You requested a password reset for your EveAI account. Click the link below to reset your password:</p>
<p><a href="{{ reset_url }}">Reset Password</a></p>
<p>If you did not request a password reset, please ignore this email.</p>
<p>Thanks,<br>The EveAI Team</p>
</body>
</html>

View File

@@ -0,0 +1,13 @@
<!doctype html>
<html>
<head>
<title>Reset Your Password</title>
</head>
<body>
<p>Hi,</p>
<p>You requested a password reset for your EveAI account. Click the link below to reset your password:</p>
<p><a href="{{ reset_link }}">Reset Password</a></p>
<p>If you did not request a password reset, please ignore this email.</p>
<p>Thanks,<br>The EveAI Team</p>
</body>
</html>

View File

@@ -9,10 +9,16 @@
{% include "security/_messages.html" %}
<form action="{{ url_for_security('forgot_password') }}" method="post" name="forgot_password_form">
{{ forgot_password_form.hidden_tag() }}
<p>
{{ forgot_password_form.email.label }}<br>
{{ forgot_password_form.email(size=80) }}
</p>
<p>{{ forgot_password_form.submit() }}</p>
{{ render_form_errors(forgot_password_form) }}
{{ render_field_with_errors(forgot_password_form.email) }}
{{ render_field_errors(forgot_password_form.csrf_token) }}
{{ render_field(forgot_password_form.submit) }}
</form>
{% include "security/_menu.html" %}
<!-- {% include "security/_menu.html" %}-->
{% endblock content %}

View File

@@ -14,10 +14,7 @@
{{ login_user_form.password.label }}<br>
{{ login_user_form.password(size=80) }}
</p>
{# <p>#}
{# {{ login_user_form.remember_me }}#}
{# {{ login_user_form.remember_me.label }}#}
{# </p>#}
<p>{{ login_user_form.submit() }}</p>
</form>

View File

@@ -1,12 +1,12 @@
{% extends "security/base.html" %}
{% from "macros.html" import render_field %}
{% block title %} {{ _fsdomain('Reset password') }} {% endblock %}
{% block content_title %} {{ _fsdomain('Reset password') }} {% endblock %}
{% block title %} {{ _fsdomain('Reset AskEveAI password') }} {% endblock %}
{% block content_title %} {{ _fsdomain('Reset AskEveAI password') }} {% endblock %}
{% block content_description %}An email will be sent to you with instructions.{% endblock %}
{% block content %}
{# {% include "security/_messages.html" %}#}
{# <form action="{{ url_for_security('reset_password', token=reset_password_token) }}" method="post" name="reset_password_form">#}
{# <form action="{{ prefixed_url_for('security.reset_password', token=reset_password_token) }}" method="post" name="reset_password_form">#}
<form action="" method="post">
{{ reset_password_form.hidden_tag() }}
{# {{ render_form_errors(reset_password_form) }}#}

View File

@@ -12,6 +12,7 @@
<div class="form-group mt-3">
<button type="submit" name="action" value="edit_user" class="btn btn-primary">Edit Selected User</button>
<button type="submit" name="action" value="resend_confirmation_email" class="btn btn-secondary">Resend Confirmation Email</button>
<button type="submit" name="action" value="send_password_reset_email" class="btn btn-secondary">Send Password Reset Email</button>
<button type="submit" name="action" value="reset_uniquifier" class="btn btn-secondary">Reset Uniquifier</button>
<!-- Additional buttons can be added here for other actions -->
</div>

View File

@@ -2,6 +2,10 @@ from flask import current_app
from flask_wtf import FlaskForm
from wtforms import PasswordField, SubmitField, StringField
from wtforms.validators import DataRequired, Length, Email, NumberRange, Optional, EqualTo
from flask_security.forms import ForgotPasswordForm
from flask_security.utils import send_mail, config_value
from common.utils.nginx_utils import prefixed_url_for
class SetPasswordForm(FlaskForm):
@@ -18,4 +22,4 @@ class RequestResetForm(FlaskForm):
class ResetPasswordForm(FlaskForm):
password = PasswordField('Password', validators=[DataRequired()])
confirm_password = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')])
submit = SubmitField('Reset Password')
submit = SubmitField('Reset Password')

View File

@@ -164,3 +164,5 @@ def reset_password(token):

View File

@@ -154,30 +154,20 @@ def user():
form.tenant_id.data = session.get('tenant').get('id') # It is only possible to create users for the session tenant
if form.validate_on_submit():
current_app.logger.info(f"Adding User for tenant {session['tenant']['id']} ")
if form.password.data != form.confirm_password.data:
flash('Passwords do not match.', 'danger')
return render_template('user/user.html', form=form)
# Handle the required attributes
hashed_password = hash_password(form.password.data)
new_user = User(user_name=form.user_name.data,
email=form.email.data,
password=hashed_password,
first_name=form.first_name.data,
last_name=form.last_name.data,
valid_to=form.valid_to.data,
tenant_id=form.tenant_id.data
tenant_id=form.tenant_id.data,
fs_uniquifier=uuid.uuid4().hex,
)
timestamp = dt.now(tz.utc)
new_user.created_at = timestamp
new_user.updated_at = timestamp
# Handle the relations
tenant_id = request.form.get('tenant_id')
# the_tenant = Tenant.query.get(tenant_id)
# new_user.tenant = the_tenant
# Add roles
for role_id in form.roles.data:
the_role = Role.query.get(role_id)
@@ -188,11 +178,17 @@ def user():
try:
db.session.add(new_user)
db.session.commit()
security.datastore.set_uniquifier()
send_confirmation_email(new_user)
current_app.logger.debug(f'User {new_user.id} with name {new_user.user_name} added to database'
f'Confirmation email sent to {new_user.email}')
flash('User added successfully and confirmation email sent.', 'success')
# security.datastore.set_uniquifier(new_user)
try:
send_confirmation_email(new_user)
current_app.logger.debug(f'User {new_user.id} with name {new_user.user_name} added to database'
f'Confirmation email sent to {new_user.email}')
flash('User added successfully and confirmation email sent.', 'success')
except Exception as e:
current_app.logger.error(f'Failed to send confirmation email to {new_user.email}. Error: {str(e)}')
flash('User added successfully, but failed to send confirmation email. '
'Please contact the administrator.', 'warning')
return redirect(prefixed_url_for('user_bp.view_users'))
except Exception as e:
current_app.logger.error(f'Failed to add user with name {new_user.user_name}. Error: {str(e)}')
@@ -315,6 +311,9 @@ def handle_user_action():
elif action == 'resend_confirmation_email':
send_confirmation_email(user)
flash(f'Confirmation email sent to {user.email}.', 'success')
elif action == 'send_password_reset_email':
send_reset_email(user)
flash(f'Password reset email sent to {user.email}.', 'success')
elif action == 'reset_uniquifier':
reset_uniquifier(user)
flash(f'Uniquifier reset for {user.user_name}.', 'success')