1use crate::error;
6use crate::error::Error;
7use crate::error::Error::DeserializationError;
8
9use base64::engine::general_purpose;
10use base64::Engine;
11use error::Result;
12#[cfg(feature = "mock_salts")]
13use lazy_static::lazy_static;
14use rand::prelude::ThreadRng;
15use rand::RngCore;
16use serde_json::Value;
17use sha2::Digest;
18#[cfg(feature = "mock_salts")]
19use std::{collections::VecDeque, sync::Mutex};
20
21#[cfg(feature = "mock_salts")]
22lazy_static! {
23 pub static ref SALTS: Mutex<VecDeque<String>> = Mutex::new(VecDeque::new());
24}
25
26#[doc(hidden)]
27pub fn base64_hash(data: &[u8]) -> String {
28 let mut hasher = sha2::Sha256::new();
29 hasher.update(data);
30 let hash = hasher.finalize();
31
32 general_purpose::URL_SAFE_NO_PAD.encode(hash)
33}
34
35pub(crate) fn base64url_encode(data: &[u8]) -> String {
36 general_purpose::URL_SAFE_NO_PAD.encode(data)
37}
38
39#[doc(hidden)]
40pub fn base64url_decode(b64data: &str) -> Result<Vec<u8>> {
41 general_purpose::URL_SAFE_NO_PAD
42 .decode(b64data)
43 .map_err(|e| Error::DeserializationError(e.to_string()))
44}
45
46pub(crate) fn generate_salt() -> String {
47 let mut buf = [0u8; 16];
48 ThreadRng::default().fill_bytes(&mut buf);
49 base64url_encode(&buf)
50}
51
52#[cfg(feature = "mock_salts")]
53pub(crate) fn generate_salt_mock() -> String {
54 let mut salts = SALTS.lock().unwrap();
55 return salts.pop_front().expect("SALTS is empty");
56}
57
58pub(crate) fn jwt_payload_decode(b64data: &str) -> Result<serde_json::Map<String, Value>> {
59 serde_json::from_str(
60 &String::from_utf8(
61 base64url_decode(b64data).map_err(|e| DeserializationError(e.to_string()))?,
62 )
63 .map_err(|e| DeserializationError(e.to_string()))?,
64 )
65 .map_err(|e| DeserializationError(e.to_string()))
66}