Skip to main content

Mountain/Track/Effect/CreateEffectForRequest/
Secrets.rs

1#![allow(non_snake_case, unused_variables, dead_code, unused_imports)]
2
3use std::{future::Future, pin::Pin, sync::Arc};
4
5use CommonLibrary::{Environment::Requires::Requires, Secret::SecretProvider::SecretProvider};
6use serde_json::{Value, json};
7use tauri::Runtime;
8
9use crate::{RunTime::ApplicationRunTime::ApplicationRunTime, Track::Effect::MappedEffectType::MappedEffect};
10
11/// Helper: Accept either positional `[key, value?]` or an object
12/// `{ key, extension_id?, extensionId? }`, returning `(Key,
13/// ExtensionIdentifier)`.
14fn ExtractSecretKey(Parameters:&Value) -> (String, String) {
15	if let Some(Object) = Parameters.as_object() {
16		let Key = Object.get("key").and_then(Value::as_str).unwrap_or("").to_string();
17		let ExtensionId = Object
18			.get("extension_id")
19			.or_else(|| Object.get("extensionId"))
20			.and_then(Value::as_str)
21			.unwrap_or("unknown")
22			.to_string();
23		(Key, ExtensionId)
24	} else {
25		let Key = Parameters.get(0).and_then(Value::as_str).unwrap_or("").to_string();
26		let ExtensionId = Parameters.get(2).and_then(Value::as_str).unwrap_or("unknown").to_string();
27		(Key, ExtensionId)
28	}
29}
30
31pub fn CreateEffect<R:Runtime>(MethodName:&str, Parameters:Value) -> Option<Result<MappedEffect, String>> {
32	match MethodName {
33		"secrets.get" => {
34			let effect =
35				move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
36					Box::pin(async move {
37						let provider:Arc<dyn SecretProvider> = run_time.Environment.Require();
38						let (Key, ExtensionId) = ExtractSecretKey(&Parameters);
39						match provider.GetSecret(ExtensionId, Key).await {
40							Ok(Some(Value)) => Ok(json!(Value)),
41							Ok(None) => Ok(Value::Null),
42							Err(Error) => Err(Error.to_string()),
43						}
44					})
45				};
46			Some(Ok(Box::new(effect)))
47		},
48
49		"secrets.store" => {
50			let effect =
51				move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
52					Box::pin(async move {
53						let provider:Arc<dyn SecretProvider> = run_time.Environment.Require();
54						let (Key, ExtensionId) = ExtractSecretKey(&Parameters);
55						let SecretValue = if let Some(Object) = Parameters.as_object() {
56							Object.get("value").and_then(Value::as_str).unwrap_or("").to_string()
57						} else {
58							Parameters.get(1).and_then(Value::as_str).unwrap_or("").to_string()
59						};
60						provider
61							.StoreSecret(ExtensionId, Key, SecretValue)
62							.await
63							.map(|_| json!(null))
64							.map_err(|e| e.to_string())
65					})
66				};
67			Some(Ok(Box::new(effect)))
68		},
69
70		"secrets.delete" => {
71			let effect =
72				move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
73					Box::pin(async move {
74						let provider:Arc<dyn SecretProvider> = run_time.Environment.Require();
75						let (Key, ExtensionId) = ExtractSecretKey(&Parameters);
76						provider
77							.DeleteSecret(ExtensionId, Key)
78							.await
79							.map(|_| json!(null))
80							.map_err(|e| e.to_string())
81					})
82				};
83			Some(Ok(Box::new(effect)))
84		},
85
86		_ => None,
87	}
88}