Skip to main content

cookie_agent_protocol/session/client/
runtime.rs

1//! Protocol-10 coherent runtime and provider mutation RPCs.
2
3use crate::{
4    ProviderConnectParams, ProviderConnectResult, ProviderDisconnectParams,
5    ProviderDisconnectResult, RuntimeSnapshotGetParams, RuntimeSnapshotResult,
6};
7use serde_json::Value;
8
9use super::{
10    Client, ClientError, SensitiveJson, record_provider_connect_wipe, send_sensitive_command,
11};
12
13struct ProviderConnectGuard(ProviderConnectParams);
14
15impl Drop for ProviderConnectGuard {
16    fn drop(&mut self) {
17        record_provider_connect_wipe();
18    }
19}
20
21impl Client {
22    pub async fn runtime_snapshot(&self) -> Result<RuntimeSnapshotResult, ClientError> {
23        self.call(
24            crate::RUNTIME_SNAPSHOT_GET_METHOD,
25            &RuntimeSnapshotGetParams {},
26        )
27        .await
28    }
29
30    pub fn connect_provider(
31        &self,
32        params: ProviderConnectParams,
33    ) -> impl std::future::Future<Output = Result<ProviderConnectResult, ClientError>> + '_ {
34        let params = ProviderConnectGuard(params);
35        async move {
36            let value = provider_connect_value(&params.0)?;
37            let result =
38                send_sensitive_command(&self.commands, crate::PROVIDER_CONNECT_METHOD, value)
39                    .await?;
40            Ok(serde_json::from_value(result)?)
41        }
42    }
43
44    pub async fn disconnect_provider(
45        &self,
46        params: ProviderDisconnectParams,
47    ) -> Result<ProviderDisconnectResult, ClientError> {
48        self.call(crate::PROVIDER_DISCONNECT_METHOD, &params).await
49    }
50}
51
52fn provider_connect_value(params: &ProviderConnectParams) -> Result<SensitiveJson, ClientError> {
53    let setup_values = serde_json::to_value(&params.setup_values)?;
54    let provider_id = serde_json::to_value(&params.provider_id)?;
55    let expected_catalog_revision = serde_json::to_value(&params.expected_catalog_revision)?;
56    let auth_method = serde_json::to_value(&params.auth_method)?;
57    let client_connect_id = serde_json::to_value(&params.client_connect_id)?;
58    let mut value = SensitiveJson::object();
59    let object = value.object_mut();
60    object.insert("provider_id".into(), provider_id);
61    object.insert(
62        "expected_catalog_revision".into(),
63        expected_catalog_revision,
64    );
65    object.insert("setup_values".into(), setup_values);
66    object.insert("auth_method".into(), auth_method);
67    object.insert("auth_values".into(), Value::Object(serde_json::Map::new()));
68    object.insert("client_connect_id".into(), client_connect_id);
69    let auth_values = object
70        .get_mut("auth_values")
71        .and_then(Value::as_object_mut)
72        .expect("auth values were initialized as an object");
73    for field in params.auth_values.field_names() {
74        let id = crate::AuthFieldName::new(field.to_owned())
75            .expect("protocol credential field names are validated");
76        if let Some(secret) = params.auth_values.get(&id) {
77            auth_values.insert(field.to_owned(), Value::String(secret.to_owned()));
78        }
79    }
80    Ok(value)
81}