- 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:
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
@@ -481,3 +504,7 @@ def is_file_type_supported_by_catalog(catalog_id, file_type):
|
|||||||
|
|
||||||
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}/"
|
||||||
@@ -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 %}
|
||||||
|
|
||||||
|
|||||||
@@ -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')
|
||||||
|
|||||||
@@ -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 = []
|
||||||
|
|||||||
Reference in New Issue
Block a user