e5afd54ce0
* Basic storage stub * New models for new node status api * Route handling * Mounting new routes * Missing selective commit * Moved network monitor related files to separate package * Starting to see some sqlx action * Schema updates * Log statement upon finished migration * Removed old diesel related imports * Converted mixnode cache initialisation into a fairing * Moved cache related functionalities to separate package Also defined staging there * Created run method for validator cache + removed unwrap * Removed old node-status-api types and left bunch of todo placeholders in their place * Fixed managing validatorcache * Status reports are starting to get constructed * Submitting some dummy results to the database * Removing duplicate code for generating reports * Removed statuses older than 48h * Initial attempt at trying to obtain reports for all active nodes * Removed duplicates from the full report * Grabbing uptime history * Updating historical uptimes of active nodes * Updated sqlx-data.json * Removed all placeholder foomp owner values * Changed Layer serde behaviour for easier usage * Extended validator api config * Initial (seems working !) integration with network monitor * Added database path configuration to config * Using ValidatorCache in NetworkMonitor * Flag indicating whether validator cache has been initialised * Introduced a locla-only route for reward script to perform daily chores * Flag to save config to a file * Moved spawning of receiving future to run method rather than new * Removed arguments that dont make sense to be configured via CLI * Removed dead code from config file * More dead code removal * Added validator API to CI * Corrected manifest-path arguments * Constructing network monitor by passing config * Combined validator API CI with the main CI file * Using query_as for NodeStatus * Checking if historical uptimes were already calculated on particular day * Making id field NOT NULL * More query_as! action * Updated sqlx-data.json * Removed unused chrono feature * Renamed the migration file * Changed default validator endpoint to point to local validator * Removing unnecessary clone * More appropriate naming * Removed dead code * Lock file updates * Updated network monitor address in contract code * Don't stage node status api if network monitor is disabled * cargo fmt * Updated all license notices to SPDX
109 lines
2.9 KiB
Rust
109 lines
2.9 KiB
Rust
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
use crate::traits::{PemStorableKey, PemStorableKeyPair};
|
|
use pem::{self, Pem};
|
|
use std::fs::File;
|
|
use std::io::{self, Read, Write};
|
|
use std::path::{Path, PathBuf};
|
|
|
|
pub mod traits;
|
|
|
|
pub struct KeyPairPath {
|
|
private_key_path: PathBuf,
|
|
public_key_path: PathBuf,
|
|
}
|
|
|
|
impl KeyPairPath {
|
|
pub fn new(private_key_path: PathBuf, public_key_path: PathBuf) -> Self {
|
|
KeyPairPath {
|
|
private_key_path,
|
|
public_key_path,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn load_keypair<T>(paths: &KeyPairPath) -> io::Result<T>
|
|
where
|
|
T: PemStorableKeyPair,
|
|
{
|
|
let private = load_key::<T::PrivatePemKey>(&paths.private_key_path)?;
|
|
let public = load_key::<T::PublicPemKey>(&paths.public_key_path)?;
|
|
Ok(T::from_keys(private, public))
|
|
}
|
|
|
|
pub fn store_keypair<T>(keypair: &T, paths: &KeyPairPath) -> io::Result<()>
|
|
where
|
|
T: PemStorableKeyPair,
|
|
{
|
|
store_key(keypair.public_key(), &paths.public_key_path)?;
|
|
store_key(keypair.private_key(), &paths.private_key_path)
|
|
}
|
|
|
|
pub fn load_key<T>(path: &Path) -> io::Result<T>
|
|
where
|
|
T: PemStorableKey,
|
|
{
|
|
let key_pem = read_pem_file(path)?;
|
|
|
|
if T::pem_type() != key_pem.tag {
|
|
return Err(io::Error::new(
|
|
io::ErrorKind::Other,
|
|
"unexpected key pem tag",
|
|
));
|
|
}
|
|
|
|
let key = match T::from_bytes(&key_pem.contents) {
|
|
Ok(key) => key,
|
|
Err(err) => return Err(io::Error::new(io::ErrorKind::InvalidData, err.to_string())),
|
|
};
|
|
|
|
Ok(key)
|
|
}
|
|
|
|
pub fn store_key<T>(key: &T, path: &Path) -> io::Result<()>
|
|
where
|
|
T: PemStorableKey,
|
|
{
|
|
write_pem_file(path, key.to_bytes(), T::pem_type())
|
|
}
|
|
|
|
fn read_pem_file(filepath: &Path) -> io::Result<Pem> {
|
|
let mut pem_bytes = File::open(filepath)?;
|
|
let mut buf = Vec::new();
|
|
pem_bytes.read_to_end(&mut buf)?;
|
|
pem::parse(&buf).map_err(|e| io::Error::new(io::ErrorKind::Other, e))
|
|
}
|
|
|
|
fn write_pem_file(filepath: &Path, data: Vec<u8>, tag: &str) -> io::Result<()> {
|
|
// ensure the whole directory structure exists
|
|
if let Some(parent_dir) = filepath.parent() {
|
|
std::fs::create_dir_all(parent_dir)?;
|
|
}
|
|
let pem = Pem {
|
|
tag: tag.to_string(),
|
|
contents: data,
|
|
};
|
|
let key = pem::encode(&pem);
|
|
|
|
let mut file = File::create(filepath)?;
|
|
file.write_all(key.as_bytes())?;
|
|
|
|
// note: this is only supported on unix (on different systems, like Windows, it will just
|
|
// be ignored)
|
|
// TODO: a possible consideration would be to use `permission.set_readonly(true)`,
|
|
// which would work on both platforms, but that would leave keys on unix with 0444,
|
|
// which I feel is too open.
|
|
#[cfg(target_family = "unix")]
|
|
{
|
|
use std::fs;
|
|
use std::os::unix::fs::PermissionsExt;
|
|
|
|
let mut permissions = file.metadata()?.permissions();
|
|
permissions.set_mode(0o600);
|
|
fs::set_permissions(filepath, permissions)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|