Skip to content
This repository has been archived by the owner on Mar 24, 2023. It is now read-only.

Commit

Permalink
refactor raising of scanprofile (#162)
Browse files Browse the repository at this point in the history
  • Loading branch information
Lisser authored Jan 19, 2023
1 parent 53ef3e8 commit bfa2543
Show file tree
Hide file tree
Showing 11 changed files with 174 additions and 138 deletions.
80 changes: 65 additions & 15 deletions account/mixins.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
from datetime import datetime, timezone

from django.contrib import messages
from django.http import Http404
from django.utils.translation import gettext_lazy as _
from django.views import View

from octopoes.connector.octopoes import OctopoesAPIConnector
from octopoes.models import DeclaredScanProfile, ScanLevel, Reference

from rocky.exceptions import (
IndemnificationNotPresentException,
AcknowledgedClearanceLevelTooLowException,
TrustedClearanceLevelTooLowException,
ClearanceLevelTooLowException,
)
from rocky.settings import OCTOPOES_API
from tools.models import Organization, OrganizationMember, Indemnification

Expand All @@ -13,14 +23,20 @@ def __init__(self, **kwargs):
super().__init__(**kwargs)
self.organization = None
self.octopoes_api_connector = None
self._may_update_scan_profile = False
self.organization_member = None
self.indemnification_present = False

def setup(self, request, *args, **kwargs):
super().setup(request, *args, **kwargs)

# authentication/otp flow happens before setup
if not request.user.is_authenticated:
return

organization_code = kwargs["organization_code"]
try:
self.organization = Organization.objects.get(code=organization_code)
self.indemnification_present = Indemnification.objects.filter(organization=self.organization).exists()
except Organization.DoesNotExist:
self.organization = None
try:
Expand All @@ -44,29 +60,63 @@ def get_context_data(self, **kwargs):
if self.organization:
context["organization"] = self.organization
context["organization_member"] = self.organization_member
context["may_update_scan_profile"] = self.may_update_scan_profile
context["may_update_clearance_level"] = self.may_update_clearance_level
return context

@property
def may_update_scan_profile(self):
if not Indemnification.objects.filter(organization=self.organization).exists():
def may_update_clearance_level(self) -> bool:
if not self.indemnification_present:
return False
if self.organization_member.acknowledged_clearance_level < 0:
return False
if self.organization_member.trusted_clearance_level < 0:
return False
return True

def verify_may_update_scan_profile(self) -> bool:
if not Indemnification.objects.filter(organization=self.organization).exists():
messages.add_message(self.request, messages.ERROR, _("No indemnification present for organization."))
return False

if self.organization_member.acknowledged_clearance_level < 0:
messages.add_message(self.request, messages.ERROR, _("Acknowledged clearance level too low."))
return False
def verify_raise_clearance_level(self, level: int) -> bool:
if not self.indemnification_present:
raise IndemnificationNotPresentException()
if self.organization_member.acknowledged_clearance_level < level:
raise AcknowledgedClearanceLevelTooLowException()
if self.organization_member.trusted_clearance_level < level:
raise TrustedClearanceLevelTooLowException()
return True

if self.organization_member.trusted_clearance_level < 0:
messages.add_message(self.request, messages.ERROR, _("Trusted clearance level too low."))
return False
def raise_clearance_level(self, ooi_reference: Reference, level: int) -> bool:
try:
self.verify_raise_clearance_level(level)
self.octopoes_api_connector.save_scan_profile(
DeclaredScanProfile(reference=ooi_reference, level=ScanLevel(level)),
datetime.now(timezone.utc),
)
except IndemnificationNotPresentException as exc:
messages.add_message(
self.request,
messages.ERROR,
_(
"Could not raise clearance level of %s to L%s. \
Indemnification not present at organization %s."
)
% (
ooi_reference.human_readable,
level,
self.organization.name,
),
)
raise exc
except ClearanceLevelTooLowException as exc:
messages.add_message(
self.request,
messages.ERROR,
_(
"Could not raise clearance level of %s to L%s. \
You acknowledged a clearance level of %s."
)
% (
ooi_reference.human_readable,
level,
self.organization_member.acknowledged_clearance_level,
),
)
raise exc
return True
8 changes: 2 additions & 6 deletions katalogus/views/change_clearance_level.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,11 @@ def get(self, request, *args, **kwargs):

def post(self, request, *args, **kwargs):
"""Start scanning oois at plugin detail page."""
if not self.verify_may_update_scan_profile():
if not self.indemnification_present:
return self.get(request, *args, **kwargs)

boefje = self.katalogus_client.get_boefje(self.plugin_id)
self.run_boefje_for_oois(
boefje=boefje,
oois=self.oois,
api_connector=self.octopoes_api_connector,
)
self.run_boefje_for_oois(boefje=boefje, oois=self.oois)
messages.add_message(self.request, messages.SUCCESS, _("Scanning successfully scheduled."))
del request.session["selected_oois"] # delete session
return redirect(reverse("task_list", kwargs={"organization_code": self.organization.code}))
Expand Down
19 changes: 7 additions & 12 deletions katalogus/views/mixins.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from datetime import datetime, timezone
from logging import getLogger
from typing import List
from uuid import uuid4
Expand All @@ -10,8 +9,8 @@

from account.mixins import OrganizationView
from katalogus.client import get_katalogus
from octopoes.connector.octopoes import OctopoesAPIConnector
from octopoes.models import OOI, DeclaredScanProfile
from octopoes.models import OOI
from rocky.exceptions import IndemnificationNotPresentException, ClearanceLevelTooLowException
from rocky.scheduler import Boefje, BoefjeTask, QueuePrioritizedItem, client
from rocky.views.mixins import OctopoesView

Expand Down Expand Up @@ -70,18 +69,14 @@ def run_boefje_for_oois(
self,
boefje: Boefje,
oois: List[OOI],
api_connector: OctopoesAPIConnector,
) -> None:

for ooi in oois:
if ooi.scan_profile.level < boefje.scan_level:
api_connector.save_scan_profile(
DeclaredScanProfile(
reference=ooi.reference,
level=boefje.scan_level,
),
datetime.now(timezone.utc),
)
try:
self.raise_clearance_level(ooi.reference, boefje.scan_level)
except (IndemnificationNotPresentException, ClearanceLevelTooLowException):
continue
self.run_boefje(boefje, ooi)

def scan(self, view_args) -> None:
Expand All @@ -106,7 +101,7 @@ def scan(self, view_args) -> None:
oois = [self.get_single_ooi(pk=ooi_id) for ooi_id in ooi_ids]

try:
self.run_boefje_for_oois(boefje, oois, self.octopoes_api_connector)
self.run_boefje_for_oois(boefje, oois)
except HTTPError:
return

Expand Down
3 changes: 1 addition & 2 deletions katalogus/views/plugin_detail_scan_oois.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class PluginDetailScanOOI(BoefjeMixin, TemplateView):

def post(self, request, *args, **kwargs):
"""Start scanning oois at plugin detail page."""
if not self.verify_may_update_scan_profile():
if not self.indemnification_present:
return self.get(request, *args, **kwargs)

selected_oois = request.POST.getlist("ooi")
Expand All @@ -31,7 +31,6 @@ def post(self, request, *args, **kwargs):
self.run_boefje_for_oois(
boefje=boefje,
oois=oois_with_clearance_level,
api_connector=self.octopoes_api_connector,
)
oois_without_clearance_level = self.get_oois_without_clearance_level(selected_oois)
if oois_without_clearance_level:
Expand Down
20 changes: 8 additions & 12 deletions onboarding/views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from datetime import datetime, timezone
from typing import Type, List, Dict, Any

from django.contrib import messages
Expand All @@ -18,7 +17,6 @@
from account.mixins import OrganizationView
from katalogus.client import get_katalogus
from octopoes.connector.octopoes import OctopoesAPIConnector
from octopoes.models import DeclaredScanProfile
from octopoes.models import OOI
from octopoes.models.ooi.network import Network
from octopoes.models.types import type_by_name
Expand All @@ -34,6 +32,7 @@
KatIntroductionAdminStepsMixin,
KatIntroductionRegistrationStepsMixin,
)
from rocky.exceptions import IndemnificationNotPresentException, ClearanceLevelTooLowException
from rocky.views.indemnification_add import IndemnificationAddView
from rocky.views.ooi_report import Report, DNSReport, build_findings_list_from_store
from rocky.views.ooi_view import BaseOOIFormView, SingleOOITreeMixin, BaseOOIDetailView
Expand Down Expand Up @@ -258,20 +257,17 @@ def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)

