mirror of
https://github.com/jpros/tacticalrmm-web.git
synced 2026-02-26 14:22:05 +00:00
audit manager rework
This commit is contained in:
@@ -8,9 +8,12 @@
|
||||
<q-tooltip content-class="bg-white text-primary">Close</q-tooltip>
|
||||
</q-btn>
|
||||
</q-bar>
|
||||
<div class="text-h6 q-pl-sm q-pt-sm">Filter Results</div>
|
||||
<div class="text-h6 q-pl-sm q-pt-sm">Filter</div>
|
||||
<div class="row">
|
||||
<div class="q-pa-sm col-2">
|
||||
<div class="q-pa-sm col-1">
|
||||
<q-option-group v-model="filterType" :options="filterTypeOptions" color="primary" @input="clear" />
|
||||
</div>
|
||||
<div class="q-pa-sm col-2" v-if="filterType === 'agents'">
|
||||
<q-select
|
||||
new-value-mode="add"
|
||||
multiple
|
||||
@@ -34,6 +37,20 @@
|
||||
</template>
|
||||
</q-select>
|
||||
</div>
|
||||
<div class="q-pa-sm col-2" v-if="filterType === 'clients'">
|
||||
<q-select
|
||||
clearable
|
||||
multiple
|
||||
filled
|
||||
dense
|
||||
v-model="clientFilter"
|
||||
fill-input
|
||||
label="Clients"
|
||||
map-options
|
||||
emit-value
|
||||
:options="clientsOptions"
|
||||
/>
|
||||
</div>
|
||||
<div class="q-pa-sm col-2">
|
||||
<q-select
|
||||
new-value-mode="add"
|
||||
@@ -58,6 +75,19 @@
|
||||
</template>
|
||||
</q-select>
|
||||
</div>
|
||||
<div class="q-pa-sm col-2">
|
||||
<q-select
|
||||
clearable
|
||||
filled
|
||||
multiple
|
||||
dense
|
||||
v-model="actionFilter"
|
||||
label="Action"
|
||||
emit-value
|
||||
map-options
|
||||
:options="actionOptions"
|
||||
/>
|
||||
</div>
|
||||
<div class="q-pa-sm col-2">
|
||||
<q-select filled dense v-model="timeFilter" label="Time" emit-value map-options :options="timeOptions">
|
||||
<template v-slot:no-option>
|
||||
@@ -77,18 +107,25 @@
|
||||
dense
|
||||
class="audit-mgr-tbl-sticky"
|
||||
binary-state-sort
|
||||
virtual-scroll
|
||||
title="Audit Logs"
|
||||
:data="auditLogs"
|
||||
:columns="columns"
|
||||
row-key="id"
|
||||
:pagination.sync="pagination"
|
||||
:rows-per-page-options="[25, 50, 100, 500, 1000]"
|
||||
:no-data-label="noDataText"
|
||||
@row-click="showDetails"
|
||||
>
|
||||
<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-section>
|
||||
<div class="q-pa-md q-gutter-sm">
|
||||
@@ -132,9 +169,23 @@ export default {
|
||||
auditLogs: [],
|
||||
userOptions: [],
|
||||
agentOptions: [],
|
||||
agentFilter: [],
|
||||
agentFilter: null,
|
||||
userFilter: [],
|
||||
actionFilter: null,
|
||||
clientsOptions: [],
|
||||
clientFilter: null,
|
||||
timeFilter: 30,
|
||||
filterType: "clients",
|
||||
filterTypeOptions: [
|
||||
{
|
||||
label: "Clients",
|
||||
value: "clients",
|
||||
},
|
||||
{
|
||||
label: "Agents",
|
||||
value: "agents",
|
||||
},
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
name: "entry_time",
|
||||
@@ -147,9 +198,30 @@ export default {
|
||||
{ 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 },
|
||||
{ name: "object_type", label: "Object", field: "object_type", 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 },
|
||||
],
|
||||
actionOptions: [
|
||||
{ value: "login", label: "User Login" },
|
||||
{ value: "failed_login", label: "Failed User login" },
|
||||
{ value: "add", label: "Add Object" },
|
||||
{ value: "modify", label: "Modify Object" },
|
||||
{ value: "delete", label: "Delete Object" },
|
||||
{ value: "check_run", label: "Check Run Results" },
|
||||
{ value: "task_run", label: "Task Run Results" },
|
||||
{ value: "agent_install", label: "Agent Installs" },
|
||||
{ value: "remote_session", label: "Remote Session" },
|
||||
{ value: "execute_script", label: "Execute Script" },
|
||||
{ value: "execute_command", label: "Execute Command" },
|
||||
{ value: "bulk_action", label: "Bulk Actions" },
|
||||
],
|
||||
timeOptions: [
|
||||
{ value: 1, label: "1 Day Ago" },
|
||||
{ value: 7, label: "1 Week Ago" },
|
||||
@@ -159,13 +231,18 @@ export default {
|
||||
{ value: 0, label: "Everything" },
|
||||
],
|
||||
pagination: {
|
||||
rowsPerPage: 50,
|
||||
rowsPerPage: 25,
|
||||
sortBy: "entry_time",
|
||||
descending: true,
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getClients() {
|
||||
this.$axios.get("/clients/clients/").then(r => {
|
||||
this.clientsOptions = Object.freeze(r.data.map(client => ({ label: client.name, value: client.id })));
|
||||
});
|
||||
},
|
||||
getUserOptions(val, update, abort) {
|
||||
if (val.length < 2) {
|
||||
abort();
|
||||
@@ -185,7 +262,7 @@ export default {
|
||||
this.$axios
|
||||
.post(`logs/auditlogs/optionsfilter/`, data)
|
||||
.then(r => {
|
||||
this.userOptions = r.data.map(user => user.username);
|
||||
this.userOptions = Object.freeze(r.data.map(user => user.username));
|
||||
this.$q.loading.hide();
|
||||
})
|
||||
.catch(e => {
|
||||
@@ -212,7 +289,7 @@ export default {
|
||||
this.$axios
|
||||
.post(`logs/auditlogs/optionsfilter/`, data)
|
||||
.then(r => {
|
||||
this.agentOptions = r.data.map(agent => agent.hostname);
|
||||
this.agentOptions = Object.freeze(r.data.map(agent => agent.hostname));
|
||||
this.$q.loading.hide();
|
||||
})
|
||||
.catch(e => {
|
||||
@@ -252,23 +329,17 @@ export default {
|
||||
this.searched = true;
|
||||
let data = {};
|
||||
|
||||
if (this.agentFilter.length > 0) {
|
||||
data["agentFilter"] = this.agentFilter;
|
||||
}
|
||||
|
||||
if (this.userFilter.length > 0) {
|
||||
data["userFilter"] = this.userFilter;
|
||||
}
|
||||
|
||||
if (this.timeFilter) {
|
||||
data["timeFilter"] = this.timeFilter;
|
||||
}
|
||||
if (this.agentFilter !== null) data["agentFilter"] = this.agentFilter;
|
||||
else if (this.clientFilter !== null) data["clientFilter"] = this.clientFilter;
|
||||
if (this.userFilter.length > 0) data["userFilter"] = this.userFilter;
|
||||
if (this.timeFilter) data["timeFilter"] = this.timeFilter;
|
||||
if (this.actionFilter !== null) data["actionFilter"] = this.actionFilter;
|
||||
|
||||
this.$axios
|
||||
.patch("/logs/auditlogs/", data)
|
||||
.then(r => {
|
||||
this.$q.loading.hide();
|
||||
this.auditLogs = r.data;
|
||||
this.auditLogs = Object.freeze(r.data);
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
@@ -282,11 +353,40 @@ export default {
|
||||
this.logDetails = null;
|
||||
this.showLogDetails = false;
|
||||
},
|
||||
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);
|
||||
},
|
||||
clear() {
|
||||
this.clientFilter = null;
|
||||
this.agentFilter = null;
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
noDataText() {
|
||||
return this.searched ? "No data found. Try to refine you search" : "Click search to find audit logs";
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getClients();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<q-card style="width: 70vw; max-width: 90vw;">
|
||||
<q-card style="width: 70vw; max-width: 90vw">
|
||||
<q-bar>
|
||||
<span class="text-caption">{{ log.message }}</span>
|
||||
<q-space />
|
||||
<q-btn dense flat icon="close" v-close-popup />
|
||||
</q-bar>
|
||||
<q-card-section class="row">
|
||||
<div class="col-6">
|
||||
<q-card-section class="row scroll" style="max-height: 65vh">
|
||||
<div class="col-6" v-if="log.before_value !== null">
|
||||
<div class="text-h6">Before</div>
|
||||
<pre>{{ JSON.stringify(log.before_value, null, 4) }}</pre>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user