#![feature(maybe_uninit_ref)]
#[macro_use]
extern crate serde_derive;
pub mod database;
pub use database::*;
pub mod permissions;
pub mod archive;
pub mod users;
pub use crate::database::*;
use crate::permissions::*;
use networking::encryption::*;
use networking::query::Query;
use networking::ArtificeConfig;
use networking::ArtificePeer;
use serde::{de::Deserialize, de::DeserializeOwned,ser::Serialize};
use crate::archive::*;
use std::{
convert::AsRef,
fmt::Debug,
path::{Path, PathBuf},
fs::File,
io::{Read},
};
#[derive(Debug, Clone)]
pub struct PermissionManager {
permissions: PermissionsGranted,
password: Vec<u8>,
query: Query<(Permission, ArtificePeer), PermissionResult>,
}
impl PermissionManager {
pub fn get_query(&self) -> Query<(Permission, ArtificePeer), PermissionResult>{
self.query.clone()
}
}
impl<'a> Table<'a, String, Permission, std::io::Error> for PermissionManager{
fn create<P: AsRef<Path>>(path: P, pass: &[u8]) -> Result<Self, std::io::Error>{
let mut password = Vec::new();
password.extend_from_slice(pass);
let query = Query::new();
let mut file = File::open(&format!("{}.artusr",path.as_ref().display()))?;
let mut data = Vec::new();
file.read_to_end(&mut data)?;
let mut outbuf = Vec::new();
decrypt(pass, &data, &mut outbuf);
let permissions = serde_json::from_str(&String::from_utf8(outbuf).unwrap()).unwrap();
Ok(Self{permissions, password, query})
}
fn get<K: ToString>(&self, key: &K) -> Result<Permission, std::io::Error>{
for permission in self.permissions.iter(){
if key.to_string() == permission.get_key(){
return Ok(permission.clone())
}
}
Err(std::io::Error::new(std::io::ErrorKind::NotFound, "permission not found"))
}
fn insert<K: ToString>(&self, _permission: &Permission) -> Result<(), std::io::Error>{
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ArtificeDB {
root: String,
entries: Vec<String>,
}
impl ArtificeDB {
pub fn default_from_root<P: AsRef<Path>>(root: P) -> Self {
let root = format!("{}", root.as_ref().display());
let permissions = format!("{}permissions.artusr", root);
let peers = format!("{}peers/", root);
let config = format!("{}config.artusr", root);
let applications = format!("{}applications.artusr", root);
let mut entries = Vec::new();
entries.push(permissions);
entries.push(peers);
entries.push(config);
entries.push(applications);
Self {
root,
entries,
}
}
pub fn archive(&self) -> std::io::Result<Vec<u8>>{
archive(&self.root)
}
pub fn install_archive(&self, archive: &[u8]) -> std::io::Result<()>{
dearchive(archive, &self.root)
}
}
impl Database<std::io::Error> for ArtificeDB {
fn create<P: AsRef<Path>>(root: P) -> Result<Self, std::io::Error> {
Ok(Self::default_from_root(root))
}
fn root(&self) -> PathBuf {
let path = Path::new(&self.root);
path.to_path_buf()
}
fn create_table<'a, B, A, T>(&self, key: B, password: &[u8]) -> Result<T, std::io::Error>
where
B: ToString,
A: Debug + Clone + Serialize + Deserialize<'a> + GetPrimaryKey<B>,
T: Table<'a, B, A, std::io::Error>,
{
let pathstr = format!("{}{}", self.root, key.to_string());
let path = Path::new(&pathstr);
T::create(path, password)
}
fn load_entry<K, T>(&self, key: K, password: &[u8]) -> Result<T, std::io::Error>
where
K: ToString,
T: Debug + Clone + Serialize + DeserializeOwned,
{
let pathstr = format!("{}{}", self.root, key.to_string());
let path = Path::new(&pathstr);
let mut file = File::open(path)?;
let mut invec = Vec::new();
let mut outvec = Vec::new();
file.read_to_end(&mut invec)?;
decrypt(password, &invec, &mut outvec);
let content = String::from_utf8(outvec).unwrap();
let entry = serde_json::from_value(serde_json::Value::String(content)).unwrap();
Ok(entry)
}
}
impl Default for ArtificeDB {
fn default() -> Self {
let root = format!(
"{}.artifice/",
dirs::home_dir().unwrap().display().to_string()
);
Self::default_from_root(root)
}
}
pub struct Manager {
_permissions: PermissionManager,
_database: ArtificeDB,
peers: ArtificePeers,
config: ArtificeConfig,
}
impl Manager{
pub fn load(database: ArtificeDB, password: &[u8]) -> Result<Self, std::io::Error>{
let permissions = database.create_table("permissions".to_string(), password)?;
let peers = database.create_table("peers/".to_string(), password)?;
let config: ArtificeConfig = database.load_entry("config".to_string(), password)?;
Ok(Self {_permissions: permissions, _database: database, peers, config})
}
pub fn config(&self) -> &ArtificeConfig{
&self.config
}
pub fn authenticate(&self, peer: &ArtificePeer) -> std::io::Result<bool>{
Ok(self.peers.get(&peer.global_peer_hash())? == *peer)
}
pub fn get_peer(&self, key: &str) -> std::io::Result<ArtificePeer>{
self.peers.get(&key.to_string())
}
}