1use serde::{Deserialize, Serialize};
9use std::fmt;
10use std::str::FromStr;
11
12use super::permission::Permission;
13use crate::errors::ParseEnumError;
14
15#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, schemars::JsonSchema)]
16#[serde(rename_all = "lowercase")]
17pub enum JwtAudience {
18 Web,
19 Api,
20 A2a,
21 Mcp,
22 Internal,
23 Bridge,
24 Hook,
25 #[serde(untagged)]
26 Resource(String),
27}
28
29impl JwtAudience {
30 pub fn as_str(&self) -> &str {
31 match self {
32 Self::Web => "web",
33 Self::Api => "api",
34 Self::A2a => "a2a",
35 Self::Mcp => "mcp",
36 Self::Internal => "internal",
37 Self::Bridge => "bridge",
38 Self::Hook => "hook",
39 Self::Resource(s) => s.as_str(),
40 }
41 }
42
43 pub fn standard() -> Vec<Self> {
44 vec![Self::Web, Self::Api, Self::A2a, Self::Mcp]
45 }
46
47 pub fn service() -> Vec<Self> {
48 vec![Self::Api, Self::Mcp, Self::A2a, Self::Internal]
49 }
50}
51
52impl fmt::Display for JwtAudience {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54 write!(f, "{}", self.as_str())
55 }
56}
57
58impl FromStr for JwtAudience {
59 type Err = ParseEnumError;
60 fn from_str(s: &str) -> Result<Self, Self::Err> {
61 match s {
62 "web" => Ok(Self::Web),
63 "api" => Ok(Self::Api),
64 "a2a" => Ok(Self::A2a),
65 "mcp" => Ok(Self::Mcp),
66 "internal" => Ok(Self::Internal),
67 "bridge" => Ok(Self::Bridge),
68 "hook" => Ok(Self::Hook),
69 _ => Ok(Self::Resource(s.to_owned())),
70 }
71 }
72}
73
74#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
75#[serde(rename_all = "lowercase")]
76pub enum UserType {
77 Admin,
78 User,
79 A2a,
80 Mcp,
81 Service,
82 Anon,
83 Unknown,
84}
85
86impl UserType {
87 pub fn from_permissions(permissions: &[Permission]) -> Self {
93 let has = |p: Permission| permissions.contains(&p);
94 if has(Permission::Admin) {
95 Self::Admin
96 } else if has(Permission::User) {
97 Self::User
98 } else if has(Permission::A2a) {
99 Self::A2a
100 } else if has(Permission::Mcp) {
101 Self::Mcp
102 } else if has(Permission::Service)
103 || has(Permission::HookGovern)
104 || has(Permission::HookTrack)
105 {
106 Self::Service
107 } else {
108 Self::Anon
109 }
110 }
111
112 pub const fn as_str(&self) -> &'static str {
113 match self {
114 Self::Admin => "admin",
115 Self::User => "user",
116 Self::A2a => "a2a",
117 Self::Mcp => "mcp",
118 Self::Service => "service",
119 Self::Anon => "anon",
120 Self::Unknown => "unknown",
121 }
122 }
123
124 pub const fn rate_tier(&self) -> RateLimitTier {
125 match self {
126 Self::Admin => RateLimitTier::Admin,
127 Self::User => RateLimitTier::User,
128 Self::A2a => RateLimitTier::A2a,
129 Self::Mcp => RateLimitTier::Mcp,
130 Self::Service => RateLimitTier::Service,
131 Self::Anon | Self::Unknown => RateLimitTier::Anon,
132 }
133 }
134
135 #[must_use]
140 pub const fn reconcile_with(self, user_is_admin: bool) -> Self {
141 match self {
142 Self::Admin if !user_is_admin => Self::User,
143 other => other,
144 }
145 }
146}
147
148impl fmt::Display for UserType {
149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150 write!(f, "{}", self.as_str())
151 }
152}
153
154impl FromStr for UserType {
155 type Err = ParseEnumError;
156 fn from_str(s: &str) -> Result<Self, Self::Err> {
157 match s {
158 "admin" => Ok(Self::Admin),
159 "user" => Ok(Self::User),
160 "a2a" => Ok(Self::A2a),
161 "mcp" => Ok(Self::Mcp),
162 "service" => Ok(Self::Service),
163 "anon" => Ok(Self::Anon),
164 "unknown" => Ok(Self::Unknown),
165 _ => Err(ParseEnumError::new("user_type", s)),
166 }
167 }
168}
169
170#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
171pub enum TokenType {
172 #[default]
173 Bearer,
174}
175
176impl TokenType {
177 pub const fn as_str(self) -> &'static str {
178 match self {
179 Self::Bearer => "Bearer",
180 }
181 }
182}
183
184impl fmt::Display for TokenType {
185 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
186 write!(f, "Bearer")
187 }
188}
189
190#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
191#[serde(rename_all = "lowercase")]
192pub enum RateLimitTier {
193 Admin,
194 User,
195 A2a,
196 Mcp,
197 Service,
198 Anon,
199}
200
201impl RateLimitTier {
202 pub const fn as_str(&self) -> &'static str {
203 match self {
204 Self::Admin => "admin",
205 Self::User => "user",
206 Self::A2a => "a2a",
207 Self::Mcp => "mcp",
208 Self::Service => "service",
209 Self::Anon => "anon",
210 }
211 }
212}
213
214impl fmt::Display for RateLimitTier {
215 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
216 write!(f, "{}", self.as_str())
217 }
218}
219
220impl FromStr for RateLimitTier {
221 type Err = ParseEnumError;
222 fn from_str(s: &str) -> Result<Self, Self::Err> {
223 match s {
224 "admin" => Ok(Self::Admin),
225 "user" => Ok(Self::User),
226 "a2a" => Ok(Self::A2a),
227 "mcp" => Ok(Self::Mcp),
228 "service" => Ok(Self::Service),
229 "anon" => Ok(Self::Anon),
230 _ => Err(ParseEnumError::new("rate_limit_tier", s)),
231 }
232 }
233}
234
235#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
236#[serde(rename_all = "lowercase")]
237pub enum UserRole {
238 Admin,
239 User,
240 Anonymous,
241}
242
243impl UserRole {
244 pub const fn as_str(&self) -> &'static str {
245 match self {
246 Self::Admin => "admin",
247 Self::User => "user",
248 Self::Anonymous => "anonymous",
249 }
250 }
251}
252
253impl fmt::Display for UserRole {
254 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
255 write!(f, "{}", self.as_str())
256 }
257}
258
259impl FromStr for UserRole {
260 type Err = ParseEnumError;
261 fn from_str(s: &str) -> Result<Self, Self::Err> {
262 match s {
263 "admin" => Ok(Self::Admin),
264 "user" => Ok(Self::User),
265 "anonymous" => Ok(Self::Anonymous),
266 _ => Err(ParseEnumError::new("user_role", s)),
267 }
268 }
269}
270
271#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
272#[serde(rename_all = "lowercase")]
273pub enum UserStatus {
274 Active,
275 Inactive,
276 Suspended,
277 Pending,
278 Deleted,
279 Temporary,
280}
281
282impl UserStatus {
283 pub const fn as_str(&self) -> &'static str {
284 match self {
285 Self::Active => "active",
286 Self::Inactive => "inactive",
287 Self::Suspended => "suspended",
288 Self::Pending => "pending",
289 Self::Deleted => "deleted",
290 Self::Temporary => "temporary",
291 }
292 }
293
294 pub const fn is_active(&self) -> bool {
295 matches!(self, Self::Active)
296 }
297}
298
299impl fmt::Display for UserStatus {
300 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
301 write!(f, "{}", self.as_str())
302 }
303}
304
305impl FromStr for UserStatus {
306 type Err = ParseEnumError;
307 fn from_str(s: &str) -> Result<Self, Self::Err> {
308 match s {
309 "active" => Ok(Self::Active),
310 "inactive" => Ok(Self::Inactive),
311 "suspended" => Ok(Self::Suspended),
312 "pending" => Ok(Self::Pending),
313 "deleted" => Ok(Self::Deleted),
314 "temporary" => Ok(Self::Temporary),
315 _ => Err(ParseEnumError::new("user_status", s)),
316 }
317 }
318}