feat: #8 parse store file content and add test
This commit is contained in:
parent
8bf503df14
commit
73059c724f
@ -12,6 +12,9 @@ regex = "1"
|
|||||||
tokio = { version = "1.21.1", features = ["full"] }
|
tokio = { version = "1.21.1", features = ["full"] }
|
||||||
async-trait = "0.1.57"
|
async-trait = "0.1.57"
|
||||||
|
|
||||||
|
# useful for tests (embedded files should be delete in release ?)
|
||||||
|
#rust-embed="6.4.1"
|
||||||
|
|
||||||
[dependencies.async-std]
|
[dependencies.async-std]
|
||||||
version = "1.6"
|
version = "1.6"
|
||||||
features = ["attributes"]
|
features = ["attributes"]
|
||||||
|
|||||||
@ -11,30 +11,65 @@ use super::store::{Credentials, Store};
|
|||||||
/// FileStore references a `store` file
|
/// FileStore references a `store` file
|
||||||
pub struct FileStore {
|
pub struct FileStore {
|
||||||
path: String,
|
path: String,
|
||||||
|
credentials: Vec<Credentials>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileStore {
|
impl FileStore {
|
||||||
fn new(path: String) -> Self {
|
fn new(path: String) -> Self {
|
||||||
FileStore { path }
|
FileStore {
|
||||||
|
path,
|
||||||
|
credentials: vec![],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn parse_contents(&self, mut file: File) -> Vec<u8> {
|
/// parse_contents loads and reads the file asynchonously
|
||||||
let mut contents = vec![];
|
/// parses the file line by line to retrieve the credentials
|
||||||
let byte_read = file.read_to_end(&mut contents).await;
|
async fn parse_contents(&mut self) {
|
||||||
if byte_read.is_err() {
|
let contents = tokio::fs::read_to_string(&self.path).await;
|
||||||
eprintln!(
|
let mut credentials: Vec<Credentials> = vec![];
|
||||||
"error occurred while reading store file: {}, err={:?}",
|
match contents {
|
||||||
self.path,
|
Ok(c) => {
|
||||||
byte_read.err()
|
let lines: Vec<&str> = c.split("\n").collect();
|
||||||
);
|
for line in lines {
|
||||||
|
if line.starts_with("#") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let line_split: Vec<&str> = line.split(":").collect();
|
||||||
|
if line_split.len() != 2 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
credentials.push(Credentials::new(
|
||||||
|
line_split[0].to_string(),
|
||||||
|
line_split[1].to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!(
|
||||||
|
"error occurred while reading store file: {}, err={:?}",
|
||||||
|
self.path, e
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
contents
|
self.credentials = credentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn auth(&self, username: String, password: String) -> bool {
|
||||||
|
let credentials: Vec<&Credentials> = self
|
||||||
|
.credentials
|
||||||
|
.iter()
|
||||||
|
.filter(|x| x.username == username && x.password == password)
|
||||||
|
.collect();
|
||||||
|
if credentials.len() == 1 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Store for FileStore {
|
impl Store for FileStore {
|
||||||
async fn is_auth(&self, data: &json::JsonValue) -> bool {
|
async fn is_auth(&mut self, data: &json::JsonValue) -> bool {
|
||||||
// ensure that the store file already exists even after its instanciation
|
// ensure that the store file already exists even after its instanciation
|
||||||
if !Path::new(&self.path).is_file() {
|
if !Path::new(&self.path).is_file() {
|
||||||
eprintln!("{} path referencing file store does not exist", self.path);
|
eprintln!("{} path referencing file store does not exist", self.path);
|
||||||
@ -47,22 +82,22 @@ impl Store for FileStore {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let store = File::open(&self.path).await;
|
let contents = self.parse_contents().await;
|
||||||
match store {
|
|
||||||
Ok(f) => {
|
self.auth(credentials.username, credentials.password)
|
||||||
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]
|
#[tokio::test]
|
||||||
async fn test_store() {
|
async fn test_store() {
|
||||||
let store = FileStore::new("/tmp/thegux.pid".to_string());
|
use std::env;
|
||||||
let data = json::parse(r#"{"access_token": "toto", "refresh_token": "tutu"}"#).unwrap();
|
|
||||||
assert_eq!(store.is_auth(&data).await, false);
|
let root_path = env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||||
|
// TODO: path::Path should be better
|
||||||
|
let store_path = format!("{}/{}/{}/{}", root_path, "tests", "data", "store.txt");
|
||||||
|
|
||||||
|
let mut store = FileStore::new(store_path);
|
||||||
|
|
||||||
|
let data = json::parse(r#"{"username": "toto", "password": "tata"}"#).unwrap();
|
||||||
|
assert_eq!(store.is_auth(&data).await, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use json::object::Object;
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait Store {
|
pub trait Store {
|
||||||
async fn is_auth(&self, data: &json::JsonValue) -> bool;
|
async fn is_auth(&mut self, data: &json::JsonValue) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// extract_json_value extracts String json value from a key
|
/// extract_json_value extracts String json value from a key
|
||||||
@ -18,14 +18,14 @@ fn extract_json_value(data: &Object, key: &str) -> String {
|
|||||||
"".to_string()
|
"".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, Debug)]
|
||||||
pub struct Credentials {
|
pub struct Credentials {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
pub password: String,
|
pub password: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Credentials {
|
impl Credentials {
|
||||||
fn new(username: String, password: String) -> Self {
|
pub fn new(username: String, password: String) -> Self {
|
||||||
Credentials { username, password }
|
Credentials { username, password }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
4
tests/data/store.txt
Normal file
4
tests/data/store.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# this a test password storage with password in clear
|
||||||
|
# need to be updated in the future to encrypt or hash the password
|
||||||
|
# <username>:<password>
|
||||||
|
toto:tata
|
||||||
Loading…
x
Reference in New Issue
Block a user