Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F33486430
D9282.1769047618.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D9282.1769047618.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D9282: [reports-service] Obtain service-to-service token for anonymous requests
Attached
Detach File
Event Timeline
Log In to Comment