Add a browser-utils crate (#4394)

* Squash

* Fix keystore on wasm

* Update utils/browser/Cargo.toml

Co-Authored-By: Benjamin Kampmann <ben@gnunicorn.org>

* export console functions

* Use an Option<PathBuf> in keystore instead of cfg flags

* Add a KeystoreConfig

* Update libp2p

* Bump kvdb-web version

* Fix cli

* Upgrade versions

* Update wasm-bindgen stuff

Co-authored-by: Benjamin Kampmann <ben.kampmann@googlemail.com>
This commit is contained in:
Ashley
2020-01-07 16:30:04 +01:00
committed by GitHub
parent d76a33033d
commit bb44f8fc24
13 changed files with 432 additions and 254 deletions
+39 -23
View File
@@ -71,7 +71,7 @@ impl std::error::Error for Error {
///
/// Every pair that is being generated by a `seed`, will be placed in memory.
pub struct Store {
path: PathBuf,
path: Option<PathBuf>,
additional: HashMap<(KeyTypeId, Vec<u8>), Vec<u8>>,
password: Option<Protected<String>>,
}
@@ -84,10 +84,19 @@ impl Store {
let path = path.into();
fs::create_dir_all(&path)?;
let instance = Self { path, additional: HashMap::new(), password };
let instance = Self { path: Some(path), additional: HashMap::new(), password };
Ok(Arc::new(RwLock::new(instance)))
}
/// Create a new in-memory store.
pub fn new_in_memory() -> KeyStorePtr {
Arc::new(RwLock::new(Self {
path: None,
additional: HashMap::new(),
password: None
}))
}
/// Get the public/private key pair for the given public key and key type.
fn get_additional_pair<Pair: PairT>(
&self,
@@ -113,9 +122,11 @@ impl Store {
///
/// Places it into the file system store.
fn insert_unknown(&self, key_type: KeyTypeId, suri: &str, public: &[u8]) -> Result<()> {
let mut file = File::create(self.key_file_path(public, key_type)).map_err(Error::Io)?;
serde_json::to_writer(&file, &suri).map_err(Error::Json)?;
file.flush().map_err(Error::Io)?;
if let Some(path) = self.key_file_path(public, key_type) {
let mut file = File::create(path).map_err(Error::Io)?;
serde_json::to_writer(&file, &suri).map_err(Error::Json)?;
file.flush().map_err(Error::Io)?;
}
Ok(())
}
@@ -144,9 +155,11 @@ impl Store {
/// Places it into the file system store.
pub fn generate_by_type<Pair: PairT>(&self, key_type: KeyTypeId) -> Result<Pair> {
let (pair, phrase, _) = Pair::generate_with_phrase(self.password.as_ref().map(|p| &***p));
let mut file = File::create(self.key_file_path(pair.public().as_slice(), key_type))?;
serde_json::to_writer(&file, &phrase)?;
file.flush()?;
if let Some(path) = self.key_file_path(pair.public().as_slice(), key_type) {
let mut file = File::create(path)?;
serde_json::to_writer(&file, &phrase)?;
file.flush()?;
}
Ok(pair)
}
@@ -186,7 +199,8 @@ impl Store {
return Ok(pair)
}
let path = self.key_file_path(public.as_slice(), key_type);
let path = self.key_file_path(public.as_slice(), key_type)
.ok_or_else(|| Error::Unavailable)?;
let file = File::open(path)?;
let phrase: String = serde_json::from_reader(&file)?;
@@ -219,19 +233,21 @@ impl Store {
})
.collect();
for entry in fs::read_dir(&self.path)? {
let entry = entry?;
let path = entry.path();
if let Some(path) = &self.path {
for entry in fs::read_dir(&path)? {
let entry = entry?;
let path = entry.path();
// skip directories and non-unicode file names (hex is unicode)
if let Some(name) = path.file_name().and_then(|n| n.to_str()) {
match hex::decode(name) {
Ok(ref hex) if hex.len() > 4 => {
if &hex[0..4] != &key_type.0 { continue }
let public = TPublic::from_slice(&hex[4..]);
public_keys.push(public);
// skip directories and non-unicode file names (hex is unicode)
if let Some(name) = path.file_name().and_then(|n| n.to_str()) {
match hex::decode(name) {
Ok(ref hex) if hex.len() > 4 => {
if &hex[0..4] != &key_type.0 { continue }
let public = TPublic::from_slice(&hex[4..]);
public_keys.push(public);
}
_ => continue,
}
_ => continue,
}
}
}
@@ -251,12 +267,12 @@ impl Store {
}
/// Returns the file path for the given public key and key type.
fn key_file_path(&self, public: &[u8], key_type: KeyTypeId) -> PathBuf {
let mut buf = self.path.clone();
fn key_file_path(&self, public: &[u8], key_type: KeyTypeId) -> Option<PathBuf> {
let mut buf = self.path.as_ref()?.clone();
let key_type = hex::encode(key_type.0);
let key = hex::encode(public);
buf.push(key_type + key.as_str());
buf
Some(buf)
}
}