1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
use crate::Error; use chrono::{Duration, Utc}; use jsonwebtoken::{DecodingKey, EncodingKey, Header, Validation}; use serde::{de::DeserializeOwned, ser::Serialize}; use serde_json::value::RawValue; use std::sync::Arc; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct WebToken { pub body: Box<RawValue>, pub body_type: String, pub exp: usize, } pub trait AccessTokenBody: Serialize + DeserializeOwned { fn type_name() -> &'static str { std::any::type_name::<Self>() } } impl WebToken { pub fn new<B>(body: &B, valid_dur: Duration) -> Result<Self, Error> where B: AccessTokenBody, { let exp = (Utc::now() + valid_dur).timestamp() as usize; let serialized_body = serde_json::to_string(body).map_err(Error::internal)?; let raw_val = RawValue::from_string(serialized_body).map_err(Error::internal)?; Ok(WebToken { body: raw_val, body_type: std::any::type_name::<B>().to_string(), exp, }) } pub fn get_body<B>(&self) -> Result<B, Error> where B: AccessTokenBody, { if self.body_type != std::any::type_name::<B>() { return Err(Error::bad_input(format!( "body type is not {}", std::any::type_name::<B>() ))); } Ok(serde_json::from_str::<B>(self.body.get()).map_err(Error::internal)?) } } #[derive(Debug, Clone)] pub struct JwtEncoder { inner: Arc<Inner>, } impl JwtEncoder { pub fn from_secret(secret: &[u8]) -> JwtEncoder { JwtEncoder { inner: Arc::new(Inner::from_secret(secret)), } } pub fn encode(&self, token: &WebToken) -> Result<String, Error> { self.inner.encode(token) } pub fn decode(&self, token: &str) -> Result<WebToken, Error> { self.inner.decode(token) } } #[derive(Debug)] struct Inner { encoding_key: EncodingKey, decoding_key: DecodingKey<'static>, } impl Inner { fn from_secret(secret: &[u8]) -> Inner { Inner { encoding_key: EncodingKey::from_secret(secret), decoding_key: DecodingKey::from_secret(secret).into_static(), } } fn encode(&self, token: &WebToken) -> Result<String, Error> { jsonwebtoken::encode(&Header::default(), token, &self.encoding_key).map_err(Error::internal) } fn decode(&self, token: &str) -> Result<WebToken, Error> { let res = jsonwebtoken::decode::<WebToken>(token, &self.decoding_key, &Validation::default()) .map_err(Error::internal)?; Ok(res.claims) } }