RANGER-4187: Not able to search using multiple user filter in access audit tab
diff --git a/security-admin/src/main/webapp/react-webapp/src/components/structured-filter/react-typeahead/tokenizer/index.js b/security-admin/src/main/webapp/react-webapp/src/components/structured-filter/react-typeahead/tokenizer/index.js
index 82f7302..c17a3ff 100644
--- a/security-admin/src/main/webapp/react-webapp/src/components/structured-filter/react-typeahead/tokenizer/index.js
+++ b/security-admin/src/main/webapp/react-webapp/src/components/structured-filter/react-typeahead/tokenizer/index.js
@@ -23,7 +23,7 @@
import Typeahead from "../typeahead";
import createReactClass from "create-react-class";
import PropTypes from "prop-types";
-import { find, map, some, trim } from "lodash";
+import { find, filter, map, some, trim, includes } from "lodash";
var classNames = require("classnames");
/**
* A typeahead that, when an option is selected, instead of simply filling
@@ -74,7 +74,7 @@
!!this.props.customClasses.token;
var classList = classNames(tokenClasses);
var result = this.state.selected.map(function (selected, index) {
- let mykey = selected.category + selected.value;
+ let mykey = selected.category + selected.value + index;
let categoryLabel = this._getFilterCategoryLabel(selected.category);
let categoryValue = this._getFilterCategoryLabelForOption(
selected.category,
@@ -113,7 +113,15 @@
if (this.state.category == "") {
var categories = [];
let selectedCategory = [];
- selectedCategory = map(this.state.selected, "category");
+ let bypassCategory = map(
+ filter(this.props.options, ["addMultiple", true]),
+ "category"
+ );
+ selectedCategory = this.state.selected
+ .map((item) => {
+ if (!bypassCategory.includes(item.category)) return item.category;
+ })
+ .filter(Boolean);
for (var i = 0; i < this.props.options.length; i++) {
selectedCategory.indexOf(this.props.options[i].category) === -1 &&
categories.push(this.props.options[i].category);
@@ -245,7 +253,16 @@
_getOptionsLabel: function () {
var currentHeader = this._getHeader();
var optionsLabel = [];
- let selectedCategory = map(this.state.selected, "category");
+ let selectedCategory = [];
+ let bypassCategory = map(
+ filter(this.props.options, ["addMultiple", true]),
+ "category"
+ );
+ selectedCategory = this.state.selected
+ .map((item) => {
+ if (!bypassCategory.includes(item.category)) return item.category;
+ })
+ .filter(Boolean);
if (currentHeader == "Category") {
for (var i = 0; i < this.props.options.length; i++) {
selectedCategory.indexOf(this.props.options[i].category) === -1 &&
diff --git a/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js b/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js
index ebf1b3f..9f67062 100644
--- a/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js
+++ b/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js
@@ -41,7 +41,8 @@
isNull,
some,
has,
- sortBy
+ sortBy,
+ isArray
} from "lodash";
import { matchRoutes } from "react-router-dom";
import dateFormat from "dateformat";
@@ -1141,28 +1142,49 @@
let defaultSearchFilterParam = [];
// Get search filter params from current search params
- const currentParams = Object.fromEntries([...searchParams]);
- for (const param in currentParams) {
+ for (const [key, value] of searchParams.entries()) {
let searchFilterObj = find(searchFilterOptions, {
- urlLabel: param
+ urlLabel: key
});
if (!isUndefined(searchFilterObj)) {
let category = searchFilterObj.category;
- let value = currentParams[param];
+ let categoryValue = value;
- if (searchFilterObj.type == "textoptions") {
- let textOptionObj = find(searchFilterObj.options(), {
- label: value
- });
- value = !isUndefined(textOptionObj) ? textOptionObj.value : value;
+ if (searchFilterObj?.addMultiple) {
+ let oldValue = searchFilterParam[category];
+ let newValue = value;
+ if (oldValue) {
+ if (isArray(oldValue)) {
+ searchFilterParam[category].push(newValue);
+ searchParam[key].push(newValue);
+ } else {
+ searchFilterParam[category] = [oldValue, newValue];
+ searchParam[key] = [oldValue, newValue];
+ }
+ } else {
+ searchFilterParam[category] = newValue;
+ searchParam[key] = newValue;
+ }
+ } else {
+ if (searchFilterObj.type == "textoptions") {
+ let textOptionObj = find(searchFilterObj.options(), {
+ label: categoryValue
+ });
+ categoryValue = !isUndefined(textOptionObj)
+ ? textOptionObj.value
+ : categoryValue;
+ }
+
+ searchFilterParam[category] = categoryValue;
+ searchParam[key] = value;
}
-
- searchFilterParam[category] = value;
defaultSearchFilterParam.push({
category: category,
- value: value
+ value: categoryValue
});
+ } else {
+ searchParam[key] = value;
}
}
@@ -1182,26 +1204,49 @@
let category = searchFilterObj.category;
let value = localStorageParams[localParam];
- if (searchFilterObj.type == "textoptions") {
- let textOptionObj = find(searchFilterObj.options(), {
- label: value
- });
- value = !isUndefined(textOptionObj) ? textOptionObj.value : value;
- }
+ if (searchFilterObj?.addMultiple) {
+ if (isArray(value)) {
+ for (const val of value) {
+ searchFilterParam[category] = value;
+ defaultSearchFilterParam.push({
+ category: category,
+ value: val
+ });
+ searchParam[localParam] = value;
+ }
+ } else {
+ searchFilterParam[category] = value;
+ defaultSearchFilterParam.push({
+ category: category,
+ value: value
+ });
+ searchParam[localParam] = value;
+ }
+ } else {
+ if (searchFilterObj.type == "textoptions") {
+ let textOptionObj = find(searchFilterObj.options(), {
+ label: value
+ });
+ value = !isUndefined(textOptionObj) ? textOptionObj.value : value;
+ }
- searchFilterParam[category] = value;
- defaultSearchFilterParam.push({
- category: category,
- value: value
- });
+ searchFilterParam[category] = value;
+ defaultSearchFilterParam.push({
+ category: category,
+ value: value
+ });
+ searchParam[localParam] = localStorageParams[localParam];
+ }
+ } else {
searchParam[localParam] = localStorageParams[localParam];
}
}
}
}
+
finalSearchFilterData["searchFilterParam"] = searchFilterParam;
finalSearchFilterData["defaultSearchFilterParam"] = defaultSearchFilterParam;
- finalSearchFilterData["searchParam"] = { ...currentParams, ...searchParam };
+ finalSearchFilterData["searchParam"] = searchParam;
return finalSearchFilterData;
};
@@ -1217,7 +1262,21 @@
});
if (searchFilterObj !== undefined) {
- searchFilterParam[obj.category] = obj.value;
+ if (searchFilterObj?.addMultiple) {
+ let oldValue = searchFilterParam[obj.category];
+ let newValue = obj.value;
+ if (oldValue) {
+ if (isArray(oldValue)) {
+ searchFilterParam[obj.category].push(newValue);
+ } else {
+ searchFilterParam[obj.category] = [oldValue, newValue];
+ }
+ } else {
+ searchFilterParam[obj.category] = newValue;
+ }
+ } else {
+ searchFilterParam[obj.category] = obj.value;
+ }
let urlLabelParam = searchFilterObj.urlLabel;
@@ -1228,7 +1287,12 @@
searchParam[urlLabelParam] =
textOptionObj !== undefined ? textOptionObj.label : obj.value;
} else {
- searchParam[urlLabelParam] = obj.value;
+ if (searchFilterObj?.addMultiple) {
+ searchParam[urlLabelParam] =
+ searchFilterParam[searchFilterObj.category];
+ } else {
+ searchParam[urlLabelParam] = obj.value;
+ }
}
}
});
@@ -1352,9 +1416,8 @@
};
export const handleLogout = async (checkKnoxSSOVal, navigate) => {
- let logoutResp = {};
try {
- logoutResp = await fetchApi({
+ await fetchApi({
url: "logout",
baseURL: "",
headers: {
diff --git a/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AccessLogs.jsx b/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AccessLogs.jsx
index 7ec8503..141b06c 100644
--- a/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AccessLogs.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AccessLogs.jsx
@@ -18,7 +18,7 @@
*/
import React, { useState, useCallback, useEffect, useRef } from "react";
-import { useSearchParams, useOutletContext } from "react-router-dom";
+import { useSearchParams, useOutletContext, Link } from "react-router-dom";
import { Badge, Button, Row, Col, Table, Modal } from "react-bootstrap";
import XATableLayout from "Components/XATableLayout";
import dateFormat from "dateformat";
@@ -40,10 +40,12 @@
toString,
toUpper,
has,
- filter
+ filter,
+ find,
+ isArray
} from "lodash";
import { toast } from "react-toastify";
-import { Link } from "react-router-dom";
+import qs from "qs";
import { AccessMoreLess } from "Components/CommonComponents";
import { PolicyViewDetails } from "./AdminLogs/PolicyViewDetails";
import StructuredFilter from "../../components/structured-filter/react-typeahead/tokenizer";
@@ -120,10 +122,13 @@
});
}
- // Updating the states for search params, search filter, default search filter and localStorage
- if (localStorage?.excludeServiceUser) {
+ // Add excludeServiceUser if not present in the search param with default state value of checked
+ if (!has(searchParam, "excludeServiceUser")) {
searchParam["excludeServiceUser"] = checked;
}
+ localStorage.setItem("excludeServiceUser", checked);
+
+ // Updating the states for search params, search filter, default search filter and localStorage
setSearchParams(searchParam, { replace: true });
setSearchFilterParams(searchFilterParam);
setDefaultSearchFilterParams(defaultSearchFilterParam);
@@ -135,17 +140,16 @@
let { searchFilterParam, defaultSearchFilterParam, searchParam } =
fetchSearchFilterParams("bigData", searchParams, searchFilterOptions);
- // Updating the states for search params, search filter, default search filter and localStorage
- if (localStorage?.excludeServiceUser || searchParam?.excludeServiceUser) {
- if (searchParam?.excludeServiceUser) {
- setChecked(searchParam?.excludeServiceUser == "true" ? true : false);
- localStorage.setItem(
- "excludeServiceUser",
- searchParam?.excludeServiceUser
- );
- }
- searchParam["excludeServiceUser"] = localStorage?.excludeServiceUser;
+ // Update excludeServiceUser in the search param and in the localStorage
+ if (searchParam?.excludeServiceUser) {
+ setChecked(searchParam?.excludeServiceUser == "true" ? true : false);
+ localStorage.setItem(
+ "excludeServiceUser",
+ searchParam?.excludeServiceUser
+ );
}
+
+ // Updating the states for search params, search filter, default search filter and localStorage
setSearchParams(searchParam, { replace: true });
if (
JSON.stringify(searchFilterParams) !== JSON.stringify(searchFilterParam)
@@ -154,6 +158,7 @@
}
setDefaultSearchFilterParams(defaultSearchFilterParam);
localStorage.setItem("bigData", JSON.stringify(searchParam));
+
setContentLoader(false);
}
}, [searchParams, servicesAvailable]);
@@ -186,7 +191,10 @@
try {
logsResp = await fetchApi({
url: "assets/accessAudit",
- params: params
+ params: params,
+ paramsSerializer: function (params) {
+ return qs.stringify(params, { arrayFormat: "repeat" });
+ }
});
logs = logsResp.data.vXAccessAudits;
totalCount = logsResp.data.totalCount;
@@ -223,13 +231,39 @@
};
const toggleChange = (chkVal) => {
- let currentParams = Object.fromEntries([...searchParams]);
- currentParams["excludeServiceUser"] = chkVal?.target?.checked;
- localStorage.setItem(
- "excludeServiceUser",
- JSON.stringify(chkVal?.target?.checked)
- );
- setSearchParams(currentParams, { replace: true });
+ let checkBoxValue = chkVal?.target?.checked;
+ let searchParam = {};
+
+ for (const [key, value] of searchParams.entries()) {
+ let searchFilterObj = find(searchFilterOptions, {
+ urlLabel: key
+ });
+
+ if (!isUndefined(searchFilterObj)) {
+ if (searchFilterObj?.addMultiple) {
+ let oldValue = searchParam[key];
+ let newValue = value;
+ if (oldValue) {
+ if (isArray(oldValue)) {
+ searchParam[key].push(newValue);
+ } else {
+ searchParam[key] = [oldValue, newValue];
+ }
+ } else {
+ searchParam[key] = newValue;
+ }
+ } else {
+ searchParam[key] = value;
+ }
+ } else {
+ searchParam[key] = value;
+ }
+ }
+
+ searchParam["excludeServiceUser"] = checkBoxValue;
+ localStorage.setItem("excludeServiceUser", checkBoxValue);
+
+ setSearchParams(searchParam, { replace: true });
setAccessLogs([]);
setChecked(chkVal?.target?.checked);
setLoader(true);
@@ -238,6 +272,7 @@
const handleClosePolicyId = () => setPolicyViewModal(false);
const handleClose = () => setShowRowModal(false);
+
const rowModal = (row) => {
setShowRowModal(true);
setRowData(row.original);
@@ -770,7 +805,7 @@
category: "eventId",
label: "Audit ID",
urlLabel: "eventId",
- type: "number"
+ type: "text"
},
{
category: "clientIP",
@@ -794,7 +829,8 @@
category: "excludeUser",
label: "Exclude User",
urlLabel: "excludeUser",
- type: "number"
+ addMultiple: true,
+ type: "text"
},
{
category: "policyId",
@@ -857,6 +893,7 @@
category: "requestUser",
label: "User",
urlLabel: "user",
+ addMultiple: true,
type: "text"
},
{