use std::{
collections::BTreeMap,
str::FromStr,
time::{Duration, UNIX_EPOCH},
};
use scion_sdk_common_types::ed25519::Ed25519SigningKeyPem;
use serde::{Deserialize, Serialize};
use snap_tokens::Pssid;
use utoipa::ToSchema;
use crate::{
session::state::{Session, SessionId, SessionManagerState, SessionTokenIssuerState},
state::DataPlaneId,
};
#[derive(Debug, Serialize, Deserialize, ToSchema, Clone)]
pub struct SessionManagerStateDto {
pub session_duration: Duration,
pub sessions: Vec<SessionDto>,
}
impl From<&SessionManagerState> for SessionManagerStateDto {
fn from(value: &SessionManagerState) -> Self {
Self {
session_duration: value.session_duration,
sessions: value
.sessions
.iter()
.map(|(session_id, session)| {
SessionDto {
session_id: SessionIdDto {
pssid: session_id.pssid.0.to_string(),
data_plane_id: session_id.data_plane_id,
},
expiry: session.expiry.duration_since(UNIX_EPOCH).unwrap().as_secs(),
}
})
.collect(),
}
}
}
impl TryFrom<SessionManagerStateDto> for SessionManagerState {
type Error = std::io::Error;
fn try_from(value: SessionManagerStateDto) -> Result<Self, Self::Error> {
let sessions: BTreeMap<SessionId, Session> = value
.sessions
.into_iter()
.map(|session| {
Pssid::from_str(&session.session_id.pssid).map(|pssid| {
let session_id = SessionId::new(pssid, session.session_id.data_plane_id);
let expiry = UNIX_EPOCH + Duration::from_secs(session.expiry);
(session_id, Session::new(expiry))
})
})
.collect::<Result<_, _>>()?;
Ok(SessionManagerState {
session_duration: value.session_duration,
sessions,
})
}
}
#[derive(Debug, Serialize, Deserialize, ToSchema, Clone)]
pub struct SessionDto {
pub session_id: SessionIdDto,
pub expiry: u64,
}
#[derive(Debug, Ord, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Clone, ToSchema)]
pub struct SessionIdDto {
pub pssid: String,
pub data_plane_id: DataPlaneId,
}
#[derive(Debug, Serialize, Deserialize, ToSchema, Clone)]
pub struct SessionTokenIssuerStateDto {
pub key: String,
}
impl From<&SessionTokenIssuerState> for SessionTokenIssuerStateDto {
fn from(value: &SessionTokenIssuerState) -> Self {
Self {
key: value.key.warning_to_private_key_pem(),
}
}
}
impl TryFrom<SessionTokenIssuerStateDto> for SessionTokenIssuerState {
type Error = std::io::Error;
fn try_from(value: SessionTokenIssuerStateDto) -> Result<Self, Self::Error> {
let key = Ed25519SigningKeyPem::from_str(&value.key)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
Ok(SessionTokenIssuerState { key })
}
}