objectstore_server/auth/
key_directory.rs1use std::collections::{BTreeMap, HashSet};
2use std::path::Path;
3
4use jsonwebtoken::DecodingKey;
5use objectstore_types::Permission;
6
7use crate::auth::AuthError;
8use crate::config::{AuthZ, AuthZVerificationKey};
9
10fn read_key_from_file(filename: &Path) -> Result<DecodingKey, AuthError> {
11 let key_content = std::fs::read_to_string(filename).map_err(|_| {
12 AuthError::InitFailure(format!("key could not be read from '{filename:?}'"))
13 })?;
14 DecodingKey::from_ed_pem(key_content.as_bytes())
15 .map_err(|_| AuthError::InitFailure("key could not be parsed".into()))
16}
17
18#[derive(Debug)]
22pub struct PublicKeyConfig {
23 pub key_versions: Vec<DecodingKey>,
29
30 pub max_permissions: HashSet<Permission>,
36}
37
38impl TryFrom<&AuthZVerificationKey> for PublicKeyConfig {
39 type Error = AuthError;
40 fn try_from(key_config: &AuthZVerificationKey) -> Result<Self, Self::Error> {
41 Ok(Self {
42 max_permissions: key_config.max_permissions.clone(),
43 key_versions: key_config
44 .key_files
45 .iter()
46 .map(|filename| read_key_from_file(filename))
47 .collect::<Result<Vec<DecodingKey>, AuthError>>()?,
48 })
49 }
50}
51
52#[derive(Debug)]
58pub struct PublicKeyDirectory {
59 pub keys: BTreeMap<String, PublicKeyConfig>,
61}
62
63impl TryFrom<&AuthZ> for PublicKeyDirectory {
64 type Error = AuthError;
65
66 fn try_from(auth_config: &AuthZ) -> Result<Self, Self::Error> {
67 Ok(Self {
68 keys: auth_config
69 .keys
70 .iter()
71 .map(|(kid, key)| Ok((kid.clone(), key.try_into()?)))
72 .collect::<Result<BTreeMap<String, PublicKeyConfig>, AuthError>>()?,
73 })
74 }
75}