diff options
author | mdecimus <mauro@stalw.art> | 2024-09-12 17:42:14 +0200 |
---|---|---|
committer | mdecimus <mauro@stalw.art> | 2024-09-12 17:42:14 +0200 |
commit | d214468c54415f3048f0246eb176f6d25a3acdd2 (patch) | |
tree | adc9eaefdbd9c7a57f5c7a83fed41c92fe5d590b /crates/smtp | |
parent | fbcf55d8e1891b72499fed7d5ff54964c8a2f256 (diff) |
Roles and multi-tenancy - part 1
Diffstat (limited to 'crates/smtp')
-rw-r--r-- | crates/smtp/src/inbound/auth.rs | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/crates/smtp/src/inbound/auth.rs b/crates/smtp/src/inbound/auth.rs index d7ff8c24..419b4dab 100644 --- a/crates/smtp/src/inbound/auth.rs +++ b/crates/smtp/src/inbound/auth.rs @@ -5,11 +5,11 @@ */ use common::listener::SessionStream; -use directory::backend::internal::PrincipalField; +use directory::{backend::internal::PrincipalField, Permission}; use mail_parser::decoders::base64::base64_decode; use mail_send::Credentials; use smtp_proto::{IntoString, AUTH_LOGIN, AUTH_OAUTHBEARER, AUTH_PLAIN, AUTH_XOAUTH2}; -use trc::{AuthEvent, SmtpEvent}; +use trc::{AddContext, AuthEvent, SmtpEvent}; use crate::core::Session; @@ -165,7 +165,9 @@ impl<T: SessionStream> Session<T> { | Credentials::XOauth2 { username, .. } | Credentials::OAuthBearer { token: username } => username.to_string(), }; - match self + + // Authenticate + let mut result = self .core .core .authenticate( @@ -175,10 +177,35 @@ impl<T: SessionStream> Session<T> { self.data.remote_ip, false, ) - .await - { + .await; + + // Validate permissions + if let Ok(principal) = &result { + match self + .core + .core + .get_cached_access_token(principal.id()) + .await + .caused_by(trc::location!()) + { + Ok(access_token) => { + if let Err(err) = access_token + .assert_has_permission(Permission::EmailSend) + .and_then(|_| { + access_token.assert_has_permission(Permission::Authenticate) + }) + { + result = Err(err); + } + } + Err(err) => { + result = Err(err); + } + } + } + + match result { Ok(principal) => { - let todo = "check smtp auth permissions"; self.data.authenticated_as = authenticated_as.to_lowercase(); self.data.authenticated_emails = principal .iter_str(PrincipalField::Emails) @@ -207,6 +234,11 @@ impl<T: SessionStream> Session<T> { ) .await; } + trc::EventType::Security(trc::SecurityEvent::Unauthorized) => { + self.write(b"550 5.7.1 Your account is not authorized to use this service.\r\n") + .await?; + return Ok(false); + } trc::EventType::Security(_) => { return Err(()); } |