From d5104b5d27835cec43327d14e3737e35b23ffbe3 Mon Sep 17 00:00:00 2001 From: silversword411 Date: Sat, 6 Nov 2021 15:23:16 -0400 Subject: [PATCH 01/14] Add veeam wip scripts --- .../Win_Veeam_Backup_Script_Notification.ps1 | 35 ++- .../Win_Veeam_Backup_Script_Notification2.ps1 | 18 ++ .../Win_Veeam_Check_Agent_Backup24_Hours.ps1 | 223 ++++++++++++++++++ 3 files changed, 272 insertions(+), 4 deletions(-) create mode 100644 scripts_wip/Win_Veeam_Backup_Script_Notification2.ps1 create mode 100644 scripts_wip/Win_Veeam_Check_Agent_Backup24_Hours.ps1 diff --git a/scripts_wip/Win_Veeam_Backup_Script_Notification.ps1 b/scripts_wip/Win_Veeam_Backup_Script_Notification.ps1 index e5623ef3a8..2d8684bebf 100644 --- a/scripts_wip/Win_Veeam_Backup_Script_Notification.ps1 +++ b/scripts_wip/Win_Veeam_Backup_Script_Notification.ps1 @@ -1,13 +1,40 @@ +# Untested probably doesn't work -# Create RMMAlerts when a backup fails +if (Test-Path -Path "C:\Program Files\Veeam\Endpoint Backup") { + Write-Output "Veeam Installed" + + $event = Get-EventLog "Veeam Backup" -newest 1 -After (Get-Date).AddDays(-1) | Where-Object { $_.EventID -eq 0 } + + if ($event.entrytype -eq "Error") { + write-host "We got an event that is an error from Veeam Backup!" + Rmm-Alert -Category "veeam_backup_failed" -Body "Veeam Backup Failed on $(%computername%) - message: $($event.message)" + } + else { + write-host "No errors here" + } + +} +else { + Write-Output "Veeam not Installed + exit 0" +} + + +Exit $LASTEXITCODE $event = Get-EventLog "Veeam Backup" -newest 1 -After (Get-Date).AddDays(-1) | Where-Object { $_.EventID -eq 0 } if ($event.entrytype -eq "Error") { - write-host "We got an event that is an error from Veeam Backup!" - Rmm-Alert -Category "veeam_backup_failed" -Body "Veeam Backup Failed on $(%computername%) - message: $($event.message)" + write-host "We got an event that is an error from Veeam Backup!" + Rmm-Alert -Category "veeam_backup_failed" -Body "Veeam Backup Failed on $(%computername%) - message: $($event.message)" } else { - write-host "No errors here" + write-host "No errors here" } +else { + Write-Output "Veeam not Installed + exit 0" +} + +Exit $LASTEXITCODE \ No newline at end of file diff --git a/scripts_wip/Win_Veeam_Backup_Script_Notification2.ps1 b/scripts_wip/Win_Veeam_Backup_Script_Notification2.ps1 new file mode 100644 index 0000000000..e01068cfcc --- /dev/null +++ b/scripts_wip/Win_Veeam_Backup_Script_Notification2.ps1 @@ -0,0 +1,18 @@ +# Untested probably doesn't work + +$event = Get-EventLog "Veeam Backup" -newest 1 -After (Get-Date).AddDays(-1) | Where-Object { $_.EventID -eq 0 } + +if ($event.entrytype -eq "Error") { + write-host "We got an event that is an error from Veeam Backup!" + Rmm-Alert -Category "veeam_backup_failed" -Body "Veeam Backup Failed on $(%computername%) - message: $($event.message)" +} +else { + write-host "No errors here" +} +else { + Write-Output "Veeam not Installed + exit 0" +} + + +Exit $LASTEXITCODE \ No newline at end of file diff --git a/scripts_wip/Win_Veeam_Check_Agent_Backup24_Hours.ps1 b/scripts_wip/Win_Veeam_Check_Agent_Backup24_Hours.ps1 new file mode 100644 index 0000000000..f95a5c079f --- /dev/null +++ b/scripts_wip/Win_Veeam_Check_Agent_Backup24_Hours.ps1 @@ -0,0 +1,223 @@ +# +# Script name: check_veeam_eventlogs.ps1 +# Version: 1.1 +# Created on: 6May2015 +# Modified on: 24April2018 +# Author: Dallas Haselhorst +# Purpose: Check Veeam Backup success or failure via event logs +# Note: this requires PowerShell, however, it does NOT use the Veeam PowerShell plug-in +# +# Copyright: +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public +# License along with this program. If not, see . +# +# Heavily modified from the original script watch-eventlogs.ps1 +# written by Aaron Wurthmann (aaron (AT) wurthmann (DOT) com). Nonetheless, thanks Aaron! +# +# Older versions of NCPA used the following format, i.e. the following line can be copied to the $ARG1$ text box. +# -t '' -P -M 'agent/plugin/check_veeam_eventlogs.ps1//' +# Newer versions of NCPA would use the following format. Note the removal of "agent" and the added "s" to plugin +# -t '' -P -M 'plugins/check_veeam_eventlogs.ps1//' +# +# For testing from the Nagios command line, add './check_ncpa.py -H ' to the above line +# ArgBackupJobName is required. +# *** If your backup job name has special characters or spaces, I would suggest removing them! *** +# ArgLastMinutes should be populated with the time to check in minutes, e.g. 60 (for 1 hour), 120 (for 2 hours), +# +# Old Example +# -t 'TokenPass' -P 5693 -M 'agent/plugin/check_veeam_eventlogs.ps1/Management_VMs/24' +# -- above line would check the last 24 hours of Veeam Backup logs for the job named "Management_VMs" +# New Example +# -t 'TokenPass' -P 5693 -M 'plugins/check_veeam_eventlogs.ps1/TS01/24' +# -- above line would check the last 24 hours of Veeam Backup logs for the job named "TS01" + + +# Pull in arguments +$ArgLogName = "Veeam Agent" # veeam backup event log +$ArgEntryType = 1,2,3,4 # look for critical, error, warning and informational logs +$ArgProviderName = "Veeam Agent" +$ArgEventID = 190 # backup job complete event id + +$ArgBackupJobName = "Daily Backup" +$ArgLastHours = 24 + + +if (!$ArgBackupJobName) { +write-host "Sorry... at the very least, I need a backup job name." +write-host "Command line usage: check_veeam_eventlogs.ps1 " +write-host "Nagios NCPA usage: agent/plugin/check_veeam_eventlogs.ps1//" +exit +} +# Setting default values if null +if (!$ArgLastHours) { $ArgLastHours = (24) } +if (!$ArgWarningTH) { $ArgWarningTH = 0 } +if (!$ArgCriticalTH) { $ArgCriticalTH = 0 } +if (!$ArgMaxEntries) { $ArgMaxEntries = 50 } + +$CriticalErrorResultCount = 0 +$WarningResultCount = 0 +$InfoResultCount = 0 +$EventTypeLoopCount = 0 +$LogNameLoopCount = 0 +$ProviderNameLoopCount = 0 +$EventIDLoopCount = 0 + +$Properties='Level','Message','ProviderName','TimeCreated','Id' + +$Filter = @{ + LogName = $ArgLogName + StartTime = (Get-Date).AddHours(-$ArgLastHours) +} + +if($ArgProviderName) { $Filter += @{ProviderName = $ArgProviderName } } +if($ArgEventID) { $Filter += @{Id = $ArgEventID } } +if($ArgEntryType) { $Filter += @{Level = $ArgEntryType } } + +# -ea SilentlyContinue gets rid of non-terminating error resulting from zero events +$LogEntries = Get-WinEvent -MaxEvents $ArgMaxEntries -FilterHashtable $Filter -ea SilentlyContinue -Oldest | Select-Object -Property $Properties + +if ($LogEntries) { + + ForEach ($LogEntry in $LogEntries) { + if ($LogEntry.Message.ToString() -like "*Veeam Agent `'$ArgBackupJobName`'*") + { + $Level=$LogEntry.Level.ToString() + if (($Level -eq 1) -Or ($Level -eq 2)) # find critical and errors + { + $Message=$LogEntry.Message.Substring(0,[System.Math]::Min(180, $LogEntry.Message.Length)).TrimEnd().ToString() + $ProviderName=$LogEntry.ProviderName.ToString() + $TimeCreated=$LogEntry.TimeCreated.ToString() + $Id=$LogEntry.Id.ToString() + $CriticalErrorResultCount++ + + $CriticalErrorResults=@" + +At: $TimeCreated +Level: $Level +Event ID: $Id +Message: $Message +Source: $ProviderName +$CriticalErrorResults +"@ + } + elseif ($Level -eq 3) # find warnings + { + $Message=$LogEntry.Message.Substring(0,[System.Math]::Min(180, $LogEntry.Message.Length)).TrimEnd().ToString() + $ProviderName=$LogEntry.ProviderName.ToString() + $TimeCreated=$LogEntry.TimeCreated.ToString() + $Id=$LogEntry.Id.ToString() + $WarningResultCount++ + + $WarningResults=@" + +At: $TimeCreated +Level: $Level +Event ID: $Id +Message: $Message +Source: $ProviderName +$WarningResults +"@ + } + else # all that's left, find info (4) messages + { + $Message=$LogEntry.Message.Substring(0,[System.Math]::Min(180, $LogEntry.Message.Length)).TrimEnd().ToString() + $ProviderName=$LogEntry.ProviderName.ToString() + $TimeCreated=$LogEntry.TimeCreated.ToString() + $Id=$LogEntry.Id.ToString() + $InfoResultCount++ + + $InfoResults=@" + +At: $TimeCreated +Level: $Level +Event ID: $Id +Message: $Message +Source: $ProviderName +$InfoResults +"@ + } + } + +} + +} + +$Results= @" +$CriticalErrorResults $WarningResults $InfoResults +"@ + +if ($ArgEntryType) { +$TypeArray = @("all level","critical","error","warning","informational") +$LevelString = foreach ($Entry in $ArgEntryType) { + if ($ArgEntryType.Count -gt 1) { + $LevelStringBuild = $TypeArray[$Entry] + if ($ArgEntryType.Count -ne $EventTypeLoopCount+1) { + $LevelStringBuild +="," + } + } + + else { $LevelStringBuild = $TypeArray[$Entry] } + $EventTypeLoopCount++ + $LevelStringBuild + } +} + +$LogNameString = foreach ($LogNameEntry in $ArgLogName) { + $LogNameStringBuild += $LogNameEntry + if ($ArgLogName.Count -gt 1 -And $ArgLogName.Count -ne $LogNameLoopCount+1) { + $LogNameStringBuild += ", " + } + $LogNameLoopCount++ + } + +$ProviderNameString = foreach ($ProviderNameEntry in $ArgProviderName) { + $ProviderNameStringBuild += $ProviderNameEntry + if ($ArgProviderName.Count -gt 1 -And $ArgProviderName.Count -ne $ProviderNameLoopCount+1) { + $ProviderNameStringBuild += ", " + } + $ProviderNameLoopCount++ + } + +$EventIDString = foreach ($EventIDEntry in $ArgEventID) { + $EventIDStringBuild += "$EventIDEntry" + if ($ArgEventID.Count -gt 1 -And $ArgEventID.Count -ne $EventIDLoopCount+1) { + $EventIDStringBuild += ", " + } + $EventIDLoopCount++ + } + +If ($CriticalErrorResultCount -gt 0) { + $ResultString += "Backup failed: $CriticalErrorResultCount critical error(s) for backup job $ArgBackupJobName in last $ArgLastHours hours " + $NagiosMetricString += "'Errors'=$CriticalErrorResultCount 'BackupUnknown'=1 " + $ExitCode = 1 + } + +If ($WarningResultCount -gt 0) { + $ResultString += "Warning: backup job $ArgBackupJobName had $WarningResultCount warning message(s) in the last $ArgLastHours hours " + If ($ExitCode -ne 1) { + $NagiosMetricString += "'BackupUnknown'=1 " + $ExitCode = 1 + } + $NagiosMetricString += "'Warnings'=$WarningResultCount " + + } + +If (($InfoResultCount -lt 1) -And ($ExitCode -ne 1)) { + $ResultString += "Backup failed: backup job $ArgBackupJobName has not run in last $ArgLastHours hours " + $NagiosMetricString += "'BackupNotRun'=1 " + If ($ExitCode -ne 1) { $ExitCode = 1 } + } + +If (($InfoResultCount -ge 1) -And ($CriticalErrorResultCount -eq 0 ) -And ($WarningResultCount -eq 0 )){ + $ResultString += "OK: backup job $ArgBackupJobName completed successfully in last $ArgLastHours hours " + $NagiosMetricString = "'BackupSuccess'=1 " + $ExitCode = 0 + } + + write-host $ResultString + write-host $Results + write-host $ResultString"|"$NagiosMetricString + exit $ExitCode \ No newline at end of file From 706902da1c69e18ad3853b7415e2cc3c6f0f78dc Mon Sep 17 00:00:00 2001 From: silversword411 Date: Sat, 6 Nov 2021 15:30:51 -0400 Subject: [PATCH 02/14] wip script - user logon auditing --- scripts_wip/Win_User_Logon_Details.ps1 | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 scripts_wip/Win_User_Logon_Details.ps1 diff --git a/scripts_wip/Win_User_Logon_Details.ps1 b/scripts_wip/Win_User_Logon_Details.ps1 new file mode 100644 index 0000000000..3914929503 --- /dev/null +++ b/scripts_wip/Win_User_Logon_Details.ps1 @@ -0,0 +1,13 @@ +# Takes a long time to run. Probably needs at 5mins. +# Want to add logon events too + +$events = Get-WinEvent -Path C:\Windows\System32\winevt\Logs\Security.evtx | where { ($_.Id -eq 4624 -and $_.properties[8].value -eq 10) -or ($_.Id -eq 4634 -and $_.properties[4].value -eq 2) } + +foreach ($event in $events) { + + # userid will vary depending on event type: + if ($event.Id -eq 4624) { $userid = $event.properties[5].value } + if ($event.Id -eq 4634) { $userid = $event.properties[1].value } + + $event | Select TimeCReated, TaskDisplayName, Machinename, @{"Name" = "UserID"; "Expression" = { $userid } } +} \ No newline at end of file From bc495d77d1148a2c25d6b688a1d18ddafd0e025f Mon Sep 17 00:00:00 2001 From: wh1te909 Date: Sun, 7 Nov 2021 09:38:08 +0000 Subject: [PATCH 03/14] fix django admin render error --- api/tacticalrmm/checks/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/tacticalrmm/checks/models.py b/api/tacticalrmm/checks/models.py index 0f6ec9762c..3c14bc5138 100644 --- a/api/tacticalrmm/checks/models.py +++ b/api/tacticalrmm/checks/models.py @@ -679,4 +679,4 @@ class CheckHistory(models.Model): results = models.JSONField(null=True, blank=True) def __str__(self): - return self.x + return str(self.x) From 496abdd230e60fc37c2a4391c3b6b86a44843fab Mon Sep 17 00:00:00 2001 From: wh1te909 Date: Sun, 7 Nov 2021 09:39:04 +0000 Subject: [PATCH 04/14] fix sorting --- web/src/components/agents/WinUpdateTab.vue | 4 ++-- web/src/utils/format.js | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/web/src/components/agents/WinUpdateTab.vue b/web/src/components/agents/WinUpdateTab.vue index 98e0d51a8f..5ebf61a532 100644 --- a/web/src/components/agents/WinUpdateTab.vue +++ b/web/src/components/agents/WinUpdateTab.vue @@ -123,7 +123,7 @@ import { useStore } from "vuex"; import { useQuasar } from "quasar"; import { fetchAgentUpdates, editAgentUpdate, runAgentUpdateScan, runAgentUpdateInstall } from "@/api/winupdates"; import { notifySuccess } from "@/utils/notify"; -import { truncateText, formatDate } from "@/utils/format"; +import { truncateText, formatDate, dateStringToUnix } from "@/utils/format"; // ui imports import ExportTableBtn from "@/components/ui/ExportTableBtn"; @@ -167,7 +167,7 @@ const columns = [ field: "date_installed", align: "left", sortable: true, - sort: (a, b) => this.dateStringToUnix(a) - this.dateStringToUnix(b), + sort: (a, b) => dateStringToUnix(a) - dateStringToUnix(b), }, ]; diff --git a/web/src/utils/format.js b/web/src/utils/format.js index 1b8ed54629..03f24fe478 100644 --- a/web/src/utils/format.js +++ b/web/src/utils/format.js @@ -181,6 +181,11 @@ export function getNextAgentUpdateTime() { return `${a} at ${b}`; } +export function dateStringToUnix(drfString) { + if (!drfString) return 0; + const d = date.extractDate(drfString, "MM DD YYYY HH:mm"); + return parseInt(date.formatDate(d, "X")); +} // string formatting From 1b02974efae0c9b3b306c14931326e8be68d2aad Mon Sep 17 00:00:00 2001 From: sadnub Date: Sun, 7 Nov 2021 07:24:46 -0500 Subject: [PATCH 05/14] fix core settings showing when permissions should restrict it --- api/tacticalrmm/core/views.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api/tacticalrmm/core/views.py b/api/tacticalrmm/core/views.py index a3324f05b6..488b5ddbc3 100644 --- a/api/tacticalrmm/core/views.py +++ b/api/tacticalrmm/core/views.py @@ -57,9 +57,8 @@ def put(self, request, format=None): "Mesh Agent uploaded successfully", status=status.HTTP_201_CREATED ) - +@permission_classes([IsAuthenticated, CoreSettingsPerms]) class GetEditCoreSettings(APIView): - @permission_classes([IsAuthenticated, CoreSettingsPerms]) def get(self, request): settings = CoreSettings.objects.first() return Response(CoreSettingsSerializer(settings).data) From f60e4e3e4fc79a04c300a3c4c901d202414d8c14 Mon Sep 17 00:00:00 2001 From: sadnub Date: Sun, 7 Nov 2021 07:31:45 -0500 Subject: [PATCH 06/14] fix email test sending --- api/tacticalrmm/core/models.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/api/tacticalrmm/core/models.py b/api/tacticalrmm/core/models.py index 7227cf7506..8d3c02fbb2 100644 --- a/api/tacticalrmm/core/models.py +++ b/api/tacticalrmm/core/models.py @@ -153,9 +153,9 @@ def email_is_configured(self): def send_mail(self, subject, body, alert_template=None, test=False): - if not alert_template or not self.email_is_configured: + if not alert_template and not self.email_is_configured: if test: - return "Missing required fields (need at least 1 recipient)" + return "Email server settings are not configured correctly" return False # override email from if alert_template is passed and is set @@ -170,6 +170,9 @@ def send_mail(self, subject, body, alert_template=None, test=False): else: email_recipients = ", ".join(self.email_alert_recipients) + if not email_recipients: + return "There needs to be at least one email recipient configured" + try: msg = EmailMessage() msg["Subject"] = subject @@ -197,7 +200,7 @@ def send_mail(self, subject, body, alert_template=None, test=False): return True def send_sms(self, body, alert_template=None, test=False): - if not alert_template or not self.sms_is_configured: + if not alert_template and not self.sms_is_configured: return "Sms alerting is not setup correctly." # override email recipients if alert_template is passed and is set From 363e48a1e8c96a528d4168bbb8599803add56737 Mon Sep 17 00:00:00 2001 From: sadnub Date: Sun, 7 Nov 2021 07:34:14 -0500 Subject: [PATCH 07/14] formatting --- api/tacticalrmm/core/views.py | 1 + 1 file changed, 1 insertion(+) diff --git a/api/tacticalrmm/core/views.py b/api/tacticalrmm/core/views.py index 488b5ddbc3..06438d7132 100644 --- a/api/tacticalrmm/core/views.py +++ b/api/tacticalrmm/core/views.py @@ -57,6 +57,7 @@ def put(self, request, format=None): "Mesh Agent uploaded successfully", status=status.HTTP_201_CREATED ) + @permission_classes([IsAuthenticated, CoreSettingsPerms]) class GetEditCoreSettings(APIView): def get(self, request): From b079eebe79987e172d5b95c7e8802b7d3d6ed658 Mon Sep 17 00:00:00 2001 From: sadnub Date: Sun, 7 Nov 2021 07:56:12 -0500 Subject: [PATCH 08/14] add restricted users to the client/site that they are adding to the system --- api/tacticalrmm/clients/tests.py | 32 ++++++++++++++++++++++++++++++++ api/tacticalrmm/clients/views.py | 8 ++++++++ 2 files changed, 40 insertions(+) diff --git a/api/tacticalrmm/clients/tests.py b/api/tacticalrmm/clients/tests.py index 19d6f1ee5e..cb8534c7b2 100644 --- a/api/tacticalrmm/clients/tests.py +++ b/api/tacticalrmm/clients/tests.py @@ -839,3 +839,35 @@ def test_delete_deployments_permissions(self, delete): self.check_authorized("delete", url) self.check_not_authorized("delete", unauthorized_url) + + def test_restricted_user_creating_clients(self): + from accounts.models import User + + # when a user that is limited to a specific subset of clients creates a client. It should allow access to that client + client = baker.make("clients.Client") + user = self.create_user_with_roles(["can_manage_clients"]) + self.client.force_authenticate(user=user) # type: ignore + user.role.can_view_clients.set([client]) + + data = {"client": {"name": "New Client"}, "site": {"name": "New Site"}} + + self.client.post(f"{base_url}/", data, format="json") + + # make sure two clients are allowed now + self.assertEqual(User.objects.get(id=user.id).role.can_view_clients.count(), 2) + + def test_restricted_user_creating_sites(self): + from accounts.models import User + + # when a user that is limited to a specific subset of clients creates a client. It should allow access to that client + site = baker.make("clients.Site") + user = self.create_user_with_roles(["can_manage_sites"]) + self.client.force_authenticate(user=user) # type: ignore + user.role.can_view_sites.set([site]) + + data = {"site": {"client": site.client.id, "name": "New Site"}} + + self.client.post(f"{base_url}/sites/", data, format="json") + + # make sure two sites are allowed now + self.assertEqual(User.objects.get(id=user.id).role.can_view_sites.count(), 2) diff --git a/api/tacticalrmm/clients/views.py b/api/tacticalrmm/clients/views.py index 30144453b0..6bec2a4a09 100644 --- a/api/tacticalrmm/clients/views.py +++ b/api/tacticalrmm/clients/views.py @@ -76,6 +76,10 @@ def post(self, request): serializer.is_valid(raise_exception=True) serializer.save() + # add user to allowed clients in role if restricted user created the client + if request.user.role and request.user.role.can_view_clients.exists(): + request.user.role.can_view_clients.add(client) + return Response(f"{client.name} was added") @@ -167,6 +171,10 @@ def post(self, request): serializer.is_valid(raise_exception=True) serializer.save() + # add user to allowed sites in role if restricted user created the client + if request.user.role and request.user.role.can_view_sites.exists(): + request.user.role.can_view_sites.add(site) + return Response(f"Site {site.name} was added!") From c76d2633751aa99e57113b65c20ee9f783789429 Mon Sep 17 00:00:00 2001 From: sadnub Date: Sun, 7 Nov 2021 12:37:36 -0500 Subject: [PATCH 09/14] stop loading when no audit log permissions --- web/src/api/logs.js | 6 ++---- web/src/components/logs/AuditManager.vue | 9 +++++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/web/src/api/logs.js b/web/src/api/logs.js index 26c7ef9334..0462626a59 100644 --- a/web/src/api/logs.js +++ b/web/src/api/logs.js @@ -10,10 +10,8 @@ export async function fetchDebugLog(payload) { } export async function fetchAuditLog(payload) { - try { - const { data } = await axios.patch(`${baseUrl}/audit/`, payload) - return data - } catch (e) { } + const { data } = await axios.patch(`${baseUrl}/audit/`, payload) + return data } // pending actions diff --git a/web/src/components/logs/AuditManager.vue b/web/src/components/logs/AuditManager.vue index bca5151224..eb4bb0b934 100644 --- a/web/src/components/logs/AuditManager.vue +++ b/web/src/components/logs/AuditManager.vue @@ -274,10 +274,11 @@ export default { 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; + try { + const { audit_logs, total } = await fetchAuditLog(data); + auditLogs.value = audit_logs; + pagination.value.rowsNumber = total; + } catch (e) {} loading.value = false; } From a55f1879584b203849622b58efcb8c5c788d4f76 Mon Sep 17 00:00:00 2001 From: sadnub Date: Sun, 7 Nov 2021 13:00:53 -0500 Subject: [PATCH 10/14] fit task control to screen --- web/src/views/TakeControl.vue | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/web/src/views/TakeControl.vue b/web/src/views/TakeControl.vue index 0f07223b19..4e6a3c0785 100644 --- a/web/src/views/TakeControl.vue +++ b/web/src/views/TakeControl.vue @@ -1,6 +1,6 @@ From 2926b68c325401638525a89ef411605f8ca7d95c Mon Sep 17 00:00:00 2001 From: sadnub Date: Sun, 7 Nov 2021 13:12:45 -0500 Subject: [PATCH 11/14] change permission_classes under class view instead of decorator --- api/tacticalrmm/core/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/tacticalrmm/core/views.py b/api/tacticalrmm/core/views.py index 06438d7132..fa68fb6c54 100644 --- a/api/tacticalrmm/core/views.py +++ b/api/tacticalrmm/core/views.py @@ -58,8 +58,9 @@ def put(self, request, format=None): ) -@permission_classes([IsAuthenticated, CoreSettingsPerms]) class GetEditCoreSettings(APIView): + permission_classes = [IsAuthenticated, CoreSettingsPerms] + def get(self, request): settings = CoreSettings.objects.first() return Response(CoreSettingsSerializer(settings).data) From fa3f5f8d6823cc1333e3b1c713a9d620f34417a4 Mon Sep 17 00:00:00 2001 From: wh1te909 Date: Sun, 7 Nov 2021 20:11:59 +0000 Subject: [PATCH 12/14] fix alerts still polling on logout --- web/src/components/AlertsIcon.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/components/AlertsIcon.vue b/web/src/components/AlertsIcon.vue index 9f47151726..6d38dff31a 100644 --- a/web/src/components/AlertsIcon.vue +++ b/web/src/components/AlertsIcon.vue @@ -138,7 +138,7 @@ export default { else return this.alertsCount; }, pollAlerts() { - setInterval(() => { + this.poll = setInterval(() => { this.getAlerts(); }, 60 * 1 * 1000); }, From 166be395b9d665cbbf4bfd76b5297566bbf9fa6d Mon Sep 17 00:00:00 2001 From: wh1te909 Date: Sun, 7 Nov 2021 20:33:58 +0000 Subject: [PATCH 13/14] fix email/sms --- api/tacticalrmm/core/models.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/api/tacticalrmm/core/models.py b/api/tacticalrmm/core/models.py index 8d3c02fbb2..2f9c233752 100644 --- a/api/tacticalrmm/core/models.py +++ b/api/tacticalrmm/core/models.py @@ -152,10 +152,10 @@ def email_is_configured(self): return False def send_mail(self, subject, body, alert_template=None, test=False): - - if not alert_template and not self.email_is_configured: - if test: - return "Email server settings are not configured correctly" + if test and not self.email_is_configured: + return "There needs to be at least one email recipient configured" + # return since email must be configured to continue + elif not self.email_is_configured: return False # override email from if alert_template is passed and is set @@ -200,7 +200,7 @@ def send_mail(self, subject, body, alert_template=None, test=False): return True def send_sms(self, body, alert_template=None, test=False): - if not alert_template and not self.sms_is_configured: + if not self.sms_is_configured: return "Sms alerting is not setup correctly." # override email recipients if alert_template is passed and is set From b84d4a99b833d323cc1492225f78d9a6ec0b4142 Mon Sep 17 00:00:00 2001 From: wh1te909 Date: Sun, 7 Nov 2021 21:00:25 +0000 Subject: [PATCH 14/14] bump version --- api/tacticalrmm/tacticalrmm/settings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/tacticalrmm/tacticalrmm/settings.py b/api/tacticalrmm/tacticalrmm/settings.py index eeb2c6c251..e14cb08a0c 100644 --- a/api/tacticalrmm/tacticalrmm/settings.py +++ b/api/tacticalrmm/tacticalrmm/settings.py @@ -15,11 +15,11 @@ AUTH_USER_MODEL = "accounts.User" # latest release -TRMM_VERSION = "0.9.0" +TRMM_VERSION = "0.9.1" # bump this version everytime vue code is changed # to alert user they need to manually refresh their browser -APP_VER = "0.0.148" +APP_VER = "0.0.149" # https://github.com/wh1te909/rmmagent LATEST_AGENT_VER = "1.6.2"