coven_storage/
invite_storage.rs1use crate::{CloudProvider, S3Credentials, StorageError, StorageFailure, StorageInvitation};
4use coven_crypto::SecretBytes;
5use coven_format::code_fields::{pack, FieldReader};
6
7#[derive(Clone)]
10pub enum InviteStorage {
11 Account(StorageInvitation),
13 S3 {
15 invitation: StorageInvitation,
17 credentials: S3Credentials,
19 },
20}
21
22impl InviteStorage {
23 pub fn encode(&self) -> Result<SecretBytes, StorageError> {
27 let (invitation, credentials) = match self {
28 Self::Account(invitation) => (invitation, None),
29 Self::S3 { invitation, credentials } => (invitation, Some(credentials)),
30 };
31 if (invitation.location().provider() == CloudProvider::S3) != credentials.is_some() {
32 return Err(StorageFailure::InvalidConfiguration
33 .with_source("an S3 invite carries the member's key; no other invite does"));
34 }
35 if let Some(credentials) = credentials {
36 credentials.validate()?;
37 }
38 Ok(pack(|out| {
39 invitation.pack(out)?;
40 match credentials {
41 Some(credentials) => credentials.pack(out),
42 None => Ok(()),
43 }
44 })?)
45 }
46 pub fn decode(bytes: &[u8]) -> Result<Self, StorageError> {
49 let mut input = FieldReader::new(bytes)?;
50 let invitation = StorageInvitation::unpack(&mut input)?;
51 let storage = match invitation.location().provider() {
52 CloudProvider::S3 => {
53 Self::S3 { invitation, credentials: S3Credentials::unpack(&mut input)? }
54 }
55 _ => Self::Account(invitation),
56 };
57 input.finish()?;
58 Ok(storage)
59 }
60}
61
62#[cfg(test)]
63#[path = "invite_storage_tests.rs"]
64mod tests;