- Correction in the tenant_list_view to only show 'partner tenants' in case the user is a partner admin.

- Edit Partner can only be executed by Super User
- Give a more precise error message when a 403 client error is returned trying to get a URL.
This commit is contained in:
Josako
2025-07-22 15:44:39 +02:00
parent a0f806ba4e
commit dc6cd9d940
5 changed files with 97 additions and 9 deletions

View File

@@ -1,4 +1,4 @@
from typing import List from typing import List, Dict, Any
from flask import session from flask import session
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
@@ -43,5 +43,11 @@ class PartnerServices:
return license_tier_ids return license_tier_ids
@staticmethod
def get_management_service() -> Dict[str, Any]:
management_service = next((service for service in session['partner']['services']
if service.get('type') == 'MANAGEMENT_SERVICE'), None)
return management_service

View File

@@ -192,9 +192,32 @@ def process_url(url, tenant_id):
existing_doc = DocumentVersion.query.filter_by(url=url).first() existing_doc = DocumentVersion.query.filter_by(url=url).first()
if existing_doc: if existing_doc:
raise EveAIDoubleURLException raise EveAIDoubleURLException
# Prepare the headers for maximal chance of downloading url
referer = get_referer_from_url(url)
headers = {
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/115.0.0.0 Safari/537.36"
),
"Accept": (
"text/html,application/xhtml+xml,application/xml;"
"q=0.9,image/avif,image/webp,image/apng,*/*;"
"q=0.8,application/signed-exchange;v=b3;q=0.7"
),
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "nl-BE,nl;q=0.9,en-US;q=0.8,en;q=0.7",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Referer": referer,
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-User": "?1",
}
# Download the content # Download the content
response = requests.get(url) response = requests.get(url, headers=headers)
response.raise_for_status() response.raise_for_status()
file_content = response.content file_content = response.content
@@ -480,4 +503,8 @@ def is_file_type_supported_by_catalog(catalog_id, file_type):
supported_file_types.extend(file_types) supported_file_types.extend(file_types)
if file_type not in supported_file_types: if file_type not in supported_file_types:
raise EveAIUnsupportedFileType() raise EveAIUnsupportedFileType()
def get_referer_from_url(url):
parsed = urlparse(url)
return f"{parsed.scheme}://{parsed.netloc}/"

View File

@@ -86,7 +86,7 @@
{% if 'partner' in session and session['partner'] %} {% if 'partner' in session and session['partner'] %}
{% set partner_menu_items = partner_menu_items + [ {% set partner_menu_items = partner_menu_items + [
{'name': 'Edit Partner', 'url': '/partner/partner/' ~ session['partner'].get('id'), 'roles': ['Super User', 'Partner Admin']} {'name': 'Edit Partner', 'url': '/partner/partner/' ~ session['partner'].get('id'), 'roles': ['Super User']}
] %} ] %}
{% endif %} {% endif %}

View File

@@ -8,7 +8,7 @@ from sqlalchemy.orm import aliased
from werkzeug.utils import secure_filename from werkzeug.utils import secure_filename
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
import requests import requests
from requests.exceptions import SSLError from requests.exceptions import SSLError, HTTPError
import json import json
from common.models.document import Document, DocumentVersion, Catalog, Retriever, Processor from common.models.document import Document, DocumentVersion, Catalog, Retriever, Processor
@@ -416,7 +416,7 @@ def add_url():
catalog = Catalog.query.get_or_404(catalog_id) catalog = Catalog.query.get_or_404(catalog_id)
if catalog.configuration and len(catalog.configuration) > 0: if catalog.configuration and len(catalog.configuration) > 0:
form.add_dynamic_fields("tagging_fields", catalog.configuration) form.add_dynamic_fields("tagging_fields", catalog.configuration)
url=""
if form.validate_on_submit(): if form.validate_on_submit():
try: try:
tenant_id = session['tenant']['id'] tenant_id = session['tenant']['id']
@@ -456,6 +456,9 @@ def add_url():
except EveAIException as e: except EveAIException as e:
current_app.logger.error(f"Error adding document: {str(e)}") current_app.logger.error(f"Error adding document: {str(e)}")
flash(str(e), 'danger') flash(str(e), 'danger')
except HTTPError as e:
current_app.logger.error(f"Server refused download for {url}: {str(e)}")
flash(f'Server refused download for {url}: {str(e)}', 'danger')
except Exception as e: except Exception as e:
current_app.logger.error(f'Error adding document: {str(e)}') current_app.logger.error(f'Error adding document: {str(e)}')
flash('An error occurred while adding the document.', 'danger') flash('An error occurred while adding the document.', 'danger')

View File

@@ -4,15 +4,67 @@ from sqlalchemy.exc import SQLAlchemyError
import ast import ast
from common.models.user import Tenant, User, TenantDomain, TenantProject, TenantMake, PartnerTenant, PartnerService from common.models.user import Tenant, User, TenantDomain, TenantProject, TenantMake, PartnerTenant, PartnerService
from common.services.user import UserServices from common.services.user import UserServices, PartnerServices
from common.utils.eveai_exceptions import EveAINoSessionPartner, EveAINoManagementPartnerService
from common.utils.security_utils import current_user_has_role
from eveai_app.views.list_views.list_view_utils import render_list_view from eveai_app.views.list_views.list_view_utils import render_list_view
# Tenant list view helper # Tenant list view helper
def get_tenants_list_view(): def get_tenants_list_view():
"""Generate the tenants list view configuration""" """Generate the tenants list view configuration"""
# Get all tenants (no server side filtering - handled client-side) # Get all tenants (no server side filtering - handled client-side)
tenant_query = Tenant.query.order_by(Tenant.id) is_partner_admin = current_user_has_role('Partner Admin')
all_tenants = tenant_query.all() is_super_user = current_user_has_role('Super User')
if is_partner_admin and not is_super_user:
# Partner Admin (not Super User) - filter tenants based on management service + own tenant
try:
partner = session.get('partner')
if not partner:
# No partner in session, return empty list
all_tenants = []
else:
tenant_ids = set()
# Add the partner's own tenant
partner_tenant_id = partner.get('tenant_id')
if partner_tenant_id:
tenant_ids.add(partner_tenant_id)
# Add tenants associated with the management service
management_service = PartnerServices.get_management_service()
if management_service:
management_service_id = management_service['id']
# Get tenant IDs associated with this management service via PartnerTenant
partner_tenants = PartnerTenant.query.filter_by(
partner_service_id=management_service_id
).all()
for pt in partner_tenants:
tenant_ids.add(pt.tenant_id)
# Query for all allowed tenants
if tenant_ids:
tenant_query = Tenant.query.filter(Tenant.id.in_(tenant_ids)).order_by(Tenant.id)
all_tenants = tenant_query.all()
else:
all_tenants = []
except (EveAINoSessionPartner, EveAINoManagementPartnerService):
# No partner in session or no management service
# Still try to get the partner's own tenant if available
try:
partner = session.get('partner')
if partner and partner.get('tenant_id'):
tenant_query = Tenant.query.filter_by(id=partner['tenant_id']).order_by(Tenant.id)
all_tenants = tenant_query.all()
else:
all_tenants = []
except Exception:
all_tenants = []
else:
# Super User or other roles - get all tenants
tenant_query = Tenant.query.order_by(Tenant.id)
all_tenants = tenant_query.all()
# Prepare data for Tabulator # Prepare data for Tabulator
data = [] data = []