Optimizing admin interface for user domain, completing security views

This commit is contained in:
Josako
2024-06-03 09:37:59 +02:00
parent e5a36798bf
commit fcc0caeb09
24 changed files with 523 additions and 174 deletions

View File

@@ -104,7 +104,6 @@ class User(db.Model, UserMixin):
password = db.Column(db.String(255), nullable=False)
first_name = db.Column(db.String(80), nullable=False)
last_name = db.Column(db.String(80), nullable=False)
is_active = db.Column(db.Boolean, default=True)
active = db.Column(db.Boolean)
fs_uniquifier = db.Column(db.String(255), unique=True, nullable=False)
confirmed_at = db.Column(db.DateTime, nullable=True)

View File

@@ -1,34 +1,62 @@
from flask import request
from flask import request, session
import time
from flask_security import current_user
def log_request_middleware(app):
@app.before_request
def log_request_info():
start_time = time.time()
app.logger.debug(f"Request URL: {request.url}")
app.logger.debug(f"Request Method: {request.method}")
app.logger.debug(f"Request Headers: {request.headers}")
app.logger.debug(f"Time taken for logging request info: {time.time() - start_time} seconds")
try:
app.logger.debug(f"Request Body: {request.get_data()}")
except Exception as e:
app.logger.error(f"Error reading request body: {e}")
app.logger.debug(f"Time taken for logging request body: {time.time() - start_time} seconds")
# @app.before_request
# def log_request_info():
# start_time = time.time()
# app.logger.debug(f"Request URL: {request.url}")
# app.logger.debug(f"Request Method: {request.method}")
# app.logger.debug(f"Request Headers: {request.headers}")
# app.logger.debug(f"Time taken for logging request info: {time.time() - start_time} seconds")
# try:
# app.logger.debug(f"Request Body: {request.get_data()}")
# except Exception as e:
# app.logger.error(f"Error reading request body: {e}")
# app.logger.debug(f"Time taken for logging request body: {time.time() - start_time} seconds")
# @app.before_request
# def check_csrf_token():
# start_time = time.time()
# if request.method == "POST":
# csrf_token = request.form.get("csrf_token")
# app.logger.debug(f"CSRF Token: {csrf_token}")
# app.logger.debug(f"Time taken for logging CSRF token: {time.time() - start_time} seconds")
# @app.before_request
# def log_user_info():
# if current_user and current_user.is_authenticated:
# app.logger.debug(f"Before: User ID: {current_user.id}")
# app.logger.debug(f"Before: User Email: {current_user.email}")
# app.logger.debug(f"Before: User Roles: {current_user.roles}")
# else:
# app.logger.debug("After: No user logged in")
@app.before_request
def check_csrf_token():
start_time = time.time()
if request.method == "POST":
csrf_token = request.form.get("csrf_token")
app.logger.debug(f"CSRF Token: {csrf_token}")
app.logger.debug(f"Time taken for logging CSRF token: {time.time() - start_time} seconds")
def log_session_state_before():
app.logger.debug(f'Session state before request: {session.items()}')
# @app.after_request
# def log_response_info(response):
# start_time = time.time()
# app.logger.debug(f"Response Status: {response.status}")
# app.logger.debug(f"Response Headers: {response.headers}")
#
# app.logger.debug(f"Time taken for logging response info: {time.time() - start_time} seconds")
# return response
# @app.after_request
# def log_user_after_request(response):
# if current_user and current_user.is_authenticated:
# app.logger.debug(f"After: User ID: {current_user.id}")
# app.logger.debug(f"after: User Email: {current_user.email}")
# app.logger.debug(f"After: User Roles: {current_user.roles}")
# else:
# app.logger.debug("After: No user logged in")
@app.after_request
def log_response_info(response):
start_time = time.time()
app.logger.debug(f"Response Status: {response.status}")
app.logger.debug(f"Response Headers: {response.headers}")
app.logger.debug(f"Time taken for logging response info: {time.time() - start_time} seconds")
return response
def log_session_state_after(response):
app.logger.debug(f'Session state after request: {session.items()}')
return response

View File

View File

@@ -1,7 +1,19 @@
from flask import current_app, request, url_for
from flask import request, current_app, url_for
from urllib.parse import urlsplit, urlunsplit
def prefixed_url_for(endpoint, **values):
prefix = request.headers.get('X-Forwarded-Prefix', '')
current_app.logger.debug(f'prefix: {prefix}')
return prefix + url_for(endpoint, **values)
scheme = request.headers.get('X-Forwarded-Proto', request.scheme)
host = request.headers.get('Host', request.host)
current_app.logger.debug(f'prefix: {prefix}, scheme: {scheme}, host: {host}')
external = values.pop('_external', False)
generated_url = url_for(endpoint, **values)
if external:
path, query, fragment = urlsplit(generated_url)[2:5]
new_path = prefix + path
return urlunsplit((scheme, host, new_path, query, fragment))
else:
return prefix + generated_url

View File

@@ -1,9 +1,10 @@
from flask import session
from flask import session, current_app
from common.models.user import Tenant
# Definition of Trigger Handlers
def set_tenant_session_data(sender, user, **kwargs):
current_app.logger.debug(f"Setting tenant session data for user {user.id}")
tenant = Tenant.query.filter_by(id=user.tenant_id).first()
session['tenant'] = tenant.to_dict()
session['default_language'] = tenant.default_language

View File

@@ -0,0 +1,53 @@
from flask import current_app, render_template
from flask_mailman import EmailMessage
from itsdangerous import URLSafeTimedSerializer
from common.utils.nginx_utils import prefixed_url_for
def confirm_token(token, expiration=3600):
serializer = URLSafeTimedSerializer(current_app.config['SECRET_KEY'])
try:
email = serializer.loads(token, salt=current_app.config['SECURITY_PASSWORD_SALT'], max_age=expiration)
except Exception as e:
current_app.logger.debug(f'Error confirming token: {e}')
raise
return email
def send_email(to, subject, template):
msg = EmailMessage(subject=subject,
body=template,
to=[to])
msg.content_subtype = "html"
msg.send()
def generate_reset_token(email):
serializer = URLSafeTimedSerializer(current_app.config['SECRET_KEY'])
return serializer.dumps(email, salt=current_app.config['SECURITY_PASSWORD_SALT'])
def generate_confirmation_token(email):
serializer = URLSafeTimedSerializer(current_app.config['SECRET_KEY'])
return serializer.dumps(email, salt=current_app.config['SECURITY_PASSWORD_SALT'])
def send_confirmation_email(user):
current_app.logger.debug(f'Sending confirmation email to {user.email}')
token = generate_confirmation_token(user.email)
confirm_url = prefixed_url_for('security_bp.confirm_email', token=token, _external=True)
current_app.logger.debug(f'Confirmation URL: {confirm_url}')
html = render_template('email/activate.html', confirm_url=confirm_url)
send_email(user.email, "Confirm your email", html)
def send_reset_email(user):
token = generate_reset_token(user.email)
reset_url = prefixed_url_for('security_bp.reset_password', token=token, _external=True)
html = render_template('email/reset_password.html', reset_url=reset_url)
send_email(user.email, "Reset Your Password", html)