1use super::callbacks::{
2 ApiKeyDefaultPermissions, ApiKeyGenerator, ApiKeyGetter, ApiKeyPermissions, ApiKeyValidator,
3};
4use super::storage::{ApiKeyStorage, ApiKeyStorageMode};
5use std::sync::Arc;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
9pub enum ApiKeyReferences {
10 #[default]
12 User,
13 Organization,
16}
17
18#[derive(Clone)]
20#[expect(
21 clippy::struct_excessive_bools,
22 reason = "Independent configuration switches model distinct upstream behavior, rather than mutually exclusive states"
23)]
24pub struct ApiKeyConfig {
25 pub config_id: String,
28 pub references: ApiKeyReferences,
31
32 pub storage: ApiKeyStorageMode,
34 pub fallback_to_database: bool,
36 pub secondary_storage: Option<Arc<dyn alibi_core::store::CacheAdapter>>,
38 pub custom_storage: Option<Arc<dyn ApiKeyStorage>>,
40
41 pub key_length: f64,
45 pub prefix: Option<String>,
46 pub default_permissions: Option<ApiKeyPermissions>,
48 pub custom_key_generator: Option<Arc<dyn ApiKeyGenerator>>,
50 pub default_permissions_callback: Option<Arc<dyn ApiKeyDefaultPermissions>>,
52
53 pub api_key_headers: Vec<String>,
54 pub custom_api_key_getter: Option<Arc<dyn ApiKeyGetter>>,
56 pub custom_api_key_validator: Option<Arc<dyn ApiKeyValidator>>,
58
59 pub disable_key_hashing: bool,
60
61 pub starting_characters_length: f64,
65 pub store_starting_characters: bool,
66
67 pub max_prefix_length: f64,
69 pub min_prefix_length: f64,
71
72 pub max_name_length: f64,
74 pub min_name_length: f64,
76 pub require_name: bool,
77
78 pub enable_metadata: bool,
79
80 pub key_expiration: KeyExpirationConfig,
81
82 pub rate_limit: RateLimitDefaults,
83
84 pub enable_session_for_api_keys: bool,
85 pub defer_updates: bool,
90}
91
92impl ApiKeyConfig {
93 pub(in crate::api_key) const fn normalized(mut self) -> Self {
94 if self.key_length == 0.0 || self.key_length.is_nan() {
96 self.key_length = 64.0;
97 }
98 self
99 }
100}
101
102impl std::fmt::Debug for ApiKeyConfig {
103 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
104 f.debug_struct("ApiKeyConfig")
105 .field("config_id", &self.config_id)
106 .field("references", &self.references)
107 .field("key_length", &self.key_length)
108 .field("prefix", &self.prefix)
109 .field("custom_key_generator", &self.custom_key_generator.is_some())
110 .field(
111 "default_permissions_callback",
112 &self.default_permissions_callback.is_some(),
113 )
114 .field("api_key_headers", &self.api_key_headers)
115 .field(
116 "custom_api_key_getter",
117 &self.custom_api_key_getter.is_some(),
118 )
119 .field(
120 "custom_api_key_validator",
121 &self.custom_api_key_validator.is_some(),
122 )
123 .field(
124 "enable_session_for_api_keys",
125 &self.enable_session_for_api_keys,
126 )
127 .field("storage", &self.storage)
128 .field("fallback_to_database", &self.fallback_to_database)
129 .field("secondary_storage", &self.secondary_storage.is_some())
130 .field("custom_storage", &self.custom_storage.is_some())
131 .field("defer_updates", &self.defer_updates)
132 .finish_non_exhaustive()
133 }
134}
135
136#[derive(Debug, Clone)]
138pub struct KeyExpirationConfig {
139 pub default_expires_in: Option<f64>,
143 pub disable_custom_expires_time: bool,
145 pub max_expires_in: f64,
147 pub min_expires_in: f64,
149}
150
151impl Default for KeyExpirationConfig {
152 fn default() -> Self {
153 Self {
154 default_expires_in: None,
155 disable_custom_expires_time: false,
156 max_expires_in: 365.0,
157 min_expires_in: 1.0,
158 }
159 }
160}
161
162#[derive(Debug, Clone)]
164pub struct RateLimitDefaults {
165 pub enabled: bool,
166 pub time_window: f64,
168 pub max_requests: f64,
170}
171
172impl Default for RateLimitDefaults {
173 fn default() -> Self {
174 Self {
175 enabled: true,
176 time_window: 86_400_000.0, max_requests: 10.0,
178 }
179 }
180}
181
182impl Default for ApiKeyConfig {
183 fn default() -> Self {
184 Self {
185 storage: ApiKeyStorageMode::Database,
186 fallback_to_database: false,
187 custom_storage: None,
188 secondary_storage: None,
189 config_id: "default".to_owned(),
190 references: ApiKeyReferences::default(),
191 key_length: 64.0,
192 prefix: None,
193 default_permissions: None,
194 custom_key_generator: None,
195 default_permissions_callback: None,
196 api_key_headers: vec!["x-api-key".to_owned()],
197 custom_api_key_getter: None,
198 custom_api_key_validator: None,
199 disable_key_hashing: false,
200 starting_characters_length: 6.0,
201 store_starting_characters: true,
202 max_prefix_length: 32.0,
203 min_prefix_length: 1.0,
204 max_name_length: 32.0,
205 min_name_length: 1.0,
206 require_name: false,
207 enable_metadata: false,
208 key_expiration: KeyExpirationConfig::default(),
209 rate_limit: RateLimitDefaults::default(),
210 enable_session_for_api_keys: false,
211 defer_updates: false,
212 }
213 }
214}