cataclysm_jwt/
jwt_session.rs1mod rs256_session;
2mod hs256_session;
3
4pub use rs256_session::{JWTRS256Session, JWTRS256Builder};
5pub use hs256_session::{JWTHS256Session, JWTHS256Builder};
6
7use crate::{Error, error::JWTError, JWT};
8
9use base64::{engine::general_purpose, Engine};
10use serde_json::Value;
11use std::collections::HashMap;
12use cataclysm::{session::SessionCreator, http::Request};
13
14pub trait JWTSession: Clone + SessionCreator {
21
22 fn initial_validation(&self, jwt: &JWT) -> Result<(),Error>;
24
25 fn deserialize_token(token: String) -> Result<JWT,Error> {
29
30 let token_parts: Vec<&str> = token.split('.').collect();
31
32 let header = match general_purpose::URL_SAFE_NO_PAD.decode(token_parts[0]) {
34 Ok(h) => match std::str::from_utf8(&h) {
35 Ok(h_s) => {
36
37 serde_json::from_str::<HashMap<String,Value>>(h_s).map_err(|e| Error::Serde(e))?.into_iter().map(|(k,v)| -> Result<(String,String),Error> {
38 let v = if v.is_string() {
39 v.as_str().ok_or(Error::JWT(JWTError::HeaderField))?.to_string()
40 } else {
41 v.to_string()
42 };
43 Ok((k,v))
44 }).collect::<Result<HashMap<String,String>,_>>()?
45
46 },
47 Err(e) => return Err(Error::UTF8(e))
48 },
49 Err(e) => return Err(Error::Decode(e, "Unable to decode jwt header into HashMap!"))
50 };
51
52 let payload: HashMap<String,String> = match general_purpose::URL_SAFE_NO_PAD.decode(token_parts[1]) {
54 Ok(p) => match std::str::from_utf8(&p) {
55 Ok(p_s) => {
56
57 serde_json::from_str::<HashMap<String,Value>>(p_s).map_err(|e| Error::Serde(e))?.into_iter().map(|(k,v)| -> Result<(String,String),Error> {
58 let v = if v.is_string() {
59 v.as_str().ok_or(Error::JWT(JWTError::PayloadField))?.to_string()
60 } else {
61 v.to_string()
62 };
63 Ok((k,v))
64 }).collect::<Result<HashMap<String,String>,_>>()?
65
66 },
67 Err(e) => return Err(Error::UTF8(e))
68 },
69 Err(e) => return Err(Error::Decode(e,"Unable to decode jwt payload into HashMap!"))
70 };
71
72 let signature = token_parts[2].to_string();
74
75 Ok(JWT {
76 header,
77 payload,
78 signature,
79 raw_jwt: token
80 })
81
82 }
83
84 fn obtain_token_from_req(req: &Request) -> Result<JWT,Error> {
86
87 let authorization_header = match req.headers.get("Authorization") {
89 Some(a) => a,
90 None => {
91 match req.headers.get("authorization") {
92 Some(a_t) => a_t,
93 None => {
94 return Err(Error::JWT(JWTError::Header));
95 }
96 }
97 }
98 };
99
100 let token: String = authorization_header[0].split(' ').collect::<Vec<&str>>()[1].to_string();
102 Self::deserialize_token(token)
103
104 }
105
106 fn build_from_req(&self, req: &Request) -> Result<HashMap<String,String>, Error>;
108
109}
110
111
112pub struct JWTSessionBuilder();
114
115impl JWTSessionBuilder {
116
117 pub fn with_rs256() -> JWTRS256Builder {
119 JWTRS256Builder::default()
120 }
121
122 pub fn with_hs256() -> JWTHS256Builder {
124 JWTHS256Builder::default()
125 }
126
127}
128