Skip to content

Commit

Permalink
Merge pull request #4437 from cisagov/feature/CSET-3014
Browse files Browse the repository at this point in the history
Move POAM export to CMMC section and disable if < Level 1 achieved
  • Loading branch information
LaddieZeigler authored Feb 13, 2025
2 parents c959e1a + 33ae322 commit 6d97be2
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,8 @@ public List<Individual> GetObservationIndividuals()
List<Individual> individualList = [];

var observations = (from f in _context.FINDING
join fc in _context.FINDING_CONTACT on f.Finding_Id equals fc.Finding_Id
join fc in _context.FINDING_CONTACT on f.Finding_Id equals fc.Finding_Id into fc1
from fc in fc1.DefaultIfEmpty()
join a in _context.ANSWER on f.Answer_Id equals a.Answer_Id
join mq in _context.MATURITY_QUESTIONS on a.Question_Or_Requirement_Id equals mq.Mat_Question_Id into mq1
from mq in mq1.DefaultIfEmpty()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ export class ReportListCommonComponent implements OnChanges {
return result ? result.reportList : [];
}

/**
*
*/
iseCheckAndSetDisabled(reportList: any[]) {
if (!this.ncuaSvc.ISE_StateLed) {
this.acetSvc.getIseAnswerCompletionRate().subscribe((percentAnswered: number) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,24 @@ <h4>{{sectionTitle}}</h4>
<div *ngFor="let rl of list; let i = index" class="mb-3 p-3 w-100"
[class.gray-box]="translateDesc(sectionId, i).length > 0">
<div class="d-flex flex-row" style="align-items: end">
<div>

<!-- normal report link -->
<div *ngIf="!!rl.linkUrl">
<button tabindex="0" (click)="reportSvc.clickReportLink(rl.linkUrl, rl.print ?? false)"
[disabled]="rl.disabled" class="btn btn-link btn-link-dark px-0 pt-0">
{{ t('reports.launch.' + sectionId.toLowerCase() + '.' + (i+1) + '.title') }}
</button>
</div>

<!-- excel export link -->
<div *ngIf="!!rl.exportUrl">
<button tabindex="0" (click)="reportSvc.clickExcelLink(rl.exportUrl)" [disabled]="isDisabled(rl.disabledWhen)"
class="btn btn-link btn-link-dark px-0 pt-0">
<span class="cset-icons-export-excel fs-base me-2 align-middle"></span>
{{ t('reports.launch.' + sectionId.toLowerCase() + '.' + (i+1) + '.title') }}
</button>
</div>

<div class="ms-4" *ngIf="rl.securityPicker">
<label class="mb-1" for="securityId">Confidentiality</label>
<select class="form-select" [(ngModel)]="confidentiality" id="securityId" name="securityId"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,16 @@ import { AssessmentService } from '../../../../services/assessment.service';
import { NCUAService } from '../../../../services/ncua.service';
import { ObservationsService } from '../../../../services/observations.service';
import { ACETService } from '../../../../services/acet.service';
import { MaturityService } from '../../../../services/maturity.service';

/**
* This component displays a list of report launching links.
* The links defined for each assessment type is defined in report-list.json
* Two types of links are supported. Most launch an HTML report in a new tab,
* defined with a 'linkUrl' property.
* The other will launch an exported Excel spreadsheet, defined with an 'exportUrl'
* property.
*/
@Component({
selector: 'app-report-list',
templateUrl: './report-list.component.html',
Expand All @@ -25,13 +34,19 @@ export class ReportListComponent implements OnInit {
@Input()
list: any[];

/**
* Used to disable report link
*/
cmmcLevel1Achieved = false;

/**
*
*/
constructor(
public reportSvc: ReportService,
public tSvc: TranslocoService,
public assessSvc: AssessmentService,
public maturitySvc: MaturityService,
public ncuaSvc: NCUAService,
public observationsSvc: ObservationsService,
public acetSvc: ACETService
Expand All @@ -41,8 +56,12 @@ export class ReportListComponent implements OnInit {
if (!this.sectionId) {
return;
}

const key = 'reports.launch.' + this.sectionId.toLowerCase() + '.sectionTitle';
this.sectionTitle = this.tSvc.translate(key);

// get CMMC scores if appropriate
this.setCmmcLevelAchievement();
}

/**
Expand All @@ -61,4 +80,28 @@ export class ReportListComponent implements OnInit {
const val = this.tSvc.translate(key);
return val === key ? '' : val;
}

/**
* If this is a CMMC assessment, check the score for Level 1.
*/
setCmmcLevelAchievement() {
const cmmcModels = ['CMMC', 'CMMC2', 'CMMC2F'];
if (cmmcModels.indexOf(this.assessSvc.assessment.maturityModel?.modelName) >= 0) {
this.maturitySvc.getCmmcScores().subscribe((scores: any) => {
this.cmmcLevel1Achieved = scores.level1Score == scores.level1MaxScore;
});
}
}

/**
* Evaluates certain conditions to indicate if a report link
* should be disabled.
*/
isDisabled(condition: string) {
if (condition == 'cmmc level 1 not achieved') {
return !this.cmmcLevel1Achieved;
}

return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@
},
{
"linkUrl": "cmmc2CommentsMarked"
},
{
"exportUrl": "poam",
"icon": "export excel",
"disabledWhen": "cmmc level 1 not achieved"
}
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ <h3>{{ 'titles.reports' | transloco }}</h3>
</button>
</div>
</div>
<div class="my-3">
<div class="mt-3">
{{t('observations tear-out sheets.summary')}}
</div>
</div>

<div class="mb-3 p-3 w-100" [class.gray-box]="true">
<button tabindex="0" (click)="clickExcelLink('observations')" class="btn btn-link btn-link-dark px-0 pt-0">
<button tabindex="0" (click)="reportSvc.clickExcelLink('observations')" class="btn btn-link btn-link-dark px-0 pt-0">
<span class="cset-icons-export-excel fs-base me-2 align-middle"></span>
{{t('observations tear-out sheets.export csv link')}}
</button>
Expand All @@ -75,21 +75,6 @@ <h3>{{ 'titles.reports' | transloco }}</h3>
<!-- All reports component -->
<app-report-list-common *ngIf="currentSectionId" [sectionId]="currentSectionId"></app-report-list-common>

<!-- CMMC -->
<div *ngIf="currentSectionId == 'CMMC2'">
<h4>Plan of Action and Milestones</h4>

<p>
This report generates a Plan of Action and Milestones (POA&M) template which includes a list of unmet practices
eligible for remediation. This POA&M will exclude any CMMC practices that are ineligible for inclusion per CMMC
ruling.
</p>
<button class="icon-button-dark btn btn-primary" (click)="clickExcelLink('poam')">
<span class="cset-icons-export-excel fs-base me-2 align-middle"></span>
<span>Export POAM to Excel</span>
</button>
</div>

<!-- ISE -->
<app-report-list-common *ngIf="assessSvc.isISE() && !isMobile" sectionId="ISE">
</app-report-list-common>
Expand Down
17 changes: 0 additions & 17 deletions CSETWebNg/src/app/assessment/results/reports/reports.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,23 +240,6 @@ export class ReportsComponent implements OnInit, AfterViewInit {
});
}

/**
*
*/
clickExcelLink(reportType: string) {
let url = '';
if (reportType.toLowerCase() == 'poam') {
url = this.configSvc.apiUrl + 'reports/poam/excelexport?token=' + localStorage.getItem('userToken');
}

if (reportType.toLowerCase() == 'observations') {
url = this.configSvc.apiUrl + 'reports/observations/excel?token=' + localStorage.getItem('userToken');
}

if (url.length > 0) {
window.open(url, '_blank');
}
}

/**
* If all ACET statements are not answered, set the 'disable' flag
Expand Down
18 changes: 18 additions & 0 deletions CSETWebNg/src/app/services/report.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,24 @@ export class ReportService {
window.open(url, '_blank');
}

/**
*
*/
clickExcelLink(reportType: string) {
let url = '';
if (reportType.toLowerCase() == 'poam') {
url = this.configSvc.apiUrl + 'reports/poam/excelexport?token=' + localStorage.getItem('userToken');
}

if (reportType.toLowerCase() == 'observations') {
url = this.configSvc.apiUrl + 'reports/observations/excel?token=' + localStorage.getItem('userToken');
}

if (url.length > 0) {
window.open(url, '_blank');
}
}

/**
* Converts linebreak characters to HTML <br> tag.
*/
Expand Down
4 changes: 4 additions & 0 deletions CSETWebNg/src/assets/i18n/reports/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@
"3": {
"title": "CMMC 2.0 - Comments and Marked for Review",
"desc": "This document consolidates all practices that have received comments and have been flagged for review during the assessment process. It provides an overview of areas where further attention or clarification may be needed."
},
"4": {
"title": "Export POAM to Excel",
"desc": "This report generates a Plan of Action and Milestones (POA&M) template which includes a list of unmet practices eligible for remediation. This POA&M will exclude any CMMC practices that are ineligible for inclusion per CMMC ruling. It is available for assessments that have achieved Level 1 or above."
}
},
"rra": {
Expand Down
21 changes: 21 additions & 0 deletions CSETWebNg/src/assets/i18n/reports/es.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,25 @@
{
"launch": {
"cmmc2": {
"sectionTitle": "Certificación del Modelo de Madurez de Capacidades (CMMC) 2.0",
"1": {
"title": "CMMC 2.0 - Resumen ejecutivo",
"desc": "El informe incluye gráficos para resaltar el cumplimiento por nivel, el cumplimiento por dominio y la puntuación por nivel."
},
"2": {
"title": "CMMC 2.0 - Informe de cuadro de mando",
"desc": "El informe enumera todas las prácticas, cómo se respondieron y cualquier deducción de puntuación por prácticas no cumplidas."
},
"3": {
"title": "CMMC 2.0 - Comentarios y marcados para revisión",
"desc": "Este documento consolida todas las prácticas que han recibido comentarios y que se han marcado para su revisión durante el proceso de evaluación. Ofrece una descripción general de las áreas en las que puede ser necesario prestar más atención o realizar aclaraciones."
},
"4": {
"title": "Exportar POAM a Excel",
"desc": "Este informe genera una plantilla de Plan de acción e hitos (POA&M) que incluye una lista de prácticas no cumplidas que pueden remediarse. Este POA&M excluirá cualquier práctica de CMMC que no sea elegible para su inclusión según la resolución de CMMC. Está disponible para evaluaciones que hayan alcanzado el Nivel 1 o superior."
}
}
},
"assessment complete message": "Gracias por completar su evaluación. Los informes en esta página capturan resúmenes de sus resultados que pueden ayudar en la planificación y crecimiento de la ciberseguridad de su organización en el futuro. La evaluación fue actualizada por última vez el {date}.",
"reports run prior message": " Los informes generados antes de esa actualización pueden no reflejar el estado actual de la evaluación.",
"printing report instructions button": "Instrucciones para imprimir informes",
Expand Down
19 changes: 19 additions & 0 deletions CSETWebNg/src/assets/i18n/reports/uk.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,25 @@
"title": "CPG Дефіцит",
"desc": "Звіт містить список усіх методів безпеки, які були позначені як «Не реалізовано» або без відповіді під час процесу оцінювання. Цей звіт слугує для виявлення недоліків або прогалин у практиці кібербезпеки організації та містить пропозиції щодо покращення."
}
},
"cmmc2": {
"sectionTitle": "Сертифікація моделі зрілості можливостей (CMMC) 2.0",
"1": {
"title": "CMMC 2.0 – Резюме",
"desc": "Звіт містить графіки, на яких показано відповідність за рівнями, відповідність за доменами та оцінку за рівнями."
},
"2": {
"title": "CMMC 2.0 - Звіт системи показників",
"desc": "У звіті наведено перелік усіх практик, відповіді на них та будь-які вирахування балів за недотримані практики."
},
"3": {
"title": "CMMC 2.0 – коментарі та позначено для перегляду",
"desc": "Цей документ об’єднує всі практики, які отримали коментарі та були позначені для перевірки під час процесу оцінювання. Він містить огляд областей, де може знадобитися додаткова увага чи роз’яснення."
},
"4": {
"title": "Експорт POAM в Excel",
"desc": "У цьому звіті створюється шаблон плану дій і основних етапів (POA&M), який містить список недотриманих практик, які підлягають виправленню. Це POA&M виключатиме будь-які практики CMMC, які не підлягають включенню відповідно до рішення CMMC. Він доступний для оцінювання, яке досягло рівня 1 або вище."
}
}
},
"assessment complete message": "Дякуємо за завершення оцінювання. Звіти на цій сторінці містять підсумки ваших результатів, які можуть допомогти вашій організації планувати кібербезпеку та розвиватися в майбутньому. Оцінка востаннє оновлювалася {date}.",
Expand Down

0 comments on commit 6d97be2

Please sign in to comment.