2020-03-20 00:55:11 +00:00
|
|
|
use crate::{
|
2020-03-23 22:17:53 +00:00
|
|
|
data::NodeCache,
|
2020-03-20 00:55:11 +00:00
|
|
|
db::Db,
|
2021-09-18 17:55:39 +00:00
|
|
|
error::Error,
|
2020-12-23 18:06:15 +00:00
|
|
|
requests::{Breakers, Requests},
|
2023-07-27 15:19:20 +00:00
|
|
|
spawner::Spawner,
|
2020-03-20 00:55:11 +00:00
|
|
|
};
|
2022-01-17 22:54:45 +00:00
|
|
|
use activitystreams::iri_string::types::IriString;
|
2020-03-20 00:55:11 +00:00
|
|
|
use actix_web::web;
|
2020-03-15 16:29:01 +00:00
|
|
|
use lru::LruCache;
|
2020-03-16 03:36:46 +00:00
|
|
|
use rand::thread_rng;
|
2023-08-17 22:09:35 +00:00
|
|
|
use reqwest_middleware::ClientWithMiddleware;
|
2021-08-01 20:12:06 +00:00
|
|
|
use rsa::{RsaPrivateKey, RsaPublicKey};
|
2022-12-09 23:47:45 +00:00
|
|
|
use std::sync::{Arc, RwLock};
|
2020-03-15 02:05:40 +00:00
|
|
|
|
2022-12-21 22:51:17 +00:00
|
|
|
use super::LastOnline;
|
|
|
|
|
2020-03-15 02:05:40 +00:00
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct State {
|
2023-08-17 22:09:35 +00:00
|
|
|
pub(crate) requests: Requests,
|
2021-08-01 20:12:06 +00:00
|
|
|
pub(crate) public_key: RsaPublicKey,
|
2022-01-17 22:54:45 +00:00
|
|
|
object_cache: Arc<RwLock<LruCache<IriString, IriString>>>,
|
2023-08-17 22:09:35 +00:00
|
|
|
pub(crate) node_cache: NodeCache,
|
2020-12-23 18:06:15 +00:00
|
|
|
breakers: Breakers,
|
2022-12-21 22:51:17 +00:00
|
|
|
pub(crate) last_online: Arc<LastOnline>,
|
2021-02-10 04:05:06 +00:00
|
|
|
pub(crate) db: Db,
|
2020-03-15 02:05:40 +00:00
|
|
|
}
|
|
|
|
|
2021-09-18 17:55:39 +00:00
|
|
|
impl std::fmt::Debug for State {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
f.debug_struct("State")
|
|
|
|
.field("node_cache", &self.node_cache)
|
|
|
|
.field("breakers", &self.breakers)
|
|
|
|
.field("db", &self.db)
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-16 03:36:46 +00:00
|
|
|
impl State {
|
2021-09-21 19:32:25 +00:00
|
|
|
#[tracing::instrument(
|
2022-11-16 01:56:13 +00:00
|
|
|
level = "debug",
|
2021-09-21 19:32:25 +00:00
|
|
|
name = "Get inboxes for other domains",
|
2022-11-01 20:57:33 +00:00
|
|
|
skip_all,
|
2021-09-21 19:32:25 +00:00
|
|
|
fields(
|
|
|
|
existing_inbox = existing_inbox.to_string().as_str(),
|
2022-01-17 22:54:45 +00:00
|
|
|
authority
|
2021-09-21 19:32:25 +00:00
|
|
|
)
|
|
|
|
)]
|
2021-02-10 04:05:06 +00:00
|
|
|
pub(crate) async fn inboxes_without(
|
|
|
|
&self,
|
2022-01-17 22:54:45 +00:00
|
|
|
existing_inbox: &IriString,
|
|
|
|
authority: &str,
|
|
|
|
) -> Result<Vec<IriString>, Error> {
|
2021-02-10 04:05:06 +00:00
|
|
|
Ok(self
|
|
|
|
.db
|
|
|
|
.inboxes()
|
|
|
|
.await?
|
2020-03-15 22:37:53 +00:00
|
|
|
.iter()
|
2021-02-10 04:05:06 +00:00
|
|
|
.filter_map(|inbox| {
|
2022-01-17 22:54:45 +00:00
|
|
|
if let Some(authority_str) = inbox.authority_str() {
|
|
|
|
if inbox != existing_inbox && authority_str != authority {
|
2021-02-10 04:05:06 +00:00
|
|
|
return Some(inbox.clone());
|
2020-03-15 22:37:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
None
|
|
|
|
})
|
2021-02-10 04:05:06 +00:00
|
|
|
.collect())
|
2020-03-15 22:37:53 +00:00
|
|
|
}
|
|
|
|
|
2022-12-09 23:47:45 +00:00
|
|
|
pub(crate) fn is_cached(&self, object_id: &IriString) -> bool {
|
|
|
|
self.object_cache.read().unwrap().contains(object_id)
|
2020-03-15 17:49:27 +00:00
|
|
|
}
|
|
|
|
|
2022-12-09 23:47:45 +00:00
|
|
|
pub(crate) fn cache(&self, object_id: IriString, actor_id: IriString) {
|
|
|
|
self.object_cache.write().unwrap().put(object_id, actor_id);
|
2020-03-15 17:49:27 +00:00
|
|
|
}
|
|
|
|
|
2023-07-28 22:46:23 +00:00
|
|
|
pub(crate) fn is_connected(&self, iri: &IriString) -> bool {
|
|
|
|
self.breakers.should_try(iri)
|
|
|
|
}
|
|
|
|
|
2022-11-16 01:56:13 +00:00
|
|
|
#[tracing::instrument(level = "debug", name = "Building state", skip_all)]
|
2023-08-17 22:09:35 +00:00
|
|
|
pub(crate) async fn build(
|
|
|
|
db: Db,
|
|
|
|
key_id: String,
|
|
|
|
spawner: Spawner,
|
|
|
|
client: ClientWithMiddleware,
|
|
|
|
) -> Result<Self, Error> {
|
2021-02-10 04:05:06 +00:00
|
|
|
let private_key = if let Ok(Some(key)) = db.private_key().await {
|
2022-11-16 01:56:13 +00:00
|
|
|
tracing::debug!("Using existing key");
|
2021-02-10 04:05:06 +00:00
|
|
|
key
|
|
|
|
} else {
|
2022-11-02 18:55:45 +00:00
|
|
|
tracing::info!("Generating new keys");
|
2021-02-10 04:05:06 +00:00
|
|
|
let key = web::block(move || {
|
|
|
|
let mut rng = thread_rng();
|
2021-08-01 20:12:06 +00:00
|
|
|
RsaPrivateKey::new(&mut rng, 4096)
|
2021-02-10 04:05:06 +00:00
|
|
|
})
|
2021-02-11 00:00:11 +00:00
|
|
|
.await??;
|
2020-03-20 00:55:11 +00:00
|
|
|
|
2021-02-10 04:05:06 +00:00
|
|
|
db.update_private_key(&key).await?;
|
2020-03-20 00:55:11 +00:00
|
|
|
|
2021-02-10 04:05:06 +00:00
|
|
|
key
|
2020-03-20 00:55:11 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
let public_key = private_key.to_public_key();
|
2020-03-15 02:05:40 +00:00
|
|
|
|
2023-08-17 22:09:35 +00:00
|
|
|
let breakers = Breakers::default();
|
|
|
|
let last_online = Arc::new(LastOnline::empty());
|
|
|
|
|
|
|
|
let requests = Requests::new(
|
|
|
|
key_id,
|
|
|
|
private_key,
|
|
|
|
breakers.clone(),
|
|
|
|
last_online.clone(),
|
|
|
|
spawner,
|
|
|
|
client,
|
|
|
|
);
|
|
|
|
|
2020-03-23 17:38:39 +00:00
|
|
|
let state = State {
|
2023-08-17 22:09:35 +00:00
|
|
|
requests,
|
2020-03-20 00:55:11 +00:00
|
|
|
public_key,
|
2022-09-28 23:01:52 +00:00
|
|
|
object_cache: Arc::new(RwLock::new(LruCache::new(
|
|
|
|
(1024 * 8).try_into().expect("nonzero"),
|
|
|
|
))),
|
2021-02-10 04:05:06 +00:00
|
|
|
node_cache: NodeCache::new(db.clone()),
|
2023-08-17 22:09:35 +00:00
|
|
|
breakers,
|
2021-02-10 04:05:06 +00:00
|
|
|
db,
|
2023-08-17 22:09:35 +00:00
|
|
|
last_online,
|
2020-03-23 17:38:39 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Ok(state)
|
|
|
|
}
|
2020-03-15 02:05:40 +00:00
|
|
|
}
|