use std::path::Path;
use std::fs::File;
use std::io::prelude::*;
use serde_yaml;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Allowance {
pub name: String,
pub binary: String,
pub arg_blacklist: Option<Vec<String>>
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Config {
pub socket_path: Option<String>,
pub user: Option<Vec<Allowance>>,
pub group: Option<Vec<Allowance>>
}
impl Config {
fn read_file(path: &str) -> String {
let path_object = Path::new(&path);
let mut file = match File::open(&path_object) {
Err(_) => match File::create(&path_object) {
Err(error) => panic!("Couldn't open or create file: {:?}", error),
Ok(file) => file
},
Ok(file) => file
};
let mut content = String::new();
match file.read_to_string(&mut content) {
Err(error) => panic!("couldn't read {}: {:?}", &path, error),
Ok(_) => {}
}
content
}
pub fn new(path: &str) -> Config {
let config_raw = Config::read_file(&path);
let config: Config = serde_yaml::from_str(&config_raw).unwrap();
config
}
pub fn serialize(&self) -> String {
serde_yaml::to_string(&self).unwrap()
}
pub fn check_allowed(&self, command: &str, filter: &str, group: bool) -> bool {
if !group {
match self.user.clone() {
Some(config_user) => {
let user_whitelist = config_user.iter().filter(|x| &x.name == filter).map(|x| &x.binary).collect::<Vec<_>>();
if user_whitelist.contains(&&command.to_string()) {
true
} else {
false
}
},
None => {
false
}
}
} else {
match self.group.clone() {
Some(config_group) => {
let group_whitelist = config_group.iter().filter(|x| &x.name == filter).map(|x| &x.binary).collect::<Vec<_>>();
if group_whitelist.contains(&&command.to_string()) {
true
} else {
false
}
},
None => {
false
}
}
}
}
}