Skip to content

Commit

Permalink
Merge branch 'main' into import_risk_assessment
Browse files Browse the repository at this point in the history
  • Loading branch information
ab-smith committed Dec 1, 2024
2 parents 263da46 + b444ad8 commit b85bc36
Show file tree
Hide file tree
Showing 19 changed files with 254 additions and 49 deletions.
86 changes: 84 additions & 2 deletions backend/app_tests/api/test_api_requirement_assessments.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,48 @@ def test_get_requirement_assessments(self, test):
"id": str(compliance_assessment.id),
"str": compliance_assessment.name,
},
"requirement": str(RequirementNode.objects.all()[0].id),
"requirement": {
"str": str(RequirementNode.objects.all()[0]),
"id": str(RequirementNode.objects.all()[0].id),
"urn": RequirementNode.objects.all()[0].urn,
"annotation": RequirementNode.objects.all()[0].annotation,
"name": RequirementNode.objects.all()[0].name,
"description": RequirementNode.objects.all()[0].description,
"typical_evidence": RequirementNode.objects.all()[
0
].typical_evidence,
"ref_id": RequirementNode.objects.all()[0].ref_id,
"associated_reference_controls": RequirementNode.objects.all()[
0
].associated_reference_controls,
"associated_threats": RequirementNode.objects.all()[
0
].associated_threats,
"parent_requirement": {
"str": RequirementNode.objects.all()[0].parent_requirement.get(
"str"
),
"urn": RequirementNode.objects.all()[0].parent_requirement.get(
"urn"
),
"id": str(
RequirementNode.objects.all()[0].parent_requirement.get(
"id"
)
),
"ref_id": RequirementNode.objects.all()[
0
].parent_requirement.get("ref_id"),
"name": RequirementNode.objects.all()[0].parent_requirement.get(
"name"
),
"description": RequirementNode.objects.all()[
0
].parent_requirement.get("description"),
}
if RequirementNode.objects.all()[0].parent_requirement
else None,
},
},
base_count=-1,
user_group=test.user_group,
Expand Down Expand Up @@ -210,7 +251,48 @@ def test_update_requirement_assessments(self, test):
"id": str(compliance_assessment.id),
"str": compliance_assessment.name,
},
"requirement": str(RequirementNode.objects.all()[0].id),
"requirement": {
"str": str(RequirementNode.objects.all()[0]),
"id": str(RequirementNode.objects.all()[0].id),
"urn": RequirementNode.objects.all()[0].urn,
"annotation": RequirementNode.objects.all()[0].annotation,
"name": RequirementNode.objects.all()[0].name,
"description": RequirementNode.objects.all()[0].description,
"typical_evidence": RequirementNode.objects.all()[
0
].typical_evidence,
"ref_id": RequirementNode.objects.all()[0].ref_id,
"associated_reference_controls": RequirementNode.objects.all()[
0
].associated_reference_controls,
"associated_threats": RequirementNode.objects.all()[
0
].associated_threats,
"parent_requirement": {
"str": RequirementNode.objects.all()[0].parent_requirement.get(
"str"
),
"urn": RequirementNode.objects.all()[0].parent_requirement.get(
"urn"
),
"id": str(
RequirementNode.objects.all()[0].parent_requirement.get(
"id"
)
),
"ref_id": RequirementNode.objects.all()[
0
].parent_requirement.get("ref_id"),
"name": RequirementNode.objects.all()[0].parent_requirement.get(
"name"
),
"description": RequirementNode.objects.all()[
0
].parent_requirement.get("description"),
}
if RequirementNode.objects.all()[0].parent_requirement
else None,
},
},
user_group=test.user_group,
)
Expand Down
7 changes: 4 additions & 3 deletions backend/core/management/commands/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ def handle(self, *args, **kwargs):
nb_risk_assessments = RiskAssessment.objects.all().count()
nb_risk_scenarios = RiskScenario.objects.all().count()
nb_risk_acceptances = RiskAcceptance.objects.all().count()
nb_seats_available = getattr(settings, "LICENSE_SEATS", 0)
nb_expiry_date = getattr(settings, "LICENSE_EXPIRATION", "")
nb_seats = getattr(settings, "LICENSE_SEATS", 0)
nb_editors = len(User.get_editors())
expiration = getattr(settings, "LICENSE_EXPIRATION", "")

