Skip to content

Commit

Permalink
Release 0.15.8
Browse files Browse the repository at this point in the history
  • Loading branch information
wh1te909 committed Mar 23, 2023
2 parents 074f898 + b5eed69 commit 4f44671
Show file tree
Hide file tree
Showing 79 changed files with 1,669 additions and 437 deletions.
4 changes: 2 additions & 2 deletions .devcontainer/api.dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# pulls community scripts from git repo
FROM python:3.10.8-slim AS GET_SCRIPTS_STAGE
FROM python:3.11.2-slim AS GET_SCRIPTS_STAGE

RUN apt-get update && \
apt-get install -y --no-install-recommends git && \
git clone https://github.com/amidaware/community-scripts.git /community-scripts

FROM python:3.10.8-slim
FROM python:3.11.2-slim

ENV TACTICAL_DIR /opt/tactical
ENV TACTICAL_READY_FILE ${TACTICAL_DIR}/tmp/tactical.ready
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
name: Tests
strategy:
matrix:
python-version: ["3.10.8", "3.11.1"]
python-version: ["3.11.2"]

steps:
- uses: actions/checkout@v3
Expand Down
4 changes: 2 additions & 2 deletions ansible/roles/trmm_dev/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
user: "tactical"
python_ver: "3.10.8"
go_ver: "1.18.5"
python_ver: "3.11.2"
go_ver: "1.19.7"
backend_repo: "https://github.com/amidaware/tacticalrmm.git"
frontend_repo: "https://github.com/amidaware/tacticalrmm-web.git"
scripts_repo: "https://github.com/amidaware/community-scripts.git"
Expand Down
2 changes: 1 addition & 1 deletion ansible/roles/trmm_dev/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@
tags: pip
ansible.builtin.shell:
chdir: "{{ backend_dir }}/api"
cmd: python3.10 -m venv env
cmd: python3.11 -m venv env

- name: update pip to latest
tags: pip
Expand Down
1 change: 0 additions & 1 deletion api/tacticalrmm/accounts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ def __str__(self):
return self.name

def save(self, *args, **kwargs) -> None:

# delete cache on save
cache.delete(f"{ROLE_CACHE_PREFIX}{self.name}")
super(BaseAuditModel, self).save(*args, **kwargs)
Expand Down
2 changes: 0 additions & 2 deletions api/tacticalrmm/accounts/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ class Meta:


class TOTPSetupSerializer(ModelSerializer):

qr_url = SerializerMethodField()

class Meta:
Expand Down Expand Up @@ -80,7 +79,6 @@ class Meta:


class APIKeySerializer(ModelSerializer):

username = ReadOnlyField(source="user.username")

class Meta:
Expand Down
5 changes: 0 additions & 5 deletions api/tacticalrmm/accounts/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,9 @@


class CheckCreds(KnoxLoginView):

permission_classes = (AllowAny,)

def post(self, request, format=None):

# check credentials
serializer = AuthTokenSerializer(data=request.data)
if not serializer.is_valid():
Expand All @@ -55,7 +53,6 @@ def post(self, request, format=None):


class LoginView(KnoxLoginView):

permission_classes = (AllowAny,)

def post(self, request, format=None):
Expand Down Expand Up @@ -196,10 +193,8 @@ def put(self, request):


class TOTPSetup(APIView):

# totp setup
def post(self, request):

user = request.user
if not user.totp_key:
code = pyotp.random_base32()
Expand Down
1 change: 0 additions & 1 deletion api/tacticalrmm/agents/consumers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

class SendCMD(AsyncJsonWebsocketConsumer):
async def connect(self):

self.user = self.scope["user"]

if isinstance(self.user, AnonymousUser):
Expand Down
1 change: 0 additions & 1 deletion api/tacticalrmm/agents/management/commands/demo_cron.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ class Command(BaseCommand):
help = "stuff for demo site in cron"

def handle(self, *args, **kwargs):

random_dates = []
now = djangotime.now()

Expand Down
3 changes: 0 additions & 3 deletions api/tacticalrmm/agents/management/commands/fake_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ def rand_string(self, length: int) -> str:
return "".join(random.choice(chars) for _ in range(length))

def handle(self, *args, **kwargs) -> None:

user = User.objects.first()
if user:
user.totp_key = "ABSA234234"
Expand Down Expand Up @@ -295,7 +294,6 @@ def handle(self, *args, **kwargs) -> None:
show_tmp_dir_script.save()

for count_agents in range(AGENTS_TO_GENERATE):

client = random.choice(clients)

if client == clients[0]:
Expand Down Expand Up @@ -823,7 +821,6 @@ def handle(self, *args, **kwargs) -> None:
pick = random.randint(1, 10)

