diff --git a/security-c4po-angular/src/app/header/header.component.ts b/security-c4po-angular/src/app/header/header.component.ts index bf65160..73aad41 100644 --- a/security-c4po-angular/src/app/header/header.component.ts +++ b/security-c4po-angular/src/app/header/header.component.ts @@ -87,7 +87,6 @@ export class HeaderComponent implements OnInit { if (menuBag.item.icon) { // tslint:disable-next-line:no-string-literal if (menuBag.item.icon['icon'] === this.settingsIcon) { - console.warn('Profile'); this.dialogService.openCustomDialog( ProfileSettingsComponent, { @@ -98,7 +97,7 @@ export class HeaderComponent implements OnInit { untilDestroyed(this) ).subscribe({ next: () => { - console.warn('New Settings confirmed'); + console.info('New Settings confirmed'); } }); } diff --git a/security-c4po-angular/src/assets/i18n/de-DE.json b/security-c4po-angular/src/assets/i18n/de-DE.json index 71510eb..4f8a183 100644 --- a/security-c4po-angular/src/assets/i18n/de-DE.json +++ b/security-c4po-angular/src/assets/i18n/de-DE.json @@ -183,12 +183,12 @@ "title": "Titel", "description": "Beschreibung", "impact": "Auswirkung", - "affectedUrls": "Betroffene URL's", + "affectedUrls": "Betroffene URL's / API's", "reproduction": "Reproduktion", "mitigation": "Minderung", "add": "Fund hinzufügen", - "add.url": "Betroffene URL hinzufügen", - "affectedUrls.placeholder": "Betroffene URL hier eingeben..", + "add.url": "Betroffene URL / API hinzufügen", + "affectedUrls.placeholder": "Betroffene URL oder API hier eingeben..", "create": { "header": "Neuen Fund erstellen" }, diff --git a/security-c4po-angular/src/assets/i18n/en-US.json b/security-c4po-angular/src/assets/i18n/en-US.json index e8dbd0f..e818f97 100644 --- a/security-c4po-angular/src/assets/i18n/en-US.json +++ b/security-c4po-angular/src/assets/i18n/en-US.json @@ -183,12 +183,12 @@ "title": "Title", "description": "Description", "impact": "Impact", - "affectedUrls": "Affected URL's", + "affectedUrls": "Affected URL's / API's", "reproduction": "Reproduction", "mitigation": "Mitigation", "add": "Add finding", - "add.url": "Add affected Url", - "affectedUrls.placeholder": "Enter affected URL here..", + "add.url": "Add affected URL / API", + "affectedUrls.placeholder": "Enter affected URL or API here..", "create": { "header": "Create New Finding" }, diff --git a/security-c4po-angular/src/shared/modules/export-report-dialog/export-report-dialog.component.html b/security-c4po-angular/src/shared/modules/export-report-dialog/export-report-dialog.component.html index cc1e566..b68311d 100644 --- a/security-c4po-angular/src/shared/modules/export-report-dialog/export-report-dialog.component.html +++ b/security-c4po-angular/src/shared/modules/export-report-dialog/export-report-dialog.component.html @@ -13,7 +13,7 @@ -
+
- -
diff --git a/security-c4po-angular/src/shared/modules/export-report-dialog/export-report-dialog.component.scss b/security-c4po-angular/src/shared/modules/export-report-dialog/export-report-dialog.component.scss index 36eda9f..ee7e925 100644 --- a/security-c4po-angular/src/shared/modules/export-report-dialog/export-report-dialog.component.scss +++ b/security-c4po-angular/src/shared/modules/export-report-dialog/export-report-dialog.component.scss @@ -4,13 +4,18 @@ .export-report-dialog { width: 45.25rem !important; - height: 56.25rem; + height: 48.25rem; .export-report-header { height: 8vh; font-size: 1.5rem; } + .objective-chart { + padding-top: 1.5rem; + padding-bottom: 1.5rem; + } + .languageContainer { display: flex; max-width: 8rem; @@ -22,17 +27,19 @@ } } - .hint { - padding-bottom: 0.5rem; - color: nb-theme(color-danger-default); - } - .export-radio-buttons { float: left; clear: none; margin-left: 1rem; } + .hint { + padding-bottom: 0.5rem; + color: nb-theme(color-danger-default); + } + + + nb-form-field { padding: 0.5rem 0 0.75rem; } diff --git a/security-c4po-angular/src/shared/modules/export-report-dialog/export-report-dialog.component.ts b/security-c4po-angular/src/shared/modules/export-report-dialog/export-report-dialog.component.ts index d5e79a0..4c6957e 100644 --- a/security-c4po-angular/src/shared/modules/export-report-dialog/export-report-dialog.component.ts +++ b/security-c4po-angular/src/shared/modules/export-report-dialog/export-report-dialog.component.ts @@ -81,7 +81,6 @@ export class ExportReportDialogComponent implements OnInit { } onClickExport(reportFormat: string, reportLanguage: string): void { - console.warn('ToDo: Use format ', reportFormat); // Get project id from dialog data const projectId = this.dialogData.options[0].additionalData.id; // 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 switch (reportFormat) { case ExportFormatOptions.PDF: { - // @ts-ignore this.downloadPentestReport$ = this.reportingService.getReportPDFforProjectById(projectId, reportLanguage) .pipe( shareReplay(), @@ -112,16 +110,6 @@ export class ExportReportDialogComponent implements OnInit { }); 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: { this.loading$.next(false); this.notificationService.showPopup('report.popup.generation.failed', PopupType.FAILURE); diff --git a/security-c4po-angular/src/shared/modules/profile-settings/profile-settings.component.ts b/security-c4po-angular/src/shared/modules/profile-settings/profile-settings.component.ts index 678244b..d4daffc 100644 --- a/security-c4po-angular/src/shared/modules/profile-settings/profile-settings.component.ts +++ b/security-c4po-angular/src/shared/modules/profile-settings/profile-settings.component.ts @@ -77,7 +77,6 @@ export class ProfileSettingsComponent implements OnInit { this.userNameControl.setValue(user.username); this.userFirstNameControl.setValue(user.firstName); this.userLastNameControl.setValue(user.lastName); - console.warn(this.user.getValue()); }, error: err => { console.error(err); @@ -121,6 +120,9 @@ export class ProfileSettingsComponent implements OnInit { onClickLanguage(language: string): void { 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 { diff --git a/security-c4po-angular/src/shared/pipes/date-time-format.pipe.ts b/security-c4po-angular/src/shared/pipes/date-time-format.pipe.ts index 3355552..405496e 100644 --- a/security-c4po-angular/src/shared/pipes/date-time-format.pipe.ts +++ b/security-c4po-angular/src/shared/pipes/date-time-format.pipe.ts @@ -1,15 +1,16 @@ import {Pipe, PipeTransform} from '@angular/core'; import {formatDate} from '@angular/common'; import {Store} from '@ngxs/store'; -import {SessionState} from '@shared/stores/session-state/session-state'; import {CustomPipe} from '@shared/models/custom-pipe.mode'; +import {TranslateService} from '@ngx-translate/core'; @Pipe({ - name: 'dateTimeFormat' + name: 'dateTimeFormat', + pure: false }) 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 '-'; } - const localeDateAndNumberFormat = this.store.selectSnapshot(SessionState.userAccount) ? - // @ts-ignore - this.store.selectSnapshot(SessionState.userAccount.interfaceLang) : 'en-US'; + const currentLanguage = this.translateService.currentLang; - if (!localeDateAndNumberFormat) { + if (!currentLanguage) { return formatDate(value, CustomPipe.DATE_TIME_FMT_EN, 'en-US'); } - if (localeDateAndNumberFormat === 'de-DE') { - return formatDate(value, CustomPipe.DATE_TIME_FMT_DE, localeDateAndNumberFormat) + ' Uhr'; + if (currentLanguage === 'de-DE') { + return formatDate(value, CustomPipe.DATE_TIME_FMT_DE, currentLanguage) + ' Uhr'; } // @ts-ignore - return formatDate(value, CustomPipe.DATE_TIME_FMT_EN, localeDateAndNumberFormat); + return formatDate(value, CustomPipe.DATE_TIME_FMT_EN, currentLanguage); } - } diff --git a/security-c4po-angular/src/shared/services/dialog-service/dialog.service.ts b/security-c4po-angular/src/shared/services/dialog-service/dialog.service.ts index 0a45a22..a0d6825 100644 --- a/security-c4po-angular/src/shared/services/dialog-service/dialog.service.ts +++ b/security-c4po-angular/src/shared/services/dialog-service/dialog.service.ts @@ -23,7 +23,7 @@ export class DialogService { additionalData: any ): NbDialogRef { return this.dialog.open(componentOrTemplateRef, { - closeOnEsc: false, + closeOnEsc: true, hasScroll: false, autoFocus: true, closeOnBackdropClick: false, diff --git a/security-c4po-angular/src/shared/services/reporting/reporting.service.ts b/security-c4po-angular/src/shared/services/reporting/reporting.service.ts index 863258f..f49a5bd 100644 --- a/security-c4po-angular/src/shared/services/reporting/reporting.service.ts +++ b/security-c4po-angular/src/shared/services/reporting/reporting.service.ts @@ -18,7 +18,6 @@ export class ReportingService { /** * Get PDF Report by project id */ - // ToDo: Add language here public getReportPDFforProjectById(projectId: string, reportLanguage: string): Observable> { return this.http.get(`${this.reportBaseURL}/${projectId}/pdf/${reportLanguage}`, { @@ -29,12 +28,6 @@ export class ReportingService { } ).pipe(loadContent()); } - - /* ToDo: Remove report function without observing report progress - public getReportPDFforProjectById(projectId: string): Observable { - // @ts-ignore - return this.http.get(`${this.reportBaseURL}/${projectId}/pdf`, {responseType: 'arraybuffer'}) - }*/ } export interface ReportDownloadConfiguration { diff --git a/security-c4po-reporting/src/main/kotlin/com/securityc4po/reporting/report/ReportController.kt b/security-c4po-reporting/src/main/kotlin/com/securityc4po/reporting/report/ReportController.kt index 2a015c8..07802fb 100644 --- a/security-c4po-reporting/src/main/kotlin/com/securityc4po/reporting/report/ReportController.kt +++ b/security-c4po-reporting/src/main/kotlin/com/securityc4po/reporting/report/ReportController.kt @@ -1,11 +1,8 @@ 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.extensions.getLoggerFor import com.securityc4po.reporting.remote.APIService -import com.securityc4po.reporting.remote.model.ProjectReport import org.springframework.http.MediaType import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity.notFound @@ -13,7 +10,6 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal import org.springframework.web.bind.annotation.* import reactor.core.publisher.Mono import reactor.kotlin.core.publisher.switchIfEmpty -import java.io.File @RestController @RequestMapping("/reports") @@ -31,7 +27,6 @@ class ReportController(private val apiService: APIService, private val reportSer "/{projectId}/pdf/{reportLanguage}", 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> { return this.apiService.requestProjectReportDataById(projectId, user.token).flatMap {projectReport -> 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(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(jsonProjectReportString) - /* jsonProjectReportCollection */ - } - */ } diff --git a/security-c4po-reporting/src/main/kotlin/com/securityc4po/reporting/report/ReportService.kt b/security-c4po-reporting/src/main/kotlin/com/securityc4po/reporting/report/ReportService.kt index bb9e5b4..af99925 100644 --- a/security-c4po-reporting/src/main/kotlin/com/securityc4po/reporting/report/ReportService.kt +++ b/security-c4po-reporting/src/main/kotlin/com/securityc4po/reporting/report/ReportService.kt @@ -76,19 +76,18 @@ class ReportService { lateinit var severityRatingTablePath: String fun createReport(projectReportCollection: ProjectReport, reportFormat: String, reportLanguage: String): Mono { - logger.info("Use: " + reportLanguage) // Setup PDFMergerUtility val mergedC4POPentestReport: PDFMergerUtility = PDFMergerUtility() // Setup ByteArrayOutputStream for "on the fly" file generation - val pdfDocOutputstream = ByteArrayOutputStream() + val penetstReportOutputstream = ByteArrayOutputStream() // Try to create report files & merge them together return createPentestReportFiles(projectReportCollection, reportFormat, reportLanguage, mergedC4POPentestReport).collectList() .map { // Merge report files - mergedC4POPentestReport.destinationStream = pdfDocOutputstream + mergedC4POPentestReport.destinationStream = penetstReportOutputstream mergedC4POPentestReport.mergeDocuments(MemoryUsageSetting.setupTempFileOnly()) }.flatMap { - return@flatMap Mono.just(pdfDocOutputstream.toByteArray()) + return@flatMap Mono.just(penetstReportOutputstream.toByteArray()) }.doOnError { logger.error("Report generation failed.") } @@ -113,13 +112,13 @@ class ReportService { createAppendencies(reportFormat, resourceBundle) ).map { jasperObject -> if (jasperObject is ByteArray) { - val pdfInputSteam = ByteArrayInputStream(jasperObject) - mergedC4POPentestReport.addSource(pdfInputSteam) + val reportFilesInputSteam = ByteArrayInputStream(jasperObject) + mergedC4POPentestReport.addSource(reportFilesInputSteam) } else if (jasperObject is List<*>) { jasperObject.forEach { jasperFile -> if (jasperFile is ByteArray) { - val pdfInputSteam = ByteArrayInputStream(jasperFile) - mergedC4POPentestReport.addSource(pdfInputSteam) + val reportFilesInputSteam = ByteArrayInputStream(jasperFile) + mergedC4POPentestReport.addSource(reportFilesInputSteam) } } } diff --git a/security-c4po-reporting/src/main/resources/jasper/localization/labels_de.properties b/security-c4po-reporting/src/main/resources/jasper/localization/labels_de.properties index f30474e..148b266 100644 --- a/security-c4po-reporting/src/main/resources/jasper/localization/labels_de.properties +++ b/security-c4po-reporting/src/main/resources/jasper/localization/labels_de.properties @@ -2,6 +2,7 @@ # Cover title.cover_one=Penetrationstest 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 # Table of contents @@ -26,11 +27,11 @@ title.comment=Kommentar: title=Titel: description=Beschreibung: impact=Auswirkung: -reproduction_steps=Reproduktion: +reproduction_steps=Schritte zur Reproduktion: mitigation=Minderung: no_mitigation=Keine Schadensminderung zur Vermeidung, Minimierung oder Kompensation des festgestellten oder erforderlichen Befunds. -affected_urls=Betroffene URL's: -no_affected_urls=Keine spezifischen URLs betroffen. +affected_urls=Betroffene URL's / API's: +no_affected_urls=Keine spezifischen URLs oder API's betroffen. # Appendencies 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. 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: -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_score=Risiko-Score to=bis diff --git a/security-c4po-reporting/src/main/resources/jasper/localization/labels_en.properties b/security-c4po-reporting/src/main/resources/jasper/localization/labels_en.properties index 10fd22f..a1452ca 100644 --- a/security-c4po-reporting/src/main/resources/jasper/localization/labels_en.properties +++ b/security-c4po-reporting/src/main/resources/jasper/localization/labels_en.properties @@ -2,6 +2,7 @@ # Cover title.cover_one=Penetration Test 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 # Table of contents @@ -29,8 +30,8 @@ impact=Impact: reproduction_steps=Reproduction Steps: mitigation=Mitigation: no_mitigation=No mitigation to avoid, minimize or compensate the finding found or needed. -affected_urls=Affected URL's: -no_affected_urls=No specific URL's affected. +affected_urls=Affected URL's / API's: +no_affected_urls=No specific URL's or API's affected. # Appendencies title.appendencies=Appendencies diff --git a/security-c4po-reporting/src/main/resources/jasper/reports/c4po_cover.jrxml b/security-c4po-reporting/src/main/resources/jasper/reports/c4po_cover.jrxml index 1b898bf..aacc727 100644 --- a/security-c4po-reporting/src/main/resources/jasper/reports/c4po_cover.jrxml +++ b/security-c4po-reporting/src/main/resources/jasper/reports/c4po_cover.jrxml @@ -147,7 +147,7 @@ - + @@ -177,7 +177,7 @@ - + diff --git a/security-c4po-reporting/src/main/resources/jasper/reports/test.jrxml b/security-c4po-reporting/src/main/resources/jasper/reports/test.jrxml new file mode 100644 index 0000000..a9078bf --- /dev/null +++ b/security-c4po-reporting/src/main/resources/jasper/reports/test.jrxml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <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> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +