use std::{
collections::HashMap,
net::IpAddr,
sync::{Arc, Mutex},
time::Instant,
};
use crate::pg_wap::auth::AuthInfo;
#[derive(Clone)]
pub struct WapSessionManager {
inner: Arc<Mutex<WapSessionManagerInner>>,
}
impl WapSessionManager {
pub fn add_session_authentication(&self, auth_info: AuthInfo) {
let mut inner = self.inner.lock().unwrap();
inner.add_session_authentication(auth_info);
}
pub fn authenticated_sessions_for_ip(&self, client_addr: IpAddr) -> Vec<AuthInfo> {
let mut inner = self.inner.lock().unwrap();
inner.authenticated_sessions_for_ip(Instant::now(), client_addr)
}
}
pub struct WapSessionManagerInner {
sessions: HashMap<IpAddr, Vec<AuthInfo>>,
}
impl WapSessionManager {
pub fn new() -> Self {
let inner = Arc::new(Mutex::new(WapSessionManagerInner {
sessions: HashMap::new(),
}));
Self { inner }
}
}
impl Default for WapSessionManager {
fn default() -> Self {
Self::new()
}
}
impl WapSessionManagerInner {
pub fn add_session_authentication(&mut self, auth_info: AuthInfo) {
self.sessions
.entry(auth_info.ip)
.or_default()
.push(auth_info);
}
pub fn authenticated_sessions_for_ip(
&mut self,
now: Instant,
client_addr: IpAddr,
) -> Vec<AuthInfo> {
let Some(auth_infos) = self.sessions.get_mut(&client_addr) else {
return Vec::new();
};
auth_infos.retain(|auth| auth.valid_until > now);
if auth_infos.is_empty() {
self.sessions.remove(&client_addr);
Vec::new()
} else {
auth_infos.clone()
}
}
}