use super::{
auth_type::{
AuthType,
Bearer,
Cookie,
},
boarding_pass::{
payloads::JsonWebToken,
BoardingPass,
},
passport_register::PassportRegister,
storage::BoardingPassStorage,
};
use crate::Ticket;
use anyhow::anyhow;
pub trait Gate<BPD, T, ID, ENC>
where
T: AuthType,
{
fn login<BPS, PR>(
ticket: Ticket,
passport_register: &PR,
boarding_pass_storage: &BPS,
) -> anyhow::Result<String>
where
BPS: BoardingPassStorage<BPD, T, ID, ENC>,
PR: PassportRegister;
fn logout<BPS>(
identifier: ID,
boarding_pass_storage: &BPS,
) -> anyhow::Result<()>
where
BPS: BoardingPassStorage<BPD, T, ID, ENC>,
{
boarding_pass_storage.remove_boarding_pass(identifier)
}
}
pub struct JwtCookieGate;
impl Gate<JsonWebToken, Cookie, (), String> for JwtCookieGate {
fn login<BPS, PR>(
ticket: Ticket,
passport_register: &PR,
boarding_pass_storage: &BPS,
) -> anyhow::Result<String>
where
BPS: BoardingPassStorage<JsonWebToken, Cookie, (), String>,
PR: PassportRegister,
{
let Some(passport) = passport_register.verify_credentials(&ticket)?
else {
return Err(anyhow!(
"No passport found for ticket with id: {}",
ticket.id
));
};
let boarding_pass: BoardingPass<JsonWebToken, Cookie> =
BoardingPass::try_from(&passport)?;
boarding_pass_storage.store_boarding_pass(&boarding_pass)
}
}
pub struct JwtBearerGate;
impl Gate<JsonWebToken, Bearer, (), String> for JwtBearerGate {
fn login<BPS, PR>(
ticket: Ticket,
passport_register: &PR,
boarding_pass_storage: &BPS,
) -> anyhow::Result<String>
where
BPS: BoardingPassStorage<JsonWebToken, Bearer, (), String>,
PR: PassportRegister,
{
let Some(passport) = passport_register.verify_credentials(&ticket)?
else {
return Err(anyhow!(
"No passport found for ticket with id: {}",
ticket.id
));
};
let boarding_pass: BoardingPass<JsonWebToken, Bearer> =
BoardingPass::try_from(&passport)?;
boarding_pass_storage.store_boarding_pass(&boarding_pass)
}
}