1use std::convert::TryFrom;
2
3use serde::{Deserialize, Serialize};
4
5#[cfg(feature = "oobi")]
6use crate::oobi::OobiManager;
7#[cfg(feature = "query")]
8use crate::{
9 database::EventDatabase,
10 event_message::signed_event_message::Op,
11 processor::event_storage::EventStorage,
12 query::{
13 key_state_notice::KeyStateNotice,
14 mailbox::MailboxRoute,
15 query_event::QueryRoute,
16 query_event::SignedQueryMessage,
17 reply_event::{ReplyRoute, SignedReply},
18 ReplyType,
19 },
20};
21use crate::{
22 error::Error,
23 event_message::{
24 cesr_adapter::ParseError,
25 signed_event_message::{Message, Notice},
26 },
27 prefix::IdentifierPrefix,
28 processor::Processor,
29};
30#[cfg(feature = "mailbox")]
31use crate::{
32 event_message::{signature::Signature, signed_event_message::SignedEventMessage},
33 mailbox::exchange::{Exchange, ExchangeMessage, ForwardTopic, SignedExchange},
34};
35pub use cesrox::cesr_proof::MaterialPath;
36use cesrox::parse_many;
37#[cfg(feature = "query")]
38use said::version::format::SerializationFormats;
39
40pub mod error;
41pub mod event_generator;
42#[cfg(all(feature = "query", feature = "oobi", feature = "mailbox"))]
43pub mod simple_controller;
44
45pub fn parse_event_stream(stream: &[u8]) -> Result<Vec<Message>, ParseError> {
46 let (_rest, events) = parse_many(stream).map_err(|e| ParseError::CesrError(e.to_string()))?;
47 events.into_iter().map(Message::try_from).collect()
48}
49
50pub fn parse_notice_stream(stream: &[u8]) -> Result<Vec<Notice>, ParseError> {
51 let (_rest, notices) = parse_many(stream).map_err(|e| ParseError::CesrError(e.to_string()))?;
52 notices.into_iter().map(Notice::try_from).collect()
53}
54
55#[cfg(any(feature = "query", feature = "oobi"))]
56pub fn parse_op_stream(stream: &[u8]) -> Result<Vec<Op>, ParseError> {
57 let (_rest, ops) = parse_many(stream).map_err(|e| ParseError::CesrError(e.to_string()))?;
58 ops.into_iter().map(Op::try_from).collect()
59}
60
61#[cfg(any(feature = "query", feature = "oobi"))]
62pub fn parse_query_stream(stream: &[u8]) -> Result<Vec<SignedQueryMessage>, ParseError> {
63 let (_rest, queries) = parse_many(stream).map_err(|e| ParseError::CesrError(e.to_string()))?;
64 queries
65 .into_iter()
66 .map(SignedQueryMessage::try_from)
67 .collect()
68}
69
70#[cfg(any(feature = "query", feature = "oobi"))]
71pub fn parse_reply_stream(stream: &[u8]) -> Result<Vec<SignedReply>, ParseError> {
72 let (_rest, replies) = parse_many(stream).map_err(|e| ParseError::CesrError(e.to_string()))?;
73 replies.into_iter().map(SignedReply::try_from).collect()
74}
75
76#[cfg(feature = "mailbox")]
77pub fn parse_exchange_stream(stream: &[u8]) -> Result<Vec<SignedExchange>, ParseError> {
78 let (_rest, exchanges) =
79 parse_many(stream).map_err(|e| ParseError::CesrError(e.to_string()))?;
80 exchanges
81 .into_iter()
82 .map(SignedExchange::try_from)
83 .collect()
84}
85
86pub fn process_notice<P: Processor>(msg: Notice, processor: &P) -> Result<(), Error> {
87 processor.process_notice(&msg)
88}
89
90#[cfg(feature = "query")]
91pub fn process_reply<P: Processor>(
92 sr: SignedReply,
93 #[cfg(feature = "oobi")] oobi_manager: &OobiManager,
94 processor: &P,
95 event_storage: &EventStorage<P::Database>,
96) -> Result<(), Error> {
97 match sr.reply.get_route() {
98 #[cfg(feature = "oobi")]
99 ReplyRoute::LocScheme(_) | ReplyRoute::EndRoleAdd(_) | ReplyRoute::EndRoleCut(_) => {
100 process_signed_oobi(&sr, oobi_manager, event_storage)
101 }
102 ReplyRoute::Ksn(_, _) => processor.process_op_reply(&sr),
103 }
104}
105
106#[cfg(feature = "oobi")]
107pub fn process_signed_oobi<D: EventDatabase>(
108 signed_oobi: &SignedReply,
109 oobi_manager: &OobiManager,
110 event_storage: &EventStorage<D>,
111) -> Result<(), Error> {
112 use crate::processor::validator::EventValidator;
113
114 let validator = EventValidator::new(
115 event_storage.escrow_db.clone(),
116 event_storage.events_db.clone(),
117 );
118 validator.verify(&signed_oobi.reply.encode()?, &signed_oobi.signature)?;
120 signed_oobi.reply.check_digest()?;
122 oobi_manager
124 .process_oobi(signed_oobi)
125 .map_err(|e| Error::SemanticError(e.to_string()))?;
126
127 Ok(())
128}
129
130#[cfg(feature = "mailbox")]
131pub fn process_signed_exn<D: EventDatabase>(
132 exn: SignedExchange,
133 storage: &EventStorage<D>,
134) -> Result<(), Error> {
135 let exn_message = &exn.exchange_message;
136 let verification_result =
137 exn.signature
138 .iter()
139 .try_fold(true, |acc, signature| -> Result<bool, Error> {
140 Ok(acc && signature.verify(&exn_message.encode()?, storage)?)
141 });
142 if verification_result? {
143 process_exn(exn_message, exn.data_signature, storage)
144 } else {
145 Err(Error::SignatureVerificationError)
146 }
147}
148
149#[cfg(feature = "mailbox")]
150fn process_exn<D: EventDatabase>(
151 exn: &ExchangeMessage,
152 attachemnt: (MaterialPath, Vec<Signature>),
153 storage: &EventStorage<D>,
154) -> Result<(), Error> {
155 let (receipient, to_forward, topic) = match &exn.data.data {
156 Exchange::Fwd { args, to_forward } => (&args.recipient_id, to_forward, &args.topic),
157 };
158 let (sigs, witness_receipts) = attachemnt.1.into_iter().fold(
159 (vec![], vec![]),
160 |(mut signatures, mut witness_receipts), s| {
161 match s {
162 Signature::Transferable(_sd, mut sigs) => signatures.append(&mut sigs),
163 Signature::NonTransferable(receipts) => witness_receipts.push(receipts),
164 }
165 (signatures, witness_receipts)
166 },
167 );
168
169 let signed_to_forward = SignedEventMessage {
170 event_message: to_forward.clone(),
171 signatures: sigs,
172 witness_receipts: if witness_receipts.is_empty() {
173 None
174 } else {
175 Some(witness_receipts)
176 },
177 delegator_seal: None,
178 };
179
180 match topic {
181 ForwardTopic::Multisig => {
182 storage.add_mailbox_multisig(receipient, signed_to_forward)?;
183 }
184 ForwardTopic::Delegate => {
185 storage.add_mailbox_delegate(receipient, signed_to_forward)?;
186 }
187 };
188 Ok(())
189}
190
191#[cfg(feature = "query")]
192pub fn process_signed_query<D: EventDatabase>(
193 qr: SignedQueryMessage,
194 storage: &EventStorage<D>,
195) -> Result<ReplyType, SignedQueryError> {
196 let verify = |data: &[u8], signature: Signature| -> Result<_, SignedQueryError> {
197 let ver_result = signature.verify(&data, storage)?;
198 if !ver_result {
199 Err(SignedQueryError::InvalidSignature)
200 } else {
201 Ok(())
202 }
203 };
204 match qr {
205 SignedQueryMessage::KelQuery(kqry) => {
206 let signature = kqry.signature;
207 let data = &kqry.query.encode().map_err(|_e| Error::VersionError)?;
208 verify(&data, signature)?;
210
211 Ok(process_query(kqry.query.get_route(), storage)?)
214 }
215 SignedQueryMessage::MailboxQuery(mqry) => {
216 let signature = mqry.signature;
217 let data = &mqry.query.encode().map_err(|_e| Error::VersionError)?;
218 verify(&data, signature)?;
220 Ok(process_mailbox_query(&mqry.query.data.data, storage)?)
221 }
222 }
223}
224
225#[derive(Debug, thiserror::Error, Serialize, Deserialize)]
226pub enum SignedQueryError {
227 #[error(transparent)]
228 KeriError(#[from] crate::error::Error),
229
230 #[error(transparent)]
231 DbError(#[from] crate::database::sled::DbError),
232
233 #[error(transparent)]
234 QueryError(#[from] QueryError),
235
236 #[error("unknown signer with id {id:?}")]
237 UnknownSigner { id: IdentifierPrefix },
238
239 #[error("signature verification failed")]
240 InvalidSignature,
241}
242
243#[cfg(feature = "query")]
244pub fn process_query<D: EventDatabase>(
245 qr: &QueryRoute,
246 storage: &EventStorage<D>,
247) -> Result<ReplyType, QueryError> {
248 match qr {
249 QueryRoute::Ksn { args, .. } => {
250 let state = storage
252 .get_state(&args.i)
253 .ok_or_else(|| QueryError::UnknownId { id: args.i.clone() })?;
254 let ksn = KeyStateNotice::new_ksn(state, SerializationFormats::JSON);
255 Ok(ReplyType::Ksn(ksn))
256 }
257 QueryRoute::Logs {
258 reply_route: _,
259 args,
260 } => {
261 let response = match (args.s, args.limit) {
262 (None, _) => storage.get_kel_messages_with_receipts_all(&args.i)?,
263 (Some(sn), None) => storage
264 .get_event_at_sn(&args.i, sn)
265 .map(|event| vec![Notice::Event(event.signed_event_message)]),
266 (Some(sn), Some(limit)) => {
267 storage.get_kel_messages_with_receipts_range(&args.i, sn, limit)?
268 }
269 }
270 .ok_or_else(|| QueryError::UnknownId { id: args.i.clone() })?
271 .into_iter()
272 .map(Message::Notice)
273 .collect::<Vec<_>>();
274
275 Ok(ReplyType::Kel(response))
276 }
277 }
278}
279
280#[cfg(feature = "query")]
281pub fn process_mailbox_query<D: EventDatabase>(
282 qr: &MailboxRoute,
283 storage: &EventStorage<D>,
284) -> Result<ReplyType, QueryError> {
285 match qr {
286 MailboxRoute::Mbx { args, .. } => {
287 let mail = storage.get_mailbox_messages(args)?;
288 Ok(ReplyType::Mbx(mail))
289 }
290 }
291}
292
293#[derive(Debug, thiserror::Error, Serialize, Deserialize)]
294pub enum QueryError {
295 #[error(transparent)]
296 KeriError(#[from] crate::error::Error),
297
298 #[error(transparent)]
299 DbError(#[from] crate::database::sled::DbError),
300
301 #[error("unknown identifier {id:?}")]
302 UnknownId { id: IdentifierPrefix },
303}
304
305pub mod prelude {
306 #[cfg(feature = "oobi")]
307 pub use crate::actor::process_signed_oobi;
308 #[cfg(feature = "query")]
309 pub use crate::actor::{process_reply, process_signed_query};
310 #[cfg(feature = "query")]
311 pub use crate::query::ReplyType;
312 pub use crate::{
313 actor::process_notice,
314 database::sled::SledEventDatabase,
315 event_message::signed_event_message::Message,
316 processor::{basic_processor::BasicProcessor, event_storage::EventStorage, Processor},
317 };
318 pub use said::version::{error::Error as VersionError, format::SerializationFormats};
319 pub use said::{
320 derivation::HashFunction, derivation::HashFunctionCode, SelfAddressingIdentifier,
321 };
322}