tuwunel_service/threepid/
mod.rs1mod binding;
2mod canonical;
3mod pending;
4mod ratelimit;
5
6use std::{
7 collections::HashMap,
8 net::IpAddr,
9 sync::{Arc, Mutex},
10 time::Instant,
11};
12
13use ruma::{MilliSecondsSinceUnixEpoch, OwnedDeviceId, OwnedUserId, thirdparty::Medium};
14use serde::{Deserialize, Serialize};
15use tuwunel_core::{Result, smallstr::SmallString, utils::MutexMap};
16use tuwunel_database::{Database, Map};
17
18pub use self::{canonical::canonicalize_email, pending::PendingOutcome};
19
20type Ratelimiter<K> = Mutex<HashMap<K, (Instant, f64)>>;
23
24type EmailKey = SmallString<[u8; 48]>;
27
28pub struct Service {
34 db: Data,
35 pending_mutex: MutexMap<String, ()>,
36 claim_mutex: MutexMap<UiaaKey, ()>,
37 ip_ratelimiter: Ratelimiter<IpAddr>,
38 address_ratelimiter: Ratelimiter<EmailKey>,
39}
40
41struct Data {
42 database: Arc<Database>,
43 userid_email: Arc<Map>,
44 email_userid: Arc<Map>,
45 threepidsid_pending: Arc<Map>,
46 userdevicesessionid_threepid: Arc<Map>,
47}
48
49pub type UiaaSessionId = SmallString<[u8; 32]>;
53
54pub type UiaaKey = (OwnedUserId, OwnedDeviceId, UiaaSessionId);
58
59#[derive(Clone, Debug, Deserialize, Serialize)]
62struct Binding {
63 medium: Medium,
64 validated_at: MilliSecondsSinceUnixEpoch,
65 added_at: MilliSecondsSinceUnixEpoch,
66}
67
68#[derive(Clone, Debug)]
71pub struct Association {
72 pub medium: Medium,
73 pub address: String,
74}
75
76impl crate::Service for Service {
77 fn build(args: &crate::Args<'_>) -> Result<Arc<Self>> {
78 Ok(Arc::new(Self {
79 db: Data {
80 database: args.db.clone(),
81 userid_email: args.db["userid_email"].clone(),
82 email_userid: args.db["email_userid"].clone(),
83 threepidsid_pending: args.db["threepidsid_pending"].clone(),
84 userdevicesessionid_threepid: args.db["userdevicesessionid_threepid"].clone(),
85 },
86 pending_mutex: MutexMap::new(),
87 claim_mutex: MutexMap::new(),
88 ip_ratelimiter: Mutex::new(HashMap::new()),
89 address_ratelimiter: Mutex::new(HashMap::new()),
90 }))
91 }
92
93 fn name(&self) -> &str { crate::service::make_name(std::module_path!()) }
94}