extern crate biscuit_auth as biscuit;
use biscuit::macros::block;
use hessra_token_core::{Biscuit, PublicKey, TokenError, utils};
pub struct DesignationBuilder {
token: Vec<u8>,
public_key: PublicKey,
designations: Vec<(String, String)>,
}
impl DesignationBuilder {
pub fn new(token: Vec<u8>, public_key: PublicKey) -> Self {
Self {
token,
public_key,
designations: Vec::new(),
}
}
pub fn from_base64(token: String, public_key: PublicKey) -> Result<Self, TokenError> {
let token_bytes = utils::decode_token(&token)?;
Ok(Self::new(token_bytes, public_key))
}
pub fn designate(mut self, label: String, value: String) -> Self {
self.designations.push((label, value));
self
}
pub fn attenuate(self) -> Result<Vec<u8>, TokenError> {
let biscuit = Biscuit::from(&self.token, self.public_key)?;
let mut block_builder = block!(r#""#);
for (label, value) in &self.designations {
let label = label.clone();
let value = value.clone();
block_builder = block_builder
.check(biscuit::macros::check!(
r#"check if designation({label}, {value});"#
))
.map_err(|e| TokenError::AttenuationFailed {
reason: format!("Failed to add designation check: {e}"),
})?;
}
let attenuated =
biscuit
.append(block_builder)
.map_err(|e| TokenError::AttenuationFailed {
reason: format!("Failed to append designation block: {e}"),
})?;
attenuated
.to_vec()
.map_err(|e| TokenError::AttenuationFailed {
reason: format!("Failed to serialize attenuated token: {e}"),
})
}
pub fn attenuate_base64(self) -> Result<String, TokenError> {
let bytes = self.attenuate()?;
Ok(utils::encode_token(&bytes))
}
}