1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
use crate::{auth, error::Error};
pub enum Auth {
GoogleAuth(auth::Google),
Password(String),
}
pub(super) struct ImapOAuth2<'a> {
email: &'a str,
token: &'a str,
}
impl imap::Authenticator for ImapOAuth2<'_> {
type Response = String;
fn process(&self, _challenge: &[u8]) -> Self::Response {
format!("user={}\x01auth=Bearer {}\x01\x01", self.email, self.token)
}
}
#[async_trait::async_trait]
pub(super) trait GoogleAuthExt {
async fn as_imap_oauth2<'a>(&'a mut self, email: &'a str) -> Result<ImapOAuth2<'a>, Error>;
}
#[async_trait::async_trait]
impl GoogleAuthExt for auth::Google {
async fn as_imap_oauth2<'a>(&'a mut self, email: &'a str) -> Result<ImapOAuth2<'a>, Error> {
Ok(ImapOAuth2 {
email,
token: self.access_token().await?,
})
}
}