Skip to content

Commit 32efa8d

Browse files
authored
Merge pull request #61 from dwc0011/fix-add-is-debug-to-dict
Fix add is debug to dict
2 parents b337921 + b117ed2 commit 32efa8d

7 files changed

Lines changed: 49 additions & 10 deletions

File tree

.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 3.0.0
2+
current_version = 3.0.1
33
commit = True
44
message = Bumps version to {new_version}
55
tag = False

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
66

7+
### [3.0.1](https://github.com/plus3it/terraform-aws-tardigrade-iam-key-enforcer/releases/tag/3.0.1)
8+
9+
**Released**: 2026.03.26
10+
11+
**Summary**:
12+
13+
* Fix defect where if is_debug is not passed in the lambda will fail to run email
14+
* Add user emails for warning actions
15+
716
### [3.0.0](https://github.com/plus3it/terraform-aws-tardigrade-iam-key-enforcer/releases/tag/3.0.0)
817

918
**Released**: 2026.01.20

src/python/iam_key_enforcer_reporter.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ def __init__(self, client_iam, event: dict):
6161
"""Create IAM Key Enforcer Reporter."""
6262
self.client_iam = client_iam
6363
self.enforce_details = event
64+
self.enforce_details["is_debug"] = event.get("is_debug") or False
6465
self.has_errors = False
6566
self.log_prefix = ARMED_PREFIX if event["armed"] else NOT_ARMED_PREFIX
6667

@@ -178,7 +179,7 @@ def process_user_access_key(self, key_user):
178179
)
179180

180181
# Send emails to user if an action was taken that requires notification
181-
if action in (DELETE_ACTION, DISABLE_ACTION):
182+
if action in (DELETE_ACTION, DISABLE_ACTION, WARN_ACTION):
182183
self.mail_user_key_report(action, key_user)
183184

184185
return enforcement_report_row

src/python/mailers.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,7 @@ def log_invalid_email(email_type, email):
125125

126126
def validate_email(email):
127127
"""Validate email provided matches regex."""
128-
if not email or not re.fullmatch(EMAIL_REGEX, email):
129-
return False
130-
return True
128+
return bool(email and re.fullmatch(EMAIL_REGEX, email))
131129

132130

133131
def send_email(ses_client, template, template_data, email_targets):

src/python/utils.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@
99
DELETE_ACTION,
1010
DISABLE_ACTION,
1111
EMAIL_ADMIN_TEMPLATE,
12+
KEY_AGE_INACTIVE,
13+
KEY_AGE_WARNING,
1214
LOG,
1315
S3_BUCKET,
16+
WARN_ACTION,
1417
)
1518
from errors import TemplateDataError
1619

@@ -98,12 +101,18 @@ def root_user(user) -> bool:
98101

99102
def action_armed_state_message(action, is_armed) -> str | None:
100103
"""Return message based on action and armed state."""
104+
armed_msg = "has been" if is_armed else "would be"
101105
if action == DELETE_ACTION:
102-
return "has been deleted" if is_armed else "would be marked for deletion"
106+
return f"{armed_msg} deleted"
103107

104108
if action == DISABLE_ACTION:
109+
return f"{armed_msg} marked 'Inactive'"
110+
111+
if action == WARN_ACTION:
112+
armed_msg = "will be" if is_armed else "would be"
105113
return (
106-
"has been marked 'Inactive'" if is_armed else "would be marked 'Inactive'"
114+
f"is older than {KEY_AGE_WARNING} days and {armed_msg} "
115+
f"disabled at {KEY_AGE_INACTIVE} days"
107116
)
108117

109118
return None

