cornflow 1.2.3a1__py3-none-any.whl → 1.2.3a2__py3-none-any.whl
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/commands/permissions.py +24 -2
- cornflow/shared/const.py +1 -1
- cornflow/tests/unit/test_commands.py +57 -0
- {cornflow-1.2.3a1.dist-info → cornflow-1.2.3a2.dist-info}/METADATA +1 -1
- {cornflow-1.2.3a1.dist-info → cornflow-1.2.3a2.dist-info}/RECORD +8 -8
- {cornflow-1.2.3a1.dist-info → cornflow-1.2.3a2.dist-info}/WHEEL +0 -0
- {cornflow-1.2.3a1.dist-info → cornflow-1.2.3a2.dist-info}/entry_points.txt +0 -0
- {cornflow-1.2.3a1.dist-info → cornflow-1.2.3a2.dist-info}/top_level.txt +0 -0
cornflow/commands/permissions.py
CHANGED
@@ -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
|
] + [
|
cornflow/shared/const.py
CHANGED
@@ -584,3 +584,60 @@ class TestCommands(TestCase):
|
|
584
584
|
finally:
|
585
585
|
# Restore original ROLES_WITH_ACCESS to avoid affecting other tests
|
586
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
|
@@ -32,7 +32,7 @@ cornflow/commands/access.py,sha256=NTZJFF9la8TDuMcD_ISQtJTj-wtM2p1dddokQJHtkj0,7
|
|
32
32
|
cornflow/commands/actions.py,sha256=4AwgAmyI6VeaugkISvTlNGrIzMMU_-ZB3MhwDD_CIEA,1544
|
33
33
|
cornflow/commands/cleanup.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
34
34
|
cornflow/commands/dag.py,sha256=AtagFGnB_ucfO0qUawDgd4iRoBCVc-RiOs08DqXSwXM,3786
|
35
|
-
cornflow/commands/permissions.py,sha256=
|
35
|
+
cornflow/commands/permissions.py,sha256=xrAVNjipabc1SWt3TApRdoVsHjtfmpEPnC6vXmmhLWs,7412
|
36
36
|
cornflow/commands/roles.py,sha256=Oux-UkswkQ74zqaMEJYIEsZpQZGBcGaSahVzx9feAHU,1516
|
37
37
|
cornflow/commands/schemas.py,sha256=40dZSJ2nEqBa7Crb6DbFmnclT5e8ljAIjscOgHr9lhk,1970
|
38
38
|
cornflow/commands/users.py,sha256=2YTbNYY5kZL6ujxGP4fyYgqtv5uuVGdkLR31n7OFFaE,2477
|
@@ -119,7 +119,7 @@ cornflow/schemas/user_role.py,sha256=e5y6RgdZZtLqD-h2B3sa5WokI5-pT78tWw85IG34I74
|
|
119
119
|
cornflow/schemas/view.py,sha256=ctq9Y1TmjrWdyOqgDYeEx7qbbuNLKfSiNOlFTlXmpaw,429
|
120
120
|
cornflow/shared/__init__.py,sha256=1ahcBwWOsSjGI4FEm77JBQjitBdBszOncKcEMjzwGYE,29
|
121
121
|
cornflow/shared/compress.py,sha256=pohQaGs1xbH8CN6URIH6BAHA--pFq7Hmjz8oI3c3B5c,1347
|
122
|
-
cornflow/shared/const.py,sha256=
|
122
|
+
cornflow/shared/const.py,sha256=iyD9RFf0z7NyGvZJtNGLIAbsxYYcG3IpRbke72pl-7A,3555
|
123
123
|
cornflow/shared/email.py,sha256=QNDDMv86LZObkevSCyUbLQeR2UD3zWScPIr82NDzYHQ,3437
|
124
124
|
cornflow/shared/exceptions.py,sha256=E82488IiwTXCv8iwrnGvkTonhJcwbeE5ARO4Zsmhl2c,6966
|
125
125
|
cornflow/shared/licenses.py,sha256=Lc71Jw2NxVTFWtoXdQ9wJX_o3BDfYg1xVoehDXvnCkQ,1328
|
@@ -148,7 +148,7 @@ cornflow/tests/unit/test_apiview.py,sha256=03M1GsQRVK7zqmslhOJXr4lLDLY2gMAgg86nk
|
|
148
148
|
cornflow/tests/unit/test_application.py,sha256=ZVmTQDUOkPRxHqt6mWU9G_lQ3jJNMJR0cx7IkLMFGrU,1715
|
149
149
|
cornflow/tests/unit/test_cases.py,sha256=Ez9dxlZL-SUf9DW9b_A_qPowHqUZ-TA73DMOzeBeLIU,37718
|
150
150
|
cornflow/tests/unit/test_cli.py,sha256=E2w-Lzgx_k__0mYwlbg2z80_z9nwPZKI0CbgyGmpQRY,18775
|
151
|
-
cornflow/tests/unit/test_commands.py,sha256=
|
151
|
+
cornflow/tests/unit/test_commands.py,sha256=EcaZh1DsA3HgHx5NhpIJKcnUn8KDcnyk2QajhwGs6Yk,21063
|
152
152
|
cornflow/tests/unit/test_dags.py,sha256=XsOi5bBJQdQz3DmYAVJf1myoAsRyBBdmku-xBr0Bku0,13386
|
153
153
|
cornflow/tests/unit/test_data_checks.py,sha256=6s50d1iuRTUcAYn14oEcRS39ZZ6E9ussU4YpkpYhtC4,8612
|
154
154
|
cornflow/tests/unit/test_example_data.py,sha256=D-Tgnqw7NZlnBXaDcUU0reNhAca5JlJP2Sdn3KdS4Sw,4127
|
@@ -169,8 +169,8 @@ cornflow/tests/unit/test_tables.py,sha256=SW_K8LRLwR1nB0uH8CPQCjeN8Gei-TasAgkOin
|
|
169
169
|
cornflow/tests/unit/test_token.py,sha256=PZ11b46UCQpCESsRiAPhpgWkGAsAwKCVNxVQai_kxXM,4199
|
170
170
|
cornflow/tests/unit/test_users.py,sha256=N5tcF5nSncD0F_ZlBxGuS87p6kNS4hUzRLr3_AcnK-o,22802
|
171
171
|
cornflow/tests/unit/tools.py,sha256=ag3sWv2WLi498R1GL5AOUnXqSsszD3UugzLZLC5NqAw,585
|
172
|
-
cornflow-1.2.
|
173
|
-
cornflow-1.2.
|
174
|
-
cornflow-1.2.
|
175
|
-
cornflow-1.2.
|
176
|
-
cornflow-1.2.
|
172
|
+
cornflow-1.2.3a2.dist-info/METADATA,sha256=FFezXKR-SO1Jiu61BODNGQ8Bkva4mCNw02isDt9XwEc,9529
|
173
|
+
cornflow-1.2.3a2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
174
|
+
cornflow-1.2.3a2.dist-info/entry_points.txt,sha256=q9cPKAFBsmHkERCqQ2JcOTM-tVBLHTl-DGxwCXowAWM,46
|
175
|
+
cornflow-1.2.3a2.dist-info/top_level.txt,sha256=Qj9kLFJW1PLb-ZV2s_aCkQ-Wi5W6KC6fFR-LTBrx-rU,24
|
176
|
+
cornflow-1.2.3a2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|