def post(self, request, *args, **kwargs):
if not self.verify_may_update_scan_profile():

ooi = self.get_ooi()
level = int(self.request.session["clearance_level"])
try:
self.raise_clearance_level(ooi.reference, level)
except (IndemnificationNotPresentException, ClearanceLevelTooLowException):
return self.get(request, *args, **kwargs)

self.set_clearance_level()
self.enable_selected_boefjes()
return redirect(get_ooi_url("step_report", self.get_ooi_id(), self.organization.code))

def set_clearance_level(self):
ooi = self.get_ooi()
self.octopoes_api_connector.save_scan_profile(
DeclaredScanProfile(reference=ooi.reference, level=self.request.session["clearance_level"]),
valid_time=datetime.now(timezone.utc),
)

def enable_selected_boefjes(self) -> None:
if not self.request.session.get("selected_boefjes"):
return
Expand Down Expand Up @@ -305,7 +301,7 @@ def get_success_url(self, **kwargs):
return get_ooi_url("step_setup_scan_select_plugins", self.request.GET.get("ooi_id"), self.organization.code)

def form_valid(self, form):
self.request.session["clearance_level"] = form.data["level"]
self.request.session["clearance_level"] = form.cleaned_data["level"]
self.add_success_notification()
return super().form_valid(form)

