93 lines
3.3 KiB
Rust
93 lines
3.3 KiB
Rust
// src/api/consents.rs
|
|
// Consent request and retrieval logic - Functional style
|
|
|
|
use super::{client::{BankClient, BankingError}, models::{ConsentRequestBody, ConsentResponse}};
|
|
use tracing::{info, debug, error};
|
|
|
|
impl BankClient {
|
|
pub async fn request_consent(&self, client_id: &str) -> Result<ConsentResponse, BankingError> {
|
|
info!("🔐 Requesting consent for client_id: {}", client_id);
|
|
|
|
let body = self.build_consent_request(client_id);
|
|
let token = self.get_token().await?;
|
|
|
|
debug!("✅ Got bank token");
|
|
debug!("📤 Sending consent request to bank");
|
|
|
|
let response = self.http_client
|
|
.post(self.base_url.join("/account-consents/request")?)
|
|
.bearer_auth(token)
|
|
.header("x-requesting-bank", self.client_id.as_str())
|
|
.json(&body)
|
|
.send()
|
|
.await?;
|
|
|
|
debug!("📥 Bank response status: {}", response.status());
|
|
|
|
response
|
|
.text()
|
|
.await
|
|
.map_err(Into::into)
|
|
.and_then(|text| self.parse_consent_response(&text))
|
|
}
|
|
|
|
fn build_consent_request(&self, client_id: &str) -> ConsentRequestBody {
|
|
ConsentRequestBody {
|
|
client_id: client_id.to_string(),
|
|
permissions: vec![
|
|
"ReadAccountsDetail".to_string(),
|
|
"ReadBalances".to_string(),
|
|
"ReadTransactionsDetail".to_string(),
|
|
],
|
|
reason: "Account aggregation for Multiberry app".to_string(),
|
|
requesting_bank: self.client_id.clone(),
|
|
requesting_bank_name: "Multiberry Backend".to_string(),
|
|
}
|
|
}
|
|
|
|
fn parse_consent_response(&self, text: &str) -> Result<ConsentResponse, BankingError> {
|
|
info!("✅ Bank consent response: {}", text);
|
|
|
|
serde_json::from_str::<ConsentResponse>(text)
|
|
.map_err(|e| {
|
|
error!("❌ Failed to deserialize ConsentResponse: {}", e);
|
|
error!("Raw response was: {}", text);
|
|
BankingError::ApiError {
|
|
status: 500,
|
|
body: format!("Deserialization error: {}", e),
|
|
}
|
|
})
|
|
.map(|consent| {
|
|
info!("✅ Successfully parsed consent: {}", consent.consent_id);
|
|
consent
|
|
})
|
|
}
|
|
|
|
pub async fn delete_consent(&self, consent_id: &str) -> Result<(), BankingError> {
|
|
info!("🗑️ Deleting consent: {}", consent_id);
|
|
|
|
let token = self.get_token().await?;
|
|
|
|
let response = self.http_client
|
|
.delete(self.base_url.join(&format!("/account-consents/{}", consent_id))?)
|
|
.bearer_auth(token)
|
|
.header("x-fapi-interaction-id", format!("team275-{}", chrono::Utc::now().timestamp()))
|
|
.send()
|
|
.await?;
|
|
|
|
match response.status().as_u16() {
|
|
204 => {
|
|
info!("✅ Consent deleted successfully");
|
|
Ok(())
|
|
},
|
|
status => {
|
|
error!("❌ Failed to delete consent: {}", status);
|
|
Err(BankingError::ApiError {
|
|
status,
|
|
body: response.text().await.unwrap_or_default(),
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|