cornflow 1.2.3a4__tar.gz → 1.2.4__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 (188) hide show
  1. {cornflow-1.2.3a4/cornflow.egg-info → cornflow-1.2.4}/PKG-INFO +3 -3
  2. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/app.py +24 -8
  3. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/cli/service.py +2 -1
  4. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/commands/auxiliar.py +12 -3
  5. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/commands/permissions.py +32 -11
  6. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/commands/roles.py +1 -1
  7. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/commands/views.py +3 -0
  8. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/config.py +4 -4
  9. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/__init__.py +27 -0
  10. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/permission.py +1 -2
  11. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/signup.py +17 -11
  12. cornflow-1.2.4/cornflow/shared/authentication/decorators.py +73 -0
  13. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/shared/const.py +15 -1
  14. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_apiview.py +7 -1
  15. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_cli.py +6 -3
  16. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_commands.py +2 -1
  17. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_external_role_creation.py +246 -0
  18. cornflow-1.2.4/cornflow/tests/unit/test_get_resources.py +103 -0
  19. cornflow-1.2.4/cornflow/tests/unit/test_sign_up.py +297 -0
  20. {cornflow-1.2.3a4 → cornflow-1.2.4/cornflow.egg-info}/PKG-INFO +3 -3
  21. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow.egg-info/SOURCES.txt +1 -0
  22. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow.egg-info/requires.txt +2 -2
  23. {cornflow-1.2.3a4 → cornflow-1.2.4}/requirements.txt +2 -2
  24. {cornflow-1.2.3a4 → cornflow-1.2.4}/setup.py +1 -1
  25. cornflow-1.2.3a4/cornflow/shared/authentication/decorators.py +0 -42
  26. cornflow-1.2.3a4/cornflow/tests/unit/test_sign_up.py +0 -122
  27. {cornflow-1.2.3a4 → cornflow-1.2.4}/MANIFEST.in +0 -0
  28. {cornflow-1.2.3a4 → cornflow-1.2.4}/README.rst +0 -0
  29. {cornflow-1.2.3a4 → cornflow-1.2.4}/airflow_config/__init__.py +0 -0
  30. {cornflow-1.2.3a4 → cornflow-1.2.4}/airflow_config/airflow_local_settings.py +0 -0
  31. {cornflow-1.2.3a4 → cornflow-1.2.4}/airflow_config/plugins/XCom/__init__.py +0 -0
  32. {cornflow-1.2.3a4 → cornflow-1.2.4}/airflow_config/plugins/XCom/gce_xcom_backend.py +0 -0
  33. {cornflow-1.2.3a4 → cornflow-1.2.4}/airflow_config/plugins/__init__.py +0 -0
  34. {cornflow-1.2.3a4 → cornflow-1.2.4}/airflow_config/webserver_ldap.py +0 -0
  35. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/__init__.py +0 -0
  36. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/cli/__init__.py +0 -0
  37. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/cli/actions.py +0 -0
  38. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/cli/arguments.py +0 -0
  39. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/cli/config.py +0 -0
  40. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/cli/migrations.py +0 -0
  41. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/cli/permissions.py +0 -0
  42. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/cli/roles.py +0 -0
  43. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/cli/schemas.py +0 -0
  44. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/cli/tools/__init__.py +0 -0
  45. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/cli/tools/api_generator.py +0 -0
  46. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/cli/tools/endpoint_tools.py +0 -0
  47. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/cli/tools/models_tools.py +0 -0
  48. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/cli/tools/schema_generator.py +0 -0
  49. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/cli/tools/schemas_tools.py +0 -0
  50. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/cli/tools/tools.py +0 -0
  51. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/cli/users.py +0 -0
  52. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/cli/utils.py +0 -0
  53. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/cli/views.py +0 -0
  54. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/commands/__init__.py +0 -0
  55. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/commands/access.py +0 -0
  56. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/commands/actions.py +0 -0
  57. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/commands/cleanup.py +0 -0
  58. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/commands/dag.py +0 -0
  59. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/commands/schemas.py +0 -0
  60. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/commands/users.py +0 -0
  61. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/action.py +0 -0
  62. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/alarms.py +0 -0
  63. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/apiview.py +0 -0
  64. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/case.py +0 -0
  65. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/dag.py +0 -0
  66. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/data_check.py +0 -0
  67. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/example_data.py +0 -0
  68. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/execution.py +0 -0
  69. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/health.py +0 -0
  70. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/instance.py +0 -0
  71. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/licenses.py +0 -0
  72. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/login.py +0 -0
  73. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/main_alarms.py +0 -0
  74. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/meta_resource.py +0 -0
  75. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/roles.py +0 -0
  76. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/schemas.py +0 -0
  77. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/tables.py +0 -0
  78. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/token.py +0 -0
  79. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/user.py +0 -0
  80. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/endpoints/user_role.py +0 -0
  81. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/gunicorn.py +0 -0
  82. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/migrations/README +0 -0
  83. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/migrations/alembic.ini +0 -0
  84. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/migrations/env.py +0 -0
  85. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/migrations/script.py.mako +0 -0
  86. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/migrations/versions/00757b557b02_.py +0 -0
  87. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/migrations/versions/1af47a419bbd_.py +0 -0
  88. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/migrations/versions/4aac5e0c6e66_.py +0 -0
  89. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/migrations/versions/7c3ea5ab5501_.py +0 -0
  90. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/migrations/versions/991b98e24225_.py +0 -0
  91. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/migrations/versions/a472b5ad50b7_.py +0 -0
  92. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/migrations/versions/c2db9409cb5f_.py +0 -0
  93. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/migrations/versions/c8a6c762e818_.py +0 -0
  94. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/migrations/versions/ca449af8034c_.py +0 -0
  95. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/migrations/versions/d0e0700dcd8e_.py +0 -0
  96. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/migrations/versions/d1b5be1f0549_.py +0 -0
  97. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/migrations/versions/e1a50dae1ac9_.py +0 -0
  98. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/migrations/versions/e937a5234ce4_.py +0 -0
  99. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/migrations/versions/ebdd955fcc5e_.py +0 -0
  100. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/migrations/versions/f3bee20314a2_.py +0 -0
  101. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/models/__init__.py +0 -0
  102. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/models/action.py +0 -0
  103. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/models/alarms.py +0 -0
  104. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/models/base_data_model.py +0 -0
  105. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/models/case.py +0 -0
  106. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/models/dag.py +0 -0
  107. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/models/dag_permissions.py +0 -0
  108. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/models/execution.py +0 -0
  109. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/models/instance.py +0 -0
  110. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/models/main_alarms.py +0 -0
  111. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/models/meta_models.py +0 -0
  112. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/models/permissions.py +0 -0
  113. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/models/role.py +0 -0
  114. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/models/user.py +0 -0
  115. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/models/user_role.py +0 -0
  116. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/models/view.py +0 -0
  117. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/__init__.py +0 -0
  118. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/action.py +0 -0
  119. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/alarms.py +0 -0
  120. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/case.py +0 -0
  121. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/common.py +0 -0
  122. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/dag.py +0 -0
  123. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/example_data.py +0 -0
  124. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/execution.py +0 -0
  125. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/health.py +0 -0
  126. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/instance.py +0 -0
  127. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/main_alarms.py +0 -0
  128. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/model_json.py +0 -0
  129. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/patch.py +0 -0
  130. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/permissions.py +0 -0
  131. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/query.py +0 -0
  132. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/role.py +0 -0
  133. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/schemas.py +0 -0
  134. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/solution_log.py +0 -0
  135. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/tables.py +0 -0
  136. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/user.py +0 -0
  137. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/user_role.py +0 -0
  138. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/schemas/view.py +0 -0
  139. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/shared/__init__.py +0 -0
  140. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/shared/authentication/__init__.py +0 -0
  141. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/shared/authentication/auth.py +0 -0
  142. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/shared/authentication/ldap.py +0 -0
  143. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/shared/compress.py +0 -0
  144. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/shared/email.py +0 -0
  145. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/shared/exceptions.py +0 -0
  146. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/shared/licenses.py +0 -0
  147. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/shared/log_config.py +0 -0
  148. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/shared/query_tools.py +0 -0
  149. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/shared/utils.py +0 -0
  150. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/shared/utils_tables.py +0 -0
  151. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/shared/validators.py +0 -0
  152. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/__init__.py +0 -0
  153. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/const.py +0 -0
  154. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/custom_liveServer.py +0 -0
  155. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/custom_test_case.py +0 -0
  156. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/integration/__init__.py +0 -0
  157. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/integration/test_commands.py +0 -0
  158. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/integration/test_cornflowclient.py +0 -0
  159. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/ldap/__init__.py +0 -0
  160. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/ldap/test_ldap_authentication.py +0 -0
  161. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/__init__.py +0 -0
  162. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_actions.py +0 -0
  163. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_alarms.py +0 -0
  164. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_application.py +0 -0
  165. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_cases.py +0 -0
  166. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_dags.py +0 -0
  167. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_data_checks.py +0 -0
  168. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_example_data.py +0 -0
  169. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_executions.py +0 -0
  170. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_generate_from_schema.py +0 -0
  171. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_health.py +0 -0
  172. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_instances.py +0 -0
  173. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_instances_file.py +0 -0
  174. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_licenses.py +0 -0
  175. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_log_in.py +0 -0
  176. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_main_alarms.py +0 -0
  177. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_permissions.py +0 -0
  178. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_roles.py +0 -0
  179. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_schema_from_models.py +0 -0
  180. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_schemas.py +0 -0
  181. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_tables.py +0 -0
  182. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_token.py +0 -0
  183. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/test_users.py +0 -0
  184. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow/tests/unit/tools.py +0 -0
  185. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow.egg-info/dependency_links.txt +0 -0
  186. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow.egg-info/entry_points.txt +0 -0
  187. {cornflow-1.2.3a4 → cornflow-1.2.4}/cornflow.egg-info/top_level.txt +0 -0
  188. {cornflow-1.2.3a4 → cornflow-1.2.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cornflow
3
- Version: 1.2.3a4
3
+ Version: 1.2.4
4
4
  Summary: cornflow is an open source multi-solver optimization server with a REST API built using flask.
5
5
  Home-page: https://github.com/baobabsoluciones/cornflow
6
6
  Author: baobab soluciones
@@ -14,7 +14,7 @@ Requires-Dist: alembic==1.9.2
14
14
  Requires-Dist: apispec<=6.3.0
15
15
  Requires-Dist: cachetools==5.3.3
16
16
  Requires-Dist: click<=8.1.7
17
- Requires-Dist: cornflow-client>=1.2.3.a4
17
+ Requires-Dist: cornflow-client<=1.2.4
18
18
  Requires-Dist: cryptography<=44.0.1
19
19
  Requires-Dist: disposable-email-domains>=0.0.86
20
20
  Requires-Dist: Flask==2.3.2
@@ -37,7 +37,7 @@ Requires-Dist: PuLP<=2.9.0
37
37
  Requires-Dist: psycopg2<=2.9.9
38
38
  Requires-Dist: PyJWT<=2.8.0
39
39
  Requires-Dist: pytups>=0.86.2
40
- Requires-Dist: requests<=2.32.3
40
+ Requires-Dist: requests<=2.32.4
41
41
  Requires-Dist: SQLAlchemy==1.3.21
42
42
  Requires-Dist: webargs<=8.3.0
43
43
  Requires-Dist: Werkzeug==3.0.6
@@ -4,6 +4,8 @@ Main file with the creation of the app logic
4
4
 
5
5
  # Full imports
6
6
  import os
7
+ from logging.config import dictConfig
8
+
7
9
  import click
8
10
 
9
11
  # Partial imports
@@ -13,9 +15,8 @@ from flask_apispec.extension import FlaskApiSpec
13
15
  from flask_cors import CORS
14
16
  from flask_migrate import Migrate
15
17
  from flask_restful import Api
16
- from logging.config import dictConfig
17
- from werkzeug.middleware.dispatcher import DispatcherMiddleware
18
18
  from werkzeug.exceptions import NotFound
19
+ from werkzeug.middleware.dispatcher import DispatcherMiddleware
19
20
 
20
21
  # Module imports
21
22
  from cornflow.commands import (
@@ -36,7 +37,14 @@ from cornflow.endpoints.login import LoginEndpoint, LoginOpenAuthEndpoint
36
37
  from cornflow.endpoints.signup import SignUpEndpoint
37
38
  from cornflow.shared import db, bcrypt
38
39
  from cornflow.shared.compress import init_compress
39
- from cornflow.shared.const import AUTH_DB, AUTH_LDAP, AUTH_OID
40
+ from cornflow.shared.const import (
41
+ AUTH_DB,
42
+ AUTH_LDAP,
43
+ AUTH_OID,
44
+ CONDITIONAL_ENDPOINTS,
45
+ SIGNUP_WITH_AUTH,
46
+ SIGNUP_WITH_NO_AUTH,
47
+ )
40
48
  from cornflow.shared.exceptions import initialize_errorhandlers, ConfigurationError
41
49
  from cornflow.shared.log_config import log_config
42
50
 
@@ -95,13 +103,21 @@ def create_app(env_name="development", dataconn=None):
95
103
 
96
104
  if auth_type == AUTH_DB:
97
105
  signup_activated = int(app.config["SIGNUP_ACTIVATED"])
98
- if signup_activated == 1:
99
- api.add_resource(SignUpEndpoint, "/signup/", endpoint="signup")
100
- api.add_resource(LoginEndpoint, "/login/", endpoint="login")
106
+ if signup_activated in [SIGNUP_WITH_AUTH, SIGNUP_WITH_NO_AUTH]:
107
+ api.add_resource(
108
+ SignUpEndpoint, CONDITIONAL_ENDPOINTS["signup"], endpoint="signup"
109
+ )
110
+ api.add_resource(
111
+ LoginEndpoint, CONDITIONAL_ENDPOINTS["login"], endpoint="login"
112
+ )
101
113
  elif auth_type == AUTH_LDAP:
102
- api.add_resource(LoginEndpoint, "/login/", endpoint="login")
114
+ api.add_resource(
115
+ LoginEndpoint, CONDITIONAL_ENDPOINTS["login"], endpoint="login"
116
+ )
103
117
  elif auth_type == AUTH_OID:
104
- api.add_resource(LoginOpenAuthEndpoint, "/login/", endpoint="login")
118
+ api.add_resource(
119
+ LoginOpenAuthEndpoint, CONDITIONAL_ENDPOINTS["login"], endpoint="login"
120
+ )
105
121
  else:
106
122
  raise ConfigurationError(
107
123
  error="Invalid authentication type",
@@ -36,6 +36,7 @@ from cornflow.shared.const import (
36
36
  ADMIN_ROLE,
37
37
  SERVICE_ROLE,
38
38
  PLANNER_ROLE,
39
+ SIGNUP_WITH_AUTH,
39
40
  )
40
41
  from cornflow.shared import db
41
42
  from cryptography.fernet import Fernet
@@ -171,7 +172,7 @@ def _setup_environment_variables():
171
172
  os.environ["CORNFLOW_LOGGING"] = cornflow_logging
172
173
  open_deployment = os.getenv("OPEN_DEPLOYMENT", 1)
173
174
  os.environ["OPEN_DEPLOYMENT"] = str(open_deployment)
174
- signup_activated = os.getenv("SIGNUP_ACTIVATED", 1)
175
+ signup_activated = os.getenv("SIGNUP_ACTIVATED", SIGNUP_WITH_AUTH)
175
176
  os.environ["SIGNUP_ACTIVATED"] = str(signup_activated)
176
177
  user_access_all_objects = os.getenv("USER_ACCESS_ALL_OBJECTS", 0)
177
178
  os.environ["USER_ACCESS_ALL_OBJECTS"] = str(user_access_all_objects)
@@ -3,7 +3,7 @@ from importlib import import_module
3
3
 
4
4
  from flask import current_app
5
5
 
6
- from cornflow.endpoints import resources, alarms_resources
6
+ from cornflow.endpoints import alarms_resources, get_resources
7
7
  from cornflow.models import RoleModel
8
8
  from cornflow.shared.const import (
9
9
  EXTRA_PERMISSION_ASSIGNATION,
@@ -14,12 +14,16 @@ from cornflow.shared.const import ROLES_MAP
14
14
 
15
15
  def get_all_external(external_app):
16
16
  """
17
- Get all resources and extra permissions.
17
+ Get all resources, extra permissions, and custom roles actions.
18
18
  external_app: If provided, it will get the resources and extra permissions for the external app.
19
19
  """
20
+ # We get base and conditional resources
21
+ resources = get_resources()
22
+
20
23
  if external_app is None:
21
24
  resources_to_register = resources
22
25
  extra_permissions = EXTRA_PERMISSION_ASSIGNATION
26
+ custom_roles_actions = {}
23
27
  if current_app.config["ALARMS_ENDPOINTS"]:
24
28
  resources_to_register = resources + alarms_resources
25
29
  else:
@@ -33,13 +37,18 @@ def get_all_external(external_app):
33
37
  except AttributeError:
34
38
  extra_permissions = EXTRA_PERMISSION_ASSIGNATION
35
39
 
40
+ try:
41
+ custom_roles_actions = external_module.shared.const.CUSTOM_ROLES_ACTIONS
42
+ except AttributeError:
43
+ custom_roles_actions = {}
44
+
36
45
  if current_app.config["ALARMS_ENDPOINTS"]:
37
46
  resources_to_register = (
38
47
  external_module.endpoints.resources + resources + alarms_resources
39
48
  )
40
49
  else:
41
50
  resources_to_register = external_module.endpoints.resources + resources
42
- return resources_to_register, extra_permissions
51
+ return resources_to_register, extra_permissions, custom_roles_actions
43
52
 
44
53
 
45
54
  def get_all_resources(resources_to_register):
@@ -19,15 +19,22 @@ def register_base_permissions_command(external_app: str = None, verbose: bool =
19
19
  external_app: If provided, it will register the permissions for the external app.
20
20
  verbose: If True, it will print the permissions that are being registered.
21
21
  """
22
- # Get all resources and extra permissions
23
- resources_to_register, extra_permissions = get_all_external(external_app)
22
+ # Get all resources, extra permissions, and custom roles actions
23
+ resources_to_register, extra_permissions, custom_roles_actions = get_all_external(
24
+ external_app
25
+ )
26
+
24
27
  # Get all views in the database
25
28
  views_in_db = {view.name: view.id for view in ViewModel.get_all_objects()}
26
29
  permissions_in_db, permissions_in_db_keys = get_db_permissions()
30
+
27
31
  # Get all resources and roles with access
28
32
  resources_roles_with_access = get_all_resources(resources_to_register)
33
+
29
34
  # Get the new roles and base permissions assignation
30
- base_permissions_assignation = get_base_permissions(resources_roles_with_access)
35
+ base_permissions_assignation = get_base_permissions(
36
+ resources_roles_with_access, custom_roles_actions
37
+ )
31
38
  # Get the permissions to register and delete
32
39
  permissions_tuples = get_permissions_in_code_as_tuples(
33
40
  resources_to_register,
@@ -46,12 +53,14 @@ def register_base_permissions_command(external_app: str = None, verbose: bool =
46
53
  save_and_delete_permissions(permissions_to_register, permissions_to_delete)
47
54
 
48
55
  if len(permissions_to_register) > 0:
49
- current_app.logger.info(f"Permissions registered: {permissions_to_register}")
56
+ current_app.logger.info(
57
+ f"Permissions registered: {len(permissions_to_register)}"
58
+ )
50
59
  else:
51
60
  current_app.logger.info("No new permissions to register")
52
61
 
53
62
  if len(permissions_to_delete) > 0:
54
- current_app.logger.info(f"Permissions deleted: {permissions_to_delete}")
63
+ current_app.logger.info(f"Permissions deleted: {len(permissions_to_delete)}")
55
64
  else:
56
65
  current_app.logger.info("No permissions to delete")
57
66
 
@@ -165,11 +174,11 @@ def get_permissions_in_code_as_tuples(
165
174
  return permissions_tuples
166
175
 
167
176
 
168
- def get_base_permissions(resources_roles_with_access):
177
+ def get_base_permissions(resources_roles_with_access, custom_roles_actions):
169
178
  """
170
179
  Get the new roles and base permissions assignation.
171
- new_roles_to_add: List of new roles to add.
172
180
  resources_roles_with_access: Dictionary of resources and roles with access.
181
+ custom_roles_actions: Dictionary mapping custom roles to their allowed actions.
173
182
  """
174
183
  # Get all custom roles (both new and existing) that appear in ROLES_WITH_ACCESS
175
184
  all_custom_roles_in_access = set(
@@ -181,12 +190,24 @@ def get_base_permissions(resources_roles_with_access):
181
190
  ]
182
191
  )
183
192
 
193
+ # Validate that all custom roles are defined in custom_roles_actions
194
+ undefined_roles = all_custom_roles_in_access - set(custom_roles_actions.keys())
195
+ if undefined_roles:
196
+ raise ValueError(
197
+ f"The following custom roles are used in code but not defined in CUSTOM_ROLES_ACTIONS: {undefined_roles}. "
198
+ f"Please define their allowed actions in the CUSTOM_ROLES_ACTIONS dictionary in shared/const.py."
199
+ )
200
+
184
201
  # Create extended permission assignation including all custom roles
185
- # For custom roles (not in ALL_DEFAULT_ROLES), only grant GET access
186
- base_permissions_assignation = BASE_PERMISSION_ASSIGNATION + [
187
- (custom_role, GET_ACTION) for custom_role in all_custom_roles_in_access
202
+ # For custom roles, use the actions defined in custom_roles_actions
203
+ custom_permissions = [
204
+ (custom_role, action)
205
+ for custom_role in all_custom_roles_in_access
206
+ for action in custom_roles_actions[custom_role]
188
207
  ]
189
208
 
209
+ base_permissions_assignation = BASE_PERMISSION_ASSIGNATION + custom_permissions
210
+
190
211
  return base_permissions_assignation
191
212
 
192
213
 
@@ -277,7 +298,7 @@ def register_dag_permissions_command(
277
298
 
278
299
  if verbose:
279
300
  if len(permissions) > 1:
280
- current_app.logger.info(f"DAG permissions registered: {permissions}")
301
+ current_app.logger.info(f"DAG permissions registered: {len(permissions)}")
281
302
  else:
282
303
  current_app.logger.info("No new DAG permissions")
283
304
 
@@ -10,7 +10,7 @@ def register_roles_command(external_app: str = None, verbose: bool = True):
10
10
  get_new_roles_to_add,
11
11
  )
12
12
 
13
- resources_to_register, extra_permissions = get_all_external(external_app)
13
+ resources_to_register, extra_permissions, _ = get_all_external(external_app)
14
14
  resources_roles_with_access = get_all_resources(resources_to_register)
15
15
  new_roles_to_add = get_new_roles_to_add(
16
16
  extra_permissions, resources_roles_with_access
@@ -7,6 +7,8 @@ from sqlalchemy.exc import DBAPIError, IntegrityError
7
7
 
8
8
  from cornflow.endpoints import resources, alarms_resources
9
9
 
10
+ from cornflow.endpoints import alarms_resources, get_resources
11
+
10
12
  # Imports from internal libraries
11
13
  from cornflow.models import ViewModel
12
14
  from cornflow.shared import db
@@ -182,6 +184,7 @@ def get_database_view():
182
184
 
183
185
 
184
186
  def get_resources_to_register(external_app):
187
+ resources = get_resources()
185
188
  if external_app is None:
186
189
  resources_to_register = resources
187
190
  if current_app.config["ALARMS_ENDPOINTS"]:
@@ -1,5 +1,5 @@
1
1
  import os
2
- from .shared.const import AUTH_DB, PLANNER_ROLE, AUTH_OID
2
+ from .shared.const import AUTH_DB, PLANNER_ROLE, AUTH_OID, SIGNUP_WITH_AUTH, SIGNUP_WITH_NO_AUTH
3
3
  from apispec import APISpec
4
4
  from apispec.ext.marshmallow import MarshmallowPlugin
5
5
 
@@ -25,7 +25,7 @@ class DefaultConfig(object):
25
25
  DEBUG = True
26
26
  TESTING = True
27
27
  LOG_LEVEL = int(os.getenv("LOG_LEVEL", 20))
28
- SIGNUP_ACTIVATED = int(os.getenv("SIGNUP_ACTIVATED", 1))
28
+ SIGNUP_ACTIVATED = int(os.getenv("SIGNUP_ACTIVATED", SIGNUP_WITH_AUTH))
29
29
  CORNFLOW_SERVICE_USER = os.getenv("CORNFLOW_SERVICE_USER", "service_user")
30
30
 
31
31
  # If service user is allowed to log with username and password
@@ -119,7 +119,7 @@ class Testing(DefaultConfig):
119
119
  AIRFLOW_PWD = os.getenv("AIRFLOW_PWD", "admin")
120
120
  OPEN_DEPLOYMENT = 1
121
121
  LOG_LEVEL = int(os.getenv("LOG_LEVEL", 10))
122
-
122
+ SIGNUP_ACTIVATED = SIGNUP_WITH_NO_AUTH
123
123
 
124
124
  class TestingOpenAuth(Testing):
125
125
  """
@@ -157,5 +157,5 @@ app_config = {
157
157
  "testing": Testing,
158
158
  "production": Production,
159
159
  "testing-oauth": TestingOpenAuth,
160
- "testing-root": TestingApplicationRoot
160
+ "testing-root": TestingApplicationRoot,
161
161
  }
@@ -4,6 +4,8 @@ All references to endpoints should be imported from here
4
4
  The login resource gets created on app startup as it depends on configuration
5
5
  """
6
6
 
7
+ from flask import current_app
8
+ from cornflow.shared.const import CONDITIONAL_ENDPOINTS
7
9
  from .action import ActionListEndpoint
8
10
  from .alarms import AlarmsEndpoint, AlarmDetailEndpoint
9
11
  from .apiview import ApiViewListEndpoint
@@ -237,3 +239,28 @@ alarms_resources = [
237
239
  endpoint="main-alarms",
238
240
  ),
239
241
  ]
242
+
243
+
244
+ def get_resources():
245
+ """
246
+ Get the resources based on the configuration
247
+
248
+ :return: The resources based on the configuration
249
+ :rtype: list
250
+ """
251
+ base_resources = resources.copy()
252
+ registered_resources = current_app.view_functions.keys()
253
+ for resource in registered_resources:
254
+ if resource in CONDITIONAL_ENDPOINTS.keys():
255
+ # Check if the resource already exists
256
+ if resource not in [
257
+ present_resource["endpoint"] for present_resource in base_resources
258
+ ]:
259
+ base_resources.append(
260
+ dict(
261
+ resource=current_app.view_functions[resource].view_class,
262
+ urls=CONDITIONAL_ENDPOINTS[resource],
263
+ endpoint=resource,
264
+ )
265
+ )
266
+ return base_resources
@@ -1,6 +1,5 @@
1
- """
1
+ """ """
2
2
 
3
- """
4
3
  # Import from libraries
5
4
  from flask_apispec import doc, marshal_with, use_kwargs
6
5
  from flask import current_app
@@ -1,6 +1,7 @@
1
1
  """
2
2
  External endpoint for the user to signup
3
3
  """
4
+
4
5
  # Import from libraries
5
6
  from flask import current_app
6
7
  from flask_apispec import use_kwargs, doc
@@ -9,8 +10,8 @@ from flask_apispec import use_kwargs, doc
9
10
  from cornflow.endpoints.meta_resource import BaseMetaResource
10
11
  from cornflow.models import PermissionsDAG, UserRoleModel, UserModel
11
12
  from cornflow.schemas.user import SignupRequest
12
- from cornflow.shared.authentication import Auth
13
- from cornflow.shared.const import AUTH_LDAP, AUTH_OID
13
+ from cornflow.shared.authentication import Auth, authenticate
14
+ from cornflow.shared.const import AUTH_LDAP, AUTH_OID, ADMIN_ROLE, SIGNUP_WITH_NO_AUTH
14
15
  from cornflow.shared.exceptions import (
15
16
  EndpointNotImplemented,
16
17
  InvalidCredentials,
@@ -23,6 +24,8 @@ class SignUpEndpoint(BaseMetaResource):
23
24
  Endpoint used to sign up to the cornflow web server.
24
25
  """
25
26
 
27
+ ROLES_WITH_ACCESS = [ADMIN_ROLE]
28
+
26
29
  def __init__(self):
27
30
  super().__init__()
28
31
  self.data_model = UserModel
@@ -30,6 +33,11 @@ class SignUpEndpoint(BaseMetaResource):
30
33
  self.user_role_association = UserRoleModel
31
34
 
32
35
  @doc(description="Sign up", tags=["Users"])
36
+ @authenticate(
37
+ auth_class=Auth(),
38
+ optional_auth="SIGNUP_ACTIVATED",
39
+ no_auth_list=[SIGNUP_WITH_NO_AUTH],
40
+ )
33
41
  @use_kwargs(SignupRequest, location="json")
34
42
  def post(self, **kwargs):
35
43
  """
@@ -57,14 +65,12 @@ class SignUpEndpoint(BaseMetaResource):
57
65
  if auth_type == AUTH_LDAP:
58
66
  err = "The user has to sign up on the active directory"
59
67
  raise EndpointNotImplemented(
60
- err,
61
- log_txt="Error while user tries to sign up. " + err
68
+ err, log_txt="Error while user tries to sign up. " + err
62
69
  )
63
70
  elif auth_type == AUTH_OID:
64
71
  err = "The user has to sign up with the OpenID protocol"
65
72
  raise EndpointNotImplemented(
66
- err,
67
- log_txt="Error while user tries to sign up. " + err
73
+ err, log_txt="Error while user tries to sign up. " + err
68
74
  )
69
75
 
70
76
  user = self.data_model(kwargs)
@@ -72,14 +78,13 @@ class SignUpEndpoint(BaseMetaResource):
72
78
  if user.check_username_in_use():
73
79
  raise InvalidCredentials(
74
80
  error="Username already in use, please supply another username",
75
- log_txt="Error while user tries to sign up. Username already in use."
76
-
81
+ log_txt="Error while user tries to sign up. Username already in use.",
77
82
  )
78
83
 
79
84
  if user.check_email_in_use():
80
85
  raise InvalidCredentials(
81
86
  error="Email already in use, please supply another email address",
82
- log_txt="Error while user tries to sign up. Email already in use."
87
+ log_txt="Error while user tries to sign up. Email already in use.",
83
88
  )
84
89
 
85
90
  user.save()
@@ -94,8 +99,9 @@ class SignUpEndpoint(BaseMetaResource):
94
99
  token = self.auth_class.generate_token(user.id)
95
100
  except Exception as e:
96
101
  raise InvalidUsage(
97
- error="Error in generating user token: " + str(e), status_code=400,
98
- log_txt="Error while user tries to sign up. Unable to generate token."
102
+ error="Error in generating user token: " + str(e),
103
+ status_code=400,
104
+ log_txt="Error while user tries to sign up. Unable to generate token.",
99
105
  )
100
106
  current_app.logger.info(f"New user created: {user}")
101
107
  return {"token": token, "id": user.id}, 201
@@ -0,0 +1,73 @@
1
+ """
2
+ This file contains the decorator used for the authentication
3
+ """
4
+
5
+ from functools import wraps
6
+ from .auth import Auth
7
+ from cornflow.shared.exceptions import InvalidCredentials
8
+ from flask import current_app
9
+ import os
10
+
11
+
12
+ def authenticate(
13
+ auth_class: Auth, optional_auth: str = None, no_auth_list: list = None
14
+ ):
15
+ """
16
+ This is the decorator used for the authentication
17
+
18
+ :param auth_class: the class used for the authentication. It should be `BaseAuth` or a class that inherits from it
19
+ and that has a authenticate method.
20
+ :param optional_auth: the env variable that indicates if authentication should be deactivated
21
+ :param no_auth_list: the list of the values that indicates if authentication should be deactivated
22
+ :type auth_class: `BaseAuth`
23
+ :return: the wrapped function
24
+ """
25
+
26
+ def decorator(func: callable):
27
+ """
28
+ The decorator definition
29
+
30
+ :param callable func: the function that gets decorated
31
+ """
32
+
33
+ @wraps(func)
34
+ def wrapper(*args, **kwargs):
35
+ """
36
+ The wrapper to the function that performs the authentication.
37
+
38
+ :param args: the original args sent to the decorated function
39
+ :param kwargs: the original kwargs sent to the decorated function
40
+ :return: the result of the call to the function
41
+ """
42
+ if endpoint_qualified_for_no_auth(no_auth_list, optional_auth):
43
+ # Authentication is deactivated for this value
44
+ return func(*args, **kwargs)
45
+
46
+ if auth_class.authenticate():
47
+ return func(*args, **kwargs)
48
+ else:
49
+ raise InvalidCredentials("Unable to authenticate the user")
50
+ return wrapper
51
+
52
+ return decorator
53
+
54
+ def endpoint_qualified_for_no_auth(no_auth_list, optional_auth):
55
+ """
56
+ This function is used to check if the endpoint is qualified for no authentication.
57
+
58
+ :param no_auth_list: the list of the values that indicates if authentication should be deactivated
59
+ :param optional_auth: the env variable that indicates if authentication should be deactivated
60
+ :type no_auth_list: list
61
+ :type optional_auth: str
62
+ :return: True if the endpoint is qualified for no authentication, False otherwise
63
+ """
64
+ if optional_auth is None:
65
+ return False
66
+ if no_auth_list is None:
67
+ raise InvalidCredentials(
68
+ "The list of the values that indicates if authentication should be deactivated is not defined"
69
+ )
70
+ env_variable = current_app.config[optional_auth]
71
+ if env_variable in no_auth_list:
72
+ return True
73
+ return False
@@ -1,7 +1,8 @@
1
1
  """
2
2
  In this file we import the values for different constants on cornflow server
3
3
  """
4
- CORNFLOW_VERSION = "1.2.3.a4"
4
+
5
+ CORNFLOW_VERSION = "1.2.4"
5
6
  INTERNAL_TOKEN_ISSUER = "cornflow"
6
7
 
7
8
  # endpoints responses for health check
@@ -44,6 +45,13 @@ AIRFLOW_TO_STATE_MAP = dict(
44
45
  failed=EXEC_STATE_ERROR,
45
46
  queued=EXEC_STATE_QUEUED,
46
47
  )
48
+ # SIGNUP OPTIONS
49
+ # NO_SIGNUP: no signup endpoint
50
+ # SIGNUP_WITH_NO_AUTH: signup endpoint with no auth
51
+ # SIGNUP_WITH_AUTH: signup endpoint with auth
52
+ NO_SIGNUP = 0
53
+ SIGNUP_WITH_NO_AUTH = 1
54
+ SIGNUP_WITH_AUTH = 2
47
55
 
48
56
  # These codes and names are inherited from flask app builder in order to have the same names and values
49
57
  # as this library that is the base of airflow
@@ -121,3 +129,9 @@ AIRFLOW_NOT_REACHABLE_MSG = "Airflow is not reachable"
121
129
  DAG_PAUSED_MSG = "The dag exists but it is paused in airflow"
122
130
  AIRFLOW_ERROR_MSG = "Airflow responded with an error:"
123
131
  DATA_DOES_NOT_EXIST_MSG = "The data entity does not exist on the database"
132
+
133
+ # Conditional endpoints
134
+ CONDITIONAL_ENDPOINTS = {
135
+ "signup": "/signup/",
136
+ "login": "/login/",
137
+ }
@@ -13,7 +13,7 @@ TestApiViewListEndpoint
13
13
  """
14
14
 
15
15
  # Import from internal modules
16
- from cornflow.endpoints import ApiViewListEndpoint, resources, alarms_resources
16
+ from cornflow.endpoints import ApiViewListEndpoint, alarms_resources, get_resources
17
17
  from cornflow.models import ViewModel
18
18
  from cornflow.shared.const import ROLES_MAP
19
19
  from cornflow.tests.const import APIVIEW_URL
@@ -42,6 +42,8 @@ class TestApiViewListEndpoint(CustomTestCase):
42
42
  """
43
43
  super().setUp()
44
44
  self.roles_with_access = ApiViewListEndpoint.ROLES_WITH_ACCESS
45
+ # Get resources within application context
46
+ resources = get_resources()
45
47
  self.payload = [
46
48
  {
47
49
  "name": view["endpoint"],
@@ -127,6 +129,8 @@ class TestApiViewModel(CustomTestCase):
127
129
  """
128
130
  super().setUp()
129
131
  self.roles_with_access = ApiViewListEndpoint.ROLES_WITH_ACCESS
132
+ # Get resources within application context
133
+ resources = get_resources()
130
134
  self.payload = [
131
135
  {
132
136
  "name": view["endpoint"],
@@ -141,6 +145,8 @@ class TestApiViewModel(CustomTestCase):
141
145
  """
142
146
  Test that the get_all_objects method works properly
143
147
  """
148
+ # Get resources within application context
149
+ resources = get_resources()
144
150
  expected_count = len(resources) + len(alarms_resources)
145
151
  # Test getting all objects
146
152
  all_instances = ViewModel.get_all_objects().all()
@@ -33,7 +33,7 @@ from cornflow.models import (
33
33
  from cornflow.models import UserModel
34
34
  from cornflow.shared import db
35
35
  from cornflow.shared.exceptions import NoPermission, ObjectDoesNotExist
36
- from cornflow.endpoints import resources, alarms_resources
36
+ from cornflow.endpoints import alarms_resources, get_resources
37
37
 
38
38
 
39
39
  class CLITests(TestCase):
@@ -278,6 +278,7 @@ class CLITests(TestCase):
278
278
  - Correct number of views created
279
279
  - Database state after initialization
280
280
  """
281
+ resources = get_resources()
281
282
  runner = CliRunner()
282
283
  result = runner.invoke(cli, ["views", "init", "-v"])
283
284
  self.assertEqual(result.exit_code, 0)
@@ -315,6 +316,7 @@ class CLITests(TestCase):
315
316
  - Correct number of actions, roles, views, and permissions
316
317
  - Database state after initialization
317
318
  """
319
+ resources = get_resources()
318
320
  runner = CliRunner()
319
321
  result = runner.invoke(cli, ["permissions", "init", "-v"])
320
322
  self.assertEqual(result.exit_code, 0)
@@ -325,7 +327,7 @@ class CLITests(TestCase):
325
327
  self.assertEqual(len(actions), 5)
326
328
  self.assertEqual(len(roles), 4)
327
329
  self.assertEqual(len(views), (len(resources) + len(alarms_resources)))
328
- self.assertEqual(len(permissions), 562)
330
+ self.assertEqual(len(permissions), 583)
329
331
 
330
332
  def test_permissions_base_command(self):
331
333
  """
@@ -337,6 +339,7 @@ class CLITests(TestCase):
337
339
  - Correct setup of all permission components
338
340
  - Database state consistency
339
341
  """
342
+ resources = get_resources()
340
343
  runner = CliRunner()
341
344
  runner.invoke(cli, ["actions", "init", "-v"])
342
345
  runner.invoke(cli, ["roles", "init", "-v"])
@@ -350,7 +353,7 @@ class CLITests(TestCase):
350
353
  self.assertEqual(len(actions), 5)
351
354
  self.assertEqual(len(roles), 4)
352
355
  self.assertEqual(len(views), (len(resources) + len(alarms_resources)))
353
- self.assertEqual(len(permissions), 562)
356
+ self.assertEqual(len(permissions), 583)
354
357
 
355
358
  def test_service_entrypoint(self):
356
359
  """
@@ -31,7 +31,7 @@ from cornflow.app import (
31
31
  register_views,
32
32
  )
33
33
  from cornflow.commands.dag import register_deployed_dags_command_test
34
- from cornflow.endpoints import resources, alarms_resources
34
+ from cornflow.endpoints import alarms_resources, get_resources
35
35
  from cornflow.models import (
36
36
  ActionModel,
37
37
  PermissionViewRoleModel,
@@ -98,6 +98,7 @@ class TestCommands(TestCase):
98
98
  "email": "testemail@test.org",
99
99
  "password": "Testpassword1!",
100
100
  }
101
+ resources = get_resources()
101
102
  self.resources = resources + alarms_resources
102
103
  self.runner = self.create_app().test_cli_runner()
103
104
  self.runner.invoke(register_roles, ["-v"])