iatoolkit 2.69.0__tar.gz → 2.70.0__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.
Files changed (277) hide show
  1. {iatoolkit-2.69.0/src/iatoolkit.egg-info → iatoolkit-2.70.0}/PKG-INFO +1 -1
  2. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/__init__.py +1 -1
  3. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/locales/en.yaml +5 -0
  4. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/locales/es.yaml +5 -0
  5. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/models.py +6 -0
  6. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/api_key_service.py +13 -4
  7. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/auth_service.py +37 -7
  8. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/profile_service.py +14 -0
  9. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/api_key_api_view.py +5 -2
  10. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/users_api_view.py +5 -0
  11. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/wiki_page_view.py +2 -2
  12. {iatoolkit-2.69.0 → iatoolkit-2.70.0/src/iatoolkit.egg-info}/PKG-INFO +1 -1
  13. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/LICENSE +0 -0
  14. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/LICENSE_COMMUNITY.md +0 -0
  15. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/pyproject.toml +0 -0
  16. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/readme.md +0 -0
  17. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/setup.cfg +0 -0
  18. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/base_company.py +0 -0
  19. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/cli_commands.py +0 -0
  20. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/__init__.py +0 -0
  21. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/bridge_validation.py +0 -0
  22. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/company_paths.py +0 -0
  23. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/exceptions.py +0 -0
  24. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/interfaces/__init__.py +0 -0
  25. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/interfaces/asset_storage.py +0 -0
  26. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/interfaces/database_provider.py +0 -0
  27. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/interfaces/memory_compilation_trigger.py +0 -0
  28. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/interfaces/secret_provider.py +0 -0
  29. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/interfaces/signup_policy_resolver.py +0 -0
  30. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/interfaces/web_search_provider.py +0 -0
  31. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/memory_tools.py +0 -0
  32. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/model_registry.py +0 -0
  33. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/routes.py +0 -0
  34. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/search_terms.py +0 -0
  35. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/secret_resolver.py +0 -0
  36. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/session_manager.py +0 -0
  37. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/text_splitter.py +0 -0
  38. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/url_safety.py +0 -0
  39. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/common/util.py +0 -0
  40. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/company_registry.py +0 -0
  41. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/__init__.py +0 -0
  42. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/llm_capabilities.yaml +0 -0
  43. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_agents/memory_compiler.prompt +0 -0
  44. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_agents/memory_correction.prompt +0 -0
  45. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_agents/memory_document_ingest.prompt +0 -0
  46. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_agents/memory_image_ingest.prompt +0 -0
  47. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_agents/memory_meeting_ingest.prompt +0 -0
  48. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_agents/memory_question_review.prompt +0 -0
  49. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_agents_pack.yaml +0 -0
  50. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/channel_business_identity.prompt +0 -0
  51. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/channel_conversation_continuity.prompt +0 -0
  52. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/channel_response_style.prompt +0 -0
  53. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/chat_state_rules.prompt +0 -0
  54. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/chat_user_profile.prompt +0 -0
  55. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/core_identity.prompt +0 -0
  56. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/email_output.prompt +0 -0
  57. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/file_download_output.prompt +0 -0
  58. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/format_styles.prompt +0 -0
  59. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/html_structures.prompt +0 -0
  60. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/links_documents.prompt +0 -0
  61. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/memory_usage.prompt +0 -0
  62. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/multimodal_basics.prompt +0 -0
  63. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/output_basics.prompt +0 -0
  64. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/presentation_formatting.prompt +0 -0
  65. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/query_main.prompt +0 -0
  66. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/sql_aggregation_scope.prompt +0 -0
  67. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/sql_casting.prompt +0 -0
  68. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/sql_core.prompt +0 -0
  69. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/sql_jsonb.prompt +0 -0
  70. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/sql_mysql_casting.prompt +0 -0
  71. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/sql_mysql_json.prompt +0 -0
  72. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/sql_redshift_basics.prompt +0 -0
  73. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/sql_redshift_types.prompt +0 -0
  74. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/sql_rules.prompt +0 -0
  75. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts/tool_html_passthrough.prompt +0 -0
  76. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_prompts_pack.yaml +0 -0
  77. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/config/system_tools_pack.yaml +0 -0
  78. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/core.py +0 -0
  79. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/__init__.py +0 -0
  80. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/brevo_mail_app.py +0 -0
  81. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/call_service.py +0 -0
  82. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/connectors/__init__.py +0 -0
  83. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/connectors/file_connector.py +0 -0
  84. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/connectors/file_connector_factory.py +0 -0
  85. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/connectors/google_cloud_storage_connector.py +0 -0
  86. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/connectors/google_drive_connector.py +0 -0
  87. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/connectors/local_file_connector.py +0 -0
  88. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/connectors/s3_connector.py +0 -0
  89. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/google_auth_client.py +0 -0
  90. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/google_chat_app.py +0 -0
  91. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/inference_embeddings_client.py +0 -0
  92. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/inference_handler.py +0 -0
  93. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/jina_embeddings_client.py +0 -0
  94. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/llm_gateway_resolver.py +0 -0
  95. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/llm_providers/__init__.py +0 -0
  96. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/llm_providers/anthropic_adapter.py +0 -0
  97. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/llm_providers/deepseek_adapter.py +0 -0
  98. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/llm_providers/gemini_adapter.py +0 -0
  99. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/llm_providers/openai_adapter.py +0 -0
  100. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/llm_providers/openai_compatible_chat_adapter.py +0 -0
  101. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/llm_providers/openrouter_adapter.py +0 -0
  102. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/llm_proxy.py +0 -0
  103. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/llm_response.py +0 -0
  104. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/infra/redis_session_manager.py +0 -0
  105. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/__init__.py +0 -0
  106. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/advisory_lock.py +0 -0
  107. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/api_key_repo.py +0 -0
  108. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/bridge_repo.py +0 -0
  109. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/database_manager.py +0 -0
  110. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/document_repo.py +0 -0
  111. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/env_secret_provider.py +0 -0
  112. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/filesystem_asset_repository.py +0 -0
  113. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/knowledge_wiki_repo.py +0 -0
  114. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/llm_query_repo.py +0 -0
  115. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/mcp_token_repo.py +0 -0
  116. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/memory_question_repo.py +0 -0
  117. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/memory_repo.py +0 -0
  118. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/memory_usage_repo.py +0 -0
  119. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/profile_repo.py +0 -0
  120. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/prompt_resource_repo.py +0 -0
  121. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/sql_dataset_repo.py +0 -0
  122. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/sql_source_repo.py +0 -0
  123. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/repositories/vs_repo.py +0 -0
  124. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/runtime_logging.py +0 -0
  125. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/__init__.py +0 -0
  126. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/attachment_policy_service.py +0 -0
  127. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/branding_service.py +0 -0
  128. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/company_context_service.py +0 -0
  129. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/configuration_service.py +0 -0
  130. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/context_builder_service.py +0 -0
  131. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/dispatcher_service.py +0 -0
  132. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/embedding_service.py +0 -0
  133. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/excel_service.py +0 -0
  134. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/file_processor_service.py +0 -0
  135. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/history_manager_service.py +0 -0
  136. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/http_tool_service.py +0 -0
  137. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/i18n_service.py +0 -0
  138. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/inference_service.py +0 -0
  139. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/jwt_service.py +0 -0
  140. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/knowledge_base_service.py +0 -0
  141. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/language_service.py +0 -0
  142. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/license_service.py +0 -0
  143. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/llm_client_service.py +0 -0
  144. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/mail_service.py +0 -0
  145. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/markdown_wiki_service.py +0 -0
  146. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/mcp_token_service.py +0 -0
  147. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/memory_compiler_service.py +0 -0
  148. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/memory_lookup_policy_service.py +0 -0
  149. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/memory_question_service.py +0 -0
  150. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/memory_service.py +0 -0
  151. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/memory_sources.py +0 -0
  152. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/memory_usage_service.py +0 -0
  153. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/memory_wiki_service.py +0 -0
  154. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/noop_memory_compilation_trigger.py +0 -0
  155. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/operator_identity_service.py +0 -0
  156. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/parsers/__init__.py +0 -0
  157. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/parsers/contracts.py +0 -0
  158. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/parsers/image_normalizer.py +0 -0
  159. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/parsers/parsing_service.py +0 -0
  160. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/parsers/pdf_ocr_detection.py +0 -0
  161. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/parsers/provider_factory.py +0 -0
  162. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/parsers/provider_resolver.py +0 -0
  163. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/parsers/providers/__init__.py +0 -0
  164. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/parsers/providers/basic_provider.py +0 -0
  165. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/parsers/providers/docling_provider.py +0 -0
  166. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/parsers/validator.py +0 -0
  167. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/pdf_service.py +0 -0
  168. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/prompt_resource_service.py +0 -0
  169. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/prompt_service.py +0 -0
  170. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/query_service.py +0 -0
  171. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/signup_policy_resolver.py +0 -0
  172. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/sql_dataset_service.py +0 -0
  173. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/sql_service.py +0 -0
  174. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/sql_source_service.py +0 -0
  175. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/storage_service.py +0 -0
  176. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/structured_output_service.py +0 -0
  177. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/system_agent_catalog.py +0 -0
  178. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/system_agent_runner.py +0 -0
  179. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/system_prompt_catalog.py +0 -0
  180. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/system_tools.py +0 -0
  181. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/telemetry_service.py +0 -0
  182. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/tenant_wiki_service.py +0 -0
  183. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/tool_output_contract.py +0 -0
  184. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/tool_service.py +0 -0
  185. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/user_feedback_service.py +0 -0
  186. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/user_session_context_service.py +0 -0
  187. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/visual_kb_service.py +0 -0
  188. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/visual_tool_service.py +0 -0
  189. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/warmup_service.py +0 -0
  190. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/web_search/__init__.py +0 -0
  191. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/web_search/provider_factory.py +0 -0
  192. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/web_search/providers/__init__.py +0 -0
  193. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/web_search/providers/brave_provider.py +0 -0
  194. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/web_search_service.py +0 -0
  195. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/services/wiki_page_index_service.py +0 -0
  196. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/images/favicon.ico +0 -0
  197. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/images/favicon.png +0 -0
  198. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/images/fernando.jpeg +0 -0
  199. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/images/iatoolkit_core.png +0 -0
  200. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/images/iatoolkit_logo.png +0 -0
  201. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/js/chat_feedback_button.js +0 -0
  202. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/js/chat_filepond.js +0 -0
  203. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/js/chat_header_navigation.js +0 -0
  204. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/js/chat_help_content.js +0 -0
  205. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/js/chat_history_button.js +0 -0
  206. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/js/chat_logout_button.js +0 -0
  207. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/js/chat_main.js +0 -0
  208. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/js/chat_memory_button.js +0 -0
  209. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/js/chat_model_selector.js +0 -0
  210. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/js/chat_onboarding_button.js +0 -0
  211. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/js/chat_prompt_manager.js +0 -0
  212. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/js/chat_reload_button.js +0 -0
  213. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/styles/account.css +0 -0
  214. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/styles/chat_iatoolkit.css +0 -0
  215. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/styles/chat_modal.css +0 -0
  216. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/styles/chat_public.css +0 -0
  217. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/styles/documents.css +0 -0
  218. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/styles/landing_page.css +0 -0
  219. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/styles/llm_output.css +0 -0
  220. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/styles/onboarding.css +0 -0
  221. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/static/styles/wiki_page.css +0 -0
  222. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/_chat_header.html +0 -0
  223. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/_company_header.html +0 -0
  224. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/_login_widget.html +0 -0
  225. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/account.html +0 -0
  226. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/base.html +0 -0
  227. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/change_password.html +0 -0
  228. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/chat.html +0 -0
  229. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/chat_memory_modal.html +0 -0
  230. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/chat_modals.html +0 -0
  231. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/error.html +0 -0
  232. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/forgot_password.html +0 -0
  233. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/home_hosted_default.html +0 -0
  234. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/login_global.html +0 -0
  235. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/memory/wiki_schema.md +0 -0
  236. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/onboarding_shell.html +0 -0
  237. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/pdf/base.html +0 -0
  238. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/pdf/letter.html +0 -0
  239. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/pdf/report.html +0 -0
  240. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/pdf/simple.html +0 -0
  241. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/signup.html +0 -0
  242. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/templates/wiki_page.html +0 -0
  243. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/__init__.py +0 -0
  244. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/account_view.py +0 -0
  245. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/base_login_view.py +0 -0
  246. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/categories_api_view.py +0 -0
  247. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/change_password_view.py +0 -0
  248. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/chat_context_preview_api_view.py +0 -0
  249. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/chat_view.py +0 -0
  250. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/configuration_api_view.py +0 -0
  251. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/connectors_api_view.py +0 -0
  252. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/embedding_api_view.py +0 -0
  253. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/forgot_password_view.py +0 -0
  254. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/help_content_api_view.py +0 -0
  255. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/history_api_view.py +0 -0
  256. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/home_view.py +0 -0
  257. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/init_context_api_view.py +0 -0
  258. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/llmquery_api_view.py +0 -0
  259. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/load_document_api_view.py +0 -0
  260. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/login_view.py +0 -0
  261. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/logout_api_view.py +0 -0
  262. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/memory_api_view.py +0 -0
  263. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/profile_api_view.py +0 -0
  264. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/prompt_api_view.py +0 -0
  265. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/prompt_context_preview_api_view.py +0 -0
  266. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/prompt_resource_api_view.py +0 -0
  267. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/rag_api_view.py +0 -0
  268. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/root_redirect_view.py +0 -0
  269. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/signup_view.py +0 -0
  270. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/static_page_view.py +0 -0
  271. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/tool_api_view.py +0 -0
  272. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/user_feedback_api_view.py +0 -0
  273. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit/views/verify_user_view.py +0 -0
  274. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit.egg-info/SOURCES.txt +0 -0
  275. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit.egg-info/dependency_links.txt +0 -0
  276. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit.egg-info/requires.txt +0 -0
  277. {iatoolkit-2.69.0 → iatoolkit-2.70.0}/src/iatoolkit.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iatoolkit