Expand Down
16 changes: 16 additions & 0 deletions rocky/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,18 @@
class RockyError(Exception):
pass


class IndemnificationNotPresentException(Exception):
pass


class ClearanceLevelTooLowException(Exception):
pass


class AcknowledgedClearanceLevelTooLowException(ClearanceLevelTooLowException):
pass


class TrustedClearanceLevelTooLowException(ClearanceLevelTooLowException):
pass
6 changes: 2 additions & 4 deletions rocky/templates/oois/ooi_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ <h1>{% translate 'Object list' %}</h1>
{% if ooi_list %}
<fieldset>
<div class="horizontal-view">
{% if may_update_scan_profile %}
{% if may_update_clearance_level %}
<select id="scan-profiles" name="scan-profile">
{% for level in scan_levels %}
<option value="{{ level }}">
Expand All @@ -47,10 +47,8 @@ <h1>{% translate 'Object list' %}</h1>
value="update-scan-profile">
{% translate 'Set clearance level' %}
</button>
<button type="submit" class="dropdown-button" name="action" value="delete">{% translate 'Delete object(s)' %}</button>
{% else %}
<button type="submit" class="dropdown-button" name="action" value="delete">{% translate 'Delete object(s)' %}</button>
{% endif %}
<button type="submit" class="dropdown-button" name="action" value="delete">{% translate 'Delete object(s)' %}</button>
</div>
</fieldset>
{% endif %}
Expand Down
2 changes: 1 addition & 1 deletion rocky/views/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
from octopoes.models.tree import ReferenceTree
from octopoes.models.types import get_relations, get_collapsed_types, type_by_name
from rocky.bytes_client import get_bytes_client
from tools.forms.settings import DEPTH_MAX, DEPTH_DEFAULT
from tools.forms.base import ObservedAtForm
from tools.forms.settings import DEPTH_MAX, DEPTH_DEFAULT
from tools.models import Organization
from tools.ooi_helpers import (
get_knowledge_base_data_for_ooi_store,
Expand Down
4 changes: 2 additions & 2 deletions rocky/views/ooi_detail.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class OOIDetailView(
scan_history_limit = 10

def post(self, request, *args, **kwargs):
if not self.verify_may_update_scan_profile():
if not self.indemnification_present:
return self.get(request, *args, **kwargs)

if "action" not in self.request.POST:
Expand All @@ -61,7 +61,7 @@ def handle_page_action(self, action: str) -> bool:

boefje = get_katalogus(self.organization.code).get_boefje(boefje_id)
ooi = self.get_single_ooi(pk=ooi_id)
self.run_boefje_for_oois(boefje, [ooi], self.api_connector)
self.run_boefje_for_oois(boefje, [ooi])
return True

except RequestException as exception:
Expand Down
Loading

0 comments on commit bfa2543

Please sign in to comment.