- Improved CSRF handling
- Wordpress plugin for Evie Chat
This commit is contained in:
@@ -53,6 +53,10 @@ def create_app(config_file=None):
|
||||
|
||||
register_extensions(app)
|
||||
|
||||
# Configure CSRF protection
|
||||
app.config['WTF_CSRF_CHECK_DEFAULT'] = False # Disable global CSRF protection
|
||||
app.config['WTF_CSRF_TIME_LIMIT'] = None # Remove time limit for CSRF tokens
|
||||
|
||||
app.celery = make_celery(app.name, app.config)
|
||||
init_celery(app.celery, app)
|
||||
|
||||
@@ -88,6 +92,12 @@ def create_app(config_file=None):
|
||||
}
|
||||
return jsonify(response), 500
|
||||
|
||||
@app.before_request
|
||||
def before_request():
|
||||
# app.logger.debug(f"Before request - Session ID: {session.sid}")
|
||||
app.logger.debug(f"Before request - Session data: {session}")
|
||||
app.logger.debug(f"Before request - Request headers: {request.headers}")
|
||||
|
||||
# Register API
|
||||
register_api(app)
|
||||
|
||||
|
||||
@@ -27,9 +27,18 @@ def access_forbidden(error):
|
||||
return render_template('error/403.html')
|
||||
|
||||
|
||||
def key_error_handler(error):
|
||||
# Check if the KeyError is specifically for 'tenant'
|
||||
if str(error) == "'tenant'":
|
||||
return redirect(prefixed_url_for('security.login'))
|
||||
# For other KeyErrors, you might want to log the error and return a generic error page
|
||||
return render_template('error/generic.html', error_message="An unexpected error occurred"), 500
|
||||
|
||||
|
||||
def register_error_handlers(app):
|
||||
app.register_error_handler(404, not_found_error)
|
||||
app.register_error_handler(500, internal_server_error)
|
||||
app.register_error_handler(401, not_authorised_error)
|
||||
app.register_error_handler(403, not_authorised_error)
|
||||
app.register_error_handler(KeyError, key_error_handler)
|
||||
|
||||
|
||||
9
eveai_app/templates/error/generic.html
Normal file
9
eveai_app/templates/error/generic.html
Normal file
@@ -0,0 +1,9 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Unexpected Error{% endblock %}
|
||||
|
||||
{% block content_title %}Internal Server error{% endblock %}
|
||||
{% block content_description %}Something unexpected happened! The administrator has been notified.{% endblock %}
|
||||
{% block content %}
|
||||
<p><a href="{{ url_for('basic_bp.index') }}">Return home</a></p>
|
||||
{% endblock %}
|
||||
@@ -20,6 +20,13 @@
|
||||
{# </p>#}
|
||||
<p>{{ login_user_form.submit() }}</p>
|
||||
</form>
|
||||
|
||||
<!-- Debugging information -->
|
||||
{# <div style="margin-top: 20px; border: 1px solid #ccc; padding: 10px;">#}
|
||||
{# <h4>Debugging Information:</h4>#}
|
||||
{# <p>CSRF Token: {{ login_user_form.csrf_token.current_token }}</p>#}
|
||||
{# <p>Session ID: {{ session.sid }}</p>#}
|
||||
{# </div>#}
|
||||
{% endblock %}
|
||||
{% block content_footer %}
|
||||
First time here? Forgot your password?
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from flask import request, render_template, Blueprint, session, current_app, jsonify
|
||||
from flask_security import roles_required, roles_accepted
|
||||
from flask_wtf.csrf import generate_csrf
|
||||
|
||||
from .basic_forms import SessionDefaultsForm
|
||||
|
||||
@@ -59,3 +60,14 @@ def set_user_timezone():
|
||||
def health():
|
||||
return jsonify({'status': 'ok'}), 200
|
||||
|
||||
|
||||
@basic_bp.route('/check_csrf', methods=['GET'])
|
||||
def check_csrf():
|
||||
csrf_token = generate_csrf()
|
||||
return jsonify({
|
||||
'csrf_token_in_session': session.get('csrf_token'),
|
||||
'generated_csrf_token': csrf_token,
|
||||
'session_id': session.sid if hasattr(session, 'sid') else None,
|
||||
'session_data': dict(session)
|
||||
})
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ from flask import Blueprint, render_template, redirect, request, flash, current_
|
||||
from flask_security import current_user, login_required, login_user, logout_user
|
||||
from flask_security.utils import verify_and_update_password, get_message, do_flash, config_value, hash_password
|
||||
from flask_security.forms import LoginForm
|
||||
from flask_wtf.csrf import CSRFError, generate_csrf
|
||||
from urllib.parse import urlparse
|
||||
from datetime import datetime as dt, timezone as tz
|
||||
|
||||
@@ -45,27 +46,41 @@ def login():
|
||||
|
||||
form = LoginForm()
|
||||
|
||||
if form.validate_on_submit():
|
||||
current_app.logger.debug(f'Validating login form: {form.email.data}')
|
||||
user = User.query.filter_by(email=form.email.data).first()
|
||||
if user is None or not verify_and_update_password(form.password.data, user):
|
||||
flash('Invalid username or password', 'danger')
|
||||
if request.method == 'POST':
|
||||
current_app.logger.debug(f"Starting login procedure for {form.email.data}")
|
||||
try:
|
||||
if form.validate_on_submit():
|
||||
user = User.query.filter_by(email=form.email.data).first()
|
||||
if user is None or not verify_and_update_password(form.password.data, user):
|
||||
flash('Invalid username or password', 'danger')
|
||||
current_app.logger.debug(f'Failed to login user')
|
||||
return redirect(prefixed_url_for('security_bp.login'))
|
||||
|
||||
if login_user(user):
|
||||
current_app.logger.info(f'Login successful! Current User is {current_user.email}')
|
||||
db.session.commit()
|
||||
if current_user.has_roles('Super User'):
|
||||
return redirect(prefixed_url_for('user_bp.select_tenant'))
|
||||
else:
|
||||
return redirect(prefixed_url_for('user_bp.tenant_overview'))
|
||||
else:
|
||||
flash('Invalid username or password', 'danger')
|
||||
current_app.logger.debug(f'Failed to login user {user.email}')
|
||||
abort(401)
|
||||
else:
|
||||
current_app.logger.debug(f'Invalid login form: {form.errors}')
|
||||
|
||||
except CSRFError:
|
||||
current_app.logger.warning('CSRF token mismatch during login attempt')
|
||||
flash('Your session has expired. Please try logging in again.', 'danger')
|
||||
return redirect(prefixed_url_for('security_bp.login'))
|
||||
|
||||
if login_user(user):
|
||||
current_app.logger.info(f'Login successful! Current User is {current_user.email}')
|
||||
db.session.commit()
|
||||
if current_user.has_roles('Super User'):
|
||||
return redirect(prefixed_url_for('user_bp.select_tenant'))
|
||||
else:
|
||||
return redirect(prefixed_url_for('user_bp.tenant_overview'))
|
||||
else:
|
||||
flash('Invalid username or password', 'danger')
|
||||
current_app.logger.debug(f'Failed to login user {user.email}')
|
||||
abort(401)
|
||||
else:
|
||||
current_app.logger.debug(f'Invalid login form: {form.errors}')
|
||||
if request.method == 'GET':
|
||||
csrf_token = generate_csrf()
|
||||
current_app.logger.debug(f'Generated new CSRF token: {csrf_token}')
|
||||
|
||||
# current_app.logger.debug(f"Login route completed - Session ID: {session.sid}")
|
||||
current_app.logger.debug(f"Login route completed - Session data: {session}")
|
||||
return render_template('security/login_user.html', login_user_form=form)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user