use crate::codec::external_credential::{
from_wire_exchange_external_credential_response, from_wire_external_credential,
from_wire_list_external_credentials_response, from_wire_resolve_external_credential_response,
to_wire_delete_external_credential_request, to_wire_exchange_external_credential_request,
to_wire_get_external_credential_request, to_wire_list_external_credentials_request,
to_wire_resolve_external_credential_request, to_wire_upsert_external_credential_request,
to_wire_validate_external_credential_config_request,
};
use crate::codec::host_service::{HostServiceChannel, connect_host_service, plain_channel};
use crate::generated::v1;
use crate::rpc_support::GestaltError;
#[derive(Clone, Debug, Default, PartialEq)]
pub struct DeleteExternalCredentialRequest {
pub id: String,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ExchangeExternalCredentialRequest {
pub provider: String,
pub connection: String,
pub connection_id: String,
pub credential_subject_id: String,
pub actor_subject_id: String,
pub instance: String,
pub auth: Option<ExternalCredentialAuthConfig>,
pub credential_json: String,
pub connection_params: std::collections::BTreeMap<String, String>,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ExchangeExternalCredentialResponse {
pub token_response: Option<ExternalCredentialTokenResponse>,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ExternalCredential {
pub id: String,
pub subject_id: String,
pub instance: String,
pub access_token: String,
pub refresh_token: String,
pub scopes: String,
pub expires_at: Option<std::time::SystemTime>,
pub last_refreshed_at: Option<std::time::SystemTime>,
pub refresh_error_count: i32,
pub metadata_json: String,
pub created_at: Option<std::time::SystemTime>,
pub updated_at: Option<std::time::SystemTime>,
pub connection_id: String,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ExternalCredentialAuthConfig {
pub r#type: String,
pub token: String,
pub token_prefix: String,
pub grant_type: String,
pub token_url: String,
pub client_id: String,
pub client_secret: String,
pub client_auth: String,
pub token_exchange: String,
pub scopes: Vec<String>,
pub scope_param: String,
pub scope_separator: String,
pub token_params: std::collections::BTreeMap<String, String>,
pub refresh_params: std::collections::BTreeMap<String, String>,
pub accept_header: String,
pub access_token_path: String,
pub token_exchange_drivers: Vec<ExternalCredentialTokenExchangeDriver>,
pub refresh_token: String,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ExternalCredentialLookup {
pub subject_id: String,
pub instance: String,
pub connection_id: String,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ExternalCredentialTokenExchangeDriver {
pub r#type: String,
pub target_principal: String,
pub scopes: Vec<String>,
pub lifetime_seconds: i32,
pub endpoint: String,
pub params: std::collections::BTreeMap<String, String>,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ExternalCredentialTokenResponse {
pub access_token: String,
pub refresh_token: String,
pub expires_in: i32,
pub token_type: String,
pub extra_json: String,
pub refresh_source: String,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct GetExternalCredentialRequest {
pub lookup: Option<ExternalCredentialLookup>,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ListExternalCredentialsRequest {
pub subject_id: String,
pub instance: String,
pub connection_id: String,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ListExternalCredentialsResponse {
pub credentials: Vec<ExternalCredential>,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ResolveExternalCredentialRequest {
pub provider: String,
pub connection: String,
pub connection_id: String,
pub mode: String,
pub credential_subject_id: String,
pub actor_subject_id: String,
pub instance: String,
pub auth: Option<ExternalCredentialAuthConfig>,
pub connection_params: std::collections::BTreeMap<String, String>,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ResolveExternalCredentialResponse {
pub token: String,
pub expires_at: Option<std::time::SystemTime>,
pub metadata_json: String,
pub params: std::collections::BTreeMap<String, String>,
pub credential: Option<ExternalCredential>,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct UpsertExternalCredentialRequest {
pub credential: Option<ExternalCredential>,
pub preserve_timestamps: bool,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ValidateExternalCredentialConfigRequest {
pub provider: String,
pub connection: String,
pub connection_id: String,
pub mode: String,
pub auth: Option<ExternalCredentialAuthConfig>,
pub connection_params: std::collections::BTreeMap<String, String>,
}
pub struct ExternalCredentials {
inner: v1::external_credentials_client::ExternalCredentialsClient<HostServiceChannel>,
timeout: Option<std::time::Duration>,
}
impl ExternalCredentials {
pub fn new(channel: tonic::transport::Channel) -> Self {
Self {
inner: v1::external_credentials_client::ExternalCredentialsClient::new(plain_channel(
channel,
)),
timeout: None,
}
}
pub fn with_timeout(mut self, timeout: std::time::Duration) -> Self {
self.timeout = Some(timeout);
self
}
pub async fn connect() -> Result<Self, GestaltError> {
Self::connect_named("").await
}
pub async fn connect_named(name: &str) -> Result<Self, GestaltError> {
Ok(Self {
inner: v1::external_credentials_client::ExternalCredentialsClient::new(
connect_host_service("external_credentials", name).await?,
),
timeout: None,
})
}
pub async fn upsert_credential(
&mut self,
preserve_timestamps: bool,
credential: Option<ExternalCredential>,
) -> Result<ExternalCredential, GestaltError> {
let request = UpsertExternalCredentialRequest {
preserve_timestamps,
credential,
};
let mut tonic_request =
tonic::Request::new(to_wire_upsert_external_credential_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.upsert_credential(tonic_request).await?;
Ok(from_wire_external_credential(response.into_inner()))
}
pub async fn upsert_credential_raw(
&mut self,
request: UpsertExternalCredentialRequest,
) -> Result<ExternalCredential, GestaltError> {
let mut tonic_request =
tonic::Request::new(to_wire_upsert_external_credential_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.upsert_credential(tonic_request).await?;
Ok(from_wire_external_credential(response.into_inner()))
}
pub async fn get_credential(
&mut self,
lookup: Option<ExternalCredentialLookup>,
) -> Result<ExternalCredential, GestaltError> {
let request = GetExternalCredentialRequest { lookup };
let mut tonic_request =
tonic::Request::new(to_wire_get_external_credential_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.get_credential(tonic_request).await?;
Ok(from_wire_external_credential(response.into_inner()))
}
pub async fn get_credential_raw(
&mut self,
request: GetExternalCredentialRequest,
) -> Result<ExternalCredential, GestaltError> {
let mut tonic_request =
tonic::Request::new(to_wire_get_external_credential_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.get_credential(tonic_request).await?;
Ok(from_wire_external_credential(response.into_inner()))
}
pub async fn list_credentials(
&mut self,
subject_id: String,
instance: String,
connection_id: String,
) -> Result<Vec<ExternalCredential>, GestaltError> {
let request = ListExternalCredentialsRequest {
subject_id,
instance,
connection_id,
};
let mut tonic_request =
tonic::Request::new(to_wire_list_external_credentials_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = from_wire_list_external_credentials_response(
self.inner
.list_credentials(tonic_request)
.await?
.into_inner(),
);
Ok(response.credentials)
}
pub async fn list_credentials_raw(
&mut self,
request: ListExternalCredentialsRequest,
) -> Result<ListExternalCredentialsResponse, GestaltError> {
let mut tonic_request =
tonic::Request::new(to_wire_list_external_credentials_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.list_credentials(tonic_request).await?;
Ok(from_wire_list_external_credentials_response(
response.into_inner(),
))
}
pub async fn delete_credential(&mut self, id: String) -> Result<(), GestaltError> {
let request = DeleteExternalCredentialRequest { id };
let mut tonic_request =
tonic::Request::new(to_wire_delete_external_credential_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
self.inner.delete_credential(tonic_request).await?;
Ok(())
}
pub async fn delete_credential_raw(
&mut self,
request: DeleteExternalCredentialRequest,
) -> Result<(), GestaltError> {
let mut tonic_request =
tonic::Request::new(to_wire_delete_external_credential_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
self.inner.delete_credential(tonic_request).await?;
Ok(())
}
pub async fn validate_credential_config(
&mut self,
provider: String,
connection: String,
connection_id: String,
mode: String,
auth: Option<ExternalCredentialAuthConfig>,
) -> Result<(), GestaltError> {
let request = ValidateExternalCredentialConfigRequest {
provider,
connection,
connection_id,
mode,
auth,
..Default::default()
};
let mut tonic_request =
tonic::Request::new(to_wire_validate_external_credential_config_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
self.inner.validate_credential_config(tonic_request).await?;
Ok(())
}
pub async fn validate_credential_config_raw(
&mut self,
request: ValidateExternalCredentialConfigRequest,
) -> Result<(), GestaltError> {
let mut tonic_request =
tonic::Request::new(to_wire_validate_external_credential_config_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
self.inner.validate_credential_config(tonic_request).await?;
Ok(())
}
#[allow(clippy::too_many_arguments)]
pub async fn resolve_credential(
&mut self,
provider: String,
connection: String,
connection_id: String,
mode: String,
credential_subject_id: String,
actor_subject_id: String,
instance: String,
auth: Option<ExternalCredentialAuthConfig>,
) -> Result<ResolveExternalCredentialResponse, GestaltError> {
let request = ResolveExternalCredentialRequest {
provider,
connection,
connection_id,
mode,
credential_subject_id,
actor_subject_id,
instance,
auth,
..Default::default()
};
let mut tonic_request =
tonic::Request::new(to_wire_resolve_external_credential_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.resolve_credential(tonic_request).await?;
Ok(from_wire_resolve_external_credential_response(
response.into_inner(),
))
}
pub async fn resolve_credential_raw(
&mut self,
request: ResolveExternalCredentialRequest,
) -> Result<ResolveExternalCredentialResponse, GestaltError> {
let mut tonic_request =
tonic::Request::new(to_wire_resolve_external_credential_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.resolve_credential(tonic_request).await?;
Ok(from_wire_resolve_external_credential_response(
response.into_inner(),
))
}
#[allow(clippy::too_many_arguments)]
pub async fn exchange_credential(
&mut self,
provider: String,
connection: String,
connection_id: String,
credential_subject_id: String,
actor_subject_id: String,
instance: String,
credential_json: String,
auth: Option<ExternalCredentialAuthConfig>,
) -> Result<Option<ExternalCredentialTokenResponse>, GestaltError> {
let request = ExchangeExternalCredentialRequest {
provider,
connection,
connection_id,
credential_subject_id,
actor_subject_id,
instance,
credential_json,
auth,
..Default::default()
};
let mut tonic_request =
tonic::Request::new(to_wire_exchange_external_credential_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = from_wire_exchange_external_credential_response(
self.inner
.exchange_credential(tonic_request)
.await?
.into_inner(),
);
Ok(response.token_response)
}
pub async fn exchange_credential_raw(
&mut self,
request: ExchangeExternalCredentialRequest,
) -> Result<ExchangeExternalCredentialResponse, GestaltError> {
let mut tonic_request =
tonic::Request::new(to_wire_exchange_external_credential_request(request));
if let Some(timeout) = self.timeout {
tonic_request.set_timeout(timeout);
}
let response = self.inner.exchange_credential(tonic_request).await?;
Ok(from_wire_exchange_external_credential_response(
response.into_inner(),
))
}
}