Skip to main content

oci_rust_sdk/auth/
simple.rs

1use crate::auth::provider::AuthProvider;
2use crate::core::region::Region;
3
4/// Required fields for SimpleAuthProvider
5pub struct SimpleAuthProviderRequiredFields {
6    /// Tenancy OCID
7    pub tenancy: String,
8    /// User OCID
9    pub user: String,
10    /// Public key fingerprint
11    pub fingerprint: String,
12    /// Private key in PEM format
13    pub private_key: String,
14}
15
16/// Simple authentication provider that holds credentials directly in memory
17///
18/// This is the Rust equivalent of TypeScript SDK's SimpleAuthenticationDetailsProvider.
19/// It provides a straightforward way to create an authentication provider with
20/// credentials provided directly, without reading from configuration files.
21///
22/// # Example
23///
24/// ```
25/// use oci_rust_sdk::auth::{SimpleAuthProvider, SimpleAuthProviderRequiredFields};
26/// use oci_rust_sdk::core::Region;
27///
28/// let required = SimpleAuthProviderRequiredFields {
29///     tenancy: "ocid1.tenancy.oc1..aaa...".to_string(),
30///     user: "ocid1.user.oc1..aaa...".to_string(),
31///     fingerprint: "aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99".to_string(),
32///     private_key: "-----BEGIN RSA PRIVATE KEY-----\n...".to_string(),
33/// };
34///
35/// let provider = SimpleAuthProvider::builder(required)
36///     .region(Region::ApSeoul1)
37///     .build();
38/// ```
39#[derive(Debug, Clone)]
40pub struct SimpleAuthProvider {
41    tenancy: String,
42    user: String,
43    fingerprint: String,
44    private_key: String,
45    passphrase: Option<String>,
46    region: Option<Region>,
47    auth_type: Option<String>,
48    delegation_token: Option<String>,
49    session_token: Option<String>,
50}
51
52impl SimpleAuthProvider {
53    /// Create a new SimpleAuthProvider with required fields
54    ///
55    /// # Arguments
56    ///
57    /// * `tenancy` - Tenancy OCID
58    /// * `user` - User OCID
59    /// * `fingerprint` - Public key fingerprint
60    /// * `private_key` - Private key in PEM format
61    pub fn new(
62        tenancy: impl Into<String>,
63        user: impl Into<String>,
64        fingerprint: impl Into<String>,
65        private_key: impl Into<String>,
66    ) -> Self {
67        Self {
68            tenancy: tenancy.into(),
69            user: user.into(),
70            fingerprint: fingerprint.into(),
71            private_key: private_key.into(),
72            passphrase: None,
73            region: None,
74            auth_type: None,
75            delegation_token: None,
76            session_token: None,
77        }
78    }
79
80    /// Create a builder for constructing a SimpleAuthProvider
81    pub fn builder(required: SimpleAuthProviderRequiredFields) -> SimpleAuthProviderBuilder {
82        SimpleAuthProviderBuilder {
83            tenancy: required.tenancy,
84            user: required.user,
85            fingerprint: required.fingerprint,
86            private_key: required.private_key,
87            passphrase: None,
88            region: None,
89            auth_type: None,
90            delegation_token: None,
91            session_token: None,
92        }
93    }
94
95    /// Get the tenancy OCID
96    pub fn tenancy(&self) -> &str {
97        &self.tenancy
98    }
99
100    /// Get the user OCID
101    pub fn user(&self) -> &str {
102        &self.user
103    }
104
105    /// Get the fingerprint
106    pub fn fingerprint(&self) -> &str {
107        &self.fingerprint
108    }
109
110    /// Get the region (if set)
111    pub fn region(&self) -> Option<Region> {
112        self.region
113    }
114
115    /// Set the region
116    pub fn set_region(&mut self, region: Region) {
117        self.region = Some(region);
118    }
119
120    /// Set the region (builder style)
121    pub fn with_region(mut self, region: Region) -> Self {
122        self.region = Some(region);
123        self
124    }
125
126    /// Get the authentication type
127    pub fn auth_type(&self) -> Option<&str> {
128        self.auth_type.as_deref()
129    }
130
131    /// Set the authentication type
132    pub fn set_auth_type(&mut self, auth_type: impl Into<String>) {
133        self.auth_type = Some(auth_type.into());
134    }
135
136    /// Set the authentication type (builder style)
137    pub fn with_auth_type(mut self, auth_type: impl Into<String>) -> Self {
138        self.auth_type = Some(auth_type.into());
139        self
140    }
141
142    /// Get the delegation token
143    pub fn delegation_token(&self) -> Option<&str> {
144        self.delegation_token.as_deref()
145    }
146
147    /// Set the delegation token
148    pub fn set_delegation_token(&mut self, token: impl Into<String>) {
149        self.delegation_token = Some(token.into());
150    }
151
152    /// Set the delegation token (builder style)
153    pub fn with_delegation_token(mut self, token: impl Into<String>) -> Self {
154        self.delegation_token = Some(token.into());
155        self
156    }
157
158    /// Get the session token
159    pub fn session_token(&self) -> Option<&str> {
160        self.session_token.as_deref()
161    }
162
163    /// Set the session token
164    pub fn set_session_token(&mut self, token: impl Into<String>) {
165        self.session_token = Some(token.into());
166    }
167
168    /// Set the session token (builder style)
169    pub fn with_session_token(mut self, token: impl Into<String>) -> Self {
170        self.session_token = Some(token.into());
171        self
172    }
173}
174
175impl AuthProvider for SimpleAuthProvider {
176    fn get_key_id(&self) -> String {
177        format!("{}/{}/{}", self.tenancy, self.user, self.fingerprint)
178    }
179
180    fn get_private_key(&self) -> &str {
181        &self.private_key
182    }
183
184    fn get_passphrase(&self) -> Option<&str> {
185        self.passphrase.as_deref()
186    }
187}
188
189/// Builder for SimpleAuthProvider
190///
191/// Provides a convenient way to construct a SimpleAuthProvider with optional fields.
192#[derive(Debug)]
193pub struct SimpleAuthProviderBuilder {
194    tenancy: String,
195    user: String,
196    fingerprint: String,
197    private_key: String,
198    passphrase: Option<String>,
199    region: Option<Region>,
200    auth_type: Option<String>,
201    delegation_token: Option<String>,
202    session_token: Option<String>,
203}
204
205impl SimpleAuthProviderBuilder {
206    /// Set the passphrase for the private key
207    pub fn passphrase(mut self, passphrase: impl Into<String>) -> Self {
208        self.passphrase = Some(passphrase.into());
209        self
210    }
211
212    /// Set the region
213    pub fn region(mut self, region: Region) -> Self {
214        self.region = Some(region);
215        self
216    }
217
218    /// Set the authentication type
219    pub fn auth_type(mut self, auth_type: impl Into<String>) -> Self {
220        self.auth_type = Some(auth_type.into());
221        self
222    }
223
224    /// Set the delegation token
225    pub fn delegation_token(mut self, token: impl Into<String>) -> Self {
226        self.delegation_token = Some(token.into());
227        self
228    }
229
230    /// Set the session token
231    pub fn session_token(mut self, token: impl Into<String>) -> Self {
232        self.session_token = Some(token.into());
233        self
234    }
235
236    /// Build the SimpleAuthProvider
237    pub fn build(self) -> SimpleAuthProvider {
238        SimpleAuthProvider {
239            tenancy: self.tenancy,
240            user: self.user,
241            fingerprint: self.fingerprint,
242            private_key: self.private_key,
243            passphrase: self.passphrase,
244            region: self.region,
245            auth_type: self.auth_type,
246            delegation_token: self.delegation_token,
247            session_token: self.session_token,
248        }
249    }
250}
251
252#[cfg(test)]
253mod tests {
254    use super::*;
255
256    #[test]
257    fn test_simple_auth_provider_new() {
258        let provider = SimpleAuthProvider::new(
259            "ocid1.tenancy.oc1..aaa",
260            "ocid1.user.oc1..bbb",
261            "aa:bb:cc:dd:ee:ff",
262            "-----BEGIN RSA PRIVATE KEY-----\ntest\n-----END RSA PRIVATE KEY-----",
263        );
264
265        assert_eq!(provider.tenancy(), "ocid1.tenancy.oc1..aaa");
266        assert_eq!(provider.user(), "ocid1.user.oc1..bbb");
267        assert_eq!(provider.fingerprint(), "aa:bb:cc:dd:ee:ff");
268        assert_eq!(provider.region(), None);
269    }
270
271    #[test]
272    fn test_simple_auth_provider_builder() {
273        let required = SimpleAuthProviderRequiredFields {
274            tenancy: "ocid1.tenancy.oc1..aaa".to_string(),
275            user: "ocid1.user.oc1..bbb".to_string(),
276            fingerprint: "aa:bb:cc:dd:ee:ff".to_string(),
277            private_key: "-----BEGIN RSA PRIVATE KEY-----\ntest\n-----END RSA PRIVATE KEY-----"
278                .to_string(),
279        };
280
281        let provider = SimpleAuthProvider::builder(required)
282            .passphrase("mypassphrase")
283            .region(Region::ApSeoul1)
284            .auth_type("api_key")
285            .build();
286
287        assert_eq!(provider.tenancy(), "ocid1.tenancy.oc1..aaa");
288        assert_eq!(provider.user(), "ocid1.user.oc1..bbb");
289        assert_eq!(provider.fingerprint(), "aa:bb:cc:dd:ee:ff");
290        assert_eq!(provider.region(), Some(Region::ApSeoul1));
291        assert_eq!(provider.auth_type(), Some("api_key"));
292        assert_eq!(provider.get_passphrase(), Some("mypassphrase"));
293    }
294
295    #[test]
296    fn test_auth_provider_trait() {
297        let provider = SimpleAuthProvider::new(
298            "ocid1.tenancy.oc1..aaa",
299            "ocid1.user.oc1..bbb",
300            "aa:bb:cc:dd:ee:ff",
301            "-----BEGIN RSA PRIVATE KEY-----\ntest\n-----END RSA PRIVATE KEY-----",
302        );
303
304        assert_eq!(
305            provider.get_key_id(),
306            "ocid1.tenancy.oc1..aaa/ocid1.user.oc1..bbb/aa:bb:cc:dd:ee:ff"
307        );
308        assert!(provider.get_private_key().contains("BEGIN RSA PRIVATE KEY"));
309        assert_eq!(provider.get_passphrase(), None);
310    }
311
312    #[test]
313    fn test_region_management() {
314        let mut provider = SimpleAuthProvider::new(
315            "ocid1.tenancy.oc1..aaa",
316            "ocid1.user.oc1..bbb",
317            "aa:bb:cc:dd:ee:ff",
318            "key",
319        );
320
321        assert_eq!(provider.region(), None);
322
323        provider.set_region(Region::ApSeoul1);
324        assert_eq!(provider.region(), Some(Region::ApSeoul1));
325
326        let provider = provider.with_region(Region::UsPhoenix1);
327        assert_eq!(provider.region(), Some(Region::UsPhoenix1));
328    }
329
330    #[test]
331    fn test_token_management() {
332        let required = SimpleAuthProviderRequiredFields {
333            tenancy: "t".to_string(),
334            user: "u".to_string(),
335            fingerprint: "f".to_string(),
336            private_key: "k".to_string(),
337        };
338
339        let provider = SimpleAuthProvider::builder(required)
340            .delegation_token("delegation123")
341            .session_token("session456")
342            .build();
343
344        assert_eq!(provider.delegation_token(), Some("delegation123"));
345        assert_eq!(provider.session_token(), Some("session456"));
346    }
347}