objectstore_server/auth/
key_directory.rs1use std::collections::{BTreeMap, HashSet};
2use std::path::Path;
3
4use anyhow::Context;
5use jsonwebtoken::DecodingKey;
6use objectstore_types::auth::Permission;
7
8use crate::config::{AuthZ, AuthZVerificationKey};
9
10fn read_key_from_file(filename: &Path) -> anyhow::Result<DecodingKey> {
11 let key_content = std::fs::read_to_string(filename)
12 .with_context(|| format!("reading key from {:?}", filename))?;
13 DecodingKey::from_ed_pem(key_content.as_bytes())
14 .with_context(|| format!("parsing key from {:?}", filename))
15}
16
17#[derive(Debug)]
21pub struct PublicKeyConfig {
22 pub key_versions: Vec<DecodingKey>,
28
29 pub max_permissions: HashSet<Permission>,
35}
36
37impl TryFrom<&AuthZVerificationKey> for PublicKeyConfig {
38 type Error = anyhow::Error;
39
40 fn try_from(key_config: &AuthZVerificationKey) -> Result<Self, anyhow::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| {
47 read_key_from_file(filename).inspect_err(|e| objectstore_log::error!("{:?}", e))
48 })
49 .collect::<anyhow::Result<Vec<DecodingKey>>>()?,
50 })
51 }
52}
53
54#[derive(Debug)]
61pub struct PublicKeyDirectory {
62 pub keys: BTreeMap<String, PublicKeyConfig>,
64}
65
66impl TryFrom<&AuthZ> for PublicKeyDirectory {
67 type Error = anyhow::Error;
68
69 fn try_from(auth_config: &AuthZ) -> Result<Self, Self::Error> {
70 Ok(Self {
71 keys: auth_config
72 .keys
73 .iter()
74 .map(|(kid, key)| Ok((kid.clone(), key.try_into()?)))
75 .collect::<Result<BTreeMap<String, PublicKeyConfig>, anyhow::Error>>()?,
76 })
77 }
78}