3
- Version: 2.69.0
3
+ Version: 2.70.0
4
4
  Summary: IAToolkit
5
5
  Author: Fernando Libedinsky
6
6
  License-Expression: MIT
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # IAToolkit is open source software.
5
5
 
6
- __version__ = "2.69.0"
6
+ __version__ = "2.70.0"
7
7
 
8
8
  # Expose main classes and functions at the top level of the package
9
9
 
@@ -2087,6 +2087,11 @@ ui:
2087
2087
  routing_profile_hint: "Used by enterprise tool routing to rank and select candidate tools."
2088
2088
 
2089
2089
  api_key:
2090
+ can_act_for_users: "May act on behalf of users"
2091
+ can_act_for_users_help: "Without this, the key acts as itself (service:<name>) and cannot pass for anyone. Turn it on only for integrations that must name the user they act for (a portal with its own login, an MCP gateway)."
2092
+ acts: "Acts"
2093
+ acts_as_itself: "As itself"
2094
+ acts_for_users: "On behalf of users"
2090
2095
  title: "API Keys"
2091
2096
  subtitle: "Manage company API keys used to authenticate external requests."
2092
2097
  new_btn: "New API Key"
@@ -2105,6 +2105,11 @@ ui:
2105
2105
  routing_profile_hint: "Usado por el router enterprise para rankear y seleccionar herramientas candidatas."
2106
2106
 
2107
2107
  api_key:
2108
+ can_act_for_users: "Puede actuar en nombre de usuarios"
2109
+ can_act_for_users_help: "Sin esta opción, la llave actúa como sí misma (service:<nombre>) y no puede hacerse pasar por nadie. Actívala solo para integraciones que deben indicar el usuario por el que actúan (un portal con login propio, un gateway MCP)."
2110
+ acts: "Actúa"
2111
+ acts_as_itself: "Como sí misma"
2112
+ acts_for_users: "En nombre de usuarios"
2108
2113
  title: "API Keys"
2109
2114
  subtitle: "Administra las API keys de la empresa para autenticar solicitudes externas."
2110
2115
  new_btn: "Nueva API Key"
@@ -9,6 +9,7 @@ from sqlalchemy import Column, Integer, BigInteger, String, DateTime, Enum, Text
9
9
  from sqlalchemy.orm import DeclarativeBase
10
10
  from sqlalchemy.orm import relationship, class_mapper
11
11
  from sqlalchemy.sql import func, literal_column
12
+ from sqlalchemy.sql import text as sql_text
12
13
  from sqlalchemy import UniqueConstraint, Index
13
14
  from sqlalchemy.dialects.postgresql import JSONB
14
15
  from datetime import datetime
@@ -125,6 +126,11 @@ class ApiKey(Base):
125
126
  is_active = Column(Boolean, default=True, nullable=False)
126
127
  created_at = Column(DateTime, default=datetime.now)
127
128
  last_used_at = Column(DateTime, nullable=True) # Opcional: para rastrear uso
129
+ # A key is a service account that acts as itself ("service:<key name>"). Only with
130
+ # this on may it name the user it acts for, who must belong to the company
131
+ # (BL-010, Fase 0). Keys created before it existed keep acting for users;
132
+ # migration: iatoolkit-enterprise/migrations/2026-10-18-api-keys-can-act-for-users.sql
133
+ can_act_for_users = Column(Boolean, nullable=False, default=False, server_default=sql_text("true"))
128
134
 
129
135
  company = relationship("Company", back_populates="api_keys")
130
136
 
@@ -30,6 +30,8 @@ class ApiKeyService:
30
30
  "key_name": api_key.key_name,
31
31
  "key": api_key.key,
32
32
  "is_active": api_key.is_active,
33
+ # BL-010, Fase 0: whether the key may name the user it acts for.
34
+ "can_act_for_users": bool(getattr(api_key, "can_act_for_users", False)),
33
35
  "created_at": api_key.created_at.isoformat() if api_key.created_at else None,
