Skip to content

Commit f33befd

Browse files
[FC-0099] refactor: avoid duplicates when getting role scopes (#137)
1 parent b9414ed commit f33befd

4 files changed

Lines changed: 45 additions & 2 deletions

File tree

CHANGELOG.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ Change Log
1414
Unreleased
1515
**********
1616

17+
0.13.1 - 2025-11-06
18+
********************
19+
20+
Fixed
21+
=====
22+
23+
* Avoid duplicates when getting scopes for given user and permissions.
24+
1725
0.13.0 - 2025-11-05
1826
********************
1927

openedx_authz/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44

55
import os
66

7-
__version__ = "0.13.0"
7+
__version__ = "0.13.1"
88

99
ROOT_DIRECTORY = os.path.dirname(os.path.abspath(__file__))

openedx_authz/api/roles.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,6 @@ def get_scopes_for_subject_and_permission(
398398
scopes = []
399399
for role_assignment in roles_for_subject:
400400
for role in role_assignment.roles:
401-
if permission in role.permissions:
401+
if permission in role.permissions and role_assignment.scope not in scopes:
402402
scopes.append(role_assignment.scope)
403403
return scopes

openedx_authz/tests/api/test_roles.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,41 @@ def test_get_scopes_for_subject_and_permission(self, subject_name, action_name,
620620
for expected_scope in expected_scope_names:
621621
self.assertIn(expected_scope, actual_scope_names)
622622

623+
def test_get_scopes_for_subject_and_permission_no_duplicates(self):
624+
"""Test that get_scopes_for_subject_and_permission returns no duplicate scopes.
625+
626+
This test verifies that when a subject has multiple roles in the same scope
627+
that grant the same permission, the scope appears only once in the result.
628+
629+
Expected result:
630+
- Each scope appears exactly once in the returned list
631+
- No duplicate scopes even when multiple roles grant the same permission
632+
"""
633+
test_scope = "lib:TestOrg:duplicate_test"
634+
test_subject = "test_user_duplicates"
635+
636+
assign_role_to_subject_in_scope(
637+
SubjectData(external_key=test_subject),
638+
RoleData(external_key=roles.LIBRARY_ADMIN.external_key),
639+
ScopeData(external_key=test_scope),
640+
)
641+
642+
assign_role_to_subject_in_scope(
643+
SubjectData(external_key=test_subject),
644+
RoleData(external_key=roles.LIBRARY_AUTHOR.external_key),
645+
ScopeData(external_key=test_scope),
646+
)
647+
648+
subject = SubjectData(external_key=test_subject)
649+
permission = PermissionData(action=ActionData(external_key="view_library"))
650+
651+
scopes = get_scopes_for_subject_and_permission(subject, permission)
652+
scope_external_keys = [scope.external_key for scope in scopes]
653+
654+
self.assertEqual(len(scope_external_keys), 1)
655+
self.assertEqual(scope_external_keys[0], test_scope)
656+
self.assertEqual(len(scope_external_keys), len(set(scope_external_keys)))
657+
623658
@ddt_data(
624659
(roles.LIBRARY_AUTHOR.external_key, "lib:Org4:art_101", {"liam"}),
625660
(roles.LIBRARY_AUTHOR.external_key, "lib:Org4:art_201", {"liam"}),

0 commit comments

Comments
 (0)