finish debug and audit rework

This commit is contained in:
sadnub
2021-07-05 18:19:36 -04:00
parent 451e8f2e76
commit 7ad67f3630
8 changed files with 341 additions and 568 deletions

View File

@@ -1,160 +0,0 @@
<template>
<q-card>
<q-bar>
<q-btn @click="search" class="q-mr-sm" dense flat push icon="refresh" />
<q-space />Audit Manager
<q-space />
<q-btn dense flat icon="close" v-close-popup>
<q-tooltip class="bg-white text-primary">Close</q-tooltip>
</q-btn>
</q-bar>
<div class="text-h6 q-pl-sm q-pt-sm">Filter</div>
<div class="row">
<div class="q-pa-sm col-1">
<q-option-group v-model="filterType" :options="filterTypeOptions" color="primary" />
</div>
<div class="q-pa-sm col-2" v-if="filterType === 'agents'">
<tactical-dropdown v-model="agentFilter" :options="agentOptions" label="Agent" clearable multiple filled />
</div>
<div class="q-pa-sm col-2" v-if="filterType === 'clients'">
<tactical-dropdown
v-model="clientFilter"
:options="clientOptions"
label="Clients"
clearable
multiple
filled
mapOptions
/>
</div>
<div class="q-pa-sm col-2">
<tactical-dropdown v-model="userFilter" :options="userOptions" label="Users" clearable filled multiple />
</div>
<div class="q-pa-sm col-2">
<tactical-dropdown
v-model="actionFilter"
:options="actionOptions"
label="Action"
clearable
filled
multiple
mapOptions
/>
</div>
<div class="q-pa-sm col-2">
<tactical-dropdown
v-model="objectFilter"
:options="objectOptions"
label="Object"
clearable
filled
multiple
mapOptions
/>
</div>
<div class="q-pa-sm col-2">
<tactical-dropdown v-model="timeFilter" :options="timeOptions" label="Time" filled mapOptions />
</div>
<div class="q-pa-sm col-1">
<q-btn color="primary" label="Search" @click="search" />
</div>
</div>
<q-separator />
<q-card-section>
<q-table
@request="onRequest"
title="Audit Logs"
:rows="auditLogs"
:columns="columns"
row-key="id"
dense
binary-state-sort
v-model:pagination="pagination"
:rows-per-page-options="[25, 50, 100, 500, 1000]"
:no-data-label="tableNoDataText"
@row-click="openAuditDetail"
:loading="loading"
>
<template v-slot:top-right>
<q-btn dense color="primary" icon-right="archive" @click="exportLog" />
</template>
<template v-slot:body-cell-action="props">
<q-td :props="props">
<div>
<q-badge :color="formatActionColor(props.value)" :label="props.value" />
</div>
</q-td>
</template>
</q-table>
</q-card-section>
</q-card>
</template>
<script>
// composition imports
import { onMounted } from "vue";
import { useAuditLog } from "@/composables/logs";
import { useClientDropdown } from "@/composables/clients";
import { useAgentDropdown } from "@/composables/agents";
import { useUserDropdown } from "@/composables/accounts";
import { exportTableToCSV } from "@/utils/csv";
// ui imported
import TacticalDropdown from "@/components/ui/TacticalDropdown";
export default {
name: "AuditManager",
components: { TacticalDropdown },
setup() {
// setup dropdowns
const { clientOptions, getClientOptions } = useClientDropdown();
const { agentOptions, getAgentOptions } = useAgentDropdown();
const { userOptions, userDropdownLoading, getUserOptions } = useUserDropdown();
onMounted(() => {
getClientOptions();
getAgentOptions(true);
getUserOptions(true);
});
const AuditLog = useAuditLog();
return {
// data
auditLogs: AuditLog.auditLogs,
agentFilter: AuditLog.agentFilter,
userFilter: AuditLog.userFilter,
actionFilter: AuditLog.actionFilter,
clientFilter: AuditLog.clientFilter,
objectFilter: AuditLog.objectFilter,
timeFilter: AuditLog.timeFilter,
filterType: AuditLog.filterType,
loading: AuditLog.loading,
pagination: AuditLog.pagination,
userOptions,
userDropdownLoading,
// non-reactive data
clientOptions,
agentOptions,
columns: useAuditLog.tableColumns,
actionOptions: useAuditLog.actionOptions,
objectOptions: useAuditLog.objectOptions,
timeOptions: useAuditLog.timeOptions,
filterTypeOptions: useAuditLog.filterTypeOptions,
//computed
tableNoDataText: AuditLog.noDataText,
// methods
search: AuditLog.search,
onRequest: AuditLog.onRequest,
openAuditDetail: AuditLog.openAuditDetail,
formatActionColor: AuditLog.formatActionColor,
exportLog: () => {
exportTableToCSV(auditLogs, useAuditLog.tableColumns);
},
};
},
};
</script>

