Page MenuHomePhorge

D9282.1769047618.diff
No OneTemporary

Size
4 KB
Referenced Files
None
Subscribers
None

D9282.1769047618.diff

diff --git a/services/reports/src/service.rs b/services/reports/src/service.rs
--- a/services/reports/src/service.rs
+++ b/services/reports/src/service.rs
@@ -1,7 +1,7 @@
use actix_web::FromRequest;
use chrono::Utc;
use comm_services_lib::{
- auth::UserIdentity,
+ auth::{AuthService, AuthorizationCredential},
blob::client::{BlobServiceClient, BlobServiceError},
crypto::aes256,
database,
@@ -9,10 +9,11 @@
use derive_more::{Display, Error, From};
use std::{
collections::HashMap,
- future::{ready, Ready},
+ future::{ready, Future},
+ pin::Pin,
sync::Arc,
};
-use tracing::{error, trace};
+use tracing::{error, trace, warn};
use crate::{
config::CONFIG,
@@ -71,13 +72,20 @@
}
}
- pub fn authenticated(&self, user: UserIdentity) -> Self {
- let user_id = user.user_id.to_string();
+ /// Clones the service with a new auth identity. When the credential is
+ /// a service-to-service, the `user_id` is None.
+ pub fn with_authentication(&self, token: AuthorizationCredential) -> Self {
+ let requesting_user_id = match &token {
+ AuthorizationCredential::ServicesToken(_) => None,
+ AuthorizationCredential::UserToken(user) => {
+ Some(user.user_id.to_string())
+ }
+ };
Self {
db: self.db.clone(),
email_config: self.email_config.clone(),
- blob_client: self.blob_client.with_user_identity(user),
- requesting_user_id: Some(user_id),
+ blob_client: self.blob_client.with_authentication(token),
+ requesting_user_id,
}
}
@@ -195,35 +203,62 @@
impl FromRequest for ReportsService {
type Error = actix_web::Error;
- type Future = Ready<Result<Self, actix_web::Error>>;
+ type Future = Pin<Box<dyn Future<Output = Result<Self, actix_web::Error>>>>;
#[inline]
fn from_request(
req: &actix_web::HttpRequest,
_payload: &mut actix_web::dev::Payload,
) -> Self::Future {
+ use actix_web::error::{ErrorForbidden, ErrorInternalServerError};
use actix_web::HttpMessage;
- let Some(service) = req.app_data::<ReportsService>() else {
- tracing::error!(
- "FATAL! Failed to extract ReportsService from actix app_data. \
- Check HTTP server configuration"
- );
- return ready(Err(actix_web::error::ErrorInternalServerError("Internal server error")));
- };
+ let base_service =
+ req.app_data::<ReportsService>().cloned().ok_or_else(|| {
+ tracing::error!(
+ "FATAL! Failed to extract ReportsService from actix app_data. \
+ Check HTTP server configuration"
+ );
+ ErrorInternalServerError("Internal server error")
+ });
let auth_service =
- if let Some(user_identity) = req.extensions().get::<UserIdentity>() {
- tracing::trace!("Found user identity. Creating authenticated service");
- service.authenticated(user_identity.clone())
- } else {
- tracing::trace!(
- "No user identity found. Leaving unauthenticated service"
+ req.app_data::<AuthService>().cloned().ok_or_else(|| {
+ tracing::error!(
+ "FATAL! Failed to extract AuthService from actix app_data. \
+ Check HTTP server configuration"
);
- service.clone()
- };
+ ErrorInternalServerError("Internal server error")
+ });
- ready(Ok(auth_service))
+ let request_auth_value =
+ req.extensions().get::<AuthorizationCredential>().cloned();
+
+ Box::pin(async move {
+ let auth_service = auth_service?;
+ let base_service = base_service?;
+
+ // This is Some for endpoints hidden behind auth validation middleware
+ let auth_token = match request_auth_value {
+ Some(token @ AuthorizationCredential::UserToken(_)) => token,
+ Some(_) => {
+ // Reports service shouldn't be called by other services
+ warn!("Reports service requires user authorization");
+ return Err(ErrorForbidden("Forbidden"));
+ }
+ None => {
+ // Unauthenticated requests get a service-to-service token
+ let services_token =
+ auth_service.get_services_token().await.map_err(|err| {
+ error!("Failed to get services token: {err}");
+ ErrorInternalServerError("Internal server error")
+ })?;
+ AuthorizationCredential::ServicesToken(services_token)
+ }
+ };
+ let service = base_service.with_authentication(auth_token);
+ Ok(service)
+ })
}
}

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 22, 2:06 AM (2 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5973323
Default Alt Text
D9282.1769047618.diff (4 KB)

Event Timeline