sos_core/encoding/v1/
events.rs

1use crate::{
2    crypto::AeadPack,
3    encoding::{decode_uuid, encoding_error},
4    events::{AccountEvent, DeviceEvent, EventKind, LogEvent, WriteEvent},
5    VaultCommit, VaultFlags,
6};
7#[cfg(feature = "files")]
8use crate::{events::FileEvent, SecretPath};
9
10use std::io::{Error, ErrorKind, Result};
11use tokio::io::{AsyncRead, AsyncSeek, AsyncWrite};
12
13use async_trait::async_trait;
14use binary_stream::futures::{
15    BinaryReader, BinaryWriter, Decodable, Encodable,
16};
17
18#[async_trait]
19impl Encodable for EventKind {
20    async fn encode<W: AsyncWrite + AsyncSeek + Unpin + Send>(
21        &self,
22        writer: &mut BinaryWriter<W>,
23    ) -> Result<()> {
24        let value: u16 = self.into();
25        writer.write_u16(value).await?;
26        Ok(())
27    }
28}
29
30#[async_trait]
31impl Decodable for EventKind {
32    async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
33        &mut self,
34        reader: &mut BinaryReader<R>,
35    ) -> Result<()> {
36        let op = reader.read_u16().await?;
37        *self = op.try_into().map_err(|_| {
38            Error::new(ErrorKind::Other, format!("unknown event kind {}", op))
39        })?;
40        Ok(())
41    }
42}
43
44/*
45#[async_trait]
46impl Encodable for EventRecord {
47    async fn encode<W: AsyncWrite + AsyncSeek + Unpin + Send>(
48        &self,
49        writer: &mut BinaryWriter<W>,
50    ) -> Result<()> {
51        // Prepare the bytes for the row length
52        let size_pos = writer.stream_position().await?;
53        writer.write_u32(0).await?;
54
55        // Encodable the time component
56        self.0.encode(&mut *writer).await?;
57
58        // Write the previous commit hash bytes
59        writer.write_bytes(self.1.as_ref()).await?;
60
61        // Write the commit hash bytes
62        writer.write_bytes(self.2.as_ref()).await?;
63
64        // FIXME: ensure the buffer size does not exceed u32
65
66        // Write the data bytes
67        writer.write_u32(self.3.len() as u32).await?;
68        writer.write_bytes(&self.3).await?;
69
70        // Backtrack to size_pos and write new length
71        let row_pos = writer.stream_position().await?;
72        let row_len = row_pos - (size_pos + 4);
73        writer.seek(SeekFrom::Start(size_pos)).await?;
74        writer.write_u32(row_len as u32).await?;
75        writer.seek(SeekFrom::Start(row_pos)).await?;
76
77        // Write out the row len at the end of the record too
78        // so we can support double ended iteration
79        writer.write_u32(row_len as u32).await?;
80
81        Ok(())
82    }
83}
84
85#[async_trait]
86impl Decodable for EventRecord {
87    async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
88        &mut self,
89        reader: &mut BinaryReader<R>,
90    ) -> Result<()> {
91        // Read in the row length
92        let _ = reader.read_u32().await?;
93
94        // Decodable the time component
95        let mut time: UtcDateTime = Default::default();
96        time.decode(&mut *reader).await?;
97
98        // Read the hash bytes
99        let previous: [u8; 32] = reader
100            .read_bytes(32)
101            .await?
102            .as_slice()
103            .try_into()
104            .map_err(encoding_error)?;
105        let commit: [u8; 32] = reader
106            .read_bytes(32)
107            .await?
108            .as_slice()
109            .try_into()
110            .map_err(encoding_error)?;
111
112        // Read the data bytes
113        let length = reader.read_u32().await?;
114        let buffer = reader.read_bytes(length as usize).await?;
115
116        self.0 = time;
117        self.1 = CommitHash(previous);
118        self.2 = CommitHash(commit);
119        self.3 = buffer;
120
121        // Read in the row length appended to the end of the record
122        let _ = reader.read_u32().await?;
123
124        Ok(())
125    }
126}
127*/
128
129#[async_trait]
130impl Encodable for WriteEvent {
131    async fn encode<W: AsyncWrite + AsyncSeek + Unpin + Send>(
132        &self,
133        writer: &mut BinaryWriter<W>,
134    ) -> Result<()> {
135        let op = self.event_kind();
136        op.encode(&mut *writer).await?;
137
138        match self {
139            WriteEvent::Noop => {
140                panic!("attempt to encode a noop")
141            }
142            WriteEvent::CreateVault(vault) => {
143                writer.write_u32(vault.len() as u32).await?;
144                writer.write_bytes(vault).await?;
145            }
146            WriteEvent::SetVaultName(name) => {
147                writer.write_string(name).await?;
148            }
149            WriteEvent::SetVaultFlags(flags) => {
150                writer.write_u64(flags.bits()).await?;
151            }
152            WriteEvent::SetVaultMeta(meta) => {
153                meta.encode(&mut *writer).await?;
154            }
155            WriteEvent::CreateSecret(uuid, value) => {
156                writer.write_bytes(uuid.as_bytes()).await?;
157                value.encode(&mut *writer).await?;
158            }
159            WriteEvent::UpdateSecret(uuid, value) => {
160                writer.write_bytes(uuid.as_bytes()).await?;
161                value.encode(&mut *writer).await?;
162            }
163            WriteEvent::DeleteSecret(uuid) => {
164                writer.write_bytes(uuid.as_bytes()).await?;
165            }
166        }
167        Ok(())
168    }
169}
170
171#[async_trait]
172impl Decodable for WriteEvent {
173    async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
174        &mut self,
175        reader: &mut BinaryReader<R>,
176    ) -> Result<()> {
177        let mut op: EventKind = Default::default();
178        op.decode(&mut *reader).await?;
179        match op {
180            EventKind::Noop => panic!("attempt to decode a noop"),
181            EventKind::CreateVault => {
182                let length = reader.read_u32().await?;
183                let buffer = reader.read_bytes(length as usize).await?;
184                *self = WriteEvent::CreateVault(buffer);
185            }
186            EventKind::SetVaultName => {
187                let name = reader.read_string().await?;
188                *self = WriteEvent::SetVaultName(name);
189            }
190            EventKind::SetVaultFlags => {
191                let flags = reader.read_u64().await?;
192                let flags =
193                    VaultFlags::from_bits(flags).ok_or_else(|| {
194                        Error::new(
195                            ErrorKind::Other,
196                            format!("invalid vault flags {}", flags),
197                        )
198                    })?;
199                *self = WriteEvent::SetVaultFlags(flags);
200            }
201            EventKind::SetVaultMeta => {
202                let mut aead_pack: AeadPack = Default::default();
203                aead_pack.decode(&mut *reader).await?;
204                *self = WriteEvent::SetVaultMeta(aead_pack);
205            }
206            EventKind::CreateSecret => {
207                let id = decode_uuid(&mut *reader).await?;
208                let mut commit: VaultCommit = Default::default();
209                commit.decode(&mut *reader).await?;
210                *self = WriteEvent::CreateSecret(id, commit);
211            }
212            EventKind::UpdateSecret => {
213                let id = decode_uuid(&mut *reader).await?;
214                let mut commit: VaultCommit = Default::default();
215                commit.decode(&mut *reader).await?;
216                *self = WriteEvent::UpdateSecret(id, commit);
217            }
218            EventKind::DeleteSecret => {
219                let id = decode_uuid(&mut *reader).await?;
220                *self = WriteEvent::DeleteSecret(id);
221            }
222            _ => {
223                return Err(Error::new(
224                    ErrorKind::Other,
225                    format!("unknown event kind {}", op),
226                ));
227            }
228        }
229        Ok(())
230    }
231}
232
233/*
234#[async_trait]
235impl Decodable for EventLogRecord {
236    async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
237        &mut self,
238        reader: &mut BinaryReader<R>,
239    ) -> Result<()> {
240        self.time.decode(&mut *reader).await?;
241        self.last_commit = reader
242            .read_bytes(32)
243            .await?
244            .as_slice()
245            .try_into()
246            .map_err(encoding_error)?;
247        self.commit = reader
248            .read_bytes(32)
249            .await?
250            .as_slice()
251            .try_into()
252            .map_err(encoding_error)?;
253        Ok(())
254    }
255}
256
257#[async_trait]
258impl Decodable for FileRecord {
259    async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
260        &mut self,
261        _reader: &mut BinaryReader<R>,
262    ) -> Result<()> {
263        Ok(())
264    }
265}
266
267#[async_trait]
268impl Decodable for VaultRecord {
269    async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
270        &mut self,
271        reader: &mut BinaryReader<R>,
272    ) -> Result<()> {
273        let id: [u8; 16] = reader
274            .read_bytes(16)
275            .await?
276            .as_slice()
277            .try_into()
278            .map_err(encoding_error)?;
279        let commit: [u8; 32] = reader
280            .read_bytes(32)
281            .await?
282            .as_slice()
283            .try_into()
284            .map_err(encoding_error)?;
285
286        self.id = id;
287        self.commit = commit;
288        Ok(())
289    }
290}
291*/
292
293#[async_trait]
294impl Encodable for AccountEvent {
295    async fn encode<W: AsyncWrite + AsyncSeek + Unpin + Send>(
296        &self,
297        writer: &mut BinaryWriter<W>,
298    ) -> Result<()> {
299        let op = self.event_kind();
300        op.encode(&mut *writer).await?;
301
302        match self {
303            AccountEvent::Noop => panic!("attempt to encode a noop"),
304            AccountEvent::RenameAccount(name) => {
305                writer.write_string(name).await?;
306            }
307            AccountEvent::UpdateIdentity(buffer) => {
308                writer.write_u32(buffer.len() as u32).await?;
309                writer.write_bytes(buffer).await?;
310            }
311            AccountEvent::UpdateFolder(id, buffer)
312            | AccountEvent::CompactFolder(id, buffer)
313            | AccountEvent::ChangeFolderPassword(id, buffer)
314            | AccountEvent::CreateFolder(id, buffer) => {
315                writer.write_bytes(id.as_bytes()).await?;
316                writer.write_u32(buffer.len() as u32).await?;
317                writer.write_bytes(buffer).await?;
318            }
319            AccountEvent::RenameFolder(id, name) => {
320                writer.write_bytes(id.as_bytes()).await?;
321                writer.write_string(name).await?;
322            }
323            AccountEvent::DeleteFolder(id) => {
324                writer.write_bytes(id.as_bytes()).await?;
325            }
326        }
327        Ok(())
328    }
329}
330
331#[async_trait]
332impl Decodable for AccountEvent {
333    async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
334        &mut self,
335        reader: &mut BinaryReader<R>,
336    ) -> Result<()> {
337        let mut op: EventKind = Default::default();
338        op.decode(&mut *reader).await?;
339        match op {
340            EventKind::Noop => panic!("attempt to decode a noop"),
341            EventKind::RenameAccount => {
342                *self =
343                    AccountEvent::RenameAccount(reader.read_string().await?);
344            }
345            EventKind::UpdateIdentity => {
346                let len = reader.read_u32().await?;
347                let buffer = reader.read_bytes(len as usize).await?;
348                *self = AccountEvent::UpdateIdentity(buffer)
349            }
350            EventKind::CreateVault => {
351                let id = decode_uuid(&mut *reader).await?;
352                let len = reader.read_u32().await?;
353                let buffer = reader.read_bytes(len as usize).await?;
354                *self = AccountEvent::CreateFolder(id, buffer)
355            }
356            EventKind::ChangePassword => {
357                let id = decode_uuid(&mut *reader).await?;
358                let len = reader.read_u32().await?;
359                let buffer = reader.read_bytes(len as usize).await?;
360                *self = AccountEvent::ChangeFolderPassword(id, buffer)
361            }
362            EventKind::UpdateVault => {
363                let id = decode_uuid(&mut *reader).await?;
364                let len = reader.read_u32().await?;
365                let buffer = reader.read_bytes(len as usize).await?;
366                *self = AccountEvent::UpdateFolder(id, buffer)
367            }
368            EventKind::CompactVault => {
369                let id = decode_uuid(&mut *reader).await?;
370                let len = reader.read_u32().await?;
371                let buffer = reader.read_bytes(len as usize).await?;
372                *self = AccountEvent::CompactFolder(id, buffer)
373            }
374            EventKind::SetVaultName => {
375                let id = decode_uuid(&mut *reader).await?;
376                let name = reader.read_string().await?;
377                *self = AccountEvent::RenameFolder(id, name);
378            }
379            EventKind::DeleteVault => {
380                let id = decode_uuid(&mut *reader).await?;
381                *self = AccountEvent::DeleteFolder(id);
382            }
383            _ => {
384                return Err(Error::new(
385                    ErrorKind::Other,
386                    format!("unknown account event kind {}", op),
387                ));
388            }
389        }
390        Ok(())
391    }
392}
393
394#[async_trait]
395impl Encodable for DeviceEvent {
396    async fn encode<W: AsyncWrite + AsyncSeek + Unpin + Send>(
397        &self,
398        writer: &mut BinaryWriter<W>,
399    ) -> Result<()> {
400        let op = self.event_kind();
401        op.encode(&mut *writer).await?;
402        match self {
403            DeviceEvent::Noop => panic!("attempt to encode a noop"),
404            DeviceEvent::Trust(device) => {
405                let buf = serde_json::to_vec(device)?;
406                writer.write_u32(buf.len() as u32).await?;
407                writer.write_bytes(&buf).await?;
408            }
409            DeviceEvent::Revoke(public_key) => {
410                writer.write_bytes(public_key.as_ref()).await?;
411            }
412        }
413        Ok(())
414    }
415}
416
417#[async_trait]
418impl Decodable for DeviceEvent {
419    async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
420        &mut self,
421        reader: &mut BinaryReader<R>,
422    ) -> Result<()> {
423        use crate::device::{DevicePublicKey, TrustedDevice};
424        let mut op: EventKind = Default::default();
425        op.decode(&mut *reader).await?;
426        match op {
427            EventKind::Noop => panic!("attempt to decode a noop"),
428            EventKind::TrustDevice => {
429                let len = reader.read_u32().await?;
430                let buf = reader.read_bytes(len as usize).await?;
431                let device: TrustedDevice = serde_json::from_slice(&buf)?;
432                *self = DeviceEvent::Trust(device);
433            }
434            EventKind::RevokeDevice => {
435                let public_key: [u8; DevicePublicKey::SIZE] = reader
436                    .read_bytes(DevicePublicKey::SIZE)
437                    .await?
438                    .as_slice()
439                    .try_into()
440                    .map_err(encoding_error)?;
441                *self = DeviceEvent::Revoke(public_key.into());
442            }
443            _ => {
444                return Err(Error::new(
445                    ErrorKind::Other,
446                    format!("unknown device event kind {}", op),
447                ));
448            }
449        }
450        Ok(())
451    }
452}
453
454#[cfg(feature = "files")]
455#[async_trait]
456impl Encodable for FileEvent {
457    async fn encode<W: AsyncWrite + AsyncSeek + Unpin + Send>(
458        &self,
459        writer: &mut BinaryWriter<W>,
460    ) -> Result<()> {
461        let op = self.event_kind();
462        op.encode(&mut *writer).await?;
463        match self {
464            FileEvent::Noop => panic!("attempt to encode a noop"),
465            FileEvent::CreateFile(owner, name)
466            | FileEvent::DeleteFile(owner, name) => {
467                writer.write_bytes(owner.0.as_bytes()).await?;
468                writer.write_bytes(owner.1.as_bytes()).await?;
469                writer.write_bytes(name.as_ref()).await?;
470            }
471            FileEvent::MoveFile { name, from, dest } => {
472                writer.write_bytes(name.as_ref()).await?;
473                writer.write_bytes(from.0.as_bytes()).await?;
474                writer.write_bytes(from.1.as_bytes()).await?;
475                writer.write_bytes(dest.0.as_bytes()).await?;
476                writer.write_bytes(dest.1.as_bytes()).await?;
477            }
478        }
479        Ok(())
480    }
481}
482
483#[cfg(feature = "files")]
484#[async_trait]
485impl Decodable for FileEvent {
486    async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
487        &mut self,
488        reader: &mut BinaryReader<R>,
489    ) -> Result<()> {
490        let mut op: EventKind = Default::default();
491        op.decode(&mut *reader).await?;
492        match op {
493            EventKind::Noop => panic!("attempt to decode a noop"),
494            EventKind::CreateFile => {
495                let folder_id = decode_uuid(&mut *reader).await?;
496                let secret_id = decode_uuid(&mut *reader).await?;
497                let name = reader.read_bytes(32).await?;
498                let name: [u8; 32] =
499                    name.as_slice().try_into().map_err(encoding_error)?;
500                *self = FileEvent::CreateFile(
501                    SecretPath(folder_id, secret_id),
502                    name.into(),
503                )
504            }
505            EventKind::DeleteFile => {
506                let folder_id = decode_uuid(&mut *reader).await?;
507                let secret_id = decode_uuid(&mut *reader).await?;
508                let name = reader.read_bytes(32).await?;
509                let name: [u8; 32] =
510                    name.as_slice().try_into().map_err(encoding_error)?;
511                *self = FileEvent::DeleteFile(
512                    SecretPath(folder_id, secret_id),
513                    name.into(),
514                )
515            }
516            EventKind::MoveFile => {
517                let name = reader.read_bytes(32).await?;
518                let name: [u8; 32] =
519                    name.as_slice().try_into().map_err(encoding_error)?;
520                let from = SecretPath(
521                    decode_uuid(&mut *reader).await?,
522                    decode_uuid(&mut *reader).await?,
523                );
524                let dest = SecretPath(
525                    decode_uuid(&mut *reader).await?,
526                    decode_uuid(&mut *reader).await?,
527                );
528                *self = FileEvent::MoveFile {
529                    name: name.into(),
530                    from,
531                    dest,
532                }
533            }
534            _ => {
535                return Err(Error::new(
536                    ErrorKind::Other,
537                    format!("unknown file event kind {}", op),
538                ));
539            }
540        }
541        Ok(())
542    }
543}