aws_lite_rs/api/
securityhub.rs1use crate::{
11 AwsError, AwsHttpClient, Result, ops::securityhub::SecurityhubOps,
12 types::securityhub::DescribeHubResponse,
13};
14
15pub struct SecurityHubClient<'a> {
17 ops: SecurityhubOps<'a>,
18}
19
20impl<'a> SecurityHubClient<'a> {
21 pub(crate) fn new(client: &'a AwsHttpClient) -> Self {
23 Self {
24 ops: SecurityhubOps::new(client),
25 }
26 }
27
28 pub async fn describe_hub(&self) -> Result<DescribeHubResponse> {
36 self.ops.describe_hub("").await
37 }
38
39 pub async fn is_enabled(&self) -> Result<bool> {
46 match self.ops.describe_hub("").await {
47 Ok(_) => Ok(true),
48 Err(AwsError::NotFound { .. }) => Ok(false),
49 Err(AwsError::ServiceError { status: 403, .. }) => Ok(false),
51 Err(e) => Err(e),
52 }
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use crate::AwsError;
59 use serde_json::json;
60
61 #[tokio::test]
62 async fn test_describe_hub_returns_hub_details() {
63 let mut mock = crate::MockClient::new();
64 mock.expect_get("/accounts")
65 .returning_json(json!({
66 "HubArn": "arn:aws:securityhub:us-east-1:123456789012:hub/default",
67 "SubscribedAt": "2024-01-15T10:00:00.000Z",
68 "AutoEnableControls": true,
69 "ControlFindingGenerator": "SECURITY_CONTROL"
70 }))
71 .times(1);
72
73 let client = crate::AwsHttpClient::from_mock(mock);
74 let sh = client.securityhub();
75 let hub = sh.describe_hub().await.unwrap();
76 assert_eq!(
77 hub.hub_arn.as_deref(),
78 Some("arn:aws:securityhub:us-east-1:123456789012:hub/default")
79 );
80 assert_eq!(hub.auto_enable_controls, Some(true));
81 assert_eq!(
82 hub.control_finding_generator.as_deref(),
83 Some("SECURITY_CONTROL")
84 );
85 }
86
87 #[tokio::test]
88 async fn test_is_enabled_true() {
89 let mut mock = crate::MockClient::new();
90 mock.expect_get("/accounts")
91 .returning_json(json!({
92 "HubArn": "arn:aws:securityhub:us-east-1:123456789012:hub/default",
93 "SubscribedAt": "2024-01-15T10:00:00.000Z"
94 }))
95 .times(1);
96
97 let client = crate::AwsHttpClient::from_mock(mock);
98 assert!(client.securityhub().is_enabled().await.unwrap());
99 }
100
101 #[tokio::test]
102 async fn test_is_enabled_false_when_not_found() {
103 let mut mock = crate::MockClient::new();
104 mock.expect_get("/accounts")
105 .returning_error(AwsError::NotFound {
106 resource: "Account is not subscribed to AWS Security Hub".into(),
107 })
108 .times(1);
109
110 let client = crate::AwsHttpClient::from_mock(mock);
111 assert!(!client.securityhub().is_enabled().await.unwrap());
112 }
113
114 #[tokio::test]
115 async fn test_is_enabled_false_when_invalid_access() {
116 let mut mock = crate::MockClient::new();
118 mock.expect_get("/accounts")
119 .returning_error(AwsError::ServiceError {
120 code: "HttpError403".into(),
121 message: "The AWS Access Key Id needs a subscription for the service".into(),
122 status: 403,
123 })
124 .times(1);
125
126 let client = crate::AwsHttpClient::from_mock(mock);
127 assert!(!client.securityhub().is_enabled().await.unwrap());
128 }
129}