cornflow 1.2.2__tar.gz → 1.2.3a2__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.
- {cornflow-1.2.2/cornflow.egg-info → cornflow-1.2.3a2}/PKG-INFO +2 -2
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/commands/permissions.py +27 -5
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/shared/const.py +1 -1
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_commands.py +147 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2/cornflow.egg-info}/PKG-INFO +2 -2
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow.egg-info/requires.txt +1 -1
- {cornflow-1.2.2 → cornflow-1.2.3a2}/requirements.txt +1 -1
- {cornflow-1.2.2 → cornflow-1.2.3a2}/setup.py +1 -1
- {cornflow-1.2.2 → cornflow-1.2.3a2}/MANIFEST.in +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/README.rst +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/airflow_config/__init__.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/airflow_config/airflow_local_settings.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/airflow_config/plugins/XCom/__init__.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/airflow_config/plugins/XCom/gce_xcom_backend.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/airflow_config/plugins/__init__.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/airflow_config/webserver_ldap.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/__init__.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/app.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/cli/__init__.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/cli/actions.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/cli/arguments.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/cli/config.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/cli/migrations.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/cli/permissions.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/cli/roles.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/cli/schemas.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/cli/service.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/cli/tools/__init__.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/cli/tools/api_generator.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/cli/tools/endpoint_tools.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/cli/tools/models_tools.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/cli/tools/schema_generator.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/cli/tools/schemas_tools.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/cli/tools/tools.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/cli/users.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/cli/utils.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/cli/views.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/commands/__init__.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/commands/access.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/commands/actions.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/commands/cleanup.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/commands/dag.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/commands/roles.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/commands/schemas.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/commands/users.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/commands/views.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/config.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/__init__.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/action.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/alarms.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/apiview.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/case.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/dag.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/data_check.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/example_data.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/execution.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/health.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/instance.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/licenses.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/login.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/main_alarms.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/meta_resource.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/permission.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/roles.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/schemas.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/signup.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/tables.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/token.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/user.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/endpoints/user_role.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/gunicorn.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/migrations/README +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/migrations/alembic.ini +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/migrations/env.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/migrations/script.py.mako +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/migrations/versions/00757b557b02_.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/migrations/versions/1af47a419bbd_.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/migrations/versions/4aac5e0c6e66_.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/migrations/versions/7c3ea5ab5501_.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/migrations/versions/991b98e24225_.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/migrations/versions/a472b5ad50b7_.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/migrations/versions/c2db9409cb5f_.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/migrations/versions/c8a6c762e818_.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/migrations/versions/ca449af8034c_.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/migrations/versions/d0e0700dcd8e_.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/migrations/versions/d1b5be1f0549_.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/migrations/versions/e1a50dae1ac9_.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/migrations/versions/e937a5234ce4_.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/migrations/versions/ebdd955fcc5e_.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/migrations/versions/f3bee20314a2_.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/models/__init__.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/models/action.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/models/alarms.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/models/base_data_model.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/models/case.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/models/dag.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/models/dag_permissions.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/models/execution.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/models/instance.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/models/main_alarms.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/models/meta_models.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/models/permissions.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/models/role.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/models/user.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/models/user_role.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/models/view.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/__init__.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/action.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/alarms.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/case.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/common.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/dag.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/example_data.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/execution.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/health.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/instance.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/main_alarms.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/model_json.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/patch.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/permissions.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/query.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/role.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/schemas.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/solution_log.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/tables.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/user.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/user_role.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/schemas/view.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/shared/__init__.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/shared/authentication/__init__.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/shared/authentication/auth.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/shared/authentication/decorators.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/shared/authentication/ldap.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/shared/compress.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/shared/email.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/shared/exceptions.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/shared/licenses.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/shared/log_config.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/shared/query_tools.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/shared/utils.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/shared/utils_tables.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/shared/validators.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/__init__.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/const.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/custom_liveServer.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/custom_test_case.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/integration/__init__.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/integration/test_commands.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/integration/test_cornflowclient.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/ldap/__init__.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/ldap/test_ldap_authentication.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/__init__.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_actions.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_alarms.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_apiview.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_application.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_cases.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_cli.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_dags.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_data_checks.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_example_data.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_executions.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_generate_from_schema.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_health.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_instances.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_instances_file.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_licenses.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_log_in.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_main_alarms.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_permissions.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_roles.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_schema_from_models.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_schemas.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_sign_up.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_tables.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_token.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/test_users.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow/tests/unit/tools.py +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow.egg-info/SOURCES.txt +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow.egg-info/dependency_links.txt +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow.egg-info/entry_points.txt +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/cornflow.egg-info/top_level.txt +0 -0
- {cornflow-1.2.2 → cornflow-1.2.3a2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: cornflow
|
3
|
-
Version: 1.2.
|
3
|
+
Version: 1.2.3a2
|
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.
|
17
|
+
Requires-Dist: cornflow-client>=1.2.0
|
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
|
@@ -4,8 +4,14 @@ from importlib import import_module
|
|
4
4
|
from cornflow.shared.const import (
|
5
5
|
BASE_PERMISSION_ASSIGNATION,
|
6
6
|
EXTRA_PERMISSION_ASSIGNATION,
|
7
|
+
ROLES_MAP,
|
8
|
+
GET_ACTION,
|
9
|
+
PATCH_ACTION,
|
10
|
+
POST_ACTION,
|
11
|
+
PUT_ACTION,
|
12
|
+
DELETE_ACTION,
|
7
13
|
)
|
8
|
-
from cornflow.models import ViewModel, PermissionViewRoleModel
|
14
|
+
from cornflow.models import ViewModel, PermissionViewRoleModel, RoleModel
|
9
15
|
from cornflow.shared import db
|
10
16
|
from flask import current_app
|
11
17
|
from sqlalchemy.exc import DBAPIError, IntegrityError
|
@@ -14,6 +20,7 @@ from sqlalchemy.exc import DBAPIError, IntegrityError
|
|
14
20
|
def register_base_permissions_command(external_app: str = None, verbose: bool = False):
|
15
21
|
if external_app is None:
|
16
22
|
from cornflow.endpoints import resources, alarms_resources
|
23
|
+
|
17
24
|
resources_to_register = resources
|
18
25
|
if current_app.config["ALARMS_ENDPOINTS"]:
|
19
26
|
resources_to_register = resources + alarms_resources
|
@@ -31,6 +38,21 @@ def register_base_permissions_command(external_app: str = None, verbose: bool =
|
|
31
38
|
(perm.role_id, perm.action_id, perm.api_view_id) for perm in permissions_in_db
|
32
39
|
]
|
33
40
|
resources_names = [resource["endpoint"] for resource in resources_to_register]
|
41
|
+
roles_in_db = [role.name for role in RoleModel.get_all_objects()]
|
42
|
+
# Check which roles are not in ROLES_MAP
|
43
|
+
roles_not_in_map = [role for role in roles_in_db if role not in ROLES_MAP.keys()]
|
44
|
+
complete_base_assignation = BASE_PERMISSION_ASSIGNATION.copy()
|
45
|
+
if len(roles_not_in_map) > 0:
|
46
|
+
# We add to the complete_base_assignation the roles that are not in ROLES_MAP
|
47
|
+
for role in roles_not_in_map:
|
48
|
+
for action in [
|
49
|
+
GET_ACTION,
|
50
|
+
PATCH_ACTION,
|
51
|
+
POST_ACTION,
|
52
|
+
PUT_ACTION,
|
53
|
+
DELETE_ACTION,
|
54
|
+
]:
|
55
|
+
complete_base_assignation.append((role, action))
|
34
56
|
|
35
57
|
# Create base permissions
|
36
58
|
permissions_in_app = [
|
@@ -41,7 +63,7 @@ def register_base_permissions_command(external_app: str = None, verbose: bool =
|
|
41
63
|
"api_view_id": views_in_db[view["endpoint"]],
|
42
64
|
}
|
43
65
|
)
|
44
|
-
for role, action in
|
66
|
+
for role, action in complete_base_assignation
|
45
67
|
for view in resources_to_register
|
46
68
|
if role in view["resource"].ROLES_WITH_ACCESS
|
47
69
|
] + [
|
@@ -79,9 +101,9 @@ def register_base_permissions_command(external_app: str = None, verbose: bool =
|
|
79
101
|
|
80
102
|
# TODO: for now the permission are not going to get deleted just in case.
|
81
103
|
# We are just going to register new permissions
|
82
|
-
|
83
|
-
|
84
|
-
|
104
|
+
if len(permissions_to_delete) > 0:
|
105
|
+
for permission in permissions_to_delete:
|
106
|
+
db.session.delete(permission)
|
85
107
|
|
86
108
|
try:
|
87
109
|
db.session.commit()
|
@@ -29,6 +29,7 @@ from cornflow.app import (
|
|
29
29
|
register_dag_permissions,
|
30
30
|
register_roles,
|
31
31
|
register_views,
|
32
|
+
register_base_assignations,
|
32
33
|
)
|
33
34
|
from cornflow.commands.dag import register_deployed_dags_command_test
|
34
35
|
from cornflow.endpoints import resources, alarms_resources
|
@@ -494,3 +495,149 @@ class TestCommands(TestCase):
|
|
494
495
|
},
|
495
496
|
)
|
496
497
|
self.assertEqual(403, response.status_code)
|
498
|
+
|
499
|
+
def test_permissions_not_deleted_when_roles_removed_from_code(self):
|
500
|
+
"""
|
501
|
+
Test that permissions are NOT deleted when roles are removed from ROLES_WITH_ACCESS.
|
502
|
+
|
503
|
+
This test demonstrates the current bug: when a role is removed from
|
504
|
+
ROLES_WITH_ACCESS in an endpoint's code, the corresponding permissions
|
505
|
+
in the database are not automatically deleted. This happens because
|
506
|
+
the deletion logic in register_base_permissions_command is commented out.
|
507
|
+
|
508
|
+
The test should currently FAIL to demonstrate the bug exists.
|
509
|
+
"""
|
510
|
+
# First, initialize the access system normally
|
511
|
+
self.runner.invoke(access_init)
|
512
|
+
|
513
|
+
# Get the original ROLES_WITH_ACCESS for ExampleDataListEndpoint
|
514
|
+
from cornflow.endpoints.example_data import ExampleDataListEndpoint
|
515
|
+
|
516
|
+
original_roles = ExampleDataListEndpoint.ROLES_WITH_ACCESS.copy()
|
517
|
+
|
518
|
+
# Verify initial permissions are created for all three roles
|
519
|
+
# Get the view ID for the endpoint
|
520
|
+
from cornflow.models import ViewModel
|
521
|
+
|
522
|
+
view = ViewModel.query.filter_by(name="example-data").first()
|
523
|
+
self.assertIsNotNone(view, "example-data view should exist")
|
524
|
+
|
525
|
+
# Check permissions exist for all original roles
|
526
|
+
from cornflow.shared.const import ACTIONS_MAP
|
527
|
+
from cornflow.models import PermissionViewRoleModel
|
528
|
+
|
529
|
+
# Check GET action permissions (action_id=1 is typically GET)
|
530
|
+
get_action_id = 1
|
531
|
+
initial_permissions = PermissionViewRoleModel.query.filter_by(
|
532
|
+
api_view_id=view.id, action_id=get_action_id
|
533
|
+
).all()
|
534
|
+
|
535
|
+
initial_role_ids = [perm.role_id for perm in initial_permissions]
|
536
|
+
self.assertEqual(
|
537
|
+
len(original_roles),
|
538
|
+
len(initial_permissions),
|
539
|
+
f"Should have permissions for all {len(original_roles)} original roles",
|
540
|
+
)
|
541
|
+
|
542
|
+
# Now simulate removing PLANNER_ROLE from ROLES_WITH_ACCESS
|
543
|
+
from cornflow.shared.const import PLANNER_ROLE, VIEWER_ROLE, ADMIN_ROLE
|
544
|
+
|
545
|
+
modified_roles = [VIEWER_ROLE, ADMIN_ROLE] # Remove PLANNER_ROLE
|
546
|
+
|
547
|
+
# Temporarily modify the ROLES_WITH_ACCESS
|
548
|
+
ExampleDataListEndpoint.ROLES_WITH_ACCESS = modified_roles
|
549
|
+
|
550
|
+
try:
|
551
|
+
|
552
|
+
# Run the permission registration again
|
553
|
+
# (this simulates redeploying the app with modified roles)
|
554
|
+
self.runner.invoke(register_base_assignations, ["-v"])
|
555
|
+
|
556
|
+
# Check permissions after the "code change"
|
557
|
+
updated_permissions = PermissionViewRoleModel.query.filter_by(
|
558
|
+
api_view_id=view.id, action_id=get_action_id
|
559
|
+
).all()
|
560
|
+
|
561
|
+
updated_role_ids = [perm.role_id for perm in updated_permissions]
|
562
|
+
|
563
|
+
# THIS IS THE BUG: The permission for PLANNER_ROLE should be deleted
|
564
|
+
# but it's not because the deletion logic is commented out
|
565
|
+
# So we expect this assertion to FAIL, demonstrating the bug
|
566
|
+
self.assertEqual(
|
567
|
+
len(modified_roles),
|
568
|
+
len(updated_permissions),
|
569
|
+
f"After removing PLANNER_ROLE from code, should only have {len(modified_roles)} permissions, "
|
570
|
+
f"but still has {len(updated_permissions)} permissions. "
|
571
|
+
f"This demonstrates the bug: permissions are not deleted when roles are removed from ROLES_WITH_ACCESS.",
|
572
|
+
)
|
573
|
+
|
574
|
+
# Also check that PLANNER_ROLE permission was actually removed
|
575
|
+
planner_permissions = [
|
576
|
+
perm for perm in updated_permissions if perm.role_id == PLANNER_ROLE
|
577
|
+
]
|
578
|
+
self.assertEqual(
|
579
|
+
0,
|
580
|
+
len(planner_permissions),
|
581
|
+
"PLANNER_ROLE permission should have been deleted but still exists",
|
582
|
+
)
|
583
|
+
|
584
|
+
finally:
|
585
|
+
# Restore original ROLES_WITH_ACCESS to avoid affecting other tests
|
586
|
+
ExampleDataListEndpoint.ROLES_WITH_ACCESS = original_roles
|
587
|
+
|
588
|
+
def test_custom_role_permissions_are_preserved(self):
|
589
|
+
"""
|
590
|
+
Test that permissions for custom roles (not in ROLES_MAP) are preserved
|
591
|
+
during permission synchronization.
|
592
|
+
|
593
|
+
This test verifies that when permissions are synchronized, only permissions
|
594
|
+
for roles defined in ROLES_MAP are subject to deletion, while custom roles
|
595
|
+
added manually to the database are preserved.
|
596
|
+
"""
|
597
|
+
# First, initialize the access system normally
|
598
|
+
self.runner.invoke(access_init)
|
599
|
+
|
600
|
+
# Get a view to work with
|
601
|
+
from cornflow.models import ViewModel, PermissionViewRoleModel, RoleModel
|
602
|
+
|
603
|
+
view = ViewModel.query.filter_by(name="example-data").first()
|
604
|
+
self.assertIsNotNone(view, "example-data view should exist")
|
605
|
+
|
606
|
+
# Create a custom role that is NOT in ROLES_MAP
|
607
|
+
custom_role_id = 999 # Use an ID that's not in ROLES_MAP
|
608
|
+
custom_role = RoleModel({"id": custom_role_id, "name": "custom_role"})
|
609
|
+
custom_role.save()
|
610
|
+
|
611
|
+
# Create a permission for this custom role
|
612
|
+
from cornflow.shared.const import GET_ACTION
|
613
|
+
|
614
|
+
custom_permission = PermissionViewRoleModel(
|
615
|
+
{"role_id": custom_role_id, "action_id": GET_ACTION, "api_view_id": view.id}
|
616
|
+
)
|
617
|
+
custom_permission.save()
|
618
|
+
|
619
|
+
# Verify the custom permission exists
|
620
|
+
custom_perms_before = PermissionViewRoleModel.query.filter_by(
|
621
|
+
role_id=custom_role_id, action_id=GET_ACTION, api_view_id=view.id
|
622
|
+
).all()
|
623
|
+
self.assertEqual(
|
624
|
+
1, len(custom_perms_before), "Custom permission should exist before sync"
|
625
|
+
)
|
626
|
+
|
627
|
+
# Run permission synchronization (this would previously delete custom role permissions)
|
628
|
+
self.runner.invoke(register_base_assignations, ["-v"])
|
629
|
+
|
630
|
+
# Verify the custom permission still exists after synchronization
|
631
|
+
custom_perms_after = PermissionViewRoleModel.query.filter_by(
|
632
|
+
role_id=custom_role_id, action_id=GET_ACTION, api_view_id=view.id
|
633
|
+
).all()
|
634
|
+
self.assertEqual(
|
635
|
+
1,
|
636
|
+
len(custom_perms_after),
|
637
|
+
"Custom role permission should be preserved after synchronization. "
|
638
|
+
"Permissions should only be deleted for roles defined in ROLES_MAP.",
|
639
|
+
)
|
640
|
+
|
641
|
+
# Clean up
|
642
|
+
custom_permission.delete()
|
643
|
+
custom_role.delete()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: cornflow
|
3
|
-
Version: 1.2.
|
3
|
+
Version: 1.2.3a2
|
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.
|
17
|
+
Requires-Dist: cornflow-client>=1.2.0
|
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
|
@@ -9,7 +9,7 @@ with open("requirements.txt", "r") as fh:
|
|
9
9
|
|
10
10
|
setuptools.setup(
|
11
11
|
name="cornflow",
|
12
|
-
version="1.2.
|
12
|
+
version="1.2.3a2",
|
13
13
|
author="baobab soluciones",
|
14
14
|
author_email="cornflow@baobabsoluciones.es",
|
15
15
|
description="cornflow is an open source multi-solver optimization server with a REST API built using flask.",
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|