34
36
  "last_used_at": api_key.last_used_at.isoformat() if api_key.last_used_at else None,
35
37
  }
@@ -65,7 +67,7 @@ class ApiKeyService:
65
67
 
66
68
  return {"data": self._api_key_to_dict(api_key)}
67
69
 
68
- def create_api_key_entry(self, company_short_name: str, key_name: str) -> Dict:
70
+ def create_api_key_entry(self, company_short_name: str, key_name: str, can_act_for_users: bool = False) -> Dict:
69
71
  company, error = self._get_company(company_short_name)
70
72
  if error:
71
73
  return error
@@ -81,7 +83,8 @@ class ApiKeyService:
81
83
  alphabet = string.ascii_letters + string.digits
82
84
  key = ''.join(secrets.choice(alphabet) for _ in range(length))
83
85
 
84
- api_key = ApiKey(key=key, company_id=company.id, key_name=key_name)
86
+ # A new key acts as itself unless the admin allows it to act for users (BL-010).
87
+ api_key = ApiKey(key=key, company_id=company.id, key_name=key_name, can_act_for_users=bool(can_act_for_users))
85
88
  created = self.api_key_repo.create_api_key(api_key)
86
89
  return {"data": self._api_key_to_dict(created)}
87
90
 
@@ -89,7 +92,8 @@ class ApiKeyService:
89
92
  company_short_name: str,
90
93
  api_key_id: int,
91
94
  key_name: str | None = None,
92
- is_active: bool | None = None) -> Dict:
95
+ is_active: bool | None = None,
96
+ can_act_for_users: bool | None = None) -> Dict:
93
97
  company, error = self._get_company(company_short_name)
94
98
  if error:
95
99
  return error
@@ -98,7 +102,7 @@ class ApiKeyService:
98
102
  if not api_key:
99
103
  return {"error": "API key not found.", "status_code": 404}
100
104
 
101
- if key_name is None and is_active is None:
105
+ if key_name is None and is_active is None and can_act_for_users is None:
102
106
  return {"error": "No changes provided.", "status_code": 400}
103
107
 
104
108
  if key_name is not None:
@@ -116,6 +120,11 @@ class ApiKeyService:
116
120
  return {"error": "Invalid value for is_active.", "status_code": 400}
117
121
  api_key.is_active = is_active
118
122
 
123
+ if can_act_for_users is not None:
124
+ if not isinstance(can_act_for_users, bool):
125
+ return {"error": "Invalid value for can_act_for_users.", "status_code": 400}
126
+ api_key.can_act_for_users = can_act_for_users
127
+
119
128
  updated = self.api_key_repo.update_api_key(api_key)
