feat(imap): bring back oauth2 logic

This commit is contained in:
dignifiedquire
2019-05-12 23:45:11 +02:00
parent ab94fddde2
commit d480209cfa

View File

@@ -7,10 +7,12 @@ use crate::constants::*;
use crate::dc_context::dc_context_t; use crate::dc_context::dc_context_t;
use crate::dc_log::*; use crate::dc_log::*;
use crate::dc_loginparam::*; use crate::dc_loginparam::*;
use crate::dc_oauth2::dc_get_oauth2_access_token;
use crate::dc_sqlite3::*; use crate::dc_sqlite3::*;
use crate::types::*; use crate::types::*;
pub const DC_IMAP_SEEN: usize = 0x0001; pub const DC_IMAP_SEEN: usize = 0x0001;
pub const DC_REGENERATE: usize = 0x01;
pub const DC_SUCCESS: usize = 3; pub const DC_SUCCESS: usize = 3;
pub const DC_ALREADY_DONE: usize = 2; pub const DC_ALREADY_DONE: usize = 2;
@@ -34,6 +36,23 @@ pub struct Imap {
session: Arc<Mutex<(Option<Session>, Option<net::TcpStream>)>>, session: Arc<Mutex<(Option<Session>, Option<net::TcpStream>)>>,
} }
struct OAuth2 {
user: String,
access_token: String,
}
impl imap::Authenticator for OAuth2 {
type Response = String;
#[allow(unused_variables)]
fn process(&self, data: &[u8]) -> Self::Response {
format!(
"user={}\x01auth=Bearer {}\x01\x01",
self.user, self.access_token
)
}
}
#[derive(Debug)] #[derive(Debug)]
pub enum FolderMeaning { pub enum FolderMeaning {
Unknown, Unknown,
@@ -121,6 +140,23 @@ impl Client {
} }
} }
pub fn authenticate<A: imap::Authenticator, S: AsRef<str>>(
self,
auth_type: S,
authenticator: &A,
) -> Result<(Session, net::TcpStream), (imap::error::Error, Client)> {
match self {
Client::Secure(i, stream) => match i.authenticate(auth_type, authenticator) {
Ok(session) => Ok((Session::Secure(session), stream)),
Err((err, c)) => Err((err, Client::Secure(c, stream))),
},
Client::Insecure(i, stream) => match i.authenticate(auth_type, authenticator) {
Ok(session) => Ok((Session::Insecure(session), stream)),
Err((err, c)) => Err((err, Client::Insecure(c, stream))),
},
}
}
pub fn login<U: AsRef<str>, P: AsRef<str>>( pub fn login<U: AsRef<str>, P: AsRef<str>>(
self, self,
username: U, username: U,
@@ -365,10 +401,48 @@ impl Imap {
Client::connect_secure((imap_server, imap_port), imap_server) Client::connect_secure((imap_server, imap_port), imap_server)
}; };
match connection_res { let login_res = match connection_res {
Ok(client) => { Ok(client) => {
// TODO: handle oauth2 if (server_flags & DC_LP_AUTH_OAUTH2) != 0 {
match client.login(imap_user, imap_pw) { let access_token = unsafe {
CStr::from_ptr(dc_get_oauth2_access_token(
context,
lp.addr,
lp.mail_pw,
DC_REGENERATE as libc::c_int,
))
.to_str()
.unwrap()
};
let auth = OAuth2 {
user: imap_user.into(),
access_token: access_token.into(),
};
client.authenticate("XOAUTH2", &auth)
} else {
client.login(imap_user, imap_pw)
}
}
Err(err) => {
eprintln!("failed to connect: {:?}", err);
unsafe {
dc_log_event_seq(
context,
Event::ERROR_NETWORK,
&mut 0 as *mut i32,
b"Could not connect to IMAP-server %s:%i.\x00" as *const u8
as *const libc::c_char,
imap_server,
imap_port as usize as libc::c_int,
)
};
return 0;
}
};
match login_res {
Ok((mut session, stream)) => { Ok((mut session, stream)) => {
// TODO: error handling // TODO: error handling
let caps = session.capabilities().unwrap(); let caps = session.capabilities().unwrap();
@@ -414,24 +488,6 @@ impl Imap {
} }
} }
} }
Err(err) => {
eprintln!("failed to connect: {:?}", err);
unsafe {
dc_log_event_seq(
context,
Event::ERROR_NETWORK,
&mut 0 as *mut i32,
b"Could not connect to IMAP-server %s:%i.\x00" as *const u8
as *const libc::c_char,
imap_server,
imap_port as usize as libc::c_int,
)
};
0
}
}
}
pub fn disconnect(&self, context: &dc_context_t) { pub fn disconnect(&self, context: &dc_context_t) {
let session = self.session.lock().unwrap().0.take(); let session = self.session.lock().unwrap().0.take();