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
44
45
46
47
48
49
use crate::auth::google::{Google as GoogleAuth, GoogleOAuth2Error as GoogleAuthError};
pub enum Auth {
GmailOAuth2(GoogleAuth),
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>, GoogleAuthError>;
}
#[async_trait::async_trait]
impl GoogleAuthExt for GoogleAuth {
async fn as_imap_oauth2<'a>(
&'a mut self,
email: &'a str,
) -> Result<ImapOAuth2<'a>, GoogleAuthError> {
Ok(ImapOAuth2 {
email,
token: self.access_token().await?,
})
}
}