wildland_http_client/sc/
client.rs1use std::rc::Rc;
19
20use serde::Serialize;
21use wildland_crypto::identity::signing_keypair::SigningKeypair;
22
23use super::constants::WILDLAND_SIGNATURE_HEADER;
24use super::models::{
25 CreateCredentialsReq,
26 CreateCredentialsRes,
27 CreateStorageRes,
28 RequestMetricsReq,
29 RequestMetricsRes,
30 SignatureRequestReq,
31 SignatureRequestRes,
32};
33use crate::cross_platform_http_client::{CurrentPlatformClient, HttpClient, Request};
34use crate::error::WildlandHttpClientError;
35use crate::response_handler::check_status_code;
36
37#[derive(Debug)]
38pub struct Credentials {
39 pub id: String,
40 pub secret: String,
41}
42
43#[derive(Clone)]
44pub struct StorageControllerClient {
45 pub credential_id: String,
47 pub credential_secret: String,
48 http_client: Rc<dyn HttpClient>,
49}
50
51impl StorageControllerClient {
52 #[tracing::instrument(level = "debug", skip_all)]
53 pub fn new(base_url: &str) -> Self {
54 let http_client = Rc::new(CurrentPlatformClient {
55 base_url: base_url.into(),
56 });
57
58 Self {
59 credential_id: String::default(),
60 credential_secret: String::default(),
61 http_client,
62 }
63 }
64
65 #[tracing::instrument(level = "debug", skip_all)]
66 pub fn create_storage(&self) -> Result<CreateStorageRes, WildlandHttpClientError> {
67 let request = Request::new("/storage/create");
68 let response = self.http_client.post(request)?;
69 let response = check_status_code(response)?;
70 Ok(response.deserialize()?)
71 }
72
73 #[tracing::instrument(level = "debug", skip_all)]
74 pub fn create_credentials(
75 &self,
76 request: CreateCredentialsReq,
77 ) -> Result<CreateCredentialsRes, WildlandHttpClientError> {
78 let signature = self.sign_request(&request)?;
79 let http_request = Request::new("/credential/create")
80 .with_json(&request)
81 .with_header(WILDLAND_SIGNATURE_HEADER, signature);
82 let response = self.http_client.post(http_request)?;
83 let response = check_status_code(response)?;
84 Ok(response.deserialize()?)
85 }
86
87 #[tracing::instrument(level = "debug", skip_all)]
88 pub fn request_signature(
89 &self,
90 request: SignatureRequestReq,
91 ) -> Result<SignatureRequestRes, WildlandHttpClientError> {
92 let signature = self.sign_request(&request)?;
93 let http_request = Request::new("/signature/request")
94 .with_json(&request)
95 .with_header(WILDLAND_SIGNATURE_HEADER, signature);
96 let response = self.http_client.post(http_request)?;
97 let response = check_status_code(response)?;
98 Ok(response.deserialize()?)
99 }
100
101 #[tracing::instrument(level = "debug", skip_all)]
102 pub fn request_metrics(
103 &self,
104 request: RequestMetricsReq,
105 ) -> Result<RequestMetricsRes, WildlandHttpClientError> {
106 let signature = self.sign_request(&request)?;
107 let http_request = Request::new("/metrics")
108 .with_json(&request)
109 .with_header(WILDLAND_SIGNATURE_HEADER, signature);
110 let response = self.http_client.post(http_request)?;
111 let response = check_status_code(response)?;
112 Ok(response.deserialize()?)
113 }
114
115 #[tracing::instrument(level = "debug", skip_all)]
116 pub fn get_credential_id(&self) -> &str {
117 &self.credential_id
118 }
119
120 #[tracing::instrument(level = "debug", skip_all)]
121 pub fn get_credential_secret(&self) -> &str {
122 &self.credential_secret
123 }
124
125 #[tracing::instrument(level = "debug", skip_all)]
126 fn sign_request<T>(&self, request: &T) -> Result<String, WildlandHttpClientError>
127 where
128 T: Serialize,
129 {
130 let message = serde_json::to_vec(request).map_err(Rc::new)?;
131 let keypair =
132 SigningKeypair::try_from_str(self.get_credential_id(), self.get_credential_secret())?;
133 let signature = keypair.sign(&message);
134 Ok(signature.encode_signature())
135 }
136}