View File

@@ -25,10 +25,10 @@
<q-item clickable v-close-popup @click="showUploadMesh = true">
<q-item-section>Upload MeshAgent</q-item-section>
</q-item>
<q-item clickable v-close-popup @click="showAuditManager = true">
<q-item clickable v-close-popup @click="showAuditManager">
<q-item-section>Audit Log</q-item-section>
</q-item>
<q-item clickable v-close-popup @click="showDebugLog()">
<q-item clickable v-close-popup @click="showDebugLog">
<q-item-section>Debug Log</q-item-section>
</q-item>
</q-list>
@@ -154,12 +154,6 @@
<PendingActions @close="showPendingActions = false" />
</q-dialog>
</div>
<!-- audit manager -->
<div class="q-pa-md q-gutter-sm">
<q-dialog v-model="showAuditManager" maximized transition-show="slide-up" transition-hide="slide-down">
<AuditManager @close="showAuditManager = false" />
</q-dialog>
</div>
<!-- Install Agents -->
<div class="q-pa-md q-gutter-sm">
<q-dialog v-model="showInstallAgent">
@@ -223,7 +217,7 @@ import AutomationManager from "@/components/automation/AutomationManager";
import AdminManager from "@/components/AdminManager";
import InstallAgent from "@/components/modals/agents/InstallAgent";
import UploadMesh from "@/components/modals/core/UploadMesh";
import AuditManager from "@/components/AuditManager";
import AuditManager from "@/components/logs/AuditManager";
import BulkAction from "@/components/modals/agents/BulkAction";
import Deployment from "@/components/Deployment";
import ServerMaintenance from "@/components/modals/core/ServerMaintenance";
@@ -241,7 +235,6 @@ export default {
InstallAgent,
UploadMesh,
AdminManager,
AuditManager,
BulkAction,
Deployment,
ServerMaintenance,
@@ -256,7 +249,6 @@ export default {
showAdminManager: false,
showInstallAgent: false,
showUploadMesh: false,
showAuditManager: false,
showBulkAction: false,
showPendingActions: false,
bulkMode: null,
@@ -327,6 +319,23 @@ export default {
component: PermissionsManager,
});
},
showAuditManager() {
this.$q.dialog({
component: DialogWrapper,
componentProps: {
vuecomponent: AuditManager,
noCard: true,
componentProps: {
modal: true,
},
dialogProps: {
maximized: true,
["transition-show"]: "slide-up",
["transition-hide"]: "slide-down",
},
},
});
},
showDebugLog() {
this.$q.dialog({
component: DialogWrapper,

View File

@@ -1,122 +1,31 @@
<template>
<div v-if="!selectedAgentPk">No agent selected</div>
<div v-else class="q-pa-none">
<div class="q-gutter-y-md">
<q-card>
<q-table
@request="onRequest"
dense
:table-class="{ 'table-bgcolor': !$q.dark.isActive, 'table-bgcolor-dark': $q.dark.isActive }"
class="audit-mgr-tbl-sticky"
binary-state-sort
title="Audit Logs"
:rows="auditLogs"
:columns="columns"
row-key="id"
v-model:pagination="pagination"
:rows-per-page-options="[25, 50, 100, 500]"
:no-data-label="noDataText"
@row-click="showDetails"
virtual-scroll
>
<template v-slot:top-right>
<q-btn color="primary" icon-right="archive" label="Export to csv" no-caps @click="exportLog" />
</template>
<template v-slot:body-cell-action="props">
<q-td :props="props">
<div>
<q-badge :color="actionColor(props.value)" :label="actionText(props.value)" />
</div>
</q-td>
</template>
</q-table>
</q-card>
</div>
<div v-if="!selectedAgent">No agent selected</div>
<div v-else>
<AuditManager :agentpk="selectedAgent" />
</div>
</template>
<script>
import { mapGetters } from "vuex";
// composition imports
import { computed } from "vue";
import { useStore } from "vuex";
// ui imports
import AuditManager from "@/components/logs/AuditManager";
export default {
name: "AuditTab",
data() {
components: {
AuditManager,
},
setup() {
const store = useStore();
const selectedAgent = computed(() => store.state.selectedRow);
return {
columns: [
{
name: "entry_time",
label: "Time",
field: "entry_time",
align: "left",
sortable: true,
format: (val, row) => this.formatDate(val, true),
},
{ name: "username", label: "Username", field: "username", align: "left", sortable: true },
{ name: "action", label: "Action", field: "action", align: "left", sortable: true },
{
name: "object_type",
label: "Object",
field: "object_type",
align: "left",
sortable: true,
format: (val, row) => this.formatObject(val),
},
{ name: "message", label: "Message", field: "message", align: "left", sortable: true },
],
timeOptions: [
{ value: 1, label: "1 Day Ago" },
{ value: 7, label: "1 Week Ago" },
{ value: 30, label: "30 Days Ago" },
{ value: 90, label: "3 Months Ago" },
{ value: 180, label: "6 Months Ago" },
{ value: 365, label: "1 Year Ago" },
{ value: 0, label: "Everything" },
],
pagination: {
rowsPerPage: 25,
rowsNumber: null,
sortBy: "entry_time",
descending: true,
page: 1,
},
// computed
selectedAgent,
};
},
computed: {
...mapGetters(["selectedAgentPk"]),
},
methods: {
onRequest(props) {
// needed to update external pagination object
const { page, rowsPerPage, sortBy, descending } = props.pagination;
this.pagination.page = page;
this.pagination.rowsPerPage = rowsPerPage;
this.pagination.sortBy = sortBy;
this.pagination.descending = descending;
this.search();
},
actionColor(action) {
if (action === "add") return "success";
else if (action === "agent_install") return "success";
else if (action === "modify") return "warning";
else if (action === "delete") return "negative";
else if (action === "failed_login") return "negative";
else return "primary";
},
actionText(action) {
if (action.includes("_")) {
let text = action.split("_");
return this.capitalize(text[0]) + " " + this.capitalize(text[1]);
} else {
return this.capitalize(action);
}
},
formatObject(text) {
if (text === "winupdatepolicy") return "Patch Policy";
else if (text === "automatedtask") return "Automated Task";
else if (text === "coresettings") return "Core Settings";
else return this.capitalize(text);
},
},
};
</script>

View File

@@ -0,0 +1,23 @@
<template>
<div v-if="!selectedAgent">No agent selected</div>
<div v-else></div>
</template>
<script>
// composition imports
import { computed } from "vue";
import { useStore } from "vuex";
export default {
name: "HistoryTab",
setup() {
const store = useStore();
const selectedAgent = computed(() => store.state.selectedRow);
return {
// computed
selectedAgent,
};
},
};
</script>

View File

@@ -13,8 +13,16 @@
<div class="q-pa-sm col-1" v-if="!agentpk">
<q-option-group v-model="filterType" :options="filterTypeOptions" color="primary" />
</div>
<div class="q-pa-sm col-2" v-if="filterType === 'agents'">
<tactical-dropdown v-model="agentFilter" :options="agentOptions" label="Agent" clearable multiple filled />
<div class="q-pa-sm col-2" v-if="filterType === 'agents' && !agentpk">
<tactical-dropdown
v-model="agentFilter"
:options="agentOptions"
label="Agent"
clearable
mapOptions
multiple
filled
/>
</div>
<div class="q-pa-sm col-2" v-if="filterType === 'clients' && !agentpk">
<tactical-dropdown
@@ -41,7 +49,7 @@
mapOptions
/>
</div>
<div class="q-pa-sm col-2">
<div class="q-pa-sm col-2" v-if="!agentpk">
<tactical-dropdown
v-model="objectFilter"
:options="objectOptions"
@@ -55,11 +63,13 @@
<div class="q-pa-sm col-2">
<tactical-dropdown v-model="timeFilter" :options="timeOptions" label="Time" filled mapOptions />
</div>
<div class="q-pa-sm col-1">
<div class="q-pa-sm col-1" v-if="!agentpk">
<q-btn color="primary" label="Search" @click="search" />
</div>
<q-space />
<export-table-btn v-if="!modal" :data="auditLogs" :columns="columns" />
<div class="q-pa-sm" v-if="!modal">
<export-table-btn :data="auditLogs" :columns="columns" />
</div>
</div>
<q-separator />
<q-card-section>
@@ -94,16 +104,102 @@
<script>
// composition imports
import { onMounted } from "vue";
import { useAuditLog } from "@/composables/logs";
import { ref, computed, watch, onMounted, toRefs } from "vue";
import { useClientDropdown } from "@/composables/clients";
import { useAgentDropdown } from "@/composables/agents";
import { useUserDropdown } from "@/composables/accounts";
import { useQuasar } from "quasar";
import { fetchAuditLog } from "@/api/logs";
import { formatDate, formatTableColumnText } from "@/utils/format";
// ui imported
import AuditLogDetailModal from "@/components/logs/AuditLogDetailModal";
import ExportTableBtn from "@/components/ui/ExportTableBtn";
import TacticalDropdown from "@/components/ui/TacticalDropdown";
import ExportTableBtn from "../ui/ExportTableBtn.vue";
// static data
const columns = [
{
name: "entry_time",
label: "Time",
field: "entry_time",
align: "left",
sortable: true,
format: (val, row) => formatDate(val, true),
},
{ name: "username", label: "Username", field: "username", align: "left", sortable: true },
{ name: "agent", label: "Agent", field: "agent", align: "left", sortable: true },
{
name: "action",
label: "Action",
field: "action",
align: "left",
sortable: true,
format: (val, row) => formatTableColumnText(val),
},
{
name: "object_type",
label: "Object",
field: "object_type",
align: "left",
sortable: true,
format: (val, row) => formatTableColumnText(val),
},
{ name: "message", label: "Message", field: "message", align: "left", sortable: true },
];
const agentActionOptions = [
{ value: "add", label: "Add Object" },
{ value: "modify", label: "Modify Object" },
{ value: "execute_command", label: "Execute Command" },
{ value: "execute_script", label: "Execute Script" },
{ value: "remote_session", label: "Remote Session" },
];
const actionOptions = [
{ value: "agent_install", label: "Agent Installs" },
{ value: "bulk_action", label: "Bulk Actions" },
{ value: "delete", label: "Delete Object" },
{ value: "failed_login", label: "Failed User login" },
{ value: "login", label: "User Login" },
{ value: "modify", label: "Modify Object" },
{ value: "task_run", label: "Task Run Results" },
];
const objectOptions = [
{ value: "agent", label: "Agent" },
{ value: "automatedtask", label: "Automated Task" },
{ value: "bulk", label: "Bulk Actions" },
{ value: "coresettings", label: "Core Settings" },
{ value: "check", label: "Check" },
{ value: "client", label: "Client" },
{ value: "policy", label: "Policy" },
{ value: "site", label: "Site" },
{ value: "script", label: "Script" },
{ value: "user", label: "User" },
{ value: "winupdatepolicy", label: "Patch Policy" },
];
const timeOptions = [
{ value: 1, label: "1 Day Ago" },
{ value: 7, label: "1 Week Ago" },
{ value: 30, label: "30 Days Ago" },
{ value: 90, label: "3 Months Ago" },
{ value: 180, label: "6 Months Ago" },
{ value: 365, label: "1 Year Ago" },
{ value: 0, label: "Everything" },
];
const filterTypeOptions = [
{
label: "Clients",
value: "clients",
},
{
label: "Agents",
value: "agents",
},
];
export default {
name: "AuditManager",
@@ -115,53 +211,143 @@ export default {
default: false,
},
},
setup() {
setup(props) {
// setup dropdowns
const { clientOptions, getClientOptions } = useClientDropdown();
const { agentOptions, getAgentOptions } = useAgentDropdown();
const { userOptions, getUserOptions } = useUserDropdown();
// setup main audit log functionality
const auditLogs = ref([]);
const agentFilter = ref(null);
const userFilter = ref(null);
const actionFilter = ref(null);
const clientFilter = ref(null);
const objectFilter = ref(null);
const timeFilter = ref(7);
const filterType = ref("clients");
const loading = ref(false);
const searched = ref(false);
const pagination = ref({
rowsPerPage: 25,
rowsNumber: null,
sortBy: "entry_time",
descending: true,
page: 1,
});
async function search() {
loading.value = true;
searched.value = true;
const data = {
pagination: pagination.value,
};
if (agentFilter.value && agentFilter.value.length > 0) data["agentFilter"] = agentFilter.value;
else if (clientFilter.value && clientFilter.value.length > 0) data["clientFilter"] = clientFilter.value;
if (userFilter.value && userFilter.value.length > 0) data["userFilter"] = userFilter.value;
if (timeFilter.value) data["timeFilter"] = timeFilter.value;
if (actionFilter.value && actionFilter.value.length > 0) data["actionFilter"] = actionFilter.value;
if (objectFilter.value && objectFilter.value.length > 0) data["objectFilter"] = objectFilter.value;
console.log(data);
const { audit_logs, total } = await fetchAuditLog(data);
auditLogs.value = audit_logs;
pagination.value.rowsNumber = total;
loading.value = false;
}
function onRequest(data) {
const { page, rowsPerPage, sortBy, descending } = data.pagination;
pagination.value.page = page;
pagination.value.rowsPerPage = rowsPerPage;
pagination.value.sortBy = sortBy;
pagination.value.descending = descending;
search();
}
// audit detail modal
const { dialog } = useQuasar();
function openAuditDetail(evt, log) {
dialog({
component: AuditLogDetailModal,
componentProps: {
log,
},
});
}
function formatActionColor(action) {
if (action === "add") return "success";
else if (action === "agent_install") return "success";
else if (action === "modify") return "warning";
else if (action === "delete") return "negative";
else if (action === "failed_login") return "negative";
else return "primary";
}
// watchers
watch(filterType, () => {
agentFilter.value = null;
clientFilter.value = null;
});
if (props.agentpk) {
agentFilter.value = [props.agentpk];
watch([userFilter, actionFilter, timeFilter], search);
}
// vue component hooks
onMounted(() => {
if (!props.agentpk) {
getClientOptions();
getAgentOptions();
} else {
search();
}
getUserOptions(true);
});
const AuditLog = useAuditLog();
return {
// data
auditLogs: AuditLog.auditLogs,
agentFilter: agentpk ? [agentpk] : AuditLog.agentFilter,
userFilter: AuditLog.userFilter,
actionFilter: AuditLog.actionFilter,
clientFilter: AuditLog.clientFilter,
objectFilter: AuditLog.objectFilter,
timeFilter: AuditLog.timeFilter,
filterType: AuditLog.filterType,
loading: AuditLog.loading,
pagination: AuditLog.pagination,
auditLogs,
agentFilter,
userFilter,
actionFilter,
clientFilter,
objectFilter,
timeFilter,
filterType,
loading,
searched,
pagination,
userOptions,
// non-reactive data
clientOptions,
agentOptions,
columns: useAuditLog.tableColumns,
actionOptions: useAuditLog.actionOptions,
objectOptions: useAuditLog.objectOptions,
timeOptions: useAuditLog.timeOptions,
filterTypeOptions: useAuditLog.filterTypeOptions,
columns,
actionOptions: props.agentpk ? [...agentActionOptions] : [...agentActionOptions, ...actionOptions],
objectOptions,
timeOptions,
filterTypeOptions,
//computed
tableNoDataText: AuditLog.noDataText,
tableNoDataText: computed(() =>
searched.value ? "No data found. Try to refine you search" : "Click search to find audit logs"
),
// methods
search: AuditLog.search,
onRequest: AuditLog.onRequest,
openAuditDetail: AuditLog.openAuditDetail,
formatActionColor: AuditLog.formatActionColor,
search,
onRequest,
openAuditDetail,
formatActionColor,
};
},
};

View File

@@ -42,6 +42,7 @@
:columns="columns"
:title="modal ? 'Debug Logs' : ''"
:pagination="{ sortBy: 'entry_time', descending: true }"
:loading="loading"
dense
binary-state-sort
>
@@ -55,14 +56,46 @@
<script>
// composition api
import { watch, onMounted } from "vue";
import { useDebugLog } from "@/composables/logs";
import { ref, watch, onMounted, toRefs } from "vue";
import { useAgentDropdown } from "@/composables/agents";
import { fetchDebugLog } from "@/api/logs";
import { formatDate, formatTableColumnText } from "@/utils/format";
// ui components
import TacticalDropdown from "@/components/ui/TacticalDropdown";
import ExportTableBtn from "@/components/ui/ExportTableBtn.vue";
// static data
const logTypeOptions = [
{ label: "Agent Update", value: "agent_update" },
{ label: "Agent Issues", value: "agent_issues" },
{ label: "Windows Updates", value: "windows_updates" },
{ label: "System Issues", value: "system_issues" },
{ label: "Scripting", value: "scripting" },
];
const columns = [
{
name: "entry_time",
label: "Time",
field: "entry_time",
align: "left",
sortable: true,
format: (val, row) => formatDate(val, true),
},
{ name: "log_level", label: "Log Level", field: "log_level", align: "left", sortable: true },
{ name: "agent", label: "Agent", field: "agent", align: "left", sortable: true },
{
name: "log_type",
label: "Log Type",
field: "log_type",
align: "left",
sortable: true,
format: (val, row) => formatTableColumnText(val),
},
{ name: "message", label: "Message", field: "message", align: "left", sortable: true },
];
export default {
name: "LogModal",
components: {
@@ -77,15 +110,36 @@ export default {
},
},
setup(props) {
const { debugLog, logLevelFilter, logTypeFilter, agentFilter, getDebugLog } = useDebugLog();
// setup dropdowns
const { agentOptions, getAgentOptions } = useAgentDropdown();
// set main debug log functionality
const debugLog = ref([]);
const agentFilter = ref(null);
const logLevelFilter = ref("info");
const logTypeFilter = ref(null);
const loading = ref(false);
async function getDebugLog() {
loading.value = true;
const data = {
logLevelFilter: logLevelFilter.value,
};
if (agentFilter.value) data["agentFilter"] = agentFilter.value;
if (logTypeFilter.value) data["logTypeFilter"] = logTypeFilter.value;
debugLog.value = await fetchDebugLog(data);
loading.value = false;
}
if (props.agentpk) {
agentFilter.value = props.agentpk;
}
// watchers
watch([logLevelFilter, agentFilter, logTypeFilter], getDebugLog);
// vue component hooks
onMounted(() => {
if (!props.agentpk) getAgentOptions();
getDebugLog();
@@ -98,10 +152,11 @@ export default {
logTypeFilter,
agentFilter,
agentOptions,
loading,
// non-reactive data
columns: useDebugLog.tableColumns,
logTypeOptions: useDebugLog.logTypeOptions,
columns,
logTypeOptions,
// methods
getDebugLog,

View File

@@ -3,6 +3,7 @@ import { ref } from "vue"
import { fetchAgents } from "@/api/agents"
import { formatAgentOptions } from "@/utils/format"
// agent dropdown
export function useAgentDropdown() {
const agentOptions = ref([])
@@ -19,4 +20,4 @@ export function useAgentDropdown() {
//methods
getAgentOptions
}
}
}

View File

@@ -1,250 +0,0 @@
import { ref, computed, watch } from "vue"
import { useQuasar } from "quasar"
import { fetchDebugLog, fetchAuditLog } from "@/api/logs"
import { formatDate, formatTableColumnText } from "@/utils/format"
import AuditLogDetailModal from "@/components/logs/AuditLogDetailModal";
// debug log
export function useDebugLog() {
const debugLog = ref([])
const agentFilter = ref(null)
const logLevelFilter = ref("info")
const logTypeFilter = ref(null)
async function getDebugLog() {
const data = {
logLevelFilter: logLevelFilter.value
}
if (agentFilter.value) data["agentFilter"] = agentFilter.value
if (logTypeFilter.value) data["logTypeFilter"] = logTypeFilter.value
debugLog.value = await fetchDebugLog(data)
}
return {
// data
logLevelFilter,
logTypeFilter,
agentFilter,
debugLog,
// methods
getDebugLog
}
}
useDebugLog.logTypeOptions = [
{ label: "Agent Update", value: "agent_update" },
{ label: "Agent Issues", value: "agent_issues" },
{ label: "Windows Updates", value: "windows_updates" },
{ label: "System Issues", value: "system_issues" },
{ label: "Scripting", value: "scripting" }
]
useDebugLog.tableColumns = [
{
name: "entry_time",
label: "Time",
field: "entry_time",
align: "left",
sortable: true,
format: (val, row) => formatDate(val, true),
},
{ name: "log_level", label: "Log Level", field: "log_level", align: "left", sortable: true },
{ name: "agent", label: "Agent", field: "agent", align: "left", sortable: true },
{
name: "log_type",
label: "Log Type",
field: "log_type",
align: "left",
sortable: true,
format: (val, row) => formatTableColumnText(val),
},
{ name: "message", label: "Message", field: "message", align: "left", sortable: true },
]
// audit Log
export function useAuditLog() {
const auditLogs = ref([])
const agentFilter = ref(null)
const userFilter = ref(null)
const actionFilter = ref(null)
const clientFilter = ref(null)
const objectFilter = ref(null)
const timeFilter = ref(7)
const filterType = ref("clients")
const loading = ref(false)
const searched = ref(false)
const pagination = ref({
rowsPerPage: 25,
rowsNumber: null,
sortBy: "entry_time",
descending: true,
page: 1,
})
async function search() {
loading.value = true
searched.value = true;
const data = {
pagination: pagination.value
};
if (!!agentFilter.value && agentFilter.value.length > 0) data["agentFilter"] = agentFilter.value;
else if (!!clientFilter.value && clientFilter.value.length > 0) data["clientFilter"] = clientFilter.value;
if (!!userFilter.value && userFilter.value.length > 0) data["userFilter"] = userFilter.value;
if (!!timeFilter.value) data["timeFilter"] = timeFilter.value;
if (!!actionFilter.value && actionFilter.value.length > 0) data["actionFilter"] = actionFilter.value;
if (!!objectFilter.value && objectFilter.value.length > 0) data["objectFilter"] = objectFilter.value;
const { audit_logs, total } = await fetchAuditLog(data)
auditLogs.value = audit_logs
pagination.value.rowsNumber = total
loading.value = false
}
function onRequest(props) {
const { page, rowsPerPage, sortBy, descending } = props.pagination;
pagination.value.page = page;
pagination.value.rowsPerPage = rowsPerPage;
pagination.value.sortBy = sortBy;
pagination.value.descending = descending;
search();
}
const { dialog } = useQuasar()
function openAuditDetail(evt, log) {
dialog({
component: AuditLogDetailModal,
componentProps: {
log
}
})
}
function formatActionColor(action) {
if (action === "add") return "success";
else if (action === "agent_install") return "success";
else if (action === "modify") return "warning";
else if (action === "delete") return "negative";
else if (action === "failed_login") return "negative";
else return "primary";
}
watch(filterType, () => {
agentFilter.value = null
clientFilter.value = null
})
const noDataText = computed(() => searched ? "No data found. Try to refine you search" : "Click search to find audit logs")
return {
// data
auditLogs,
agentFilter,
userFilter,
actionFilter,
clientFilter,
objectFilter,
timeFilter,
filterType,
loading,
searched,
pagination,
//computed
noDataText,
// methods
search,
onRequest,
openAuditDetail,
formatActionColor
}
}
useAuditLog.tableColumns = [
{
name: "entry_time",
label: "Time",
field: "entry_time",
align: "left",
sortable: true,
format: (val, row) => formatDate(val, true),
},
{ name: "username", label: "Username", field: "username", align: "left", sortable: true },
{ name: "agent", label: "Agent", field: "agent", align: "left", sortable: true },
{
name: "action",
label: "Action",
field: "action",
align: "left",
sortable: true,
format: (val, row) => formatTableColumnText(val)
},
{
name: "object_type",
label: "Object",
field: "object_type",
align: "left",
sortable: true,
format: (val, row) => formatTableColumnText(val),
},
{ name: "message", label: "Message", field: "message", align: "left", sortable: true },
]
useAuditLog.actionOptions = [
{ value: "agent_install", label: "Agent Installs" },
{ value: "add", label: "Add Object" },
{ value: "bulk_action", label: "Bulk Actions" },
{ value: "check_run", label: "Check Run Results" },
{ value: "execute_command", label: "Execute Command" },
{ value: "execute_script", label: "Execute Script" },
{ value: "delete", label: "Delete Object" },
{ value: "failed_login", label: "Failed User login" },
{ value: "login", label: "User Login" },
{ value: "modify", label: "Modify Object" },
{ value: "remote_session", label: "Remote Session" },
{ value: "task_run", label: "Task Run Results" },
]
useAuditLog.objectOptions = [
{ value: "agent", label: "Agent" },
{ value: "automatedtask", label: "Automated Task" },
{ value: "bulk", label: "Bulk Actions" },
{ value: "coresettings", label: "Core Settings" },
{ value: "check", label: "Check" },
{ value: "client", label: "Client" },
{ value: "policy", label: "Policy" },
{ value: "site", label: "Site" },
{ value: "script", label: "Script" },
{ value: "user", label: "User" },
{ value: "winupdatepolicy", label: "Patch Policy" },
]
useAuditLog.timeOptions = [
{ value: 1, label: "1 Day Ago" },
{ value: 7, label: "1 Week Ago" },
{ value: 30, label: "30 Days Ago" },
{ value: 90, label: "3 Months Ago" },
{ value: 180, label: "6 Months Ago" },
{ value: 365, label: "1 Year Ago" },
{ value: 0, label: "Everything" },
]
useAuditLog.filterTypeOptions = [
{
label: "Clients",
value: "clients",
},
{
label: "Agents",
value: "agents",
},
]