diff --git a/api/tacticalrmm/accounts/views.py b/api/tacticalrmm/accounts/views.py index 4a7ca5e1..a8e8f446 100644 --- a/api/tacticalrmm/accounts/views.py +++ b/api/tacticalrmm/accounts/views.py @@ -11,7 +11,7 @@ from rest_framework.permissions import AllowAny, IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIView -from tacticalrmm.utils import notify_error +from tacticalrmm.helpers import notify_error from .models import APIKey, Role, User from .permissions import AccountsPerms, APIKeyPerms, RolesPerms diff --git a/api/tacticalrmm/agents/management/commands/fake_agents.py b/api/tacticalrmm/agents/management/commands/fake_agents.py index bb5c635a..eb47d992 100644 --- a/api/tacticalrmm/agents/management/commands/fake_agents.py +++ b/api/tacticalrmm/agents/management/commands/fake_agents.py @@ -43,19 +43,19 @@ EVT_LOG_FAIL = settings.BASE_DIR.joinpath( class Command(BaseCommand): help = "populate database with fake agents" - def rand_string(self, length): + def rand_string(self, length: int) -> str: chars = string.ascii_letters return "".join(random.choice(chars) for _ in range(length)) - def handle(self, *args, **kwargs): + def handle(self, *args, **kwargs) -> None: user = User.objects.first() if user: user.totp_key = "ABSA234234" user.save(update_fields=["totp_key"]) - Client.objects.all().delete() Agent.objects.all().delete() + Client.objects.all().delete() Check.objects.all().delete() Script.objects.all().delete() AutomatedTask.objects.all().delete() @@ -65,6 +65,9 @@ class Command(BaseCommand): PendingAction.objects.all().delete() call_command("load_community_scripts") + call_command("initial_db_setup") + call_command("load_chocos") + call_command("create_installer_user") # policies check_policy = Policy() @@ -95,27 +98,27 @@ class Command(BaseCommand): update_policy.email_if_fail = True update_policy.save() - clients = [ + clients = ( + "Company 1", "Company 2", "Company 3", - "Company 1", "Company 4", "Company 5", "Company 6", - ] - sites1 = ["HQ1", "LA Office 1", "NY Office 1"] - sites2 = ["HQ2", "LA Office 2", "NY Office 2"] - sites3 = ["HQ3", "LA Office 3", "NY Office 3"] - sites4 = ["HQ4", "LA Office 4", "NY Office 4"] - sites5 = ["HQ5", "LA Office 5", "NY Office 5"] - sites6 = ["HQ6", "LA Office 6", "NY Office 6"] + ) + sites1 = ("HQ1", "LA Office 1", "NY Office 1") + sites2 = ("HQ2", "LA Office 2", "NY Office 2") + sites3 = ("HQ3", "LA Office 3", "NY Office 3") + sites4 = ("HQ4", "LA Office 4", "NY Office 4") + sites5 = ("HQ5", "LA Office 5", "NY Office 5") + sites6 = ("HQ6", "LA Office 6", "NY Office 6") - client1 = Client(name="Company 1") - client2 = Client(name="Company 2") - client3 = Client(name="Company 3") - client4 = Client(name="Company 4") - client5 = Client(name="Company 5") - client6 = Client(name="Company 6") + client1 = Client(name=clients[0]) + client2 = Client(name=clients[1]) + client3 = Client(name=clients[2]) + client4 = Client(name=clients[3]) + client5 = Client(name=clients[4]) + client6 = Client(name=clients[5]) client1.save() client2.save() @@ -142,7 +145,7 @@ class Command(BaseCommand): for site in sites6: Site(client=client6, name=site).save() - hostnames = [ + hostnames = ( "DC-1", "DC-2", "FSV-1", @@ -150,26 +153,27 @@ class Command(BaseCommand): "WSUS", "DESKTOP-12345", "LAPTOP-55443", - ] - descriptions = ["Bob's computer", "Primary DC", "File Server", "Karen's Laptop"] - modes = ["server", "workstation"] - op_systems_servers = [ + ) + descriptions = ("Bob's computer", "Primary DC", "File Server", "Karen's Laptop") + modes = ("server", "workstation") + op_systems_servers = ( "Microsoft Windows Server 2016 Standard, 64bit (build 14393)", "Microsoft Windows Server 2012 R2 Standard, 64bit (build 9600)", "Microsoft Windows Server 2019 Standard, 64bit (build 17763)", - ] + ) - op_systems_workstations = [ + op_systems_workstations = ( "Microsoft Windows 8.1 Pro, 64bit (build 9600)", "Microsoft Windows 10 Pro for Workstations, 64bit (build 18363)", "Microsoft Windows 10 Pro, 64bit (build 18363)", - ] + ) public_ips = ["65.234.22.4", "74.123.43.5", "44.21.134.45"] total_rams = [4, 8, 16, 32, 64, 128] now = dt.datetime.now() + django_now = djangotime.now() boot_times = [] @@ -196,10 +200,7 @@ class Command(BaseCommand): with open(WMI_3) as f: wmi3 = json.load(f) - wmi_details = [] - wmi_details.append(wmi1) - wmi_details.append(wmi2) - wmi_details.append(wmi3) + wmi_details = [i for i in (wmi1, wmi2, wmi3)] # software with open(SW_1) as f: @@ -208,9 +209,7 @@ class Command(BaseCommand): with open(SW_2) as f: software2 = json.load(f) - softwares = [] - softwares.append(software1) - softwares.append(software2) + softwares = [i for i in (software1, software2)] # windows updates with open(WIN_UPDATES) as f: @@ -261,20 +260,18 @@ class Command(BaseCommand): client = random.choice(clients) - if client == "Company 1": + if client == clients[0]: site = random.choice(sites1) - elif client == "Company 2": + elif client == clients[1]: site = random.choice(sites2) - elif client == "Company 3": + elif client == clients[2]: site = random.choice(sites3) - elif client == "Company 4": + elif client == clients[3]: site = random.choice(sites4) - elif client == "Company 5": + elif client == clients[4]: site = random.choice(sites5) - elif client == "Company 6": + elif client == clients[5]: site = random.choice(sites6) - else: - site = None agent = Agent() @@ -285,15 +282,15 @@ class Command(BaseCommand): agent.operating_system = random.choice(op_systems_workstations) agent.hostname = random.choice(hostnames) + agent.goarch = "amd64" agent.version = settings.LATEST_AGENT_VER agent.site = Site.objects.get(name=site) - agent.agent_id = self.rand_string(25) + agent.agent_id = self.rand_string(40) agent.description = random.choice(descriptions) agent.monitoring_type = mode agent.public_ip = random.choice(public_ips) agent.last_seen = djangotime.now() agent.plat = "windows" - agent.plat_release = "windows-2019Server" agent.total_ram = random.choice(total_rams) agent.boot_time = random.choice(boot_times) agent.logged_in_username = random.choice(user_names) @@ -317,9 +314,7 @@ class Command(BaseCommand): WinUpdatePolicy(agent=agent).save() # windows updates load - guids = [] - for k in windows_updates.keys(): - guids.append(k) + guids = [i for i in windows_updates.keys()] for i in guids: WinUpdate( @@ -357,14 +352,8 @@ class Command(BaseCommand): # disk space check check1 = Check() - check_result1 = CheckResult(assigned_check=check1, agent=agent) check1.agent = agent check1.check_type = "diskspace" - check_result1.status = "passing" - check_result1.last_run = djangotime.now() - check_result1.more_info = "Total: 498.7GB, Free: 287.4GB" - check_result1.save() - check1.warning_threshold = 25 check1.error_threshold = 10 check1.disk = "C:" @@ -372,6 +361,14 @@ class Command(BaseCommand): check1.text_alert = random.choice([True, False]) check1.save() + check_result1 = CheckResult() + check_result1.agent = agent + check_result1.assigned_check = check1 + check_result1.status = "passing" + check_result1.last_run = django_now + check_result1.more_info = "Total: 498.7GB, Free: 287.4GB" + check_result1.save() + for i in range(30): check1_history = CheckHistory() check1_history.check_id = check1.pk @@ -384,13 +381,18 @@ class Command(BaseCommand): # ping check check2 = Check() - check_result2 = CheckResult(assigned_check=check2, agent=agent) + check_result2 = CheckResult() + check2.agent = agent check2.check_type = "ping" - check_result2.last_run = djangotime.now() + check2.email_alert = random.choice([True, False]) check2.text_alert = random.choice([True, False]) + check_result2.agent = agent + check_result2.assigned_check = check2 + check_result2.last_run = django_now + if site in sites5: check2.name = "Synology NAS" check_result2.status = "failing" diff --git a/api/tacticalrmm/agents/views.py b/api/tacticalrmm/agents/views.py index b4975163..806fceb8 100644 --- a/api/tacticalrmm/agents/views.py +++ b/api/tacticalrmm/agents/views.py @@ -37,7 +37,8 @@ from tacticalrmm.permissions import ( _has_perm_on_client, _has_perm_on_site, ) -from tacticalrmm.utils import get_default_timezone, notify_error, reload_nats +from tacticalrmm.utils import get_default_timezone, reload_nats +from tacticalrmm.helpers import notify_error from .models import Agent, AgentCustomField, AgentHistory, Note from .permissions import ( diff --git a/api/tacticalrmm/alerts/views.py b/api/tacticalrmm/alerts/views.py index 4c215ad0..78b33362 100644 --- a/api/tacticalrmm/alerts/views.py +++ b/api/tacticalrmm/alerts/views.py @@ -7,7 +7,7 @@ from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIView -from tacticalrmm.utils import notify_error +from tacticalrmm.helpers import notify_error from .models import Alert, AlertTemplate from .permissions import AlertPerms, AlertTemplatePerms diff --git a/api/tacticalrmm/apiv3/views.py b/api/tacticalrmm/apiv3/views.py index 1b8f4f67..424145b3 100644 --- a/api/tacticalrmm/apiv3/views.py +++ b/api/tacticalrmm/apiv3/views.py @@ -24,7 +24,8 @@ from software.models import InstalledSoftware from winupdate.models import WinUpdate, WinUpdatePolicy from tacticalrmm.constants import MeshAgentIdent -from tacticalrmm.utils import notify_error, reload_nats +from tacticalrmm.utils import reload_nats +from tacticalrmm.helpers import notify_error class CheckIn(APIView): diff --git a/api/tacticalrmm/checks/views.py b/api/tacticalrmm/checks/views.py index 2c690ee3..fafb1d32 100644 --- a/api/tacticalrmm/checks/views.py +++ b/api/tacticalrmm/checks/views.py @@ -14,7 +14,7 @@ from rest_framework.response import Response from rest_framework.views import APIView from tacticalrmm.permissions import _has_perm_on_agent -from tacticalrmm.utils import notify_error +from tacticalrmm.helpers import notify_error from .models import Check, CheckHistory, CheckResult from .permissions import ChecksPerms, RunChecksPerms diff --git a/api/tacticalrmm/clients/views.py b/api/tacticalrmm/clients/views.py index bd5decbb..30db166a 100644 --- a/api/tacticalrmm/clients/views.py +++ b/api/tacticalrmm/clients/views.py @@ -14,7 +14,7 @@ from rest_framework.views import APIView from knox.models import AuthToken from tacticalrmm.permissions import _has_perm_on_client, _has_perm_on_site -from tacticalrmm.utils import notify_error +from tacticalrmm.helpers import notify_error from .models import Client, ClientCustomField, Deployment, Site, SiteCustomField from .permissions import ClientsPerms, DeploymentPerms, SitesPerms diff --git a/api/tacticalrmm/core/views.py b/api/tacticalrmm/core/views.py index f70ec325..cd32712d 100644 --- a/api/tacticalrmm/core/views.py +++ b/api/tacticalrmm/core/views.py @@ -15,7 +15,7 @@ from tacticalrmm.permissions import ( _has_perm_on_client, _has_perm_on_site, ) -from tacticalrmm.utils import notify_error +from tacticalrmm.helpers import notify_error from .models import CodeSignToken, CoreSettings, CustomField, GlobalKVStore, URLAction from .permissions import ( diff --git a/api/tacticalrmm/logs/views.py b/api/tacticalrmm/logs/views.py index c58f6454..07077a27 100644 --- a/api/tacticalrmm/logs/views.py +++ b/api/tacticalrmm/logs/views.py @@ -13,7 +13,8 @@ from rest_framework.views import APIView from tacticalrmm.constants import AGENT_DEFER from tacticalrmm.permissions import _audit_log_filter, _has_perm_on_agent -from tacticalrmm.utils import get_default_timezone, notify_error +from tacticalrmm.utils import get_default_timezone +from tacticalrmm.helpers import notify_error from .models import AuditLog, DebugLog, PendingAction from .permissions import AuditLogPerms, DebugLogPerms, PendingActionPerms diff --git a/api/tacticalrmm/scripts/views.py b/api/tacticalrmm/scripts/views.py index 5d9c5266..147269ef 100644 --- a/api/tacticalrmm/scripts/views.py +++ b/api/tacticalrmm/scripts/views.py @@ -7,7 +7,7 @@ from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIView -from tacticalrmm.utils import notify_error +from tacticalrmm.helpers import notify_error from .models import Script, ScriptSnippet from .permissions import ScriptsPerms diff --git a/api/tacticalrmm/services/views.py b/api/tacticalrmm/services/views.py index 63f588e9..d23e81fb 100644 --- a/api/tacticalrmm/services/views.py +++ b/api/tacticalrmm/services/views.py @@ -6,7 +6,7 @@ from django.shortcuts import get_object_or_404 from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIView -from tacticalrmm.utils import notify_error +from tacticalrmm.helpers import notify_error from typing import Union, Dict, Tuple diff --git a/api/tacticalrmm/software/views.py b/api/tacticalrmm/software/views.py index d7ab0af6..70b96e02 100644 --- a/api/tacticalrmm/software/views.py +++ b/api/tacticalrmm/software/views.py @@ -9,7 +9,7 @@ from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIView -from tacticalrmm.utils import notify_error +from tacticalrmm.helpers import notify_error from .models import ChocoSoftware, InstalledSoftware from .permissions import SoftwarePerms diff --git a/api/tacticalrmm/tacticalrmm/helpers.py b/api/tacticalrmm/tacticalrmm/helpers.py new file mode 100644 index 00000000..000641ef --- /dev/null +++ b/api/tacticalrmm/tacticalrmm/helpers.py @@ -0,0 +1,6 @@ +from rest_framework import status +from rest_framework.response import Response + + +def notify_error(msg: str) -> Response: + return Response(msg, status=status.HTTP_400_BAD_REQUEST) diff --git a/api/tacticalrmm/tacticalrmm/middleware.py b/api/tacticalrmm/tacticalrmm/middleware.py index 723c8bb6..aac03ca7 100644 --- a/api/tacticalrmm/tacticalrmm/middleware.py +++ b/api/tacticalrmm/tacticalrmm/middleware.py @@ -6,6 +6,7 @@ from typing import Dict, Optional, Any from rest_framework.exceptions import AuthenticationFailed from tacticalrmm.constants import DEMO_NOT_ALLOWED, LINUX_NOT_IMPLEMENTED +from tacticalrmm.helpers import notify_error request_local = threading.local() @@ -27,6 +28,11 @@ EXCLUDE_PATHS = ( "/api/schema", ) +DEMO_EXCLUDE_PATHS = ( + "/api/v3", + "/api/schema", +) + class AuditMiddleware: def __init__(self, get_response): @@ -59,12 +65,16 @@ class AuditMiddleware: try: if hasattr(request, "user") and request.user.is_authenticated: + try: + view_Name = view_func.__dict__["view_class"].__name__ + except: + view_Name = view_func.__name__ debug_info = {} # gather and save debug info debug_info["url"] = request.path debug_info["method"] = request.method debug_info["view_class"] = view_func.cls.__name__ - debug_info["view_func"] = view_func.__name__ + debug_info["view_func"] = view_Name debug_info["view_args"] = view_args debug_info["view_kwargs"] = view_kwargs debug_info["ip"] = request._client_ip @@ -91,7 +101,7 @@ class LogIPMiddleware: self.get_response = get_response def __call__(self, request): - client_ip, is_routable = get_client_ip(request) + client_ip, _ = get_client_ip(request) request._client_ip = client_ip response = self.get_response(request) @@ -115,16 +125,16 @@ class DemoMiddleware: return view.finalize_response(request, resp).render() def process_view(self, request, view_func, view_args, view_kwargs): - from .utils import notify_error - err = "Not available in demo" - excludes = ("/api/v3",) - - if request.path.startswith(excludes): + if request.path.startswith(DEMO_EXCLUDE_PATHS): return self.drf_mock_response(request, notify_error(err)) + try: + view_Name = view_func.__dict__["view_class"].__name__ + except: + return for i in self.not_allowed: - if view_func.__name__ == i["name"] and request.method in i["methods"]: + if view_Name == i["name"] and request.method in i["methods"]: return self.drf_mock_response(request, notify_error(err)) @@ -154,11 +164,12 @@ class LinuxMiddleware: agent_id=view_kwargs["agent_id"] ) if agent.plat == "linux": - from .utils import notify_error + + try: + view_Name = view_func.__dict__["view_class"].__name__ + except: + return for i in self.not_implemented: - if ( - view_func.__name__ == i["name"] - and request.method in i["methods"] - ): + if view_Name == i["name"] and request.method in i["methods"]: return self.drf_mock_response(request, notify_error(err)) diff --git a/api/tacticalrmm/tacticalrmm/settings.py b/api/tacticalrmm/tacticalrmm/settings.py index 98aefc87..538c9f7d 100644 --- a/api/tacticalrmm/tacticalrmm/settings.py +++ b/api/tacticalrmm/tacticalrmm/settings.py @@ -162,7 +162,7 @@ MIDDLEWARE = [ "django.middleware.clickjacking.XFrameOptionsMiddleware", ] -if DEBUG: +if DEBUG and not DEMO: INSTALLED_APPS += ( "django_extensions", "silk", diff --git a/api/tacticalrmm/tacticalrmm/urls.py b/api/tacticalrmm/tacticalrmm/urls.py index 905c612f..f86aea13 100644 --- a/api/tacticalrmm/tacticalrmm/urls.py +++ b/api/tacticalrmm/tacticalrmm/urls.py @@ -43,7 +43,7 @@ if getattr(settings, "ADMIN_ENABLED", False): urlpatterns += (path(settings.ADMIN_URL, admin.site.urls),) -if getattr(settings, "DEBUG", False): +if getattr(settings, "DEBUG", False) and not getattr(settings, "DEMO", False): urlpatterns += [path("silk/", include("silk.urls", namespace="silk"))] if getattr(settings, "SWAGGER_ENABLED", False): diff --git a/api/tacticalrmm/tacticalrmm/utils.py b/api/tacticalrmm/tacticalrmm/utils.py index fff83da2..6b76d1f8 100644 --- a/api/tacticalrmm/tacticalrmm/utils.py +++ b/api/tacticalrmm/tacticalrmm/utils.py @@ -16,15 +16,11 @@ from django.contrib.auth.models import AnonymousUser from django.http import FileResponse from knox.auth import TokenAuthentication from logs.models import DebugLog -from rest_framework import status from rest_framework.response import Response from core.utils import get_core_settings from tacticalrmm.constants import MONTH_DAYS, MONTHS, WEEK_DAYS, WEEKS - - -def notify_error(msg: str) -> Response: - return Response(msg, status=status.HTTP_400_BAD_REQUEST) +from tacticalrmm.helpers import notify_error def generate_winagent_exe(