120
129
  return {"data": self._api_key_to_dict(updated)}
121
130
 
@@ -14,6 +14,8 @@ from iatoolkit.repositories.models import AccessLog
14
14
  from iatoolkit.infra.google_auth_client import GoogleAuthClient, GoogleAuthError
15
15
  from flask import request
16
16
  import logging
17
+ import re
18
+ import unicodedata
17
19
  import hashlib
18
20
 
19
21
 
@@ -284,7 +286,11 @@ class AuthService:
284
286
  "success": True,
285
287
  "company_short_name": session_info['company_short_name'],
286
288
  "user_identifier": session_info['user_identifier'],
287
- "user_role": (session_info.get('profile') or {}).get('user_role'),
289
+ # From the database, never from the stored session profile: an SSO
290
+ # hook writes that profile, and must not be able to grant admin
291
+ # (BL-010, Fase 0).
292
+ "user_role": self._role_in_company(session_info['company_short_name'],
293
+ session_info['user_identifier']),
288
294
  }
289
295
 
290
296
  # --- Priority 2: Check for a valid API Key in headers ---
@@ -311,7 +317,22 @@ class AuthService:
311
317
  # get the company from the api_key_entry
312
318
  company = api_key_entry.company
313
319
 
314
- # For API calls, the external_user_id must be provided in the request.
320
+ # The key is a service account (BL-010, Fase 0): it acts as itself unless it
321
+ # was allowed to act for users. Every result says which key acted.
322
+ principal = self.service_principal(api_key_entry)
323
+ base = {
324
+ "success": True,
325
+ "company_short_name": company.short_name,
326
+ "auth_type": "api_key",
327
+ "auth_principal": principal,
328
+ "api_key_id": api_key_entry.id,
329
+ }
330
+ # Only an explicit False: a key loaded before the column existed keeps acting for users.
331
+ if getattr(api_key_entry, "can_act_for_users", None) is False:
332
+ # Whatever user the request names is ignored: the key cannot pass for anyone.
333
+ return {**base, "user_identifier": principal, "acting_for": None}
334
+
335
+ # A key allowed to act for users must say who (unless the endpoint allows none).
315
336
  data = request.get_json(silent=True) or {}
316
337
  user_identifier = data.get('user_identifier', '')
317
338
  if not anonymous and not user_identifier:
@@ -320,11 +341,20 @@ class AuthService:
320
341
  "error_message": self.i18n_service.t('errors.auth.no_user_identifier_api'),
321
342
  "status_code": 403}
322
343
 
323
- return {
324
- "success": True,
325
- "company_short_name": company.short_name,
326
- "user_identifier": user_identifier
327
- }
344
+ return {**base, "user_identifier": user_identifier, "acting_for": user_identifier or None}
345
+
346
+ SERVICE_PREFIX = "service:"
347
+
348
+ @classmethod
349
+ def service_principal(cls, api_key_entry) -> str:
350
+ """The identity a key acts with by itself: "service:<key name>" (lowercase, dashes)."""
351
+ raw = unicodedata.normalize("NFKD", str(getattr(api_key_entry, "key_name", "") or ""))
352
+ ascii_name = raw.encode("ascii", "ignore").decode("ascii").strip().lower()
353
+ name = re.sub(r"[^a-z0-9._-]+", "-", ascii_name)
354
+ return f"{cls.SERVICE_PREFIX}{name.strip('-') or getattr(api_key_entry, 'id', 'key')}"
355
+
356
+ def _role_in_company(self, company_short_name: str, user_identifier: str) -> str | None:
357
+ return self.profile_service.get_role_in_company(company_short_name, user_identifier)
328
358
 
329
359
  def verify_for_company(self, company_short_name: str, anonymous: bool = False) -> dict:
