feat: load billing adapters #125

Merged
realaravinth merged 63 commits from load-billing-adapter into master 2025-01-11 19:41:14 +05:30
11 changed files with 228 additions and 2 deletions
Showing only changes of commit 970a4d4581 - Show all commits

16
Cargo.lock generated
View file

@ -4172,6 +4172,21 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "twilio_client"
version = "0.1.0"
dependencies = [
"actix-rt",
"derive-getters",
"derive_builder 0.20.2",
"derive_more 0.99.18",
"log",
"reqwest",
"serde",
"serde_json",
"url",
]
[[package]]
name = "typenum"
version = "1.17.0"
@ -4445,6 +4460,7 @@ dependencies = [
"time",
"tracing",
"tracing-actix-web",
"twilio_client",
"url",
"uuid",
"validator 0.18.1",

View file

@ -5,7 +5,7 @@ edition = "2021"
[workspace]
exclude = ["utils/db-migrations"] #, "utils/cache-bust"]
members = [".", "mailpit_client"]
members = [".", "mailpit_client", "twilio_client"]
[dependencies]
actix-identity = "0.8.0"
@ -36,7 +36,8 @@ tracing = { version = "0.1.40", features = ["log"] }
tracing-actix-web = "0.7.10"
url = { version = "2.5.0", features = ["serde"] }
uuid = { version = "1.10.0", features = ["v4", "serde"] }
validator = { version = "0.18.1", features = ["derive"] }
validator = { version = "0.19.0", features = ["derive"] }
twilio_client = { path = "./twilio_client" }
[dev-dependencies]
#reqwest = { version = "0.12.4", features = ["json"] }

View file

@ -4,3 +4,4 @@
pub mod db;
pub mod mailer;
pub mod phone;

View file

@ -0,0 +1,5 @@
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
pub mod twilio;

View file

@ -0,0 +1,57 @@
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use lettre::{message::header::ContentType, AsyncTransport, Message};
use super::*;
use crate::identity::application::port::output::phone::{account_login_otp::*, errors::*};
use crate::identity::domain::employee_aggregate::PhoneNumber;
#[async_trait::async_trait]
impl AccountLoginOTPOutPhonePort for Phone {
async fn account_login_otp(&self, to: &PhoneNumber, otp: usize) -> OutPhonePortResult<()> {
unimplemented!()
}
}
#[cfg(test)]
mod tests {
use super::*;
use url::Url;
use mailpit_client::*;
use serde::Deserialize;
#[actix_rt::test]
async fn test_phone_account_validation_otp() {
// let username = "batman";
// let email = "batman@account_validation_otp.example.com";
// let validation_secret = "dafsdfasecret";
//
// let settings = crate::settings::tests::get_settings().await;
// let m = Lettrephone::new(&settings);
//
// m.account_validation_otp(email, username, validation_secret)
// .await
// .unwrap();
//
// let mailpit_url =
// std::env::var("MAILPIT_URL").expect("Please set mailpit instance URL in MAILPIT_URL");
// let mc = MailPitHTTPClientBuilder::default()
// .url(Url::parse(&mailpit_url).unwrap())
// .build()
// .unwrap();
//
// let mailpit_email = mc.get_email_addressed_to(email).await;
//
// assert!(mailpit_email.text().contains(validation_secret));
// assert!(mailpit_email.text().contains(username));
// assert!(mailpit_email
// .to()
// .iter()
// .any(|t| t.address() == email && t.name() == username));
//
// mc.delete_email(mailpit_email).await;
}
}

View file

@ -0,0 +1,57 @@
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use lettre::{message::header::ContentType, AsyncTransport, Message};
use super::*;
use crate::identity::application::port::output::phone::{account_validation_otp::*, errors::*};
use crate::identity::domain::employee_aggregate::PhoneNumber;
#[async_trait::async_trait]
impl AccountValidationOTPOutPhonePort for Phone {
async fn account_validation_otp(&self, to: &PhoneNumber, otp: usize) -> OutPhonePortResult<()> {
unimplemented!()
}
}
#[cfg(test)]
mod tests {
use super::*;
use url::Url;
use mailpit_client::*;
use serde::Deserialize;
#[actix_rt::test]
async fn test_phone_account_validation_otp() {
// let username = "batman";
// let email = "batman@account_validation_otp.example.com";
// let validation_secret = "dafsdfasecret";
//
// let settings = crate::settings::tests::get_settings().await;
// let m = Lettrephone::new(&settings);
//
// m.account_validation_otp(email, username, validation_secret)
// .await
// .unwrap();
//
// let mailpit_url =
// std::env::var("MAILPIT_URL").expect("Please set mailpit instance URL in MAILPIT_URL");
// let mc = MailPitHTTPClientBuilder::default()
// .url(Url::parse(&mailpit_url).unwrap())
// .build()
// .unwrap();
//
// let mailpit_email = mc.get_email_addressed_to(email).await;
//
// assert!(mailpit_email.text().contains(validation_secret));
// assert!(mailpit_email.text().contains(username));
// assert!(mailpit_email
// .to()
// .iter()
// .any(|t| t.address() == email && t.name() == username));
//
// mc.delete_email(mailpit_email).await;
}
}

View file

@ -0,0 +1 @@

View file

@ -0,0 +1,29 @@
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::sync::Arc;
use twilio_client::{TwilioClient, TwilioClientBuilder};
use crate::settings::Settings;
mod account_login_otp;
mod account_validation_otp;
mod errors;
#[derive(Clone)]
pub struct Phone {
tx: TwilioClient,
}
impl Phone {
pub fn new(s: &Settings) -> Self {
let tx = TwilioClientBuilder::default()
.auth_token(s.phone.twilio_auth_token.clone())
.account_id(s.phone.twilio_account_id.clone())
.build()
.unwrap();
Self { tx }
}
}

1
twilio_client/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
target/

15
twilio_client/Cargo.toml Normal file
View file

@ -0,0 +1,15 @@
[package]
name = "twilio_client"
version = "0.1.0"
edition = "2024"
[dependencies]
reqwest = { version = "0.12.4", features = ["json", "native-tls-vendored"] }
serde = { version = "1.0.201", features = ["derive"] }
serde_json = "1.0.117"
actix-rt = "2.9.0"
derive-getters = "0.5.0"
derive_more = "0.99.17"
log = "0.4.21"
derive_builder = "0.20.0"
url = { version = "2.5.0", features = ["serde"] }

43
twilio_client/src/lib.rs Normal file
View file

@ -0,0 +1,43 @@
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use derive_builder::Builder;
#[allow(unused_imports)]
use log::*;
#[allow(unused_imports)]
#[cfg(test)]
use println as info;
use reqwest::Client;
use serde::{Deserialize, Serialize};
use url::Url;
#[derive(Clone, Debug, Builder)]
pub struct TwilioClient {
auth_token: String,
account_id: String,
#[builder(default = "Client::default()")]
client: Client,
}
impl TwilioClient {
async fn send_sms(from: &str, to: &str, msg: &str) -> Result<(), String> {
unimplemented!()
// Ok(())
}
}
//pub fn add(left: u64, right: u64) -> u64 {
// left + right
//}
//
//#[cfg(test)]
//mod tests {
// use super::*;
//
// #[test]
// fn it_works() {
// let result = add(2, 2);
// assert_eq!(result, 4);
// }
//}