deribit_http/config/credentials.rs
1use crate::HttpError;
2use pretty_simple_display::{DebugPretty, DisplaySimple};
3use serde::{Deserialize, Serialize};
4use std::env;
5use tracing::warn;
6
7/// API credentials for authentication
8#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize)]
9pub struct ApiCredentials {
10 /// Client ID for OAuth2
11 pub client_id: Option<String>,
12 /// Client secret for OAuth2
13 pub client_secret: Option<String>,
14}
15
16impl ApiCredentials {
17 /// Validates whether the required fields `client_id` and `client_secret` are present.
18 ///
19 /// # Returns
20 ///
21 /// * `true` - If both `client_id` and `client_secret` are `Some` (i.e., not `None`).
22 /// * `false` - If either `client_id` or `client_secret` is `None`.
23 ///
24 pub fn is_valid(&self) -> bool {
25 self.client_id.is_some() && self.client_secret.is_some()
26 }
27
28 /// Creates a new instance of the struct with credentials initialized from environment variables.
29 ///
30 /// # Returns
31 /// - `Ok(Self)`: If the credentials are properly configured and valid.
32 /// - `Err(HttpError::ConfigError)`: If the credentials are not properly set or invalid, with an appropriate
33 /// error message indicating the configuration issue.
34 ///
35 /// # Note
36 /// - If the credentials are invalid or not set, a warning will be logged, and only public API endpoints
37 /// will be accessible.
38 ///
39 pub fn new() -> Result<Self, HttpError> {
40 let creds = Self::default();
41 if creds.is_valid() {
42 Ok(creds)
43 } else {
44 warn!(
45 "API credentials are provided in environment variables, only public endpoints will be available."
46 );
47 Err(HttpError::ConfigError(
48 "API credentials are not properly set in environment variables".into(),
49 ))
50 }
51 }
52
53 /// Retrieves the client credentials (Client ID and Client Secret) required for OAuth2 authentication.
54 ///
55 /// # Returns
56 /// - `Ok((String, String))`: A tuple containing the `client_id` and `client_secret` if they are both set.
57 /// - `Err(HttpError)`: An error of type `HttpError::ConfigError` if either `client_id` or `client_secret` is not set.
58 ///
59 /// # Errors
60 /// Returns an `HttpError::ConfigError` with a message indicating that both `Client ID`
61 /// and `Client Secret` must be set for OAuth2 authentication when either or both are absent.
62 ///
63 /// # Note
64 /// This function assumes that `client_id` and `client_secret` are optional fields.
65 /// Ensure they are properly configured before invoking this function.
66 pub fn get_client_credentials(&self) -> Result<(String, String), HttpError> {
67 if self.client_id.is_some() && self.client_secret.is_some() {
68 Ok((
69 self.client_id.clone().unwrap(),
70 self.client_secret.clone().unwrap(),
71 ))
72 } else {
73 Err(HttpError::ConfigError(
74 "Client ID and Client Secret must be set for OAuth2 authentication".into(),
75 ))
76 }
77 }
78}
79
80impl Default for ApiCredentials {
81 fn default() -> Self {
82 dotenv::dotenv().ok();
83 let client_id = env::var("DERIBIT_CLIENT_ID").ok();
84 let client_secret = env::var("DERIBIT_CLIENT_SECRET").ok();
85 Self {
86 client_id,
87 client_secret,
88 }
89 }
90}