Page MenuHomePhabricator

D13873.id45607.diff
No OneTemporary

D13873.id45607.diff

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
@@ -8,7 +8,7 @@
pub use aws_sdk_dynamodb::Error as DynamoDBError;
use comm_lib::database::Error as DBError;
use comm_lib::{auth::AuthServiceError, blob::client::BlobServiceError};
-use grpc_clients::error::Error as IdentityClientError;
+use grpc_clients::error::Error as IdentityError;
use reqwest::StatusCode;
use tracing::{error, trace, warn};
@@ -21,7 +21,8 @@
BlobError(BlobServiceError),
AuthError(AuthServiceError),
DB(comm_lib::database::Error),
- IdentityClientError(IdentityClientError),
+ IdentityError(IdentityError),
+ BadRequest,
}
impl From<&BackupError> for actix_web::Error {
@@ -68,11 +69,12 @@
ErrorInternalServerError("server error")
}
},
- BackupError::IdentityClientError(err) => {
+ BackupError::IdentityError(err) => {
warn!("Transient identity error occurred: {err}");
ErrorServiceUnavailable("please retry")
}
BackupError::NoUserID => ErrorBadRequest("bad request"),
+ BackupError::BadRequest => ErrorBadRequest("bad request"),
}
}
}
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
@@ -52,46 +52,10 @@
)
.await?;
- let attachments_hashes: Vec<String> =
- match get_text_field(&mut multipart).await? {
- Some((name, attachments)) => {
- if name != "attachments" {
- warn!(
- name,
- "Malformed request: 'attachments' text field expected."
- );
- return Err(ErrorBadRequest("Bad request"));
- }
-
- attachments.lines().map(ToString::to_string).collect()
- }
- None => Vec::new(),
- };
-
- let mut attachments = Vec::new();
- let mut attachments_revokes = Vec::new();
- for attachment_hash in attachments_hashes {
- let (holder, revoke) =
- create_attachment_holder(&attachment_hash, &blob_client).await?;
+ let (attachments, attachments_revokes) =
+ process_attachments(&mut multipart, &blob_client).await?;
- attachments.push(BlobInfo {
- blob_hash: attachment_hash,
- holder,
- });
- attachments_revokes.push(revoke);
- }
-
- let siwe_backup_msg_option: Option<String> =
- match get_text_field(&mut multipart).await? {
- Some((name, siwe_backup_msg)) => {
- if name == "siwe_backup_msg" {
- Some(siwe_backup_msg)
- } else {
- None
- }
- }
- _ => None,
- };
+ let siwe_backup_msg = get_siwe_backup_msg(&mut multipart).await?;
let item = BackupItem::new(
user.user_id.clone(),
@@ -99,7 +63,7 @@
user_keys_blob_info,
user_data_blob_info,
attachments,
- siwe_backup_msg_option,
+ siwe_backup_msg,
);
db_client
@@ -194,7 +158,7 @@
async fn create_attachment_holder<'revoke, 'blob: 'revoke>(
attachment: &str,
blob_client: &'blob BlobServiceClient,
-) -> Result<(String, Defer<'revoke>), BackupError> {
+) -> Result<(BlobInfo, Defer<'revoke>), BackupError> {
let holder = uuid::Uuid::new_v4().to_string();
if !blob_client
@@ -211,7 +175,57 @@
blob_client.schedule_revoke_holder(revoke_hash, revoke_holder)
});
- Ok((holder, revoke_holder))
+ let blob_info = BlobInfo {
+ blob_hash: attachment.to_string(),
+ holder,
+ };
+
+ Ok((blob_info, revoke_holder))
+}
+
+#[instrument(skip_all)]
+async fn process_attachments<'revoke, 'blob: 'revoke>(
+ multipart: &mut actix_multipart::Multipart,
+ blob_client: &'blob BlobServiceClient,
+) -> Result<(Vec<BlobInfo>, Vec<Defer<'revoke>>), BackupError> {
+ let attachments_hashes: Vec<String> = match get_text_field(multipart).await {
+ Ok(Some((name, attachments))) => {
+ if name != "attachments" {
+ warn!(
+ name,
+ "Malformed request: 'attachments' text field expected."
+ );
+ return Err(BackupError::BadRequest);
+ }
+
+ attachments.lines().map(ToString::to_string).collect()
+ }
+ Ok(None) => Vec::new(),
+ Err(_) => return Err(BackupError::BadRequest),
+ };
+
+ let mut attachments = Vec::new();
+ let mut attachments_revokes = Vec::new();
+ for attachment_hash in attachments_hashes {
+ let (attachment, revoke) =
+ create_attachment_holder(&attachment_hash, blob_client).await?;
+ attachments.push(attachment);
+ attachments_revokes.push(revoke);
+ }
+
+ Ok((attachments, attachments_revokes))
+}
+
+#[instrument(skip_all)]
+pub async fn get_siwe_backup_msg(
+ multipart: &mut actix_multipart::Multipart,
+) -> actix_web::Result<Option<String>> {
+ Ok(
+ get_text_field(multipart)
+ .await?
+ .filter(|(name, _)| name == "siwe_backup_msg")
+ .map(|(_, siwe_backup_msg)| siwe_backup_msg),
+ )
}
#[instrument(skip_all, fields(backup_id = %path))]
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
@@ -38,7 +38,7 @@
.app_data(auth_service.to_owned())
.route("/health", web::get().to(HttpResponse::Ok))
.service(
- // Backup services that don't require authetication
+ // Backup services that don't require authentication
web::scope("/backups/latest")
.service(
web::resource("{user_identifier}/backup_info")
@@ -49,9 +49,14 @@
)),
)
.service(
- // Backup services requiring authetication
+ // Backup services requiring authentication
web::scope("/backups")
.wrap(get_comm_authentication_middleware())
+ // Uploads backup data from multipart form data.
+ // This function requires both User Keys and User Data form fields
+ // in order to proceed with the upload.
+ // If either User Keys or User Data is not present in the form data,
+ // the upload will fail.
.service(
web::resource("").route(web::post().to(handlers::backup::upload)),
)

File Metadata

Mime Type
text/plain
Expires
Thu, Nov 7, 3:24 PM (19 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2436760
Default Alt Text
D13873.id45607.diff (6 KB)

Event Timeline