Page MenuHomePhabricator

D8964.diff
No OneTemporary

D8964.diff

diff --git a/services/backup/Cargo.lock b/services/backup/Cargo.lock
--- a/services/backup/Cargo.lock
+++ b/services/backup/Cargo.lock
@@ -761,6 +761,8 @@
"once_cell",
"rand",
"reqwest",
+ "serde",
+ "serde_json",
"tokio",
"tokio-stream",
"tonic-build",
diff --git a/services/backup/Cargo.toml b/services/backup/Cargo.toml
--- a/services/backup/Cargo.toml
+++ b/services/backup/Cargo.toml
@@ -31,6 +31,8 @@
reqwest = "0.11.18"
derive_more = "0.99"
actix-multipart = "0.6"
+serde = { version = "1.0", features = ["derive"] }
+serde_json = { version = "1.0" }
[build-dependencies]
tonic-build = "0.8"
diff --git a/services/backup/src/database/mod.rs b/services/backup/src/database/mod.rs
--- a/services/backup/src/database/mod.rs
+++ b/services/backup/src/database/mod.rs
@@ -72,7 +72,7 @@
),
]);
- match self
+ let output = self
.client
.get_item()
.table_name(BACKUP_TABLE_NAME)
@@ -82,15 +82,16 @@
.map_err(|e| {
error!("DynamoDB client failed to find backup item");
Error::AwsSdk(e.into())
- })? {
- GetItemOutput {
- item: Some(item), ..
- } => {
- let backup_item = item.try_into()?;
- Ok(Some(backup_item))
- }
- _ => Ok(None),
- }
+ })?;
+
+ let GetItemOutput {
+ item: Some(item), ..
+ } = output else {
+ return Ok(None)
+ };
+
+ let backup_item = item.try_into()?;
+ Ok(Some(backup_item))
}
pub async fn find_last_backup_item(
diff --git a/services/backup/src/error.rs b/services/backup/src/error.rs
--- a/services/backup/src/error.rs
+++ b/services/backup/src/error.rs
@@ -1,6 +1,6 @@
use actix_web::{
error::{
- ErrorBadRequest, ErrorConflict, ErrorInternalServerError,
+ ErrorBadRequest, ErrorConflict, ErrorInternalServerError, ErrorNotFound,
ErrorServiceUnavailable, HttpError,
},
HttpResponse, ResponseError,
@@ -15,6 +15,7 @@
Debug, derive_more::Display, derive_more::From, derive_more::Error,
)]
pub enum BackupError {
+ NoBackup,
BlobError(BlobServiceError),
DB(comm_services_lib::database::Error),
}
@@ -23,6 +24,7 @@
fn from(value: &BackupError) -> Self {
trace!("Handling backup service error: {value}");
match value {
+ BackupError::NoBackup => ErrorNotFound("not found"),
BackupError::BlobError(
err @ (BlobServiceError::ClientError(_)
| BlobServiceError::UnexpectedHttpStatus(_)
diff --git a/services/backup/src/http/handlers/backup.rs b/services/backup/src/http/handlers/backup.rs
--- a/services/backup/src/http/handlers/backup.rs
+++ b/services/backup/src/http/handlers/backup.rs
@@ -144,3 +144,66 @@
Ok(blob_info)
}
+
+#[instrument(name = "download_user_keys", skip_all, fields(backup_id = %path.as_str()))]
+pub async fn download_user_keys(
+ user: UserIdentity,
+ path: web::Path<String>,
+ blob_client: web::Data<BlobServiceClient>,
+ db_client: web::Data<DatabaseClient>,
+) -> actix_web::Result<HttpResponse> {
+ info!("Download user keys request");
+ let backup_id = path.into_inner();
+ download_user_blob(
+ |item| &item.user_keys,
+ &user.user_id,
+ &backup_id,
+ blob_client,
+ db_client,
+ )
+ .await
+}
+
+#[instrument(name = "download_user_data", skip_all, fields(backup_id = %path.as_str()))]
+pub async fn download_user_data(
+ user: UserIdentity,
+ path: web::Path<String>,
+ blob_client: web::Data<BlobServiceClient>,
+ db_client: web::Data<DatabaseClient>,
+) -> actix_web::Result<HttpResponse> {
+ info!("Download user data request");
+ let backup_id = path.into_inner();
+ download_user_blob(
+ |item| &item.user_data,
+ &user.user_id,
+ &backup_id,
+ blob_client,
+ db_client,
+ )
+ .await
+}
+
+pub async fn download_user_blob(
+ data_extractor: impl FnOnce(&BackupItem) -> &BlobInfo,
+ user_id: &str,
+ backup_id: &str,
+ blob_client: web::Data<BlobServiceClient>,
+ db_client: web::Data<DatabaseClient>,
+) -> actix_web::Result<HttpResponse> {
+ let backup_item = db_client
+ .find_backup_item(user_id, backup_id)
+ .await
+ .map_err(BackupError::from)?
+ .ok_or(BackupError::NoBackup)?;
+
+ let stream = blob_client
+ .get(&data_extractor(&backup_item).blob_hash)
+ .await
+ .map_err(BackupError::from)?;
+
+ Ok(
+ HttpResponse::Ok()
+ .content_type("application/octet-stream")
+ .streaming(stream),
+ )
+}
diff --git a/services/backup/src/http/mod.rs b/services/backup/src/http/mod.rs
--- a/services/backup/src/http/mod.rs
+++ b/services/backup/src/http/mod.rs
@@ -25,8 +25,6 @@
let blob = web::Data::new(blob_client);
HttpServer::new(move || {
- let auth_middleware = get_comm_authentication_middleware();
-
App::new()
.wrap(tracing_actix_web::TracingLogger::default())
.wrap(comm_services_lib::http::cors_config(
@@ -35,9 +33,20 @@
.app_data(db.clone())
.app_data(blob.clone())
.service(
- web::resource("/backups")
- .route(web::post().to(handlers::backup::upload))
- .wrap(auth_middleware),
+ // Services requiring authetication
+ web::scope("/backups")
+ .wrap(get_comm_authentication_middleware())
+ .service(
+ web::resource("").route(web::post().to(handlers::backup::upload)),
+ )
+ .service(
+ web::resource("{backup_id}/user_keys")
+ .route(web::get().to(handlers::backup::download_user_keys)),
+ )
+ .service(
+ web::resource("{backup_id}/user_data")
+ .route(web::get().to(handlers::backup::download_user_data)),
+ ),
)
})
.bind(("0.0.0.0", CONFIG.http_port))?

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 23, 8:20 AM (17 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2569859
Default Alt Text
D8964.diff (5 KB)

Event Timeline