menmos_auth/lib.rs
1//! Menmos authentication library
2mod storage_node_identity;
3mod user_identity;
4
5pub use storage_node_identity::StorageNodeIdentity;
6pub use user_identity::UserIdentity;
7
8use std::fmt::Debug;
9
10use branca::Branca;
11
12use serde::{Deserialize, Serialize};
13
14const TOKEN_TTL_SECONDS: u32 = 60 * 60 * 6; // 6 hours.
15
16/// The encryption key format that is expected by menmos_auth.
17///
18/// For the axum handlers, menmos_auth gets this structure from an extension layer that must be
19/// set manually in your axum router.
20#[derive(Clone, PartialEq, Eq)]
21pub struct EncryptionKey {
22 pub key: String,
23}
24
25/// Generate a signed token from an encryption key and a serializable payload.
26///
27/// The generated token will be valid for six hours.
28///
29/// The encryption key *must* be exactly 32 characters long, else an error will be returned.
30///
31/// # Examples
32/// ```
33/// use serde::Serialize;
34///
35/// #[derive(Serialize)]
36/// struct UserInfo {
37/// username: String,
38/// is_admin: bool
39/// }
40///
41/// let encryption_key = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; // 32 characters.
42/// let token_data = UserInfo{username: "johnsmith".into(), is_admin: true};
43///
44/// let token = menmos_auth::make_token(encryption_key, &token_data)?;
45/// # Ok::<(), anyhow::Error>(())
46/// ```
47pub fn make_token<K: AsRef<str>, D: Serialize>(key: K, data: D) -> anyhow::Result<String> {
48 let mut token = Branca::new(key.as_ref().as_bytes())?;
49 token
50 .set_ttl(TOKEN_TTL_SECONDS)
51 .set_timestamp(time::OffsetDateTime::now_utc().unix_timestamp() as u32);
52
53 let encoded_body = bincode::serialize(&data)?;
54 Ok(token.encode(&encoded_body)?)
55}
56
57#[derive(Debug, Default, Deserialize, Serialize)]
58struct Signature {
59 pub signature: Option<String>,
60}