1use std::collections::HashMap;
2
3use chrono::Utc;
4
5use crate::types::*;
6
7#[derive(Debug, Default)]
8pub struct WorkspacesWebState {
9 pub portals: HashMap<String, Portal>,
10 pub browser_settings: HashMap<String, BrowserSettings>,
11 pub network_settings: HashMap<String, NetworkSettings>,
12 pub user_access_logging_settings: HashMap<String, UserAccessLoggingSettings>,
13 pub user_settings: HashMap<String, UserSettings>,
14 pub identity_providers: HashMap<String, IdentityProvider>,
15 pub ip_access_settings: HashMap<String, IpAccessSettings>,
16 pub trust_stores: HashMap<String, TrustStore>,
17 pub data_protection_settings: HashMap<String, DataProtectionSettings>,
18 pub session_loggers: HashMap<String, SessionLogger>,
19 pub sessions: HashMap<String, Session>,
20}
21
22#[derive(Debug, thiserror::Error)]
23pub enum WorkspacesWebError {
24 #[error("Resource {0} not found.")]
25 ResourceNotFound(String),
26 #[error("Session {0} not found.")]
27 SessionNotFound(String),
28}
29
30impl WorkspacesWebState {
31 pub fn create_portal(
34 &mut self,
35 display_name: Option<&str>,
36 account_id: &str,
37 region: &str,
38 tags: HashMap<String, String>,
39 ) -> Result<&Portal, WorkspacesWebError> {
40 let portal_id = uuid::Uuid::new_v4().to_string();
41 let portal_arn = format!("arn:aws:workspaces-web:{region}:{account_id}:portal/{portal_id}");
42 let portal_endpoint = format!("https://{portal_id}.workspaces-web.{region}.amazonaws.com");
43
44 let name = display_name.unwrap_or("").to_string();
45
46 let portal = Portal {
47 portal_arn: portal_arn.clone(),
48 portal_endpoint,
49 display_name: name,
50 portal_status: "Active".to_string(),
51 browser_type: "Chrome".to_string(),
52 renderer_type: "AppStream".to_string(),
53 creation_date: Utc::now(),
54 browser_settings_arn: None,
55 network_settings_arn: None,
56 user_access_logging_settings_arn: None,
57 user_settings_arn: None,
58 trust_store_arn: None,
59 ip_access_settings_arn: None,
60 data_protection_settings_arn: None,
61 session_logger_arn: None,
62 tags,
63 };
64
65 self.portals.insert(portal_arn.clone(), portal);
66 Ok(self.portals.get(&portal_arn).unwrap())
67 }
68
69 pub fn get_portal(&self, portal_arn: &str) -> Result<&Portal, WorkspacesWebError> {
70 self.portals
71 .get(portal_arn)
72 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(portal_arn.to_string()))
73 }
74
75 pub fn delete_portal(&mut self, portal_arn: &str) -> Result<(), WorkspacesWebError> {
76 if self.portals.remove(portal_arn).is_none() {
77 return Err(WorkspacesWebError::ResourceNotFound(portal_arn.to_string()));
78 }
79 Ok(())
80 }
81
82 pub fn list_portals(&self) -> Vec<&Portal> {
83 self.portals.values().collect()
84 }
85
86 pub fn create_browser_settings(
89 &mut self,
90 browser_policy: Option<&str>,
91 account_id: &str,
92 region: &str,
93 tags: HashMap<String, String>,
94 ) -> Result<&BrowserSettings, WorkspacesWebError> {
95 let id = uuid::Uuid::new_v4().to_string();
96 let arn = format!("arn:aws:workspaces-web:{region}:{account_id}:browserSettings/{id}");
97
98 let bs = BrowserSettings {
99 browser_settings_arn: arn.clone(),
100 browser_policy: browser_policy.map(|s| s.to_string()),
101 associated_portal_arns: Vec::new(),
102 tags,
103 };
104
105 self.browser_settings.insert(arn.clone(), bs);
106 Ok(self.browser_settings.get(&arn).unwrap())
107 }
108
109 pub fn get_browser_settings(&self, arn: &str) -> Result<&BrowserSettings, WorkspacesWebError> {
110 self.browser_settings
111 .get(arn)
112 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(arn.to_string()))
113 }
114
115 pub fn delete_browser_settings(&mut self, arn: &str) -> Result<(), WorkspacesWebError> {
116 if self.browser_settings.remove(arn).is_none() {
117 return Err(WorkspacesWebError::ResourceNotFound(arn.to_string()));
118 }
119 Ok(())
120 }
121
122 pub fn list_browser_settings(&self) -> Vec<&BrowserSettings> {
123 self.browser_settings.values().collect()
124 }
125
126 pub fn create_network_settings(
129 &mut self,
130 vpc_id: &str,
131 subnet_ids: Vec<String>,
132 security_group_ids: Vec<String>,
133 account_id: &str,
134 region: &str,
135 tags: HashMap<String, String>,
136 ) -> Result<&NetworkSettings, WorkspacesWebError> {
137 let id = uuid::Uuid::new_v4().to_string();
138 let arn = format!("arn:aws:workspaces-web:{region}:{account_id}:networkSettings/{id}");
139
140 let ns = NetworkSettings {
141 network_settings_arn: arn.clone(),
142 vpc_id: vpc_id.to_string(),
143 subnet_ids,
144 security_group_ids,
145 associated_portal_arns: Vec::new(),
146 tags,
147 };
148
149 self.network_settings.insert(arn.clone(), ns);
150 Ok(self.network_settings.get(&arn).unwrap())
151 }
152
153 pub fn get_network_settings(&self, arn: &str) -> Result<&NetworkSettings, WorkspacesWebError> {
154 self.network_settings
155 .get(arn)
156 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(arn.to_string()))
157 }
158
159 pub fn delete_network_settings(&mut self, arn: &str) -> Result<(), WorkspacesWebError> {
160 if self.network_settings.remove(arn).is_none() {
161 return Err(WorkspacesWebError::ResourceNotFound(arn.to_string()));
162 }
163 Ok(())
164 }
165
166 pub fn list_network_settings(&self) -> Vec<&NetworkSettings> {
167 self.network_settings.values().collect()
168 }
169
170 pub fn create_user_access_logging_settings(
173 &mut self,
174 kinesis_stream_arn: &str,
175 account_id: &str,
176 region: &str,
177 tags: HashMap<String, String>,
178 ) -> Result<&UserAccessLoggingSettings, WorkspacesWebError> {
179 let id = uuid::Uuid::new_v4().to_string();
180 let arn =
181 format!("arn:aws:workspaces-web:{region}:{account_id}:userAccessLoggingSettings/{id}");
182
183 let ual = UserAccessLoggingSettings {
184 user_access_logging_settings_arn: arn.clone(),
185 kinesis_stream_arn: kinesis_stream_arn.to_string(),
186 associated_portal_arns: Vec::new(),
187 tags,
188 };
189
190 self.user_access_logging_settings.insert(arn.clone(), ual);
191 Ok(self.user_access_logging_settings.get(&arn).unwrap())
192 }
193
194 pub fn get_user_access_logging_settings(
195 &self,
196 arn: &str,
197 ) -> Result<&UserAccessLoggingSettings, WorkspacesWebError> {
198 self.user_access_logging_settings
199 .get(arn)
200 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(arn.to_string()))
201 }
202
203 pub fn delete_user_access_logging_settings(
204 &mut self,
205 arn: &str,
206 ) -> Result<(), WorkspacesWebError> {
207 if self.user_access_logging_settings.remove(arn).is_none() {
208 return Err(WorkspacesWebError::ResourceNotFound(arn.to_string()));
209 }
210 Ok(())
211 }
212
213 pub fn list_user_access_logging_settings(&self) -> Vec<&UserAccessLoggingSettings> {
214 self.user_access_logging_settings.values().collect()
215 }
216
217 pub fn create_user_settings(
220 &mut self,
221 copy_allowed: &str,
222 paste_allowed: &str,
223 download_allowed: &str,
224 upload_allowed: &str,
225 print_allowed: &str,
226 disconnect_timeout_in_minutes: Option<i32>,
227 idle_disconnect_timeout_in_minutes: Option<i32>,
228 account_id: &str,
229 region: &str,
230 tags: HashMap<String, String>,
231 ) -> Result<&UserSettings, WorkspacesWebError> {
232 let id = uuid::Uuid::new_v4().to_string();
233 let arn = format!("arn:aws:workspaces-web:{region}:{account_id}:userSettings/{id}");
234
235 let us = UserSettings {
236 user_settings_arn: arn.clone(),
237 copy_allowed: copy_allowed.to_string(),
238 paste_allowed: paste_allowed.to_string(),
239 download_allowed: download_allowed.to_string(),
240 upload_allowed: upload_allowed.to_string(),
241 print_allowed: print_allowed.to_string(),
242 disconnect_timeout_in_minutes,
243 idle_disconnect_timeout_in_minutes,
244 associated_portal_arns: Vec::new(),
245 tags,
246 };
247
248 self.user_settings.insert(arn.clone(), us);
249 Ok(self.user_settings.get(&arn).unwrap())
250 }
251
252 pub fn get_user_settings(&self, arn: &str) -> Result<&UserSettings, WorkspacesWebError> {
253 self.user_settings
254 .get(arn)
255 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(arn.to_string()))
256 }
257
258 pub fn delete_user_settings(&mut self, arn: &str) -> Result<(), WorkspacesWebError> {
259 if self.user_settings.remove(arn).is_none() {
260 return Err(WorkspacesWebError::ResourceNotFound(arn.to_string()));
261 }
262 Ok(())
263 }
264
265 pub fn list_user_settings(&self) -> Vec<&UserSettings> {
266 self.user_settings.values().collect()
267 }
268
269 pub fn associate_browser_settings(
272 &mut self,
273 portal_arn: &str,
274 browser_settings_arn: &str,
275 ) -> Result<(), WorkspacesWebError> {
276 if !self.portals.contains_key(portal_arn) {
278 return Err(WorkspacesWebError::ResourceNotFound(portal_arn.to_string()));
279 }
280 if !self.browser_settings.contains_key(browser_settings_arn) {
281 return Err(WorkspacesWebError::ResourceNotFound(
282 browser_settings_arn.to_string(),
283 ));
284 }
285 self.portals
286 .get_mut(portal_arn)
287 .unwrap()
288 .browser_settings_arn = Some(browser_settings_arn.to_string());
289 let bs = self.browser_settings.get_mut(browser_settings_arn).unwrap();
290 if !bs.associated_portal_arns.contains(&portal_arn.to_string()) {
291 bs.associated_portal_arns.push(portal_arn.to_string());
292 }
293 Ok(())
294 }
295
296 pub fn associate_network_settings(
297 &mut self,
298 portal_arn: &str,
299 network_settings_arn: &str,
300 ) -> Result<(), WorkspacesWebError> {
301 if !self.portals.contains_key(portal_arn) {
302 return Err(WorkspacesWebError::ResourceNotFound(portal_arn.to_string()));
303 }
304 if !self.network_settings.contains_key(network_settings_arn) {
305 return Err(WorkspacesWebError::ResourceNotFound(
306 network_settings_arn.to_string(),
307 ));
308 }
309 self.portals
310 .get_mut(portal_arn)
311 .unwrap()
312 .network_settings_arn = Some(network_settings_arn.to_string());
313 let ns = self.network_settings.get_mut(network_settings_arn).unwrap();
314 if !ns.associated_portal_arns.contains(&portal_arn.to_string()) {
315 ns.associated_portal_arns.push(portal_arn.to_string());
316 }
317 Ok(())
318 }
319
320 pub fn associate_user_access_logging_settings(
321 &mut self,
322 portal_arn: &str,
323 user_access_logging_settings_arn: &str,
324 ) -> Result<(), WorkspacesWebError> {
325 if !self.portals.contains_key(portal_arn) {
326 return Err(WorkspacesWebError::ResourceNotFound(portal_arn.to_string()));
327 }
328 if !self
329 .user_access_logging_settings
330 .contains_key(user_access_logging_settings_arn)
331 {
332 return Err(WorkspacesWebError::ResourceNotFound(
333 user_access_logging_settings_arn.to_string(),
334 ));
335 }
336 self.portals
337 .get_mut(portal_arn)
338 .unwrap()
339 .user_access_logging_settings_arn = Some(user_access_logging_settings_arn.to_string());
340 let ual = self
341 .user_access_logging_settings
342 .get_mut(user_access_logging_settings_arn)
343 .unwrap();
344 if !ual.associated_portal_arns.contains(&portal_arn.to_string()) {
345 ual.associated_portal_arns.push(portal_arn.to_string());
346 }
347 Ok(())
348 }
349
350 pub fn associate_user_settings(
351 &mut self,
352 portal_arn: &str,
353 user_settings_arn: &str,
354 ) -> Result<(), WorkspacesWebError> {
355 if !self.portals.contains_key(portal_arn) {
356 return Err(WorkspacesWebError::ResourceNotFound(portal_arn.to_string()));
357 }
358 if !self.user_settings.contains_key(user_settings_arn) {
359 return Err(WorkspacesWebError::ResourceNotFound(
360 user_settings_arn.to_string(),
361 ));
362 }
363 self.portals.get_mut(portal_arn).unwrap().user_settings_arn =
364 Some(user_settings_arn.to_string());
365 let us = self.user_settings.get_mut(user_settings_arn).unwrap();
366 if !us.associated_portal_arns.contains(&portal_arn.to_string()) {
367 us.associated_portal_arns.push(portal_arn.to_string());
368 }
369 Ok(())
370 }
371
372 pub fn update_portal(
375 &mut self,
376 portal_arn: &str,
377 display_name: Option<&str>,
378 ) -> Result<&Portal, WorkspacesWebError> {
379 let portal = self
380 .portals
381 .get_mut(portal_arn)
382 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(portal_arn.to_string()))?;
383 if let Some(name) = display_name {
384 portal.display_name = name.to_string();
385 }
386 Ok(self.portals.get(portal_arn).unwrap())
387 }
388
389 pub fn create_identity_provider(
392 &mut self,
393 portal_arn: &str,
394 name: &str,
395 provider_type: &str,
396 details: HashMap<String, String>,
397 account_id: &str,
398 region: &str,
399 ) -> Result<&IdentityProvider, WorkspacesWebError> {
400 if !self.portals.contains_key(portal_arn) {
401 return Err(WorkspacesWebError::ResourceNotFound(portal_arn.to_string()));
402 }
403 let id = uuid::Uuid::new_v4().to_string();
404 let arn = format!("arn:aws:workspaces-web:{region}:{account_id}:identityProvider/{id}");
405 let ip = IdentityProvider {
406 identity_provider_arn: arn.clone(),
407 portal_arn: portal_arn.to_string(),
408 identity_provider_name: name.to_string(),
409 identity_provider_type: provider_type.to_string(),
410 identity_provider_details: details,
411 };
412 self.identity_providers.insert(arn.clone(), ip);
413 Ok(self.identity_providers.get(&arn).unwrap())
414 }
415
416 pub fn get_identity_provider(
417 &self,
418 arn: &str,
419 ) -> Result<&IdentityProvider, WorkspacesWebError> {
420 self.identity_providers
421 .get(arn)
422 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(arn.to_string()))
423 }
424
425 pub fn delete_identity_provider(&mut self, arn: &str) -> Result<(), WorkspacesWebError> {
426 if self.identity_providers.remove(arn).is_none() {
427 return Err(WorkspacesWebError::ResourceNotFound(arn.to_string()));
428 }
429 Ok(())
430 }
431
432 pub fn list_identity_providers(&self, portal_arn: &str) -> Vec<&IdentityProvider> {
433 self.identity_providers
434 .values()
435 .filter(|ip| ip.portal_arn == portal_arn)
436 .collect()
437 }
438
439 pub fn update_identity_provider(
440 &mut self,
441 arn: &str,
442 name: Option<&str>,
443 provider_type: Option<&str>,
444 details: Option<HashMap<String, String>>,
445 ) -> Result<&IdentityProvider, WorkspacesWebError> {
446 let ip = self
447 .identity_providers
448 .get_mut(arn)
449 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(arn.to_string()))?;
450 if let Some(n) = name {
451 ip.identity_provider_name = n.to_string();
452 }
453 if let Some(t) = provider_type {
454 ip.identity_provider_type = t.to_string();
455 }
456 if let Some(d) = details {
457 ip.identity_provider_details = d;
458 }
459 Ok(self.identity_providers.get(arn).unwrap())
460 }
461
462 pub fn create_ip_access_settings(
465 &mut self,
466 ip_rules: Vec<IpRule>,
467 display_name: Option<String>,
468 description: Option<String>,
469 account_id: &str,
470 region: &str,
471 tags: HashMap<String, String>,
472 ) -> Result<&IpAccessSettings, WorkspacesWebError> {
473 let id = uuid::Uuid::new_v4().to_string();
474 let arn = format!("arn:aws:workspaces-web:{region}:{account_id}:ipAccessSettings/{id}");
475 let ias = IpAccessSettings {
476 ip_access_settings_arn: arn.clone(),
477 display_name,
478 description,
479 ip_rules,
480 associated_portal_arns: Vec::new(),
481 creation_date: Utc::now(),
482 tags,
483 };
484 self.ip_access_settings.insert(arn.clone(), ias);
485 Ok(self.ip_access_settings.get(&arn).unwrap())
486 }
487
488 pub fn get_ip_access_settings(
489 &self,
490 arn: &str,
491 ) -> Result<&IpAccessSettings, WorkspacesWebError> {
492 self.ip_access_settings
493 .get(arn)
494 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(arn.to_string()))
495 }
496
497 pub fn delete_ip_access_settings(&mut self, arn: &str) -> Result<(), WorkspacesWebError> {
498 if self.ip_access_settings.remove(arn).is_none() {
499 return Err(WorkspacesWebError::ResourceNotFound(arn.to_string()));
500 }
501 Ok(())
502 }
503
504 pub fn list_ip_access_settings(&self) -> Vec<&IpAccessSettings> {
505 self.ip_access_settings.values().collect()
506 }
507
508 pub fn update_ip_access_settings(
509 &mut self,
510 arn: &str,
511 ip_rules: Option<Vec<IpRule>>,
512 display_name: Option<String>,
513 description: Option<String>,
514 ) -> Result<&IpAccessSettings, WorkspacesWebError> {
515 let ias = self
516 .ip_access_settings
517 .get_mut(arn)
518 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(arn.to_string()))?;
519 if let Some(rules) = ip_rules {
520 ias.ip_rules = rules;
521 }
522 if display_name.is_some() {
523 ias.display_name = display_name;
524 }
525 if description.is_some() {
526 ias.description = description;
527 }
528 Ok(self.ip_access_settings.get(arn).unwrap())
529 }
530
531 pub fn associate_ip_access_settings(
532 &mut self,
533 portal_arn: &str,
534 ip_access_settings_arn: &str,
535 ) -> Result<(), WorkspacesWebError> {
536 if !self.portals.contains_key(portal_arn) {
537 return Err(WorkspacesWebError::ResourceNotFound(portal_arn.to_string()));
538 }
539 if !self.ip_access_settings.contains_key(ip_access_settings_arn) {
540 return Err(WorkspacesWebError::ResourceNotFound(
541 ip_access_settings_arn.to_string(),
542 ));
543 }
544 self.portals
545 .get_mut(portal_arn)
546 .unwrap()
547 .ip_access_settings_arn = Some(ip_access_settings_arn.to_string());
548 let ias = self
549 .ip_access_settings
550 .get_mut(ip_access_settings_arn)
551 .unwrap();
552 if !ias.associated_portal_arns.contains(&portal_arn.to_string()) {
553 ias.associated_portal_arns.push(portal_arn.to_string());
554 }
555 Ok(())
556 }
557
558 pub fn disassociate_ip_access_settings(
559 &mut self,
560 portal_arn: &str,
561 ) -> Result<(), WorkspacesWebError> {
562 let portal = self
563 .portals
564 .get_mut(portal_arn)
565 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(portal_arn.to_string()))?;
566 portal.ip_access_settings_arn = None;
567 Ok(())
568 }
569
570 pub fn create_trust_store(
573 &mut self,
574 certificate_list: Vec<String>,
575 account_id: &str,
576 region: &str,
577 tags: HashMap<String, String>,
578 ) -> Result<&TrustStore, WorkspacesWebError> {
579 let id = uuid::Uuid::new_v4().to_string();
580 let arn = format!("arn:aws:workspaces-web:{region}:{account_id}:trustStore/{id}");
581 let certs: Vec<TrustStoreCertificate> = certificate_list
582 .into_iter()
583 .enumerate()
584 .map(|(i, body)| TrustStoreCertificate {
585 thumbprint: format!("thumb{i:04}"),
586 body,
587 issuer: None,
588 subject: None,
589 })
590 .collect();
591 let ts = TrustStore {
592 trust_store_arn: arn.clone(),
593 certificate_list: certs,
594 associated_portal_arns: Vec::new(),
595 tags,
596 };
597 self.trust_stores.insert(arn.clone(), ts);
598 Ok(self.trust_stores.get(&arn).unwrap())
599 }
600
601 pub fn get_trust_store(&self, arn: &str) -> Result<&TrustStore, WorkspacesWebError> {
602 self.trust_stores
603 .get(arn)
604 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(arn.to_string()))
605 }
606
607 pub fn delete_trust_store(&mut self, arn: &str) -> Result<(), WorkspacesWebError> {
608 if self.trust_stores.remove(arn).is_none() {
609 return Err(WorkspacesWebError::ResourceNotFound(arn.to_string()));
610 }
611 Ok(())
612 }
613
614 pub fn list_trust_stores(&self) -> Vec<&TrustStore> {
615 self.trust_stores.values().collect()
616 }
617
618 pub fn update_trust_store(
619 &mut self,
620 arn: &str,
621 certs_to_add: Vec<String>,
622 thumbprints_to_delete: Vec<String>,
623 ) -> Result<&TrustStore, WorkspacesWebError> {
624 let ts = self
625 .trust_stores
626 .get_mut(arn)
627 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(arn.to_string()))?;
628 ts.certificate_list
629 .retain(|c| !thumbprints_to_delete.contains(&c.thumbprint));
630 let existing_count = ts.certificate_list.len();
631 for (i, body) in certs_to_add.into_iter().enumerate() {
632 ts.certificate_list.push(TrustStoreCertificate {
633 thumbprint: format!("thumb{:04}", existing_count + i),
634 body,
635 issuer: None,
636 subject: None,
637 });
638 }
639 Ok(self.trust_stores.get(arn).unwrap())
640 }
641
642 pub fn associate_trust_store(
643 &mut self,
644 portal_arn: &str,
645 trust_store_arn: &str,
646 ) -> Result<(), WorkspacesWebError> {
647 if !self.portals.contains_key(portal_arn) {
648 return Err(WorkspacesWebError::ResourceNotFound(portal_arn.to_string()));
649 }
650 if !self.trust_stores.contains_key(trust_store_arn) {
651 return Err(WorkspacesWebError::ResourceNotFound(
652 trust_store_arn.to_string(),
653 ));
654 }
655 self.portals.get_mut(portal_arn).unwrap().trust_store_arn =
656 Some(trust_store_arn.to_string());
657 let ts = self.trust_stores.get_mut(trust_store_arn).unwrap();
658 if !ts.associated_portal_arns.contains(&portal_arn.to_string()) {
659 ts.associated_portal_arns.push(portal_arn.to_string());
660 }
661 Ok(())
662 }
663
664 pub fn disassociate_trust_store(&mut self, portal_arn: &str) -> Result<(), WorkspacesWebError> {
665 let portal = self
666 .portals
667 .get_mut(portal_arn)
668 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(portal_arn.to_string()))?;
669 portal.trust_store_arn = None;
670 Ok(())
671 }
672
673 pub fn create_data_protection_settings(
676 &mut self,
677 display_name: Option<String>,
678 description: Option<String>,
679 account_id: &str,
680 region: &str,
681 tags: HashMap<String, String>,
682 ) -> Result<&DataProtectionSettings, WorkspacesWebError> {
683 let id = uuid::Uuid::new_v4().to_string();
684 let arn =
685 format!("arn:aws:workspaces-web:{region}:{account_id}:dataProtectionSettings/{id}");
686 let dps = DataProtectionSettings {
687 data_protection_settings_arn: arn.clone(),
688 display_name,
689 description,
690 associated_portal_arns: Vec::new(),
691 creation_date: Utc::now(),
692 tags,
693 };
694 self.data_protection_settings.insert(arn.clone(), dps);
695 Ok(self.data_protection_settings.get(&arn).unwrap())
696 }
697
698 pub fn get_data_protection_settings(
699 &self,
700 arn: &str,
701 ) -> Result<&DataProtectionSettings, WorkspacesWebError> {
702 self.data_protection_settings
703 .get(arn)
704 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(arn.to_string()))
705 }
706
707 pub fn delete_data_protection_settings(&mut self, arn: &str) -> Result<(), WorkspacesWebError> {
708 if self.data_protection_settings.remove(arn).is_none() {
709 return Err(WorkspacesWebError::ResourceNotFound(arn.to_string()));
710 }
711 Ok(())
712 }
713
714 pub fn list_data_protection_settings(&self) -> Vec<&DataProtectionSettings> {
715 self.data_protection_settings.values().collect()
716 }
717
718 pub fn update_data_protection_settings(
719 &mut self,
720 arn: &str,
721 display_name: Option<String>,
722 description: Option<String>,
723 ) -> Result<&DataProtectionSettings, WorkspacesWebError> {
724 let dps = self
725 .data_protection_settings
726 .get_mut(arn)
727 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(arn.to_string()))?;
728 if display_name.is_some() {
729 dps.display_name = display_name;
730 }
731 if description.is_some() {
732 dps.description = description;
733 }
734 Ok(self.data_protection_settings.get(arn).unwrap())
735 }
736
737 pub fn associate_data_protection_settings(
738 &mut self,
739 portal_arn: &str,
740 data_protection_settings_arn: &str,
741 ) -> Result<(), WorkspacesWebError> {
742 if !self.portals.contains_key(portal_arn) {
743 return Err(WorkspacesWebError::ResourceNotFound(portal_arn.to_string()));
744 }
745 if !self
746 .data_protection_settings
747 .contains_key(data_protection_settings_arn)
748 {
749 return Err(WorkspacesWebError::ResourceNotFound(
750 data_protection_settings_arn.to_string(),
751 ));
752 }
753 self.portals
754 .get_mut(portal_arn)
755 .unwrap()
756 .data_protection_settings_arn = Some(data_protection_settings_arn.to_string());
757 let dps = self
758 .data_protection_settings
759 .get_mut(data_protection_settings_arn)
760 .unwrap();
761 if !dps.associated_portal_arns.contains(&portal_arn.to_string()) {
762 dps.associated_portal_arns.push(portal_arn.to_string());
763 }
764 Ok(())
765 }
766
767 pub fn disassociate_data_protection_settings(
768 &mut self,
769 portal_arn: &str,
770 ) -> Result<(), WorkspacesWebError> {
771 let portal = self
772 .portals
773 .get_mut(portal_arn)
774 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(portal_arn.to_string()))?;
775 portal.data_protection_settings_arn = None;
776 Ok(())
777 }
778
779 pub fn create_session_logger(
782 &mut self,
783 display_name: Option<String>,
784 account_id: &str,
785 region: &str,
786 tags: HashMap<String, String>,
787 ) -> Result<&SessionLogger, WorkspacesWebError> {
788 let id = uuid::Uuid::new_v4().to_string();
789 let arn = format!("arn:aws:workspaces-web:{region}:{account_id}:sessionLogger/{id}");
790 let sl = SessionLogger {
791 session_logger_arn: arn.clone(),
792 display_name,
793 associated_portal_arns: Vec::new(),
794 creation_date: Utc::now(),
795 tags,
796 };
797 self.session_loggers.insert(arn.clone(), sl);
798 Ok(self.session_loggers.get(&arn).unwrap())
799 }
800
801 pub fn get_session_logger(&self, arn: &str) -> Result<&SessionLogger, WorkspacesWebError> {
802 self.session_loggers
803 .get(arn)
804 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(arn.to_string()))
805 }
806
807 pub fn delete_session_logger(&mut self, arn: &str) -> Result<(), WorkspacesWebError> {
808 if self.session_loggers.remove(arn).is_none() {
809 return Err(WorkspacesWebError::ResourceNotFound(arn.to_string()));
810 }
811 Ok(())
812 }
813
814 pub fn list_session_loggers(&self) -> Vec<&SessionLogger> {
815 self.session_loggers.values().collect()
816 }
817
818 pub fn update_session_logger(
819 &mut self,
820 arn: &str,
821 display_name: Option<String>,
822 ) -> Result<&SessionLogger, WorkspacesWebError> {
823 let sl = self
824 .session_loggers
825 .get_mut(arn)
826 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(arn.to_string()))?;
827 if display_name.is_some() {
828 sl.display_name = display_name;
829 }
830 Ok(self.session_loggers.get(arn).unwrap())
831 }
832
833 pub fn associate_session_logger(
834 &mut self,
835 portal_arn: &str,
836 session_logger_arn: &str,
837 ) -> Result<(), WorkspacesWebError> {
838 if !self.portals.contains_key(portal_arn) {
839 return Err(WorkspacesWebError::ResourceNotFound(portal_arn.to_string()));
840 }
841 if !self.session_loggers.contains_key(session_logger_arn) {
842 return Err(WorkspacesWebError::ResourceNotFound(
843 session_logger_arn.to_string(),
844 ));
845 }
846 self.portals.get_mut(portal_arn).unwrap().session_logger_arn =
847 Some(session_logger_arn.to_string());
848 let sl = self.session_loggers.get_mut(session_logger_arn).unwrap();
849 if !sl.associated_portal_arns.contains(&portal_arn.to_string()) {
850 sl.associated_portal_arns.push(portal_arn.to_string());
851 }
852 Ok(())
853 }
854
855 pub fn disassociate_session_logger(
856 &mut self,
857 portal_arn: &str,
858 ) -> Result<(), WorkspacesWebError> {
859 let portal = self
860 .portals
861 .get_mut(portal_arn)
862 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(portal_arn.to_string()))?;
863 portal.session_logger_arn = None;
864 Ok(())
865 }
866
867 pub fn get_session(
870 &self,
871 portal_id: &str,
872 session_id: &str,
873 ) -> Result<&Session, WorkspacesWebError> {
874 self.sessions
875 .get(session_id)
876 .filter(|s| s.portal_id == portal_id)
877 .ok_or_else(|| WorkspacesWebError::SessionNotFound(session_id.to_string()))
878 }
879
880 pub fn list_sessions(&self, portal_id: &str) -> Vec<&Session> {
881 self.sessions
882 .values()
883 .filter(|s| s.portal_id == portal_id)
884 .collect()
885 }
886
887 pub fn expire_session(
888 &mut self,
889 portal_id: &str,
890 session_id: &str,
891 ) -> Result<(), WorkspacesWebError> {
892 let session = self
893 .sessions
894 .get_mut(session_id)
895 .filter(|s| s.portal_id == portal_id)
896 .ok_or_else(|| WorkspacesWebError::SessionNotFound(session_id.to_string()))?;
897 session.status = "Terminated".to_string();
898 session.end_time = Some(Utc::now());
899 Ok(())
900 }
901
902 pub fn disassociate_browser_settings(
905 &mut self,
906 portal_arn: &str,
907 ) -> Result<(), WorkspacesWebError> {
908 let portal = self
909 .portals
910 .get_mut(portal_arn)
911 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(portal_arn.to_string()))?;
912 portal.browser_settings_arn = None;
913 Ok(())
914 }
915
916 pub fn disassociate_network_settings(
917 &mut self,
918 portal_arn: &str,
919 ) -> Result<(), WorkspacesWebError> {
920 let portal = self
921 .portals
922 .get_mut(portal_arn)
923 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(portal_arn.to_string()))?;
924 portal.network_settings_arn = None;
925 Ok(())
926 }
927
928 pub fn disassociate_user_access_logging_settings(
929 &mut self,
930 portal_arn: &str,
931 ) -> Result<(), WorkspacesWebError> {
932 let portal = self
933 .portals
934 .get_mut(portal_arn)
935 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(portal_arn.to_string()))?;
936 portal.user_access_logging_settings_arn = None;
937 Ok(())
938 }
939
940 pub fn disassociate_user_settings(
941 &mut self,
942 portal_arn: &str,
943 ) -> Result<(), WorkspacesWebError> {
944 let portal = self
945 .portals
946 .get_mut(portal_arn)
947 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(portal_arn.to_string()))?;
948 portal.user_settings_arn = None;
949 Ok(())
950 }
951
952 pub fn update_browser_settings(
955 &mut self,
956 arn: &str,
957 browser_policy: Option<String>,
958 ) -> Result<&BrowserSettings, WorkspacesWebError> {
959 let bs = self
960 .browser_settings
961 .get_mut(arn)
962 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(arn.to_string()))?;
963 if let Some(p) = browser_policy {
964 bs.browser_policy = Some(p);
965 }
966 Ok(self.browser_settings.get(arn).unwrap())
967 }
968
969 pub fn update_network_settings(
970 &mut self,
971 arn: &str,
972 vpc_id: Option<String>,
973 subnet_ids: Option<Vec<String>>,
974 security_group_ids: Option<Vec<String>>,
975 ) -> Result<&NetworkSettings, WorkspacesWebError> {
976 let ns = self
977 .network_settings
978 .get_mut(arn)
979 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(arn.to_string()))?;
980 if let Some(v) = vpc_id {
981 ns.vpc_id = v;
982 }
983 if let Some(s) = subnet_ids {
984 ns.subnet_ids = s;
985 }
986 if let Some(sg) = security_group_ids {
987 ns.security_group_ids = sg;
988 }
989 Ok(self.network_settings.get(arn).unwrap())
990 }
991
992 pub fn update_user_access_logging_settings(
993 &mut self,
994 arn: &str,
995 kinesis_stream_arn: Option<String>,
996 ) -> Result<&UserAccessLoggingSettings, WorkspacesWebError> {
997 let ual = self
998 .user_access_logging_settings
999 .get_mut(arn)
1000 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(arn.to_string()))?;
1001 if let Some(k) = kinesis_stream_arn {
1002 ual.kinesis_stream_arn = k;
1003 }
1004 Ok(self.user_access_logging_settings.get(arn).unwrap())
1005 }
1006
1007 pub fn update_user_settings(
1008 &mut self,
1009 arn: &str,
1010 copy_allowed: Option<String>,
1011 paste_allowed: Option<String>,
1012 download_allowed: Option<String>,
1013 upload_allowed: Option<String>,
1014 print_allowed: Option<String>,
1015 disconnect_timeout: Option<i32>,
1016 idle_disconnect_timeout: Option<i32>,
1017 ) -> Result<&UserSettings, WorkspacesWebError> {
1018 let us = self
1019 .user_settings
1020 .get_mut(arn)
1021 .ok_or_else(|| WorkspacesWebError::ResourceNotFound(arn.to_string()))?;
1022 if let Some(v) = copy_allowed {
1023 us.copy_allowed = v;
1024 }
1025 if let Some(v) = paste_allowed {
1026 us.paste_allowed = v;
1027 }
1028 if let Some(v) = download_allowed {
1029 us.download_allowed = v;
1030 }
1031 if let Some(v) = upload_allowed {
1032 us.upload_allowed = v;
1033 }
1034 if let Some(v) = print_allowed {
1035 us.print_allowed = v;
1036 }
1037 if let Some(v) = disconnect_timeout {
1038 us.disconnect_timeout_in_minutes = Some(v);
1039 }
1040 if let Some(v) = idle_disconnect_timeout {
1041 us.idle_disconnect_timeout_in_minutes = Some(v);
1042 }
1043 Ok(self.user_settings.get(arn).unwrap())
1044 }
1045
1046 pub fn get_tags_for_resource(
1049 &self,
1050 resource_arn: &str,
1051 ) -> Result<&HashMap<String, String>, WorkspacesWebError> {
1052 if let Some(p) = self.portals.get(resource_arn) {
1053 return Ok(&p.tags);
1054 }
1055 if let Some(bs) = self.browser_settings.get(resource_arn) {
1056 return Ok(&bs.tags);
1057 }
1058 if let Some(ns) = self.network_settings.get(resource_arn) {
1059 return Ok(&ns.tags);
1060 }
1061 if let Some(ual) = self.user_access_logging_settings.get(resource_arn) {
1062 return Ok(&ual.tags);
1063 }
1064 if let Some(us) = self.user_settings.get(resource_arn) {
1065 return Ok(&us.tags);
1066 }
1067 if let Some(ias) = self.ip_access_settings.get(resource_arn) {
1068 return Ok(&ias.tags);
1069 }
1070 if let Some(ts) = self.trust_stores.get(resource_arn) {
1071 return Ok(&ts.tags);
1072 }
1073 if let Some(dps) = self.data_protection_settings.get(resource_arn) {
1074 return Ok(&dps.tags);
1075 }
1076 if let Some(sl) = self.session_loggers.get(resource_arn) {
1077 return Ok(&sl.tags);
1078 }
1079 Err(WorkspacesWebError::ResourceNotFound(
1080 resource_arn.to_string(),
1081 ))
1082 }
1083
1084 pub fn tag_resource(
1085 &mut self,
1086 resource_arn: &str,
1087 tags: HashMap<String, String>,
1088 ) -> Result<(), WorkspacesWebError> {
1089 let tag_map = self.get_tags_mut(resource_arn)?;
1090 for (k, v) in tags {
1091 tag_map.insert(k, v);
1092 }
1093 Ok(())
1094 }
1095
1096 pub fn untag_resource(
1097 &mut self,
1098 resource_arn: &str,
1099 tag_keys: &[String],
1100 ) -> Result<(), WorkspacesWebError> {
1101 let tag_map = self.get_tags_mut(resource_arn)?;
1102 for key in tag_keys {
1103 tag_map.remove(key);
1104 }
1105 Ok(())
1106 }
1107
1108 fn get_tags_mut(
1109 &mut self,
1110 resource_arn: &str,
1111 ) -> Result<&mut HashMap<String, String>, WorkspacesWebError> {
1112 if self.portals.contains_key(resource_arn) {
1113 return Ok(&mut self.portals.get_mut(resource_arn).unwrap().tags);
1114 }
1115 if self.browser_settings.contains_key(resource_arn) {
1116 return Ok(&mut self.browser_settings.get_mut(resource_arn).unwrap().tags);
1117 }
1118 if self.network_settings.contains_key(resource_arn) {
1119 return Ok(&mut self.network_settings.get_mut(resource_arn).unwrap().tags);
1120 }
1121 if self.user_access_logging_settings.contains_key(resource_arn) {
1122 return Ok(&mut self
1123 .user_access_logging_settings
1124 .get_mut(resource_arn)
1125 .unwrap()
1126 .tags);
1127 }
1128 if self.user_settings.contains_key(resource_arn) {
1129 return Ok(&mut self.user_settings.get_mut(resource_arn).unwrap().tags);
1130 }
1131 if self.ip_access_settings.contains_key(resource_arn) {
1132 return Ok(&mut self.ip_access_settings.get_mut(resource_arn).unwrap().tags);
1133 }
1134 if self.trust_stores.contains_key(resource_arn) {
1135 return Ok(&mut self.trust_stores.get_mut(resource_arn).unwrap().tags);
1136 }
1137 if self.data_protection_settings.contains_key(resource_arn) {
1138 return Ok(&mut self
1139 .data_protection_settings
1140 .get_mut(resource_arn)
1141 .unwrap()
1142 .tags);
1143 }
1144 if self.session_loggers.contains_key(resource_arn) {
1145 return Ok(&mut self.session_loggers.get_mut(resource_arn).unwrap().tags);
1146 }
1147 Err(WorkspacesWebError::ResourceNotFound(
1148 resource_arn.to_string(),
1149 ))
1150 }
1151}