nest_data_source_api/
messages.rs

1use crate::api::ApiError;
2use crate::participant_info::{PEPParticipantInfo, ParticipantInfo};
3use libpep::high_level::contexts::PseudonymizationDomain;
4use paas_client::pseudonym_service::PseudonymService;
5use rand::{CryptoRng, RngCore};
6use serde::{Deserialize, Serialize};
7use serde_json::Value;
8use std::fmt::Debug;
9
10pub trait HasParticipantInfo {
11    fn participant_info(&self) -> &ParticipantInfo;
12}
13
14pub trait HasPEPParticipantInfo {
15    fn pep_participant_info(&self) -> &PEPParticipantInfo;
16    fn domain_to(&self) -> &PseudonymizationDomain;
17}
18
19pub trait PEPMessageType: Debug {
20    type PEPMessage: HasPEPParticipantInfo + Serialize + Debug;
21    type Message: HasParticipantInfo + Debug;
22    #[allow(async_fn_in_trait)]
23    async fn pack<R: RngCore + CryptoRng>(
24        request: Self::Message,
25        domain_to: PseudonymizationDomain,
26        ps: &mut PseudonymService,
27        rng: &mut R,
28    ) -> Result<Self::PEPMessage, ApiError>;
29
30    #[allow(async_fn_in_trait)]
31    async fn unpack(
32        request: Self::PEPMessage,
33        ps: &mut PseudonymService,
34    ) -> Result<Self::Message, ApiError>;
35}
36
37#[derive(Debug, Serialize, Deserialize)]
38pub struct PEPParticipantRequest {
39    pub participant: PEPParticipantInfo,
40    pub domain_to: PseudonymizationDomain, // We need to know in which domain to create the participant. It may often be 1-1 with the data source, but not always. It may also be 1-1 with the column, but not always.
41    pub extra_data: Value,
42}
43
44#[derive(Debug)]
45pub struct ParticipantRequest {
46    pub participant: ParticipantInfo,
47    pub extra_data: Value,
48}
49
50#[derive(Debug)]
51pub struct ParticipantResponse {
52    pub participant: ParticipantInfo,
53    pub extra_data: Value,
54}
55
56#[derive(Debug, Serialize, Deserialize)]
57pub struct PEPParticipantResponse {
58    pub participant: PEPParticipantInfo,
59    pub domain_to: PseudonymizationDomain,
60    pub extra_data: Value,
61}
62
63#[derive(Debug, Serialize, Deserialize)]
64pub struct PEPActivityRequest {
65    pub participant: PEPParticipantInfo,
66    pub domain_to: PseudonymizationDomain, // We need to know in which domain to create the participant. It may often be 1-1 with the data source, but not always. It may also be 1-1 with the column, but not always.
67    pub activity: String,
68    pub extra_data: Value,
69}
70#[derive(Debug)]
71pub struct ActivityRequest {
72    pub participant: ParticipantInfo,
73    pub activity: String,
74    pub extra_data: Value,
75}
76
77#[derive(Debug)]
78pub struct ActivityResponse {
79    pub participant: ParticipantInfo,
80    pub activity: String,
81    pub extra_data: Value,
82}
83
84#[derive(Debug, Serialize, Deserialize)]
85pub struct PEPActivityResponse {
86    pub participant: PEPParticipantInfo,
87    pub domain_to: PseudonymizationDomain,
88    pub activity: String,
89    pub extra_data: Value,
90}
91
92impl HasParticipantInfo for ParticipantRequest {
93    fn participant_info(&self) -> &ParticipantInfo {
94        &self.participant
95    }
96}
97
98impl HasPEPParticipantInfo for PEPParticipantRequest {
99    fn pep_participant_info(&self) -> &PEPParticipantInfo {
100        &self.participant
101    }
102
103    fn domain_to(&self) -> &PseudonymizationDomain {
104        &self.domain_to
105    }
106}
107
108impl HasParticipantInfo for ParticipantResponse {
109    fn participant_info(&self) -> &ParticipantInfo {
110        &self.participant
111    }
112}
113
114impl HasPEPParticipantInfo for PEPParticipantResponse {
115    fn pep_participant_info(&self) -> &PEPParticipantInfo {
116        &self.participant
117    }
118
119    fn domain_to(&self) -> &PseudonymizationDomain {
120        &self.domain_to
121    }
122}
123#[derive(Debug)]
124pub struct ParticipantRequestMessageType;
125
126impl PEPMessageType for ParticipantRequestMessageType {
127    type PEPMessage = PEPParticipantRequest;
128    type Message = ParticipantRequest;
129
130    async fn pack<R: RngCore + CryptoRng>(
131        request: Self::Message,
132        domain_to: PseudonymizationDomain,
133        ps: &mut PseudonymService,
134        rng: &mut R,
135    ) -> Result<Self::PEPMessage, ApiError> {
136        Ok(Self::PEPMessage {
137            participant: request.participant.encrypt(ps, rng).await?,
138            domain_to,
139            extra_data: request.extra_data,
140        })
141    }
142    async fn unpack(
143        request: Self::PEPMessage,
144        ps: &mut PseudonymService,
145    ) -> Result<Self::Message, ApiError> {
146        Ok(Self::Message {
147            participant: request.participant.decrypt(ps, request.domain_to).await?,
148            extra_data: request.extra_data,
149        })
150    }
151}
152
153#[derive(Debug)]
154pub struct ParticipantResponseMessageType;
155
156impl PEPMessageType for ParticipantResponseMessageType {
157    type PEPMessage = PEPParticipantResponse;
158    type Message = ParticipantResponse;
159
160    async fn pack<R: RngCore + CryptoRng>(
161        request: Self::Message,
162        domain_to: PseudonymizationDomain,
163        ps: &mut PseudonymService,
164        rng: &mut R,
165    ) -> Result<Self::PEPMessage, ApiError> {
166        Ok(Self::PEPMessage {
167            participant: request.participant.encrypt(ps, rng).await?,
168            domain_to,
169            extra_data: request.extra_data,
170        })
171    }
172    async fn unpack(
173        request: Self::PEPMessage,
174        ps: &mut PseudonymService,
175    ) -> Result<Self::Message, ApiError> {
176        Ok(Self::Message {
177            participant: request.participant.decrypt(ps, request.domain_to).await?,
178            extra_data: request.extra_data,
179        })
180    }
181}
182
183impl HasParticipantInfo for ActivityRequest {
184    fn participant_info(&self) -> &ParticipantInfo {
185        &self.participant
186    }
187}
188
189impl HasPEPParticipantInfo for PEPActivityRequest {
190    fn pep_participant_info(&self) -> &PEPParticipantInfo {
191        &self.participant
192    }
193
194    fn domain_to(&self) -> &PseudonymizationDomain {
195        &self.domain_to
196    }
197}
198
199impl HasParticipantInfo for ActivityResponse {
200    fn participant_info(&self) -> &ParticipantInfo {
201        &self.participant
202    }
203}
204
205impl HasPEPParticipantInfo for PEPActivityResponse {
206    fn pep_participant_info(&self) -> &PEPParticipantInfo {
207        &self.participant
208    }
209
210    fn domain_to(&self) -> &PseudonymizationDomain {
211        &self.domain_to
212    }
213}
214
215#[derive(Debug)]
216pub struct ActivityRequestMessageType;
217
218impl PEPMessageType for ActivityRequestMessageType {
219    type PEPMessage = PEPActivityRequest;
220    type Message = ActivityRequest;
221    async fn pack<R: RngCore + CryptoRng>(
222        request: Self::Message,
223        domain_to: PseudonymizationDomain,
224        ps: &mut PseudonymService,
225        rng: &mut R,
226    ) -> Result<Self::PEPMessage, ApiError> {
227        Ok(Self::PEPMessage {
228            participant: request.participant.encrypt(ps, rng).await?,
229            domain_to,
230            activity: request.activity,
231            extra_data: request.extra_data,
232        })
233    }
234    async fn unpack(
235        request: Self::PEPMessage,
236        ps: &mut PseudonymService,
237    ) -> Result<Self::Message, ApiError> {
238        Ok(Self::Message {
239            participant: request.participant.decrypt(ps, request.domain_to).await?,
240            activity: request.activity,
241            extra_data: request.extra_data,
242        })
243    }
244}
245
246#[derive(Debug)]
247pub struct ActivityResponseMessageType;
248
249impl PEPMessageType for ActivityResponseMessageType {
250    type PEPMessage = PEPActivityResponse;
251    type Message = ActivityResponse;
252    async fn pack<R: RngCore + CryptoRng>(
253        request: Self::Message,
254        domain_to: PseudonymizationDomain,
255        ps: &mut PseudonymService,
256        rng: &mut R,
257    ) -> Result<Self::PEPMessage, ApiError> {
258        Ok(Self::PEPMessage {
259            participant: request.participant.encrypt(ps, rng).await?,
260            domain_to,
261            activity: request.activity,
262            extra_data: request.extra_data,
263        })
264    }
265    async fn unpack(
266        request: Self::PEPMessage,
267        ps: &mut PseudonymService,
268    ) -> Result<Self::Message, ApiError> {
269        Ok(Self::Message {
270            participant: request.participant.decrypt(ps, request.domain_to).await?,
271            activity: request.activity,
272            extra_data: request.extra_data,
273        })
274    }
275}