330
360
  """
@@ -396,6 +396,20 @@ class ProfileService:
396
396
  "profile": profile
397
397
  }
398
398
 
399
+ def get_role_in_company(self, company_short_name: str, user_identifier: str) -> str | None:
400
+ """
401
+ The person's role in the company as iat_user_company records it; None if
402
+ not a member. Every authorization reads the role here, never from the
403
+ stored session profile: an SSO hook writes that profile (BL-010, Fase 0).
404
+ """
405
+ try:
406
+ company = self.profile_repo.get_company_by_short_name(company_short_name)
407
+ user = self.profile_repo.get_user_by_email(str(user_identifier or "").strip().lower()) if company else None
408
+ return self.profile_repo.get_user_role_in_company(company.id, user.id) if user else None
409
+ except Exception as exc:
410
+ logging.warning("Role of %s in %s could not be read: %s", user_identifier, company_short_name, exc)
411
+ return None
412
+
399
413
  def _account_user(self, company_short_name: str, session_info: dict):
400
414
  profile = session_info.get("profile") or {}
401
415
  method = (profile.get("extras") or {}).get("auth_method")
@@ -56,7 +56,8 @@ class ApiKeyApiView(MethodView):
56
56
 
57
57
  data = request.get_json() or {}
58
58
  key_name = (data.get("key_name") or "").strip()
59
- result = self.api_key_service.create_api_key_entry(company_short_name, key_name)
59
+ result = self.api_key_service.create_api_key_entry(
60
+ company_short_name, key_name, can_act_for_users=bool(data.get("can_act_for_users")))
60
61
  return self._build_response(result, success_status_code=201)
61
62
 
62
63
  def put(self, company_short_name: str, api_key_id: int):
@@ -70,12 +71,14 @@ class ApiKeyApiView(MethodView):
70
71
  key_name = key_name.strip()
71
72
 
72
73
  is_active = data["is_active"] if "is_active" in data else None
74
+ can_act_for_users = data["can_act_for_users"] if "can_act_for_users" in data else None
73
75
 
74
76
  result = self.api_key_service.update_api_key_entry(
75
77
  company_short_name=company_short_name,
76
78
  api_key_id=api_key_id,
77
79
  key_name=key_name,
78
- is_active=is_active
80
+ is_active=is_active,
81
+ can_act_for_users=can_act_for_users,
79
82
  )
80
83
  return self._build_response(result, success_status_code=200)
81
84
 
@@ -10,6 +10,7 @@ class UsersApiView(MethodView):
10
10
  """
11
11
  list company users and their roles
12
12
  """
13
+ MANAGER_ROLES = {"editor", "admin", "owner"}
13
14
  @inject
14
15
  def __init__(self,
15
16
  auth_service: AuthService,
@@ -22,6 +23,10 @@ class UsersApiView(MethodView):
22
23
  auth_result = self.auth_service.verify_for_company(company_short_name, anonymous=True)
23
24
  if not auth_result.get("success"):
24
25
  return jsonify(auth_result), auth_result.get("status_code", 401)
26
+ # Who is in the company and with which role is for the people who run it
27
+ # (the admin's Team screen), not for every user (BL-010, Fase 0).
28
+ if "user_role" in auth_result and str(auth_result.get("user_role") or "").lower() not in self.MANAGER_ROLES:
29
+ return jsonify({"error": "Forbidden"}), 403
25
30
 
26
31
  # get users of the company
27
32
  users = self.profile_service.get_company_users(company_short_name)
@@ -59,8 +59,8 @@ class WikiPageView(MethodView):
59
59
  next=request.full_path.rstrip('?')))
60
60
 
61
61
  page_kwargs = {"wiki_key": wiki_key, "path": page_path or "/", "user_identifier": user_identifier}
62
- # The role lives in the session's profile (ProfileService.get_current_session_info).
63
- user_role = (session_info.get('profile') or {}).get('user_role') or session_info.get('user_role')
62
+ # From the database, never from the session profile (an SSO hook writes it).
63
+ user_role = self.profile_service.get_role_in_company(company_short_name, user_identifier)
64
64
  if self.tenant_wiki_service.viewer_may_read_system_wiki(company_short_name, wiki_key, user_role):
65
65
  # A system wiki its feature opened to this role (Memoria for admin and owner).
66
66
  page_kwargs["include_system"] = True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iatoolkit
3
- Version: 2.69.0
3
+ Version: 2.70.0
4
4
  Summary: IAToolkit
5
5
  Author: Fernando Libedinsky
6
6
  License-Expression: MIT
File without changes
File without changes
File without changes
File without changes