use crate::api::ApiError;
use crate::participant_info::{PEPParticipantInfo, ParticipantInfo};
use libpep::factors::PseudonymizationDomain;
use paas_client::pseudonym_service::PseudonymService;
use rand::{CryptoRng, Rng};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::fmt::Debug;
pub trait HasParticipantInfo {
fn participant_info(&self) -> &ParticipantInfo;
}
pub trait HasPEPParticipantInfo {
fn pep_participant_info(&self) -> &PEPParticipantInfo;
fn domain_to(&self) -> &PseudonymizationDomain;
}
pub trait PEPMessageType: Debug {
type PEPMessage: HasPEPParticipantInfo + Serialize + Debug;
type Message: HasParticipantInfo + Debug;
#[allow(async_fn_in_trait)]
async fn pack<R: Rng + CryptoRng>(
request: Self::Message,
domain_to: PseudonymizationDomain,
ps: &mut PseudonymService,
rng: &mut R,
) -> Result<Self::PEPMessage, ApiError>;
#[allow(async_fn_in_trait)]
async fn unpack(
request: Self::PEPMessage,
ps: &mut PseudonymService,
) -> Result<Self::Message, ApiError>;
}
#[derive(Debug, Serialize, Deserialize)]
pub struct PEPActivityRequest {
pub participant: PEPParticipantInfo,
pub domain_to: PseudonymizationDomain, pub activity: String,
pub extra_data: Value,
}
#[derive(Debug)]
pub struct ActivityRequest {
pub participant: ParticipantInfo,
pub activity: String,
pub extra_data: Value,
}
#[derive(Debug)]
pub struct ActivityResponse {
pub participant: ParticipantInfo,
pub activity: String,
pub extra_data: Value,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct PEPActivityResponse {
pub participant: PEPParticipantInfo,
pub domain_to: PseudonymizationDomain,
pub activity: String,
pub extra_data: Value,
}
impl HasParticipantInfo for ActivityRequest {
fn participant_info(&self) -> &ParticipantInfo {
&self.participant
}
}
impl HasPEPParticipantInfo for PEPActivityRequest {
fn pep_participant_info(&self) -> &PEPParticipantInfo {
&self.participant
}
fn domain_to(&self) -> &PseudonymizationDomain {
&self.domain_to
}
}
impl HasParticipantInfo for ActivityResponse {
fn participant_info(&self) -> &ParticipantInfo {
&self.participant
}
}
impl HasPEPParticipantInfo for PEPActivityResponse {
fn pep_participant_info(&self) -> &PEPParticipantInfo {
&self.participant
}
fn domain_to(&self) -> &PseudonymizationDomain {
&self.domain_to
}
}
#[derive(Debug)]
pub struct ActivityRequestMessageType;
impl PEPMessageType for ActivityRequestMessageType {
type PEPMessage = PEPActivityRequest;
type Message = ActivityRequest;
async fn pack<R: Rng + CryptoRng>(
request: Self::Message,
domain_to: PseudonymizationDomain,
ps: &mut PseudonymService,
rng: &mut R,
) -> Result<Self::PEPMessage, ApiError> {
Ok(Self::PEPMessage {
participant: request.participant.encrypt(ps, rng).await?,
domain_to,
activity: request.activity,
extra_data: request.extra_data,
})
}
async fn unpack(
request: Self::PEPMessage,
ps: &mut PseudonymService,
) -> Result<Self::Message, ApiError> {
Ok(Self::Message {
participant: request.participant.decrypt(ps, request.domain_to).await?,
activity: request.activity,
extra_data: request.extra_data,
})
}
}
#[derive(Debug)]
pub struct ActivityResponseMessageType;
impl PEPMessageType for ActivityResponseMessageType {
type PEPMessage = PEPActivityResponse;
type Message = ActivityResponse;
async fn pack<R: Rng + CryptoRng>(
request: Self::Message,
domain_to: PseudonymizationDomain,
ps: &mut PseudonymService,
rng: &mut R,
) -> Result<Self::PEPMessage, ApiError> {
Ok(Self::PEPMessage {
participant: request.participant.encrypt(ps, rng).await?,
domain_to,
activity: request.activity,
extra_data: request.extra_data,
})
}
async fn unpack(
request: Self::PEPMessage,
ps: &mut PseudonymService,
) -> Result<Self::Message, ApiError> {
Ok(Self::Message {
participant: request.participant.decrypt(ps, request.domain_to).await?,
activity: request.activity,
extra_data: request.extra_data,
})
}
}