OAUTHBEARER SASL support in all services (closes #627)
This commit is contained in:
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user