OAUTHBEARER SASL support in all services (closes #627)

This commit is contained in:
mdecimus
2024-09-26 18:59:07 +02:00
parent ce8182ae07
commit 0fbf574651
43 changed files with 932 additions and 814 deletions

View File

@@ -4,16 +4,14 @@
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use common::listener::SessionStream;
use common::{auth::AuthRequest, listener::SessionStream};
use directory::Permission;
use imap_proto::{
protocol::{authenticate::Mechanism, capability::Capability},
receiver::{self, Request},
Command, ResponseCode, StatusResponse,
};
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;
@@ -79,37 +77,33 @@ impl<T: SessionStream> Session<T> {
.map_err(|err| err.id(tag.clone()))?;
// 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),
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)) {
let auth_failures = self.state.auth_failures();
if auth_failures < self.server.core.imap.max_auth_failures {
self.state = State::NotAuthenticated {
auth_failures: auth_failures + 1,
};
} else {
return trc::AuthEvent::TooManyAttempts.into_err().caused_by(err);
}
}
}
}
.map_err(|err| {
if err.matches(trc::EventType::Auth(trc::AuthEvent::Failed)) {
let auth_failures = self.state.auth_failures();
if auth_failures < self.server.core.imap.max_auth_failures {
self.state = State::NotAuthenticated {
auth_failures: auth_failures + 1,
};
} else {
return trc::AuthEvent::TooManyAttempts.into_err().caused_by(err);
}
}
err.id(tag.clone())
})?;
err.id(tag.clone())
})
.and_then(|token| {
token
.assert_has_permission(Permission::ImapAuthenticate)
.map(|_| token)
})?;
// Enforce concurrency limits
let in_flight = match self
@@ -125,13 +119,6 @@ impl<T: SessionStream> Session<T> {
}
};
// Validate access
access_token.assert_has_permission(Permission::ImapAuthenticate)?;
// Cache access token
let access_token = Arc::new(access_token);
self.server.cache_access_token(access_token.clone());
// Create session
self.state = State::Authenticated {
data: Arc::new(