created_at = Folder.get_root_folder().created_at
last_login = max(
Expand All @@ -41,5 +42,5 @@ def handle(self, *args, **kwargs):
+ f"threats={nb_threats} functions={nb_functions} measures={nb_measures} "
+ f"evidences={nb_evidences} compliance={nb_compliance_assessments} risk={nb_risk_assessments} "
+ f"scenarios={nb_risk_scenarios} acceptances={nb_risk_acceptances} "
+ f"number_of_seats={nb_seats_available} expiry_date={nb_expiry_date}"
+ f"seats={nb_seats} editors={nb_editors} expiration={expiration}"
)
34 changes: 34 additions & 0 deletions backend/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,40 @@ class RequirementNode(ReferentialObjectMixin, I18nObjectMixin):
)
question = models.JSONField(blank=True, null=True, verbose_name=_("Question"))

@property
def associated_reference_controls(self):
_reference_controls = self.reference_controls.all()
reference_controls = []
for control in _reference_controls:
reference_controls.append(
{"str": control.display_long, "urn": control.urn, "id": control.id}
)
return reference_controls

@property
def associated_threats(self):
_threats = self.threats.all()
threats = []
for control in _threats:
threats.append(
{"str": control.display_long, "urn": control.urn, "id": control.id}
)
return threats

@property
def parent_requirement(self):
parent_requirement = RequirementNode.objects.filter(urn=self.parent_urn).first()
if not parent_requirement:
return None
return {
"str": parent_requirement.display_long,
"urn": parent_requirement.urn,
"id": parent_requirement.id,
"ref_id": parent_requirement.ref_id,
"name": parent_requirement.name,
"description": parent_requirement.description,
}

class Meta:
verbose_name = _("RequirementNode")
verbose_name_plural = _("RequirementNodes")
Expand Down
14 changes: 14 additions & 0 deletions backend/core/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,20 @@ class RequirementAssessmentReadSerializer(BaseModelSerializer):
compliance_assessment = FieldsRelatedField()
folder = FieldsRelatedField()
assessable = serializers.BooleanField(source="requirement.assessable")
requirement = FieldsRelatedField(
[
"id",
"urn",
"annotation",
"name",
"description",
"typical_evidence",
"ref_id",
"associated_reference_controls",
"associated_threats",
"parent_requirement",
]
)

class Meta:
model = RequirementAssessment
Expand Down
1 change: 0 additions & 1 deletion backend/core/startup.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,6 @@
"view_complianceassessment",
"view_requirementassessment",
"change_requirementassessment",
"view_requirementnode",
"view_evidence",
"add_evidence",
"change_evidence",
Expand Down
23 changes: 17 additions & 6 deletions enterprise/frontend/src/routes/(authentication)/login/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,29 @@
export let form: ActionData;
</script>

