use std::fmt::Debug;
use std::ptr::NonNull;
use mountpoint_s3_crt_sys::{
aws_credentials_provider, aws_credentials_provider_acquire, aws_credentials_provider_chain_default_options,
aws_credentials_provider_new_chain_default, aws_credentials_provider_new_profile,
aws_credentials_provider_new_static, aws_credentials_provider_profile_options, aws_credentials_provider_release,
aws_credentials_provider_static_options,
};
use crate::auth::auth_library_init;
use crate::common::allocator::Allocator;
use crate::common::error::Error;
use crate::io::channel_bootstrap::ClientBootstrap;
use crate::{CrtError as _, ToAwsByteCursor as _};
#[derive(Debug)]
pub struct CredentialsProviderChainDefaultOptions<'a> {
pub bootstrap: &'a mut ClientBootstrap,
}
#[derive(Debug)]
pub struct CredentialsProviderProfileOptions<'a> {
pub bootstrap: &'a mut ClientBootstrap,
pub profile_name_override: &'a str,
}
pub struct CredentialsProviderStaticOptions<'a> {
pub access_key_id: &'a str,
pub secret_access_key: &'a str,
pub session_token: Option<&'a str>,
}
impl Debug for CredentialsProviderStaticOptions<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("CredentialsProviderStaticOptions")
.field("access_key_id", &"** redacted **")
.field("secret_access_key", &"** redacted **")
.field("session_token", &self.session_token.map(|_| "** redacted **"))
.finish()
}
}
#[derive(Debug)]
pub struct CredentialsProvider {
pub(crate) inner: NonNull<aws_credentials_provider>,
}
impl CredentialsProvider {
pub fn new_chain_default(
allocator: &Allocator,
options: CredentialsProviderChainDefaultOptions,
) -> Result<Self, Error> {
auth_library_init(allocator);
let inner_options = aws_credentials_provider_chain_default_options {
bootstrap: options.bootstrap.inner.as_ptr(),
..Default::default()
};
let inner = unsafe {
aws_credentials_provider_new_chain_default(allocator.inner.as_ptr(), &inner_options).ok_or_last_error()?
};
Ok(Self { inner })
}
pub fn new_profile(allocator: &Allocator, options: CredentialsProviderProfileOptions) -> Result<Self, Error> {
auth_library_init(allocator);
let inner = unsafe {
let inner_options = aws_credentials_provider_profile_options {
bootstrap: options.bootstrap.inner.as_ptr(),
profile_name_override: options.profile_name_override.as_aws_byte_cursor(),
..Default::default()
};
aws_credentials_provider_new_profile(allocator.inner.as_ptr(), &inner_options).ok_or_last_error()?
};
Ok(Self { inner })
}
pub fn new_static(allocator: &Allocator, options: CredentialsProviderStaticOptions) -> Result<Self, Error> {
auth_library_init(allocator);
let inner = unsafe {
let inner_options = aws_credentials_provider_static_options {
access_key_id: options.access_key_id.as_aws_byte_cursor(),
secret_access_key: options.secret_access_key.as_aws_byte_cursor(),
session_token: options
.session_token
.map(|t| t.as_aws_byte_cursor())
.unwrap_or_default(),
..Default::default()
};
aws_credentials_provider_new_static(allocator.inner.as_ptr(), &inner_options).ok_or_last_error()?
};
Ok(Self { inner })
}
}
impl Clone for CredentialsProvider {
fn clone(&self) -> Self {
unsafe {
aws_credentials_provider_acquire(self.inner.as_ptr());
}
Self { inner: self.inner }
}
}
impl Drop for CredentialsProvider {
fn drop(&mut self) {
unsafe {
aws_credentials_provider_release(self.inner.as_ptr());
}
}
}