Skip to content

Commit 203999e

Browse files
author
Andrea Tomassilli
committed
change
1 parent 3646512 commit 203999e

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed

src/azure-cli/azure/cli/command_modules/role/custom.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ def _search_role_assignments(assignments_client, definitions_client,
540540

541541
if role:
542542
role_id = _resolve_role_id(role, scope, definitions_client)
543-
assignments = [ra for ra in assignments if ra.role_definition_id.endswith(role_id)]
543+
assignments = [ra for ra in assignments if ra.role_definition_id and ra.role_definition_id.endswith(role_id)]
544544

545545
# filter the assignee if "include_groups" is not provided because service side
546546
# does not accept filter "principalId eq and atScope()"

src/azure-cli/azure/cli/command_modules/role/tests/latest/test_role_custom.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,83 @@ def test_include_inherited_returns_parent_scope_assignments(self, mock_clients):
159159
)
160160

161161
assert len(result) == 2
162+
163+
def test_include_inherited_false_filters_parent_scope(self, mock_clients):
164+
"""include_inherited=False filters out assignments at parent scopes."""
165+
assignments_client, definitions_client = mock_clients
166+
role_def_id = '/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7'
167+
168+
assignments_client.list_for_scope.return_value = [
169+
self._create_assignment('/', role_def_id, 'principal-1'),
170+
self._create_assignment('/subscriptions/sub1', role_def_id, 'principal-2'),
171+
]
172+
173+
result = _search_role_assignments(
174+
assignments_client, definitions_client,
175+
scope='/subscriptions/sub1',
176+
assignee_object_id=None, role=None,
177+
include_inherited=False, include_groups=False
178+
)
179+
180+
assert len(result) == 1
181+
assert result[0].principal_id == 'principal-2'
182+
183+
def test_assignee_filter(self, mock_clients):
184+
"""assignee_object_id filters assignments by principal."""
185+
assignments_client, definitions_client = mock_clients
186+
role_def_id = '/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7'
187+
188+
assignments_client.list_for_scope.return_value = [
189+
self._create_assignment('/subscriptions/sub1', role_def_id, 'principal-1'),
190+
self._create_assignment('/subscriptions/sub1', role_def_id, 'principal-2'),
191+
]
192+
193+
result = _search_role_assignments(
194+
assignments_client, definitions_client,
195+
scope='/subscriptions/sub1',
196+
assignee_object_id='principal-1', role=None,
197+
include_inherited=False, include_groups=False
198+
)
199+
200+
assert len(result) == 1
201+
assert result[0].principal_id == 'principal-1'
202+
203+
def test_no_scope_uses_subscription_api(self, mock_clients):
204+
"""When scope is None, list_for_subscription is called and all assignments returned."""
205+
assignments_client, definitions_client = mock_clients
206+
role_def_id = '/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7'
207+
208+
assignments_client.list_for_subscription.return_value = [
209+
self._create_assignment('/subscriptions/sub1', role_def_id, 'principal-1'),
210+
self._create_assignment('/subscriptions/sub1/resourceGroups/rg1', role_def_id, 'principal-2'),
211+
]
212+
213+
result = _search_role_assignments(
214+
assignments_client, definitions_client,
215+
scope=None,
216+
assignee_object_id=None, role=None,
217+
include_inherited=False, include_groups=False
218+
)
219+
220+
assert len(result) == 2
221+
assignments_client.list_for_subscription.assert_called_once()
222+
assignments_client.list_for_scope.assert_not_called()
223+
224+
def test_none_role_definition_id_is_skipped(self, mock_clients):
225+
"""Assignments with None role_definition_id are skipped when filtering by role."""
226+
assignments_client, definitions_client = mock_clients
227+
role_guid = 'acdd72a7-3385-48ef-bd42-f606fba81ae7'
228+
229+
assignment_with_none = self._create_assignment('/', None)
230+
assignment_with_role = self._create_assignment(
231+
'/', f'/providers/Microsoft.Authorization/roleDefinitions/{role_guid}')
232+
assignments_client.list_for_scope.return_value = [assignment_with_none, assignment_with_role]
233+
234+
result = _search_role_assignments(
235+
assignments_client, definitions_client,
236+
scope='/', assignee_object_id=None, role=role_guid,
237+
include_inherited=False, include_groups=False
238+
)
239+
240+
assert len(result) == 1
241+
assert result[0].role_definition_id is not None

0 commit comments

Comments
 (0)