1use crate::{AuditData, AuditEvent, AuditLogFlags};
2use async_trait::async_trait;
3use binary_stream::futures::{
4 BinaryReader, BinaryWriter, Decodable, Encodable,
5};
6use sos_core::{
7 encoding::{decode_uuid, encoding_error},
8 UtcDateTime,
9};
10use std::io::{Error, Result};
11use tokio::io::{AsyncRead, AsyncSeek, AsyncWrite};
12
13#[async_trait]
14impl Encodable for AuditEvent {
15 async fn encode<W: AsyncWrite + AsyncSeek + Unpin + Send>(
16 &self,
17 writer: &mut BinaryWriter<W>,
18 ) -> Result<()> {
19 let flags = self.log_flags();
21 writer.write_u16(flags.bits()).await?;
22 self.time.encode(&mut *writer).await?;
24 self.event_kind.encode(&mut *writer).await?;
26 writer.write_bytes(self.account_id.as_ref()).await?;
28 if flags.contains(AuditLogFlags::DATA) {
30 let data = self.data.as_ref().unwrap();
31 data.encode(&mut *writer).await?;
32 }
33 Ok(())
34 }
35}
36
37#[async_trait]
38impl Decodable for AuditEvent {
39 async fn decode<R: AsyncRead + AsyncSeek + Unpin + Send>(
40 &mut self,
41 reader: &mut BinaryReader<R>,
42 ) -> Result<()> {
43 let bits = reader.read_u16().await?;
45 let mut timestamp: UtcDateTime = Default::default();
47 timestamp.decode(&mut *reader).await?;
48 self.time = timestamp;
49 self.event_kind.decode(&mut *reader).await?;
51 let address = reader.read_bytes(20).await?;
53 let address: [u8; 20] =
54 address.as_slice().try_into().map_err(encoding_error)?;
55 self.account_id = address.into();
56 if let Some(flags) = AuditLogFlags::from_bits(bits) {
58 if flags.contains(AuditLogFlags::DATA) {
59 if flags.contains(AuditLogFlags::DATA_VAULT) {
60 let vault_id = decode_uuid(&mut *reader).await?;
61 if !flags.contains(AuditLogFlags::DATA_SECRET) {
62 self.data = Some(AuditData::Vault(vault_id));
63 } else {
64 let secret_id = decode_uuid(&mut *reader).await?;
65 self.data =
66 Some(AuditData::Secret(vault_id, secret_id));
67 }
68 } else if flags.contains(AuditLogFlags::MOVE_SECRET) {
69 let from_vault_id = decode_uuid(&mut *reader).await?;
70 let from_secret_id = decode_uuid(&mut *reader).await?;
71 let to_vault_id = decode_uuid(&mut *reader).await?;
72 let to_secret_id = decode_uuid(&mut *reader).await?;
73 self.data = Some(AuditData::MoveSecret {
74 from_vault_id,
75 from_secret_id,
76 to_vault_id,
77 to_secret_id,
78 });
79 }
80 }
81 } else {
82 return Err(Error::other(
83 "log data flags has bad bits",
84 ));
85 }
86 Ok(())
87 }
88}
89
90#[async_trait]
91impl Encodable for AuditData {
92 async fn encode<W: AsyncWrite + AsyncSeek + Unpin + Send>(
93 &self,
94 writer: &mut BinaryWriter<W>,
95 ) -> Result<()> {
96 match self {
97 AuditData::Vault(vault_id) => {
98 writer.write_bytes(vault_id.as_bytes()).await?;
99 }
100 AuditData::Secret(vault_id, secret_id) => {
101 writer.write_bytes(vault_id.as_bytes()).await?;
102 writer.write_bytes(secret_id.as_bytes()).await?;
103 }
104 AuditData::MoveSecret {
105 from_vault_id,
106 from_secret_id,
107 to_vault_id,
108 to_secret_id,
109 } => {
110 writer.write_bytes(from_vault_id.as_bytes()).await?;
111 writer.write_bytes(from_secret_id.as_bytes()).await?;
112 writer.write_bytes(to_vault_id.as_bytes()).await?;
113 writer.write_bytes(to_secret_id.as_bytes()).await?;
114 }
115 AuditData::Device(public_key) => {
116 writer.write_bytes(public_key.as_ref()).await?;
117 }
118 }
119 Ok(())
120 }
121}