Skip to main content

systemprompt_models/auth/
claims.rs

1use serde::{Deserialize, Serialize};
2use std::str::FromStr;
3
4use super::{
5    parse_permissions, permissions_to_string, JwtAudience, Permission, RateLimitTier, TokenType,
6    UserType,
7};
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct JwtClaims {
11    pub sub: String,
12    pub iat: i64,
13    pub exp: i64,
14    pub iss: String,
15    #[serde(
16        serialize_with = "serialize_audiences",
17        deserialize_with = "deserialize_audiences"
18    )]
19    pub aud: Vec<JwtAudience>,
20    pub jti: String,
21
22    #[serde(
23        serialize_with = "serialize_scope",
24        deserialize_with = "deserialize_scope"
25    )]
26    pub scope: Vec<Permission>,
27
28    pub username: String,
29    pub email: String,
30    pub user_type: UserType,
31
32    #[serde(default, skip_serializing_if = "Vec::is_empty")]
33    pub roles: Vec<String>,
34
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub client_id: Option<String>,
37    pub token_type: TokenType,
38    pub auth_time: i64,
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub session_id: Option<String>,
41
42    #[serde(skip_serializing_if = "Option::is_none")]
43    pub rate_limit_tier: Option<RateLimitTier>,
44}
45
46fn serialize_audiences<S>(auds: &[JwtAudience], s: S) -> Result<S::Ok, S::Error>
47where
48    S: serde::Serializer,
49{
50    use serde::ser::SerializeSeq;
51    let mut seq = s.serialize_seq(Some(auds.len()))?;
52    for aud in auds {
53        seq.serialize_element(aud.as_str())?;
54    }
55    seq.end()
56}
57
58fn deserialize_audiences<'de, D>(d: D) -> Result<Vec<JwtAudience>, D::Error>
59where
60    D: serde::Deserializer<'de>,
61{
62    let strings: Vec<String> = Vec::deserialize(d)?;
63    strings
64        .iter()
65        .map(|s| JwtAudience::from_str(s).map_err(serde::de::Error::custom))
66        .collect()
67}
68
69fn serialize_scope<S>(permissions: &[Permission], s: S) -> Result<S::Ok, S::Error>
70where
71    S: serde::Serializer,
72{
73    s.serialize_str(&permissions_to_string(permissions))
74}
75
76fn deserialize_scope<'de, D>(d: D) -> Result<Vec<Permission>, D::Error>
77where
78    D: serde::Deserializer<'de>,
79{
80    let scope_string: String = String::deserialize(d)?;
81    parse_permissions(&scope_string).map_err(serde::de::Error::custom)
82}
83
84impl JwtClaims {
85    pub fn has_permission(&self, permission: Permission) -> bool {
86        self.scope.contains(&permission)
87    }
88
89    pub fn permissions(&self) -> &[Permission] {
90        &self.scope
91    }
92
93    pub fn get_permissions(&self) -> Vec<Permission> {
94        self.scope.clone()
95    }
96
97    pub fn get_scopes(&self) -> Vec<String> {
98        self.scope.iter().map(ToString::to_string).collect()
99    }
100
101    pub fn is_admin(&self) -> bool {
102        self.has_permission(Permission::Admin)
103    }
104
105    pub fn is_registered_user(&self) -> bool {
106        self.has_permission(Permission::User)
107    }
108
109    pub fn is_anonymous(&self) -> bool {
110        self.has_permission(Permission::Anonymous)
111    }
112
113    pub fn has_audience(&self, aud: JwtAudience) -> bool {
114        self.aud.contains(&aud)
115    }
116
117    pub fn has_role(&self, role: &str) -> bool {
118        self.roles.iter().any(|r| r == role)
119    }
120
121    pub fn roles(&self) -> &[String] {
122        &self.roles
123    }
124}