diff --git a/eveai_app/views/basic_views.py b/eveai_app/views/basic_views.py
index 544e523..fd7b1dc 100644
--- a/eveai_app/views/basic_views.py
+++ b/eveai_app/views/basic_views.py
@@ -70,7 +70,7 @@ def session_defaults():
session.pop('catalog_name', None)
flash('Session defaults updated successfully', 'success')
- return redirect(prefixed_url_for('basic_bp.index'))
+ return redirect(prefixed_url_for('basic_bp.index', for_redirect=True))
return render_template('basic/session_defaults.html', form=form)
@@ -80,7 +80,7 @@ def session_defaults():
except Exception as e:
current_app.logger.error(f"Error in session_defaults: {str(e)}")
flash('Error accessing catalog data. Please ensure your session is valid.', 'danger')
- return redirect(prefixed_url_for('security_bp.login'))
+ return redirect(prefixed_url_for('security_bp.login', for_redirect=True))
@basic_bp.route('/set_user_timezone', methods=['POST'])
@@ -129,7 +129,7 @@ def view_content(content_type):
if not content_data:
flash(f'Content van type {content_type} werd niet gevonden.', 'danger')
- return redirect(prefixed_url_for('basic_bp.index'))
+ return redirect(prefixed_url_for('basic_bp.index', for_redirect=True))
# Titels en beschrijvingen per contenttype
titles = {
@@ -156,10 +156,10 @@ def view_content(content_type):
except Exception as e:
current_app.logger.error(f"Error displaying content {content_type}: {str(e)}")
flash(f'Error displaying content: {str(e)}', 'danger')
- return redirect(prefixed_url_for('basic_bp.index'))
+ return redirect(prefixed_url_for('basic_bp.index', for_redirect=True))
@basic_bp.route('/release_notes', methods=['GET'])
@roles_accepted('Super User', 'Partner Admin', 'Tenant Admin')
def release_notes():
"""Doorverwijzen naar de nieuwe content view voor changelog"""
- return redirect(prefixed_url_for('basic_bp.view_content', content_type='changelog'))
+ return redirect(prefixed_url_for('basic_bp.view_content', content_type='changelog', for_redirect=True))
diff --git a/eveai_app/views/document_views.py b/eveai_app/views/document_views.py
index 56ced27..ba1e08b 100644
--- a/eveai_app/views/document_views.py
+++ b/eveai_app/views/document_views.py
@@ -74,7 +74,7 @@ def catalog():
flash('Catalog successfully added!', 'success')
current_app.logger.info(f'Catalog {new_catalog.name} successfully added for tenant {tenant_id}!')
# Enable step 2 of creation of catalog - add configuration of the catalog (dependent on type)
- return redirect(prefixed_url_for('document_bp.catalog', catalog_id=new_catalog.id))
+ return redirect(prefixed_url_for('document_bp.catalog', catalog_id=new_catalog.id, for_redirect=True))
except SQLAlchemyError as e:
db.session.rollback()
flash(f'Failed to add catalog. Error: {e}', 'danger')
@@ -97,7 +97,7 @@ def catalogs():
def handle_catalog_selection():
action = request.form['action']
if action == 'create_catalog':
- return redirect(prefixed_url_for('document_bp.catalog'))
+ return redirect(prefixed_url_for('document_bp.catalog', for_redirect=True))
catalog_identification = request.form.get('selected_row')
catalog_id = ast.literal_eval(catalog_identification).get('value')
catalog = Catalog.query.get_or_404(catalog_id)
@@ -108,9 +108,9 @@ def handle_catalog_selection():
session['catalog_name'] = catalog.name
session['catalog'] = catalog.to_dict()
elif action == 'edit_catalog':
- return redirect(prefixed_url_for('document_bp.edit_catalog', catalog_id=catalog_id))
+ return redirect(prefixed_url_for('document_bp.edit_catalog', catalog_id=catalog_id, for_redirect=True))
- return redirect(prefixed_url_for('document_bp.catalogs'))
+ return redirect(prefixed_url_for('document_bp.catalogs', for_redirect=True))
@document_bp.route('/catalog/', methods=['GET', 'POST'])
@@ -136,7 +136,7 @@ def edit_catalog(catalog_id):
flash(f'Failed to update catalog. Error: {e}', 'danger')
current_app.logger.error(f'Failed to update catalog {catalog_id} for tenant {tenant_id}. Error: {str(e)}')
- return redirect(prefixed_url_for('document_bp.catalogs'))
+ return redirect(prefixed_url_for('document_bp.catalogs', for_redirect=True))
else:
form_validation_failed(request, form)
@@ -166,7 +166,7 @@ def processor():
flash('Processor successfully added!', 'success')
current_app.logger.info(f'Processor {new_processor.name} successfully added for tenant {tenant_id}!')
# Enable step 2 of creation of retriever - add configuration of the retriever (dependent on type)
- return redirect(prefixed_url_for('document_bp.edit_processor', processor_id=new_processor.id))
+ return redirect(prefixed_url_for('document_bp.edit_processor', processor_id=new_processor.id, for_redirect=True))
except SQLAlchemyError as e:
db.session.rollback()
flash(f'Failed to add processor. Error: {e}', 'danger')
@@ -215,7 +215,7 @@ def edit_processor(processor_id):
current_app.logger.error(f'Failed to update processor {processor_id}. Error: {str(e)}')
return render_template('document/edit_processor.html', form=form, processor_id=processor_id)
- return redirect(prefixed_url_for('document_bp.processors'))
+ return redirect(prefixed_url_for('document_bp.processors', for_redirect=True))
else:
form_validation_failed(request, form)
@@ -228,7 +228,7 @@ def processors():
catalog_id = session.get('catalog_id', None)
if not catalog_id:
flash('You need to set a Session Catalog before adding Documents or URLs', 'warning')
- return redirect(prefixed_url_for('document_bp.catalogs'))
+ return redirect(prefixed_url_for('document_bp.catalogs', for_redirect=True))
# Get configuration and render the list view
config = get_processors_list_view(catalog_id)
@@ -240,14 +240,14 @@ def processors():
def handle_processor_selection():
action = request.form['action']
if action == 'create_processor':
- return redirect(prefixed_url_for('document_bp.processor'))
+ return redirect(prefixed_url_for('document_bp.processor', for_redirect=True))
processor_identification = request.form.get('selected_row')
processor_id = ast.literal_eval(processor_identification).get('value')
if action == 'edit_processor':
- return redirect(prefixed_url_for('document_bp.edit_processor', processor_id=processor_id))
+ return redirect(prefixed_url_for('document_bp.edit_processor', processor_id=processor_id, for_redirect=True))
- return redirect(prefixed_url_for('document_bp.processors'))
+ return redirect(prefixed_url_for('document_bp.processors', for_redirect=True))
# Retriever Management ----------------------------------------------------------------------------
@@ -272,7 +272,7 @@ def retriever():
flash('Retriever successfully added!', 'success')
current_app.logger.info(f'Catalog {new_retriever.name} successfully added for tenant {tenant_id}!')
# Enable step 2 of creation of retriever - add configuration of the retriever (dependent on type)
- return redirect(prefixed_url_for('document_bp.edit_retriever', retriever_id=new_retriever.id))
+ return redirect(prefixed_url_for('document_bp.edit_retriever', retriever_id=new_retriever.id, for_redirect=True))
except SQLAlchemyError as e:
db.session.rollback()
flash(f'Failed to add retriever. Error: {e}', 'danger')
@@ -315,7 +315,7 @@ def edit_retriever(retriever_id):
current_app.logger.error(f'Failed to update retriever {retriever_id}. Error: {str(e)}')
return render_template('document/edit_retriever.html', form=form, retriever_id=retriever_id)
- return redirect(prefixed_url_for('document_bp.retrievers'))
+ return redirect(prefixed_url_for('document_bp.retrievers', for_redirect=True))
else:
form_validation_failed(request, form)
@@ -328,7 +328,7 @@ def retrievers():
catalog_id = session.get('catalog_id', None)
if not catalog_id:
flash('You need to set a Session Catalog before adding Documents or URLs', 'warning')
- return redirect(prefixed_url_for('document_bp.catalogs'))
+ return redirect(prefixed_url_for('document_bp.catalogs', for_redirect=True))
# Get configuration and render the list view
config = get_retrievers_list_view(catalog_id)
@@ -340,14 +340,14 @@ def retrievers():
def handle_retriever_selection():
action = request.form['action']
if action == 'create_retriever':
- return redirect(prefixed_url_for('document_bp.retriever'))
+ return redirect(prefixed_url_for('document_bp.retriever', for_redirect=True))
retriever_identification = request.form.get('selected_row')
retriever_id = ast.literal_eval(retriever_identification).get('value')
if action == 'edit_retriever':
- return redirect(prefixed_url_for('document_bp.edit_retriever', retriever_id=retriever_id))
+ return redirect(prefixed_url_for('document_bp.edit_retriever', retriever_id=retriever_id, for_redirect=True))
- return redirect(prefixed_url_for('document_bp.retrievers'))
+ return redirect(prefixed_url_for('document_bp.retrievers', for_redirect=True))
# Document Management -----------------------------------------------------------------------------
@@ -358,7 +358,7 @@ def add_document():
catalog_id = session.get('catalog_id', None)
if catalog_id is None:
flash('You need to set a Session Catalog before adding Documents or URLs', 'warning')
- return redirect(prefixed_url_for('document_bp.catalogs'))
+ return redirect(prefixed_url_for('document_bp.catalogs', for_redirect=True))
catalog = Catalog.query.get_or_404(catalog_id)
if catalog.configuration and len(catalog.configuration) > 0:
@@ -392,7 +392,7 @@ def add_document():
flash(f'Processing on document {new_doc.name}, version {new_doc_vers.id} started. Task ID: {task_id}.',
'success')
- return redirect(prefixed_url_for('document_bp.documents_processing'))
+ return redirect(prefixed_url_for('document_bp.documents_processing', for_redirect=True))
except EveAIException as e:
flash(str(e), 'danger')
@@ -411,7 +411,7 @@ def add_url():
catalog_id = session.get('catalog_id', None)
if catalog_id is None:
flash('You need to set a Session Catalog before adding Documents or URLs', 'warning')
- return redirect(prefixed_url_for('document_bp.catalogs'))
+ return redirect(prefixed_url_for('document_bp.catalogs', for_redirect=True))
catalog = Catalog.query.get_or_404(catalog_id)
if catalog.configuration and len(catalog.configuration) > 0:
@@ -451,7 +451,7 @@ def add_url():
flash(f'Processing on document {new_doc.name}, version {new_doc_vers.id} started. Task ID: {task_id}.',
'success')
- return redirect(prefixed_url_for('document_bp.documents_processing'))
+ return redirect(prefixed_url_for('document_bp.documents_processing', for_redirect=True))
except EveAIException as e:
current_app.logger.error(f"Error adding document: {str(e)}")
@@ -472,7 +472,7 @@ def documents():
catalog_id = session.get('catalog_id', None)
if not catalog_id:
flash('You need to set a Session Catalog before adding Documents or URLs', 'warning')
- return redirect(prefixed_url_for('document_bp.catalogs'))
+ return redirect(prefixed_url_for('document_bp.catalogs', for_redirect=True))
config = get_documents_list_view(catalog_id)
return render_list_view('list_view.html', **config)
@@ -484,7 +484,7 @@ def documents_processing():
catalog_id = session.get('catalog_id', None)
if not catalog_id:
flash('You need to set a Session Catalog before adding Documents or URLs', 'warning')
- return redirect(prefixed_url_for('document_bp.catalogs'))
+ return redirect(prefixed_url_for('document_bp.catalogs', for_redirect=True))
config = get_documents_processing_list_view(catalog_id)
return render_list_view('list_view.html', **config)
@@ -502,16 +502,16 @@ def handle_document_selection():
doc_id = ast.literal_eval(document_identification).get('value')
except (ValueError, AttributeError):
flash('Invalid document selection.', 'danger')
- return redirect(prefixed_url_for('document_bp.documents'))
+ return redirect(prefixed_url_for('document_bp.documents', for_redirect=True))
action = request.form['action']
match action:
case 'edit_document':
- return redirect(prefixed_url_for('document_bp.edit_document', document_id=doc_id))
+ return redirect(prefixed_url_for('document_bp.edit_document', document_id=doc_id, for_redirect=True))
case 'refresh':
refresh_document_view(doc_id)
- return redirect(prefixed_url_for('document_bp.documents', document_id=doc_id))
+ return redirect(prefixed_url_for('document_bp.documents', document_id=doc_id, for_redirect=True))
case 're_process':
document = Document.query.get_or_404(doc_id)
doc_vers_id = document.latest_version.id
@@ -520,14 +520,14 @@ def handle_document_selection():
document = Document.query.get_or_404(doc_id)
doc_vers_id = document.latest_version.id
return redirect(prefixed_url_for('document_bp.view_document_version_markdown',
- document_version_id=doc_vers_id))
+ document_version_id=doc_vers_id, for_redirect=True))
case 'edit_document_version':
document = Document.query.get_or_404(doc_id)
doc_vers_id = document.latest_version.id
- return redirect(prefixed_url_for('document_bp.edit_document_version', document_version_id=doc_vers_id))
+ return redirect(prefixed_url_for('document_bp.edit_document_version', document_version_id=doc_vers_id, for_redirect=True))
# Add more conditions for other actions
- return redirect(prefixed_url_for('document_bp.documents'))
+ return redirect(prefixed_url_for('document_bp.documents', for_redirect=True))
@document_bp.route('/edit_document/', methods=['GET', 'POST'])
@@ -562,7 +562,7 @@ def edit_document(document_id):
)
if updated_doc:
flash(f'Document {updated_doc.id} updated successfully', 'success')
- return redirect(prefixed_url_for('document_bp.documents'))
+ return redirect(prefixed_url_for('document_bp.documents', for_redirect=True))
else:
flash(f'Error updating document: {error}', 'danger')
else:
@@ -600,7 +600,7 @@ def edit_document_version(document_version_id):
)
if updated_version:
flash(f'Document Version {updated_version.id} updated successfully', 'success')
- return redirect(prefixed_url_for('document_bp.documents', document_id=updated_version.doc_id))
+ return redirect(prefixed_url_for('document_bp.documents', document_id=updated_version.doc_id, for_redirect=True))
else:
flash(f'Error updating document version: {error}', 'danger')
else:
@@ -644,7 +644,7 @@ def view_document_version_markdown(document_version_id):
except Exception as e:
current_app.logger.error(f"Error retrieving markdown for document version {document_version_id}: {str(e)}")
flash(f"Error retrieving processed document: {str(e)}", "danger")
- return redirect(prefixed_url_for('document_bp.document_versions'))
+ return redirect(prefixed_url_for('document_bp.document_versions', for_redirect=True))
# Utilities ---------------------------------------------------------------------------------------
@@ -667,7 +667,7 @@ def handle_library_selection():
case 'refresh_all_documents':
refresh_all_documents()
- return redirect(prefixed_url_for('document_bp.library_operations'))
+ return redirect(prefixed_url_for('document_bp.library_operations', for_redirect=True))
def create_default_rag_library():
@@ -675,7 +675,7 @@ def create_default_rag_library():
catalogs = Catalog.query.all()
if catalogs:
flash("Default RAG Library can only be created if no catalogs are defined!", 'danger')
- return redirect(prefixed_url_for('document_bp.library_operations'))
+ return redirect(prefixed_url_for('document_bp.library_operations', for_redirect=True))
timestamp = dt.now(tz=tz.utc)
try:
@@ -749,7 +749,7 @@ def create_default_rag_library():
current_app.logger.error(f'Failed to create Default RAG Library'
f'for tenant {session['tenant']['id']}. Error: {str(e)}')
- return redirect(prefixed_url_for('document_bp.library_operations'))
+ return redirect(prefixed_url_for('document_bp.library_operations', for_redirect=True))
def refresh_all_documents():
@@ -763,7 +763,7 @@ def refresh_document_view(document_id):
flash(f'Document refreshed. New version: {new_version.id}. Task ID: {result}', 'success')
else:
flash(f'Error refreshing document: {result}', 'danger')
- return redirect(prefixed_url_for('document_bp.documents'))
+ return redirect(prefixed_url_for('document_bp.documents', for_redirect=True))
def re_embed_latest_versions():
@@ -785,7 +785,7 @@ def process_version(version_id):
flash(f'Processing for document version {version_id} retriggered successfully...', 'success')
- return redirect(prefixed_url_for('document_bp.documents'))
+ return redirect(prefixed_url_for('document_bp.documents', for_redirect=True))
def set_logging_information(obj, timestamp):
diff --git a/eveai_app/views/entitlements_views.py b/eveai_app/views/entitlements_views.py
index bbf9cc3..a4b0207 100644
--- a/eveai_app/views/entitlements_views.py
+++ b/eveai_app/views/entitlements_views.py
@@ -47,7 +47,7 @@ def license_tier():
current_app.logger.info(f"Successfully created license tier {new_license_tier.id}")
flash(f"Successfully created tenant license tier {new_license_tier.id}", 'success')
- return redirect(prefixed_url_for('entitlements_bp.license_tiers'))
+ return redirect(prefixed_url_for('entitlements_bp.license_tiers', for_redirect=True))
else:
form_validation_failed(request, form)
@@ -71,7 +71,7 @@ def license_tiers():
def handle_license_tier_selection():
action = request.form['action']
if action == 'create_license_tier':
- return redirect(prefixed_url_for('entitlements_bp.license_tier'))
+ return redirect(prefixed_url_for('entitlements_bp.license_tier', for_redirect=True))
license_tier_identification = request.form['selected_row']
license_tier_id = ast.literal_eval(license_tier_identification).get('value')
@@ -79,15 +79,15 @@ def handle_license_tier_selection():
match action:
case 'edit_license_tier':
return redirect(prefixed_url_for('entitlements_bp.edit_license_tier',
- license_tier_id=license_tier_id))
+ license_tier_id=license_tier_id, for_redirect=True))
case 'create_license_for_tenant':
return redirect(prefixed_url_for('entitlements_bp.create_license',
- license_tier_id=license_tier_id))
+ license_tier_id=license_tier_id, for_redirect=True))
case 'associate_license_tier_to_partner':
LicenseTierServices.associate_license_tier_with_partner(license_tier_id)
# Add more conditions for other actions
- return redirect(prefixed_url_for('entitlements_bp.license_tiers'))
+ return redirect(prefixed_url_for('entitlements_bp.license_tiers', for_redirect=True))
@entitlements_bp.route('/license_tier/', methods=['GET', 'POST'])
@@ -113,7 +113,7 @@ def edit_license_tier(license_tier_id):
flash('License Tier updated successfully.', 'success')
return redirect(
- prefixed_url_for('entitlements_bp.edit_license_tier', license_tier_id=license_tier_id))
+ prefixed_url_for('entitlements_bp.edit_license_tier', license_tier_id=license_tier_id, for_redirect=True))
else:
form_validation_failed(request, form)
@@ -152,7 +152,7 @@ def create_license(license_tier_id):
current_app.logger.error(f'Invalid currency {currency} for tenant {tenant_id} while creating license.')
flash(f"Invalid currency {currency} for tenant {tenant_id} while creating license. "
f"Check tenant's currency and try again.", 'danger')
- return redirect(prefixed_url_for('user_bp.edit_tenant', tenant_id=tenant_id))
+ return redirect(prefixed_url_for('user_bp.edit_tenant', tenant_id=tenant_id, for_redirect=True))
# General data
form.currency.data = currency
form.max_storage_mb.data = license_tier.max_storage_mb
@@ -181,7 +181,7 @@ def create_license(license_tier_id):
db.session.add(new_license)
db.session.commit()
flash('License created successfully', 'success')
- return redirect(prefixed_url_for('entitlements_bp.edit_license', license_id=new_license.id))
+ return redirect(prefixed_url_for('entitlements_bp.edit_license', license_id=new_license.id, for_redirect=True))
except Exception as e:
db.session.rollback()
flash(f'Error creating license: {str(e)}', 'error')
@@ -223,7 +223,7 @@ def edit_license(license_id):
flash('License updated successfully.', 'success')
return redirect(
- prefixed_url_for('entitlements_bp.edit_license', license_id=license_id))
+ prefixed_url_for('entitlements_bp.edit_license', license_id=license_id, for_redirect=True))
else:
form_validation_failed(request, form)
@@ -253,11 +253,11 @@ def handle_license_selection():
match action:
case 'edit_license':
- return redirect(prefixed_url_for('entitlements_bp.edit_license', license_id=license_id))
+ return redirect(prefixed_url_for('entitlements_bp.edit_license', license_id=license_id, for_redirect=True))
case 'view_periods':
- return redirect(prefixed_url_for('entitlements_bp.license_periods', license_id=license_id))
+ return redirect(prefixed_url_for('entitlements_bp.license_periods', license_id=license_id, for_redirect=True))
case _:
- return redirect(prefixed_url_for('entitlements_bp.licenses'))
+ return redirect(prefixed_url_for('entitlements_bp.licenses', for_redirect=True))
@entitlements_bp.route('/license//periods')
@@ -270,7 +270,7 @@ def license_periods(license_id):
tenant_id = session.get('tenant').get('id')
if license.tenant_id != tenant_id:
flash('Access denied to this license', 'danger')
- return redirect(prefixed_url_for('entitlements_bp.licenses'))
+ return redirect(prefixed_url_for('entitlements_bp.licenses', for_redirect=True))
config = get_license_periods_list_view(license_id)
@@ -315,7 +315,7 @@ def edit_license_period(period_id):
flash(f'Error updating status: {str(e)}', 'danger')
current_app.logger.error(f"Error updating period {period_id}: {str(e)}")
- return redirect(prefixed_url_for('entitlements_bp.license_periods', license_id=period.license_id))
+ return redirect(prefixed_url_for('entitlements_bp.license_periods', license_id=period.license_id, for_redirect=True))
return render_template('entitlements/edit_license_period.html', form=form)
@@ -328,7 +328,7 @@ def handle_license_period_selection(license_id):
# For actions that don't require a selection
if 'selected_row' not in request.form:
- return redirect(prefixed_url_for('entitlements_bp.license_periods', license_id=license_id))
+ return redirect(prefixed_url_for('entitlements_bp.license_periods', license_id=license_id, for_redirect=True))
period_identification = request.form['selected_row']
period_id = ast.literal_eval(period_identification).get('value')
@@ -337,19 +337,19 @@ def handle_license_period_selection(license_id):
case 'view_period_details':
# TODO: Implement period details view if needed
flash('Period details view not yet implemented', 'info')
- return redirect(prefixed_url_for('entitlements_bp.license_periods', license_id=license_id))
+ return redirect(prefixed_url_for('entitlements_bp.license_periods', license_id=license_id, for_redirect=True))
case 'edit_license_period':
# Display a form to choose the new status
- return redirect(prefixed_url_for('entitlements_bp.edit_license_period', period_id=period_id))
+ return redirect(prefixed_url_for('entitlements_bp.edit_license_period', period_id=period_id, for_redirect=True))
case _:
- return redirect(prefixed_url_for('entitlements_bp.license_periods', license_id=license_id))
+ return redirect(prefixed_url_for('entitlements_bp.license_periods', license_id=license_id, for_redirect=True))
@entitlements_bp.route('/view_licenses')
@roles_accepted('Super User', 'Partner Admin', 'Tenant Admin')
def view_licenses_redirect():
# Redirect to the new licenses route
- return redirect(prefixed_url_for('entitlements_bp.licenses'))
+ return redirect(prefixed_url_for('entitlements_bp.licenses', for_redirect=True))
@entitlements_bp.route('/active_usage')
@@ -359,7 +359,7 @@ def active_license_usage():
tenant_id = session.get('tenant', {}).get('id')
if not tenant_id:
flash('No active or pending license period found for this tenant', 'warning')
- return redirect(prefixed_url_for('user_bp.tenants'))
+ return redirect(prefixed_url_for('user_bp.tenants', for_redirect=True))
active_period = LicensePeriod.query \
.join(License) \
diff --git a/eveai_app/views/interaction_views.py b/eveai_app/views/interaction_views.py
index f4ebcc7..de36786 100644
--- a/eveai_app/views/interaction_views.py
+++ b/eveai_app/views/interaction_views.py
@@ -77,12 +77,12 @@ def handle_chat_session_selection():
match action:
case 'view_chat_session':
- return redirect(prefixed_url_for('interaction_bp.view_chat_session', chat_session_id=cs_id))
+ return redirect(prefixed_url_for('interaction_bp.view_chat_session', chat_session_id=cs_id, for_redirect=True))
case 'chat_session_interactions':
- return redirect(prefixed_url_for('interaction_bp.session_interactions', chat_session_id=cs_id))
+ return redirect(prefixed_url_for('interaction_bp.session_interactions', chat_session_id=cs_id, for_redirect=True))
# Add more conditions for other actions
- return redirect(prefixed_url_for('interaction_bp.chat_sessions'))
+ return redirect(prefixed_url_for('interaction_bp.chat_sessions', for_redirect=True))
@interaction_bp.route('/view_chat_session/', methods=['GET'])
@@ -184,7 +184,7 @@ def specialist():
# Initialize the newly create specialist
SpecialistServices.initialize_specialist(new_specialist.id, new_specialist.type, new_specialist.type_version)
- return redirect(prefixed_url_for('interaction_bp.edit_specialist', specialist_id=new_specialist.id))
+ return redirect(prefixed_url_for('interaction_bp.edit_specialist', specialist_id=new_specialist.id, for_redirect=True))
except Exception as e:
db.session.rollback()
@@ -257,7 +257,7 @@ def edit_specialist(specialist_id):
db.session.commit()
flash('Specialist updated successfully!', 'success')
current_app.logger.info(f'Specialist {specialist.id} updated successfully')
- return redirect(prefixed_url_for('interaction_bp.specialists'))
+ return redirect(prefixed_url_for('interaction_bp.specialists', for_redirect=True))
except SQLAlchemyError as e:
db.session.rollback()
flash(f'Failed to update specialist. Error: {str(e)}', 'danger')
@@ -297,17 +297,17 @@ def specialists():
def handle_specialist_selection():
action = request.form.get('action')
if action == 'create_specialist':
- return redirect(prefixed_url_for('interaction_bp.specialist'))
+ return redirect(prefixed_url_for('interaction_bp.specialist', for_redirect=True))
specialist_identification = request.form.get('selected_row')
specialist_id = ast.literal_eval(specialist_identification).get('value')
if action == "edit_specialist":
- return redirect(prefixed_url_for('interaction_bp.edit_specialist', specialist_id=specialist_id))
+ return redirect(prefixed_url_for('interaction_bp.edit_specialist', specialist_id=specialist_id, for_redirect=True))
elif action == "execute_specialist":
- return redirect(prefixed_url_for('interaction_bp.execute_specialist', specialist_id=specialist_id))
+ return redirect(prefixed_url_for('interaction_bp.execute_specialist', specialist_id=specialist_id, for_redirect=True))
- return redirect(prefixed_url_for('interaction_bp.specialists'))
+ return redirect(prefixed_url_for('interaction_bp.specialists', for_redirect=True))
# Routes for Agent management ---------------------------------------------------------------------
@@ -442,9 +442,9 @@ def handle_agent_selection():
action = request.form.get('action')
if action == "edit_agent":
- return redirect(prefixed_url_for('interaction_bp.edit_agent', agent_id=agent_id))
+ return redirect(prefixed_url_for('interaction_bp.edit_agent', agent_id=agent_id, for_redirect=True))
- return redirect(prefixed_url_for('interaction_bp.edit_specialist'))
+ return redirect(prefixed_url_for('interaction_bp.edit_specialist', for_redirect=True))
@interaction_bp.route('/handle_task_selection', methods=['POST'])
@@ -455,9 +455,9 @@ def handle_task_selection():
action = request.form.get('action')
if action == "edit_task":
- return redirect(prefixed_url_for('interaction_bp.edit_task', task_id=task_id))
+ return redirect(prefixed_url_for('interaction_bp.edit_task', task_id=task_id, for_redirect=True))
- return redirect(prefixed_url_for('interaction_bp.edit_specialist'))
+ return redirect(prefixed_url_for('interaction_bp.edit_specialist', for_redirect=True))
@interaction_bp.route('/handle_tool_selection', methods=['POST'])
@@ -468,9 +468,9 @@ def handle_tool_selection():
action = request.form.get('action')
if action == "edit_tool":
- return redirect(prefixed_url_for('interaction_bp.edit_tool', tool_id=tool_id))
+ return redirect(prefixed_url_for('interaction_bp.edit_tool', tool_id=tool_id, for_redirect=True))
- return redirect(prefixed_url_for('interaction_bp.edit_specialist'))
+ return redirect(prefixed_url_for('interaction_bp.edit_specialist', for_redirect=True))
# Specialist Execution ----------------------------------------------------------------------------
@@ -481,7 +481,7 @@ def execute_specialist(specialist_id):
if specialist_config.get('chat', True):
flash("Only specialists that don't require interactions can be executed this way!", 'error')
- return redirect(prefixed_url_for('interaction_bp.specialists'))
+ return redirect(prefixed_url_for('interaction_bp.specialists', for_redirect=True))
form = ExecuteSpecialistForm(request.form, obj=specialist)
if 'arguments' in specialist_config:
@@ -498,7 +498,7 @@ def execute_specialist(specialist_id):
session_id=session_id,
user_timezone=session.get('tenant').get('timezone')
)
- return redirect(prefixed_url_for('interaction_bp.session_interactions_by_session_id', session_id=session_id))
+ return redirect(prefixed_url_for('interaction_bp.session_interactions_by_session_id', session_id=session_id, for_redirect=True))
return render_template('interaction/execute_specialist.html', form=form)
@@ -564,7 +564,7 @@ def session_interactions_by_session_id(session_id):
waiting='true'))
# If we've already shown a waiting message and still don't have a session, go back to the specialists page
- return redirect(prefixed_url_for('interaction_bp.specialists'))
+ return redirect(prefixed_url_for('interaction_bp.specialists', for_redirect=True))
@interaction_bp.route('/session_interactions/', methods=['GET'])
@@ -619,7 +619,7 @@ def specialist_magic_link():
f'tenant {tenant_id}!')
return redirect(prefixed_url_for('interaction_bp.edit_specialist_magic_link',
- specialist_magic_link_id=new_specialist_magic_link.id))
+ specialist_magic_link_id=new_specialist_magic_link.id, for_redirect=True))
except Exception as e:
db.session.rollback()
@@ -666,7 +666,7 @@ def edit_specialist_magic_link(specialist_magic_link_id):
db.session.commit()
flash('Specialist Magic Link updated successfully!', 'success')
current_app.logger.info(f'Specialist Magic Link {specialist_ml.id} updated successfully')
- return redirect(prefixed_url_for('interaction_bp.specialist_magic_links'))
+ return redirect(prefixed_url_for('interaction_bp.specialist_magic_links', for_redirect=True))
except SQLAlchemyError as e:
db.session.rollback()
flash(f'Failed to update specialist Magic Link. Error: {str(e)}', 'danger')
@@ -745,19 +745,19 @@ def specialist_magic_links():
def handle_specialist_magic_link_selection():
action = request.form.get('action')
if action == 'create_specialist_magic_link':
- return redirect(prefixed_url_for('interaction_bp.specialist_magic_link'))
+ return redirect(prefixed_url_for('interaction_bp.specialist_magic_link', for_redirect=True))
specialist_ml_identification = request.form.get('selected_row')
specialist_ml_id = ast.literal_eval(specialist_ml_identification).get('value')
if action == "edit_specialist_magic_link":
return redirect(prefixed_url_for('interaction_bp.edit_specialist_magic_link',
- specialist_magic_link_id=specialist_ml_id))
+ specialist_magic_link_id=specialist_ml_id, for_redirect=True))
if action == "view_specialist_magic_link_urls":
return redirect(prefixed_url_for('interaction_bp.view_specialist_magic_link_urls',
- specialist_magic_link_id=specialist_ml_id))
+ specialist_magic_link_id=specialist_ml_id, for_redirect=True))
- return redirect(prefixed_url_for('interaction_bp.specialists'))
+ return redirect(prefixed_url_for('interaction_bp.specialists', for_redirect=True))
# Routes for Asset Management ---------------------------------------------------------------------
@@ -788,13 +788,13 @@ def handle_data_capsule_selection():
match action:
case 'view_data_capsule':
# For now, we'll just redirect to view_data_capsule
- return redirect(prefixed_url_for('interaction_bp.view_data_capsule', data_capsule_id=capsule_id))
+ return redirect(prefixed_url_for('interaction_bp.view_data_capsule', data_capsule_id=capsule_id, for_redirect=True))
case 'view_chat_session':
# Redirect to the chat session
- return redirect(prefixed_url_for('interaction_bp.view_chat_session', chat_session_id=data_capsule.chat_session_id))
+ return redirect(prefixed_url_for('interaction_bp.view_chat_session', chat_session_id=data_capsule.chat_session_id, for_redirect=True))
# Default redirect back to the data capsules list
- return redirect(prefixed_url_for('interaction_bp.eveai_data_capsules'))
+ return redirect(prefixed_url_for('interaction_bp.eveai_data_capsules', for_redirect=True))
@interaction_bp.route('/handle_asset_selection', methods=['POST'])
@@ -804,9 +804,9 @@ def handle_asset_selection():
asset_id = ast.literal_eval(asset_identification).get('value')
if action == 'edit_asset':
- return redirect(prefixed_url_for('interaction_bp.edit_asset', asset_id=asset_id))
+ return redirect(prefixed_url_for('interaction_bp.edit_asset', asset_id=asset_id, for_redirect=True))
- return redirect(prefixed_url_for('interaction_bp.assets'))
+ return redirect(prefixed_url_for('interaction_bp.assets', for_redirect=True))
@interaction_bp.route('/view_data_capsule/', methods=['GET'])
@@ -830,14 +830,14 @@ def edit_asset(asset_id):
if not tenant_id:
flash('Geen tenant geselecteerd', 'error')
- return redirect(url_for('interaction_bp.assets'))
+ return redirect(url_for('interaction_bp.assets', for_redirect=True))
# Controleer of het bestandstype wordt ondersteund
if asset.file_type != 'json':
flash(
f'Bestandstype "{asset.file_type}" wordt momenteel niet ondersteund voor bewerking. Alleen JSON-bestanden kunnen worden bewerkt.',
'warning')
- return redirect(url_for('interaction_bp.assets'))
+ return redirect(url_for('interaction_bp.assets', for_redirect=True))
if request.method == 'GET':
try:
@@ -861,11 +861,11 @@ def edit_asset(asset_id):
except json.JSONDecodeError:
flash('Fout bij het laden van het JSON-bestand: ongeldig JSON-formaat', 'error')
- return redirect(prefixed_url_for('interaction_bp.assets'))
+ return redirect(prefixed_url_for('interaction_bp.assets', for_redirect=True))
except Exception as e:
current_app.logger.error(f"Error loading asset {asset_id}: {str(e)}")
flash(f'Fout bij het laden van het asset: {str(e)}', 'error')
- return redirect(prefixed_url_for('interaction_bp.assets'))
+ return redirect(prefixed_url_for('interaction_bp.assets', for_redirect=True))
elif request.method == 'POST':
try:
@@ -877,14 +877,14 @@ def edit_asset(asset_id):
if not json_data:
current_app.logger.error(f"No JSON data received for asset {asset_id}")
flash('Geen JSON data ontvangen', 'error')
- return redirect(prefixed_url_for('interaction_bp.edit_asset', asset_id=asset_id))
+ return redirect(prefixed_url_for('interaction_bp.edit_asset', asset_id=asset_id, for_redirect=True))
# Valideer JSON formaat
try:
parsed_json = json.loads(json_data)
except json.JSONDecodeError as e:
flash(f'Ongeldig JSON-formaat: {str(e)}', 'error')
- return redirect(prefixed_url_for('interaction_bp.edit_asset', asset_id=asset_id))
+ return redirect(prefixed_url_for('interaction_bp.edit_asset', asset_id=asset_id, for_redirect=True))
# Upload de bijgewerkte JSON naar MinIO
bucket_name, object_name, file_size = minio_client.upload_asset_file(
@@ -904,10 +904,10 @@ def edit_asset(asset_id):
db.session.commit()
flash('Asset succesvol bijgewerkt', 'success')
- return redirect(prefixed_url_for('interaction_bp.assets'))
+ return redirect(prefixed_url_for('interaction_bp.assets', for_redirect=True))
except Exception as e:
db.session.rollback()
current_app.logger.error(f"Error saving asset {asset_id}: {str(e)}")
flash(f'Fout bij het opslaan van het asset: {str(e)}', 'error')
- return redirect(prefixed_url_for('interaction_bp.edit_asset', asset_id=asset_id))
+ return redirect(prefixed_url_for('interaction_bp.edit_asset', asset_id=asset_id, for_redirect=True))
diff --git a/eveai_app/views/partner_views.py b/eveai_app/views/partner_views.py
index a49e322..d558ce0 100644
--- a/eveai_app/views/partner_views.py
+++ b/eveai_app/views/partner_views.py
@@ -44,7 +44,7 @@ def handle_trigger_action():
current_app.logger.error(f"Failed to trigger usage update task: {str(e)}")
flash(f'Failed to trigger usage update: {str(e)}', 'danger')
- return redirect(prefixed_url_for('partner_bp.trigger_actions'))
+ return redirect(prefixed_url_for('partner_bp.trigger_actions', for_redirect=True))
# Partner Management ------------------------------------------------------------------------------
@@ -67,7 +67,7 @@ def edit_partner(partner_id):
refresh_session_partner(partner.id)
return redirect(
prefixed_url_for('partner_bp.edit_partner',
- partner_id=partner.id)) # Assuming there's a user profile view to redirect to
+ partner_id=partner.id, for_redirect=True)) # Assuming there's a user profile view to redirect to
else:
form_validation_failed(request, form)
@@ -88,11 +88,11 @@ def handle_partner_selection():
if action == 'create_partner':
try:
partner_id = register_partner_from_tenant(session['tenant']['id'])
- return redirect(prefixed_url_for('partner_bp.edit_partner', partner_id=partner_id, ))
+ return redirect(prefixed_url_for('partner_bp.edit_partner', partner_id=partner_id, for_redirect=True ))
except EveAIException as e:
current_app.logger.error(f'Error registering partner for tenant {session['tenant']['id']}: {str(e)}')
flash('Error Registering Partner for Selected Tenant', 'danger')
- return redirect(prefixed_url_for('partner_bp.partners'))
+ return redirect(prefixed_url_for('partner_bp.partners', for_redirect=True))
partner_identification = request.form.get('selected_row')
partner_id = ast.literal_eval(partner_identification).get('value')
partner = Partner.query.get_or_404(partner_id)
@@ -101,9 +101,9 @@ def handle_partner_selection():
current_app.logger.info(f"Setting session partner: {partner.id}")
session['partner'] = partner.to_dict()
elif action == 'edit_partner':
- return redirect(prefixed_url_for('partner_bp.edit_partner', partner_id=partner_id))
+ return redirect(prefixed_url_for('partner_bp.edit_partner', partner_id=partner_id, for_redirect=True))
- return redirect(prefixed_url_for('partner_bp.partners'))
+ return redirect(prefixed_url_for('partner_bp.partners', for_redirect=True))
# Partner Servide Management ----------------------------------------------------------------------
@@ -116,7 +116,7 @@ def partner_service():
partner = session.get('partner', None)
if not partner:
flash('No partner has been selected. Set partner before adding services.', 'warning')
- return redirect(prefixed_url_for('partner_bp.partners'))
+ return redirect(prefixed_url_for('partner_bp.partners', for_redirect=True))
partner_id = partner['id']
new_partner_service = PartnerService()
form.populate_obj(new_partner_service)
@@ -130,7 +130,7 @@ def partner_service():
current_app.logger.info(f"Partner Service {new_partner_service.name} added successfully for {partner_id}")
# Step 2 of the creation process (depending on type)
return redirect(prefixed_url_for('partner_bp.partner_service',
- partner_service_id=new_partner_service.id))
+ partner_service_id=new_partner_service.id, for_redirect=True))
except SQLAlchemyError as e:
db.session.rollback()
flash(f'Failed to add Partner Service: {str(e)}', 'danger')
@@ -172,7 +172,7 @@ def edit_partner_service(partner_service_id):
return render_template('partner/edit_partner_service.html', form=form,
partner_service_id=partner_service_id)
- return redirect(prefixed_url_for('partner_bp.partner_services'))
+ return redirect(prefixed_url_for('partner_bp.partner_services', for_redirect=True))
else:
form_validation_failed(request, form)
@@ -186,7 +186,7 @@ def partner_services():
partner = session.get('partner', None)
if not partner:
flash('No partner has been selected. Set partner before adding services.', 'warning')
- return redirect(prefixed_url_for('partner_bp.partners'))
+ return redirect(prefixed_url_for('partner_bp.partners', for_redirect=True))
partner_id = session['partner']['id']
config = get_partner_services_list_view(partner_id)
@@ -198,20 +198,20 @@ def partner_services():
def handle_partner_service_selection():
action = request.form['action']
if action == 'create_partner_service':
- return redirect(prefixed_url_for('partner_bp.partner_service'))
+ return redirect(prefixed_url_for('partner_bp.partner_service', for_redirect=True))
partner_service_identification = request.form.get('selected_row')
partner_service_id = ast.literal_eval(partner_service_identification).get('value')
if action == 'edit_partner_service':
return redirect(prefixed_url_for('partner_bp.edit_partner_service',
- partner_service_id=partner_service_id))
+ partner_service_id=partner_service_id, for_redirect=True))
elif action == 'add_partner_service_for_tenant':
add_partner_service_for_tenant(partner_service_id)
return redirect(prefixed_url_for('partner_bp.edit_partner_service',
- partner_service_id=partner_service_id))
+ partner_service_id=partner_service_id, for_redirect=True))
- return redirect(prefixed_url_for('partner_bp.partner_services'))
+ return redirect(prefixed_url_for('partner_bp.partner_services', for_redirect=True))
# Utility Functions
@@ -248,7 +248,7 @@ def add_partner_service_for_tenant(partner_service_id):
tenant = session.get('tenant', None)
if not tenant:
flash('No tenant has been selected. Set tenant before adding services.', 'warning')
- return redirect(prefixed_url_for('user_bp.tenants'))
+ return redirect(prefixed_url_for('user_bp.tenants', for_redirect=True))
tenant_id = tenant['id']
@@ -257,7 +257,7 @@ def add_partner_service_for_tenant(partner_service_id):
partner_service = PartnerService.query.get(partner_service_id)
if not partner_service:
flash(f'Partner service with ID {partner_service_id} not found.', 'danger')
- return redirect(prefixed_url_for('partner_bp.partner_services'))
+ return redirect(prefixed_url_for('partner_bp.partner_services', for_redirect=True))
# Check if the association already exists
existing = PartnerTenant.query.filter_by(
@@ -267,7 +267,7 @@ def add_partner_service_for_tenant(partner_service_id):
if existing:
flash(f'This tenant already has access to this partner service.', 'warning')
- return redirect(prefixed_url_for('partner_bp.partner_services'))
+ return redirect(prefixed_url_for('partner_bp.partner_services', for_redirect=True))
# Create new association
new_partner_tenant = PartnerTenant(
@@ -289,13 +289,13 @@ def add_partner_service_for_tenant(partner_service_id):
partner_name = partner_tenant.name if partner_tenant else 'Unknown Partner'
flash(f'Successfully added {partner_service.type} service from {partner_name} to this tenant.', 'success')
- return redirect(prefixed_url_for('partner_bp.partner_services'))
+ return redirect(prefixed_url_for('partner_bp.partner_services', for_redirect=True))
except SQLAlchemyError as e:
db.session.rollback()
current_app.logger.error(f"Database error adding partner service: {str(e)}")
flash(f'Error adding partner service: {str(e)}', 'danger')
- return redirect(prefixed_url_for('partner_bp.partner_services'))
+ return redirect(prefixed_url_for('partner_bp.partner_services', for_redirect=True))
def refresh_session_partner(partner_id):
diff --git a/eveai_app/views/security_views.py b/eveai_app/views/security_views.py
index 66f2739..9d2264c 100644
--- a/eveai_app/views/security_views.py
+++ b/eveai_app/views/security_views.py
@@ -34,7 +34,7 @@ def log_after_request(response):
@security_bp.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
- return redirect(prefixed_url_for('basic_bp.index'))
+ return redirect(prefixed_url_for('basic_bp.index', for_redirect=True))
form = LoginForm()
@@ -55,9 +55,9 @@ def login():
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.tenants'))
+ return redirect(prefixed_url_for('user_bp.tenants', for_redirect=True))
else:
- return redirect(prefixed_url_for('user_bp.tenant_overview'))
+ return redirect(prefixed_url_for('user_bp.tenant_overview', for_redirect=True))
else:
flash('Invalid username or password', 'danger')
current_app.logger.error(f'Invalid username or password for given email: {user.email}')
@@ -68,7 +68,7 @@ def login():
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'))
+ return redirect(prefixed_url_for('security_bp.login', for_redirect=True))
if request.method == 'GET':
csrf_token = generate_csrf()
@@ -80,7 +80,7 @@ def login():
@login_required
def logout():
logout_user()
- return redirect(prefixed_url_for('basic_bp.index'))
+ return redirect(prefixed_url_for('basic_bp.index', for_redirect=True))
@security_bp.route('/confirm_email/', methods=['GET', 'POST'])
@@ -89,12 +89,12 @@ def confirm_email(token):
email = confirm_token(token)
except Exception as e:
flash('The confirmation link is invalid or has expired.', 'danger')
- return redirect(prefixed_url_for('basic_bp.confirm_email_fail'))
+ return redirect(prefixed_url_for('basic_bp.confirm_email_fail', for_redirect=True))
user = User.query.filter_by(email=email).first_or_404()
if user.active:
flash('Account already confirmed. Please login.', 'success')
- return redirect(prefixed_url_for('security_bp.login'))
+ return redirect(prefixed_url_for('security_bp.login', for_redirect=True))
else:
user.active = True
user.updated_at = dt.now(tz.utc)
@@ -105,10 +105,10 @@ def confirm_email(token):
db.session.commit()
except SQLAlchemyError as e:
db.session.rollback()
- return redirect(prefixed_url_for('basic_bp.confirm_email_fail'))
+ return redirect(prefixed_url_for('basic_bp.confirm_email_fail', for_redirect=True))
send_reset_email(user)
- return redirect(prefixed_url_for('basic_bp.confirm_email_ok'))
+ return redirect(prefixed_url_for('basic_bp.confirm_email_ok', for_redirect=True))
@security_bp.route('/forgot_password', methods=['GET', 'POST'])
@@ -119,7 +119,7 @@ def forgot_password():
if user:
send_reset_email(user)
flash('An email with instructions to reset your password has been sent.', 'info')
- return redirect(prefixed_url_for('security_bp.login'))
+ return redirect(prefixed_url_for('security_bp.login', for_redirect=True))
return render_template('security/forgot_password.html', form=form)
@@ -130,7 +130,7 @@ def reset_password(token):
except Exception as e:
flash('The reset link is invalid or has expired.', 'danger')
current_app.logger.error(f'Invalid reset link detected: {token} - error: {e}')
- return redirect(prefixed_url_for('security_bp.reset_password_request'))
+ return redirect(prefixed_url_for('security_bp.reset_password_request', for_redirect=True))
user = User.query.filter_by(email=email).first_or_404()
form = ResetPasswordForm()
@@ -139,7 +139,7 @@ def reset_password(token):
user.updated_at = dt.now(tz.utc)
db.session.commit()
flash('Your password has been updated.', 'success')
- return redirect(prefixed_url_for('security_bp.login'))
+ return redirect(prefixed_url_for('security_bp.login', for_redirect=True))
return render_template('security/reset_password.html', reset_password_form=form)
diff --git a/eveai_app/views/user_views.py b/eveai_app/views/user_views.py
index 0486ab4..64407bb 100644
--- a/eveai_app/views/user_views.py
+++ b/eveai_app/views/user_views.py
@@ -48,7 +48,7 @@ def tenant():
if not UserServices.can_user_create_tenant():
current_app.logger.error(f'User {current_user.email} cannot create tenant')
flash(f"You don't have the appropriate permissions to create a tenant", 'danger')
- return redirect(prefixed_url_for('user_bp.tenants'))
+ return redirect(prefixed_url_for('user_bp.tenants', for_redirect=True))
form = TenantForm()
if request.method == 'GET':
code = f"TENANT-{str(uuid.uuid4())}"
@@ -107,7 +107,7 @@ def tenant():
current_app.logger.info(f"Creating MinIO bucket for tenant {new_tenant.id}")
minio_client.create_tenant_bucket(new_tenant.id)
- return redirect(prefixed_url_for('user_bp.tenants'))
+ return redirect(prefixed_url_for('user_bp.tenants', for_redirect=True))
else:
form_validation_failed(request, form)
@@ -155,14 +155,14 @@ def tenants():
def handle_tenant_selection():
action = request.form['action']
if action == 'create_tenant':
- return redirect(prefixed_url_for('user_bp.tenant'))
+ return redirect(prefixed_url_for('user_bp.tenant', for_redirect=True))
tenant_identification = request.form['selected_row']
tenant_id = ast.literal_eval(tenant_identification).get('value')
if not UserServices.can_user_edit_tenant(tenant_id):
current_app.logger.info(f"User not authenticated to edit tenant {tenant_id}.")
flash(f"You are not authenticated to manage tenant {tenant_id}", 'danger')
- return redirect(prefixed_url_for('user_bp.tenants'))
+ return redirect(prefixed_url_for('user_bp.tenants', for_redirect=True))
the_tenant = Tenant.query.get(tenant_id)
# set tenant information in the session
@@ -173,12 +173,12 @@ def handle_tenant_selection():
match action:
case 'edit_tenant':
- return redirect(prefixed_url_for('user_bp.edit_tenant', tenant_id=tenant_id))
+ return redirect(prefixed_url_for('user_bp.edit_tenant', tenant_id=tenant_id, for_redirect=True))
case 'select_tenant':
- return redirect(prefixed_url_for('user_bp.tenant_overview'))
+ return redirect(prefixed_url_for('user_bp.tenant_overview', for_redirect=True))
# Add more conditions for other actions
- return redirect(prefixed_url_for('tenants'))
+ return redirect(prefixed_url_for('tenants', for_redirect=True))
@user_bp.route('/tenant_overview', methods=['GET'])
@@ -244,7 +244,7 @@ def user():
flash('User added successfully, but failed to send confirmation email. '
'Please contact the administrator.', 'warning')
- return redirect(prefixed_url_for('user_bp.view_users'))
+ return redirect(prefixed_url_for('user_bp.view_users', for_redirect=True))
except Exception as e:
current_app.logger.error(f'Failed to add user with name {new_user.user_name}. Error: {str(e)}')
db.session.rollback()
@@ -286,13 +286,13 @@ def edit_user(user_id):
flash('Trying to assign unauthorized roles', 'danger')
current_app.logger.error(f"Trying to assign unauthorized roles by user {user_id},"
f"tenant {session['tenant']['id']}")
- return redirect(prefixed_url_for('user_bp.edit_user', user_id=user_id))
+ return redirect(prefixed_url_for('user_bp.edit_user', user_id=user_id, for_redirect=True))
db.session.commit()
flash('User updated successfully.', 'success')
return redirect(
prefixed_url_for('user_bp.edit_user',
- user_id=user.id)) # Assuming there's a user profile view to redirect to
+ user_id=user.id, for_redirect=True)) # Assuming there's a user profile view to redirect to
else:
form_validation_failed(request, form)
@@ -314,14 +314,14 @@ def view_users():
def handle_user_action():
action = request.form['action']
if action == 'create_user':
- return redirect(prefixed_url_for('user_bp.user'))
+ return redirect(prefixed_url_for('user_bp.user', for_redirect=True))
user_identification = request.form['selected_row']
user_id = ast.literal_eval(user_identification).get('value')
user = User.query.get_or_404(user_id)
if action == 'edit_user':
- return redirect(prefixed_url_for('user_bp.edit_user', user_id=user_id))
+ return redirect(prefixed_url_for('user_bp.edit_user', user_id=user_id, for_redirect=True))
elif action == 'resend_confirmation_email':
send_confirmation_email(user)
flash(f'Confirmation email sent to {user.email}.', 'success')
@@ -332,7 +332,7 @@ def handle_user_action():
reset_uniquifier(user)
flash(f'Uniquifier reset for {user.user_name}.', 'success')
- return redirect(prefixed_url_for('user_bp.view_users'))
+ return redirect(prefixed_url_for('user_bp.view_users', for_redirect=True))
# Tenant Domain Management (Probably obsolete )------------------------------------------------------------------------
@@ -349,15 +349,15 @@ def tenant_domains():
def handle_tenant_domain_action():
action = request.form['action']
if action == 'create_tenant_domain':
- return redirect(prefixed_url_for('user_bp.tenant_domain'))
+ return redirect(prefixed_url_for('user_bp.tenant_domain', for_redirect=True))
tenant_domain_identification = request.form['selected_row']
tenant_domain_id = ast.literal_eval(tenant_domain_identification).get('value')
if action == 'edit_tenant_domain':
- return redirect(prefixed_url_for('user_bp.edit_tenant_domain', tenant_domain_id=tenant_domain_id))
+ return redirect(prefixed_url_for('user_bp.edit_tenant_domain', tenant_domain_id=tenant_domain_id, for_redirect=True))
# Add more conditions for other actions
- return redirect(prefixed_url_for('tenant_domains'))
+ return redirect(prefixed_url_for('tenant_domains', for_redirect=True))
@user_bp.route('/tenant_domain', methods=['GET', 'POST'])
@@ -410,7 +410,7 @@ def edit_tenant_domain(tenant_domain_id):
f'Error: {str(e)}')
return redirect(
prefixed_url_for('user_bp.tenant_domains',
- tenant_id=session['tenant']['id'])) # Assuming there's a user profile view to redirect to
+ tenant_id=session['tenant']['id'], for_redirect=True)) # Assuming there's a user profile view to redirect to
else:
form_validation_failed(request, form)
@@ -461,7 +461,7 @@ def tenant_project():
current_app.logger.info(f'Tenant Project {new_tenant_project.name} added for tenant '
f'{session['tenant']['id']}.')
- return redirect(prefixed_url_for('user_bp.tenant_projects'))
+ return redirect(prefixed_url_for('user_bp.tenant_projects', for_redirect=True))
except SQLAlchemyError as e:
db.session.rollback()
flash(f'Failed to create Tenant Project. Error: {str(e)}', 'danger')
@@ -484,13 +484,13 @@ def tenant_projects():
def handle_tenant_project_selection():
action = request.form.get('action')
if action == 'create_tenant_project':
- return redirect(prefixed_url_for('user_bp.tenant_project'))
+ return redirect(prefixed_url_for('user_bp.tenant_project', for_redirect=True))
tenant_project_identification = request.form.get('selected_row')
tenant_project_id = ast.literal_eval(tenant_project_identification).get('value')
tenant_project = TenantProject.query.get_or_404(tenant_project_id)
if action == 'edit_tenant_project':
- return redirect(prefixed_url_for('user_bp.edit_tenant_project', tenant_project_id=tenant_project_id))
+ return redirect(prefixed_url_for('user_bp.edit_tenant_project', tenant_project_id=tenant_project_id, for_redirect=True))
elif action == 'invalidate_tenant_project':
tenant_project.active = False
try:
@@ -505,9 +505,9 @@ def handle_tenant_project_selection():
current_app.logger.error(f"Failed to invalidate Tenant Project for tenant {session['tenant']['id']}. "
f"Error: {str(e)}")
elif action == 'delete_tenant_project':
- return redirect(prefixed_url_for('user_bp.delete_tenant_project', tenant_project_id=tenant_project_id))
+ return redirect(prefixed_url_for('user_bp.delete_tenant_project', tenant_project_id=tenant_project_id, for_redirect=True))
- return redirect(prefixed_url_for('user_bp.tenant_projects'))
+ return redirect(prefixed_url_for('user_bp.tenant_projects', for_redirect=True))
@user_bp.route('/tenant_project/', methods=['GET', 'POST'])
@@ -527,7 +527,7 @@ def edit_tenant_project(tenant_project_id):
db.session.commit()
flash('Tenant Project updated successfully.', 'success')
current_app.logger.info(f'Tenant Project {tenant_project.name} updated for tenant {tenant_id}.')
- return redirect(prefixed_url_for('user_bp.tenant_projects'))
+ return redirect(prefixed_url_for('user_bp.tenant_projects', for_redirect=True))
except SQLAlchemyError as e:
db.session.rollback()
flash(f'Failed to update Tenant Project. Error: {str(e)}', 'danger')
@@ -545,7 +545,7 @@ def delete_tenant_project(tenant_project_id):
# Ensure project belongs to current tenant
if tenant_project.tenant_id != tenant_id:
flash('You do not have permission to delete this project.', 'danger')
- return redirect(prefixed_url_for('user_bp.tenant_projects'))
+ return redirect(prefixed_url_for('user_bp.tenant_projects', for_redirect=True))
if request.method == 'GET':
return render_template('user/confirm_delete_tenant_project.html',
@@ -562,7 +562,7 @@ def delete_tenant_project(tenant_project_id):
flash(f'Failed to delete Tenant Project. Error: {str(e)}', 'danger')
current_app.logger.error(f'Failed to delete Tenant Project {tenant_project_id}. Error: {str(e)}')
- return redirect(prefixed_url_for('user_bp.tenant_projects'))
+ return redirect(prefixed_url_for('user_bp.tenant_projects', for_redirect=True))
# Tenant Make Management --------------------------------------------------------------------------
@@ -589,7 +589,7 @@ def tenant_make():
current_app.logger.info(f'Tenant Make {new_tenant_make.name}, id {new_tenant_make.id} successfully added '
f'for tenant {tenant_id}!')
# Enable step 2 of creation of retriever - add configuration of the retriever (dependent on type)
- return redirect(prefixed_url_for('user_bp.edit_tenant_make', tenant_make_id=new_tenant_make.id))
+ return redirect(prefixed_url_for('user_bp.edit_tenant_make', tenant_make_id=new_tenant_make.id, for_redirect=True))
except SQLAlchemyError as e:
db.session.rollback()
flash(f'Failed to add Tenant Make. Error: {e}', 'danger')
@@ -647,7 +647,7 @@ def edit_tenant_make(tenant_make_id):
current_app.logger.error(f'Failed to update tenant make {tenant_make_id}. Error: {str(e)}')
return render_template('user/edit_tenant_make.html', form=form, tenant_make_id=tenant_make_id)
- return redirect(prefixed_url_for('user_bp.tenant_makes'))
+ return redirect(prefixed_url_for('user_bp.tenant_makes', for_redirect=True))
else:
form_validation_failed(request, form)
@@ -659,12 +659,12 @@ def edit_tenant_make(tenant_make_id):
def handle_tenant_make_selection():
action = request.form['action']
if action == 'create_tenant_make':
- return redirect(prefixed_url_for('user_bp.tenant_make'))
+ return redirect(prefixed_url_for('user_bp.tenant_make', for_redirect=True))
tenant_make_identification = request.form.get('selected_row')
tenant_make_id = ast.literal_eval(tenant_make_identification).get('value')
if action == 'edit_tenant_make':
- return redirect(prefixed_url_for('user_bp.edit_tenant_make', tenant_make_id=tenant_make_id))
+ return redirect(prefixed_url_for('user_bp.edit_tenant_make', tenant_make_id=tenant_make_id, for_redirect=True))
elif action == 'set_as_default':
# Set this make as the default for the tenant
tenant_id = session['tenant']['id']
@@ -682,7 +682,7 @@ def handle_tenant_make_selection():
current_app.logger.error(f'Failed to update default tenant make. Error: {str(e)}')
# Altijd teruggaan naar de tenant_makes pagina
- return redirect(prefixed_url_for('user_bp.tenant_makes'))
+ return redirect(prefixed_url_for('user_bp.tenant_makes', for_redirect=True))
@user_bp.route('/tenant_partner_services', methods=['GET', 'POST'])
diff --git a/nginx/nginx.conf b/nginx/nginx.conf
index 4155747..7910c32 100644
--- a/nginx/nginx.conf
+++ b/nginx/nginx.conf
@@ -57,9 +57,6 @@ http {
index index.html index.htm;
}
- location /reset {
- rewrite ^/reset(.*)$ /admin/reset$1 permanent;
- }
location /static/ {
alias /etc/nginx/static/;
@@ -100,17 +97,10 @@ http {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
- proxy_set_header X-Forwarded-Prefix /chat-client;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
-
- # Add CORS headers
- add_header 'Access-Control-Allow-Origin' '*' always;
- add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
- add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization' always;
- add_header 'Access-Control-Allow-Credentials' 'true' always;
}
location /admin/ {
@@ -122,7 +112,6 @@ http {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
- proxy_set_header X-Forwarded-Prefix /admin; # Required for Flask views (used in nginx_utils
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
@@ -140,60 +129,14 @@ http {
proxy_send_timeout 60s;
proxy_read_timeout 60s;
send_timeout 60s;
-
- # Subfilter to hide admin prefix from app
- sub_filter_once off;
- sub_filter_types text/html text/css application/javascript;
-
- # General HTML sub_filters
- sub_filter 'href="/static/' 'href="/static/';
- sub_filter 'src="/static/' 'src="/static/';
- sub_filter 'url("/static/' 'url("/static/';
- sub_filter 'href="/' 'href="/admin/'; # Rewrites for other content
- sub_filter 'src="/' 'src="/admin/';
- sub_filter 'action="/' 'action="/admin/';
- sub_filter 'url("/' 'url("/admin/';
-
- # Sub_filters for JavaScript URLs
- sub_filter 'url: "/' 'url: "/admin/';
- sub_filter 'url: \"/' 'url: "/admin/';
- sub_filter 'url("/' 'url("/admin/';
- sub_filter 'url(\\"/' 'url("/admin/';
-
- # Sub_filters for AJAX requests
- sub_filter 'url: \'/user/' 'url: \'/admin/user/';
- sub_filter 'url: "/user/' 'url: "/admin/user/';
- sub_filter 'url: "/api/' 'url: "/admin/api/';
- sub_filter 'url: \'/api/' 'url: \'/admin/api/';
-
}
location /api/ {
- # Handle preflight requests
- if ($request_method = 'OPTIONS') {
- add_header 'Access-Control-Allow-Origin' $http_origin always;
- add_header 'Access-Control-Allow-Credentials' 'true' always;
- add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
- add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
- add_header 'Access-Control-Max-Age' 1728000;
- add_header 'Content-Type' 'text/plain charset=UTF-8';
- add_header 'Content-Length' 0;
- return 204;
- }
- # Mirror the Origin header if it's allowed by the application
- # The application will handle the actual origin validation
- add_header 'Access-Control-Allow-Origin' $http_origin always;
- add_header 'Access-Control-Allow-Credentials' 'true' always;
- add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
- add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
- add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
-
proxy_pass http://eveai_api:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
- proxy_set_header X-Forwarded-Prefix /api;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
diff --git a/scaleway/manifests/base/networking/README-ROUTING.md b/scaleway/manifests/base/networking/README-ROUTING.md
new file mode 100644
index 0000000..96f228c
--- /dev/null
+++ b/scaleway/manifests/base/networking/README-ROUTING.md
@@ -0,0 +1,23 @@
+Routing alignment notes (staging/prod)
+
+Summary
+- Root (/) issues a 301 redirect to /admin/ via server-snippet on the apps ingress.
+- Prefixes /admin, /api, /chat-client are stripped at the edge and forwarded to their backends on /. The applications do not need to be prefix-aware.
+- /verify remains available (Prefix) without any rewrite in a separate Ingress.
+- No CORS annotations at ingress. Static assets are served by Bunny CDN; API CORS is not handled here.
+- /flower is intentionally NOT exposed on k8s.
+
+Files
+- ingress-https.yaml: NGINX Ingress (apps) with regex paths and rewrite-target to strip prefixes; includes server-snippet to 301 redirect root to /admin/.
+- ingress-verify.yaml: Separate Ingress for /verify without regex/rewrite.
+
+Paths behavior
+- / -> 301 /admin/
+- /admin/<...> -> eveai-app-service:80, backend receives /<...>
+- /api/<...> -> eveai-api-service:80, backend receives /<...>
+- /chat-client/<...> -> eveai-chat-client-service:80, backend receives /<...>
+- /verify[/**] -> verify-service:80, path preserved.
+
+Notes
+- The rewrite-target is global per Ingress. To avoid affecting /verify, we split it into its own Ingress. Keep this structure when adding/removing services.
+- If you need temporary legacy redirects (e.g., /client -> /chat-client), add an additional Ingress with nginx.ingress.kubernetes.io/permanent-redirect and regex matching, or handle it at the app/CDN layer.
diff --git a/scaleway/manifests/base/networking/ingress-https.yaml b/scaleway/manifests/base/networking/ingress-https.yaml
index d9642b4..f5c0eef 100644
--- a/scaleway/manifests/base/networking/ingress-https.yaml
+++ b/scaleway/manifests/base/networking/ingress-https.yaml
@@ -14,6 +14,12 @@ metadata:
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
cert-manager.io/cluster-issuer: letsencrypt-staging
+ nginx.ingress.kubernetes.io/use-regex: "true"
+ nginx.ingress.kubernetes.io/rewrite-target: "/$2"
+ nginx.ingress.kubernetes.io/server-snippet: |
+ location = / {
+ return 301 /admin/;
+ }
spec:
ingressClassName: nginx
tls:
@@ -24,54 +30,28 @@ spec:
- host: evie-staging.askeveai.com
http:
paths:
- # Verification service paths
- - path: /verify
- pathType: Prefix
- backend:
- service:
- name: verify-service
- port:
- number: 80
-
- # Application services
- - path: /admin
- pathType: Prefix
+ # Application services (strip prefix)
+ - path: /admin(/|$)(.*)
+ pathType: ImplementationSpecific
backend:
service:
name: eveai-app-service
port:
number: 80
- - path: /api
- pathType: Prefix
+ - path: /api(/|$)(.*)
+ pathType: ImplementationSpecific
backend:
service:
name: eveai-api-service
port:
number: 80
- - path: /client
- pathType: Prefix
+ - path: /chat-client(/|$)(.*)
+ pathType: ImplementationSpecific
backend:
service:
name: eveai-chat-client-service
port:
number: 80
-
- # Monitoring (when deployed)
- # - path: /monitoring
- # pathType: Prefix
- # backend:
- # service:
- # name: monitoring-grafana
- # port:
- # number: 80
-
- # Default: root path to verification service
- - path: /
- pathType: Prefix
- backend:
- service:
- name: verify-service
- port:
- number: 80
\ No newline at end of file
+
\ No newline at end of file
diff --git a/scaleway/manifests/base/networking/ingress-verify.yaml b/scaleway/manifests/base/networking/ingress-verify.yaml
new file mode 100644
index 0000000..62bd60a
--- /dev/null
+++ b/scaleway/manifests/base/networking/ingress-verify.yaml
@@ -0,0 +1,32 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: eveai-staging-ingress-verify
+ namespace: eveai-staging
+ labels:
+ app: eveai
+ environment: staging
+ annotations:
+ kubernetes.io/ingress.class: nginx
+ nginx.ingress.kubernetes.io/ssl-redirect: "true"
+ nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
+ nginx.ingress.kubernetes.io/proxy-body-size: "10m"
+ nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
+ cert-manager.io/cluster-issuer: letsencrypt-staging
+spec:
+ ingressClassName: nginx
+ tls:
+ - hosts:
+ - evie-staging.askeveai.com
+ secretName: evie-staging-tls
+ rules:
+ - host: evie-staging.askeveai.com
+ http:
+ paths:
+ - path: /verify
+ pathType: Prefix
+ backend:
+ service:
+ name: verify-service
+ port:
+ number: 80