recovery mode in embassyd

This commit is contained in:
Aiden McClelland
2021-09-14 12:19:20 -06:00
committed by Aiden McClelland
parent df50197c5f
commit 6b3570e150
5 changed files with 82 additions and 5 deletions

View File

@@ -5,7 +5,9 @@ use embassy::context::rpc::RpcContextConfig;
use embassy::context::{RecoveryContext, SetupContext};
use embassy::disk::main::DEFAULT_PASSWORD;
use embassy::hostname::get_product_key;
use embassy::middleware::cors::cors;
use embassy::middleware::encrypt::encrypt;
use embassy::middleware::recovery::recovery;
use embassy::util::Invoke;
use embassy::{Error, ResultExt};
use http::StatusCode;
@@ -38,6 +40,7 @@ async fn init(cfg_path: Option<&str>) -> Result<(), Error> {
context: ctx.clone(),
status: status_fn,
middleware: [
cors,
encrypt,
]
})
@@ -144,7 +147,10 @@ async fn inner_main(cfg_path: Option<&str>) -> Result<(), Error> {
command: embassy::recovery_api,
context: ctx.clone(),
status: status_fn,
middleware: [ ]
middleware: [
cors,
recovery,
]
})
.with_graceful_shutdown({
let mut shutdown = ctx.shutdown.subscribe();

View File

@@ -1,12 +1,13 @@
use std::time::Duration;
use anyhow::anyhow;
use embassy::context::RpcContext;
use embassy::context::{RecoveryContext, RpcContext};
use embassy::db::model::Database;
use embassy::db::subscribe;
use embassy::hostname::{get_hostname, get_id};
use embassy::middleware::auth::auth;
use embassy::middleware::cors::cors;
use embassy::middleware::recovery::recovery;
use embassy::net::tor::{os_key, tor_health_check};
use embassy::shutdown::Shutdown;
use embassy::status::{check_all, synchronize_all};
@@ -250,7 +251,38 @@ fn main() {
.enable_all()
.build()
.expect("failed to initialize runtime");
rt.block_on(inner_main(cfg_path, filter))
rt.block_on(async {
match inner_main(cfg_path, filter).await {
Ok(a) => Ok(a),
Err(e) => {
(|| async {
log::error!("{}", e.source);
log::debug!("{}", e.source);
embassy::sound::BEETHOVEN.play().await?;
let ctx = RecoveryContext::init(cfg_path, e).await?;
rpc_server!({
command: embassy::recovery_api,
context: ctx.clone(),
status: status_fn,
middleware: [
cors,
recovery,
]
})
.with_graceful_shutdown({
let mut shutdown = ctx.shutdown.subscribe();
async move {
shutdown.recv().await.expect("context dropped");
}
})
.await
.with_kind(embassy::ErrorKind::Network)?;
Ok::<_, Error>(None)
})()
.await
}
}
})
};
match res {

View File

@@ -30,7 +30,7 @@ pub enum ErrorKind {
InvalidOnionAddress = 22,
Pack = 23,
ValidateS9pk = 24,
OpenSSL = 25,
OpenSSL = 25, // REMOVE
Tor = 26,
ConfigGen = 27,
ParseNumber = 28,
@@ -56,6 +56,7 @@ pub enum ErrorKind {
Zfs = 48,
OpenSsl = 49,
PasswordHashGeneration = 50,
RecoveryMode = 51,
}
impl ErrorKind {
pub fn as_str(&self) -> &'static str {
@@ -85,7 +86,7 @@ impl ErrorKind {
InvalidOnionAddress => "Invalid Onion Address",
Pack => "Pack Error",
ValidateS9pk => "S9PK Validation Error",
OpenSSL => "OpenSSL Error",
OpenSSL => "OpenSSL Error", // Remove
Tor => "Tor Daemon Error",
ConfigGen => "Config Generation Error",
ParseNumber => "Number Parsing Error",
@@ -111,6 +112,7 @@ impl ErrorKind {
Zfs => "ZFS Error",
OpenSsl => "OpenSSL Internal Error",
PasswordHashGeneration => "Password Hash Generation Error",
RecoveryMode => "Embassy is in Recovery Mode",
}
}
}

View File

@@ -1,3 +1,4 @@
pub mod auth;
pub mod cors;
pub mod encrypt;
pub mod recovery;

View File

@@ -0,0 +1,36 @@
use futures::FutureExt;
use rpc_toolkit::hyper::http::Error as HttpError;
use rpc_toolkit::hyper::{Body, Request, Response};
use rpc_toolkit::rpc_server_helpers::{noop4, DynMiddlewareStage2, DynMiddlewareStage3};
use rpc_toolkit::yajrc::RpcMethod;
use rpc_toolkit::Metadata;
use crate::Error;
pub async fn recovery<M: Metadata>(
_req: &mut Request<Body>,
_metadata: M,
) -> Result<Result<DynMiddlewareStage2, Response<Body>>, HttpError> {
Ok(Ok(Box::new(|_, rpc_req| {
let method = rpc_req.method.as_str().to_owned();
async move {
let res: DynMiddlewareStage3 = Box::new(|_, rpc_res| {
async move {
if let Err(e) = rpc_res {
if e.code == -32601 {
*e = Error::new(
anyhow::anyhow!("{} is not available on the Recovery API", method),
crate::ErrorKind::RecoveryMode,
)
.into();
}
}
Ok(Ok(noop4()))
}
.boxed()
});
Ok::<_, HttpError>(Ok(res))
}
.boxed()
})))
}