Skip to content

Commit

Permalink
Fix #1421: identitycenter: handle exceptions (#1422)
Browse files Browse the repository at this point in the history
### Summary
> Describe your changes.

Fix #1421. Handles permissions exceptions when enumerating
identitycenter.

### Related issues or links
> Include links to relevant issues or other pages.

- #1421


### Checklist

Provide proof that this works (this makes reviews move faster). Please
perform one or more of the following:
- [x] Update/add unit or integration tests.
- [ ] Include a screenshot showing what the graph looked like before and
after your changes.
- [ ] Include console log trace showing what happened before and after
your changes.

Signed-off-by: Alex Chantavy <chantavy@gmail.com>
  • Loading branch information
achantavy authored Dec 28, 2024
1 parent 6abcf26 commit a00d91b
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 21 deletions.
23 changes: 3 additions & 20 deletions cartography/intel/aws/identitycenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,26 +82,6 @@ def get_permission_sets(boto3_session: boto3.session.Session, instance_arn: str,
return permission_sets


@timeit
def get_permission_set_roles(
boto3_session: boto3.session.Session,
instance_arn: str,
permission_set_arn: str,
region: str,
) -> List[Dict]:
"""
Get all accounts associated with a given permission set
"""
client = boto3_session.client('sso-admin', region_name=region)
accounts = []

paginator = client.get_paginator('list_accounts_for_provisioned_permission_set')
for page in paginator.paginate(InstanceArn=instance_arn, PermissionSetArn=permission_set_arn):
accounts.extend(page.get('AccountIds', []))

return accounts


@timeit
def load_permission_sets(
neo4j_session: neo4j.Session,
Expand All @@ -128,6 +108,7 @@ def load_permission_sets(


@timeit
@aws_handle_regions
def get_sso_users(
boto3_session: boto3.session.Session,
identity_store_id: str,
Expand Down Expand Up @@ -176,6 +157,7 @@ def load_sso_users(


@timeit
@aws_handle_regions
def get_role_assignments(
boto3_session: boto3.session.Session,
users: List[Dict],
Expand Down Expand Up @@ -231,6 +213,7 @@ def load_role_assignments(
)


@timeit
def cleanup(neo4j_session: neo4j.Session, common_job_parameters: Dict[str, Any]) -> None:
GraphJob.from_node_schema(AWSIdentityCenterInstanceSchema(), common_job_parameters).run(neo4j_session)
GraphJob.from_node_schema(AWSPermissionSetSchema(), common_job_parameters).run(neo4j_session)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from setuptools import find_packages
from setuptools import setup

__version__ = '0.97.0'
__version__ = '0.97.1'


setup(
Expand Down
34 changes: 34 additions & 0 deletions tests/unit/cartography/intel/aws/test_identitycenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import botocore.exceptions

from cartography.intel.aws.identitycenter import get_permission_sets
from cartography.intel.aws.identitycenter import get_role_assignments


def test_get_permission_sets_access_denied():
Expand Down Expand Up @@ -30,3 +31,36 @@ def test_get_permission_sets_access_denied():
mock_session.client.assert_called_once_with('sso-admin', region_name='us-east-1')
mock_client.get_paginator.assert_called_once_with('list_permission_sets')
mock_paginator.paginate.assert_called_once_with(InstanceArn="arn:aws:sso:::instance/test")


def test_get_role_assignments_access_denied():
# Ensure we gracefully handle access denied exceptions for identity center.
mock_session = MagicMock()
mock_client = MagicMock()
mock_paginator = MagicMock()
users = [{"UserId": "test-user-id"}]

# Arrange: Set up the mock chain
mock_session.client.return_value = mock_client
mock_client.get_paginator.return_value = mock_paginator

# Make paginate raise AccessDeniedException (simulate issue #1415)
mock_paginator.paginate.side_effect = botocore.exceptions.ClientError(
error_response={'Error': {'Code': 'AccessDeniedException', 'Message': 'Access Denied'}},
operation_name='ListAccountAssignmentsForPrincipal',
)

# Act: Call the function
result = get_role_assignments(mock_session, users, "arn:aws:sso:::instance/test", "us-east-1")

# Assert:Verify we got an empty list
assert result == []

# Verify our mocks were called as expected
mock_session.client.assert_called_once_with('sso-admin', region_name='us-east-1')
mock_client.get_paginator.assert_called_once_with('list_account_assignments_for_principal')
mock_paginator.paginate.assert_called_once_with(
InstanceArn="arn:aws:sso:::instance/test",
PrincipalId="test-user-id",
PrincipalType="USER",
)

0 comments on commit a00d91b

Please sign in to comment.