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
18		let ExtensionId = Object
19			.get("extension_id")
20			.or_else(|| Object.get("extensionId"))
21			.and_then(Value::as_str)
22			.unwrap_or("unknown")
23			.to_string();
24
25		(Key, ExtensionId)
26	} else {
27		let Key = Parameters.get(0).and_then(Value::as_str).unwrap_or("").to_string();
28
29		let ExtensionId = Parameters.get(2).and_then(Value::as_str).unwrap_or("unknown").to_string();
30
31		(Key, ExtensionId)
32	}
33}
34
35pub fn CreateEffect<R:Runtime>(MethodName:&str, Parameters:Value) -> Option<Result<MappedEffect, String>> {
36	match MethodName {
37		"secrets.get" => {
38			let effect =
39				move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
40					Box::pin(async move {
41						let provider:Arc<dyn SecretProvider> = run_time.Environment.Require();
42						let (Key, ExtensionId) = ExtractSecretKey(&Parameters);
43						match provider.GetSecret(ExtensionId, Key).await {
44							Ok(Some(Value)) => Ok(json!(Value)),
45							Ok(None) => Ok(Value::Null),
46							Err(Error) => Err(Error.to_string()),
47						}
48					})
49				};
50
51			Some(Ok(Box::new(effect)))
52		},
53
54		"secrets.store" => {
55			let effect =
56				move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
57					Box::pin(async move {
58						let provider:Arc<dyn SecretProvider> = run_time.Environment.Require();
59						let (Key, ExtensionId) = ExtractSecretKey(&Parameters);
60						let SecretValue = if let Some(Object) = Parameters.as_object() {
61							Object.get("value").and_then(Value::as_str).unwrap_or("").to_string()
62						} else {
63							Parameters.get(1).and_then(Value::as_str).unwrap_or("").to_string()
64						};
65						provider
66							.StoreSecret(ExtensionId, Key, SecretValue)
67							.await
68							.map(|_| json!(null))
69							.map_err(|e| e.to_string())
70					})
71				};
72
73			Some(Ok(Box::new(effect)))
74		},
75
76		"secrets.delete" => {
77			let effect =
78				move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
79					Box::pin(async move {
80						let provider:Arc<dyn SecretProvider> = run_time.Environment.Require();
81						let (Key, ExtensionId) = ExtractSecretKey(&Parameters);
82						provider
83							.DeleteSecret(ExtensionId, Key)
84							.await
85							.map(|_| json!(null))
86							.map_err(|e| e.to_string())
87					})
88				};
89
90			Some(Ok(Box::new(effect)))
91		},
92
93		_ => None,
94	}
95}