fix(opensearch): show search results only if user has access permission to the index (#5097)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Co-authored-by: Abhishek Kanojia <89402434+Abhitator216@users.noreply.github.com>
This commit is contained in:
Sandeep Kumar
2024-06-27 13:06:31 +05:30
committed by GitHub
parent ef5ed08380
commit 9c49ded104
7 changed files with 130 additions and 78 deletions

View File

@ -4,7 +4,7 @@ pub mod routes {
use actix_web::{web, Responder, Scope};
use analytics::{
api_event::api_events_core, connector_events::connector_events_core,
errors::AnalyticsError, lambda_utils::invoke_lambda,
errors::AnalyticsError, lambda_utils::invoke_lambda, opensearch::OpenSearchError,
outgoing_webhook_event::outgoing_webhook_events_core, sdk_events::sdk_events_core,
AnalyticsFlow,
};
@ -20,13 +20,14 @@ pub mod routes {
use error_stack::ResultExt;
use crate::{
core::api_locking,
consts::opensearch::OPENSEARCH_INDEX_PERMISSIONS,
core::{api_locking, errors::user::UserErrors},
db::user::UserInterface,
routes::AppState,
services::{
api,
authentication::{self as auth, AuthenticationData},
authorization::permissions::Permission,
authentication::{self as auth, AuthenticationData, UserFromToken},
authorization::{permissions::Permission, roles::RoleInfo},
ApplicationResponse,
},
types::domain::UserEmail,
@ -694,11 +695,25 @@ pub mod routes {
state.clone(),
&req,
json_payload.into_inner(),
|state, auth: AuthenticationData, req, _| async move {
|state, auth: UserFromToken, req, _| async move {
let role_id = auth.role_id;
let role_info =
RoleInfo::from_role_id(&state, &role_id, &auth.merchant_id, &auth.org_id)
.await
.change_context(UserErrors::InternalServerError)
.change_context(OpenSearchError::UnknownError)?;
let permissions = role_info.get_permissions_set();
let accessible_indexes: Vec<_> = OPENSEARCH_INDEX_PERMISSIONS
.iter()
.filter(|(_, perm)| perm.iter().any(|p| permissions.contains(p)))
.map(|(i, _)| *i)
.collect();
analytics::search::msearch_results(
&state.opensearch_client,
req,
&auth.merchant_account.merchant_id,
&auth.merchant_id,
accessible_indexes,
)
.await
.map(ApplicationResponse::Json)
@ -715,24 +730,33 @@ pub mod routes {
json_payload: web::Json<GetSearchRequest>,
index: web::Path<SearchIndex>,
) -> impl Responder {
let index = index.into_inner();
let flow = AnalyticsFlow::GetSearchResults;
let indexed_req = GetSearchRequestWithIndex {
search_req: json_payload.into_inner(),
index: index.into_inner(),
index,
};
Box::pin(api::server_wrap(
flow,
state.clone(),
&req,
indexed_req,
|state, auth: AuthenticationData, req, _| async move {
analytics::search::search_results(
&state.opensearch_client,
req,
&auth.merchant_account.merchant_id,
)
.await
.map(ApplicationResponse::Json)
|state, auth: UserFromToken, req, _| async move {
let role_id = auth.role_id;
let role_info =
RoleInfo::from_role_id(&state, &role_id, &auth.merchant_id, &auth.org_id)
.await
.change_context(UserErrors::InternalServerError)
.change_context(OpenSearchError::UnknownError)?;
let permissions = role_info.get_permissions_set();
let _ = OPENSEARCH_INDEX_PERMISSIONS
.iter()
.filter(|(ind, _)| *ind == index)
.find(|i| i.1.iter().any(|p| permissions.contains(p)))
.ok_or(OpenSearchError::IndexAccessNotPermittedError(index))?;
analytics::search::search_results(&state.opensearch_client, req, &auth.merchant_id)
.await
.map(ApplicationResponse::Json)
},
&auth::JWTAuth(Permission::Analytics),
api_locking::LockAction::NotApplicable,

View File

@ -1,3 +1,4 @@
pub mod opensearch;
#[cfg(feature = "olap")]
pub mod user;
pub mod user_role;

View File

@ -0,0 +1,22 @@
use api_models::analytics::search::SearchIndex;
use crate::services::authorization::permissions::Permission;
pub const OPENSEARCH_INDEX_PERMISSIONS: &[(SearchIndex, &[Permission])] = &[
(
SearchIndex::PaymentAttempts,
&[Permission::PaymentRead, Permission::PaymentWrite],
),
(
SearchIndex::PaymentIntents,
&[Permission::PaymentRead, Permission::PaymentWrite],
),
(
SearchIndex::Refunds,
&[Permission::RefundRead, Permission::RefundWrite],
),
(
SearchIndex::Disputes,
&[Permission::DisputeRead, Permission::DisputeWrite],
),
];

View File

@ -83,7 +83,7 @@ impl EventsConfig {
impl EventsHandler {
pub fn log_event<T: KafkaMessage>(&self, event: &T) {
match self {
Self::Kafka(kafka) => kafka.log_event(event).map_or((), |e| {
Self::Kafka(kafka) => kafka.log_event(event).unwrap_or_else(|e| {
logger::error!("Failed to log event: {:?}", e);
}),
Self::Logs(logger) => logger.log_event(event),