From 248e1effb48322e3aad0e9ca2479f0c6adebb5c1 Mon Sep 17 00:00:00 2001 From: Takumi Yanagawa Date: Fri, 25 Oct 2024 06:35:21 +0900 Subject: [PATCH 1/2] feat: add local-definitions and findings (#34) Signed-off-by: Takumi Yanagawa --- Makefile | 4 ++-- c2p/framework/c2p.py | 9 +++++++-- c2p/framework/models/pvp_result.py | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index e73d306..b1671dc 100644 --- a/Makefile +++ b/Makefile @@ -4,11 +4,11 @@ build: .PHONY: install install: - python -m pip install . + python -m pip install -e . .PHONY: install-dev install-dev: - python -m pip install ".[dev]" + python -m pip install -e ".[dev]" # Direct dependency is not allowed for Pypi packaging even if the dependant module is defined as extra dependencies. # Workaround: Move to manual installation by make diff --git a/c2p/framework/c2p.py b/c2p/framework/c2p.py index 0846fe3..4b36f86 100644 --- a/c2p/framework/c2p.py +++ b/c2p/framework/c2p.py @@ -162,6 +162,8 @@ def _get_result(self, pvp_result: PVPResult) -> Result: start=oscal_utils.get_datetime_str(), observations=self._get_observations(pvp_result), reviewed_controls=oscal_utils.reviewed_controls(self._component_root.component_definition), + local_definitions=pvp_result.local_definitions, + findings=pvp_result.findings, ) if pvp_result.links != None: result.links = list(map(lambda x: Link(href=x.href, text=x.description), pvp_result.links)) @@ -183,7 +185,10 @@ def _get_observations(self, pvp_result: PVPResult) -> List[Observation]: oscal_utils.add_prop(props, 'evaluated-on', subject, ['evaluated_on']) oscal_utils.add_prop(props, 'reason', subject, ['reason']) s = SubjectReference( - subject_uuid=oscal_utils.uuid(), title=subject.title, type=subject.type, props=props + subject_uuid=subject.subject_uuid if subject.subject_uuid else oscal_utils.uuid(), + title=subject.title, + type=subject.type, + props=props, ) subjects.append(s) @@ -197,7 +202,7 @@ def _get_observations(self, pvp_result: PVPResult) -> List[Observation]: if observation.props != None: props = props + observation.props o = Observation( - uuid=oscal_utils.uuid(), + uuid=observation.uuid if observation.uuid else oscal_utils.uuid(), title=observation.title, description=observation.title, methods=observation.methods, diff --git a/c2p/framework/models/pvp_result.py b/c2p/framework/models/pvp_result.py index e9a6e0f..31b295c 100644 --- a/c2p/framework/models/pvp_result.py +++ b/c2p/framework/models/pvp_result.py @@ -19,8 +19,11 @@ from typing import List, Optional from pydantic.v1 import Field +from trestle.oscal.assessment_results import LocalDefinitions1 from c2p.common.c2p_base_model import C2PBaseModel +from trestle.oscal.assessment_results import LocalDefinitions1 +from trestle.oscal.common import Finding class ResultEnum(str, Enum): @@ -68,6 +71,11 @@ class Subject(C2PBaseModel): A human-oriented identifier reference to a resource. Use type to indicate whether the identified resource is a component, inventory item, location, user, or something else. """ + subject_uuid: Optional[str] = Field( + None, + description="A machine-oriented identifier reference to a component, inventory-item, location, party, user, or resource using it's UUID.", + title='Subject Universally Unique Identifier Reference', + ) title: str = Field(title='Name of the object') type: str = Field( ..., @@ -89,6 +97,7 @@ class ObservationByCheck(C2PBaseModel): Describes an individual observation based on each Check_Id defined in Component Definition. """ + uuid: Optional[str] = Field(None) title: Optional[str] = Field( None, description='The title for this observation for the check item. If not given, check id is used.', @@ -118,6 +127,16 @@ class ObservationByCheck(C2PBaseModel): class PVPResult(C2PBaseModel): observations_by_check: Optional[List[ObservationByCheck]] = Field(None) + findings: Optional[List[Finding]] = Field( + None, + description='Equivalent to the "findings" defined in the OSCAL Assessment Results.', + title='Describes an individual finding', + ) + local_definitions: Optional[LocalDefinitions1] = Field( + None, + description='Equivalent to the "local-definitions" defined in the OSCAL Assessment Results.', + title='Local Definitions', + ) links: Optional[List[Link]] = Field(None) From 0d86b0c60c9768c9ddc64799367a4402d23d3daa Mon Sep 17 00:00:00 2001 From: Takumi Yanagawa Date: Tue, 5 Nov 2024 23:41:19 +0900 Subject: [PATCH 2/2] fix: trestle version in unit test Signed-off-by: Takumi Yanagawa --- tests/data/framework/c2p/assessment-results.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/data/framework/c2p/assessment-results.json b/tests/data/framework/c2p/assessment-results.json index 664b1b3..c452683 100644 --- a/tests/data/framework/c2p/assessment-results.json +++ b/tests/data/framework/c2p/assessment-results.json @@ -3,7 +3,7 @@ "metadata": { "title": "TEST Assessment Results", "last_modified": "2024-03-22T08:28:11.000+00:00", - "version": "3.4.0", + "version": "3.5.0", "oscal_version": "1.1.2" }, "import_ap": {