<div class="relative h-screen w-screen bg-slate-200">
<div class="absolute top-5 left-5">
<div class="flex flex-row max-w-48 space-x-4 pb-3">
<div class="lg:relative h-screen w-screen bg-slate-200">
<div
class="invisible lg:visible absolute top-5 left-1/2 transform -translate-x-1/2 top-5 left-5 transform-none"
>
<div class="flex justify-center justify-start flex-row max-w-48 space-x-4 pb-3">
{#if !data.clientSettings.settings.name}
<Logo />
{/if}
</div>
</div>
<div class="absolute top-1/2 left-1/2 w-full transform -translate-x-1/2 -translate-y-1/2">
<div class="flex flex-row w-full pr-8">
<div class="lg:invisible pt-5 flex justify-center">
<div class="flex justify-center flex-row max-w-48 space-x-4 pb-3">
{#if !data.clientSettings.settings.name}
<Logo />
{/if}
</div>
</div>
<div
class="lg:absolute lg:top-1/2 lg:left-1/2 w-full transform lg:-translate-x-1/2 lg:-translate-y-1/2"
>
<div class="flex flex-col lg:flex-row w-full lg:pr-8 space-y-4 lg:space-y-0 lg:space-x-4">
<Greetings />
<div class="flex justify-center pr-5 items-center space-y-4 w-2/5">
<div class="flex justify-center lg:pr-5 items-center w-full lg:w-2/5">
<FormCard {data} {form} />
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
const clientSettings = $page.data.clientSettings;
</script>

<div id="hellothere" class="flex flex-col justify-center items-center w-3/5 text-gray-900">
<div
id="hellothere"
class="flex flex-col justify-center items-center lg:w-3/5 text-gray-900 px-4 lg:px-0"
>
{#if !clientSettings?.settings.name}
<Typewriter mode="loopOnce" cursor={false} interval={50}>
<div class="text-2xl unstyled text-center pb-4">
Expand Down
4 changes: 4 additions & 0 deletions enterprise/update-ciso-assistant-enterprise.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#! /usr/bin/env bash
pushd ..
./update-ciso-assistant.sh enterprise
popd
6 changes: 5 additions & 1 deletion frontend/src/lib/utils/crud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,11 @@ export const URL_MODEL_MAP: ModelMap = {
verboseNamePlural: 'Evidences',
fileFields: ['attachment'],
foreignKeyFields: [
{ field: 'folder', urlModel: 'folders', urlParams: 'content_type=DO&content_type=GL' },
{
field: 'folder',
urlModel: 'folders',
urlParams: 'content_type=DO&content_type=GL&content_type=EN'
},
{ field: 'applied_controls', urlModel: 'applied-controls' }
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
const requirementHashmap = Object.fromEntries(
data.requirements.map((requirement) => [requirement.id, requirement])
);
$: requirement = requirementHashmap[currentRequirementAssessment.requirement];
$: requirement = requirementHashmap[currentRequirementAssessment.requirement.id];
$: parent = data.requirements.find((req) => req.urn === requirement.parent_urn);
$: title = requirement.display_short
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,8 @@ export const load = (async ({ fetch, params }) => {
const complianceAssessmentScore = await fetch(
`${BASE_API_URL}/compliance-assessments/${requirementAssessment.compliance_assessment.id}/global_score/`
).then((res) => res.json());
const requirement = await fetch(
`${BASE_API_URL}/requirement-nodes/${requirementAssessment.requirement}/`
).then((res) => res.json());
const parentRequirementNodeEndpoint = `${BASE_API_URL}/requirement-nodes/?urn=${requirement.parent_urn}`;
const parent = await fetch(parentRequirementNodeEndpoint)
.then((res) => res.json())
.then((res) => res.results[0]);
const requirement = requirementAssessment.requirement;
const parent = requirementAssessment.requirement.parent_requirement;

const tables: Record<string, any> = {};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@
import { page } from '$app/stores';
export let data: PageData;
const threats = data.requirement.threats;
const reference_controls = data.requirement.reference_controls;
const threats = data.requirementAssessment.requirement.associated_threats ?? [];
const reference_controls =
data.requirementAssessment.requirement.associated_reference_controls ?? [];
const annotation = data.requirement.annotation;
const typical_evidence = data.requirement.typical_evidence;
const has_threats = threats && threats.length > 0;
const has_reference_controls = reference_controls && reference_controls.length > 0;
const has_threats = threats.length > 0;
const has_reference_controls = reference_controls.length > 0;
$: mappingInference = {
sourceRequirementAssessment:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,12 @@ export const load = (async ({ fetch, params }) => {
}

const requirementAssessment = await fetchJson(endpoint);
const [compliance_assessment_score, requirement] = await Promise.all([
fetchJson(
`${baseUrl}/compliance-assessments/${requirementAssessment.compliance_assessment.id}/global_score/`
),
fetchJson(`${baseUrl}/requirement-nodes/${requirementAssessment.requirement}/`)
]);

const parent = await fetchJson(
`${baseUrl}/requirement-nodes/?urn=${requirement.parent_urn}`
).then((res) => res.results[0]);
const requirement = requirementAssessment.requirement;
const compliance_assessment_score = await fetchJson(
`${baseUrl}/compliance-assessments/${requirementAssessment.compliance_assessment.id}/global_score/`
);

const parent = requirementAssessment.requirement.parent_requirement;

const model = getModelInfo(URLModel);
const object = { ...requirementAssessment };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
export let data: PageData;
export let form: ActionData;
const threats = data.requirement.threats;
const reference_controls = data.requirement.reference_controls;
const threats = data.requirementAssessment.requirement.associated_threats ?? [];
const reference_controls =
data.requirementAssessment.requirement.associated_reference_controls ?? [];
const annotation = data.requirement.annotation;
const typical_evidence = data.requirement.typical_evidence;
const has_threats = threats && threats.length > 0;
const has_reference_controls = reference_controls && reference_controls.length > 0;
const has_threats = threats.length > 0;
const has_reference_controls = reference_controls.length > 0;
import { page } from '$app/stores';
import AutocompleteSelect from '$lib/components/Forms/AutocompleteSelect.svelte';
Expand Down
21 changes: 15 additions & 6 deletions frontend/src/routes/(authentication)/login/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,25 @@
export let form: ActionData;
</script>

<div class="relative h-screen w-screen bg-slate-200">
<div class="absolute top-5 left-5">
<div class="flex flex-row max-w-48 space-x-4 pb-3">
<div class="lg:relative h-screen w-screen bg-slate-200">
<div
class="invisible lg:visible absolute top-5 left-1/2 transform -translate-x-1/2 top-5 left-5 transform-none"
>
<div class="flex justify-center justify-start flex-row max-w-48 space-x-4 pb-3">
<Logo />
</div>
</div>
<div class="absolute top-1/2 left-1/2 w-full transform -translate-x-1/2 -translate-y-1/2">
<div class="flex flex-row w-full pr-8">
<div class="lg:invisible pt-5 flex justify-center">
<div class="flex justify-center flex-row max-w-48 space-x-4 pb-3">
<Logo />
</div>
</div>
<div
class="lg:absolute lg:top-1/2 lg:left-1/2 w-full transform lg:-translate-x-1/2 lg:-translate-y-1/2"
>
<div class="flex flex-col lg:flex-row w-full lg:pr-8 space-y-4 lg:space-y-0 lg:space-x-4">
<Greetings />
<div class="flex justify-center pr-5 items-center space-y-4 w-2/5">
<div class="flex justify-center lg:pr-5 items-center w-full lg:w-2/5">
<FormCard {data} {form} />
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/routes/(authentication)/login/FormCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
$: form && form.mfaFlow ? modalMFAAuthenticate() : null;
</script>

<div class="flex flex-col w-3/4 p-10 rounded-lg shadow-lg bg-white bg-opacity-[.90]">
<div class="flex flex-col w-7/8 lg:w-3/4 p-10 rounded-lg shadow-lg bg-white bg-opacity-[.90]">
<div data-testid="login" class="flex flex-col w-full items-center space-y-4">
<div class="bg-primary-300 px-6 py-5 rounded-full text-3xl">
<i class="fa-solid fa-right-to-bracket" />
Expand Down
5 changes: 4 additions & 1 deletion frontend/src/routes/(authentication)/login/Greetings.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
import Typewriter from 'svelte-typewriter';
</script>

<div id="hellothere" class="flex flex-col justify-center items-center w-3/5 text-gray-900">
<div
id="hellothere"
class="flex flex-col justify-center items-center lg:w-3/5 text-gray-900 px-4 lg:px-0"
>
<Typewriter mode="loopOnce" cursor={false} interval={50}>
<div class="text-2xl unstyled text-center pb-4">
<span class="text-2xl text-center">{m.helloThere()} </span>
Expand Down
Loading

0 comments on commit b85bc36

Please sign in to comment.