use async_trait::async_trait; use json::JsonValue; use serde::Deserialize; #[async_trait] pub trait Store { async fn is_auth(&mut self, data: &Credentials) -> bool; } #[derive(Default, Debug, Deserialize)] pub struct Credentials { email: String, password: String, } /// Credentials represents the incoming user credentials for authentication checking impl Credentials { pub fn new(email: String, password: String) -> Self { Credentials { email, password } } pub fn get_email(&self) -> String { self.email.clone() } pub fn get_password(&self) -> String { self.password.clone() } pub fn is_empty(&self) -> bool { self.email == "" || self.password == "" } } // TODO: could be less restrictive with `From<&str>` impl From<&JsonValue> for Credentials { fn from(data: &JsonValue) -> Self { let res = serde_json::from_str(&data.dump()); match res { Ok(c) => c, Err(e) => { log::warn!("unable to deserialize credentials: {}", e); return Credentials::default(); } } } } #[test] fn test_credentials() { struct Expect { data: JsonValue, is_empty: bool, } let test_cases: [Expect; 2] = [ Expect { data: json::parse(r#"{"access_token":"AAAAAAAAAAAA.BBBBBBBBBB.CCCCCCCCCC","refresh_token": "DDDDDDDDDDD.EEEEEEEEEEE.FFFFF"}"#).unwrap(), is_empty: true }, Expect { data: json::parse(r#"{"email":"toto@toto.fr","password": "tata"}"#).unwrap(), is_empty: false } ]; for t in test_cases { let credentials = Credentials::from(&t.data); assert_eq!(t.is_empty, credentials.is_empty()) } }