1use rocket::Request;
2
3pub const NCRYPTF_CONTENT_TYPE: &str = "application/vnd.ncryptf+json";
5
6pub const NCRYPTF_DRIFT_ALLOWANCE: i32 = 90;
8
9pub struct RequestPublicKey(pub Vec<u8>);
11
12pub struct RequestSigningPublicKey(pub Vec<u8>);
14
15mod json;
16pub use json::{respond_to_with_ncryptf, Error as JsonError, Json, JsonResponse, parse_body};
17mod ek;
18pub use ek::{EncryptionKey, ExportableEncryptionKeyData};
19mod auth;
20pub use auth::{AuthorizationTrait, TokenError, RequestData, *};
21
22use cached::{Cached, IOCached};
23use std::sync::{Arc, Mutex};
24
25pub enum CacheWrapper {
27 TimedCache(Arc<Mutex<cached::TimedCache<String, EncryptionKey>>>),
28 UnboundCache(Arc<Mutex<cached::UnboundCache<String, EncryptionKey>>>),
29 RedisCache(Arc<Mutex<cached::RedisCache<String, EncryptionKey>>>),
30}
31
32impl CacheWrapper {
33 pub fn get(&self, key: &str) -> Option<EncryptionKey> {
34 match self {
35 CacheWrapper::TimedCache(cache) => {
36 let mut guard = cache.lock().ok()?;
37 guard.cache_get(&key.to_string()).cloned()
38 }
39 CacheWrapper::UnboundCache(cache) => {
40 let mut guard = cache.lock().ok()?;
41 guard.cache_get(&key.to_string()).cloned()
42 }
43 CacheWrapper::RedisCache(cache) => {
44 let guard = cache.lock().ok()?;
45 match guard.cache_get(&key.to_string()) {
46 Ok(value) => value,
47 Err(_) => None,
48 }
49 }
50 }
51 }
52
53 pub fn set(&self, key: String, value: EncryptionKey) {
54 match self {
55 CacheWrapper::TimedCache(cache) => {
56 if let Ok(mut guard) = cache.lock() {
57 guard.cache_set(key, value);
58 }
59 }
60 CacheWrapper::UnboundCache(cache) => {
61 if let Ok(mut guard) = cache.lock() {
62 guard.cache_set(key, value);
63 }
64 }
65 CacheWrapper::RedisCache(cache) => {
66 if let Ok(guard) = cache.lock() {
67 let _ = guard.cache_set(key, value);
68 }
69 }
70 }
71 }
72
73 pub fn remove(&self, key: &str) -> Option<EncryptionKey> {
74 match self {
75 CacheWrapper::TimedCache(cache) => {
76 let mut guard = cache.lock().ok()?;
77 guard.cache_remove(&key.to_string())
78 }
79 CacheWrapper::UnboundCache(cache) => {
80 let mut guard = cache.lock().ok()?;
81 guard.cache_remove(&key.to_string())
82 }
83 CacheWrapper::RedisCache(cache) => {
84 let guard = cache.lock().ok()?;
85 match guard.cache_remove(&key.to_string()) {
86 Ok(value) => value,
87 Err(_) => None,
88 }
89 }
90 }
91 }
92}
93
94#[doc(hidden)]
97pub fn get_cache(req: &Request<'_>) -> Result<CacheWrapper, anyhow::Error> {
98 if let Some(cache) = req.rocket().state::<Arc<Mutex<cached::TimedCache<String, EncryptionKey>>>>() {
100 return Ok(CacheWrapper::TimedCache(cache.clone()));
101 }
102
103 if let Some(cache) = req.rocket().state::<Arc<Mutex<cached::UnboundCache<String, EncryptionKey>>>>() {
105 return Ok(CacheWrapper::UnboundCache(cache.clone()));
106 }
107
108 if let Some(cache) = req.rocket().state::<Arc<Mutex<cached::RedisCache<String, EncryptionKey>>>>() {
110 return Ok(CacheWrapper::RedisCache(cache.clone()));
111 }
112
113 Err(anyhow::anyhow!(
114 "No supported cache found in rocket state. Make sure to add your cache as managed state with .manage(Arc::new(Mutex::new(your_cache)))"
115 ))
116}