feat: As a user, I want to create reports only in PDF file format
This commit is contained in:
parent
6e55e61ce5
commit
2e6f78c1f4
|
@ -87,7 +87,6 @@ export class HeaderComponent implements OnInit {
|
||||||
if (menuBag.item.icon) {
|
if (menuBag.item.icon) {
|
||||||
// tslint:disable-next-line:no-string-literal
|
// tslint:disable-next-line:no-string-literal
|
||||||
if (menuBag.item.icon['icon'] === this.settingsIcon) {
|
if (menuBag.item.icon['icon'] === this.settingsIcon) {
|
||||||
console.warn('Profile');
|
|
||||||
this.dialogService.openCustomDialog(
|
this.dialogService.openCustomDialog(
|
||||||
ProfileSettingsComponent,
|
ProfileSettingsComponent,
|
||||||
{
|
{
|
||||||
|
@ -98,7 +97,7 @@ export class HeaderComponent implements OnInit {
|
||||||
untilDestroyed(this)
|
untilDestroyed(this)
|
||||||
).subscribe({
|
).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
console.warn('New Settings confirmed');
|
console.info('New Settings confirmed');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,12 +183,12 @@
|
||||||
"title": "Titel",
|
"title": "Titel",
|
||||||
"description": "Beschreibung",
|
"description": "Beschreibung",
|
||||||
"impact": "Auswirkung",
|
"impact": "Auswirkung",
|
||||||
"affectedUrls": "Betroffene URL's",
|
"affectedUrls": "Betroffene URL's / API's",
|
||||||
"reproduction": "Reproduktion",
|
"reproduction": "Reproduktion",
|
||||||
"mitigation": "Minderung",
|
"mitigation": "Minderung",
|
||||||
"add": "Fund hinzufügen",
|
"add": "Fund hinzufügen",
|
||||||
"add.url": "Betroffene URL hinzufügen",
|
"add.url": "Betroffene URL / API hinzufügen",
|
||||||
"affectedUrls.placeholder": "Betroffene URL hier eingeben..",
|
"affectedUrls.placeholder": "Betroffene URL oder API hier eingeben..",
|
||||||
"create": {
|
"create": {
|
||||||
"header": "Neuen Fund erstellen"
|
"header": "Neuen Fund erstellen"
|
||||||
},
|
},
|
||||||
|
|
|
@ -183,12 +183,12 @@
|
||||||
"title": "Title",
|
"title": "Title",
|
||||||
"description": "Description",
|
"description": "Description",
|
||||||
"impact": "Impact",
|
"impact": "Impact",
|
||||||
"affectedUrls": "Affected URL's",
|
"affectedUrls": "Affected URL's / API's",
|
||||||
"reproduction": "Reproduction",
|
"reproduction": "Reproduction",
|
||||||
"mitigation": "Mitigation",
|
"mitigation": "Mitigation",
|
||||||
"add": "Add finding",
|
"add": "Add finding",
|
||||||
"add.url": "Add affected Url",
|
"add.url": "Add affected URL / API",
|
||||||
"affectedUrls.placeholder": "Enter affected URL here..",
|
"affectedUrls.placeholder": "Enter affected URL or API here..",
|
||||||
"create": {
|
"create": {
|
||||||
"header": "Create New Finding"
|
"header": "Create New Finding"
|
||||||
},
|
},
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<app-version-tag [version]="dialogData.options[0].additionalData?.version"></app-version-tag>
|
<app-version-tag [version]="dialogData.options[0].additionalData?.version"></app-version-tag>
|
||||||
</div>
|
</div>
|
||||||
<!--Chart Objective Component-->
|
<!--Chart Objective Component-->
|
||||||
<div fxLayout="column" fxLayoutGap="2rem" fxLayoutAlign="center center">
|
<div fxLayout="column" fxLayoutGap="2rem" fxLayoutAlign="center center" class="objective-chart">
|
||||||
<app-objective-chart
|
<app-objective-chart
|
||||||
[projectPentestData]="selectedEvaluatedProject$.getValue().projectPentests"></app-objective-chart>
|
[projectPentestData]="selectedEvaluatedProject$.getValue().projectPentests"></app-objective-chart>
|
||||||
<span
|
<span
|
||||||
|
@ -35,8 +35,8 @@
|
||||||
alt="">
|
alt="">
|
||||||
</nb-radio>
|
</nb-radio>
|
||||||
</nb-radio-group>
|
</nb-radio-group>
|
||||||
<!--Export Format Radio Selection-->
|
<!--ToDo: Export Format Radio Selection only whne more than pdf is supported-->
|
||||||
<label class="export-format-label">
|
<!--<label class="export-format-label">
|
||||||
{{ 'report.dialog.formatLabel' | translate }}
|
{{ 'report.dialog.formatLabel' | translate }}
|
||||||
</label>
|
</label>
|
||||||
<nb-radio-group name="format" [formControl]="exportReportFormatControl" class="export-radio-buttons"
|
<nb-radio-group name="format" [formControl]="exportReportFormatControl" class="export-radio-buttons"
|
||||||
|
@ -47,10 +47,10 @@
|
||||||
<nb-radio disabled value="{{exportFormats.CSV}}">
|
<nb-radio disabled value="{{exportFormats.CSV}}">
|
||||||
{{exportFormats.CSV}}
|
{{exportFormats.CSV}}
|
||||||
</nb-radio>
|
</nb-radio>
|
||||||
<nb-radio disabled value="{{exportFormats.HTML}}">
|
<nb-radio value="{{exportFormats.HTML}}">
|
||||||
{{exportFormats.HTML}}
|
{{exportFormats.HTML}}
|
||||||
</nb-radio>
|
</nb-radio>
|
||||||
</nb-radio-group>
|
</nb-radio-group>-->
|
||||||
</div>
|
</div>
|
||||||
</nb-card-body>
|
</nb-card-body>
|
||||||
<nb-card-footer fxLayout="row" fxLayoutGap="1.5rem" fxLayoutAlign="end end">
|
<nb-card-footer fxLayout="row" fxLayoutGap="1.5rem" fxLayoutAlign="end end">
|
||||||
|
|
|
@ -4,13 +4,18 @@
|
||||||
|
|
||||||
.export-report-dialog {
|
.export-report-dialog {
|
||||||
width: 45.25rem !important;
|
width: 45.25rem !important;
|
||||||
height: 56.25rem;
|
height: 48.25rem;
|
||||||
|
|
||||||
.export-report-header {
|
.export-report-header {
|
||||||
height: 8vh;
|
height: 8vh;
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.objective-chart {
|
||||||
|
padding-top: 1.5rem;
|
||||||
|
padding-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.languageContainer {
|
.languageContainer {
|
||||||
display: flex;
|
display: flex;
|
||||||
max-width: 8rem;
|
max-width: 8rem;
|
||||||
|
@ -22,17 +27,19 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.hint {
|
|
||||||
padding-bottom: 0.5rem;
|
|
||||||
color: nb-theme(color-danger-default);
|
|
||||||
}
|
|
||||||
|
|
||||||
.export-radio-buttons {
|
.export-radio-buttons {
|
||||||
float: left;
|
float: left;
|
||||||
clear: none;
|
clear: none;
|
||||||
margin-left: 1rem;
|
margin-left: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hint {
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
color: nb-theme(color-danger-default);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nb-form-field {
|
nb-form-field {
|
||||||
padding: 0.5rem 0 0.75rem;
|
padding: 0.5rem 0 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,6 @@ export class ExportReportDialogComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickExport(reportFormat: string, reportLanguage: string): void {
|
onClickExport(reportFormat: string, reportLanguage: string): void {
|
||||||
console.warn('ToDo: Use format ', reportFormat);
|
|
||||||
// Get project id from dialog data
|
// Get project id from dialog data
|
||||||
const projectId = this.dialogData.options[0].additionalData.id;
|
const projectId = this.dialogData.options[0].additionalData.id;
|
||||||
// Loading is true as long as there is a response from the reporting service
|
// Loading is true as long as there is a response from the reporting service
|
||||||
|
@ -89,7 +88,6 @@ export class ExportReportDialogComponent implements OnInit {
|
||||||
// Export pentest in choosen format
|
// Export pentest in choosen format
|
||||||
switch (reportFormat) {
|
switch (reportFormat) {
|
||||||
case ExportFormatOptions.PDF: {
|
case ExportFormatOptions.PDF: {
|
||||||
// @ts-ignore
|
|
||||||
this.downloadPentestReport$ = this.reportingService.getReportPDFforProjectById(projectId, reportLanguage)
|
this.downloadPentestReport$ = this.reportingService.getReportPDFforProjectById(projectId, reportLanguage)
|
||||||
.pipe(
|
.pipe(
|
||||||
shareReplay(),
|
shareReplay(),
|
||||||
|
@ -112,16 +110,6 @@ export class ExportReportDialogComponent implements OnInit {
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ExportFormatOptions.CSV: {
|
|
||||||
this.loading$.next(false);
|
|
||||||
this.notificationService.showPopup('report.popup.generation.failed', PopupType.FAILURE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ExportFormatOptions.HTML: {
|
|
||||||
this.loading$.next(false);
|
|
||||||
this.notificationService.showPopup('report.popup.generation.failed', PopupType.FAILURE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
default: {
|
||||||
this.loading$.next(false);
|
this.loading$.next(false);
|
||||||
this.notificationService.showPopup('report.popup.generation.failed', PopupType.FAILURE);
|
this.notificationService.showPopup('report.popup.generation.failed', PopupType.FAILURE);
|
||||||
|
|
|
@ -77,7 +77,6 @@ export class ProfileSettingsComponent implements OnInit {
|
||||||
this.userNameControl.setValue(user.username);
|
this.userNameControl.setValue(user.username);
|
||||||
this.userFirstNameControl.setValue(user.firstName);
|
this.userFirstNameControl.setValue(user.firstName);
|
||||||
this.userLastNameControl.setValue(user.lastName);
|
this.userLastNameControl.setValue(user.lastName);
|
||||||
console.warn(this.user.getValue());
|
|
||||||
},
|
},
|
||||||
error: err => {
|
error: err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
@ -121,6 +120,9 @@ export class ProfileSettingsComponent implements OnInit {
|
||||||
|
|
||||||
onClickLanguage(language: string): void {
|
onClickLanguage(language: string): void {
|
||||||
this.translateService.use(language);
|
this.translateService.use(language);
|
||||||
|
// ToDo: Update userAccount language property
|
||||||
|
const user = this.store.selectSnapshot(SessionState.userAccount);
|
||||||
|
this.store.dispatch(new UpdateUserSettings({...user, interfaceLang: language}));
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickConfirm(): void {
|
onClickConfirm(): void {
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
import {Pipe, PipeTransform} from '@angular/core';
|
import {Pipe, PipeTransform} from '@angular/core';
|
||||||
import {formatDate} from '@angular/common';
|
import {formatDate} from '@angular/common';
|
||||||
import {Store} from '@ngxs/store';
|
import {Store} from '@ngxs/store';
|
||||||
import {SessionState} from '@shared/stores/session-state/session-state';
|
|
||||||
import {CustomPipe} from '@shared/models/custom-pipe.mode';
|
import {CustomPipe} from '@shared/models/custom-pipe.mode';
|
||||||
|
import {TranslateService} from '@ngx-translate/core';
|
||||||
|
|
||||||
@Pipe({
|
@Pipe({
|
||||||
name: 'dateTimeFormat'
|
name: 'dateTimeFormat',
|
||||||
|
pure: false
|
||||||
})
|
})
|
||||||
export class DateTimeFormatPipe implements PipeTransform {
|
export class DateTimeFormatPipe implements PipeTransform {
|
||||||
|
|
||||||
constructor(private store: Store) {
|
constructor(private store: Store, private translateService: TranslateService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,18 +23,15 @@ export class DateTimeFormatPipe implements PipeTransform {
|
||||||
return '-';
|
return '-';
|
||||||
}
|
}
|
||||||
|
|
||||||
const localeDateAndNumberFormat = this.store.selectSnapshot(SessionState.userAccount) ?
|
const currentLanguage = this.translateService.currentLang;
|
||||||
// @ts-ignore
|
|
||||||
this.store.selectSnapshot(SessionState.userAccount.interfaceLang) : 'en-US';
|
|
||||||
|
|
||||||
if (!localeDateAndNumberFormat) {
|
if (!currentLanguage) {
|
||||||
return formatDate(value, CustomPipe.DATE_TIME_FMT_EN, 'en-US');
|
return formatDate(value, CustomPipe.DATE_TIME_FMT_EN, 'en-US');
|
||||||
}
|
}
|
||||||
if (localeDateAndNumberFormat === 'de-DE') {
|
if (currentLanguage === 'de-DE') {
|
||||||
return formatDate(value, CustomPipe.DATE_TIME_FMT_DE, localeDateAndNumberFormat) + ' Uhr';
|
return formatDate(value, CustomPipe.DATE_TIME_FMT_DE, currentLanguage) + ' Uhr';
|
||||||
}
|
}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return formatDate(value, CustomPipe.DATE_TIME_FMT_EN, localeDateAndNumberFormat);
|
return formatDate(value, CustomPipe.DATE_TIME_FMT_EN, currentLanguage);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ export class DialogService {
|
||||||
additionalData: any
|
additionalData: any
|
||||||
): NbDialogRef<T> {
|
): NbDialogRef<T> {
|
||||||
return this.dialog.open<T>(componentOrTemplateRef, {
|
return this.dialog.open<T>(componentOrTemplateRef, {
|
||||||
closeOnEsc: false,
|
closeOnEsc: true,
|
||||||
hasScroll: false,
|
hasScroll: false,
|
||||||
autoFocus: true,
|
autoFocus: true,
|
||||||
closeOnBackdropClick: false,
|
closeOnBackdropClick: false,
|
||||||
|
|
|
@ -18,7 +18,6 @@ export class ReportingService {
|
||||||
/**
|
/**
|
||||||
* Get PDF Report by project id
|
* Get PDF Report by project id
|
||||||
*/
|
*/
|
||||||
// ToDo: Add language here
|
|
||||||
public getReportPDFforProjectById(projectId: string, reportLanguage: string): Observable<Loading<ArrayBuffer>> {
|
public getReportPDFforProjectById(projectId: string, reportLanguage: string): Observable<Loading<ArrayBuffer>> {
|
||||||
return this.http.get(`${this.reportBaseURL}/${projectId}/pdf/${reportLanguage}`,
|
return this.http.get(`${this.reportBaseURL}/${projectId}/pdf/${reportLanguage}`,
|
||||||
{
|
{
|
||||||
|
@ -29,12 +28,6 @@ export class ReportingService {
|
||||||
}
|
}
|
||||||
).pipe(loadContent<ArrayBuffer>());
|
).pipe(loadContent<ArrayBuffer>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ToDo: Remove report function without observing report progress
|
|
||||||
public getReportPDFforProjectById(projectId: string): Observable<ArrayBuffer> {
|
|
||||||
// @ts-ignore
|
|
||||||
return this.http.get<ArrayBuffer>(`${this.reportBaseURL}/${projectId}/pdf`, {responseType: 'arraybuffer'})
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ReportDownloadConfiguration {
|
export interface ReportDownloadConfiguration {
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
package com.securityc4po.reporting.report
|
package com.securityc4po.reporting.report
|
||||||
|
|
||||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
|
||||||
import com.fasterxml.jackson.module.kotlin.readValue
|
|
||||||
import com.securityc4po.reporting.configuration.security.Appuser
|
import com.securityc4po.reporting.configuration.security.Appuser
|
||||||
import com.securityc4po.reporting.extensions.getLoggerFor
|
import com.securityc4po.reporting.extensions.getLoggerFor
|
||||||
import com.securityc4po.reporting.remote.APIService
|
import com.securityc4po.reporting.remote.APIService
|
||||||
import com.securityc4po.reporting.remote.model.ProjectReport
|
|
||||||
import org.springframework.http.MediaType
|
import org.springframework.http.MediaType
|
||||||
import org.springframework.http.ResponseEntity
|
import org.springframework.http.ResponseEntity
|
||||||
import org.springframework.http.ResponseEntity.notFound
|
import org.springframework.http.ResponseEntity.notFound
|
||||||
|
@ -13,7 +10,6 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal
|
||||||
import org.springframework.web.bind.annotation.*
|
import org.springframework.web.bind.annotation.*
|
||||||
import reactor.core.publisher.Mono
|
import reactor.core.publisher.Mono
|
||||||
import reactor.kotlin.core.publisher.switchIfEmpty
|
import reactor.kotlin.core.publisher.switchIfEmpty
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/reports")
|
@RequestMapping("/reports")
|
||||||
|
@ -31,7 +27,6 @@ class ReportController(private val apiService: APIService, private val reportSer
|
||||||
"/{projectId}/pdf/{reportLanguage}",
|
"/{projectId}/pdf/{reportLanguage}",
|
||||||
produces = [MediaType.APPLICATION_PDF_VALUE]
|
produces = [MediaType.APPLICATION_PDF_VALUE]
|
||||||
)
|
)
|
||||||
// ToDo: Add language here
|
|
||||||
fun downloadPentestReportPDF(@PathVariable(value = "projectId") projectId: String, @PathVariable(value = "reportLanguage") reportLanguage: String, @AuthenticationPrincipal user: Appuser): Mono<ResponseEntity<ByteArray>> {
|
fun downloadPentestReportPDF(@PathVariable(value = "projectId") projectId: String, @PathVariable(value = "reportLanguage") reportLanguage: String, @AuthenticationPrincipal user: Appuser): Mono<ResponseEntity<ByteArray>> {
|
||||||
return this.apiService.requestProjectReportDataById(projectId, user.token).flatMap {projectReport ->
|
return this.apiService.requestProjectReportDataById(projectId, user.token).flatMap {projectReport ->
|
||||||
this.reportService.createReport(projectReport, "pdf", reportLanguage).map { reportClassLoaderFilePath ->
|
this.reportService.createReport(projectReport, "pdf", reportLanguage).map { reportClassLoaderFilePath ->
|
||||||
|
@ -41,35 +36,4 @@ class ReportController(private val apiService: APIService, private val reportSer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToDo: Add download API for csv report
|
|
||||||
/*
|
|
||||||
@GetMapping(
|
|
||||||
"/{projectId}/csv",
|
|
||||||
produces = ["text/csv"]
|
|
||||||
)
|
|
||||||
fun downloadPentestReportCSV() {
|
|
||||||
/* ToDo: remove if jsonProjectReportCollection not needed for report generation */
|
|
||||||
val jsonProjectReportString: String =
|
|
||||||
File("./src/test/resources/ProjectReportData.json").readText(Charsets.UTF_8)
|
|
||||||
val jsonProjectReportCollection: ProjectReport =
|
|
||||||
jacksonObjectMapper().readValue<ProjectReport>(jsonProjectReportString)
|
|
||||||
/* jsonProjectReportCollection */
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// ToDo: Add download API for html report
|
|
||||||
/*
|
|
||||||
@GetMapping(
|
|
||||||
"/{projectId}/html",
|
|
||||||
produces = ["text/html"]
|
|
||||||
)
|
|
||||||
fun downloadPentestReportHTML() {
|
|
||||||
/* ToDo: remove if jsonProjectReportCollection not needed for report generation */
|
|
||||||
val jsonProjectReportString: String =
|
|
||||||
File("./src/test/resources/ProjectReportData.json").readText(Charsets.UTF_8)
|
|
||||||
val jsonProjectReportCollection: ProjectReport =
|
|
||||||
jacksonObjectMapper().readValue<ProjectReport>(jsonProjectReportString)
|
|
||||||
/* jsonProjectReportCollection */
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,19 +76,18 @@ class ReportService {
|
||||||
lateinit var severityRatingTablePath: String
|
lateinit var severityRatingTablePath: String
|
||||||
|
|
||||||
fun createReport(projectReportCollection: ProjectReport, reportFormat: String, reportLanguage: String): Mono<ByteArray> {
|
fun createReport(projectReportCollection: ProjectReport, reportFormat: String, reportLanguage: String): Mono<ByteArray> {
|
||||||
logger.info("Use: " + reportLanguage)
|
|
||||||
// Setup PDFMergerUtility
|
// Setup PDFMergerUtility
|
||||||
val mergedC4POPentestReport: PDFMergerUtility = PDFMergerUtility()
|
val mergedC4POPentestReport: PDFMergerUtility = PDFMergerUtility()
|
||||||
// Setup ByteArrayOutputStream for "on the fly" file generation
|
// Setup ByteArrayOutputStream for "on the fly" file generation
|
||||||
val pdfDocOutputstream = ByteArrayOutputStream()
|
val penetstReportOutputstream = ByteArrayOutputStream()
|
||||||
// Try to create report files & merge them together
|
// Try to create report files & merge them together
|
||||||
return createPentestReportFiles(projectReportCollection, reportFormat, reportLanguage, mergedC4POPentestReport).collectList()
|
return createPentestReportFiles(projectReportCollection, reportFormat, reportLanguage, mergedC4POPentestReport).collectList()
|
||||||
.map {
|
.map {
|
||||||
// Merge report files
|
// Merge report files
|
||||||
mergedC4POPentestReport.destinationStream = pdfDocOutputstream
|
mergedC4POPentestReport.destinationStream = penetstReportOutputstream
|
||||||
mergedC4POPentestReport.mergeDocuments(MemoryUsageSetting.setupTempFileOnly())
|
mergedC4POPentestReport.mergeDocuments(MemoryUsageSetting.setupTempFileOnly())
|
||||||
}.flatMap {
|
}.flatMap {
|
||||||
return@flatMap Mono.just(pdfDocOutputstream.toByteArray())
|
return@flatMap Mono.just(penetstReportOutputstream.toByteArray())
|
||||||
}.doOnError {
|
}.doOnError {
|
||||||
logger.error("Report generation failed.")
|
logger.error("Report generation failed.")
|
||||||
}
|
}
|
||||||
|
@ -113,13 +112,13 @@ class ReportService {
|
||||||
createAppendencies(reportFormat, resourceBundle)
|
createAppendencies(reportFormat, resourceBundle)
|
||||||
).map { jasperObject ->
|
).map { jasperObject ->
|
||||||
if (jasperObject is ByteArray) {
|
if (jasperObject is ByteArray) {
|
||||||
val pdfInputSteam = ByteArrayInputStream(jasperObject)
|
val reportFilesInputSteam = ByteArrayInputStream(jasperObject)
|
||||||
mergedC4POPentestReport.addSource(pdfInputSteam)
|
mergedC4POPentestReport.addSource(reportFilesInputSteam)
|
||||||
} else if (jasperObject is List<*>) {
|
} else if (jasperObject is List<*>) {
|
||||||
jasperObject.forEach { jasperFile ->
|
jasperObject.forEach { jasperFile ->
|
||||||
if (jasperFile is ByteArray) {
|
if (jasperFile is ByteArray) {
|
||||||
val pdfInputSteam = ByteArrayInputStream(jasperFile)
|
val reportFilesInputSteam = ByteArrayInputStream(jasperFile)
|
||||||
mergedC4POPentestReport.addSource(pdfInputSteam)
|
mergedC4POPentestReport.addSource(reportFilesInputSteam)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
# Cover
|
# Cover
|
||||||
title.cover_one=Penetrationstest
|
title.cover_one=Penetrationstest
|
||||||
title.cover_two=Ergebnisbericht
|
title.cover_two=Ergebnisbericht
|
||||||
|
date.format=dd.MM.yyyy
|
||||||
hint=Kein Teil dieses Dokuments darf ohne die ausdrückliche schriftliche Genehmigung des Testers an externe Quellen weitergegeben werden
|
hint=Kein Teil dieses Dokuments darf ohne die ausdrückliche schriftliche Genehmigung des Testers an externe Quellen weitergegeben werden
|
||||||
|
|
||||||
# Table of contents
|
# Table of contents
|
||||||
|
@ -26,11 +27,11 @@ title.comment=Kommentar:
|
||||||
title=Titel:
|
title=Titel:
|
||||||
description=Beschreibung:
|
description=Beschreibung:
|
||||||
impact=Auswirkung:
|
impact=Auswirkung:
|
||||||
reproduction_steps=Reproduktion:
|
reproduction_steps=Schritte zur Reproduktion:
|
||||||
mitigation=Minderung:
|
mitigation=Minderung:
|
||||||
no_mitigation=Keine Schadensminderung zur Vermeidung, Minimierung oder Kompensation des festgestellten oder erforderlichen Befunds.
|
no_mitigation=Keine Schadensminderung zur Vermeidung, Minimierung oder Kompensation des festgestellten oder erforderlichen Befunds.
|
||||||
affected_urls=Betroffene URL's:
|
affected_urls=Betroffene URL's / API's:
|
||||||
no_affected_urls=Keine spezifischen URLs betroffen.
|
no_affected_urls=Keine spezifischen URLs oder API's betroffen.
|
||||||
|
|
||||||
# Appendencies
|
# Appendencies
|
||||||
title.appendencies=Anhänge
|
title.appendencies=Anhänge
|
||||||
|
@ -38,7 +39,7 @@ title.findings_severities=Schweregrade der Funde
|
||||||
text.findings_severities=Jedem Befund wurde eine Schweregradbewertung von kritisch hoch, mittel oder niedrig zugewiesen. Die Bewertung basiert auf einer Bewertung der Priorität, mit der jeder Befund betrachtet werden sollte, und der potenziellen Auswirkungen, die jeder auf die Vertraulichkeit, Integrität und Verfügbarkeit hat.
|
text.findings_severities=Jedem Befund wurde eine Schweregradbewertung von kritisch hoch, mittel oder niedrig zugewiesen. Die Bewertung basiert auf einer Bewertung der Priorität, mit der jeder Befund betrachtet werden sollte, und der potenziellen Auswirkungen, die jeder auf die Vertraulichkeit, Integrität und Verfügbarkeit hat.
|
||||||
title.risk_matrix=Risiko Matrix
|
title.risk_matrix=Risiko Matrix
|
||||||
text.risk_matrix=Die Risikomatrix wird verwendet, um den potenziellen Schaden einer Gefahr basierend auf den Faktoren Wahrscheinlichkeit und Schweregrad zu bewerten. Die Wahrscheinlichkeits- und Schweregradbewertungen werden multipliziert, um einen Bewertungswert zu erhalten. Diese Punktzahl wird in den Risikobereichen nachgeschlagen, um das Risikoniveau zu bestimmen. Ein Beispiel für eine Gefahren-Risiko-Matrix ist unten angegeben:
|
text.risk_matrix=Die Risikomatrix wird verwendet, um den potenziellen Schaden einer Gefahr basierend auf den Faktoren Wahrscheinlichkeit und Schweregrad zu bewerten. Die Wahrscheinlichkeits- und Schweregradbewertungen werden multipliziert, um einen Bewertungswert zu erhalten. Diese Punktzahl wird in den Risikobereichen nachgeschlagen, um das Risikoniveau zu bestimmen. Ein Beispiel für eine Gefahren-Risiko-Matrix ist unten angegeben:
|
||||||
example.risk_matrix=Beispiel: Wenn Wahrscheinlichkeit = Möglich (3) und Schweregrad = Erheblich (4), wird die Risikostufe durch Schweregrad * Wahrscheinlichkeit bestimmt, was 3*4 = 12 ist. Die Punktzahl 12 fällt in den Risikobereich 'Hoch'.
|
example.risk_matrix=Beispiel: Wenn Wahrscheinlichkeit = Möglich (3) und Schweregrad = Erheblich (4), wird die Risikostufe durch Schweregrad * Wahrscheinlichkeit bestimmt, was 3*4 = 12 ist. Die Punktzahl 12 fällt in den Risikobereich 'High'.
|
||||||
# Risk Matrix Table Properties
|
# Risk Matrix Table Properties
|
||||||
risk_score=Risiko-Score
|
risk_score=Risiko-Score
|
||||||
to=bis
|
to=bis
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
# Cover
|
# Cover
|
||||||
title.cover_one=Penetration Test
|
title.cover_one=Penetration Test
|
||||||
title.cover_two=Report of Findings
|
title.cover_two=Report of Findings
|
||||||
|
date.format=MM/dd/yyyy
|
||||||
hint=No part of this document may be disclosed to outside sources without the explicit written authorization of the tester
|
hint=No part of this document may be disclosed to outside sources without the explicit written authorization of the tester
|
||||||
|
|
||||||
# Table of contents
|
# Table of contents
|
||||||
|
@ -29,8 +30,8 @@ impact=Impact:
|
||||||
reproduction_steps=Reproduction Steps:
|
reproduction_steps=Reproduction Steps:
|
||||||
mitigation=Mitigation:
|
mitigation=Mitigation:
|
||||||
no_mitigation=No mitigation to avoid, minimize or compensate the finding found or needed.
|
no_mitigation=No mitigation to avoid, minimize or compensate the finding found or needed.
|
||||||
affected_urls=Affected URL's:
|
affected_urls=Affected URL's / API's:
|
||||||
no_affected_urls=No specific URL's affected.
|
no_affected_urls=No specific URL's or API's affected.
|
||||||
|
|
||||||
# Appendencies
|
# Appendencies
|
||||||
title.appendencies=Appendencies
|
title.appendencies=Appendencies
|
||||||
|
|
|
@ -147,7 +147,7 @@
|
||||||
<textElement textAlignment="Right">
|
<textElement textAlignment="Right">
|
||||||
<font fontName="SansSerif" size="12" isBold="true" isItalic="true"/>
|
<font fontName="SansSerif" size="12" isBold="true" isItalic="true"/>
|
||||||
</textElement>
|
</textElement>
|
||||||
<textFieldExpression><![CDATA[(new SimpleDateFormat("dd/MM/yyyy").format($F{createdAt}))]]></textFieldExpression>
|
<textFieldExpression><![CDATA[(new SimpleDateFormat($R{date.format}).format($F{createdAt}))]]></textFieldExpression>
|
||||||
</textField>
|
</textField>
|
||||||
</band>
|
</band>
|
||||||
</detail>
|
</detail>
|
||||||
|
@ -177,7 +177,7 @@
|
||||||
<reportElement x="-20" y="-10" width="595" height="20" forecolor="#151B2E" backcolor="#151B2E" uuid="724a02c5-82c8-4a72-bf81-b77baa72c723"/>
|
<reportElement x="-20" y="-10" width="595" height="20" forecolor="#151B2E" backcolor="#151B2E" uuid="724a02c5-82c8-4a72-bf81-b77baa72c723"/>
|
||||||
</rectangle>
|
</rectangle>
|
||||||
<textField>
|
<textField>
|
||||||
<reportElement x="0" y="-7" width="554" height="15" forecolor="#FFFFFF" uuid="32716a0d-4cec-4dc4-b766-f545dea11169"/>
|
<reportElement x="-14" y="-7" width="584" height="15" forecolor="#FFFFFF" uuid="32716a0d-4cec-4dc4-b766-f545dea11169"/>
|
||||||
<textElement textAlignment="Center" verticalAlignment="Middle">
|
<textElement textAlignment="Center" verticalAlignment="Middle">
|
||||||
<font size="8" isBold="true"/>
|
<font size="8" isBold="true"/>
|
||||||
</textElement>
|
</textElement>
|
||||||
|
|
|
@ -0,0 +1,188 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Created with Jaspersoft Studio version 6.20.0.final using JasperReports Library version 6.20.0-2bc7ab61c56f459e8176eb05c7705e145cd400ad -->
|
||||||
|
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="C4PO_Coverpage" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="1e81cc75-35cb-406c-934f-0bc56dfd965d">
|
||||||
|
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="ProjectReportJasperData Template JSON Adapter"/>
|
||||||
|
<!-- Ignores Issue about not finding a specific font -->
|
||||||
|
<property name="net.sf.jasperreports.awt.ignore.missing.font" value="true"/>
|
||||||
|
<parameter name="CDATA_WATERMARK" class="java.lang.String"/>
|
||||||
|
<parameter name="CDATA_C4POCoverBackground" class="java.lang.String"/>
|
||||||
|
<queryString language="JSON">
|
||||||
|
<![CDATA[projectReportData]]>
|
||||||
|
</queryString>
|
||||||
|
<field name="id" class="java.lang.String">
|
||||||
|
<property name="net.sf.jasperreports.json.field.expression" value="id"/>
|
||||||
|
<fieldDescription><![CDATA[id]]></fieldDescription>
|
||||||
|
</field>
|
||||||
|
<field name="client" class="java.lang.String">
|
||||||
|
<property name="net.sf.jasperreports.json.field.expression" value="client"/>
|
||||||
|
<fieldDescription><![CDATA[client]]></fieldDescription>
|
||||||
|
</field>
|
||||||
|
<field name="title" class="java.lang.String">
|
||||||
|
<property name="net.sf.jasperreports.json.field.expression" value="title"/>
|
||||||
|
<fieldDescription><![CDATA[title]]></fieldDescription>
|
||||||
|
</field>
|
||||||
|
<field name="createdAt" class="java.util.Date">
|
||||||
|
<property name="net.sf.jasperreports.json.field.expression" value="createdAt"/>
|
||||||
|
<fieldDescription><![CDATA[createdAt]]></fieldDescription>
|
||||||
|
</field>
|
||||||
|
<field name="tester" class="java.lang.String">
|
||||||
|
<property name="net.sf.jasperreports.json.field.expression" value="tester"/>
|
||||||
|
<fieldDescription><![CDATA[tester]]></fieldDescription>
|
||||||
|
</field>
|
||||||
|
<field name="summary" class="java.lang.String">
|
||||||
|
<property name="net.sf.jasperreports.json.field.expression" value="summary"/>
|
||||||
|
<fieldDescription><![CDATA[summary]]></fieldDescription>
|
||||||
|
</field>
|
||||||
|
<field name="projectPentestReport" class="java.lang.String">
|
||||||
|
<property name="net.sf.jasperreports.json.field.expression" value="projectPentestReport"/>
|
||||||
|
<fieldDescription><![CDATA[projectPentestReport]]></fieldDescription>
|
||||||
|
</field>
|
||||||
|
<field name="createdBy" class="java.lang.String">
|
||||||
|
<property name="net.sf.jasperreports.json.field.expression" value="createdBy"/>
|
||||||
|
<fieldDescription><![CDATA[createdBy]]></fieldDescription>
|
||||||
|
</field>
|
||||||
|
<field name="version" class="java.lang.String"/>
|
||||||
|
<background>
|
||||||
|
<band splitType="Stretch"/>
|
||||||
|
</background>
|
||||||
|
<title>
|
||||||
|
<band height="390" splitType="Stretch">
|
||||||
|
<image>
|
||||||
|
<reportElement x="-20" y="-20" width="595" height="409" uuid="7b8866c7-8b72-43a8-9428-2404a75e803e"/>
|
||||||
|
<imageExpression><![CDATA[$P{CDATA_C4POCoverBackground}]]></imageExpression>
|
||||||
|
</image>
|
||||||
|
<rectangle>
|
||||||
|
<reportElement x="-20" y="-20" width="595" height="280" forecolor="#151B2E" backcolor="rgba(35, 43, 68, 0.5882353)" uuid="7412dfc2-c785-4584-b8e9-120df2ef41f2"/>
|
||||||
|
<graphicElement>
|
||||||
|
<pen lineWidth="0.0"/>
|
||||||
|
</graphicElement>
|
||||||
|
</rectangle>
|
||||||
|
<rectangle>
|
||||||
|
<reportElement x="-20" y="241" width="595" height="120" forecolor="#232B44" backcolor="#232B44" uuid="c3646ed4-24af-4969-990a-322ff29697a9"/>
|
||||||
|
</rectangle>
|
||||||
|
<textField textAdjust="StretchHeight">
|
||||||
|
<reportElement x="6" y="280" width="543" height="51" forecolor="#FFFFFF" uuid="563ae593-7ae8-47fc-8728-01da0a717aad"/>
|
||||||
|
<textElement textAlignment="Center" verticalAlignment="Middle">
|
||||||
|
<font fontName="SansSerif" size="26" isBold="true"/>
|
||||||
|
</textElement>
|
||||||
|
<textFieldExpression><![CDATA[$F{client}]]></textFieldExpression>
|
||||||
|
</textField>
|
||||||
|
<textField>
|
||||||
|
<reportElement mode="Transparent" x="5" y="0" width="544" height="219" forecolor="#FEFEFF" backcolor="#232B44" uuid="173fc927-62f1-4242-9c7e-638a21a9672f">
|
||||||
|
<property name="net.sf.jasperreports.export.accessibility.tag" value="h1"/>
|
||||||
|
<property name="net.sf.jasperreports.export.pdf.tag.table" value="full"/>
|
||||||
|
</reportElement>
|
||||||
|
<textElement textAlignment="Center" verticalAlignment="Middle" markup="none">
|
||||||
|
<font fontName="SansSerif" size="36" isBold="true"/>
|
||||||
|
</textElement>
|
||||||
|
<textFieldExpression><![CDATA[$F{title}]]></textFieldExpression>
|
||||||
|
</textField>
|
||||||
|
<rectangle>
|
||||||
|
<reportElement x="-2" y="220" width="577" height="40" forecolor="#232B44" backcolor="#151B2E" uuid="2d5d891c-1d0f-4d81-beab-6d6937f08b5b"/>
|
||||||
|
<graphicElement>
|
||||||
|
<pen lineWidth="0.0"/>
|
||||||
|
</graphicElement>
|
||||||
|
</rectangle>
|
||||||
|
<ellipse>
|
||||||
|
<reportElement x="-20" y="220" width="38" height="40" backcolor="#151B2E" uuid="fefe65c4-59db-4810-9539-1865db235814"/>
|
||||||
|
<graphicElement>
|
||||||
|
<pen lineWidth="0.0"/>
|
||||||
|
</graphicElement>
|
||||||
|
</ellipse>
|
||||||
|
<image>
|
||||||
|
<reportElement x="-14" y="224" width="31" height="37" uuid="ae84d484-ee44-436a-a0cd-e94a265ed665"/>
|
||||||
|
<imageExpression><![CDATA[$P{CDATA_WATERMARK}]]></imageExpression>
|
||||||
|
</image>
|
||||||
|
<staticText>
|
||||||
|
<reportElement mode="Transparent" x="22" y="226" width="82" height="20" forecolor="#FEFEFF" backcolor="#151B2E" uuid="b40755db-f42b-47cf-9e73-57cd092f7bde"/>
|
||||||
|
<textElement>
|
||||||
|
<font fontName="SansSerif

" size="12" isBold="true" isItalic="false"/>
|
||||||
|
</textElement>
|
||||||
|
<text><![CDATA[C4PO]]></text>
|
||||||
|
</staticText>
|
||||||
|
<staticText>
|
||||||
|
<reportElement mode="Transparent" x="23" y="242" width="82" height="20" forecolor="#FEFEFF" backcolor="#151B2E" uuid="1e37e3b3-b3d2-4621-9928-08497bd4f667"/>
|
||||||
|
<textElement>
|
||||||
|
<font fontName="SansSerif

" size="10" isItalic="true"/>
|
||||||
|
</textElement>
|
||||||
|
<text><![CDATA[v.0.0.1]]></text>
|
||||||
|
</staticText>
|
||||||
|
<rectangle>
|
||||||
|
<reportElement x="-20" y="350" width="595" height="30" uuid="e6a81d95-840a-42a8-860d-cb1957d1775c"/>
|
||||||
|
<graphicElement>
|
||||||
|
<pen lineWidth="0.0"/>
|
||||||
|
</graphicElement>
|
||||||
|
</rectangle>
|
||||||
|
</band>
|
||||||
|
</title>
|
||||||
|
<columnHeader>
|
||||||
|
<band height="190" splitType="Stretch">
|
||||||
|
<textField>
|
||||||
|
<reportElement x="107" y="20" width="340" height="40" forecolor="#232B44" uuid="0c2fdc55-5038-49f5-a972-3575837bb8a6"/>
|
||||||
|
<textElement textAlignment="Center" verticalAlignment="Middle">
|
||||||
|
<font size="26" isBold="true"/>
|
||||||
|
</textElement>
|
||||||
|
<textFieldExpression><![CDATA[$R{title.cover_one}]]></textFieldExpression>
|
||||||
|
</textField>
|
||||||
|
<textField>
|
||||||
|
<reportElement x="107" y="61" width="340" height="40" forecolor="#232B44" uuid="edce29e2-8963-43bd-8361-69e579e4a1e1"/>
|
||||||
|
<textElement textAlignment="Center" verticalAlignment="Middle">
|
||||||
|
<font size="26" isBold="true"/>
|
||||||
|
</textElement>
|
||||||
|
<textFieldExpression><![CDATA[$R{title.cover_two}]]></textFieldExpression>
|
||||||
|
</textField>
|
||||||
|
</band>
|
||||||
|
</columnHeader>
|
||||||
|
<detail>
|
||||||
|
<band height="91" splitType="Stretch">
|
||||||
|
<textField>
|
||||||
|
<reportElement x="0" y="10" width="551" height="30" uuid="54c4a617-82ea-4ec4-aa3c-d52e8fd22406"/>
|
||||||
|
<textElement textAlignment="Right">
|
||||||
|
<font fontName="SansSerif" size="20" isBold="true"/>
|
||||||
|
</textElement>
|
||||||
|
<textFieldExpression><![CDATA[$F{tester}]]></textFieldExpression>
|
||||||
|
</textField>
|
||||||
|
<textField>
|
||||||
|
<reportElement x="80" y="50" width="471" height="30" uuid="f13c2ce6-8960-4ac8-ba3a-f79823f07025"/>
|
||||||
|
<textElement textAlignment="Right">
|
||||||
|
<font fontName="SansSerif" size="12" isBold="true" isItalic="true"/>
|
||||||
|
</textElement>
|
||||||
|
<textFieldExpression><![CDATA[(new SimpleDateFormat("dd/MM/yyyy").format($F{createdAt}))]]></textFieldExpression>
|
||||||
|
</textField>
|
||||||
|
</band>
|
||||||
|
</detail>
|
||||||
|
<columnFooter>
|
||||||
|
<band height="76" splitType="Stretch">
|
||||||
|
<rectangle>
|
||||||
|
<reportElement x="-20" y="30" width="595" height="30" forecolor="#232B44" backcolor="#232B44" uuid="1ed47e2d-9d46-44b9-bad7-8eeb1143c83c"/>
|
||||||
|
<graphicElement>
|
||||||
|
<pen lineWidth="1.0"/>
|
||||||
|
</graphicElement>
|
||||||
|
</rectangle>
|
||||||
|
<rectangle>
|
||||||
|
<reportElement x="-20" y="20" width="595" height="10" forecolor="#151B2E" backcolor="#151B2E" uuid="b9a5cd43-3460-4177-97f5-a46eac874e7d"/>
|
||||||
|
</rectangle>
|
||||||
|
<textField>
|
||||||
|
<reportElement x="380" y="35" width="174" height="20" forecolor="#FFFFFF" uuid="0aa9c401-c73c-4a7e-b5a2-b650d333093f"/>
|
||||||
|
<textElement textAlignment="Right" verticalAlignment="Middle">
|
||||||
|
<font size="12" isItalic="true"/>
|
||||||
|
</textElement>
|
||||||
|
<textFieldExpression><![CDATA["Version " + $F{version}]]></textFieldExpression>
|
||||||
|
</textField>
|
||||||
|
</band>
|
||||||
|
</columnFooter>
|
||||||
|
<pageFooter>
|
||||||
|
<band height="10" splitType="Stretch">
|
||||||
|
<rectangle>
|
||||||
|
<reportElement x="-20" y="-10" width="595" height="20" forecolor="#151B2E" backcolor="#151B2E" uuid="724a02c5-82c8-4a72-bf81-b77baa72c723"/>
|
||||||
|
</rectangle>
|
||||||
|
<textField>
|
||||||
|
<reportElement x="-14" y="-7" width="584" height="15" forecolor="#FFFFFF" uuid="32716a0d-4cec-4dc4-b766-f545dea11169"/>
|
||||||
|
<textElement textAlignment="Center" verticalAlignment="Middle">
|
||||||
|
<font size="8" isBold="true"/>
|
||||||
|
</textElement>
|
||||||
|
<textFieldExpression><![CDATA[$R{hint}]]></textFieldExpression>
|
||||||
|
</textField>
|
||||||
|
</band>
|
||||||
|
</pageFooter>
|
||||||
|
</jasperReport>
|
Loading…
Reference in New Issue