melib/jmap: Implement Bearer token authentication
Fastmail now uses an API token in a http header for authentication. This can be used either as a server_password or provided by a server_password_command like oauth2.
parent
2447a2cbfe
commit
275f262ffa
|
@ -89,6 +89,7 @@ pub struct JmapServerConf {
|
||||||
pub server_url: String,
|
pub server_url: String,
|
||||||
pub server_username: String,
|
pub server_username: String,
|
||||||
pub server_password: String,
|
pub server_password: String,
|
||||||
|
pub use_token: bool,
|
||||||
pub danger_accept_invalid_certs: bool,
|
pub danger_accept_invalid_certs: bool,
|
||||||
pub timeout: Option<Duration>,
|
pub timeout: Option<Duration>,
|
||||||
}
|
}
|
||||||
|
@ -123,10 +124,22 @@ macro_rules! get_conf_val {
|
||||||
|
|
||||||
impl JmapServerConf {
|
impl JmapServerConf {
|
||||||
pub fn new(s: &AccountSettings) -> Result<Self> {
|
pub fn new(s: &AccountSettings) -> Result<Self> {
|
||||||
|
let use_token: bool = get_conf_val!(s["use_token"], false)?;
|
||||||
|
|
||||||
|
if use_token
|
||||||
|
&& !(s.extra.contains_key("server_password_command")
|
||||||
|
^ s.extra.contains_key("server_password"))
|
||||||
|
{
|
||||||
|
return Err(Error::new(format!(
|
||||||
|
"({}) `use_token` use requires either the `server_password_command` set with a command that returns an Bearer token of your account, or `server_password` with the API Bearer token as a string. Consult documentation for guidance.",
|
||||||
|
s.name,
|
||||||
|
)));
|
||||||
|
}
|
||||||
Ok(JmapServerConf {
|
Ok(JmapServerConf {
|
||||||
server_url: get_conf_val!(s["server_url"])?.to_string(),
|
server_url: get_conf_val!(s["server_url"])?.to_string(),
|
||||||
server_username: get_conf_val!(s["server_username"])?.to_string(),
|
server_username: get_conf_val!(s["server_username"])?.to_string(),
|
||||||
server_password: s.server_password()?,
|
server_password: s.server_password()?,
|
||||||
|
use_token,
|
||||||
danger_accept_invalid_certs: get_conf_val!(s["danger_accept_invalid_certs"], false)?,
|
danger_accept_invalid_certs: get_conf_val!(s["danger_accept_invalid_certs"], false)?,
|
||||||
timeout: get_conf_val!(s["timeout"], 16_u64).map(|t| {
|
timeout: get_conf_val!(s["timeout"], 16_u64).map(|t| {
|
||||||
if t == 0 {
|
if t == 0 {
|
||||||
|
@ -919,6 +932,7 @@ impl JmapType {
|
||||||
get_conf_val!(s["server_url"])?;
|
get_conf_val!(s["server_url"])?;
|
||||||
get_conf_val!(s["server_username"])?;
|
get_conf_val!(s["server_username"])?;
|
||||||
|
|
||||||
|
get_conf_val!(s["use_token"], false)?;
|
||||||
// either of these two needed
|
// either of these two needed
|
||||||
get_conf_val!(s["server_password"]).or(get_conf_val!(s["server_password_command"]))?;
|
get_conf_val!(s["server_password"]).or(get_conf_val!(s["server_password_command"]))?;
|
||||||
|
|
||||||
|
|
|
@ -36,13 +36,26 @@ impl JmapConnection {
|
||||||
pub fn new(server_conf: &JmapServerConf, store: Arc<Store>) -> Result<Self> {
|
pub fn new(server_conf: &JmapServerConf, store: Arc<Store>) -> Result<Self> {
|
||||||
let client = HttpClient::builder()
|
let client = HttpClient::builder()
|
||||||
.timeout(std::time::Duration::from_secs(10))
|
.timeout(std::time::Duration::from_secs(10))
|
||||||
.redirect_policy(RedirectPolicy::Limit(10))
|
.connection_cache_size(8)
|
||||||
.authentication(isahc::auth::Authentication::basic())
|
.connection_cache_ttl(std::time::Duration::from_secs(30 * 60))
|
||||||
.credentials(isahc::auth::Credentials::new(
|
.default_header("Content-Type", "application/json")
|
||||||
&server_conf.server_username,
|
.redirect_policy(RedirectPolicy::Limit(10));
|
||||||
&server_conf.server_password,
|
let client = if server_conf.use_token {
|
||||||
))
|
client
|
||||||
.build()?;
|
.authentication(isahc::auth::Authentication::none())
|
||||||
|
.default_header(
|
||||||
|
"Authorization",
|
||||||
|
format!("Bearer {}", &server_conf.server_password),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
client
|
||||||
|
.authentication(isahc::auth::Authentication::basic())
|
||||||
|
.credentials(isahc::auth::Credentials::new(
|
||||||
|
&server_conf.server_username,
|
||||||
|
&server_conf.server_password,
|
||||||
|
))
|
||||||
|
};
|
||||||
|
let client = client.build()?;
|
||||||
let server_conf = server_conf.clone();
|
let server_conf = server_conf.clone();
|
||||||
Ok(JmapConnection {
|
Ok(JmapConnection {
|
||||||
session: Arc::new(Mutex::new(Default::default())),
|
session: Arc::new(Mutex::new(Default::default())),
|
||||||
|
|
Loading…
Reference in New Issue