Skip to content

Commit

Permalink
Merge branch 'main' into feat/audit-action-plan
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-intuitem committed May 15, 2024
2 parents 8060e58 + c41fa39 commit f9f7d9d
Show file tree
Hide file tree
Showing 16 changed files with 169 additions and 58 deletions.
62 changes: 44 additions & 18 deletions backend/core/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,8 @@ def measures_to_review(user: User):
)
measures = (
AppliedControl.objects.filter(id__in=object_ids_view)
.filter(eta__lte=date.today() + timedelta(days=30))
.exclude(status__iexact="done")
.order_by("eta")
.filter(expiry_date__lte=date.today() + timedelta(days=30))
.order_by("expiry_date")
)

return measures
Expand Down Expand Up @@ -580,7 +579,7 @@ def applied_control_per_cur_risk(user: User):
for lvl in get_rating_options(user):
cnt = (
AppliedControl.objects.filter(id__in=object_ids_view)
.exclude(status="done")
.exclude(status="active")
.filter(risk_scenarios__current_level=lvl[0])
.count()
)
Expand Down Expand Up @@ -748,15 +747,38 @@ def risks_per_project_groups(user: User):


def get_counters(user: User):
print()
return {
"domains": Folder.objects.filter(
content_type=Folder.ContentType.DOMAIN
).count(),
"projects": Project.objects.all().count(),
"applied_controls": AppliedControl.objects.all().count(),
"risk_assessments": RiskAssessment.objects.all().count(),
"compliance_assessments": ComplianceAssessment.objects.all().count(),
"policies": Policy.objects.all().count(),
"domains": len(
RoleAssignment.get_accessible_object_ids(
Folder.get_root_folder(), user, Folder
)[0]
),
"projects": len(
RoleAssignment.get_accessible_object_ids(
Folder.get_root_folder(), user, Project
)[0]
),
"applied_controls": len(
RoleAssignment.get_accessible_object_ids(
Folder.get_root_folder(), user, AppliedControl
)[0]
),
"risk_assessments": len(
RoleAssignment.get_accessible_object_ids(
Folder.get_root_folder(), user, RiskAssessment
)[0]
),
"compliance_assessments": len(
RoleAssignment.get_accessible_object_ids(
Folder.get_root_folder(), user, ComplianceAssessment
)[0]
),
"policies": len(
RoleAssignment.get_accessible_object_ids(
Folder.get_root_folder(), user, Policy
)[0]
),
}


Expand Down Expand Up @@ -845,12 +867,9 @@ def acceptances_to_review(user: User):
acceptances = (
RiskAcceptance.objects.filter(id__in=object_ids_view)
.filter(expiry_date__lte=date.today() + timedelta(days=30))
.order_by("expiry_date")
)
acceptances |= (
RiskAcceptance.objects.filter(id__in=object_ids_view)
.filter(approver=user)
.filter(state="submitted")
.filter(state__in=["submitted", "accepted"])
.order_by("expiry_date")
)

return acceptances
Expand Down Expand Up @@ -964,11 +983,18 @@ def threats_count_per_name(user: User):
_,
_,
) = RoleAssignment.get_accessible_object_ids(Folder.get_root_folder(), user, Threat)
viewable_scenarios = RoleAssignment.get_accessible_object_ids(
Folder.get_root_folder(), user, RiskScenario
)[0]

# expected by echarts to send the threats names in labels and the count of each threat in values

for threat in Threat.objects.filter(id__in=object_ids_view).order_by("name"):
val = RiskScenario.objects.filter(threats=threat).count()
val = (
RiskScenario.objects.filter(threats=threat)
.filter(id__in=viewable_scenarios)
.count()
)
if val > 0:
labels.append({"name": threat.name})
values.append(val)
Expand Down
4 changes: 2 additions & 2 deletions backend/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -938,15 +938,15 @@ def quality_check(self) -> dict:
measures[i]["id"] = json.loads(_measures)[i]["pk"]

