xfer
This commit is contained in:
@@ -2,6 +2,7 @@ use crate::xx::*;
|
||||
use crate::*;
|
||||
use data_encoding::BASE64URL_NOPAD;
|
||||
use keyring_manager::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::Path;
|
||||
|
||||
pub struct ProtectedStoreInner {
|
||||
@@ -31,15 +32,18 @@ impl ProtectedStore {
|
||||
#[instrument(level = "trace", skip(self), err)]
|
||||
pub async fn delete_all(&self) -> EyreResult<()> {
|
||||
// Delete all known keys
|
||||
if self.remove_user_secret_string("node_id").await? {
|
||||
if self.remove_user_secret("node_id").await? {
|
||||
debug!("deleted protected_store key 'node_id'");
|
||||
}
|
||||
if self.remove_user_secret_string("node_id_secret").await? {
|
||||
if self.remove_user_secret("node_id_secret").await? {
|
||||
debug!("deleted protected_store key 'node_id_secret'");
|
||||
}
|
||||
if self.remove_user_secret_string("_test_key").await? {
|
||||
if self.remove_user_secret("_test_key").await? {
|
||||
debug!("deleted protected_store key '_test_key'");
|
||||
}
|
||||
if self.remove_user_secret("RouteSpecStore").await? {
|
||||
debug!("deleted protected_store key 'RouteSpecStore'");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -139,19 +143,30 @@ impl ProtectedStore {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self), ret, err)]
|
||||
pub async fn remove_user_secret_string(&self, key: &str) -> EyreResult<bool> {
|
||||
let inner = self.inner.lock();
|
||||
match inner
|
||||
.keyring_manager
|
||||
.as_ref()
|
||||
.ok_or_else(|| eyre!("Protected store not initialized"))?
|
||||
.with_keyring(&self.service_name(), key, |kr| kr.delete_value())
|
||||
{
|
||||
Ok(_) => Ok(true),
|
||||
Err(KeyringError::NoPasswordFound) => Ok(false),
|
||||
Err(e) => Err(eyre!("Failed to remove user secret: {}", e)),
|
||||
}
|
||||
#[instrument(level = "trace", skip(self, value), ret, err)]
|
||||
pub async fn save_user_secret_cbor<T>(&self, key: &str, value: &T) -> EyreResult<bool>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
let v = serde_cbor::to_vec(value).wrap_err("couldn't store as CBOR")?;
|
||||
self.save_user_secret(&key, &v).await
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self), err)]
|
||||
pub async fn load_user_secret_cbor<T>(&self, key: &str) -> EyreResult<Option<T>>
|
||||
where
|
||||
T: for<'de> Deserialize<'de>,
|
||||
{
|
||||
let out = self.load_user_secret(key).await?;
|
||||
let b = match out {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
return Ok(None);
|
||||
}
|
||||
};
|
||||
|
||||
let obj = serde_cbor::from_slice::<T>(&b).wrap_err("failed to deserialize")?;
|
||||
Ok(Some(obj))
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self, value), ret, err)]
|
||||
@@ -195,6 +210,16 @@ impl ProtectedStore {
|
||||
|
||||
#[instrument(level = "trace", skip(self), ret, err)]
|
||||
pub async fn remove_user_secret(&self, key: &str) -> EyreResult<bool> {
|
||||
self.remove_user_secret_string(key).await
|
||||
let inner = self.inner.lock();
|
||||
match inner
|
||||
.keyring_manager
|
||||
.as_ref()
|
||||
.ok_or_else(|| eyre!("Protected store not initialized"))?
|
||||
.with_keyring(&self.service_name(), key, |kr| kr.delete_value())
|
||||
{
|
||||
Ok(_) => Ok(true),
|
||||
Err(KeyringError::NoPasswordFound) => Ok(false),
|
||||
Err(e) => Err(eyre!("Failed to remove user secret: {}", e)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -17,38 +17,40 @@ extern "C" {
|
||||
fn keytar_deletePassword(service: &str, account: &str) -> Result<Promise, JsValue>;
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ProtectedStore {
|
||||
config: VeilidConfig,
|
||||
}
|
||||
|
||||
impl ProtectedStore {
|
||||
|
||||
pub fn new(config: VeilidConfig) -> Self {
|
||||
Self {
|
||||
config,
|
||||
}
|
||||
Self { config }
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self), err)]
|
||||
pub async fn delete_all(&self) -> EyreResult<()> {
|
||||
// Delete all known keys
|
||||
if self.remove_user_secret_string("node_id").await? {
|
||||
if self.remove_user_secret("node_id").await? {
|
||||
debug!("deleted protected_store key 'node_id'");
|
||||
}
|
||||
if self.remove_user_secret_string("node_id_secret").await? {
|
||||
if self.remove_user_secret("node_id_secret").await? {
|
||||
debug!("deleted protected_store key 'node_id_secret'");
|
||||
}
|
||||
if self.remove_user_secret_string("_test_key").await? {
|
||||
if self.remove_user_secret("_test_key").await? {
|
||||
debug!("deleted protected_store key '_test_key'");
|
||||
}
|
||||
if self.remove_user_secret("RouteSpecStore").await? {
|
||||
debug!("deleted protected_store key 'RouteSpecStore'");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self), err)]
|
||||
pub async fn init(&self) -> EyreResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
pub async fn terminate(&self) {}
|
||||
|
||||
fn keyring_name(&self) -> String {
|
||||
@@ -69,12 +71,13 @@ impl ProtectedStore {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self, value), ret, err)]
|
||||
pub async fn save_user_secret_string(&self, key: &str, value: &str) -> EyreResult<bool> {
|
||||
if is_nodejs() {
|
||||
let prev = match JsFuture::from(
|
||||
keytar_getPassword(self.keyring_name().as_str(), key)
|
||||
.map_err(map_jsvalue_error)
|
||||
.wrap_err("exception thrown")?,
|
||||
.map_err(map_jsvalue_error)
|
||||
.wrap_err("exception thrown")?,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -84,8 +87,8 @@ impl ProtectedStore {
|
||||
|
||||
match JsFuture::from(
|
||||
keytar_setPassword(self.keyring_name().as_str(), key, value)
|
||||
.map_err(map_jsvalue_error)
|
||||
.wrap_err("exception thrown")?,
|
||||
.map_err(map_jsvalue_error)
|
||||
.wrap_err("exception thrown")?,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -134,6 +137,7 @@ impl ProtectedStore {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self), err)]
|
||||
pub async fn load_user_secret_string(&self, key: &str) -> EyreResult<Option<String>> {
|
||||
if is_nodejs() {
|
||||
let prev = match JsFuture::from(
|
||||
@@ -181,7 +185,73 @@ impl ProtectedStore {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn remove_user_secret_string(&self, key: &str) -> EyreResult<bool> {
|
||||
#[instrument(level = "trace", skip(self, value), ret, err)]
|
||||
pub async fn save_user_secret_cbor<T>(&self, key: &str, value: &T) -> EyreResult<bool>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
let v = serde_cbor::to_vec(value).wrap_err("couldn't store as CBOR")?;
|
||||
self.save_user_secret(&key, &v).await
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self), err)]
|
||||
pub async fn load_user_secret_cbor<T>(&self, key: &str) -> EyreResult<Option<T>>
|
||||
where
|
||||
T: for<'de> Deserialize<'de>,
|
||||
{
|
||||
let out = self.load_user_secret(key).await?;
|
||||
let b = match out {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
return Ok(None);
|
||||
}
|
||||
};
|
||||
|
||||
let obj = serde_cbor::from_slice::<T>(&b).wrap_err("failed to deserialize")?;
|
||||
Ok(Some(obj))
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self, value), ret, err)]
|
||||
pub async fn save_user_secret(&self, key: &str, value: &[u8]) -> EyreResult<bool> {
|
||||
let mut s = BASE64URL_NOPAD.encode(value);
|
||||
s.push('!');
|
||||
|
||||
self.save_user_secret_string(key, s.as_str()).await
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self), err)]
|
||||
pub async fn load_user_secret(&self, key: &str) -> EyreResult<Option<Vec<u8>>> {
|
||||
let mut s = match self.load_user_secret_string(key).await? {
|
||||
Some(s) => s,
|
||||
None => {
|
||||
return Ok(None);
|
||||
}
|
||||
};
|
||||
|
||||
if s.pop() != Some('!') {
|
||||
bail!("User secret is not a buffer");
|
||||
}
|
||||
|
||||
let mut bytes = Vec::<u8>::new();
|
||||
let res = BASE64URL_NOPAD.decode_len(s.len());
|
||||
match res {
|
||||
Ok(l) => {
|
||||
bytes.resize(l, 0u8);
|
||||
}
|
||||
Err(_) => {
|
||||
bail!("Failed to decode");
|
||||
}
|
||||
}
|
||||
|
||||
let res = BASE64URL_NOPAD.decode_mut(s.as_bytes(), &mut bytes);
|
||||
match res {
|
||||
Ok(_) => Ok(Some(bytes)),
|
||||
Err(_) => bail!("Failed to decode"),
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self), ret, err)]
|
||||
pub async fn remove_user_secret(&self, key: &str) -> EyreResult<bool> {
|
||||
if is_nodejs() {
|
||||
match JsFuture::from(
|
||||
keytar_deletePassword(self.keyring_name().as_str(), key)
|
||||
@@ -231,45 +301,4 @@ impl ProtectedStore {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn save_user_secret(&self, key: &str, value: &[u8]) -> EyreResult<bool> {
|
||||
let mut s = BASE64URL_NOPAD.encode(value);
|
||||
s.push('!');
|
||||
|
||||
self.save_user_secret_string(key, s.as_str()).await
|
||||
}
|
||||
|
||||
pub async fn load_user_secret(&self, key: &str) -> EyreResult<Option<Vec<u8>>> {
|
||||
let mut s = match self.load_user_secret_string(key).await? {
|
||||
Some(s) => s,
|
||||
None => {
|
||||
return Ok(None);
|
||||
}
|
||||
};
|
||||
|
||||
if s.pop() != Some('!') {
|
||||
bail!("User secret is not a buffer");
|
||||
}
|
||||
|
||||
let mut bytes = Vec::<u8>::new();
|
||||
let res = BASE64URL_NOPAD.decode_len(s.len());
|
||||
match res {
|
||||
Ok(l) => {
|
||||
bytes.resize(l, 0u8);
|
||||
}
|
||||
Err(_) => {
|
||||
bail!("Failed to decode");
|
||||
}
|
||||
}
|
||||
|
||||
let res = BASE64URL_NOPAD.decode_mut(s.as_bytes(), &mut bytes);
|
||||
match res {
|
||||
Ok(_) => Ok(Some(bytes)),
|
||||
Err(_) => bail!("Failed to decode"),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn remove_user_secret(&self, key: &str) -> EyreResult<bool> {
|
||||
self.remove_user_secret_string(key).await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user