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