remoteit_api/credentials.rs
1//! This module is related to loading remote.it credentials from the user's home directory.
2//! This is of course not the most secure way to store credentials, but it is the most convenient and recommended by remote.it.
3//! If you store your credentials in a different way, you can pass them to the functions in this module directly instead of using this module to load them.
4
5use base64::prelude::BASE64_STANDARD;
6use base64::Engine;
7use bon::bon;
8
9/// Credentials for the remote.it API.
10/// Remote.it credentials consist of an access key ID and a base64 encoded secret access key.
11///
12/// # Example
13/// You can directly create a new [`Credentials`] struct using the builder pattern:
14/// ```
15/// # use remoteit_api::Credentials;
16/// let credentials = Credentials::builder()
17/// .r3_access_key_id("foo")
18/// .r3_secret_access_key("YmFy")
19/// .build();
20/// ```
21/// If you enable the `credentials_loader` feature, you can also load the credentials from the default, or a custom file:
22/// ```
23/// # use remoteit_api::Credentials;
24/// let creds_from_default_loc = Credentials::load_from_disk().call().unwrap();
25/// let creds_from_custom_loc = Credentials::load_from_disk().custom_credentials_path(".env.remoteit").call().unwrap();
26/// ```
27#[derive(
28 Debug, Clone, PartialOrd, PartialEq, Eq, Ord, Hash, serde::Deserialize, serde::Serialize,
29)]
30pub struct Credentials {
31 pub(crate) r3_access_key_id: String,
32 pub(crate) r3_secret_access_key: String,
33 #[serde(skip)] // Don't want to serialize this one
34 pub(crate) key: Vec<u8>,
35}
36
37#[bon]
38impl Credentials {
39 /// Validated the given secret access key and creates a new [`Credentials`] struct.
40 ///
41 /// # Errors
42 /// - [`base64::DecodeError`] if the secret access key is not base64 encoded.
43 ///
44 /// # Example
45 /// ```
46 /// # use remoteit_api::Credentials;
47 /// let credentials = Credentials::builder()
48 /// .r3_access_key_id("foo")
49 /// .r3_secret_access_key("YmFy")
50 /// .build();
51 /// ```
52 #[builder]
53 pub fn new(
54 r3_access_key_id: String,
55 r3_secret_access_key: String,
56 ) -> Result<Self, base64::DecodeError> {
57 let key = BASE64_STANDARD.decode(&r3_secret_access_key)?;
58 Ok(Self {
59 r3_access_key_id,
60 r3_secret_access_key,
61 key,
62 })
63 }
64
65 /// # Returns
66 /// The base64 decoded secret access key.
67 #[must_use]
68 pub fn key(&self) -> &[u8] {
69 &self.key
70 }
71
72 /// # Returns
73 /// A reference to the r3_access_key_id
74 pub fn access_key_id(&self) -> &str {
75 &self.r3_access_key_id
76 }
77
78 /// # Returns
79 /// The base64 encoded r3_secret_access_key
80 pub fn secret_access_key(&self) -> &str {
81 &self.r3_secret_access_key
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88
89 #[test]
90 fn test_credentials_builder() {
91 let credentials = Credentials::builder()
92 .r3_access_key_id("foo")
93 .r3_secret_access_key("YmFy")
94 .build()
95 .unwrap();
96
97 assert_eq!(credentials.r3_access_key_id, "foo");
98 assert_eq!(credentials.r3_secret_access_key, "YmFy");
99 }
100}