if pick == 5 or pick == 3:

reboot_time = django_now + djangotime.timedelta(
minutes=random.randint(1000, 500000)
)
Expand Down
631 changes: 631 additions & 0 deletions api/tacticalrmm/agents/migrations/0056_alter_agent_time_zone.py

Large diffs are not rendered by default.

7 changes: 0 additions & 7 deletions api/tacticalrmm/agents/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,6 @@ def is_supported_script(self, platforms: List[str]) -> bool:
def get_checks_with_policies(
self, exclude_overridden: bool = False
) -> "List[Check]":

if exclude_overridden:
checks = (
list(
Expand All @@ -445,12 +444,10 @@ def get_checks_with_policies(
return self.add_check_results(checks)

def get_tasks_with_policies(self) -> "List[AutomatedTask]":

tasks = list(self.autotasks.all()) + self.get_tasks_from_policies()
return self.add_task_results(tasks)

def add_task_results(self, tasks: "List[AutomatedTask]") -> "List[AutomatedTask]":

results = self.taskresults.all() # type: ignore

for task in tasks:
Expand All @@ -462,7 +459,6 @@ def add_task_results(self, tasks: "List[AutomatedTask]") -> "List[AutomatedTask]
return tasks

def add_check_results(self, checks: "List[Check]") -> "List[Check]":

results = self.checkresults.all() # type: ignore

for check in checks:
Expand Down Expand Up @@ -524,7 +520,6 @@ def check_run_interval(self) -> int:
# determine if any agent checks have a custom interval and set the lowest interval
for check in self.get_checks_with_policies():
if check.run_interval and check.run_interval < interval:

# don't allow check runs less than 15s
interval = 15 if check.run_interval < 15 else check.run_interval

Expand All @@ -542,7 +537,6 @@ def run_script(
run_as_user: bool = False,
env_vars: list[str] = [],
) -> Any:

from scripts.models import Script

script = Script.objects.get(pk=scriptpk)
Expand Down Expand Up @@ -799,7 +793,6 @@ def _do_nats_debug(self, agent: "Agent", message: str) -> None:
async def nats_cmd(
self, data: Dict[Any, Any], timeout: int = 30, wait: bool = True
) -> Any:

opts = setup_nats_options()
try:
nc = await nats.connect(**opts)
Expand Down
2 changes: 0 additions & 2 deletions api/tacticalrmm/agents/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,8 @@ def has_permission(self, r, view) -> bool:

class AgentNotesPerms(permissions.BasePermission):
def has_permission(self, r, view) -> bool:

# permissions for GET /agents/notes/ endpoint
if r.method == "GET":

# permissions for /agents/<agent_id>/notes endpoint
if "agent_id" in view.kwargs.keys():
return _has_perm(r, "can_list_notes") and _has_perm_on_agent(
Expand Down
1 change: 0 additions & 1 deletion api/tacticalrmm/agents/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ class AgentTableSerializer(serializers.ModelSerializer):
physical_disks = serializers.ReadOnlyField()

def get_alert_template(self, obj):

if not obj.alert_template:
return None

Expand Down
4 changes: 0 additions & 4 deletions api/tacticalrmm/agents/tests/test_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,6 @@ def test_delete_note(self):
self.check_not_authenticated("delete", url)

def test_get_agent_history(self):

# setup data
agent = baker.make_recipe("agents.agent")
history = baker.make("agents.AgentHistory", agent=agent, _quantity=30)
Expand Down Expand Up @@ -1007,7 +1006,6 @@ def test_get_edit_uninstall_permissions(
@patch("time.sleep")
@patch("agents.models.Agent.nats_cmd", return_value="ok")
def test_agent_actions_permissions(self, nats_cmd, sleep):

agent = baker.make_recipe("agents.agent")
unauthorized_agent = baker.make_recipe("agents.agent")

Expand Down Expand Up @@ -1135,7 +1133,6 @@ def test_get_agent_version_permissions(self):
self.assertEqual(len(response.data["agents"]), 7)

def test_generating_agent_installer_permissions(self):

client = baker.make("clients.Client")
client_site = baker.make("clients.Site", client=client)
site = baker.make("clients.Site")
Expand Down Expand Up @@ -1198,7 +1195,6 @@ def test_generating_agent_installer_permissions(self):
self.check_not_authorized("post", url, data)

def test_agent_notes_permissions(self):

agent = baker.make_recipe("agents.agent")
notes = baker.make("agents.Note", agent=agent, _quantity=5)

Expand Down
1 change: 0 additions & 1 deletion api/tacticalrmm/agents/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ def generate_linux_install(
api: str,
download_url: str,
) -> FileResponse:

match arch:
case "amd64":
arch_id = MeshAgentIdent.LINUX64
Expand Down
18 changes: 9 additions & 9 deletions api/tacticalrmm/agents/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,7 @@ def put(self, request, agent_id):
p_serializer.save()

if "custom_fields" in request.data.keys():

for field in request.data["custom_fields"]:

custom_field = field
custom_field["agent"] = agent.pk

Expand Down Expand Up @@ -535,6 +533,13 @@ def install_agent(request):
from core.utils import token_is_valid
from knox.models import AuthToken

# TODO rework this ghetto validation hack
# https://github.com/amidaware/tacticalrmm/issues/1461
try:
int(request.data["expires"])
except ValueError:
return notify_error("Please enter a valid number of hours")

client_id = request.data["client"]
site_id = request.data["site"]
version = settings.LATEST_AGENT_VER
Expand All @@ -548,7 +553,7 @@ def install_agent(request):

if request.data["installMethod"] in {"bash", "mac"} and not is_valid:
return notify_error(
"Missing code signing token, or token is no longer valid. Please read the docs for more info."
"Linux/Mac agents require code signing. Please see https://docs.tacticalrmm.com/code_signing/ for more info."
)

inno = f"tacticalagent-v{version}-{plat}-{goarch}"
Expand All @@ -560,7 +565,7 @@ def install_agent(request):
installer_user = User.objects.filter(is_installer_user=True).first()

_, token = AuthToken.objects.create(
user=installer_user, expiry=dt.timedelta(hours=request.data["expires"])
user=installer_user, expiry=dt.timedelta(hours=int(request.data["expires"]))
)

install_flags = [
Expand Down Expand Up @@ -595,7 +600,6 @@ def install_agent(request):
)

elif request.data["installMethod"] == "bash":

from agents.utils import generate_linux_install

return generate_linux_install(
Expand Down Expand Up @@ -645,7 +649,6 @@ def install_agent(request):
return Response(resp)

elif request.data["installMethod"] == "powershell":

text = Path(settings.BASE_DIR / "core" / "installer.ps1").read_text()

replace_dict = {
Expand Down Expand Up @@ -949,7 +952,6 @@ def bulk(request):
return Response(f"{script.name} will now be run on {len(agents)} agents")

elif request.data["mode"] == "patch":

if request.data["patchMode"] == "install":
bulk_install_updates_task.delay(agents)
return Response(
Expand All @@ -965,7 +967,6 @@ def bulk(request):
@api_view(["POST"])
@permission_classes([IsAuthenticated, AgentPerms])
def agent_maintenance(request):

if request.data["type"] == "Client":
if not _has_perm_on_client(request.user, request.data["id"]):
raise PermissionDenied()
Expand Down Expand Up @@ -1051,7 +1052,6 @@ class Meta:
read_only_fields = fields

def get(self, request):

date_range_filter = Q()
script_name_filter = Q()

Expand Down
6 changes: 0 additions & 6 deletions api/tacticalrmm/alerts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ def create_or_return_check_alert(
alert_severity: Optional[str] = None,
skip_create: bool = False,
) -> "Optional[Alert]":

# need to pass agent if the check is a policy
if not cls.objects.filter(
assigned_check=check,
Expand Down Expand Up @@ -217,7 +216,6 @@ def create_or_return_task_alert(
agent: "Agent",
skip_create: bool = False,
) -> "Optional[Alert]":

if not cls.objects.filter(
assigned_task=task,
agent=agent,
Expand Down Expand Up @@ -412,7 +410,6 @@ def handle_alert_failure(

# create alert in dashboard if enabled
if dashboard_alert or always_dashboard:

# check if alert template is set and specific severities are configured
if (
not alert_template
Expand All @@ -425,7 +422,6 @@ def handle_alert_failure(

# send email if enabled
if email_alert or always_email:

# check if alert template is set and specific severities are configured
if (
not alert_template
Expand All @@ -440,7 +436,6 @@ def handle_alert_failure(

# send text if enabled
if text_alert or always_text:

# check if alert template is set and specific severities are configured
if (
not alert_template
Expand Down Expand Up @@ -624,7 +619,6 @@ def handle_alert_resolve(
)

def parse_script_args(self, args: List[str]) -> List[str]:

if not args:
return []

Expand Down
1 change: 0 additions & 1 deletion api/tacticalrmm/alerts/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@


class AlertSerializer(ModelSerializer):

hostname = ReadOnlyField(source="assigned_agent.hostname")
agent_id = ReadOnlyField(source="assigned_agent.agent_id")
client = ReadOnlyField(source="client.name")
Expand Down
Loading

0 comments on commit 4f44671

Please sign in to comment.