From c25329785de5ce1b72745cbc4b1ff6230e2d1646 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Thu, 2 May 2019 16:56:47 +0200 Subject: [PATCH] allow generic payloads in stateless tokens --- src/tokens.rs | 23 ++++++++++++----------- src/web/manage.rs | 4 ++-- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/tokens.rs b/src/tokens.rs index 22080cc..7a6f159 100644 --- a/src/tokens.rs +++ b/src/tokens.rs @@ -1,11 +1,9 @@ use sealed_state::SealedState; -use database::types::{Fingerprint}; use serde_json; +use serde::{Serialize,de::DeserializeOwned}; use Result; -const REVISION: u8 = 1; - pub struct Service { sealed_state: SealedState, validity: u64, @@ -13,12 +11,10 @@ pub struct Service { #[derive(Serialize,Deserialize)] struct Token { - #[serde(rename = "f")] - fpr: Fingerprint, #[serde(rename = "c")] creation: u64, - #[serde(rename = "r")] - revision: u8, + #[serde(rename = "p")] + payload: String, } impl Service { @@ -27,9 +23,10 @@ impl Service { Service { sealed_state, validity } } - pub fn create(&self, fpr: &Fingerprint) -> String { + pub fn create(&self, payload_content: impl Serialize) -> String { + let payload = serde_json::to_string(&payload_content).unwrap(); let creation = current_time(); - let token = Token { fpr: fpr.clone(), creation, revision: REVISION }; + let token = Token { creation, payload }; let token_serialized = serde_json::to_string(&token).unwrap(); let token_sealed = self.sealed_state.seal(&token_serialized); @@ -37,7 +34,8 @@ impl Service { base64::encode_config(&token_sealed, base64::URL_SAFE_NO_PAD) } - pub fn check(&self, token_encoded: &str) -> Result { + pub fn check(&self, token_encoded: &str) -> Result + where T: DeserializeOwned { let token_sealed = base64::decode_config(&token_encoded, base64::URL_SAFE_NO_PAD) .map_err(|_| failure::err_msg("invalid b64"))?; let token_str = self.sealed_state.unseal(token_sealed) @@ -50,7 +48,10 @@ impl Service { Err(failure::err_msg("Token has expired!"))?; } - Ok(token.fpr) + let payload: T = serde_json::from_str(&token.payload) + .map_err(|_| failure::err_msg("failed to deserialize payload"))?; + + Ok(payload) } } diff --git a/src/web/manage.rs b/src/web/manage.rs index b15f5ef..34e9fcf 100644 --- a/src/web/manage.rs +++ b/src/web/manage.rs @@ -5,7 +5,7 @@ use rocket::request::Form; use failure::Fallible as Result; use web::{HagridState, MyResponse, templates::General}; -use database::{Database, KeyDatabase, types::Email}; +use database::{Database, KeyDatabase, types::Email, types::Fingerprint}; use mail; use tokens; @@ -121,7 +121,7 @@ pub fn vks_manage_post( Err(e) => return MyResponse::ise(e), }; - let fpr = tpk.fingerprint().try_into().unwrap(); + let fpr: Fingerprint = tpk.fingerprint().try_into().unwrap(); let token = token_service.create(&fpr); let token_uri = uri!(vks_manage_key: token).to_string(); if let Some(mail_service) = mail_service {