OAUTHBEARER SASL support in all services (closes #627)
This commit is contained in:
@@ -5,14 +5,13 @@
|
||||
*/
|
||||
|
||||
use common::{
|
||||
auth::AuthRequest,
|
||||
listener::{limiter::ConcurrencyLimiter, SessionStream},
|
||||
ConcurrencyLimiters,
|
||||
};
|
||||
use directory::Permission;
|
||||
use imap::op::authenticate::{decode_challenge_oauth, decode_challenge_plain};
|
||||
use jmap::auth::{
|
||||
authenticate::Authenticator, oauth::token::TokenHandler, rate_limit::RateLimiter,
|
||||
};
|
||||
use jmap::auth::rate_limit::RateLimiter;
|
||||
use mail_parser::decoders::base64::base64_decode;
|
||||
use mail_send::Credentials;
|
||||
use std::sync::Arc;
|
||||
@@ -68,43 +67,39 @@ impl<T: SessionStream> Session<T> {
|
||||
self.server.is_auth_allowed_soft(&self.remote_addr).await?;
|
||||
|
||||
// Authenticate
|
||||
let access_token = match credentials {
|
||||
Credentials::Plain { username, secret } | Credentials::XOauth2 { username, secret } => {
|
||||
self.server
|
||||
.authenticate_plain(&username, &secret, self.remote_addr, self.session_id)
|
||||
.await
|
||||
}
|
||||
Credentials::OAuthBearer { token } => {
|
||||
match self
|
||||
.server
|
||||
.validate_access_token("access_token", &token)
|
||||
.await
|
||||
{
|
||||
Ok((account_id, _, _)) => self.server.get_access_token(account_id).await,
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
.map_err(|err| {
|
||||
if err.matches(trc::EventType::Auth(trc::AuthEvent::Failed)) {
|
||||
match &self.state {
|
||||
State::NotAuthenticated {
|
||||
auth_failures,
|
||||
username,
|
||||
} if *auth_failures < self.server.core.imap.max_auth_failures => {
|
||||
self.state = State::NotAuthenticated {
|
||||
auth_failures: auth_failures + 1,
|
||||
username: username.clone(),
|
||||
};
|
||||
}
|
||||
_ => {
|
||||
return trc::AuthEvent::TooManyAttempts.into_err().caused_by(err);
|
||||
let access_token = self
|
||||
.server
|
||||
.authenticate(&AuthRequest::from_credentials(
|
||||
credentials,
|
||||
self.session_id,
|
||||
self.remote_addr,
|
||||
))
|
||||
.await
|
||||
.map_err(|err| {
|
||||
if err.matches(trc::EventType::Auth(trc::AuthEvent::Failed)) {
|
||||
match &self.state {
|
||||
State::NotAuthenticated {
|
||||
auth_failures,
|
||||
username,
|
||||
} if *auth_failures < self.server.core.imap.max_auth_failures => {
|
||||
self.state = State::NotAuthenticated {
|
||||
auth_failures: auth_failures + 1,
|
||||
username: username.clone(),
|
||||
};
|
||||
}
|
||||
_ => {
|
||||
return trc::AuthEvent::TooManyAttempts.into_err().caused_by(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err
|
||||
})?;
|
||||
err
|
||||
})
|
||||
.and_then(|token| {
|
||||
token
|
||||
.assert_has_permission(Permission::Pop3Authenticate)
|
||||
.map(|_| token)
|
||||
})?;
|
||||
|
||||
// Enforce concurrency limits
|
||||
let in_flight = match self
|
||||
@@ -118,13 +113,6 @@ impl<T: SessionStream> Session<T> {
|
||||
}
|
||||
};
|
||||
|
||||
// Validate access
|
||||
access_token.assert_has_permission(Permission::Pop3Authenticate)?;
|
||||
|
||||
// Cache access token
|
||||
let access_token = Arc::new(access_token);
|
||||
self.server.cache_access_token(access_token.clone());
|
||||
|
||||
// Fetch mailbox
|
||||
let mailbox = self.fetch_mailbox(access_token.primary_id()).await?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user