feat(analytics): add issuer as filter for authentication analytics (#7535)

This commit is contained in:
Sandeep Kumar
2025-03-18 15:16:09 +05:30
committed by GitHub
parent a161f24773
commit a87471c45d
17 changed files with 42 additions and 0 deletions

View File

@ -169,6 +169,7 @@ pub async fn get_filters(
AuthEventDimensions::ErrorMessage => fil.error_message, AuthEventDimensions::ErrorMessage => fil.error_message,
AuthEventDimensions::AuthenticationConnector => fil.authentication_connector.map(|i| i.as_ref().to_string()), AuthEventDimensions::AuthenticationConnector => fil.authentication_connector.map(|i| i.as_ref().to_string()),
AuthEventDimensions::MessageVersion => fil.message_version, AuthEventDimensions::MessageVersion => fil.message_version,
AuthEventDimensions::AcsReferenceNumber => fil.acs_reference_number,
}) })
.collect::<Vec<String>>(); .collect::<Vec<String>>();
res.query_data.push(AuthEventFilterValue { res.query_data.push(AuthEventFilterValue {

View File

@ -59,4 +59,5 @@ pub struct AuthEventFilterRow {
pub error_message: Option<String>, pub error_message: Option<String>,
pub authentication_connector: Option<DBEnumWrapper<AuthenticationConnectors>>, pub authentication_connector: Option<DBEnumWrapper<AuthenticationConnectors>>,
pub message_version: Option<String>, pub message_version: Option<String>,
pub acs_reference_number: Option<String>,
} }

View File

@ -45,6 +45,7 @@ pub struct AuthEventMetricRow {
pub error_message: Option<String>, pub error_message: Option<String>,
pub authentication_connector: Option<DBEnumWrapper<storage_enums::AuthenticationConnectors>>, pub authentication_connector: Option<DBEnumWrapper<storage_enums::AuthenticationConnectors>>,
pub message_version: Option<String>, pub message_version: Option<String>,
pub acs_reference_number: Option<String>,
#[serde(with = "common_utils::custom_serde::iso8601::option")] #[serde(with = "common_utils::custom_serde::iso8601::option")]
pub start_bucket: Option<PrimitiveDateTime>, pub start_bucket: Option<PrimitiveDateTime>,
#[serde(with = "common_utils::custom_serde::iso8601::option")] #[serde(with = "common_utils::custom_serde::iso8601::option")]

View File

@ -110,6 +110,7 @@ where
i.error_message.clone(), i.error_message.clone(),
i.authentication_connector.as_ref().map(|i| i.0), i.authentication_connector.as_ref().map(|i| i.0),
i.message_version.clone(), i.message_version.clone(),
i.acs_reference_number.clone(),
TimeRange { TimeRange {
start_time: match (granularity, i.start_bucket) { start_time: match (granularity, i.start_bucket) {
(Some(g), Some(st)) => g.clip_to_start(st)?, (Some(g), Some(st)) => g.clip_to_start(st)?,

View File

@ -100,6 +100,7 @@ where
i.error_message.clone(), i.error_message.clone(),
i.authentication_connector.as_ref().map(|i| i.0), i.authentication_connector.as_ref().map(|i| i.0),
i.message_version.clone(), i.message_version.clone(),
i.acs_reference_number.clone(),
TimeRange { TimeRange {
start_time: match (granularity, i.start_bucket) { start_time: match (granularity, i.start_bucket) {
(Some(g), Some(st)) => g.clip_to_start(st)?, (Some(g), Some(st)) => g.clip_to_start(st)?,

View File

@ -119,6 +119,7 @@ where
i.error_message.clone(), i.error_message.clone(),
i.authentication_connector.as_ref().map(|i| i.0), i.authentication_connector.as_ref().map(|i| i.0),
i.message_version.clone(), i.message_version.clone(),
i.acs_reference_number.clone(),
TimeRange { TimeRange {
start_time: match (granularity, i.start_bucket) { start_time: match (granularity, i.start_bucket) {
(Some(g), Some(st)) => g.clip_to_start(st)?, (Some(g), Some(st)) => g.clip_to_start(st)?,

View File

@ -111,6 +111,7 @@ where
i.error_message.clone(), i.error_message.clone(),
i.authentication_connector.as_ref().map(|i| i.0), i.authentication_connector.as_ref().map(|i| i.0),
i.message_version.clone(), i.message_version.clone(),
i.acs_reference_number.clone(),
TimeRange { TimeRange {
start_time: match (granularity, i.start_bucket) { start_time: match (granularity, i.start_bucket) {
(Some(g), Some(st)) => g.clip_to_start(st)?, (Some(g), Some(st)) => g.clip_to_start(st)?,

View File

@ -105,6 +105,7 @@ where
i.error_message.clone(), i.error_message.clone(),
i.authentication_connector.as_ref().map(|i| i.0), i.authentication_connector.as_ref().map(|i| i.0),
i.message_version.clone(), i.message_version.clone(),
i.acs_reference_number.clone(),
TimeRange { TimeRange {
start_time: match (granularity, i.start_bucket) { start_time: match (granularity, i.start_bucket) {
(Some(g), Some(st)) => g.clip_to_start(st)?, (Some(g), Some(st)) => g.clip_to_start(st)?,

View File

@ -115,6 +115,7 @@ where
i.error_message.clone(), i.error_message.clone(),
i.authentication_connector.as_ref().map(|i| i.0), i.authentication_connector.as_ref().map(|i| i.0),
i.message_version.clone(), i.message_version.clone(),
i.acs_reference_number.clone(),
TimeRange { TimeRange {
start_time: match (granularity, i.start_bucket) { start_time: match (granularity, i.start_bucket) {
(Some(g), Some(st)) => g.clip_to_start(st)?, (Some(g), Some(st)) => g.clip_to_start(st)?,

View File

@ -107,6 +107,7 @@ where
i.error_message.clone(), i.error_message.clone(),
i.authentication_connector.as_ref().map(|i| i.0), i.authentication_connector.as_ref().map(|i| i.0),
i.message_version.clone(), i.message_version.clone(),
i.acs_reference_number.clone(),
TimeRange { TimeRange {
start_time: match (granularity, i.start_bucket) { start_time: match (granularity, i.start_bucket) {
(Some(g), Some(st)) => g.clip_to_start(st)?, (Some(g), Some(st)) => g.clip_to_start(st)?,

View File

@ -112,6 +112,7 @@ where
i.error_message.clone(), i.error_message.clone(),
i.authentication_connector.as_ref().map(|i| i.0), i.authentication_connector.as_ref().map(|i| i.0),
i.message_version.clone(), i.message_version.clone(),
i.acs_reference_number.clone(),
TimeRange { TimeRange {
start_time: match (granularity, i.start_bucket) { start_time: match (granularity, i.start_bucket) {
(Some(g), Some(st)) => g.clip_to_start(st)?, (Some(g), Some(st)) => g.clip_to_start(st)?,

View File

@ -108,6 +108,7 @@ where
i.error_message.clone(), i.error_message.clone(),
i.authentication_connector.as_ref().map(|i| i.0), i.authentication_connector.as_ref().map(|i| i.0),
i.message_version.clone(), i.message_version.clone(),
i.acs_reference_number.clone(),
TimeRange { TimeRange {
start_time: match (granularity, i.start_bucket) { start_time: match (granularity, i.start_bucket) {
(Some(g), Some(st)) => g.clip_to_start(st)?, (Some(g), Some(st)) => g.clip_to_start(st)?,

View File

@ -112,6 +112,7 @@ where
i.error_message.clone(), i.error_message.clone(),
i.authentication_connector.as_ref().map(|i| i.0), i.authentication_connector.as_ref().map(|i| i.0),
i.message_version.clone(), i.message_version.clone(),
i.acs_reference_number.clone(),
TimeRange { TimeRange {
start_time: match (granularity, i.start_bucket) { start_time: match (granularity, i.start_bucket) {
(Some(g), Some(st)) => g.clip_to_start(st)?, (Some(g), Some(st)) => g.clip_to_start(st)?,

View File

@ -53,6 +53,15 @@ where
) )
.attach_printable("Error adding message version filter")?; .attach_printable("Error adding message version filter")?;
} }
if !self.acs_reference_number.is_empty() {
builder
.add_filter_in_range_clause(
AuthEventDimensions::AcsReferenceNumber,
&self.acs_reference_number,
)
.attach_printable("Error adding acs reference number filter")?;
}
Ok(()) Ok(())
} }
} }

View File

@ -231,6 +231,11 @@ impl<'a> FromRow<'a, PgRow> for super::auth_events::metrics::AuthEventMetricRow
ColumnNotFound(_) => Ok(Default::default()), ColumnNotFound(_) => Ok(Default::default()),
e => Err(e), e => Err(e),
})?; })?;
let acs_reference_number: Option<String> =
row.try_get("acs_reference_number").or_else(|e| match e {
ColumnNotFound(_) => Ok(Default::default()),
e => Err(e),
})?;
let count: Option<i64> = row.try_get("count").or_else(|e| match e { let count: Option<i64> = row.try_get("count").or_else(|e| match e {
ColumnNotFound(_) => Ok(Default::default()), ColumnNotFound(_) => Ok(Default::default()),
e => Err(e), e => Err(e),
@ -249,6 +254,7 @@ impl<'a> FromRow<'a, PgRow> for super::auth_events::metrics::AuthEventMetricRow
error_message, error_message,
authentication_connector, authentication_connector,
message_version, message_version,
acs_reference_number,
count, count,
start_bucket, start_bucket,
end_bucket, end_bucket,
@ -288,6 +294,11 @@ impl<'a> FromRow<'a, PgRow> for super::auth_events::filters::AuthEventFilterRow
ColumnNotFound(_) => Ok(Default::default()), ColumnNotFound(_) => Ok(Default::default()),
e => Err(e), e => Err(e),
})?; })?;
let acs_reference_number: Option<String> =
row.try_get("acs_reference_number").or_else(|e| match e {
ColumnNotFound(_) => Ok(Default::default()),
e => Err(e),
})?;
Ok(Self { Ok(Self {
authentication_status, authentication_status,
trans_status, trans_status,
@ -295,6 +306,7 @@ impl<'a> FromRow<'a, PgRow> for super::auth_events::filters::AuthEventFilterRow
error_message, error_message,
authentication_connector, authentication_connector,
message_version, message_version,
acs_reference_number,
}) })
} }
} }

View File

@ -51,6 +51,7 @@ pub fn get_auth_event_dimensions() -> Vec<NameDescription> {
vec![ vec![
AuthEventDimensions::AuthenticationConnector, AuthEventDimensions::AuthenticationConnector,
AuthEventDimensions::MessageVersion, AuthEventDimensions::MessageVersion,
AuthEventDimensions::AcsReferenceNumber,
] ]
.into_iter() .into_iter()
.map(Into::into) .map(Into::into)

View File

@ -23,6 +23,8 @@ pub struct AuthEventFilters {
pub authentication_connector: Vec<AuthenticationConnectors>, pub authentication_connector: Vec<AuthenticationConnectors>,
#[serde(default)] #[serde(default)]
pub message_version: Vec<String>, pub message_version: Vec<String>,
#[serde(default)]
pub acs_reference_number: Vec<String>,
} }
#[derive( #[derive(
@ -50,6 +52,7 @@ pub enum AuthEventDimensions {
ErrorMessage, ErrorMessage,
AuthenticationConnector, AuthenticationConnector,
MessageVersion, MessageVersion,
AcsReferenceNumber,
} }
#[derive( #[derive(
@ -135,6 +138,7 @@ pub struct AuthEventMetricsBucketIdentifier {
pub error_message: Option<String>, pub error_message: Option<String>,
pub authentication_connector: Option<AuthenticationConnectors>, pub authentication_connector: Option<AuthenticationConnectors>,
pub message_version: Option<String>, pub message_version: Option<String>,
pub acs_reference_number: Option<String>,
#[serde(rename = "time_range")] #[serde(rename = "time_range")]
pub time_bucket: TimeRange, pub time_bucket: TimeRange,
#[serde(rename = "time_bucket")] #[serde(rename = "time_bucket")]
@ -151,6 +155,7 @@ impl AuthEventMetricsBucketIdentifier {
error_message: Option<String>, error_message: Option<String>,
authentication_connector: Option<AuthenticationConnectors>, authentication_connector: Option<AuthenticationConnectors>,
message_version: Option<String>, message_version: Option<String>,
acs_reference_number: Option<String>,
normalized_time_range: TimeRange, normalized_time_range: TimeRange,
) -> Self { ) -> Self {
Self { Self {
@ -160,6 +165,7 @@ impl AuthEventMetricsBucketIdentifier {
error_message, error_message,
authentication_connector, authentication_connector,
message_version, message_version,
acs_reference_number,
time_bucket: normalized_time_range, time_bucket: normalized_time_range,
start_time: normalized_time_range.start_time, start_time: normalized_time_range.start_time,
} }
@ -173,6 +179,7 @@ impl Hash for AuthEventMetricsBucketIdentifier {
self.authentication_type.hash(state); self.authentication_type.hash(state);
self.authentication_connector.hash(state); self.authentication_connector.hash(state);
self.message_version.hash(state); self.message_version.hash(state);
self.acs_reference_number.hash(state);
self.error_message.hash(state); self.error_message.hash(state);
self.time_bucket.hash(state); self.time_bucket.hash(state);
} }