Skip to main content

rauthy_client/
token_set.rs

1use crate::base64_url_no_pad_decode;
2use crate::rauthy_error::RauthyError;
3use crate::tokens::claims::IdToken;
4use serde::{Deserialize, Serialize};
5use std::borrow::Cow;
6use std::fmt::Debug;
7
8/// The token set returned upon a successful login flow
9#[derive(Debug, Serialize, Deserialize)]
10pub struct OidcTokenSet {
11    pub access_token: String,
12    pub token_type: Option<String>,
13    pub id_token: Option<String>,
14    pub expires_in: i32,
15    pub refresh_token: Option<String>,
16}
17
18impl OidcTokenSet {
19    /// Returns the user claims from the `id_token`.
20    ///
21    /// CAUTION: This does NOT validate the signature!
22    pub fn id_claims(&self) -> Result<Option<IdToken>, RauthyError> {
23        if let Some(raw_token) = &self.id_token {
24            let (_, rest) = raw_token.split_once('.').unwrap_or(("", ""));
25            let (claims_b64, _) = rest.split_once('.').unwrap_or(("", ""));
26            let bytes = base64_url_no_pad_decode(claims_b64)?;
27            let s = String::from_utf8_lossy(&bytes);
28            let claims = serde_json::from_str::<IdToken>(s.as_ref())?;
29            Ok(Some(claims))
30        } else {
31            Ok(None)
32        }
33    }
34
35    /// This function will return the claims from a given JWT token.
36    ///
37    /// CAUTION: It does NOT VALIDATE the token signature or any other values!
38    /// It will only try to decode the payload into the target struct.
39    pub fn danger_claims_unvalidated<T>(token: &str) -> Result<T, RauthyError>
40    where
41        T: Debug + for<'a> serde::de::Deserialize<'a>,
42    {
43        let mut split = token.split(".");
44
45        // The first part is the header
46        if split.next().is_none() {
47            return Err(RauthyError::Token(Cow::from(
48                "Bad format for raw token - header missing",
49            )));
50        }
51
52        // The second part are the claims we care about
53        let claims_b64 = match split.next() {
54            None => {
55                return Err(RauthyError::Token(Cow::from(
56                    "Bad format for raw token - claims missing",
57                )));
58            }
59            Some(s) => s,
60        };
61
62        let bytes = base64_url_no_pad_decode(claims_b64)?;
63        let s = String::from_utf8_lossy(&bytes);
64        let claims = serde_json::from_str::<T>(&s)?;
65
66        Ok(claims)
67    }
68}