mongodb_atlas_cli/secrets/
mod.rs1use crate::{
2 config::AuthType,
3 path::{GetCLICfgFilePathError, config_file},
4 secrets::{keyring::KeyringSecretStore, legacy::LegacySecretStore},
5};
6
7pub mod encoding;
8pub mod keyring;
9pub mod legacy;
10
11#[derive(thiserror::Error, Debug)]
12pub enum SecretStoreError {
13 #[error("Failed to get config file path: {0}")]
14 FailedToGetConfigFilePath(#[from] GetCLICfgFilePathError),
15 #[error("Key store unavailable: {reason}")]
16 KeyStoreUnavailable { reason: String },
17 #[error("Invalid key store format: {reason}")]
18 InvalidKeyStoreFormat { reason: String },
19 #[error("Failed to serialize key store: {reason}")]
20 Serialization { reason: String },
21}
22
23pub trait SecretStore {
24 fn get(
25 &self,
26 profile_name: &str,
27 auth_type: AuthType,
28 ) -> Result<Option<Secret>, SecretStoreError>;
29 fn set(&mut self, profile_name: &str, secret: Secret) -> Result<(), SecretStoreError>;
30 fn delete(&mut self, profile_name: &str) -> Result<(), SecretStoreError>;
31}
32
33pub fn get_secret_store() -> Result<Box<dyn SecretStore>, SecretStoreError> {
34 match KeyringSecretStore::new() {
35 Some(keyring_secret_store) => Ok(Box::new(keyring_secret_store) as Box<dyn SecretStore>),
36 None => Ok(Box::new(LegacySecretStore::new(config_file()?))),
37 }
38}
39
40#[derive(Debug, Clone, PartialEq, Eq)]
41pub enum Secret {
42 ApiKeys(ApiKeys),
43 ServiceAccount(ServiceAccount),
44 UserAccount(UserAccount),
45}
46
47#[derive(Debug, Clone, PartialEq, Eq)]
48pub struct ApiKeys {
49 pub private_api_key: String,
50 pub public_api_key: String,
51}
52
53impl ApiKeys {
54 pub fn new(public_api_key: String, private_api_key: String) -> Self {
55 Self {
56 public_api_key,
57 private_api_key,
58 }
59 }
60}
61
62impl From<ApiKeys> for Secret {
63 fn from(api_keys: ApiKeys) -> Self {
64 Secret::ApiKeys(api_keys)
65 }
66}
67
68#[derive(Debug, Clone, PartialEq, Eq)]
69pub struct ServiceAccount {
70 pub client_id: String,
71 pub client_secret: String,
72}
73
74impl ServiceAccount {
75 pub fn new(client_id: String, client_secret: String) -> Self {
76 Self {
77 client_id,
78 client_secret,
79 }
80 }
81}
82
83impl From<ServiceAccount> for Secret {
84 fn from(service_account: ServiceAccount) -> Self {
85 Secret::ServiceAccount(service_account)
86 }
87}
88
89#[derive(Debug, Clone, PartialEq, Eq)]
90pub struct UserAccount {
91 pub access_token: String,
92 pub refresh_token: String,
93}
94
95impl UserAccount {
96 pub fn new(access_token: String, refresh_token: String) -> Self {
97 Self {
98 access_token,
99 refresh_token,
100 }
101 }
102}
103
104impl From<UserAccount> for Secret {
105 fn from(user_account: UserAccount) -> Self {
106 Secret::UserAccount(user_account)
107 }
108}