Files
prowler/tests/lib/timeline/models_test.py
T
Sergio Garcia 9e7ecb39fa feat(aws): CloudTrail timeline for findings (#9101)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
2026-01-27 13:00:46 +01:00

164 lines
6.1 KiB
Python

from datetime import datetime, timezone
import pytest
from prowler.lib.timeline.models import TimelineEvent
class TestTimelineEvent:
"""Tests for TimelineEvent model."""
def test_minimal_event(self):
"""Test creating an event with only required fields."""
event = TimelineEvent(
event_id="test-event-id-123",
event_time=datetime(2024, 1, 15, 10, 30, 0, tzinfo=timezone.utc),
event_name="CreateResource",
event_source="service.example.com",
actor="user@example.com",
actor_type="User",
)
assert event.event_id == "test-event-id-123"
assert event.event_time == datetime(2024, 1, 15, 10, 30, 0, tzinfo=timezone.utc)
assert event.event_name == "CreateResource"
assert event.event_source == "service.example.com"
assert event.actor == "user@example.com"
assert event.actor_type == "User"
# Optional fields should be None
assert event.actor_uid is None
assert event.source_ip_address is None
assert event.user_agent is None
assert event.request_data is None
assert event.response_data is None
assert event.error_code is None
assert event.error_message is None
def test_full_event(self):
"""Test creating an event with all fields populated."""
event = TimelineEvent(
event_id="full-event-id-456",
event_time=datetime(2024, 1, 15, 10, 30, 0, tzinfo=timezone.utc),
event_name="ModifyResource",
event_source="storage.example.com",
actor="admin-role",
actor_uid="arn:aws:sts::123456789012:assumed-role/admin-role/session",
actor_type="AssumedRole",
source_ip_address="192.168.1.100",
user_agent="aws-cli/2.0.0",
request_data={"bucket": "my-bucket", "acl": "private"},
response_data={"status": "success"},
error_code=None,
error_message=None,
)
assert event.event_id == "full-event-id-456"
assert (
event.actor_uid
== "arn:aws:sts::123456789012:assumed-role/admin-role/session"
)
assert event.source_ip_address == "192.168.1.100"
assert event.user_agent == "aws-cli/2.0.0"
assert event.request_data == {"bucket": "my-bucket", "acl": "private"}
assert event.response_data == {"status": "success"}
def test_error_event(self):
"""Test creating an event that represents a failed operation."""
event = TimelineEvent(
event_id="error-event-id-789",
event_time=datetime(2024, 1, 15, 10, 30, 0, tzinfo=timezone.utc),
event_name="DeleteResource",
event_source="storage.example.com",
actor="unauthorized-user",
actor_type="User",
error_code="AccessDenied",
error_message="User does not have permission to delete this resource",
)
assert event.error_code == "AccessDenied"
assert (
event.error_message
== "User does not have permission to delete this resource"
)
def test_event_to_dict(self):
"""Test that event can be serialized to dictionary."""
event = TimelineEvent(
event_id="dict-test-id",
event_time=datetime(2024, 1, 15, 10, 30, 0, tzinfo=timezone.utc),
event_name="CreateResource",
event_source="service.example.com",
actor="user@example.com",
actor_type="User",
)
event_dict = event.dict()
assert event_dict["event_id"] == "dict-test-id"
assert event_dict["event_name"] == "CreateResource"
assert event_dict["actor"] == "user@example.com"
assert event_dict["actor_type"] == "User"
def test_event_from_dict(self):
"""Test creating an event from a dictionary."""
data = {
"event_id": "from-dict-id",
"event_time": datetime(2024, 1, 15, 10, 30, 0, tzinfo=timezone.utc),
"event_name": "UpdateResource",
"event_source": "compute.example.com",
"actor": "service-account",
"actor_type": "ServiceAccount",
}
event = TimelineEvent(**data)
assert event.event_id == "from-dict-id"
assert event.event_name == "UpdateResource"
assert event.actor == "service-account"
assert event.actor_type == "ServiceAccount"
def test_required_fields_validation(self):
"""Test that missing required fields raise validation error."""
with pytest.raises(Exception): # Pydantic validation error
TimelineEvent(
event_id="validation-test",
event_time=datetime.now(timezone.utc),
event_name="CreateResource",
# Missing: event_source, actor, actor_type
)
def test_actor_types_are_flexible(self):
"""Test that actor_type accepts any string value (provider-agnostic)."""
# AWS-style
aws_event = TimelineEvent(
event_id="aws-event-id",
event_time=datetime.now(timezone.utc),
event_name="CreateBucket",
event_source="s3.amazonaws.com",
actor="arn:aws:iam::123456789012:user/admin",
actor_type="IAMUser",
)
assert aws_event.actor_type == "IAMUser"
# Azure-style
azure_event = TimelineEvent(
event_id="azure-event-id",
event_time=datetime.now(timezone.utc),
event_name="CreateStorageAccount",
event_source="Microsoft.Storage",
actor="user@contoso.com",
actor_type="User",
)
assert azure_event.actor_type == "User"
# GCP-style
gcp_event = TimelineEvent(
event_id="gcp-event-id",
event_time=datetime.now(timezone.utc),
event_name="storage.buckets.create",
event_source="storage.googleapis.com",
actor="service-account@project.iam.gserviceaccount.com",
actor_type="serviceAccount",
)
assert gcp_event.actor_type == "serviceAccount"