use crate::errors::{BottleError, Result};
use crate::idcard::IDCard;
use crate::signing::Sign;
use rand::RngCore;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Membership {
member_idcard: Vec<u8>, group_public_key: Vec<u8>,
info: HashMap<String, String>,
signature: Option<Vec<u8>>,
}
impl Membership {
pub fn new(member_idcard: &IDCard, group_public_key: &[u8]) -> Self {
Self {
member_idcard: member_idcard.to_bytes().unwrap_or_default(), group_public_key: group_public_key.to_vec(),
info: HashMap::new(),
signature: None,
}
}
pub fn set_info(&mut self, key: &str, value: &str) {
self.info.insert(key.to_string(), value.to_string());
}
pub fn info(&self, key: &str) -> Option<&str> {
self.info.get(key).map(|s| s.as_str())
}
pub fn sign<R: RngCore>(&mut self, rng: &mut R, signer: &dyn Sign) -> Result<Vec<u8>> {
let data_to_sign = self.create_signing_data()?;
let signature = signer.sign(rng, &data_to_sign)?;
self.signature = Some(signature.clone());
self.to_bytes()
}
pub fn verify(&self, _group_idcard: &IDCard) -> Result<()> {
if self.signature.is_none() {
return Err(BottleError::VerifyFailed);
}
Ok(())
}
fn create_signing_data(&self) -> Result<Vec<u8>> {
let mut membership = self.clone();
membership.signature = None;
bincode::serialize(&membership).map_err(|e| {
BottleError::Serialization(format!("Failed to serialize membership: {}", e))
})
}
pub fn to_bytes(&self) -> Result<Vec<u8>> {
bincode::serialize(self).map_err(|e| {
BottleError::Serialization(format!("Failed to serialize membership: {}", e))
})
}
pub fn from_bytes(data: &[u8]) -> Result<Self> {
bincode::deserialize(data).map_err(|e| {
BottleError::Deserialization(format!("Failed to deserialize membership: {}", e))
})
}
}