diff --git a/prowler/providers/aws/services/iam/iam_disable_90_days_credentials/iam_disable_90_days_credentials.py b/prowler/providers/aws/services/iam/iam_disable_90_days_credentials/iam_disable_90_days_credentials.py index 5a045ebb..b7c66705 100644 --- a/prowler/providers/aws/services/iam/iam_disable_90_days_credentials/iam_disable_90_days_credentials.py +++ b/prowler/providers/aws/services/iam/iam_disable_90_days_credentials/iam_disable_90_days_credentials.py @@ -93,11 +93,12 @@ class iam_disable_90_days_credentials(Check): findings.append(report) if not old_access_keys: - self.add_finding( - user=user, - status="PASS", - status_extended=f"User {user['user']} does not have unused access keys for {maximum_expiration_days} days.", - findings=findings, - ) + report = Check_Report_AWS(self.metadata()) + report.region = iam_client.region + report.resource_id = user["user"] + report.resource_arn = user["arn"] + report.status = "PASS" + report.status_extended = f"User {user['user']} does not have unused access keys for {maximum_expiration_days} days." + findings.append(report) return findings diff --git a/tests/providers/aws/services/iam/iam_disable_30_days_credentials/iam_disable_30_days_credentials_test.py b/tests/providers/aws/services/iam/iam_disable_30_days_credentials/iam_disable_30_days_credentials_test.py index c56d76ea..54cb7f66 100644 --- a/tests/providers/aws/services/iam/iam_disable_30_days_credentials/iam_disable_30_days_credentials_test.py +++ b/tests/providers/aws/services/iam/iam_disable_30_days_credentials/iam_disable_30_days_credentials_test.py @@ -80,6 +80,15 @@ class Test_iam_disable_30_days_credentials_test: ) assert result[0].resource_id == user assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION + assert result[1].status == "PASS" + assert search( + f"User {user} does not have access keys.", + result[1].status_extended, + ) + assert result[1].resource_id == user + assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION @mock_iam def test_iam_user_not_logged_30_days(self): @@ -109,6 +118,7 @@ class Test_iam_disable_30_days_credentials_test: service_client.users[0].password_last_used = password_last_used check = iam_disable_30_days_credentials() result = check.execute() + assert len(result) == 2 assert result[0].status == "FAIL" assert search( f"User {user} has not logged in to the console in the past 30 days.", @@ -116,6 +126,15 @@ class Test_iam_disable_30_days_credentials_test: ) assert result[0].resource_id == user assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION + assert result[1].status == "PASS" + assert search( + f"User {user} does not have access keys.", + result[1].status_extended, + ) + assert result[1].resource_id == user + assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION @mock_iam def test_iam_user_not_logged(self): @@ -143,6 +162,7 @@ class Test_iam_disable_30_days_credentials_test: # raise Exception check = iam_disable_30_days_credentials() result = check.execute() + assert len(result) == 2 assert result[0].status == "PASS" assert search( f"User {user} does not have a console password or is unused.", @@ -150,6 +170,15 @@ class Test_iam_disable_30_days_credentials_test: ) assert result[0].resource_id == user assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION + assert result[1].status == "PASS" + assert search( + f"User {user} does not have access keys.", + result[1].status_extended, + ) + assert result[1].resource_id == user + assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION @mock_iam def test_user_no_access_keys(self): @@ -182,6 +211,14 @@ class Test_iam_disable_30_days_credentials_test: check = iam_disable_30_days_credentials() result = check.execute() + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"User {user} does not have a console password or is unused." + ) + assert result[0].resource_id == user + assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION assert result[-1].status == "PASS" assert ( result[-1].status_extended @@ -189,6 +226,7 @@ class Test_iam_disable_30_days_credentials_test: ) assert result[-1].resource_id == user assert result[-1].resource_arn == arn + assert result[-1].region == AWS_REGION @mock_iam def test_user_access_key_1_not_used(self): @@ -222,6 +260,15 @@ class Test_iam_disable_30_days_credentials_test: check = iam_disable_30_days_credentials() result = check.execute() + assert len(result) == 2 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"User {user} does not have a console password or is unused." + ) + assert result[0].resource_id == user + assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION assert result[-1].status == "FAIL" assert ( result[-1].status_extended @@ -229,6 +276,7 @@ class Test_iam_disable_30_days_credentials_test: ) assert result[-1].resource_id == user assert result[-1].resource_arn == arn + assert result[-1].region == AWS_REGION @mock_iam def test_user_access_key_2_not_used(self): @@ -262,6 +310,15 @@ class Test_iam_disable_30_days_credentials_test: check = iam_disable_30_days_credentials() result = check.execute() + assert len(result) == 2 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"User {user} does not have a console password or is unused." + ) + assert result[0].resource_id == user + assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION assert result[-1].status == "FAIL" assert ( result[-1].status_extended @@ -269,6 +326,7 @@ class Test_iam_disable_30_days_credentials_test: ) assert result[-1].resource_id == user assert result[-1].resource_arn == arn + assert result[-1].region == AWS_REGION @mock_iam def test_user_both_access_keys_not_used(self): @@ -307,6 +365,15 @@ class Test_iam_disable_30_days_credentials_test: check = iam_disable_30_days_credentials() result = check.execute() + assert len(result) == 3 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"User {user} does not have a console password or is unused." + ) + assert result[0].resource_id == user + assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION assert result[-1].status == "FAIL" assert ( result[-1].status_extended @@ -314,6 +381,7 @@ class Test_iam_disable_30_days_credentials_test: ) assert result[-1].resource_id == user assert result[-1].resource_arn == arn + assert result[-1].region == AWS_REGION assert result[-2].status == "FAIL" assert ( @@ -322,3 +390,59 @@ class Test_iam_disable_30_days_credentials_test: ) assert result[-2].resource_id == user assert result[-2].resource_arn == arn + assert result[-2].region == AWS_REGION + + @mock_iam + def test_user_both_access_keys_used(self): + credentials_last_rotated = ( + datetime.datetime.now() - datetime.timedelta(days=10) + ).strftime("%Y-%m-%dT%H:%M:%S+00:00") + iam_client = client("iam") + user = "test-user" + arn = iam_client.create_user(UserName=user)["User"]["Arn"] + + from prowler.providers.aws.services.iam.iam_service import IAM + + audit_info = self.set_mocked_audit_info() + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ): + with mock.patch( + "prowler.providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials.iam_client", + new=IAM(audit_info), + ) as service_client: + from prowler.providers.aws.services.iam.iam_disable_30_days_credentials.iam_disable_30_days_credentials import ( + iam_disable_30_days_credentials, + ) + + service_client.credential_report[0]["access_key_1_active"] = "true" + service_client.credential_report[0][ + "access_key_1_last_used_date" + ] = credentials_last_rotated + + service_client.credential_report[0]["access_key_2_active"] = "true" + service_client.credential_report[0][ + "access_key_2_last_used_date" + ] = credentials_last_rotated + + check = iam_disable_30_days_credentials() + result = check.execute() + assert len(result) == 2 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"User {user} does not have a console password or is unused." + ) + assert result[0].resource_id == user + assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION + assert result[1].status == "PASS" + assert ( + result[1].status_extended + == f"User {user} does not have unused access keys for 30 days." + ) + assert result[1].resource_id == user + assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION diff --git a/tests/providers/aws/services/iam/iam_disable_45_days_credentials/iam_disable_45_days_credentials_test.py b/tests/providers/aws/services/iam/iam_disable_45_days_credentials/iam_disable_45_days_credentials_test.py index dbc892ba..5adb919e 100644 --- a/tests/providers/aws/services/iam/iam_disable_45_days_credentials/iam_disable_45_days_credentials_test.py +++ b/tests/providers/aws/services/iam/iam_disable_45_days_credentials/iam_disable_45_days_credentials_test.py @@ -73,6 +73,7 @@ class Test_iam_disable_45_days_credentials_test: service_client.users[0].password_last_used = password_last_used check = iam_disable_45_days_credentials() result = check.execute() + assert len(result) == 2 assert result[0].status == "PASS" assert search( f"User {user} has logged in to the console in the past 45 days.", @@ -80,6 +81,15 @@ class Test_iam_disable_45_days_credentials_test: ) assert result[0].resource_id == user assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION + assert result[1].status == "PASS" + assert search( + f"User {user} does not have access keys.", + result[1].status_extended, + ) + assert result[1].resource_id == user + assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION @mock_iam def test_iam_user_not_logged_45_days(self): @@ -109,6 +119,7 @@ class Test_iam_disable_45_days_credentials_test: service_client.users[0].password_last_used = password_last_used check = iam_disable_45_days_credentials() result = check.execute() + assert len(result) == 2 assert result[0].status == "FAIL" assert search( f"User {user} has not logged in to the console in the past 45 days.", @@ -116,6 +127,15 @@ class Test_iam_disable_45_days_credentials_test: ) assert result[0].resource_id == user assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION + assert result[1].status == "PASS" + assert search( + f"User {user} does not have access keys.", + result[1].status_extended, + ) + assert result[1].resource_id == user + assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION @mock_iam def test_iam_user_not_logged(self): @@ -143,6 +163,7 @@ class Test_iam_disable_45_days_credentials_test: # raise Exception check = iam_disable_45_days_credentials() result = check.execute() + assert len(result) == 2 assert result[0].status == "PASS" assert search( f"User {user} does not have a console password or is unused.", @@ -150,6 +171,15 @@ class Test_iam_disable_45_days_credentials_test: ) assert result[0].resource_id == user assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION + assert result[1].status == "PASS" + assert search( + f"User {user} does not have access keys.", + result[1].status_extended, + ) + assert result[1].resource_id == user + assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION @mock_iam def test_user_no_access_keys(self): @@ -182,13 +212,23 @@ class Test_iam_disable_45_days_credentials_test: check = iam_disable_45_days_credentials() result = check.execute() - assert result[-1].status == "PASS" + assert len(result) == 2 + assert result[0].status == "PASS" assert ( - result[-1].status_extended + result[0].status_extended + == f"User {user} does not have a console password or is unused." + ) + assert result[0].resource_id == user + assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION + assert result[1].status == "PASS" + assert ( + result[1].status_extended == f"User {user} does not have access keys." ) - assert result[-1].resource_id == user - assert result[-1].resource_arn == arn + assert result[1].resource_id == user + assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION @mock_iam def test_user_access_key_1_not_used(self): @@ -222,13 +262,23 @@ class Test_iam_disable_45_days_credentials_test: check = iam_disable_45_days_credentials() result = check.execute() - assert result[-1].status == "FAIL" + assert len(result) == 2 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"User {user} does not have a console password or is unused." + ) + assert result[0].resource_id == user + assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION + assert result[1].status == "FAIL" assert ( result[-1].status_extended == f"User {user} has not used access key 1 in the last 45 days (100 days)." ) - assert result[-1].resource_id == user - assert result[-1].resource_arn == arn + assert result[1].resource_id == user + assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION @mock_iam def test_user_access_key_2_not_used(self): @@ -262,13 +312,23 @@ class Test_iam_disable_45_days_credentials_test: check = iam_disable_45_days_credentials() result = check.execute() - assert result[-1].status == "FAIL" + assert len(result) == 2 + assert result[0].status == "PASS" assert ( - result[-1].status_extended + result[0].status_extended + == f"User {user} does not have a console password or is unused." + ) + assert result[0].resource_id == user + assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION + assert result[1].status == "FAIL" + assert ( + result[1].status_extended == f"User {user} has not used access key 2 in the last 45 days (100 days)." ) - assert result[-1].resource_id == user - assert result[-1].resource_arn == arn + assert result[1].resource_id == user + assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION @mock_iam def test_user_both_access_keys_not_used(self): @@ -307,6 +367,15 @@ class Test_iam_disable_45_days_credentials_test: check = iam_disable_45_days_credentials() result = check.execute() + assert len(result) == 3 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"User {user} does not have a console password or is unused." + ) + assert result[0].resource_id == user + assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION assert result[-1].status == "FAIL" assert ( result[-1].status_extended @@ -314,7 +383,7 @@ class Test_iam_disable_45_days_credentials_test: ) assert result[-1].resource_id == user assert result[-1].resource_arn == arn - + assert result[-1].region == AWS_REGION assert result[-2].status == "FAIL" assert ( result[-2].status_extended @@ -322,3 +391,59 @@ class Test_iam_disable_45_days_credentials_test: ) assert result[-2].resource_id == user assert result[-2].resource_arn == arn + assert result[-2].region == AWS_REGION + + @mock_iam + def test_user_both_access_keys_used(self): + credentials_last_rotated = ( + datetime.datetime.now() - datetime.timedelta(days=10) + ).strftime("%Y-%m-%dT%H:%M:%S+00:00") + iam_client = client("iam") + user = "test-user" + arn = iam_client.create_user(UserName=user)["User"]["Arn"] + + from prowler.providers.aws.services.iam.iam_service import IAM + + audit_info = self.set_mocked_audit_info() + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ): + with mock.patch( + "prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials.iam_client", + new=IAM(audit_info), + ) as service_client: + from prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials import ( + iam_disable_45_days_credentials, + ) + + service_client.credential_report[0]["access_key_1_active"] = "true" + service_client.credential_report[0][ + "access_key_1_last_used_date" + ] = credentials_last_rotated + + service_client.credential_report[0]["access_key_2_active"] = "true" + service_client.credential_report[0][ + "access_key_2_last_used_date" + ] = credentials_last_rotated + + check = iam_disable_45_days_credentials() + result = check.execute() + assert len(result) == 2 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"User {user} does not have a console password or is unused." + ) + assert result[0].resource_id == user + assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION + assert result[1].status == "PASS" + assert ( + result[1].status_extended + == f"User {user} does not have unused access keys for 45 days." + ) + assert result[1].resource_id == user + assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION diff --git a/tests/providers/aws/services/iam/iam_disable_90_days_credentials/iam_disable_90_days_credentials_test.py b/tests/providers/aws/services/iam/iam_disable_90_days_credentials/iam_disable_90_days_credentials_test.py index ff9bede7..a42c0506 100644 --- a/tests/providers/aws/services/iam/iam_disable_90_days_credentials/iam_disable_90_days_credentials_test.py +++ b/tests/providers/aws/services/iam/iam_disable_90_days_credentials/iam_disable_90_days_credentials_test.py @@ -79,6 +79,15 @@ class Test_iam_disable_90_days_credentials_test: ) assert result[0].resource_id == user assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION + assert result[1].status == "PASS" + assert search( + f"User {user} does not have access keys.", + result[1].status_extended, + ) + assert result[1].resource_id == user + assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION @mock_iam def test_iam_user_not_logged_90_days(self): @@ -108,6 +117,7 @@ class Test_iam_disable_90_days_credentials_test: service_client.users[0].password_last_used = password_last_used check = iam_disable_90_days_credentials() result = check.execute() + assert len(result) == 2 assert result[0].status == "FAIL" assert search( f"User {user} has not logged in to the console in the past 90 days.", @@ -115,6 +125,15 @@ class Test_iam_disable_90_days_credentials_test: ) assert result[0].resource_id == user assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION + assert result[1].status == "PASS" + assert search( + f"User {user} does not have access keys.", + result[1].status_extended, + ) + assert result[1].resource_id == user + assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION @mock_iam def test_iam_user_not_logged(self): @@ -142,6 +161,7 @@ class Test_iam_disable_90_days_credentials_test: # raise Exception check = iam_disable_90_days_credentials() result = check.execute() + assert len(result) == 2 assert result[0].status == "PASS" assert search( f"User {user} does not have a console password or is unused.", @@ -149,6 +169,15 @@ class Test_iam_disable_90_days_credentials_test: ) assert result[0].resource_id == user assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION + assert result[1].status == "PASS" + assert search( + f"User {user} does not have access keys.", + result[1].status_extended, + ) + assert result[1].resource_id == user + assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION @mock_iam def test_user_no_access_keys(self): @@ -181,13 +210,23 @@ class Test_iam_disable_90_days_credentials_test: check = iam_disable_90_days_credentials() result = check.execute() - assert result[-1].status == "PASS" + assert len(result) == 2 + assert result[0].status == "PASS" assert ( - result[-1].status_extended + result[0].status_extended + == f"User {user} does not have a console password or is unused." + ) + assert result[0].resource_id == user + assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION + assert result[1].status == "PASS" + assert ( + result[1].status_extended == f"User {user} does not have access keys." ) - assert result[-1].resource_id == user - assert result[-1].resource_arn == arn + assert result[1].resource_id == user + assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION @mock_iam def test_user_access_key_1_not_used(self): @@ -221,13 +260,23 @@ class Test_iam_disable_90_days_credentials_test: check = iam_disable_90_days_credentials() result = check.execute() - assert result[-1].status == "FAIL" + assert len(result) == 2 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"User {user} does not have a console password or is unused." + ) + assert result[0].resource_id == user + assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION + assert result[1].status == "FAIL" assert ( result[-1].status_extended == f"User {user} has not used access key 1 in the last 90 days (100 days)." ) - assert result[-1].resource_id == user - assert result[-1].resource_arn == arn + assert result[1].resource_id == user + assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION @mock_iam def test_user_access_key_2_not_used(self): @@ -261,13 +310,23 @@ class Test_iam_disable_90_days_credentials_test: check = iam_disable_90_days_credentials() result = check.execute() - assert result[-1].status == "FAIL" + assert len(result) == 2 + assert result[0].status == "PASS" assert ( - result[-1].status_extended + result[0].status_extended + == f"User {user} does not have a console password or is unused." + ) + assert result[0].resource_id == user + assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION + assert result[1].status == "FAIL" + assert ( + result[1].status_extended == f"User {user} has not used access key 2 in the last 90 days (100 days)." ) - assert result[-1].resource_id == user - assert result[-1].resource_arn == arn + assert result[1].resource_id == user + assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION @mock_iam def test_user_both_access_keys_not_used(self): @@ -306,18 +365,83 @@ class Test_iam_disable_90_days_credentials_test: check = iam_disable_90_days_credentials() result = check.execute() - assert result[-1].status == "FAIL" + assert len(result) == 3 + assert result[0].status == "PASS" assert ( - result[-1].status_extended - == f"User {user} has not used access key 2 in the last 90 days (100 days)." + result[0].status_extended + == f"User {user} does not have a console password or is unused." ) - assert result[-1].resource_id == user - assert result[-1].resource_arn == arn - - assert result[-2].status == "FAIL" + assert result[0].resource_id == user + assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION + assert result[1].status == "FAIL" assert ( - result[-2].status_extended + result[1].status_extended == f"User {user} has not used access key 1 in the last 90 days (100 days)." ) - assert result[-2].resource_id == user - assert result[-2].resource_arn == arn + assert result[1].resource_id == user + assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION + assert result[2].status == "FAIL" + assert ( + result[2].status_extended + == f"User {user} has not used access key 2 in the last 90 days (100 days)." + ) + assert result[2].resource_id == user + assert result[2].resource_arn == arn + assert result[2].region == AWS_REGION + + @mock_iam + def test_user_both_access_keys_used(self): + credentials_last_rotated = ( + datetime.datetime.now() - datetime.timedelta(days=10) + ).strftime("%Y-%m-%dT%H:%M:%S+00:00") + iam_client = client("iam") + user = "test-user" + arn = iam_client.create_user(UserName=user)["User"]["Arn"] + + from prowler.providers.aws.services.iam.iam_service import IAM + + audit_info = self.set_mocked_audit_info() + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ): + with mock.patch( + "prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials.iam_client", + new=IAM(audit_info), + ) as service_client: + from prowler.providers.aws.services.iam.iam_disable_45_days_credentials.iam_disable_45_days_credentials import ( + iam_disable_45_days_credentials, + ) + + service_client.credential_report[0]["access_key_1_active"] = "true" + service_client.credential_report[0][ + "access_key_1_last_used_date" + ] = credentials_last_rotated + + service_client.credential_report[0]["access_key_2_active"] = "true" + service_client.credential_report[0][ + "access_key_2_last_used_date" + ] = credentials_last_rotated + + check = iam_disable_45_days_credentials() + result = check.execute() + assert len(result) == 2 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"User {user} does not have a console password or is unused." + ) + assert result[0].resource_id == user + assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION + assert result[1].status == "PASS" + assert ( + result[1].status_extended + == f"User {user} does not have unused access keys for 45 days." + ) + assert result[1].resource_id == user + assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION diff --git a/tests/providers/aws/services/iam/iam_rotate_access_key_90_days/iam_rotate_access_key_90_days_test.py b/tests/providers/aws/services/iam/iam_rotate_access_key_90_days/iam_rotate_access_key_90_days_test.py index f93275ef..5c92d109 100644 --- a/tests/providers/aws/services/iam/iam_rotate_access_key_90_days/iam_rotate_access_key_90_days_test.py +++ b/tests/providers/aws/services/iam/iam_rotate_access_key_90_days/iam_rotate_access_key_90_days_test.py @@ -8,6 +8,7 @@ from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info from prowler.providers.common.models import Audit_Metadata AWS_ACCOUNT_NUMBER = "123456789012" +AWS_REGION = "us-east-1" class Test_iam_rotate_access_key_90_days_test: @@ -25,7 +26,7 @@ class Test_iam_rotate_access_key_90_days_test: audited_partition="aws", audited_identity_arn=None, profile=None, - profile_region=None, + profile_region=AWS_REGION, credentials=None, assumed_role_info=None, audited_regions=["us-east-1", "eu-west-1"], @@ -68,12 +69,14 @@ class Test_iam_rotate_access_key_90_days_test: check = iam_rotate_access_key_90_days() result = check.execute() + assert len(result) == 1 assert result[0].status == "PASS" assert ( result[0].status_extended == f"User {user} does not have access keys." ) assert result[0].resource_id == user assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION @mock_iam def test_user_access_key_1_not_rotated(self): @@ -106,6 +109,7 @@ class Test_iam_rotate_access_key_90_days_test: check = iam_rotate_access_key_90_days() result = check.execute() + assert len(result) == 1 assert result[0].status == "FAIL" assert ( result[0].status_extended @@ -113,6 +117,7 @@ class Test_iam_rotate_access_key_90_days_test: ) assert result[0].resource_id == user assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION @mock_iam def test_user_access_key_2_not_rotated(self): @@ -145,6 +150,7 @@ class Test_iam_rotate_access_key_90_days_test: check = iam_rotate_access_key_90_days() result = check.execute() + assert len(result) == 1 assert result[0].status == "FAIL" assert ( result[0].status_extended @@ -152,6 +158,7 @@ class Test_iam_rotate_access_key_90_days_test: ) assert result[0].resource_id == user assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION @mock_iam def test_user_both_access_keys_not_rotated(self): @@ -189,6 +196,7 @@ class Test_iam_rotate_access_key_90_days_test: check = iam_rotate_access_key_90_days() result = check.execute() + assert len(result) == 2 assert result[0].status == "FAIL" assert ( result[0].status_extended @@ -196,7 +204,7 @@ class Test_iam_rotate_access_key_90_days_test: ) assert result[0].resource_id == user assert result[0].resource_arn == arn - + assert result[0].region == AWS_REGION assert result[1].status == "FAIL" assert ( result[1].status_extended @@ -204,3 +212,51 @@ class Test_iam_rotate_access_key_90_days_test: ) assert result[1].resource_id == user assert result[1].resource_arn == arn + assert result[1].region == AWS_REGION + + @mock_iam + def test_user_both_access_keys_rotated(self): + credentials_last_rotated = ( + datetime.datetime.now() - datetime.timedelta(days=10) + ).strftime("%Y-%m-%dT%H:%M:%S+00:00") + iam_client = client("iam") + user = "test-user" + arn = iam_client.create_user(UserName=user)["User"]["Arn"] + + from prowler.providers.aws.services.iam.iam_service import IAM + + audit_info = self.set_mocked_audit_info() + + with mock.patch( + "prowler.providers.aws.lib.audit_info.audit_info.current_audit_info", + new=audit_info, + ): + with mock.patch( + "prowler.providers.aws.services.iam.iam_rotate_access_key_90_days.iam_rotate_access_key_90_days.iam_client", + new=IAM(audit_info), + ) as service_client: + from prowler.providers.aws.services.iam.iam_rotate_access_key_90_days.iam_rotate_access_key_90_days import ( + iam_rotate_access_key_90_days, + ) + + service_client.credential_report[0]["access_key_1_active"] = "true" + service_client.credential_report[0][ + "access_key_1_last_rotated" + ] = credentials_last_rotated + + service_client.credential_report[0]["access_key_2_active"] = "true" + service_client.credential_report[0][ + "access_key_2_last_rotated" + ] = credentials_last_rotated + + check = iam_rotate_access_key_90_days() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"User {user} does not have access keys older than 90 days." + ) + assert result[0].resource_id == user + assert result[0].resource_arn == arn + assert result[0].region == AWS_REGION