use std::{
collections::HashMap,
sync::{Arc, Mutex},
time::Instant,
};
use ana_gotatun::x25519::PublicKey;
use mockall::mock;
use scion_sdk_reqwest_connect_rpc::client::CrpcClientError;
use snap_tun::{client::SnapTunControlPlaneClient, server::SnapTunAuthorization};
mock! {
pub ControlPlaneClient {}
#[async_trait::async_trait]
impl SnapTunControlPlaneClient for ControlPlaneClient {
async fn register_identity(
&self,
identity: PublicKey,
psk_share: Option<[u8; 32]>,
) -> Result<Option<[u8; 32]>, CrpcClientError>;
}
}
pub struct MockAuthorization {
inner: Arc<Mutex<MockAuthorizationInner>>,
}
struct MockAuthorizationInner {
authorized_identities: HashMap<[u8; 32], Instant>,
}
impl MockAuthorization {
pub fn new() -> Self {
Self {
inner: Arc::new(Mutex::new(MockAuthorizationInner {
authorized_identities: HashMap::new(),
})),
}
}
pub fn authorize_identity(&self, identity: [u8; 32], expires_at: Instant) {
let mut inner = self.inner.lock().unwrap();
inner.authorized_identities.insert(identity, expires_at);
}
pub fn authorize_for_duration(&self, identity: [u8; 32], duration: std::time::Duration) {
let expires_at = Instant::now() + duration;
self.authorize_identity(identity, expires_at);
}
pub fn revoke_identity(&self, identity: &[u8; 32]) {
let mut inner = self.inner.lock().unwrap();
inner.authorized_identities.remove(identity);
}
}
impl SnapTunAuthorization for MockAuthorization {
fn is_authorized(&self, now: Instant, identity: &[u8; 32]) -> bool {
let inner = self.inner.lock().unwrap();
if let Some(&expires_at) = inner.authorized_identities.get(identity) {
now < expires_at
} else {
false
}
}
}