feat: #8 impl a credentials store
This commit is contained in:
parent
2c7418f333
commit
8bf503df14
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -123,6 +123,17 @@ version = "4.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524"
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atomic-waker"
|
||||
version = "1.0.0"
|
||||
@ -504,6 +515,7 @@ name = "simple-auth"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"async-trait",
|
||||
"json",
|
||||
"lazy_static",
|
||||
"regex",
|
||||
|
||||
@ -10,6 +10,7 @@ json = "0.12.4"
|
||||
lazy_static = "1.4.0"
|
||||
regex = "1"
|
||||
tokio = { version = "1.21.1", features = ["full"] }
|
||||
async-trait = "0.1.57"
|
||||
|
||||
[dependencies.async-std]
|
||||
version = "1.6"
|
||||
|
||||
@ -68,6 +68,8 @@ impl From<HTTPRequest> for HTTPResponse {
|
||||
return response;
|
||||
}
|
||||
|
||||
// TODO: impl a valid credentials in `Store`
|
||||
|
||||
let body = json::parse(
|
||||
r#"{"token": "header.payload.signature", "refresh": "header.payload.signature"}"#,
|
||||
)
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
mod handlers;
|
||||
mod stores;
|
||||
|
||||
use tokio::{
|
||||
io::{AsyncReadExt, AsyncWriteExt},
|
||||
|
||||
68
src/stores/file.rs
Normal file
68
src/stores/file.rs
Normal file
@ -0,0 +1,68 @@
|
||||
use async_trait::async_trait;
|
||||
use json;
|
||||
use json::object::Object;
|
||||
use std::path::Path;
|
||||
|
||||
use tokio::fs::File;
|
||||
use tokio::io::AsyncReadExt; // for read_to_end()
|
||||
|
||||
use super::store::{Credentials, Store};
|
||||
|
||||
/// FileStore references a `store` file
|
||||
pub struct FileStore {
|
||||
path: String,
|
||||
}
|
||||
|
||||
impl FileStore {
|
||||
fn new(path: String) -> Self {
|
||||
FileStore { path }
|
||||
}
|
||||
|
||||
async fn parse_contents(&self, mut file: File) -> Vec<u8> {
|
||||
let mut contents = vec![];
|
||||
let byte_read = file.read_to_end(&mut contents).await;
|
||||
if byte_read.is_err() {
|
||||
eprintln!(
|
||||
"error occurred while reading store file: {}, err={:?}",
|
||||
self.path,
|
||||
byte_read.err()
|
||||
);
|
||||
}
|
||||
contents
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Store for FileStore {
|
||||
async fn is_auth(&self, data: &json::JsonValue) -> bool {
|
||||
// ensure that the store file already exists even after its instanciation
|
||||
if !Path::new(&self.path).is_file() {
|
||||
eprintln!("{} path referencing file store does not exist", self.path);
|
||||
return false;
|
||||
}
|
||||
|
||||
let credentials = Credentials::from(data);
|
||||
if credentials.is_empty() {
|
||||
eprintln!("unable to parse the credentials correctly from the incoming request");
|
||||
return false;
|
||||
}
|
||||
|
||||
let store = File::open(&self.path).await;
|
||||
match store {
|
||||
Ok(f) => {
|
||||
let contents = self.parse_contents(f).await;
|
||||
println!("file contents : {:?}", contents.len());
|
||||
return true;
|
||||
}
|
||||
Err(e) => eprintln!("error while opening the file {}, err={:?}", self.path, e),
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_store() {
|
||||
let store = FileStore::new("/tmp/thegux.pid".to_string());
|
||||
let data = json::parse(r#"{"access_token": "toto", "refresh_token": "tutu"}"#).unwrap();
|
||||
assert_eq!(store.is_auth(&data).await, false);
|
||||
}
|
||||
5
src/stores/mod.rs
Normal file
5
src/stores/mod.rs
Normal file
@ -0,0 +1,5 @@
|
||||
mod file;
|
||||
mod store;
|
||||
|
||||
pub use file::FileStore;
|
||||
pub use store::Store;
|
||||
72
src/stores/store.rs
Normal file
72
src/stores/store.rs
Normal file
@ -0,0 +1,72 @@
|
||||
use async_trait::async_trait;
|
||||
use json;
|
||||
use json::object::Object;
|
||||
|
||||
#[async_trait]
|
||||
pub trait Store {
|
||||
async fn is_auth(&self, data: &json::JsonValue) -> bool;
|
||||
}
|
||||
|
||||
/// extract_json_value extracts String json value from a key
|
||||
fn extract_json_value(data: &Object, key: &str) -> String {
|
||||
if let Some(u) = data.get(key) {
|
||||
match u.as_str() {
|
||||
Some(s) => return s.to_string(),
|
||||
None => return "".to_string(),
|
||||
}
|
||||
};
|
||||
"".to_string()
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Credentials {
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
impl Credentials {
|
||||
fn new(username: String, password: String) -> Self {
|
||||
Credentials { username, password }
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.username == "" || self.password == ""
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&json::JsonValue> for Credentials {
|
||||
fn from(data: &json::JsonValue) -> Self {
|
||||
let mut credentials = Credentials::default();
|
||||
match data {
|
||||
json::JsonValue::Object(ref d) => {
|
||||
credentials.username = extract_json_value(&d, "username");
|
||||
credentials.password = extract_json_value(&d, "password");
|
||||
}
|
||||
_ => return credentials,
|
||||
}
|
||||
credentials
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_credentials() {
|
||||
struct Expect {
|
||||
data: json::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#"{"username":"toto","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())
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user