Skip to content

Commit fab656c

Browse files
author
Devdutt Shenoi
committed
refactor as own middleware
1 parent 61cbf25 commit fab656c

File tree

4 files changed

+8
-93
lines changed

4 files changed

+8
-93
lines changed

src/audit.rs

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,8 @@ use std::{collections::HashMap, fmt::Debug, sync::Arc};
22

33
use crate::about::current;
44
use crate::handlers::http::modal::utils::rbac_utils::get_metadata;
5-
use crate::rbac::map::SessionKey;
6-
use crate::rbac::Users;
75

86
use super::option::CONFIG;
9-
use actix_web::dev::ServiceRequest;
10-
use actix_web_httpauth::extractors::basic::BasicAuth;
117
use chrono::{DateTime, Utc};
128
use reqwest::Client;
139
use serde::Serialize;
@@ -156,8 +152,6 @@ impl Default for ResponseLog {
156152
}
157153
}
158154

159-
const DROP_HEADERS: [&str; 4] = ["authorization", "cookie", "user-agent", "x-p-stream"];
160-
161155
pub struct AuditLogBuilder {
162156
version: AuditLogVersion,
163157
deployment_id: Ulid,
@@ -196,59 +190,6 @@ impl AuditLogBuilder {
196190
pub fn set_stream_name(&mut self, stream: String) {
197191
self.stream = stream;
198192
}
199-
200-
pub fn update_from_http(&mut self, req: &mut ServiceRequest) {
201-
let mut username = "Unknown".to_owned();
202-
let mut authorization_method = "None".to_owned();
203-
204-
// Extract authorization details from request, either from basic auth
205-
// header or cookie, else use default value.
206-
if let Ok(creds) = req.extract::<BasicAuth>().into_inner() {
207-
username = creds.user_id().trim().to_owned();
208-
authorization_method = "Basic Auth".to_owned();
209-
} else if let Some(cookie) = req.cookie("session") {
210-
authorization_method = "Session Cookie".to_owned();
211-
if let Some(user_id) = Ulid::from_string(cookie.value())
212-
.ok()
213-
.and_then(|ulid| Users.get_username_from_session(&SessionKey::SessionId(ulid)))
214-
{
215-
username = user_id;
216-
}
217-
}
218-
219-
let conn = req.connection_info();
220-
self.request = RequestLog {
221-
method: req.method().to_string(),
222-
path: req.path().to_string(),
223-
protocol: conn.scheme().to_owned(),
224-
headers: req
225-
.headers()
226-
.iter()
227-
.filter_map(|(name, value)| match name.as_str() {
228-
// NOTE: drop headers that are not required
229-
name if DROP_HEADERS.contains(&name.to_lowercase().as_str()) => None,
230-
name => {
231-
// NOTE: Drop headers that can't be parsed as string
232-
value
233-
.to_str()
234-
.map(|value| (name.to_owned(), value.to_string()))
235-
.ok()
236-
}
237-
})
238-
.collect(),
239-
};
240-
self.actor = ActorLog {
241-
remote_host: conn.realip_remote_addr().unwrap_or_default().to_owned(),
242-
user_agent: req
243-
.headers()
244-
.get("User-Agent")
245-
.and_then(|a| a.to_str().ok())
246-
.unwrap_or_default()
247-
.to_owned(),
248-
username,
249-
authorization_method,
250-
}
251-
}
252193
}
253194

254195
impl Drop for AuditLogBuilder {

src/handlers/http/middleware.rs

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ use actix_web::{
2828
use futures_util::future::LocalBoxFuture;
2929

3030
use crate::{
31-
audit::AuditLogBuilder,
3231
handlers::{
3332
AUTHORIZATION_KEY, KINESIS_COMMON_ATTRIBUTES_KEY, LOG_SOURCE_KEY, LOG_SOURCE_KINESIS,
3433
STREAM_NAME_HEADER_KEY,
@@ -46,16 +45,16 @@ use serde::{Deserialize, Serialize};
4645

4746
#[derive(Serialize, Deserialize, Debug)]
4847
#[serde(rename_all = "camelCase")]
49-
struct Message {
50-
common_attributes: CommonAttributes,
48+
pub struct Message {
49+
pub common_attributes: CommonAttributes,
5150
}
5251

5352
#[derive(Serialize, Deserialize, Debug)]
54-
struct CommonAttributes {
53+
pub struct CommonAttributes {
5554
#[serde(rename = "Authorization")]
5655
authorization: String,
5756
#[serde(rename = "X-P-Stream")]
58-
x_p_stream: String,
57+
pub x_p_stream: String,
5958
}
6059

6160
pub trait RouteExt {
@@ -138,7 +137,6 @@ where
138137
For requests made from other clients, no change.
139138
140139
## Section start */
141-
let mut stream_name = None;
142140
if let Some(kinesis_common_attributes) =
143141
req.request().headers().get(KINESIS_COMMON_ATTRIBUTES_KEY)
144142
{
@@ -156,27 +154,14 @@ where
156154
HeaderName::from_static(LOG_SOURCE_KEY),
157155
header::HeaderValue::from_static(LOG_SOURCE_KINESIS),
158156
);
159-
stream_name.replace(message.common_attributes.x_p_stream);
160-
} else if let Some(stream) = req.match_info().get("logstream") {
161-
stream_name.replace(stream.to_owned());
162-
} else if let Some(value) = req.headers().get(STREAM_NAME_HEADER_KEY) {
163-
if let Ok(stream) = value.to_str() {
164-
stream_name.replace(stream.to_owned());
165-
}
166157
}
167158

168159
/* ## Section end */
169160

170161
let auth_result: Result<_, Error> = (self.auth_method)(&mut req, self.action);
171162

172-
// Ensures that log will be pushed to subscriber on drop
173-
let mut log_builder = AuditLogBuilder::default();
174-
log_builder.set_stream_name(stream_name.unwrap_or_default());
175-
log_builder.update_from_http(&mut req);
176163
let fut = self.service.call(req);
177164
Box::pin(async move {
178-
log_builder.set_deployment_id().await;
179-
180165
match auth_result? {
181166
rbac::Response::UnAuthorized => return Err(
182167
ErrorForbidden("You don't have permission to access this resource. Please contact your administrator for assistance.")
@@ -186,22 +171,8 @@ where
186171
),
187172
_ => {}
188173
}
189-
let res = fut.await;
190-
191-
// Capture status_code and error information from response
192-
match &res {
193-
Ok(res) => {
194-
let status = res.status();
195-
log_builder.response.status_code = status.as_u16();
196-
// Use error information from reponse object if an error
197-
if let Some(err) = res.response().error() {
198-
log_builder.set_response_error(err.to_string());
199-
}
200-
}
201-
Err(err) => log_builder.set_response_error(err.to_string()),
202-
}
203174

204-
res
175+
fut.await
205176
})
206177
}
207178
}

src/handlers/http/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use crate::{option::CONFIG, storage::STREAM_ROOT_DIRECTORY};
2828
use self::{cluster::get_ingestor_info, query::Query};
2929

3030
pub mod about;
31+
mod audit;
3132
pub mod cluster;
3233
pub mod correlation;
3334
pub mod health_check;

src/handlers/http/modal/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ use ssl_acceptor::get_ssl_acceptor;
4141
use tokio::sync::{oneshot, Mutex};
4242
use tracing::{error, info, warn};
4343

44+
use super::audit;
4445
use super::cross_origin_config;
4546
use super::API_BASE_PATH;
4647
use super::API_VERSION;
@@ -101,6 +102,7 @@ pub trait ParseableServer {
101102
.wrap(prometheus.clone())
102103
.configure(|config| Self::configure_routes(config, oidc_client.clone()))
103104
.wrap(from_fn(health_check::check_shutdown_middleware))
105+
.wrap(from_fn(audit::audit_log_middleware))
104106
.wrap(actix_web::middleware::Logger::default())
105107
.wrap(actix_web::middleware::Compress::default())
106108
.wrap(cross_origin_config())

0 commit comments

Comments
 (0)