databricks-tellr-app 0.4.3.dev3403__tar.gz → 0.4.3.dev3432__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/PKG-INFO +1 -1
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/databricks_tellr_app.egg-info/PKG-INFO +1 -1
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/databricks_tellr_app.egg-info/SOURCES.txt +2 -2
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/pyproject.toml +1 -1
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/design_system_service.py +0 -15
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/identity_provider.py +4 -1
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/identity_providers/account_provider.py +5 -2
- databricks_tellr_app-0.4.3.dev3432/src/services/identity_providers/scim_filter.py +6 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/identity_providers/workspace_provider.py +6 -2
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/image_service.py +0 -15
- databricks_tellr_app-0.4.3.dev3403/src/services/svg_sanitizer.py +0 -414
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/README.md +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/databricks_tellr_app/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/databricks_tellr_app/run.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/databricks_tellr_app.egg-info/dependency_links.txt +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/databricks_tellr_app.egg-info/requires.txt +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/databricks_tellr_app.egg-info/top_level.txt +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/setup.cfg +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/setup.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/_otel_bootstrap.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/fixtures/tour_demo_deck.json +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/main.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/mcp_auth.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/mcp_server.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/middleware/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/middleware/csrf.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/middleware/request_logging.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/middleware/security_headers.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/_authz.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/admin.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/admin_usage.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/agent_config.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/chat.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/deck_contributors.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/export.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/feedback.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/google_slides.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/images.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/local_version.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/profiles.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/sessions.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/settings/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/settings/contributors.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/settings/deck_prompts.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/settings/design_systems.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/settings/identities.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/settings/slide_styles.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/setup.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/slides.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/tools.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/tour.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/verification.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/version.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/schemas/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/schemas/agent_config.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/schemas/feedback.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/schemas/requests.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/schemas/responses.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/schemas/settings/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/schemas/settings/requests.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/schemas/settings/responses.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/schemas/streaming.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/services/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/services/chat_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/services/export_job_queue.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/services/feedback_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/services/job_queue.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/services/session_manager.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/services/session_naming.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/services/usage_events.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/services/usage_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/utils/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/utils/validation.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/core/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/core/config_loader.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/core/context_utils.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/core/database.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/core/databricks_client.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/core/defaults.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/core/encryption.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/core/init_default_profile.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/core/lakebase.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/core/migrate_profiles_to_agent_config.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/core/mlflow_agent_spans.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/core/mlflow_tracing.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/core/otel_logging.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/core/permission_context.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/core/prompt_modules.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/core/settings_db.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/core/user_context.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/models/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/models/deck_contributor.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/models/design_system.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/models/encryption_key.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/models/feedback.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/models/genie_space.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/models/google_global_credentials.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/models/google_oauth_token.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/models/identity.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/models/image.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/models/profile.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/models/profile_contributor.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/models/prompts.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/models/request_log.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/models/session.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/models/slide_deck_prompt.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/models/slide_style_library.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/models/usage_event.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/models/user_preference.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/database/types.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/domain/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/domain/slide.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/domain/slide_deck.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/agent.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/agent_factory.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/config_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/config_validator.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/converter_jail/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/converter_jail/ast_guard.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/converter_jail/codeprep.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/converter_jail/gslides_runner.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/converter_jail/jail.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/converter_jail/pptx_runner.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/converter_jail/protocol.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/design_system_compiler.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/design_system_templates.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/drive_uploader.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/evaluation/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/evaluation/llm_judge.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/genie_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/google_slides_auth.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/google_slides_prompts_defaults.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/html_to_google_slides.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/html_to_pptx.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/identity_providers/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/identity_providers/local_provider.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/image_tools.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/permission_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/pptx_from_html_huashu.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/pptx_from_records.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/pptx_prompts_defaults.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/profile_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/streaming_callback.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/tools/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/tools/agent_bricks_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/tools/ds_asset_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/tools/genie_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/tools/mcp_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/tools/model_endpoint_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/tools/vector_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/services/validator.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/utils/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/utils/css_utils.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/utils/ds_asset_utils.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/utils/error_handling.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/utils/html_safety.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/utils/html_utils.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/utils/image_utils.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/utils/js_validator.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/utils/logging_config.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/utils/pi_filter.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/utils/slide_hash.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/utils/spotlight.py +0 -0
- {databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/utils/text_caps.py +0 -0
|
@@ -124,7 +124,6 @@ setup.py
|
|
|
124
124
|
./src/services/pptx_prompts_defaults.py
|
|
125
125
|
./src/services/profile_service.py
|
|
126
126
|
./src/services/streaming_callback.py
|
|
127
|
-
./src/services/svg_sanitizer.py
|
|
128
127
|
./src/services/validator.py
|
|
129
128
|
./src/services/converter_jail/__init__.py
|
|
130
129
|
./src/services/converter_jail/ast_guard.py
|
|
@@ -138,6 +137,7 @@ setup.py
|
|
|
138
137
|
./src/services/identity_providers/__init__.py
|
|
139
138
|
./src/services/identity_providers/account_provider.py
|
|
140
139
|
./src/services/identity_providers/local_provider.py
|
|
140
|
+
./src/services/identity_providers/scim_filter.py
|
|
141
141
|
./src/services/identity_providers/workspace_provider.py
|
|
142
142
|
./src/services/tools/__init__.py
|
|
143
143
|
./src/services/tools/agent_bricks_tool.py
|
|
@@ -287,7 +287,6 @@ src/services/pptx_from_records.py
|
|
|
287
287
|
src/services/pptx_prompts_defaults.py
|
|
288
288
|
src/services/profile_service.py
|
|
289
289
|
src/services/streaming_callback.py
|
|
290
|
-
src/services/svg_sanitizer.py
|
|
291
290
|
src/services/validator.py
|
|
292
291
|
src/services/converter_jail/__init__.py
|
|
293
292
|
src/services/converter_jail/ast_guard.py
|
|
@@ -301,6 +300,7 @@ src/services/evaluation/llm_judge.py
|
|
|
301
300
|
src/services/identity_providers/__init__.py
|
|
302
301
|
src/services/identity_providers/account_provider.py
|
|
303
302
|
src/services/identity_providers/local_provider.py
|
|
303
|
+
src/services/identity_providers/scim_filter.py
|
|
304
304
|
src/services/identity_providers/workspace_provider.py
|
|
305
305
|
src/services/tools/__init__.py
|
|
306
306
|
src/services/tools/agent_bricks_tool.py
|
|
@@ -74,7 +74,6 @@ from src.database.models.design_system import (
|
|
|
74
74
|
DesignSystemToken,
|
|
75
75
|
)
|
|
76
76
|
from src.services.design_system_compiler import recompute_compiled_style_content
|
|
77
|
-
from src.services.svg_sanitizer import looks_like_svg, sanitize_svg
|
|
78
77
|
|
|
79
78
|
logger = logging.getLogger(__name__)
|
|
80
79
|
|
|
@@ -2165,20 +2164,6 @@ def _collect_assets_and_files(
|
|
|
2165
2164
|
mime = sniffed
|
|
2166
2165
|
else:
|
|
2167
2166
|
mime = _guess_mime(rel)
|
|
2168
|
-
if mime == "image/svg+xml":
|
|
2169
|
-
try:
|
|
2170
|
-
data = sanitize_svg(data)
|
|
2171
|
-
except ValueError as exc:
|
|
2172
|
-
raise DesignSystemImportError(
|
|
2173
|
-
f"Bundle entry '{rel}' is not a valid SVG: {exc}"
|
|
2174
|
-
) from exc
|
|
2175
|
-
elif looks_like_svg(data):
|
|
2176
|
-
# Extension says raster/font/etc. but the bytes are SVG:
|
|
2177
|
-
# never trust the name to skip sanitization.
|
|
2178
|
-
raise DesignSystemImportError(
|
|
2179
|
-
f"Bundle entry '{rel}' contains SVG content but does not "
|
|
2180
|
-
"have an .svg extension"
|
|
2181
|
-
)
|
|
2182
2167
|
width, height = _image_dimensions(data, mime)
|
|
2183
2168
|
asset = DesignSystemAsset(
|
|
2184
2169
|
kind=kind,
|
|
@@ -14,6 +14,8 @@ from enum import Enum
|
|
|
14
14
|
from functools import lru_cache
|
|
15
15
|
from typing import Dict, List, Optional
|
|
16
16
|
|
|
17
|
+
from src.services.identity_providers.scim_filter import escape_scim_filter_string
|
|
18
|
+
|
|
17
19
|
logger = logging.getLogger(__name__)
|
|
18
20
|
|
|
19
21
|
|
|
@@ -33,8 +35,9 @@ def _resolve_cached(email: str) -> str:
|
|
|
33
35
|
provider = get_identity_provider()
|
|
34
36
|
from src.services.identity_providers.workspace_provider import WorkspaceIdentityProvider
|
|
35
37
|
if isinstance(provider._provider, WorkspaceIdentityProvider):
|
|
38
|
+
escaped_email = escape_scim_filter_string(email)
|
|
36
39
|
for u in provider._provider._client.users.list(
|
|
37
|
-
filter=f'userName eq "{
|
|
40
|
+
filter=f'userName eq "{escaped_email}"',
|
|
38
41
|
attributes="id,userName,displayName",
|
|
39
42
|
):
|
|
40
43
|
if u.display_name:
|
|
@@ -12,6 +12,8 @@ from typing import List, Optional
|
|
|
12
12
|
|
|
13
13
|
import requests
|
|
14
14
|
|
|
15
|
+
from src.services.identity_providers.scim_filter import escape_scim_filter_string
|
|
16
|
+
|
|
15
17
|
logger = logging.getLogger(__name__)
|
|
16
18
|
|
|
17
19
|
|
|
@@ -181,9 +183,10 @@ class AccountIdentityProvider:
|
|
|
181
183
|
Combined list of matching users and groups
|
|
182
184
|
"""
|
|
183
185
|
results = []
|
|
186
|
+
escaped_query = escape_scim_filter_string(query)
|
|
184
187
|
|
|
185
188
|
if include_users:
|
|
186
|
-
user_filter = f'userName co "{
|
|
189
|
+
user_filter = f'userName co "{escaped_query}" or displayName co "{escaped_query}"'
|
|
187
190
|
try:
|
|
188
191
|
users = self.list_users(filter_query=user_filter, max_results=max_results)
|
|
189
192
|
results.extend(users)
|
|
@@ -191,7 +194,7 @@ class AccountIdentityProvider:
|
|
|
191
194
|
logger.warning("Failed to search users in Account API")
|
|
192
195
|
|
|
193
196
|
if include_groups:
|
|
194
|
-
group_filter = f'displayName co "{
|
|
197
|
+
group_filter = f'displayName co "{escaped_query}"'
|
|
195
198
|
try:
|
|
196
199
|
groups = self.list_groups(filter_query=group_filter, max_results=max_results)
|
|
197
200
|
results.extend(groups)
|
|
@@ -12,6 +12,8 @@ from typing import List, Optional
|
|
|
12
12
|
|
|
13
13
|
from databricks.sdk import WorkspaceClient
|
|
14
14
|
|
|
15
|
+
from src.services.identity_providers.scim_filter import escape_scim_filter_string
|
|
16
|
+
|
|
15
17
|
logger = logging.getLogger(__name__)
|
|
16
18
|
|
|
17
19
|
|
|
@@ -50,8 +52,9 @@ class WorkspaceIdentityProvider:
|
|
|
50
52
|
try:
|
|
51
53
|
kwargs: dict = {"attributes": "id,userName,displayName"}
|
|
52
54
|
if filter_query:
|
|
55
|
+
escaped_query = escape_scim_filter_string(filter_query)
|
|
53
56
|
kwargs["filter"] = (
|
|
54
|
-
f'userName co "{
|
|
57
|
+
f'userName co "{escaped_query}" or displayName co "{escaped_query}"'
|
|
55
58
|
)
|
|
56
59
|
|
|
57
60
|
users: List[dict] = []
|
|
@@ -90,7 +93,8 @@ class WorkspaceIdentityProvider:
|
|
|
90
93
|
try:
|
|
91
94
|
kwargs: dict = {"attributes": "id,displayName"}
|
|
92
95
|
if filter_query:
|
|
93
|
-
|
|
96
|
+
escaped_query = escape_scim_filter_string(filter_query)
|
|
97
|
+
kwargs["filter"] = f'displayName co "{escaped_query}"'
|
|
94
98
|
|
|
95
99
|
groups: List[dict] = []
|
|
96
100
|
for g in self._client.groups.list(**kwargs):
|
|
@@ -11,7 +11,6 @@ from sqlalchemy.dialects.postgresql import JSONB
|
|
|
11
11
|
from sqlalchemy.orm import Query, Session
|
|
12
12
|
|
|
13
13
|
from src.database.models.image import ImageAsset
|
|
14
|
-
from src.services.svg_sanitizer import looks_like_svg, sanitize_svg
|
|
15
14
|
|
|
16
15
|
logger = logging.getLogger(__name__)
|
|
17
16
|
|
|
@@ -42,20 +41,6 @@ def upload_image(
|
|
|
42
41
|
if len(file_content) > MAX_FILE_SIZE:
|
|
43
42
|
raise ValueError(f"File too large: {len(file_content)} bytes (max {MAX_FILE_SIZE})")
|
|
44
43
|
|
|
45
|
-
# The client-declared MIME type is untrusted: decide on the CONTENT.
|
|
46
|
-
# SVG can carry script, so it is always sanitized; SVG bytes declared as
|
|
47
|
-
# any other type are rejected rather than stored under a raster label.
|
|
48
|
-
if mime_type == "image/svg+xml":
|
|
49
|
-
try:
|
|
50
|
-
file_content = sanitize_svg(file_content)
|
|
51
|
-
except ValueError as exc:
|
|
52
|
-
raise ValueError(f"Invalid SVG upload: {exc}") from exc
|
|
53
|
-
elif looks_like_svg(file_content):
|
|
54
|
-
raise ValueError(
|
|
55
|
-
f"File content is SVG but was declared as {mime_type}; "
|
|
56
|
-
"upload it as image/svg+xml."
|
|
57
|
-
)
|
|
58
|
-
|
|
59
44
|
# Check for duplicate original_filename among active images (case-insensitive).
|
|
60
45
|
# Ephemeral images (paste-to-chat) skip this check — they use throwaway names
|
|
61
46
|
# and should never block each other.
|
|
@@ -1,414 +0,0 @@
|
|
|
1
|
-
"""Server-side sanitization for SVG images before they are stored."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import re
|
|
6
|
-
from urllib.parse import urlsplit
|
|
7
|
-
|
|
8
|
-
from lxml import etree # type: ignore[import-untyped]
|
|
9
|
-
|
|
10
|
-
SVG_NAMESPACE = "http://www.w3.org/2000/svg"
|
|
11
|
-
|
|
12
|
-
_ALLOWED_ELEMENTS = frozenset(
|
|
13
|
-
{
|
|
14
|
-
"svg",
|
|
15
|
-
"g",
|
|
16
|
-
"defs",
|
|
17
|
-
"symbol",
|
|
18
|
-
"use",
|
|
19
|
-
"title",
|
|
20
|
-
"desc",
|
|
21
|
-
"switch",
|
|
22
|
-
"view",
|
|
23
|
-
"path",
|
|
24
|
-
"rect",
|
|
25
|
-
"circle",
|
|
26
|
-
"ellipse",
|
|
27
|
-
"line",
|
|
28
|
-
"polyline",
|
|
29
|
-
"polygon",
|
|
30
|
-
"text",
|
|
31
|
-
"tspan",
|
|
32
|
-
"textPath",
|
|
33
|
-
"a",
|
|
34
|
-
"image",
|
|
35
|
-
"style",
|
|
36
|
-
"linearGradient",
|
|
37
|
-
"radialGradient",
|
|
38
|
-
"stop",
|
|
39
|
-
"pattern",
|
|
40
|
-
"marker",
|
|
41
|
-
"mask",
|
|
42
|
-
"clipPath",
|
|
43
|
-
"filter",
|
|
44
|
-
"feBlend",
|
|
45
|
-
"feColorMatrix",
|
|
46
|
-
"feComponentTransfer",
|
|
47
|
-
"feComposite",
|
|
48
|
-
"feConvolveMatrix",
|
|
49
|
-
"feDiffuseLighting",
|
|
50
|
-
"feDisplacementMap",
|
|
51
|
-
"feDistantLight",
|
|
52
|
-
"feDropShadow",
|
|
53
|
-
"feFlood",
|
|
54
|
-
"feFuncA",
|
|
55
|
-
"feFuncB",
|
|
56
|
-
"feFuncG",
|
|
57
|
-
"feFuncR",
|
|
58
|
-
"feGaussianBlur",
|
|
59
|
-
"feImage",
|
|
60
|
-
"feMerge",
|
|
61
|
-
"feMergeNode",
|
|
62
|
-
"feMorphology",
|
|
63
|
-
"feOffset",
|
|
64
|
-
"fePointLight",
|
|
65
|
-
"feSpecularLighting",
|
|
66
|
-
"feSpotLight",
|
|
67
|
-
"feTile",
|
|
68
|
-
"feTurbulence",
|
|
69
|
-
"animate",
|
|
70
|
-
"animateMotion",
|
|
71
|
-
"animateTransform",
|
|
72
|
-
"set",
|
|
73
|
-
"mpath",
|
|
74
|
-
}
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
_ALLOWED_ATTRIBUTES = frozenset(
|
|
78
|
-
{
|
|
79
|
-
"id",
|
|
80
|
-
"class",
|
|
81
|
-
"style",
|
|
82
|
-
"transform",
|
|
83
|
-
"transform-origin",
|
|
84
|
-
"clip-path",
|
|
85
|
-
"clip-rule",
|
|
86
|
-
"mask",
|
|
87
|
-
"filter",
|
|
88
|
-
"opacity",
|
|
89
|
-
"fill",
|
|
90
|
-
"fill-opacity",
|
|
91
|
-
"fill-rule",
|
|
92
|
-
"stroke",
|
|
93
|
-
"stroke-dasharray",
|
|
94
|
-
"stroke-dashoffset",
|
|
95
|
-
"stroke-linecap",
|
|
96
|
-
"stroke-linejoin",
|
|
97
|
-
"stroke-miterlimit",
|
|
98
|
-
"stroke-opacity",
|
|
99
|
-
"stroke-width",
|
|
100
|
-
"paint-order",
|
|
101
|
-
"color",
|
|
102
|
-
"color-interpolation",
|
|
103
|
-
"color-interpolation-filters",
|
|
104
|
-
"display",
|
|
105
|
-
"visibility",
|
|
106
|
-
"systemLanguage",
|
|
107
|
-
"requiredFeatures",
|
|
108
|
-
"requiredExtensions",
|
|
109
|
-
"lang",
|
|
110
|
-
"space",
|
|
111
|
-
"role",
|
|
112
|
-
"tabindex",
|
|
113
|
-
"version",
|
|
114
|
-
"baseProfile",
|
|
115
|
-
"width",
|
|
116
|
-
"height",
|
|
117
|
-
"viewBox",
|
|
118
|
-
"preserveAspectRatio",
|
|
119
|
-
"x",
|
|
120
|
-
"y",
|
|
121
|
-
"dx",
|
|
122
|
-
"dy",
|
|
123
|
-
"zoomAndPan",
|
|
124
|
-
"d",
|
|
125
|
-
"points",
|
|
126
|
-
"rx",
|
|
127
|
-
"ry",
|
|
128
|
-
"cx",
|
|
129
|
-
"cy",
|
|
130
|
-
"r",
|
|
131
|
-
"x1",
|
|
132
|
-
"x2",
|
|
133
|
-
"y1",
|
|
134
|
-
"y2",
|
|
135
|
-
"rotate",
|
|
136
|
-
"textLength",
|
|
137
|
-
"lengthAdjust",
|
|
138
|
-
"font-family",
|
|
139
|
-
"font-size",
|
|
140
|
-
"font-style",
|
|
141
|
-
"font-variant",
|
|
142
|
-
"font-weight",
|
|
143
|
-
"letter-spacing",
|
|
144
|
-
"word-spacing",
|
|
145
|
-
"text-decoration",
|
|
146
|
-
"text-anchor",
|
|
147
|
-
"dominant-baseline",
|
|
148
|
-
"alignment-baseline",
|
|
149
|
-
"baseline-shift",
|
|
150
|
-
"writing-mode",
|
|
151
|
-
"gradientUnits",
|
|
152
|
-
"gradientTransform",
|
|
153
|
-
"spreadMethod",
|
|
154
|
-
"href",
|
|
155
|
-
"offset",
|
|
156
|
-
"stop-color",
|
|
157
|
-
"stop-opacity",
|
|
158
|
-
"patternUnits",
|
|
159
|
-
"patternContentUnits",
|
|
160
|
-
"patternTransform",
|
|
161
|
-
"markerWidth",
|
|
162
|
-
"markerHeight",
|
|
163
|
-
"markerUnits",
|
|
164
|
-
"refX",
|
|
165
|
-
"refY",
|
|
166
|
-
"orient",
|
|
167
|
-
"clipPathUnits",
|
|
168
|
-
"maskUnits",
|
|
169
|
-
"maskContentUnits",
|
|
170
|
-
"filterUnits",
|
|
171
|
-
"primitiveUnits",
|
|
172
|
-
"in",
|
|
173
|
-
"in2",
|
|
174
|
-
"result",
|
|
175
|
-
"mode",
|
|
176
|
-
"values",
|
|
177
|
-
"type",
|
|
178
|
-
"tableValues",
|
|
179
|
-
"slope",
|
|
180
|
-
"intercept",
|
|
181
|
-
"amplitude",
|
|
182
|
-
"exponent",
|
|
183
|
-
"k1",
|
|
184
|
-
"k2",
|
|
185
|
-
"k3",
|
|
186
|
-
"k4",
|
|
187
|
-
"operator",
|
|
188
|
-
"radius",
|
|
189
|
-
"stdDeviation",
|
|
190
|
-
"xChannelSelector",
|
|
191
|
-
"yChannelSelector",
|
|
192
|
-
"scale",
|
|
193
|
-
"flood-color",
|
|
194
|
-
"flood-opacity",
|
|
195
|
-
"kernelMatrix",
|
|
196
|
-
"divisor",
|
|
197
|
-
"bias",
|
|
198
|
-
"targetX",
|
|
199
|
-
"targetY",
|
|
200
|
-
"edgeMode",
|
|
201
|
-
"kernelUnitLength",
|
|
202
|
-
"preserveAlpha",
|
|
203
|
-
"lighting-color",
|
|
204
|
-
"surfaceScale",
|
|
205
|
-
"diffuseConstant",
|
|
206
|
-
"specularConstant",
|
|
207
|
-
"specularExponent",
|
|
208
|
-
"pointsAtX",
|
|
209
|
-
"pointsAtY",
|
|
210
|
-
"pointsAtZ",
|
|
211
|
-
"limitingConeAngle",
|
|
212
|
-
"azimuth",
|
|
213
|
-
"elevation",
|
|
214
|
-
"seed",
|
|
215
|
-
"numOctaves",
|
|
216
|
-
"baseFrequency",
|
|
217
|
-
"stitchTiles",
|
|
218
|
-
"attributeName",
|
|
219
|
-
"attributeType",
|
|
220
|
-
"begin",
|
|
221
|
-
"end",
|
|
222
|
-
"dur",
|
|
223
|
-
"repeatCount",
|
|
224
|
-
"repeatDur",
|
|
225
|
-
"from",
|
|
226
|
-
"to",
|
|
227
|
-
"by",
|
|
228
|
-
"keyTimes",
|
|
229
|
-
"keySplines",
|
|
230
|
-
"keyPoints",
|
|
231
|
-
"calcMode",
|
|
232
|
-
"additive",
|
|
233
|
-
"accumulate",
|
|
234
|
-
"path",
|
|
235
|
-
"startOffset",
|
|
236
|
-
"method",
|
|
237
|
-
"spacing",
|
|
238
|
-
"crossorigin",
|
|
239
|
-
"decoding",
|
|
240
|
-
"loading",
|
|
241
|
-
"target",
|
|
242
|
-
"download",
|
|
243
|
-
"rel",
|
|
244
|
-
}
|
|
245
|
-
)
|
|
246
|
-
|
|
247
|
-
_URL_ATTRIBUTES = frozenset({"href"})
|
|
248
|
-
_ANIMATION_ELEMENTS = frozenset({"animate", "animateMotion", "animateTransform", "set"})
|
|
249
|
-
_ANIMATION_FORBIDDEN_TARGETS = frozenset({"href", "style"})
|
|
250
|
-
_SAFE_DATA_IMAGE_TYPES = frozenset({"png", "jpeg", "jpg", "gif", "webp"})
|
|
251
|
-
_UNSAFE_URL_PATTERN = re.compile(
|
|
252
|
-
r"(?:javascript|vbscript|livescript|mocha):|data:image/svg\+xml",
|
|
253
|
-
re.IGNORECASE,
|
|
254
|
-
)
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
def _local_name(value: str) -> str:
|
|
258
|
-
return value.rsplit("}", 1)[-1].rsplit(":", 1)[-1]
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
def _element_local_name(element: etree._Element) -> str:
|
|
262
|
-
return etree.QName(element).localname
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
def _is_allowed_element(element: etree._Element) -> bool:
|
|
266
|
-
return _element_local_name(element) in _ALLOWED_ELEMENTS
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
def _normalized_url(value: str) -> str:
|
|
270
|
-
characters = (character for character in value if character not in "\t\n\r\f\v")
|
|
271
|
-
return "".join(characters).strip()
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
def _is_safe_url(value: str) -> bool:
|
|
275
|
-
normalized = _normalized_url(value)
|
|
276
|
-
if not normalized or normalized.startswith("#"):
|
|
277
|
-
return True
|
|
278
|
-
|
|
279
|
-
parsed = urlsplit(normalized)
|
|
280
|
-
scheme = parsed.scheme.lower()
|
|
281
|
-
if not scheme or scheme in {"http", "https", "mailto"}:
|
|
282
|
-
return True
|
|
283
|
-
if scheme != "data":
|
|
284
|
-
return False
|
|
285
|
-
|
|
286
|
-
media_type = parsed.path.split(";", 1)[0].lower()
|
|
287
|
-
image_type = media_type.removeprefix("image/")
|
|
288
|
-
return image_type in _SAFE_DATA_IMAGE_TYPES
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
def _has_external_use_reference(element: etree._Element) -> bool:
|
|
292
|
-
return any(
|
|
293
|
-
_local_name(name) == "href" and not _normalized_url(value).startswith("#")
|
|
294
|
-
for name, value in element.attrib.items()
|
|
295
|
-
)
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
def _animation_targets_forbidden_attribute(element: etree._Element) -> bool:
|
|
299
|
-
target = element.get("attributeName")
|
|
300
|
-
if target is None:
|
|
301
|
-
return False
|
|
302
|
-
local_target = _local_name(target)
|
|
303
|
-
return local_target.startswith("on") or local_target in _ANIMATION_FORBIDDEN_TARGETS
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
def _contains_unsafe_url(value: str) -> bool:
|
|
307
|
-
return _UNSAFE_URL_PATTERN.search(_normalized_url(value)) is not None
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
def _sanitize_attributes(root: etree._Element) -> None:
|
|
311
|
-
for element in root.iter():
|
|
312
|
-
for name, value in list(element.attrib.items()):
|
|
313
|
-
local_name = _local_name(name)
|
|
314
|
-
if local_name not in _ALLOWED_ATTRIBUTES:
|
|
315
|
-
del element.attrib[name]
|
|
316
|
-
continue
|
|
317
|
-
if local_name in _URL_ATTRIBUTES and not _is_safe_url(value):
|
|
318
|
-
del element.attrib[name]
|
|
319
|
-
elif local_name == "style" and _contains_unsafe_url(value):
|
|
320
|
-
del element.attrib[name]
|
|
321
|
-
|
|
322
|
-
if _element_local_name(element) == "style" and _contains_unsafe_url(
|
|
323
|
-
element.text or ""
|
|
324
|
-
):
|
|
325
|
-
element.text = None
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
_RASTER_MAGICS = (
|
|
329
|
-
b"\x89PNG\r\n\x1a\n",
|
|
330
|
-
b"\xff\xd8\xff",
|
|
331
|
-
b"GIF87a",
|
|
332
|
-
b"GIF89a",
|
|
333
|
-
)
|
|
334
|
-
_SNIFF_WINDOW = 4096
|
|
335
|
-
# An SVG document: optional BOM/whitespace, any XML prolog (declaration, comments,
|
|
336
|
-
# PIs, DOCTYPE with optional internal subset), then ``<svg`` as the ROOT element.
|
|
337
|
-
# Anchoring on the root (not a substring) keeps CSS/HTML/text that merely mentions
|
|
338
|
-
# ``<svg`` (e.g. a ``data:image/svg+xml,<svg ...>`` URI) from being treated as SVG.
|
|
339
|
-
_SVG_ROOT_RE = re.compile(
|
|
340
|
-
r"\A\ufeff?\s*"
|
|
341
|
-
r"(?:<\?.*?\?>\s*|<!--.*?-->\s*|<!DOCTYPE(?:[^>\[]|\[.*?\])*>\s*)*"
|
|
342
|
-
r"<(?:[\w.-]+:)?svg[\s/>]",
|
|
343
|
-
re.IGNORECASE | re.DOTALL,
|
|
344
|
-
)
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
def looks_like_svg(content: bytes) -> bool:
|
|
348
|
-
"""Content sniff: True if the bytes look like an SVG document.
|
|
349
|
-
|
|
350
|
-
Used so a client-declared MIME type (e.g. ``image/png``) is never trusted
|
|
351
|
-
to decide whether sanitization is needed. Content that starts with a known
|
|
352
|
-
raster magic number is not SVG; otherwise it is SVG only if ``<svg`` is the
|
|
353
|
-
root element (after any XML prolog) within the first few KB (UTF-8/ASCII or
|
|
354
|
-
BOM-marked UTF-16).
|
|
355
|
-
"""
|
|
356
|
-
head = content[:_SNIFF_WINDOW]
|
|
357
|
-
if head.startswith(_RASTER_MAGICS):
|
|
358
|
-
return False
|
|
359
|
-
if head.startswith((b"\xff\xfe", b"\xfe\xff")):
|
|
360
|
-
text = head.decode("utf-16", errors="ignore")
|
|
361
|
-
else:
|
|
362
|
-
text = head.decode("utf-8", errors="ignore")
|
|
363
|
-
return _SVG_ROOT_RE.match(text) is not None
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
def sanitize_svg(content: bytes) -> bytes:
|
|
367
|
-
"""Return a sanitized SVG, rejecting malformed or non-SVG XML input."""
|
|
368
|
-
parser = etree.XMLParser(
|
|
369
|
-
resolve_entities=False,
|
|
370
|
-
no_network=True,
|
|
371
|
-
load_dtd=False,
|
|
372
|
-
huge_tree=False,
|
|
373
|
-
remove_comments=True,
|
|
374
|
-
remove_pis=True,
|
|
375
|
-
)
|
|
376
|
-
|
|
377
|
-
try:
|
|
378
|
-
root = etree.fromstring(content, parser=parser)
|
|
379
|
-
except etree.XMLSyntaxError as exc:
|
|
380
|
-
raise ValueError("SVG must be well-formed XML") from exc
|
|
381
|
-
|
|
382
|
-
if root is None:
|
|
383
|
-
raise ValueError("SVG document is empty")
|
|
384
|
-
|
|
385
|
-
root_qname = etree.QName(root)
|
|
386
|
-
if root_qname.localname != "svg" or root_qname.namespace not in {None, SVG_NAMESPACE}:
|
|
387
|
-
raise ValueError("SVG root element is required")
|
|
388
|
-
|
|
389
|
-
if root.getroottree().docinfo.doctype:
|
|
390
|
-
raise ValueError("SVG DOCTYPE declarations are not allowed")
|
|
391
|
-
|
|
392
|
-
elements_to_remove = []
|
|
393
|
-
for element in root.iter():
|
|
394
|
-
if element is root:
|
|
395
|
-
continue
|
|
396
|
-
|
|
397
|
-
local_name = _element_local_name(element)
|
|
398
|
-
if not _is_allowed_element(element):
|
|
399
|
-
elements_to_remove.append(element)
|
|
400
|
-
elif local_name == "use" and _has_external_use_reference(element):
|
|
401
|
-
elements_to_remove.append(element)
|
|
402
|
-
elif local_name in _ANIMATION_ELEMENTS and _animation_targets_forbidden_attribute(
|
|
403
|
-
element
|
|
404
|
-
):
|
|
405
|
-
elements_to_remove.append(element)
|
|
406
|
-
|
|
407
|
-
for element in elements_to_remove:
|
|
408
|
-
parent = element.getparent()
|
|
409
|
-
if parent is not None:
|
|
410
|
-
parent.remove(element)
|
|
411
|
-
|
|
412
|
-
_sanitize_attributes(root)
|
|
413
|
-
|
|
414
|
-
return etree.tostring(root, encoding="utf-8", xml_declaration=True)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/__init__.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/_otel_bootstrap.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/mcp_auth.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/mcp_server.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/middleware/csrf.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/__init__.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/_authz.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev3403 → databricks_tellr_app-0.4.3.dev3432}/src/api/routes/admin.py
RENAMED
|
File without changes
|
|
File without changes
|