tests/python/test_iam_key_enforcer_reporter.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@ def test_enforce_with_report_rows(self, mock_iam_client, mocker):
524524
"account_number": "123456789012",
525525
"exempt_groups": None,
526526
"email_targets": ["admin@example.com"],
527+
"email_user_enabled": False,
527528
"is_debug": False,
528529
}
529530
reporter = IamKeyEnforcerReporter(mock_iam_client, event)
@@ -605,6 +606,7 @@ def test_mail_admin_report_success(self, mock_iam_client, mocker):
605606
"account_name": "test",
606607
"account_number": "123",
607608
"email_targets": ["admin@test.com"],
609+
"email_user_enabled": False,
608610
"is_debug": False,
609611
}
610612
reporter = IamKeyEnforcerReporter(mock_iam_client, event)
@@ -627,6 +629,7 @@ def test_mail_admin_report_handles_error(self, mock_iam_client, mocker):
627629
"account_name": "test",
628630
"account_number": "123",
629631
"email_targets": ["admin@test.com"],
632+
"email_user_enabled": False,
630633
"is_debug": False,
631634
}
632635
reporter = IamKeyEnforcerReporter(mock_iam_client, event)
@@ -796,6 +799,7 @@ def test_enforce_multiple_users_error_in_middle_continues_and_raises(
796799
"account_number": "123456789012",
797800
"exempt_groups": None,
798801
"email_targets": ["admin@example.com"],
802+
"email_user_enabled": False,
799803
"is_debug": False,
800804
}
801805
reporter = IamKeyEnforcerReporter(mock_iam_client, event)
@@ -869,6 +873,7 @@ def test_enforce_and_report_continues_after_user_error(
869873
"armed": True,
870874
"account_name": "test-account",
871875
"account_number": "123456789012",
876+
"email_user_enabled": False,
872877
"exempt_groups": None,
873878
}
874879
reporter = IamKeyEnforcerReporter(mock_iam_client, event)
@@ -935,6 +940,7 @@ def test_enforce_processes_all_users_and_keys_before_raising(
935940
"account_number": "123456789012",
936941
"exempt_groups": None,
937942
"email_targets": ["admin@example.com"],
943+
"email_user_enabled": False,
938944
"is_debug": True,
939945
}
940946
reporter = IamKeyEnforcerReporter(mock_iam_client, event)

tests/python/test_utils.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from datetime import UTC, datetime, timedelta
1111

1212
import pytest
13+
from constants import KEY_AGE_INACTIVE, KEY_AGE_WARNING
1314
from errors import TemplateDataError
1415
from utils import (
1516
action_armed_state_message,
@@ -427,7 +428,7 @@ def test_delete_action_not_armed(self, mocker):
427428

428429
result = action_armed_state_message("Delete", is_armed=False)
429430

430-
assert result == "would be marked for deletion"
431+
assert result == "would be deleted"
431432

432433
def test_disable_action_armed(self, mocker):
433434
"""Test disable action when armed."""
@@ -445,14 +446,29 @@ def test_disable_action_not_armed(self, mocker):
445446

446447
assert result == "would be marked 'Inactive'"
447448

448-
def test_other_action_returns_none(self, mocker):
449+
def test_warn_action_returns_armed_message(self, mocker):
449450
"""Test other actions return None."""
450451
mocker.patch("utils.DELETE_ACTION", "Delete")
451452
mocker.patch("utils.DISABLE_ACTION", "Disable")
452453

453454
result = action_armed_state_message("Warning", is_armed=True)
454455

455-
assert result is None
456+
assert result == (
457+
f"is older than {KEY_AGE_WARNING} days and will be "
458+
f"disabled at {KEY_AGE_INACTIVE} days"
459+
)
460+
461+
def test_warn_action_returns_unarmed_message(self, mocker):
462+
"""Test other actions return None."""
463+
mocker.patch("utils.DELETE_ACTION", "Delete")
464+
mocker.patch("utils.DISABLE_ACTION", "Disable")
465+
466+
result = action_armed_state_message("Warning", is_armed=False)
467+
468+
assert result == (
469+
f"is older than {KEY_AGE_WARNING} days and would be "
470+
f"disabled at {KEY_AGE_INACTIVE} days"
471+
)
456472

457473
def test_exempt_action_returns_none(self, mocker):
458474
"""Test exempt action returns None."""

0 commit comments

Comments
 (0)