#[cfg(feature = "google-services")]
pub mod google_auth;
#[cfg(feature = "google-services")]
pub mod rtdb;
#[cfg(feature = "google-services")]
pub mod service_interface;
pub enum ExternalService {
Rtdb,
}
#[cfg(all(feature = "google-services", not(target_family = "wasm")))]
#[derive(Clone)]
pub struct ServicesHandler {
pub google_auth: Option<crate::external_services::google_auth::GoogleAuth>,
pub rtdb_root_instance: Option<crate::external_services::rtdb::RtdbInstance>,
pub rtdb_config: Option<RtdbConfig>,
}
#[derive(Clone)]
#[cfg(any(not(feature = "google-services"), target_family = "wasm"))]
pub struct ServicesHandler;
#[cfg(all(feature = "google-services", not(target_family = "wasm")))]
#[derive(serde::Deserialize, Debug, Default, Clone)]
pub struct ServicesConfig {
pub google_services_json_path: Option<String>,
pub google_rtdb: Option<RtdbConfig>,
}
#[cfg(any(not(feature = "google-services"), target_family = "wasm"))]
#[derive(Default)]
pub struct ServicesConfig;
#[derive(Default, serde::Serialize, serde::Deserialize, Clone, Debug)]
pub struct ServicesObject {
pub google_auth_jwt: Option<JsonWebToken>,
pub rtdb: Option<RtdbConfig>,
}
#[derive(serde::Deserialize, serde::Serialize, Default, Debug, Clone)]
pub struct RtdbConfig {
pub url: String,
pub api_key: String,
}
#[cfg(all(feature = "google-services", not(target_family = "wasm")))]
pub mod service {
use crate::external_services::ServicesObject;
use crate::misc::AccountError;
use firebase_rtdb::FirebaseRTDB;
use std::path::Path;
impl crate::external_services::ServicesHandler {
pub async fn on_post_login_serverside(
&self,
session_cid: u64,
) -> Result<ServicesObject, AccountError> {
let mut ret: ServicesObject = Default::default();
if let Some(auth) = self.google_auth.as_ref() {
ret.google_auth_jwt = Some(auth.sign_new_custom_jwt_auth(session_cid)?)
}
ret.rtdb = self.rtdb_config.clone();
Ok(ret)
}
}
impl crate::external_services::ServicesConfig {
pub async fn into_services_handler(
self,
) -> Result<crate::external_services::ServicesHandler, AccountError> {
let (google_auth, rtdb_root_instance) = if let Some(path) =
self.google_services_json_path
{
let path = Path::new(&path);
let auth =
crate::external_services::google_auth::GoogleAuth::load_from_google_services_file(
path,
)
.await?;
let rtdb_root_instance = if let Some(rtdb_config) = self.google_rtdb.as_ref() {
let root_jwt = auth.sign_new_custom_jwt_auth("root")?;
let rtdb_root_instance = FirebaseRTDB::new_from_jwt(
&rtdb_config.url,
root_jwt,
&rtdb_config.api_key,
)
.await
.map_err(|err| {
citadel_io::error!(citadel_io::ErrorCode::ExternalService, err.inner)
})?;
Some(rtdb_root_instance.into())
} else {
None
};
(Some(auth), rtdb_root_instance)
} else {
(None, None)
};
let rtdb_config = self.google_rtdb;
Ok(crate::external_services::ServicesHandler {
google_auth,
rtdb_config,
rtdb_root_instance,
})
}
}
}
#[cfg(not(all(feature = "google-services", not(target_family = "wasm"))))]
impl ServicesHandler {
pub async fn on_post_login_serverside(
&self,
_session_cid: u64,
) -> Result<ServicesObject, crate::misc::AccountError> {
Ok(ServicesObject::default())
}
}
#[cfg(all(feature = "google-services", not(target_family = "wasm")))]
impl ServicesObject {
pub async fn setup_client_rtdb<
R: citadel_crypt::ratchets::Ratchet,
Fcm: citadel_crypt::ratchets::Ratchet,
>(
self,
cnac: &crate::client_account::ClientNetworkAccount<R, Fcm>,
) -> Result<(), crate::misc::AccountError> {
if let (Some(rtdb_cfg), Some(jwt)) = (self.rtdb, self.google_auth_jwt) {
log::trace!(target: "citadel", "Client detected RTDB config + Google Auth web token. Will login + store config to CNAC ...");
let rtdb = firebase_rtdb::FirebaseRTDB::new_from_jwt(
&rtdb_cfg.url,
jwt.clone(),
rtdb_cfg.api_key.clone(),
)
.await
.map_err(|err| citadel_io::error!(citadel_io::ErrorCode::ExternalService, err.inner))?;
let firebase_rtdb::FirebaseRTDB {
base_url,
auth,
expire_time,
api_key,
jwt,
..
} = rtdb;
cnac.store_rtdb_config(crate::external_services::rtdb::RtdbClientConfig {
url: base_url,
api_key,
auth_payload: auth,
expire_time,
jwt,
});
log::trace!(target: "citadel", "Successfully logged-in to RTDB + stored config inside CNAC ...");
}
Ok(())
}
}
#[cfg(not(all(feature = "google-services", not(target_family = "wasm"))))]
impl ServicesObject {
pub async fn setup_client_rtdb<
R: citadel_crypt::ratchets::Ratchet,
Fcm: citadel_crypt::ratchets::Ratchet,
>(
self,
_cnac: &crate::client_account::ClientNetworkAccount<R, Fcm>,
) -> Result<(), crate::misc::AccountError> {
Ok(())
}
}
pub type JsonWebToken = String;