for mtg in measures:
if not mtg["eta"]:
if not mtg["eta"] and not mtg["status"] == "active":
warnings_lst.append(
{
"msg": _("{} does not have an ETA").format(mtg["name"]),
"obj_type": "appliedcontrol",
"object": {"name": mtg["name"], "id": mtg["id"]},
}
)
else:
elif mtg["eta"] and not mtg["status"] == "active":
if date.today() > datetime.strptime(mtg["eta"], "%Y-%m-%d").date():
errors_lst.append(
{
Expand Down
50 changes: 37 additions & 13 deletions backend/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from datetime import datetime
from typing import Any
from uuid import UUID
from datetime import date, timedelta

import django_filters as df
from ciso_assistant.settings import (
Expand Down Expand Up @@ -283,14 +284,25 @@ def colors(self, request):

@action(detail=False, name="Get used risk matrices")
def used(self, request):
_used_matrices = RiskMatrix.objects.filter(
riskassessment__isnull=False
).distinct()
viewable_matrices = RoleAssignment.get_accessible_object_ids(
Folder.get_root_folder(), request.user, RiskMatrix
)[0]
viewable_assessments = RoleAssignment.get_accessible_object_ids(
Folder.get_root_folder(), request.user, RiskAssessment
)[0]
_used_matrices = (
RiskMatrix.objects.filter(riskassessment__isnull=False)
.filter(id__in=viewable_matrices)
.filter(riskassessment__id__in=viewable_assessments)
.distinct()
)
used_matrices = _used_matrices.values("id", "name")
for i in range(len(used_matrices)):
used_matrices[i]["risk_assessments_count"] = _used_matrices.get(
id=used_matrices[i]["id"]
).riskassessment_set.count()
used_matrices[i]["risk_assessments_count"] = (
RiskAssessment.objects.filter(risk_matrix=_used_matrices[i].id)
.filter(id__in=viewable_assessments)
.count()
)
return Response({"results": used_matrices})


Expand Down Expand Up @@ -578,7 +590,8 @@ def todo(self, request):

measures = sorted(
AppliedControl.objects.filter(id__in=object_ids_view)
.exclude(status="done")
.filter(eta__lte=date.today() + timedelta(days=30))
.exclude(status="active")
.order_by("eta"),
key=lambda mtg: mtg.get_ranking_score(),
reverse=True,
Expand Down Expand Up @@ -1060,14 +1073,25 @@ def tree(self, request, pk):

@action(detail=False, name="Get used frameworks")
def used(self, request):
_used_frameworks = Framework.objects.filter(
complianceassessment__isnull=False
).distinct()
viewable_framework = RoleAssignment.get_accessible_object_ids(
Folder.get_root_folder(), request.user, Framework
)[0]
viewable_assessments = RoleAssignment.get_accessible_object_ids(
Folder.get_root_folder(), request.user, ComplianceAssessment
)[0]
_used_frameworks = (
Framework.objects.filter(complianceassessment__isnull=False)
.filter(id__in=viewable_framework)
.filter(complianceassessment__id__in=viewable_assessments)
.distinct()
)
used_frameworks = _used_frameworks.values("id", "name")
for i in range(len(used_frameworks)):
used_frameworks[i]["compliance_assessments_count"] = _used_frameworks.get(
id=used_frameworks[i]["id"]
).complianceassessment_set.count()
used_frameworks[i]["compliance_assessments_count"] = (
ComplianceAssessment.objects.filter(framework=_used_frameworks[i].id)
.filter(id__in=viewable_assessments)
.count()
)
return Response({"results": used_frameworks})


Expand Down
6 changes: 3 additions & 3 deletions frontend/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@
"active": "Active",
"inactive": "Inactive",
"watchlist": "Watch list",
"watchlistDescription": "Items that have expired or with close ETA",
"watchlistDescription": "Items that have expired or will expire in the next 30 days",
"measuresToReview": "Applied controls to review",
"exceptionsToReview": "Exceptions to review",
"exceptionsToReview": "Acceptances to review",
"expired": "Expired",
"upcoming": "Upcoming",
"today": "Today",
Expand All @@ -187,7 +187,7 @@
"exportButton": "Export",
"treatmentProgressOverview": "Treatment progress overview",
"pendingMeasures": "Your pending applied controls",
"orderdByRankingScore": "Ordered by ranking score",
"orderdByRankingScore": "Over the next 30 days and ordered by ranking score",
"rankingScore": "Ranking score",
"noPendingAppliedControl": "No pending applied control",
"rankingScoreDefintion": "Ranking score is an adaptive metric that combines the information of effort and current risk level, and crosses it with the other data to assist you for the prioritization",
Expand Down
6 changes: 3 additions & 3 deletions frontend/messages/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@
"active": "Actif",
"inactive": "Inactif",
"watchlist": "Liste de surveillance",
"watchlistDescription": "Objets expirés ou expirant bientôt",
"watchlistDescription": "Objets qui ont expiré ou expireront dans les 30 prochains jours",
"measuresToReview": "Mesures à revoir",
"exceptionsToReview": "Exceptions à revoir",
"exceptionsToReview": "Acceptations à revoir",
"expired": "Expiré",
"upcoming": "À venir",
"today": "Aujourd'hui",
Expand All @@ -187,7 +187,7 @@
"exportButton": "Exporter",
"treatmentProgressOverview": "Vue d'ensemble de l'avancement du traitement",
"pendingMeasures": "Vos mesures en attente",
"orderdByRankingScore": "Classées par score",
"orderdByRankingScore": "Au cours des 30 prochains jours et classés par score de classement",
"rankingScore": "Score de classement",
"noPendingAppliedControl": "Aucune mesure appliquée en attente",
"rankingScoreDefintion": "Le score de classement est une mesure adaptative qui combine les informations relatives à l'effort et au niveau de risque courant, et les croise avec d'autres données pour vous aider à établir des priorités",
Expand Down
6 changes: 3 additions & 3 deletions frontend/messages/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@
"active": "Ativo",
"inactive": "Inativo",
"watchlist": "Lista de observação",
"watchlistDescription": "Itens que expiraram ou estão próximos do ETA",
"watchlistDescription": "Itens que expiraram ou irão expirar nos próximos 30 dias",
"measuresToReview": "Controles aplicados para revisão",
"exceptionsToReview": "Exceções para revisão",
"exceptionsToReview": "Aceitações para revisão",
"expired": "Expirado",
"upcoming": "Próximo",
"today": "Hoje",
Expand All @@ -187,7 +187,7 @@
"exportButton": "Exportar",
"treatmentProgressOverview": "Visão geral do progresso do tratamento",
"pendingMeasures": "Seus controles aplicados pendentes",
"orderdByRankingScore": "Ordenado por pontuação de classificação",
"orderdByRankingScore": "Nos próximos 30 dias e ordenados por pontuação de classificação",
"rankingScore": "Pontuação de classificação",
"noPendingAppliedControl": "Nenhum controle aplicado pendente",
"rankingScoreDefintion": "A pontuação de classificação é uma métrica adaptativa que combina informações de esforço e nível de risco atual, cruzando-as com outros dados para auxiliá-lo na priorização",
Expand Down
13 changes: 10 additions & 3 deletions frontend/src/lib/components/SideBar/SideBarFooter.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@
const modalStore = getModalStore();
const defaultLangLabels = {
fr: 'Français',
en: 'English',
ar: 'العربية',
pt: 'Português'
};
let value = languageTag();
async function handleLocaleChange(event: Event) {
Expand Down Expand Up @@ -85,9 +92,9 @@
data-testid="language-select"
>
{#each availableLanguageTags as lang}
<option value={lang} selected={lang === languageTag()}
>{LOCALE_MAP[lang].flag} {language[LOCALE_MAP[lang].name]}</option
>
<option value={lang} selected={lang === languageTag()}>
{defaultLangLabels[lang]} ({language[LOCALE_MAP[lang].name]})
</option>
{/each}
</select>
<button
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/lib/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export const MONTH_LIST = [
'December'
];

export const TODAY = new Date();

export const UUID_REGEX = '([0-9a-f]{8}\\-[0-9a-f]{4}\\-[0-9a-f]{4}\\-[0-9a-f]{4}\\-[0-9a-f]{12})';
export const UUID_LIST_REGEX = new RegExp(`^${UUID_REGEX}(,${UUID_REGEX})*$`);

Expand Down
24 changes: 24 additions & 0 deletions frontend/src/routes/(app)/analytics/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { superValidate } from 'sveltekit-superforms';
import { zod } from 'sveltekit-superforms/adapters';
import type { PageServerLoad } from './$types';
import type { Project } from '$lib/utils/types';
import { TODAY } from '$lib/utils/constants';

const REQUIREMENT_ASSESSMENT_STATUS = [
'compliant',
Expand Down Expand Up @@ -52,6 +53,21 @@ export const load: PageServerLoad = async ({ locals, fetch }) => {
const req_ord_applied_controls = await fetch(`${BASE_API_URL}/applied-controls/todo/`);
const ord_applied_controls = await req_ord_applied_controls.json();

function timeState(date: string) {
const eta = new Date(date);
if (eta.getDate() > TODAY.getDate()) {
return { name: 'incoming', hexcolor: '#93c5fd' };
} else if (eta.getDate() < TODAY.getDate()) {
return { name: 'outdated', hexcolor: '#f87171' };
} else {
return { name: 'today', hexcolor: '#fbbf24' };
}
}

for (const applied_control of ord_applied_controls.results) {
applied_control.state = timeState(applied_control.eta);
}

const req_get_counters = await fetch(`${BASE_API_URL}/get_counters/`);
const counters = await req_get_counters.json();

Expand All @@ -78,9 +94,17 @@ export const load: PageServerLoad = async ({ locals, fetch }) => {
const req_get_measures_to_review = await fetch(`${BASE_API_URL}/applied-controls/to_review/`);
const measures_to_review = await req_get_measures_to_review.json();

for (const measure of measures_to_review.results) {
measure.state = timeState(measure.expiry_date);
}

const req_get_acceptances_to_review = await fetch(`${BASE_API_URL}/risk-acceptances/to_review/`);
const acceptances_to_review = await req_get_acceptances_to_review.json();

for (const acceptance of acceptances_to_review.results) {
acceptance.state = timeState(acceptance.expiry_date);
}

const req_risk_assessments = await fetch(`${BASE_API_URL}/risk-assessments/`);
const risk_assessments = await req_risk_assessments.json();

Expand Down
Loading

0 comments on commit f9f7d9d

Please sign in to comment.