From c11f5b13bfd73bec3f0f2749aa0ca1b89018eae3 Mon Sep 17 00:00:00 2001 From: Slack Coder Date: Fri, 28 Oct 2022 06:36:06 -0500 Subject: [PATCH] rad-auth: create profile when not found Be careful about when to attempt creating a profile. Errors could trigger creating a profile even when unrelated to it not existing. Profile::load(..) is altered to distinguish between these cases. Signed-off-by: Slack Coder --- radicle-tools/src/rad-auth.rs | 17 ++++++++++++----- radicle/src/keystore.rs | 14 ++++++++++---- radicle/src/profile.rs | 18 ++++++++++++++++-- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/radicle-tools/src/rad-auth.rs b/radicle-tools/src/rad-auth.rs index 9f7673cf..04f5642b 100644 --- a/radicle-tools/src/rad-auth.rs +++ b/radicle-tools/src/rad-auth.rs @@ -1,9 +1,16 @@ +use radicle::profile; +use radicle::Profile; + fn main() -> anyhow::Result<()> { - let keypair = radicle::crypto::KeyPair::generate(); - radicle::crypto::ssh::agent::register(&keypair.sk)?; - - let profile = radicle::Profile::init(keypair)?; - + let profile = match Profile::load() { + Ok(v) => v, + Err(profile::Error::NotFound(_)) => { + let keypair = radicle::crypto::KeyPair::generate(); + radicle::crypto::ssh::agent::register(&keypair.sk)?; + radicle::Profile::init(keypair)? + } + Err(err) => anyhow::bail!(err), + }; println!("id: {}", profile.id()); println!("home: {}", profile.home.display()); diff --git a/radicle/src/keystore.rs b/radicle/src/keystore.rs index c9aa80a1..ce1429bb 100644 --- a/radicle/src/keystore.rs +++ b/radicle/src/keystore.rs @@ -58,15 +58,21 @@ impl UnsafeKeystore { Ok(()) } - pub fn get(&self) -> Result<(PublicKey, SecretKey), Error> { - let public = fs::read(self.path.join("radicle.pub"))?; + pub fn get(&self) -> Result, Error> { + let public = self.path.join("radicle.pub"); + let secret = self.path.join("radicle"); + if !public.exists() && !secret.exists() { + return Ok(None); + } + + let public = fs::read(public)?; let public = String::from_utf8(public)?; let public = PublicKey::from_pem(&public)?; - let secret = fs::read(self.path.join("radicle"))?; + let secret = fs::read(secret)?; let secret = String::from_utf8(secret)?; let secret = SecretKey::from_pem(&secret)?; - Ok((public, secret)) + Ok(Some((public, secret))) } } diff --git a/radicle/src/profile.rs b/radicle/src/profile.rs index b7d87fa6..3d9fe3f3 100644 --- a/radicle/src/profile.rs +++ b/radicle/src/profile.rs @@ -13,12 +13,24 @@ use std::path::PathBuf; use std::{env, io}; +use thiserror::Error; + use crate::crypto::{KeyPair, PublicKey, SecretKey, Signature, Signer}; -use crate::keystore::{Error, UnsafeKeystore}; +use crate::keystore::UnsafeKeystore; use crate::node; use crate::storage::git::transport; use crate::storage::git::Storage; +#[derive(Debug, Error)] +pub enum Error { + #[error(transparent)] + Io(#[from] io::Error), + #[error(transparent)] + KeyStore(#[from] crate::keystore::Error), + #[error("no profile found at the filepath '{0}'")] + NotFound(PathBuf), +} + #[derive(Debug)] pub struct UnsafeSigner { pub public: PublicKey, @@ -65,7 +77,9 @@ impl Profile { pub fn load() -> Result { let home = self::home()?; - let (public, secret) = UnsafeKeystore::new(&home.join("keys")).get()?; + let (public, secret) = UnsafeKeystore::new(&home.join("keys")) + .get()? + .ok_or_else(|| Error::NotFound(home.clone()))?; let signer = UnsafeSigner { public, secret }; let storage = Storage::open(&home.join("storage"))?;