aws_lambda_events/event/cloudwatch_events/
cloudtrail.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4
5#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
6#[serde(rename_all = "camelCase")]
7pub struct AWSAPICall<I = Value, O = Value> {
8    pub event_version: String,
9    pub user_identity: UserIdentity,
10    pub event_time: String,
11    pub event_source: String,
12    pub event_name: String,
13    pub aws_region: String,
14    #[serde(rename = "sourceIPAddress")]
15    pub source_ipaddress: String,
16    pub user_agent: String,
17    pub request_parameters: I,
18    pub response_elements: Option<O>,
19    #[serde(default)]
20    pub additional_event_data: Option<Value>,
21    #[serde(rename = "requestID")]
22    pub request_id: String,
23    #[serde(rename = "eventID")]
24    pub event_id: String,
25    pub event_type: String,
26    /// Catchall to catch any additional fields that were present but not explicitly defined by this struct.
27    /// Enabled with Cargo feature `catch-all-fields`.
28    /// If `catch-all-fields` is disabled, any additional fields that are present will be ignored.
29    #[cfg(feature = "catch-all-fields")]
30    #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
31    #[serde(flatten)]
32    pub other: serde_json::Map<String, Value>,
33}
34
35#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
36#[serde(rename_all = "camelCase")]
37pub struct SessionIssuer {
38    pub r#type: String,
39    pub user_name: Option<String>,
40    pub principal_id: String,
41    pub arn: String,
42    pub account_id: String,
43    /// Catchall to catch any additional fields that were present but not explicitly defined by this struct.
44    /// Enabled with Cargo feature `catch-all-fields`.
45    /// If `catch-all-fields` is disabled, any additional fields that are present will be ignored.
46    #[cfg(feature = "catch-all-fields")]
47    #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
48    #[serde(flatten)]
49    pub other: serde_json::Map<String, Value>,
50}
51
52#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
53#[serde(rename_all = "camelCase")]
54pub struct WebIdFederationData {
55    pub federated_provider: Option<String>,
56    pub attributes: Option<String>,
57    /// Catchall to catch any additional fields that were present but not explicitly defined by this struct.
58    /// Enabled with Cargo feature `catch-all-fields`.
59    /// If `catch-all-fields` is disabled, any additional fields that are present will be ignored.
60    #[cfg(feature = "catch-all-fields")]
61    #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
62    #[serde(flatten)]
63    pub other: serde_json::Map<String, Value>,
64}
65
66#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
67#[serde(rename_all = "camelCase")]
68pub struct Attributes {
69    pub mfa_authenticated: String,
70    pub creation_date: DateTime<Utc>,
71    /// Catchall to catch any additional fields that were present but not explicitly defined by this struct.
72    /// Enabled with Cargo feature `catch-all-fields`.
73    /// If `catch-all-fields` is disabled, any additional fields that are present will be ignored.
74    #[cfg(feature = "catch-all-fields")]
75    #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
76    #[serde(flatten)]
77    pub other: serde_json::Map<String, Value>,
78}
79
80#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
81#[serde(rename_all = "camelCase")]
82pub struct SessionContext {
83    pub session_issuer: Option<SessionIssuer>,
84    pub web_id_federation_data: Option<WebIdFederationData>,
85    pub attributes: Attributes,
86    pub source_identity: Option<String>,
87    pub ec2_role_delivery: Option<String>,
88    /// Catchall to catch any additional fields that were present but not explicitly defined by this struct.
89    /// Enabled with Cargo feature `catch-all-fields`.
90    /// If `catch-all-fields` is disabled, any additional fields that are present will be ignored.
91    #[cfg(feature = "catch-all-fields")]
92    #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
93    #[serde(flatten)]
94    pub other: serde_json::Map<String, Value>,
95}
96
97#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
98#[serde(rename_all = "camelCase")]
99pub struct OnBehalfOf {
100    pub user_id: String,
101    pub identity_store_arn: String,
102    /// Catchall to catch any additional fields that were present but not explicitly defined by this struct.
103    /// Enabled with Cargo feature `catch-all-fields`.
104    /// If `catch-all-fields` is disabled, any additional fields that are present will be ignored.
105    #[cfg(feature = "catch-all-fields")]
106    #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
107    #[serde(flatten)]
108    pub other: serde_json::Map<String, Value>,
109}
110
111// https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-user-identity.html
112#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
113#[serde(rename_all = "camelCase")]
114pub struct UserIdentity {
115    pub r#type: String,
116    pub account_id: Option<String>,
117    pub arn: Option<String>,
118    pub credential_id: Option<String>,
119    pub invoked_by: Option<String>,
120    pub principal_id: Option<String>,
121    pub session_context: Option<SessionContext>,
122    pub user_name: Option<String>,
123    pub on_behalf_of: Option<OnBehalfOf>,
124    /// Catchall to catch any additional fields that were present but not explicitly defined by this struct.
125    /// Enabled with Cargo feature `catch-all-fields`.
126    /// If `catch-all-fields` is disabled, any additional fields that are present will be ignored.
127    #[cfg(feature = "catch-all-fields")]
128    #[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
129    #[serde(flatten)]
130    pub other: serde_json::Map<String, Value>,
131}
132
133#[cfg(test)]
134mod tests {
135    use super::AWSAPICall;
136
137    #[test]
138    #[cfg(feature = "cloudwatch_events")]
139    fn example_cloudwatch_cloudtrail_unknown_assumed_role() {
140        let data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-assumed-role.json");
141        let parsed: AWSAPICall = serde_json::from_slice(data).unwrap();
142        let output: String = serde_json::to_string(&parsed).unwrap();
143        let reparsed: AWSAPICall = serde_json::from_slice(output.as_bytes()).unwrap();
144        assert_eq!(parsed, reparsed);
145    }
146    #[test]
147    #[cfg(feature = "cloudwatch_events")]
148    fn example_cloudwatch_cloudtrail_unknown_federate() {
149        let data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-unknown-federate.json");
150        let parsed: AWSAPICall = serde_json::from_slice(data).unwrap();
151        let output: String = serde_json::to_string(&parsed).unwrap();
152        let reparsed: AWSAPICall = serde_json::from_slice(output.as_bytes()).unwrap();
153        assert_eq!(parsed, reparsed);
154    }
155    #[test]
156    #[cfg(feature = "cloudwatch_events")]
157    fn example_cloudwatch_cloudtrail_assumed_role() {
158        let data = include_bytes!("../../fixtures/example-cloudwatch-cloudtrail-unknown-user-auth.json");
159        let parsed: AWSAPICall = serde_json::from_slice(data).unwrap();
160        let output: String = serde_json::to_string(&parsed).unwrap();
161        let reparsed: AWSAPICall = serde_json::from_slice(output.as_bytes()).unwrap();
162        assert_eq!(parsed, reparsed);
163    }
164}