diff --git a/octopoes/octopoes/models/ooi/dns/records.py b/octopoes/octopoes/models/ooi/dns/records.py
index 8d63cf70ed4..972b20e4a07 100644
--- a/octopoes/octopoes/models/ooi/dns/records.py
+++ b/octopoes/octopoes/models/ooi/dns/records.py
@@ -50,7 +50,7 @@ class DNSMXRecord(DNSRecord):
object_type: Literal["DNSMXRecord"] = "DNSMXRecord"
dns_record_type: Literal["MX"] = "MX"
- mail_hostname: Reference | None = ReferenceField(Hostname, default=None)
+ mail_hostname: Reference | None = ReferenceField(Hostname, default=None, max_inherit_scan_level=1)
preference: int | None = None
_reverse_relation_names = {"hostname": "dns_mx_records", "mail_hostname": "mail_server_of"}
diff --git a/rocky/reports/templates/forms/report_form_fields.html b/rocky/reports/templates/forms/report_form_fields.html
index 3e7df3310eb..f8f6d645d3c 100644
--- a/rocky/reports/templates/forms/report_form_fields.html
+++ b/rocky/reports/templates/forms/report_form_fields.html
@@ -18,7 +18,7 @@
{% endfor %}
{% endif %}
{% for required_optional_plugin, plugins_ in plugins.items %}
- {% for plugin in plugins_ %}{% endfor %}
+ {% for plugin in plugins_ %}{% endfor %}
{% endfor %}
{% if request.POST.choose_recurrence %}
{% translate "Required plugins" %}
{% for required_plugin in plugins.required|dictsort:"enabled" %}
- {% include "partials/plugin_tile.html" with plugin=required_plugin plugin_report_types=plugin_data.plugin_report_types show_report_types="yes" plugin_report_types=plugin_data.plugin_report_types %}
+ {% if required_plugin.enabled %}
+ {% include "partials/plugin_tile.html" with form_id="continue-to-configuration" plugin_report_types=plugin_data.plugin_report_types show_report_types="yes" plugin=required_plugin remove_action_buttons="yes" add_checkbox="yes" %}
+ {% else %}
+ {% include "partials/plugin_tile.html" with form_id="continue-to-configuration" plugin_report_types=plugin_data.plugin_report_types show_report_types="yes" plugin=required_plugin remove_action_buttons="yes" add_checkbox="yes" checked="yes" %}
+
+ {% endif %}
{% endfor %}
@@ -76,7 +81,7 @@ {% translate "Suggested plugins" %}
{% for optional_plugin in plugins.optional|dictsort:"enabled" %}
- {% include "partials/plugin_tile.html" with plugin=optional_plugin form_id="continue-to-configurationt" show_report_types="yes" plugin_report_types=plugin_data.plugin_report_types %}
+ {% include "partials/plugin_tile.html" with form_id="continue-to-configuration" plugin_report_types=plugin_data.plugin_report_types show_report_types="yes" plugin=optional_plugin remove_action_buttons="yes" add_checkbox="yes" %}
{% endfor %}
@@ -98,7 +103,7 @@ {% translate "Suggested plugins" %}
{% include "forms/report_form_fields.html" %}
{% else %}
diff --git a/rocky/reports/views/aggregate_report.py b/rocky/reports/views/aggregate_report.py
index af57fa39ab6..94e1db5ede5 100644
--- a/rocky/reports/views/aggregate_report.py
+++ b/rocky/reports/views/aggregate_report.py
@@ -1,10 +1,14 @@
from typing import Any
+from django.contrib import messages
from django.http import HttpRequest, HttpResponse
from django.shortcuts import redirect
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from django.views.generic import TemplateView
+from httpx import HTTPError
+from katalogus.client import get_katalogus
+from tools.view_helpers import PostRedirect
from reports.report_types.aggregate_organisation_report.report import AggregateOrganisationReport
from reports.views.base import (
@@ -107,6 +111,28 @@ class ExportSetupAggregateReportView(
current_step = 4
report_type = AggregateOrganisationReport
+ def post(self, request, *args, **kwargs):
+ selected_plugins = request.POST.getlist("plugin", [])
+
+ if not selected_plugins:
+ return super().post(request, *args, **kwargs)
+
+ if not self.organization_member.has_perm("tools.can_enable_disable_boefje"):
+ messages.error(request, _("You do not have the required permissions to enable plugins."))
+ return PostRedirect(self.get_previous())
+
+ client = get_katalogus(self.organization.code)
+ for selected_plugin in selected_plugins:
+ try:
+ client.enable_boefje_by_id(selected_plugin)
+ except HTTPError:
+ messages.error(
+ request,
+ _("An error occurred while enabling {}. The plugin is not available.").format(selected_plugin),
+ )
+ return self.post(request, *args, **kwargs)
+ return super().post(request, *args, **kwargs)
+
class SaveAggregateReportView(SaveAggregateReportMixin, BreadcrumbsAggregateReportView, SaveReportView):
"""
diff --git a/rocky/reports/views/generate_report.py b/rocky/reports/views/generate_report.py
index 55a7457a8c7..4fa5169cb75 100644
--- a/rocky/reports/views/generate_report.py
+++ b/rocky/reports/views/generate_report.py
@@ -1,10 +1,14 @@
from typing import Any
+from django.contrib import messages
from django.http import HttpRequest, HttpResponse
from django.shortcuts import redirect
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from django.views.generic import TemplateView
+from httpx import HTTPError
+from katalogus.client import get_katalogus
+from tools.view_helpers import PostRedirect
from reports.views.base import (
REPORTS_PRE_SELECTION,
@@ -100,6 +104,28 @@ class ExportSetupGenerateReportView(GenerateReportStepsMixin, BreadcrumbsGenerat
breadcrumbs_step = 6
current_step = 4
+ def post(self, request, *args, **kwargs):
+ selected_plugins = request.POST.getlist("plugin", [])
+
+ if not selected_plugins:
+ return super().post(request, *args, **kwargs)
+
+ if not self.organization_member.has_perm("tools.can_enable_disable_boefje"):
+ messages.error(request, _("You do not have the required permissions to enable plugins."))
+ return PostRedirect(self.get_previous())
+
+ client = get_katalogus(self.organization.code)
+ for selected_plugin in selected_plugins:
+ try:
+ client.enable_boefje_by_id(selected_plugin)
+ except HTTPError:
+ messages.error(
+ request,
+ _("An error occurred while enabling {}. The plugin is not available.").format(selected_plugin),
+ )
+ return self.post(request, *args, **kwargs)
+ return super().post(request, *args, **kwargs)
+
class SaveGenerateReportView(SaveGenerateReportMixin, BreadcrumbsGenerateReportView, SaveReportView):
"""
diff --git a/rocky/rocky/locale/django.pot b/rocky/rocky/locale/django.pot
index c896645a930..962ed1d10cf 100644
--- a/rocky/rocky/locale/django.pot
+++ b/rocky/rocky/locale/django.pot
@@ -1617,7 +1617,6 @@ msgstr ""
#: onboarding/templates/account/step_2a_organization_update.html
#: onboarding/templates/account/step_2b_indemnification_setup.html
#: onboarding/templates/step_3d_clearance_level_introduction.html
-#: reports/templates/partials/report_setup_scan.html
msgid "Continue"
msgstr ""
@@ -2385,7 +2384,8 @@ msgstr ""
msgid "Please select all required plugins to proceed."
msgstr ""
-#: onboarding/views.py
+#: onboarding/views.py reports/views/aggregate_report.py
+#: reports/views/generate_report.py
msgid "An error occurred while enabling {}. The plugin is not available."
msgstr ""
@@ -4063,6 +4063,10 @@ msgstr ""
msgid "There are no optional plugins."
msgstr ""
+#: reports/templates/partials/report_setup_scan.html
+msgid "Enable plugins and continue"
+msgstr ""
+
#: reports/templates/partials/report_severity_totals.html
#: reports/templates/partials/report_severity_totals_table.html
msgid "Findings overview"
@@ -4463,6 +4467,10 @@ msgstr ""
msgid "Save report"
msgstr ""
+#: reports/views/aggregate_report.py reports/views/generate_report.py
+msgid "You do not have the required permissions to enable plugins."
+msgstr ""
+
#: reports/views/base.py
msgid "Select at least one OOI to proceed."
msgstr ""