Skip to content

Commit

Permalink
chore: merge to main for release 1.23.0 (#2341)
Browse files Browse the repository at this point in the history
* fix: release to be sca scanned (#2286)

* chore(deps): update eslint monorepo to v9.16.0 (#2287)

* fix(deps): update dependency drf-spectacular to v0.28.0 (#2288)

* fix: prev/next button for license component show coming from overview list (#2289)

* feat: show observation on side of observation log (#2291)

* chore(deps): update dependency mkdocs-material to v9.5.47 (#2290)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(deps): update dependency drf-spectacular-sidecar to v2024.12.1 (#2292)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(deps): update dependency chart.js to v4.4.7 (#2293)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(deps): update dependency pylint to v3.3.2 (#2294)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency globals to v15.13.0 (#2295)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(deps): update react-admin monorepo to v5.4.1 (#2297)

* chore(deps): update typescript-eslint monorepo to v8.17.0 (#2298)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update nginx:stable-alpine-slim docker digest to c13d84b (#2299)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update keycloak/keycloak docker tag to v26.0.7 (#2300)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update github/codeql-action action to v3.27.6 (#2301)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update node.js to v22.12.0 (#2303)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency prettier to v3.4.2 (#2304)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(deps): update dependency axios to v1.7.9 (#2305)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(deps): update dependency markdown-to-jsx to v7.7.1 (#2306)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update node.js to 96cc832 (#2308)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix: do not change risk acceptance date inadvertently (#2302)

* fix: do not change risk acceptance date inadvertently

* chore: pylint

* feat: correct wrongly set dates

* chore: codereview

* chore: suppress false positive of Bandit (#2310)

* fix(deps): update dependency django to v5.1.4 (#2309)

* chore(deps): update dependency @types/react to v18.3.13 (#2311)

* feat: allow lists for CORS_ALLOWED_ORIGINS and ALLOWED_HOSTS (#2313)

* chore(deps): update dependency @eslint/compat to v1.2.4 (#2312)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update actions/cache action to v4.2.0 (#2316)

* chore(deps): update dependency @types/prop-types to v15.7.14 (#2318)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update react monorepo (#2319)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(deps): update dependency coverage to v7.6.9 (#2321)

* chore(deps): update dependency poetry to v1.8.5 (#2322)

* chore(deps): update dependency mkdocs-material to v9.5.48 (#2323)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(deps): update dependency tss-react to v4.9.14 (#2324)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(deps): update emotion monorepo to v11.14.0 (#2325)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* feat: bulk reviews and separate reviews listing (#2280)

* feat: bulk reviews and separate reviews listing

* fix: frontend lint fixes

* feat: UI improvements

* chore: finetuning

---------

Co-authored-by: Stefan Fleckenstein <[email protected]>

* chore(deps): update dependency @trivago/prettier-plugin-sort-imports to v5 (#2315)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(deps): update react-admin monorepo to v5.4.2 (#2326)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update typescript-eslint monorepo to v8.18.0 (#2327)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency @types/react-dom to v18.3.3 (#2328)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency @playwright/test to v1.49.1 (#2329)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update mcr.microsoft.com/playwright docker tag to v1.49.1 (#2330)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update github/codeql-action action to v3.27.7 (#2332)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update react monorepo (#2334)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update traefik docker tag to v3.2.2 (#2335)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency @types/node to v22.10.2 (#2336)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* feat: top level observation review list (#2337)

* chore: more authentication tests (#2338)

* chore: more authentication tests

* chore: black

* chore: two minor ui changes (#2339)

* chore(deps): lock file maintenance (#2296)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore: prepare for release 1.23.0 (#2340)

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Lukas Voetmand <[email protected]>
  • Loading branch information
3 people authored Dec 12, 2024
1 parent d1896c5 commit a8dcf4a
Show file tree
Hide file tree
Showing 74 changed files with 2,393 additions and 1,449 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/publish_docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
with:
python-version: 3.x
- uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
- uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
key: ${{ github.ref }}
path: .cache
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/scan_sca_current.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: 'v1.22.2'
ref: 'v1.23.0'
-
name: Run SCA vulnerability scanners
uses: MaibornWolff/secobserve_actions_templates/actions/vulnerability_scanner@5476f0de11c46875081d9767ec166c1e030e9ef0 # main
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/scorecard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,6 @@ jobs:

# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5
uses: github/codeql-action/upload-sarif@babb554ede22fd5605947329c4d04d8e7a0b8155 # v3.27.7
with:
sarif_file: results.sarif
2 changes: 1 addition & 1 deletion backend/application/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "1.22.5"
__version__ = "1.23.0"

import pymysql

Expand Down
60 changes: 59 additions & 1 deletion backend/application/core/api/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,17 +267,75 @@ class ObservationLogFilter(FilterSet):
field_name="observation__product",
queryset=Product.objects.all(),
)
product_group = ModelChoiceFilter(
field_name="observation__product__product_group",
queryset=Product.objects.filter(is_product_group=True),
)
observation_title = CharFilter(
field_name="observation__title",
lookup_expr="icontains",
)
branch_name = CharFilter(
field_name="observation__branch__name", lookup_expr="icontains"
)
branch = ModelChoiceFilter(
field_name="observation__branch", queryset=Branch.objects.all()
)
origin_component_name_version = CharFilter(
field_name="observation__origin_component_name_version", lookup_expr="icontains"
)
origin_docker_image_name_tag_short = CharFilter(
field_name="observation__origin_docker_image_name_tag_short",
lookup_expr="icontains",
)
origin_endpoint_hostname = CharFilter(
field_name="observation__origin_endpoint_hostname", lookup_expr="icontains"
)
origin_source_file = CharFilter(
field_name="observation__origin_source_file", lookup_expr="icontains"
)
origin_cloud_qualified_resource = CharFilter(
field_name="observation__origin_cloud_qualified_resource",
lookup_expr="icontains",
)
origin_kubernetes_qualified_resource = CharFilter(
field_name="observation__origin_kubernetes_qualified_resource",
lookup_expr="icontains",
)

ordering = OrderingFilter(
# tuple-mapping retains order
fields=(
("id", "id"),
("user__full_name", "user_full_name"),
("observation__title", "observation_title"),
("observation__product__name", "observation_data.product_data.name"),
(
"observation__product__product_group__name",
"observation_data.product_data.product_group_name",
),
("observation__branch__name", "observation_data.branch_name"),
("observation__title", "observation_data.title"),
(
"observation__origin_component_name_version",
"observation_data.origin_component_name_version",
),
(
"observation__origin_docker_image_name_tag_short",
"observation_data.origin_docker_image_name_tag_short",
),
(
"observation__origin_endpoint_hostname",
"observation_data.origin_endpoint_hostname",
),
("observation__origin_source_file", "observation_data.origin_source_file"),
(
"observation__origin_cloud_qualified_resource",
"observation_data.origin_cloud_qualified_resource",
),
(
"observation__origin_kubernetes_qualified_resource",
"observation_data.origin_kubernetes_qualified_resource",
),
("severity", "severity"),
("status", "status"),
("comment", "comment"),
Expand Down
69 changes: 48 additions & 21 deletions backend/application/core/api/serializers_observation.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ def update(self, instance: Observation, validated_data: dict):
actual_severity = instance.current_severity
actual_status = instance.current_status
actual_vex_justification = instance.current_vex_justification
actual_risk_acceptance_expiry_date = instance.risk_acceptance_expiry_date

instance.origin_component_name = ""
instance.origin_component_version = ""
Expand All @@ -282,30 +283,45 @@ def update(self, instance: Observation, validated_data: dict):

observation: Observation = super().update(instance, validated_data)

if actual_severity != observation.current_severity:
actual_severity = observation.current_severity
else:
actual_severity = ""
log_severity = (
observation.current_severity
if actual_severity != observation.current_severity
else ""
)

if actual_status != observation.current_status:
actual_status = observation.current_status
else:
actual_status = ""
log_status = (
observation.current_status
if actual_status != observation.current_status
else ""
)

if actual_vex_justification != observation.current_vex_justification:
actual_vex_justification = observation.current_vex_justification
else:
actual_vex_justification = ""
log_vex_justification = (
observation.current_vex_justification
if actual_vex_justification != observation.current_vex_justification
else ""
)

if actual_severity or actual_status:
log_risk_acceptance_expiry_date = (
observation.risk_acceptance_expiry_date
if actual_risk_acceptance_expiry_date
!= observation.risk_acceptance_expiry_date
else None
)

if (
log_severity
or log_status
or log_vex_justification
or log_risk_acceptance_expiry_date
):
create_observation_log(
observation=observation,
severity=actual_severity,
status=actual_status,
severity=log_severity,
status=log_status,
comment="Observation changed manually",
vex_justification=actual_vex_justification,
vex_justification=log_vex_justification,
assessment_status=Assessment_Status.ASSESSMENT_STATUS_AUTO_APPROVED,
risk_acceptance_expiry_date=observation.risk_acceptance_expiry_date,
risk_acceptance_expiry_date=log_risk_acceptance_expiry_date,
)

check_security_gate(observation.product)
Expand Down Expand Up @@ -533,7 +549,7 @@ class Meta:


class ObservationLogListSerializer(ModelSerializer):
observation_title = SerializerMethodField()
observation_data = ObservationListSerializer(source="observation")
user_full_name = SerializerMethodField()
approval_user_full_name = SerializerMethodField()

Expand All @@ -543,9 +559,6 @@ def get_user_full_name(self, obj: Observation_Log) -> Optional[str]:

return None

def get_observation_title(self, obj: Observation_Log) -> str:
return obj.observation.title

def get_approval_user_full_name(self, obj: Observation_Log) -> Optional[str]:
if obj.approval_user:
return obj.approval_user.full_name
Expand All @@ -564,9 +577,23 @@ class ObservationLogApprovalSerializer(Serializer):
approval_remark = CharField(max_length=255, required=True)


class ObservationLogBulkApprovalSerializer(Serializer):
assessment_status = ChoiceField(
choices=Assessment_Status.ASSESSMENT_STATUS_CHOICES_APPROVAL, required=False
)
approval_remark = CharField(max_length=255, required=True)
observation_logs = ListField(
child=IntegerField(min_value=1), min_length=0, max_length=100, required=True
)


class PotentialDuplicateSerializer(ModelSerializer):
potential_duplicate_observation = NestedObservationSerializer()

class Meta:
model = Potential_Duplicate
fields = "__all__"


class CountSerializer(Serializer):
count = IntegerField()
51 changes: 50 additions & 1 deletion backend/application/core/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from rest_framework.permissions import IsAuthenticated
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.status import HTTP_204_NO_CONTENT
from rest_framework.status import HTTP_200_OK, HTTP_204_NO_CONTENT
from rest_framework.viewsets import GenericViewSet, ModelViewSet

from application.access_control.services.authorization import user_has_permission_or_403
Expand Down Expand Up @@ -40,6 +40,7 @@
UserHasServicePermission,
)
from application.core.api.serializers_observation import (
CountSerializer,
EvidenceSerializer,
ObservationAssessmentSerializer,
ObservationBulkAssessmentSerializer,
Expand All @@ -48,6 +49,7 @@
ObservationCreateSerializer,
ObservationListSerializer,
ObservationLogApprovalSerializer,
ObservationLogBulkApprovalSerializer,
ObservationLogListSerializer,
ObservationLogSerializer,
ObservationRemoveAssessmentSerializer,
Expand Down Expand Up @@ -103,6 +105,7 @@
export_observations_excel,
)
from application.core.services.observations_bulk_actions import (
observation_logs_bulk_approval,
observations_bulk_assessment,
observations_bulk_delete,
observations_bulk_mark_duplicates,
Expand Down Expand Up @@ -624,6 +627,18 @@ def bulk_assessment(self, request):
)
return Response(status=HTTP_204_NO_CONTENT)

@extend_schema(
methods=["GET"],
request=None,
responses={HTTP_200_OK: CountSerializer},
)
@action(detail=False, methods=["get"])
def count_reviews(self, request):
count = (
get_observations().filter(current_status=Status.STATUS_IN_REVIEW).count()
)
return Response(status=HTTP_200_OK, data={"count": count})


class ObservationTitleViewSet(GenericViewSet, ListModelMixin, RetrieveModelMixin):
serializer_class = ObservationTitleSerializer
Expand Down Expand Up @@ -681,6 +696,40 @@ def approval(self, request, pk=None):

return Response()

@extend_schema(
methods=["POST"],
request=ObservationLogBulkApprovalSerializer,
responses={HTTP_204_NO_CONTENT: None},
)
@action(detail=False, methods=["post"])
def bulk_approval(self, request):
request_serializer = ObservationLogBulkApprovalSerializer(data=request.data)
if not request_serializer.is_valid():
raise ValidationError(request_serializer.errors)

observation_logs_bulk_approval(
request_serializer.validated_data.get("assessment_status"),
request_serializer.validated_data.get("approval_remark"),
request_serializer.validated_data.get("observation_logs"),
)
return Response(status=HTTP_204_NO_CONTENT)

@extend_schema(
methods=["GET"],
request=None,
responses={HTTP_200_OK: CountSerializer},
)
@action(detail=False, methods=["get"])
def count_approvals(self, request):
count = (
get_observation_logs()
.filter(
assessment_status=Assessment_Status.ASSESSMENT_STATUS_NEEDS_APPROVAL
)
.count()
)
return Response(status=HTTP_200_OK, data={"count": count})


class EvidenceViewSet(GenericViewSet, ListModelMixin, RetrieveModelMixin):
serializer_class = EvidenceSerializer
Expand Down
Loading

0 comments on commit a8dcf4a

Please sign in to comment.