return full ssh key response on add

This commit is contained in:
Keagan McClelland
2021-09-20 13:58:31 -06:00
committed by Aiden McClelland
parent 17da1dbc7f
commit b5f74cdde4
2 changed files with 32 additions and 14 deletions

View File

@@ -58,6 +58,7 @@ pub enum ErrorKind {
PasswordHashGeneration = 50, PasswordHashGeneration = 50,
DiagnosticMode = 51, DiagnosticMode = 51,
ParseDbField = 52, ParseDbField = 52,
Duplicate = 53,
} }
impl ErrorKind { impl ErrorKind {
pub fn as_str(&self) -> &'static str { pub fn as_str(&self) -> &'static str {
@@ -115,6 +116,7 @@ impl ErrorKind {
PasswordHashGeneration => "Password Hash Generation Error", PasswordHashGeneration => "Password Hash Generation Error",
DiagnosticMode => "Embassy is in Diagnostic Mode", DiagnosticMode => "Embassy is in Diagnostic Mode",
ParseDbField => "Database Field Parse Error", ParseDbField => "Database Field Parse Error",
Duplicate => "Duplication Error",
} }
} }
} }

View File

@@ -1,13 +1,14 @@
use std::path::Path; use std::path::Path;
use anyhow::anyhow; use anyhow::anyhow;
use chrono::Utc;
use clap::ArgMatches; use clap::ArgMatches;
use rpc_toolkit::command; use rpc_toolkit::command;
use sqlx::{Pool, Sqlite}; use sqlx::{Pool, Sqlite};
use crate::context::RpcContext; use crate::context::RpcContext;
use crate::util::{display_none, display_serializable, IoFormat}; use crate::util::{display_none, display_serializable, IoFormat};
use crate::Error; use crate::{Error, ErrorKind};
static SSH_AUTHORIZED_KEYS_FILE: &str = "~/.ssh/authorized_keys"; static SSH_AUTHORIZED_KEYS_FILE: &str = "~/.ssh/authorized_keys";
@@ -53,26 +54,41 @@ pub fn ssh() -> Result<(), Error> {
} }
#[command(display(display_none))] #[command(display(display_none))]
pub async fn add(#[context] ctx: RpcContext, #[arg] key: PubKey) -> Result<String, Error> { pub async fn add(#[context] ctx: RpcContext, #[arg] key: PubKey) -> Result<SshKeyResponse, Error> {
let pool = &ctx.secret_store; let pool = &ctx.secret_store;
// check fingerprint for duplicates // check fingerprint for duplicates
let fp = key.0.fingerprint_md5(); let fp = key.0.fingerprint_md5();
if sqlx::query!("SELECT * FROM ssh_keys WHERE fingerprint = ?", fp) match sqlx::query!("SELECT * FROM ssh_keys WHERE fingerprint = ?", fp)
.fetch_optional(pool) .fetch_optional(pool)
.await? .await?
.is_none()
{ {
// if no duplicates, insert into DB None => {
let raw_key = format!("{}", key.0); // if no duplicates, insert into DB
sqlx::query!( let raw_key = format!("{}", key.0);
"INSERT INTO ssh_keys (fingerprint, openssh_pubkey, created_at) VALUES (?, ?, datetime('now'))" let created_at = Utc::now().to_rfc3339();
, fp, raw_key).execute(pool).await?; sqlx::query!(
// insert into live key file, for now we actually do a wholesale replacement of the keys file, for maximum "INSERT INTO ssh_keys (fingerprint, openssh_pubkey, created_at) VALUES (?, ?, ?)",
// consistency fp,
sync_keys_from_db(pool, Path::new(SSH_AUTHORIZED_KEYS_FILE)).await?; raw_key,
created_at
)
.execute(pool)
.await?;
// insert into live key file, for now we actually do a wholesale replacement of the keys file, for maximum
// consistency
sync_keys_from_db(pool, Path::new(SSH_AUTHORIZED_KEYS_FILE)).await?;
Ok(SshKeyResponse {
alg: key.0.keytype().to_owned(),
fingerprint: fp,
hostname: key.0.comment.unwrap_or(String::new()).to_owned(),
created_at,
})
}
Some(_) => Err(Error::new(
anyhow!("Duplicate ssh key"),
ErrorKind::Duplicate,
)),
} }
// return fingerprint
Ok(fp)
} }
#[command(display(display_none))] #[command(display(display_none))]
pub async fn delete(#[context] ctx: RpcContext, #[arg] fingerprint: String) -> Result<(), Error> { pub async fn delete(#[context] ctx: RpcContext, #[arg] fingerprint: String) -> Result<(), Error> {