mirror of
https://github.com/chatmail/core.git
synced 2026-05-05 22:36:30 +03:00
feat(imap): bring back oauth2 logic
This commit is contained in:
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user