Revision control
Copy as Markdown
Other Tools
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
use base64::prelude::{Engine, BASE64_STANDARD};
use ews::{get_item::GetItem, Operation};
use mailnews_ui_glue::UserInteractiveServer;
use xpcom::RefCounted;
use super::{DoOperation, XpComEwsClient, XpComEwsError};
use crate::{
authentication::credentials::AuthenticationProvider, safe_xpcom::SafeEwsMessageFetchListener,
};
struct DoGetMessage<'a> {
pub listener: &'a SafeEwsMessageFetchListener,
pub id: String,
}
impl DoOperation for DoGetMessage<'_> {
const NAME: &'static str = GetItem::NAME;
type Okay = ();
type Listener = SafeEwsMessageFetchListener;
async fn do_operation<ServerT>(
&mut self,
client: &XpComEwsClient<ServerT>,
) -> Result<Self::Okay, XpComEwsError>
where
ServerT: AuthenticationProvider + UserInteractiveServer + RefCounted,
{
self.listener.on_fetch_start()?;
let items = client.get_items([self.id.clone()], &[], true).await?;
if items.len() != 1 {
return Err(XpComEwsError::Processing {
message: format!(
"provided single ID to GetItem operation, got {} responses",
items.len()
),
});
}
// Extract the Internet Message Format content of the message from the
// response. We've guaranteed above that the iteration will produce
// at least one element, so unwrapping is okay here.
let item = items.into_iter().next().unwrap();
let message = item.inner_message();
let raw_mime = if let Some(raw_mime) = &message.mime_content {
&raw_mime.content
} else {
return Err(XpComEwsError::Processing {
message: "item has no content".to_string(),
});
};
// EWS returns the content of the email b64encoded on top of any
// encoding within the message.
let mime_content =
BASE64_STANDARD
.decode(raw_mime)
.map_err(|_| XpComEwsError::Processing {
message: "MIME content for item is not validly base64 encoded".to_string(),
})?;
self.listener.on_fetched_data_available(mime_content)
}
fn into_success_arg(self, _ok: Self::Okay) {}
fn into_failure_arg(self) {}
}
impl<ServerT> XpComEwsClient<ServerT>
where
ServerT: AuthenticationProvider + UserInteractiveServer + RefCounted,
{
pub(crate) async fn get_message(self, listener: SafeEwsMessageFetchListener, id: String) {
let operation = DoGetMessage {
listener: &listener,
id,
};
operation.handle_operation(&self, &listener).await;
}
}