ncryptf/rocket/
ek.rs

1/// EkRoute provides a generic route which you can use to generate ephemeral (single use) encryption keys to bootstrap your request/response cycle within your application.
2///
3/// ### Setup
4///  1. Create a cache using one of the supported cache types:
5///
6///      ```rust
7///      use cached::{TimedCache, UnboundCache};
8///      use std::sync::{Arc, Mutex};
9///      use ncryptf::shared::{EncryptionKey};
10///      use ncryptf::rocket::{CacheWrapper};
11///
12///      // TimedCache with 1 hour expiration
13///      let timed_cache = Arc::new(Mutex::new(TimedCache::with_lifespan(3600)));
14///      let cache_wrapper = CacheWrapper::TimedCache(timed_cache);
15///
16///      // Or UnboundCache (no automatic expiration)
17///      let unbound_cache = Arc::new(Mutex::new(UnboundCache::new()));
18///      let cache_wrapper = CacheWrapper::UnboundCache(unbound_cache);
19///
20///      // Or RedisCache (requires redis feature)
21///      let redis_cache = Arc::new(Mutex::new(
22///          cached::RedisCache::new("redis://127.0.0.1/", std::time::Duration::from_secs(3600))
23///              .build().unwrap()
24///      ));
25///      let cache_wrapper = CacheWrapper::RedisCache(redis_cache);
26///      ```
27///
28///  2. Add the CacheWrapper as managed state to your Rocket instance:
29///
30///      ```rust
31///      let rocket = rocket::build()
32///          .manage(cache_wrapper)
33///          .mount("/ncryptf", routes![ncryptf_ek_route]);
34///      ```
35///
36///  3. Call the setup macro to instantiate the route:
37///
38///      ```rust
39///      ncryptf::ek_route!();
40///      ```
41///
42///  4. Mount the route `ncryptf_ek_route` exposed by the macro.
43///
44/// ### Features
45/// - **Unified Cache Interface**: Works with TimedCache, UnboundCache, and RedisCache through CacheWrapper
46/// - **Automatic Cache Management**: No need to manually handle different cache types
47/// - **Simple Integration**: Just manage a single CacheWrapper state instead of multiple cache types
48/// - **Parameterless Macro**: No arguments needed - the macro detects the managed cache automatically
49///
50/// Note: The CacheWrapper abstracts over all supported cache types: `TimedCache<String, EncryptionKey>`, `UnboundCache<String, EncryptionKey>`, and `RedisCache<String, EncryptionKey>`
51#[macro_export]
52macro_rules! ek_route {
53    () => {
54        use rocket::{get, http::Status, State};
55        use ncryptf::shared::{EncryptionKey, ExportableEncryptionKeyData};
56        use ncryptf::rocket::CacheWrapper;
57        use base64::{Engine as _, engine::general_purpose};
58
59        #[get("/ek")]
60        pub async fn ncryptf_ek_route(
61            cache: &State<CacheWrapper>,
62        ) -> Result<ncryptf::rocket::Json<ExportableEncryptionKeyData>, Status> {
63            let ek = EncryptionKey::new(true);
64
65            // Store the encryption key in the cache
66            cache.set(ek.get_hash_id(), ek.clone());
67
68            return Ok(ncryptf::rocket::Json(ExportableEncryptionKeyData {
69                public: general_purpose::STANDARD.encode(ek.get_box_kp().get_public_key()),
70                signature: general_purpose::STANDARD.encode(ek.get_sign_kp().get_public_key()),
71                hash_id: ek.get_hash_id(),
72                ephemeral: true,
73                expires_at: ek.expires_at,
74            }));
75        }
76    };
77}