Compare commits

...

1 Commits

Author SHA1 Message Date
Marcel Haag 2e1f96a763 feat: include reporting service in docker-compose 2023-05-03 15:05:48 +02:00
24 changed files with 1017 additions and 643 deletions

View File

@ -14,14 +14,18 @@ ______| |______ |_____ |_____| | \_ __|__ | | _/_/_/ _/
echo "-------------CLEAN UP Container---------------"
echo -e "\n"
docker rm -f c4po-keycloak
#docker rm -f c4po-db ### toggle to clear database with every start ###
#docker rm -f c4po-keycloak ### toggle to clear keycloak with every start ###
#docker rm -f c4po-db ### toggle to clear database with every start ###
docker rm -f c4po-reporting
docker rm -f c4po-api
docker rm -f c4po-angular
echo -e "\n"
echo "-----------------Start Build------------------"
echo -e "\n"
echo " - Report Engine: "
docker-compose -f ${compose} build c4po-reporting
echo -e "\n"
echo " - Backend: "
docker-compose -f ${compose} build c4po-api
echo -e "\n"

View File

@ -107,11 +107,11 @@ export class PentestHeaderComponent implements OnInit, OnDestroy {
next: (pentest: Pentest) => {
this.store.dispatch(new ChangePentest(pentest));
this.initialTimeSpent = pentest.timeSpent;
this.notificationService.showPopup('pentest.popup.complete.success', PopupType.SUCCESS);
this.notificationService.showPopup('pentest.popup.update.success', PopupType.SUCCESS);
},
error: err => {
console.log(err);
this.notificationService.showPopup('pentest.popup.complete.failed', PopupType.FAILURE);
this.notificationService.showPopup('pentest.popup.update.failed', PopupType.FAILURE);
}
});
}

View File

@ -73,7 +73,7 @@ export class UserService {
public redirectToChangePasswordAction(): Promise<void> {
// https://keycloak.discourse.group/t/integrate-change-password-from-account-console-into-own-webapp/12300
return this.keycloakService.login({
action: 'UPDATE_PASSWORD',
action: 'UPDATE_PASSWORD'
});
}

View File

@ -267,6 +267,7 @@
} ],
"security-admin-console" : [ ],
"admin-cli" : [ ],
"security-c4po-reporting" : [ ],
"c4po_local" : [ {
"id" : "e26a27e7-1648-491b-832a-8bf751d378bb",
"name" : "user",
@ -381,7 +382,7 @@
"otpPolicyLookAheadWindow" : 1,
"otpPolicyPeriod" : 30,
"otpPolicyCodeReusable" : false,
"otpSupportedApplications" : [ "totpAppGoogleName", "totpAppFreeOTPName" ],
"otpSupportedApplications" : [ "totpAppFreeOTPName", "totpAppGoogleName" ],
"webAuthnPolicyRpEntityName" : "keycloak",
"webAuthnPolicySignatureAlgorithms" : [ "ES256" ],
"webAuthnPolicyRpId" : "",
@ -815,6 +816,43 @@
"nodeReRegistrationTimeout" : -1,
"defaultClientScopes" : [ "web-origins", "profile", "roles", "email" ],
"optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
}, {
"id" : "a30ec2f6-8dfb-4bae-9b61-fd39d0861a5b",
"clientId" : "security-c4po-reporting",
"name" : "",
"description" : "",
"rootUrl" : "",
"adminUrl" : "",
"baseUrl" : "http://localhost:8444/",
"surrogateAuthRequired" : false,
"enabled" : true,
"alwaysDisplayInConsole" : false,
"clientAuthenticatorType" : "client-secret",
"redirectUris" : [ "http://localhost:8444/*" ],
"webOrigins" : [ "*" ],
"notBefore" : 0,
"bearerOnly" : false,
"consentRequired" : false,
"standardFlowEnabled" : true,
"implicitFlowEnabled" : false,
"directAccessGrantsEnabled" : true,
"serviceAccountsEnabled" : false,
"publicClient" : true,
"frontchannelLogout" : true,
"protocol" : "openid-connect",
"attributes" : {
"oidc.ciba.grant.enabled" : "false",
"backchannel.logout.session.required" : "true",
"post.logout.redirect.uris" : "*",
"oauth2.device.authorization.grant.enabled" : "false",
"display.on.consent.screen" : "false",
"backchannel.logout.revoke.offline.tokens" : "false"
},
"authenticationFlowBindingOverrides" : { },
"fullScopeAllowed" : true,
"nodeReRegistrationTimeout" : -1,
"defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ],
"optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
} ],
"clientScopes" : [ {
"id" : "4b171f57-736a-41b4-b67b-585bac1d8d24",
@ -1324,7 +1362,7 @@
"subType" : "anonymous",
"subComponents" : { },
"config" : {
"allowed-protocol-mapper-types" : [ "oidc-sha256-pairwise-sub-mapper", "oidc-full-name-mapper", "oidc-usermodel-property-mapper", "oidc-address-mapper", "oidc-usermodel-attribute-mapper", "saml-user-attribute-mapper", "saml-role-list-mapper", "saml-user-property-mapper" ]
"allowed-protocol-mapper-types" : [ "oidc-full-name-mapper", "saml-role-list-mapper", "oidc-address-mapper", "saml-user-attribute-mapper", "saml-user-property-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper" ]
}
}, {
"id" : "cc2d0cd7-3d3f-4b0a-ad95-7118f36bf188",
@ -1356,7 +1394,7 @@
"subType" : "authenticated",
"subComponents" : { },
"config" : {
"allowed-protocol-mapper-types" : [ "oidc-usermodel-attribute-mapper", "oidc-usermodel-property-mapper", "saml-user-property-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-full-name-mapper", "saml-user-attribute-mapper", "oidc-address-mapper", "saml-role-list-mapper" ]
"allowed-protocol-mapper-types" : [ "oidc-sha256-pairwise-sub-mapper", "saml-user-attribute-mapper", "oidc-usermodel-property-mapper", "saml-role-list-mapper", "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "oidc-full-name-mapper", "saml-user-property-mapper" ]
}
}, {
"id" : "92230e65-7480-44c3-af2d-72ddee758cbc",
@ -1412,7 +1450,7 @@
"supportedLocales" : [ "de", "en" ],
"defaultLocale" : "en",
"authenticationFlows" : [ {
"id" : "0296b89f-2d7b-4931-b4ce-72167e83d8b7",
"id" : "bb40c574-9008-47b8-bdce-950f92219366",
"alias" : "Account verification options",
"description" : "Method with which to verity the existing account",
"providerId" : "basic-flow",
@ -1434,7 +1472,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "64a2976c-5625-41a2-97d7-b53e78cc3a92",
"id" : "52866cca-eea7-4e24-ae8a-3e9d3cc10240",
"alias" : "Authentication Options",
"description" : "Authentication options.",
"providerId" : "basic-flow",
@ -1463,7 +1501,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "23dce318-8864-429d-8e42-8f60adf87bb8",
"id" : "04f6c37f-e60c-41a4-a8f1-b09e3c3c791f",
"alias" : "Browser - Conditional OTP",
"description" : "Flow to determine if the OTP is required for the authentication",
"providerId" : "basic-flow",
@ -1485,7 +1523,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "07c663a3-9361-4fb1-ac6f-6af140b9d8b5",
"id" : "aac0d9a0-7ff3-4a3f-87f5-4a0f8dc4169c",
"alias" : "Direct Grant - Conditional OTP",
"description" : "Flow to determine if the OTP is required for the authentication",
"providerId" : "basic-flow",
@ -1507,7 +1545,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "8a797183-07fc-44a1-80a5-bfa6b4d727e1",
"id" : "a5103f9c-2ead-46d2-90dc-b93c8fad52de",
"alias" : "First broker login - Conditional OTP",
"description" : "Flow to determine if the OTP is required for the authentication",
"providerId" : "basic-flow",
@ -1529,7 +1567,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "98e3631a-0ff2-4528-b835-4836d755b430",
"id" : "7f2db66f-d81b-475a-aac0-860d2dff10b0",
"alias" : "Handle Existing Account",
"description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider",
"providerId" : "basic-flow",
@ -1551,7 +1589,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "849a9f5a-0389-4de4-8da7-9561a1e266e8",
"id" : "5db5c83a-6ff7-41e7-97dd-dc896e7ed538",
"alias" : "Reset - Conditional OTP",
"description" : "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.",
"providerId" : "basic-flow",
@ -1573,7 +1611,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "e196e161-37ce-4616-be7f-b1742c4f7453",
"id" : "cea2f466-e748-4eec-8184-57620f9b6e19",
"alias" : "User creation or linking",
"description" : "Flow for the existing/non-existing user alternatives",
"providerId" : "basic-flow",
@ -1596,7 +1634,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "ab6e417d-91a9-4a2e-a288-230b30ed2608",
"id" : "196ae0cd-faa3-45ed-9f94-5efabeda99b1",
"alias" : "Verify Existing Account by Re-authentication",
"description" : "Reauthentication of existing account",
"providerId" : "basic-flow",
@ -1618,7 +1656,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "ed177a27-8acf-46c9-aecd-66a9de099b71",
"id" : "f26d09df-6c71-469f-a4d3-e97259b0d738",
"alias" : "browser",
"description" : "browser based authentication",
"providerId" : "basic-flow",
@ -1654,7 +1692,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "7e14a81b-508b-4a78-aeca-c783e209209d",
"id" : "57839527-0e6b-491e-9509-64759543dc06",
"alias" : "clients",
"description" : "Base authentication for clients",
"providerId" : "client-flow",
@ -1690,7 +1728,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "6e52e23e-d83f-46c2-bc4d-e336999e2293",
"id" : "4932ffe5-396c-4f34-a667-eda30f382396",
"alias" : "direct grant",
"description" : "OpenID Connect Resource Owner Grant",
"providerId" : "basic-flow",
@ -1719,7 +1757,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "6d476080-ebc3-4bce-90ac-93afc891a83e",
"id" : "35410931-d63c-45fe-aa5c-b89b9ecbd803",
"alias" : "docker auth",
"description" : "Used by Docker clients to authenticate against the IDP",
"providerId" : "basic-flow",
@ -1734,7 +1772,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "1143f6ea-867a-4b08-974e-86a4b9ba8601",
"id" : "40dbf210-48b5-4e51-bf2e-88eab2b7a9cb",
"alias" : "first broker login",
"description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
"providerId" : "basic-flow",
@ -1757,7 +1795,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "2090f383-dcab-441c-9f37-5b37504a1692",
"id" : "9420c3e7-92b9-4332-a10c-9614041390a9",
"alias" : "forms",
"description" : "Username, password, otp and other auth forms.",
"providerId" : "basic-flow",
@ -1779,7 +1817,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "13395ad8-a0eb-42f4-9d9d-c715c717d181",
"id" : "e87c0fc3-710d-447a-88de-966eb4b53178",
"alias" : "http challenge",
"description" : "An authentication flow based on challenge-response HTTP Authentication Schemes",
"providerId" : "basic-flow",
@ -1801,7 +1839,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "a656e7fc-fa52-46e3-9fc1-654cafe37087",
"id" : "b58bb0f2-c1aa-4a5a-9c18-f7f0b6951bb9",
"alias" : "registration",
"description" : "registration flow",
"providerId" : "basic-flow",
@ -1817,7 +1855,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "84e1ffa9-3dd8-4b32-8cd9-e4bbc4631624",
"id" : "fa3cdbb3-9d7a-40a6-a76c-d8fc4de447db",
"alias" : "registration form",
"description" : "registration form",
"providerId" : "form-flow",
@ -1853,7 +1891,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "68dad811-63ec-484a-a0b9-9656edc6921e",
"id" : "228942b7-863d-4ae7-8a03-f479e99563da",
"alias" : "reset credentials",
"description" : "Reset credentials for a user if they forgot their password or something",
"providerId" : "basic-flow",
@ -1889,7 +1927,7 @@
"userSetupAllowed" : false
} ]
}, {
"id" : "9a212f2d-80ae-4051-9d09-28d016809204",
"id" : "ea9b4826-ba5d-4753-be46-9aa3c4b9d543",
"alias" : "saml ecp",
"description" : "SAML ECP Profile Authentication Flow",
"providerId" : "basic-flow",
@ -1905,13 +1943,13 @@
} ]
} ],
"authenticatorConfig" : [ {
"id" : "9e437782-7c8f-4732-a1e6-cd84abdf78e3",
"id" : "2f53b30a-881f-4407-8ffa-ea9540896bea",
"alias" : "create unique user config",
"config" : {
"require.password.update.after.registration" : "false"
}
}, {
"id" : "8d01fb5d-be3d-42d9-ae27-592fab7d8d14",
"id" : "25c05d4a-ea77-4eb2-9fe4-93ebe228d10f",
"alias" : "review profile config",
"config" : {
"update.profile.on.first.login" : "missing"

File diff suppressed because it is too large Load Diff

View File

@ -64,6 +64,22 @@ services:
- 8443:8443
networks:
- c4po
c4po-reporting:
build: '../security-c4po-reporting'
image: security-c4po-reporting:latest
container_name: c4po-reporting
environment:
- SPRING_PROFILES_ACTIVE=COMPOSE
depends_on:
- c4po-keycloak
deploy:
resources:
limits:
memory: "4G"
ports:
- 8444:8444
networks:
- c4po
networks:
c4po:

View File

@ -15,6 +15,7 @@ COPY ./build/libs/security-c4po-reporting-0.0.1-SNAPSHOT.jar /
USER security-c4po-reporting
EXPOSE 8444
# RUN JAVA
# WAIT FOR KEYCLOAK & RUN JAVA
COPY ./wait-for-keycloak.sh /
# CMD [ "java", "-jar", "security-c4po-reporting-0.0.1-SNAPSHOT.jar" ]
ENTRYPOINT [ "java", "-jar", "-Dspring.profiles.active=${ENV_STAGE}", "security-c4po-reporting-0.0.1-SNAPSHOT.jar" ]
ENTRYPOINT [ "./wait-for-keycloak.sh", "http://c4po-keycloak:8080/auth/realms/c4po_realm_local", "java", "-Dspring.profiles.active=${SPRING_PROFILES_ACTIVE}", "-jar", "security-c4po-reporting-0.0.1-SNAPSHOT.jar" ]

View File

@ -62,7 +62,7 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("org.springframework.boot:spring-boot-starter-actuator")
// Security
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server")

View File

@ -37,8 +37,6 @@ class ReportController(private val apiService: APIService, private val reportSer
ResponseEntity.ok().body(reportClassLoaderFilePath)
}.switchIfEmpty {
Mono.just(notFound().build<ByteArray>())
}.doOnSuccess {
this.reportService.cleanUpFiles()
}
}
}

View File

@ -2,19 +2,15 @@ package com.securityc4po.reporting.report
import com.securityc4po.reporting.extensions.getLoggerFor
import com.securityc4po.reporting.remote.model.*
import com.securityc4po.reporting.remote.model.api.Comment
import com.securityc4po.reporting.remote.model.api.Finding
import net.sf.jasperreports.engine.*
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource
import org.apache.commons.io.FileUtils
import org.apache.pdfbox.io.MemoryUsageSetting
import org.apache.pdfbox.multipdf.PDFMergerUtility
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service
import org.springframework.util.ResourceUtils
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.*
@Service
@ -26,59 +22,68 @@ class ReportService {
var logger = getLoggerFor<ReportService>()
private val reportCoverDesignTemplate = "./src/main/resources/jasper/reports/c4po_cover.jrxml"
private val reportContentDesignTemplate = "./src/main/resources/jasper/reports/c4po_content.jrxml"
private val reportStateOfConfidentialityDesignTemplate =
"./src/main/resources/jasper/reports/c4po_state_of_confidentiality.jrxml"
private val reportExecutiveSummaryDesignTemplate =
"./src/main/resources/jasper/reports/c4po_executive_summary.jrxml"
private val reportPentestsFindingsAndCommentsDesignTemplate = "./src/main/resources/jasper/reports/c4po_pentests_findings_and_comments.jrxml"
private val reportPentestsFindingsOnlyDesignTemplate = "./src/main/resources/jasper/reports/c4po_pentests_findings_only.jrxml"
private val reportPentestsCommentsOnlyDesignTemplate = "./src/main/resources/jasper/reports/c4po_pentests_comments_only.jrxml"
private val reportAppendenciesDesignTemplate = "./src/main/resources/jasper/reports/c4po_appendencies.jrxml"
// Jasper Design template file Paths
@Value("\${reportCoverDesignTemplate}")
lateinit var reportCoverDesignTemplate: String
@Value("\${reportContentDesignTemplate}")
lateinit var reportContentDesignTemplate: String
@Value("\${reportStateOfConfidentialityDesignTemplate}")
lateinit var reportStateOfConfidentialityDesignTemplate: String
@Value("\${reportExecutiveSummaryDesignTemplate}")
lateinit var reportExecutiveSummaryDesignTemplate: String
@Value("\${reportPentestsFindingsAndCommentsDesignTemplate}")
lateinit var reportPentestsFindingsAndCommentsDesignTemplate: String
@Value("\${reportPentestsFindingsOnlyDesignTemplate}")
lateinit var reportPentestsFindingsOnlyDesignTemplate: String
@Value("\${reportPentestsCommentsOnlyDesignTemplate}")
lateinit var reportPentestsCommentsOnlyDesignTemplate: String
@Value("\${reportAppendenciesDesignTemplate}")
lateinit var reportAppendenciesDesignTemplate: String
// Path to default pdf file
private val reportDefaultPdf = "./src/main/resources/jasper/DEFAULT.pdf"
@Value("\${reportDefaultPdf}")
lateinit var reportDefaultPdfPropertyPath: String
// Path where the created Reports are saved
private val reportDestination = "./src/main/resources/jasper/reportPDFs/"
// Image paths
@Value("\${CDATA_WATERMARK}")
lateinit var waterMarkPath: String
// Path where the completed Report is saved
private val reportFileDestination = "./src/main/resources/jasper/finalReport/"
@Value("\${CDATA_C4POCoverBackground}")
lateinit var coverBackgroundPath: String
// Path where the completed Report can be found by class loader
private val reportFileForClassLoader = "/jasper/finalReport/"
// Subreport paths
@Value("\${CDATA_FindingsSubreport}")
lateinit var findingsSubreportPath: String
@Value("\${CDATA_CommentsSubreport}")
lateinit var commentsSubreportPath: String
@Value("\${CDATA_SeverityRatingTable}")
lateinit var severityRatingTablePath: String
fun createReport(projectReportCollection: ProjectReport, reportFormat: String): Mono<ByteArray> {
// Setup Filepath destination
val reportFilePathDestination: String =
reportFileDestination + projectReportCollection.title.replace(" ", "_") + "_report.pdf"
// Setup PDFMergerUtility
val mergedC4POPentestReport: PDFMergerUtility = PDFMergerUtility()
// Setup ByteArrayOutputStream for "on the fly" file generation
val pdfDocOutputstream = ByteArrayOutputStream()
// Try to create report files & merge them together
return createPentestReportFiles(projectReportCollection, reportFormat, mergedC4POPentestReport).collectList().map {
// Merge report files
mergedC4POPentestReport.destinationFileName = reportFilePathDestination
mergedC4POPentestReport.destinationStream = pdfDocOutputstream
mergedC4POPentestReport.mergeDocuments(MemoryUsageSetting.setupTempFileOnly())
}.flatMap {
return@flatMap Mono.just(pdfDocOutputstream.toByteArray())
}.doOnError {
logger.error("Report generation failed.")
}
}
fun cleanUpFiles() {
val cleanUpDirectoryReportsPath = "./src/main/resources/jasper/reportPDFs"
val cleanUpDirectoryCompletedReportsPath = "./src/main/resources/jasper/finalReport"
try {
FileUtils.cleanDirectory(File(cleanUpDirectoryReportsPath))
FileUtils.cleanDirectory(File(cleanUpDirectoryCompletedReportsPath))
} catch (e: Exception) {
logger.error("Report file cleanup failed with exception: ", e)
}
return createPentestReportFiles(projectReportCollection, reportFormat, mergedC4POPentestReport).collectList()
.map {
// Merge report files
mergedC4POPentestReport.destinationStream = pdfDocOutputstream
mergedC4POPentestReport.mergeDocuments(MemoryUsageSetting.setupTempFileOnly())
}.flatMap {
return@flatMap Mono.just(pdfDocOutputstream.toByteArray())
}.doOnError {
logger.error("Report generation failed.")
}
}
private fun createPentestReportFiles(
@ -87,7 +92,7 @@ class ReportService {
mergedC4POPentestReport: PDFMergerUtility
): Flux<Unit> {
return Flux.just(
// Create report files
// Create byte arrays of report files
createCover(projectReportCollection, reportFormat),
createTableOfContent(projectReportCollection, reportFormat),
createStateOfConfidentiality(projectReportCollection, reportFormat),
@ -95,298 +100,358 @@ class ReportService {
createPentestReports(projectReportCollection, reportFormat),
createAppendencies(reportFormat)
).map { jasperObject ->
if (jasperObject is File) {
mergedC4POPentestReport.addSource(jasperObject)
if (jasperObject is ByteArray) {
val pdfInputSteam = ByteArrayInputStream(jasperObject)
mergedC4POPentestReport.addSource(pdfInputSteam)
} else if (jasperObject is List<*>) {
jasperObject.forEach { jasperFile ->
if (jasperFile is File) {
mergedC4POPentestReport.addSource(jasperFile)
if (jasperFile is ByteArray) {
val pdfInputSteam = ByteArrayInputStream(jasperFile)
mergedC4POPentestReport.addSource(pdfInputSteam)
}
}
}
}
}
private fun createCover(projectReportCollection: ProjectReport, reportFormat: String): File {
private fun createCover(projectReportCollection: ProjectReport, reportFormat: String): ByteArray {
// Load Jasper Files
val fileCover: File = ResourceUtils.getFile(reportCoverDesignTemplate)
// Compile Jasper Reports
val jasperReportCover: JasperReport = JasperCompileManager.compileReport(fileCover.absolutePath)
// Setup Main Datasource
val dataSource: JRBeanCollectionDataSource = JRBeanCollectionDataSource(mutableListOf(projectReportCollection))
// Setup Parameter & add Sub-datasets
val parameters = HashMap<String, Any>()
// Fill Reports
val jasperPrintCover: JasperPrint = JasperFillManager.fillReport(jasperReportCover, parameters, dataSource)
// Create File
var finalFile: File = File(reportDefaultPdf)
return if (reportFormat.equals("pdf")) {
JasperExportManager.exportReportToPdfFile(jasperPrintCover, reportDestination + "A_Cover.pdf")
finalFile = File(reportDestination + "A_Cover.pdf")
finalFile
} else {
// ToDo: Implement different report formats
finalFile
val fileCoverStream = javaClass.getResourceAsStream(reportCoverDesignTemplate)
// Open file stream
fileCoverStream.use { stream ->
val inputStream = ByteArrayInputStream(stream.readAllBytes())
// Compile Jasper Reports
val jasperReportCover: JasperReport = JasperCompileManager.compileReport(inputStream)
// Setup Main Datasource
val dataSource: JRBeanCollectionDataSource =
JRBeanCollectionDataSource(mutableListOf(projectReportCollection))
// Setup Parameter & add Sub-datasets
val parameters = HashMap<String, Any>()
parameters["CDATA_WATERMARK"] = waterMarkPath
parameters["CDATA_C4POCoverBackground"] = coverBackgroundPath
// Fill Reports
val jasperPrintCover: JasperPrint = JasperFillManager.fillReport(jasperReportCover, parameters, dataSource)
// Create File
var finalFile: ByteArray = javaClass.getResourceAsStream(reportDefaultPdfPropertyPath).readAllBytes()
// Export Report
return if (reportFormat.equals("pdf")) {
finalFile = JasperExportManager.exportReportToPdf(jasperPrintCover)
finalFile
} else {
// ToDo: Implement different report formats
finalFile
}
}
}
private fun createTableOfContent(projectReportCollection: ProjectReport, reportFormat: String): File {
private fun createTableOfContent(projectReportCollection: ProjectReport, reportFormat: String): ByteArray {
// Load Jasper Files
val fileContent: File = ResourceUtils.getFile(reportContentDesignTemplate)
// Compile Jasper Reports
val jasperReportContent: JasperReport = JasperCompileManager.compileReport(fileContent.absolutePath)
// Setup Sub-dataset for Table of Content generation
val projectPentestReportDataSource: JRBeanCollectionDataSource =
JRBeanCollectionDataSource(projectReportCollection.projectPentestReport)
// Setup Parameter & add Sub-datasets
val parameters = HashMap<String, Any>()
parameters["ProjectPentestReportDataSource"] = projectPentestReportDataSource
// Fill Reports
val jasperPrintContent: JasperPrint =
JasperFillManager.fillReport(jasperReportContent, parameters, JREmptyDataSource())
// Create File
var finalFile: File = File(reportDefaultPdf)
return if (reportFormat.equals("pdf")) {
JasperExportManager.exportReportToPdfFile(jasperPrintContent, reportDestination + "B_Content.pdf")
finalFile = File(reportDestination + "B_Content.pdf")
finalFile
} else {
// ToDo: Implement different report formats
finalFile
val fileContentStream = javaClass.getResourceAsStream(reportContentDesignTemplate)
// Open file stream
fileContentStream.use { stream ->
val inputStream = ByteArrayInputStream(stream.readAllBytes())
// Compile Jasper Reports
val jasperReportContent: JasperReport = JasperCompileManager.compileReport(inputStream)
// Setup Sub-dataset for Table of Content generation
val projectPentestReportDataSource: JRBeanCollectionDataSource =
JRBeanCollectionDataSource(projectReportCollection.projectPentestReport)
// Setup Parameter & add Sub-datasets
val parameters = HashMap<String, Any>()
parameters["ProjectPentestReportDataSource"] = projectPentestReportDataSource
parameters["CDATA_WATERMARK"] = waterMarkPath
// Fill Reports
val jasperPrintContent: JasperPrint =
JasperFillManager.fillReport(jasperReportContent, parameters, JREmptyDataSource())
// Create File
var finalFile: ByteArray = javaClass.getResourceAsStream(reportDefaultPdfPropertyPath).readAllBytes()
// Export Report
return if (reportFormat.equals("pdf")) {
finalFile = JasperExportManager.exportReportToPdf(jasperPrintContent)
finalFile
} else {
// ToDo: Implement different report formats
finalFile
}
}
}
private fun createStateOfConfidentiality(projectReportCollection: ProjectReport, reportFormat: String): File {
private fun createStateOfConfidentiality(projectReportCollection: ProjectReport, reportFormat: String): ByteArray {
// Load Jasper Files
val fileContent: File = ResourceUtils.getFile(reportStateOfConfidentialityDesignTemplate)
// Compile Jasper Reports
val jasperReportContent: JasperReport = JasperCompileManager.compileReport(fileContent.absolutePath)
// Setup Main Datasource
val dataSource: JRBeanCollectionDataSource = JRBeanCollectionDataSource(mutableListOf(projectReportCollection))
// Setup Parameter & add Sub-datasets
val parameters = HashMap<String, Any>()
// Fill Reports
val jasperPrintContent: JasperPrint = JasperFillManager.fillReport(jasperReportContent, parameters, dataSource)
// Create File
var finalFile: File = File(reportDefaultPdf)
return if (reportFormat.equals("pdf")) {
JasperExportManager.exportReportToPdfFile(
jasperPrintContent,
reportDestination + "C_StateOfConfidentiality.pdf"
val fileStateOfConfidentialityStream = javaClass.getResourceAsStream(reportStateOfConfidentialityDesignTemplate)
// Open file stream
fileStateOfConfidentialityStream.use { stream ->
val inputStream = ByteArrayInputStream(stream.readAllBytes())
// Compile Jasper Reports
val jasperReportContent: JasperReport = JasperCompileManager.compileReport(inputStream)
// Setup Main Datasource
val dataSource: JRBeanCollectionDataSource =
JRBeanCollectionDataSource(mutableListOf(projectReportCollection))
// Setup Parameter & add Sub-datasets
val parameters = HashMap<String, Any>()
parameters["CDATA_WATERMARK"] = waterMarkPath
// Fill Reports
val jasperPrintStateOfConfidentiality: JasperPrint =
JasperFillManager.fillReport(jasperReportContent, parameters, dataSource)
// Create File
var finalFile: ByteArray = javaClass.getResourceAsStream(reportDefaultPdfPropertyPath).readAllBytes()
return if (reportFormat.equals("pdf")) {
finalFile = JasperExportManager.exportReportToPdf(jasperPrintStateOfConfidentiality)
finalFile
} else {
// ToDo: Implement different report formats
finalFile
}
}
}
private fun createExecutiveSummary(projectReportCollection: ProjectReport, reportFormat: String): ByteArray {
// Load Jasper Files
val fileExecutiveSummaryStream = javaClass.getResourceAsStream(reportExecutiveSummaryDesignTemplate)
// Open file stream
fileExecutiveSummaryStream.use { stream ->
val inputStream = ByteArrayInputStream(stream.readAllBytes())
// Compile Jasper Reports
val jasperReportContent: JasperReport = JasperCompileManager.compileReport(inputStream)
// Setup Main Datasource
val dataSource: JRBeanCollectionDataSource =
JRBeanCollectionDataSource(mutableListOf(projectReportCollection))
// Setup Sub-dataset for pentest evaluation pie charts
// Setup CategoryPieDataSet for each Category
val categoryFindings: MutableList<CategoryPieData> = mutableListOf<CategoryPieData>(
CategoryPieData("INFORMATION_GATHERING", 0),
CategoryPieData("CONFIGURATION_AND_DEPLOY_MANAGEMENT_TESTING", 0),
CategoryPieData("IDENTITY_MANAGEMENT_TESTING", 0),
CategoryPieData("AUTHENTICATION_TESTING", 0),
CategoryPieData("AUTHORIZATION_TESTING", 0),
CategoryPieData("SESSION_MANAGEMENT_TESTING", 0),
CategoryPieData("INPUT_VALIDATION_TESTING", 0),
CategoryPieData("ERROR_HANDLING", 0),
CategoryPieData("CRYPTOGRAPHY", 0),
CategoryPieData("BUSINESS_LOGIC_TESTING", 0),
CategoryPieData("CLIENT_SIDE_TESTING", 0)
)
finalFile = File(reportDestination + "C_StateOfConfidentiality.pdf")
finalFile
} else {
// ToDo: Implement different report formats
finalFile
}
}
private fun createExecutiveSummary(projectReportCollection: ProjectReport, reportFormat: String): File {
// Load Jasper Files
val fileContent: File = ResourceUtils.getFile(reportExecutiveSummaryDesignTemplate)
// Compile Jasper Reports
val jasperReportContent: JasperReport = JasperCompileManager.compileReport(fileContent.absolutePath)
// Setup Main Datasource
val dataSource: JRBeanCollectionDataSource = JRBeanCollectionDataSource(mutableListOf(projectReportCollection))
// Setup Sub-dataset for pentest evaluation pie charts
// Setup CategoryPieDataSet for each Category
val categoryFindings: MutableList<CategoryPieData> = mutableListOf<CategoryPieData>(
CategoryPieData("INFORMATION_GATHERING", 0),
CategoryPieData("CONFIGURATION_AND_DEPLOY_MANAGEMENT_TESTING", 0),
CategoryPieData("IDENTITY_MANAGEMENT_TESTING", 0),
CategoryPieData("AUTHENTICATION_TESTING", 0),
CategoryPieData("AUTHORIZATION_TESTING", 0),
CategoryPieData("SESSION_MANAGEMENT_TESTING", 0),
CategoryPieData("INPUT_VALIDATION_TESTING", 0),
CategoryPieData("ERROR_HANDLING", 0),
CategoryPieData("CRYPTOGRAPHY", 0),
CategoryPieData("BUSINESS_LOGIC_TESTING", 0),
CategoryPieData("CLIENT_SIDE_TESTING", 0)
)
// Fill data for CategoryPieDataSet
for (i in 0 until projectReportCollection.projectPentestReport.size) {
when (projectReportCollection.projectPentestReport[i].category) {
"INFORMATION_GATHERING" -> {
categoryFindings[0].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
}
"CONFIGURATION_AND_DEPLOY_MANAGEMENT_TESTING" -> {
categoryFindings[1].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
}
"IDENTITY_MANAGEMENT_TESTING" -> {
categoryFindings[2].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
}
"AUTHENTICATION_TESTING" -> {
categoryFindings[3].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
}
"AUTHORIZATION_TESTING" -> {
categoryFindings[4].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
}
"SESSION_MANAGEMENT_TESTING" -> {
categoryFindings[5].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
}
"INPUT_VALIDATION_TESTING" -> {
categoryFindings[6].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
}
"ERROR_HANDLING" -> {
categoryFindings[7].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
}
"CRYPTOGRAPHY" -> {
categoryFindings[8].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
}
"BUSINESS_LOGIC_TESTING" -> {
categoryFindings[9].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size - 1
}
"CLIENT_SIDE_TESTING" -> {
categoryFindings[10].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size - 1
}
else -> {
categoryFindings.add(
CategoryPieData(
"UNKNOWN_CATEGORY",
projectReportCollection.projectPentestReport[i].findings.size
)
)
}
}
}
val categoryFindingsDataSource: JRBeanCollectionDataSource = JRBeanCollectionDataSource(categoryFindings)
// Setup SeverityPieData for each Severity
val severityFindings: MutableList<SeverityPieData> = mutableListOf<SeverityPieData>(
SeverityPieData("LOW", 0),
SeverityPieData("MEDIUM", 0),
SeverityPieData("HIGH", 0),
SeverityPieData("CRITICAL", 0)
)
// Fill data for SeverityPieData
for (i in 0 until projectReportCollection.projectPentestReport.size) {
for (j in 0 until projectReportCollection.projectPentestReport[i].findings.size) {
when (projectReportCollection.projectPentestReport[i].findings[j].severity) {
"LOW" -> {
severityFindings[0].numberOfFindings += 1
// Fill data for CategoryPieDataSet
for (i in 0 until projectReportCollection.projectPentestReport.size) {
when (projectReportCollection.projectPentestReport[i].category) {
"INFORMATION_GATHERING" -> {
categoryFindings[0].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
}
"MEDIUM" -> {
severityFindings[1].numberOfFindings += 1
"CONFIGURATION_AND_DEPLOY_MANAGEMENT_TESTING" -> {
categoryFindings[1].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
}
"HIGH" -> {
severityFindings[2].numberOfFindings += 1
"IDENTITY_MANAGEMENT_TESTING" -> {
categoryFindings[2].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
}
"CRITICAL" -> {
severityFindings[3].numberOfFindings += 1
"AUTHENTICATION_TESTING" -> {
categoryFindings[3].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
}
"AUTHORIZATION_TESTING" -> {
categoryFindings[4].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
}
"SESSION_MANAGEMENT_TESTING" -> {
categoryFindings[5].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
}
"INPUT_VALIDATION_TESTING" -> {
categoryFindings[6].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
}
"ERROR_HANDLING" -> {
categoryFindings[7].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
}
"CRYPTOGRAPHY" -> {
categoryFindings[8].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
}
"BUSINESS_LOGIC_TESTING" -> {
categoryFindings[9].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size - 1
}
"CLIENT_SIDE_TESTING" -> {
categoryFindings[10].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size - 1
}
else -> {
severityFindings.add(
SeverityPieData(
"UNKNOWN_SEVERITY",
categoryFindings.add(
CategoryPieData(
"UNKNOWN_CATEGORY",
projectReportCollection.projectPentestReport[i].findings.size
)
)
}
}
}
}
val severityFindingsDataSource: JRBeanCollectionDataSource = JRBeanCollectionDataSource(severityFindings)
// Setup Parameter & add Sub-datasets
val parameters = HashMap<String, Any>()
parameters["CategoryFindingsPieChartDataSource"] = categoryFindingsDataSource
parameters["SeverityFindingsPieChartDataSource"] = severityFindingsDataSource
// Fill Reports
val jasperPrintContent: JasperPrint = JasperFillManager.fillReport(jasperReportContent, parameters, dataSource)
// Create File
var finalFile: File = File(reportDefaultPdf)
return if (reportFormat.equals("pdf")) {
JasperExportManager.exportReportToPdfFile(jasperPrintContent, reportDestination + "D_ExecutiveSummary.pdf")
finalFile = File(reportDestination + "D_ExecutiveSummary.pdf")
finalFile
} else {
// ToDo: Implement different report formats
finalFile
val categoryFindingsDataSource: JRBeanCollectionDataSource = JRBeanCollectionDataSource(categoryFindings)
// Setup SeverityPieData for each Severity
val severityFindings: MutableList<SeverityPieData> = mutableListOf<SeverityPieData>(
SeverityPieData("LOW", 0),
SeverityPieData("MEDIUM", 0),
SeverityPieData("HIGH", 0),
SeverityPieData("CRITICAL", 0)
)
// Fill data for SeverityPieData
for (i in 0 until projectReportCollection.projectPentestReport.size) {
for (j in 0 until projectReportCollection.projectPentestReport[i].findings.size) {
when (projectReportCollection.projectPentestReport[i].findings[j].severity) {
"LOW" -> {
severityFindings[0].numberOfFindings += 1
}
"MEDIUM" -> {
severityFindings[1].numberOfFindings += 1
}
"HIGH" -> {
severityFindings[2].numberOfFindings += 1
}
"CRITICAL" -> {
severityFindings[3].numberOfFindings += 1
}
else -> {
severityFindings.add(
SeverityPieData(
"UNKNOWN_SEVERITY",
projectReportCollection.projectPentestReport[i].findings.size
)
)
}
}
}
}
val severityFindingsDataSource: JRBeanCollectionDataSource = JRBeanCollectionDataSource(severityFindings)
// Setup Parameter & add Sub-datasets
val parameters = HashMap<String, Any>()
parameters["CategoryFindingsPieChartDataSource"] = categoryFindingsDataSource
parameters["SeverityFindingsPieChartDataSource"] = severityFindingsDataSource
parameters["CDATA_WATERMARK"] = waterMarkPath
// Fill Reports
val jasperPrintExecutiveSummary: JasperPrint =
JasperFillManager.fillReport(jasperReportContent, parameters, dataSource)
// Create File
var finalFile: ByteArray = javaClass.getResourceAsStream(reportDefaultPdfPropertyPath).readAllBytes()
return if (reportFormat.equals("pdf")) {
finalFile = JasperExportManager.exportReportToPdf(jasperPrintExecutiveSummary)
finalFile
} else {
// ToDo: Implement different report formats
finalFile
}
}
}
private fun createPentestReports(projectReportCollection: ProjectReport, reportFormat: String): List<File> {
private fun createPentestReports(projectReportCollection: ProjectReport, reportFormat: String): List<ByteArray> {
// Create List of Files
var finalFiles: List<File> = emptyList()
var finalFiles: List<ByteArray> = emptyList()
// Load Jasper Files
val filePentestsFindingsAndComments: File = ResourceUtils.getFile(reportPentestsFindingsAndCommentsDesignTemplate)
val filePentestsFindingsOnly: File = ResourceUtils.getFile(reportPentestsFindingsOnlyDesignTemplate)
val filePentestsCommentsOnly: File = ResourceUtils.getFile(reportPentestsCommentsOnlyDesignTemplate)
// Compile Jasper Reports
val jasperReportPentestsFindingsAndComments: JasperReport = JasperCompileManager.compileReport(filePentestsFindingsAndComments.absolutePath)
val jasperReportPentestsFindingsOnly: JasperReport = JasperCompileManager.compileReport(filePentestsFindingsOnly.absolutePath)
val jasperReportPentestsCommentsOnly: JasperReport = JasperCompileManager.compileReport(filePentestsCommentsOnly.absolutePath)
// Create pentestReport content for every objective
for (i in 0 until projectReportCollection.projectPentestReport.size) {
val projectSinglePentestReportDataSource: JRBeanCollectionDataSource =
JRBeanCollectionDataSource(mutableListOf(projectReportCollection.projectPentestReport[i]))
// Setup Parameter & add Sub-datasets
val parameters = HashMap<String, Any>()
// Setup Sub-dataset for Findings of Pentest
parameters["PentestFindingsDataSource"] = JRBeanCollectionDataSource(projectReportCollection.projectPentestReport[i].findings)
// Setup Sub-dataset for Comments of Pentest
parameters["PentestCommentsDataSource"] = JRBeanCollectionDataSource(projectReportCollection.projectPentestReport[i].comments)
// Fill Reports
// Print one report for each objective and merge them together afterwards
val jasperPrintPentests: JasperPrint = if (projectReportCollection.projectPentestReport[i].findings.isEmpty()) {
JasperFillManager.fillReport(jasperReportPentestsCommentsOnly, parameters, projectSinglePentestReportDataSource)
} else if (projectReportCollection.projectPentestReport[i].comments.isEmpty()) {
JasperFillManager.fillReport(jasperReportPentestsFindingsOnly, parameters, projectSinglePentestReportDataSource)
} else {
JasperFillManager.fillReport(jasperReportPentestsFindingsAndComments, parameters, projectSinglePentestReportDataSource)
}
// Create File
var finalFile: File = File(reportDefaultPdf)
if (reportFormat.equals("pdf")) {
JasperExportManager.exportReportToPdfFile(
jasperPrintPentests,
reportDestination + "E" + i.toString() + "_Pentestreport.pdf"
)
finalFile = File(reportDestination + "E" + i.toString() + "_Pentestreport.pdf")
finalFiles += (finalFile)
} else {
println("NONONO")
// ToDo: Implement different report formats
finalFiles += (finalFile)
val filePentestsFindingsAndCommentsStream =
javaClass.getResourceAsStream(reportPentestsFindingsAndCommentsDesignTemplate)
val filePentestsFindingsOnlyStream = javaClass.getResourceAsStream(reportPentestsFindingsOnlyDesignTemplate)
val filePentestsCommentsOnlyStream = javaClass.getResourceAsStream(reportPentestsCommentsOnlyDesignTemplate)
// Open file stream for findings & comments
filePentestsFindingsAndCommentsStream.use { pentestsFindingsAndCommentsStream ->
val inputFindingsAndCommentsStream = ByteArrayInputStream(pentestsFindingsAndCommentsStream.readAllBytes())
// Setup Jasper Report
val jasperReportPentestsFindingsAndComments =
JasperCompileManager.compileReport(inputFindingsAndCommentsStream)
// Open file stream for findings only
filePentestsFindingsOnlyStream.use { pentestsFindingsOnlyStream ->
val inputFindingsOnlyStream = ByteArrayInputStream(pentestsFindingsOnlyStream.readAllBytes())
// Setup Jasper Report
val jasperReportPentestsFindingsOnly: JasperReport =
JasperCompileManager.compileReport(inputFindingsOnlyStream)
// Open file stream for comments only
filePentestsCommentsOnlyStream.use { pentestsCommentsOnlyStream ->
val inputCommentsOnlyStream = ByteArrayInputStream(pentestsCommentsOnlyStream.readAllBytes())
// Setup Jasper Report
val jasperReportPentestsCommentsOnly: JasperReport =
JasperCompileManager.compileReport(inputCommentsOnlyStream)
// Create pentestReport content for every objective
for (i in 0 until projectReportCollection.projectPentestReport.size) {
val projectSinglePentestReportDataSource: JRBeanCollectionDataSource =
JRBeanCollectionDataSource(mutableListOf(projectReportCollection.projectPentestReport[i]))
// Setup Parameter & add Sub-datasets
val parameters = HashMap<String, Any>()
// Setup Sub-dataset for Findings of Pentest
parameters["PentestFindingsDataSource"] =
JRBeanCollectionDataSource(projectReportCollection.projectPentestReport[i].findings)
// Setup Sub-dataset for Comments of Pentest
parameters["PentestCommentsDataSource"] =
JRBeanCollectionDataSource(projectReportCollection.projectPentestReport[i].comments)
parameters["CDATA_WATERMARK"] = waterMarkPath
parameters["CDATA_FindingsSubreport"] = findingsSubreportPath
parameters["CDATA_CommentsSubreport"] = commentsSubreportPath
// Fill Reports
// Print one report for each objective and merge them together afterwards
val jasperPrintPentests: JasperPrint =
if (projectReportCollection.projectPentestReport[i].findings.isEmpty()) {
JasperFillManager.fillReport(
jasperReportPentestsCommentsOnly,
parameters,
projectSinglePentestReportDataSource
)
} else if (projectReportCollection.projectPentestReport[i].comments.isEmpty()) {
JasperFillManager.fillReport(
jasperReportPentestsFindingsOnly,
parameters,
projectSinglePentestReportDataSource
)
} else {
JasperFillManager.fillReport(
jasperReportPentestsFindingsAndComments,
parameters,
projectSinglePentestReportDataSource
)
}
// Create File
val finalFile: ByteArray =
javaClass.getResourceAsStream(reportDefaultPdfPropertyPath).readAllBytes()
// var finalFile: ByteArray = javaClass.getResourceAsStream(reportDefaultPdfProperty).readAllBytes()
if (reportFormat.equals("pdf")) {
finalFiles += JasperExportManager.exportReportToPdf(jasperPrintPentests)
} else {
// ToDo: Implement different report formats
finalFiles += (finalFile)
}
}
}
}
}
return finalFiles
}
private fun createAppendencies(reportFormat: String): File {
private fun createAppendencies(reportFormat: String): ByteArray {
// Load Jasper Files
val fileCover: File = ResourceUtils.getFile(reportAppendenciesDesignTemplate)
// Compile Jasper Reports
val jasperReportCover: JasperReport = JasperCompileManager.compileReport(fileCover.absolutePath)
// Setup Parameter & add Sub-datasets
val parameters = HashMap<String, Any>()
parameters["SeverityRatingDefinition"] = JREmptyDataSource()
// Fill Reports
val jasperPrintCover: JasperPrint =
JasperFillManager.fillReport(jasperReportCover, parameters, JREmptyDataSource())
// Create File
var finalFile: File = File(reportDefaultPdf)
return if (reportFormat.equals("pdf")) {
JasperExportManager.exportReportToPdfFile(jasperPrintCover, reportDestination + "F_Appendencies.pdf")
finalFile = File(reportDestination + "F_Appendencies.pdf")
finalFile
} else {
// ToDo: Implement different report formats
finalFile
val fileAppendenciesStream = javaClass.getResourceAsStream(reportAppendenciesDesignTemplate)
// Open file stream
fileAppendenciesStream.use { stream ->
val inputStream = ByteArrayInputStream(stream.readAllBytes())
// Compile Jasper Reports
val jasperReportCover: JasperReport = JasperCompileManager.compileReport(inputStream)
// Setup Parameter & add Sub-datasets
val parameters = HashMap<String, Any>()
parameters["SeverityRatingDefinition"] = JREmptyDataSource()
parameters["CDATA_WATERMARK"] = waterMarkPath
parameters["CDATA_SeverityRatingTable"] = severityRatingTablePath
// Fill Reports
val jasperPrintAppendencies: JasperPrint =
JasperFillManager.fillReport(jasperReportCover, parameters, JREmptyDataSource())
// Create File
var finalFile: ByteArray = javaClass.getResourceAsStream(reportDefaultPdfPropertyPath).readAllBytes()
return if (reportFormat.equals("pdf")) {
finalFile = JasperExportManager.exportReportToPdf(jasperPrintAppendencies)
finalFile
} else {
// ToDo: Implement different report formats
finalFile
}
}
}
}

View File

@ -3,3 +3,18 @@ spring.security.oauth2.resourceserver.jwt.issuer-uri=http://c4po-keycloak:8080/a
keycloakhost=c4po-keycloak
keycloak.client.url=http://c4po-keycloak:8080
keycloak.client.realm.path=auth/realms/c4po_realm_local/
## C4PO_ApiService ##
api.client.url=http://c4po-api:8443/
api.client.projects.path=projects
api.client.pentests.path=pentests
## Jasper ##
# Ressource variables for jrxml files #
CDATA_WATERMARK=BOOT-INF/classes/jasper/Watermark.png
CDATA_C4POCoverBackground=BOOT-INF/classes/jasper/C4POCoverBackground#1.jpeg
# Subreports #
CDATA_FindingsSubreport=BOOT-INF/classes/jasper/subReports/FindingsSubreport.jasper
CDATA_CommentsSubreport=BOOT-INF/classes/jasper/subReports/CommentsSubreport.jasper
CDATA_SeverityRatingTable=BOOT-INF/classes/jasper/subReports/SeverityRatingTableSubreport.jasper

View File

@ -25,4 +25,24 @@ keycloak.client.realm.path=auth/realms/c4po_realm_local/
## Total number of pentests listet in the OWASP testing guide
## https://owasp.org/www-project-web-security-testing-guide/assets/archive/OWASP_Testing_Guide_v4.pdf
owasp.web.pentests=95
# ToDo: Disabled objectives are not excluded as of now
owasp.web.pentests=95
## Jasper ##
reportCoverDesignTemplate=/jasper/reports/c4po_cover.jrxml
reportContentDesignTemplate=/jasper/reports/c4po_content.jrxml
reportStateOfConfidentialityDesignTemplate=/jasper/reports/c4po_state_of_confidentiality.jrxml
reportExecutiveSummaryDesignTemplate=/jasper/reports/c4po_executive_summary.jrxml
reportPentestsFindingsAndCommentsDesignTemplate=/jasper/reports/c4po_pentests_findings_and_comments.jrxml
reportPentestsFindingsOnlyDesignTemplate=/jasper/reports/c4po_pentests_findings_only.jrxml
reportPentestsCommentsOnlyDesignTemplate=/jasper/reports/c4po_pentests_comments_only.jrxml
reportAppendenciesDesignTemplate=/jasper/reports/c4po_appendencies.jrxml
# Path to default pdf file #
reportDefaultPdf=/jasper/DEFAULT.pdf
# Ressource variables for jrxml files #
CDATA_WATERMARK=./src/main/resources/jasper/Watermark.png
CDATA_C4POCoverBackground=./src/main/resources/jasper/C4POCoverBackground#1.jpeg
# Subreports #
CDATA_FindingsSubreport=./src/main/resources/jasper/subReports/FindingsSubreport.jasper
CDATA_CommentsSubreport=./src/main/resources/jasper/subReports/CommentsSubreport.jasper
CDATA_SeverityRatingTable=./src/main/resources/jasper/subReports/SeverityRatingTableSubreport.jasper

View File

@ -2,6 +2,10 @@
<!-- 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_Appendencies" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="dd2c2daf-6b71-4752-8ed0-e25ae2523a51">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
<!-- 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_SeverityRatingTable" class="java.lang.String"/>
<queryString>
<![CDATA[]]>
</queryString>
@ -24,7 +28,7 @@
</ellipse>
<image>
<reportElement x="539" y="3" width="23" height="24" uuid="74214b7e-f089-49f2-9ef9-ef134386750c"/>
<imageExpression><![CDATA["/Users/mhg/Documents/Projects/security-c4po/security-c4po-reporting/src/main/resources/jasper/Watermark.png"]]></imageExpression>
<imageExpression><![CDATA[$P{CDATA_WATERMARK}]]></imageExpression>
</image>
<staticText>
<reportElement x="0" y="0" width="432" height="30" forecolor="#FFFFFF" uuid="cb237865-2647-4ee2-a85c-ebc5c8f84f9e"/>
@ -54,7 +58,7 @@
<subreport>
<reportElement positionType="Float" x="-3" y="510" width="553" height="30" uuid="ca9b0ff4-30c6-43d0-8da2-458d1960ef0b"/>
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.JREmptyDataSource()]]></dataSourceExpression>
<subreportExpression><![CDATA["./src/main/resources/jasper/subreports/"+"SeverityRatingTableSubreport.jasper"]]></subreportExpression>
<subreportExpression><![CDATA[$P{CDATA_SeverityRatingTable}]]></subreportExpression>
</subreport>
<staticText>
<reportElement x="0" y="83" width="280" height="20" forecolor="#232B44" uuid="147e164e-f290-4751-82ca-e4b55508408f"/>

View File

@ -2,6 +2,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_Content" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="3c42fdce-1295-4279-a59a-999f57d99afc">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="ProjectReportData JSON Adapter"/>
<!-- Ignores Issue about not finding a specific font -->
<property name="net.sf.jasperreports.awt.ignore.missing.font" value="true"/>
<style name="Table_TH" mode="Opaque" backcolor="#FFFFFF">
<box>
<pen lineWidth="0.5" lineColor="#FFFFFF"/>
@ -42,6 +44,7 @@
<field name="status" class="java.lang.String"/>
</subDataset>
<parameter name="ProjectPentestReportDataSource" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
<parameter name="CDATA_WATERMARK" class="java.lang.String"/>
<queryString language="JSON">
<![CDATA[projectReportData]]>
</queryString>
@ -71,7 +74,7 @@
</ellipse>
<image>
<reportElement x="539" y="3" width="23" height="24" uuid="2ca905b3-37c8-40ae-a9ea-3beb016b504c"/>
<imageExpression><![CDATA["/Users/mhg/Documents/Projects/security-c4po/security-c4po-reporting/src/main/resources/jasper/Watermark.png"]]></imageExpression>
<imageExpression><![CDATA[$P{CDATA_WATERMARK}]]></imageExpression>
</image>
</band>
</title>

View File

@ -4,6 +4,8 @@
<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>
@ -47,7 +49,7 @@
<band height="390" splitType="Stretch">
<image>
<reportElement x="-20" y="-20" width="595" height="409" uuid="7b8866c7-8b72-43a8-9428-2404a75e803e"/>
<imageExpression><![CDATA["/Users/mhg/Documents/Projects/security-c4po/security-c4po-reporting/src/main/resources/jasper/C4POCoverBackground#1.jpeg"]]></imageExpression>
<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"/>
@ -89,7 +91,7 @@
</ellipse>
<image>
<reportElement x="-14" y="224" width="31" height="37" uuid="ae84d484-ee44-436a-a0cd-e94a265ed665"/>
<imageExpression><![CDATA["/Users/mhg/Documents/Projects/security-c4po/security-c4po-reporting/src/main/resources/jasper/Watermark.png"]]></imageExpression>
<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"/>

View File

@ -2,6 +2,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_ExecutiveSummary" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="a71c3e72-ee88-496d-967d-a33d331426ab">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="ProjectPentestReportJasperData Template JSON Adapter"/>
<!-- Ignores Issue about not finding a specific font -->
<property name="net.sf.jasperreports.awt.ignore.missing.font" value="true"/>
<style name="PieChart">
<conditionalStyle>
<conditionExpression><![CDATA["LOW"]]></conditionExpression>
@ -70,6 +72,7 @@
</subDataset>
<parameter name="CategoryFindingsPieChartDataSource" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
<parameter name="SeverityFindingsPieChartDataSource" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
<parameter name="CDATA_WATERMARK" class="java.lang.String"/>
<queryString language="json">
<![CDATA[projectReportData]]>
</queryString>
@ -153,7 +156,7 @@
</ellipse>
<image>
<reportElement x="539" y="3" width="23" height="24" uuid="e47a59e3-90b6-43d3-9d42-930a6d497a05"/>
<imageExpression><![CDATA["/Users/mhg/Documents/Projects/security-c4po/security-c4po-reporting/src/main/resources/jasper/Watermark.png"]]></imageExpression>
<imageExpression><![CDATA[$P{CDATA_WATERMARK}]]></imageExpression>
</image>
</band>
</title>

View File

@ -2,6 +2,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_Pentest" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="d4d219cb-f6cb-4f7b-9d33-c00b82eaa1b7">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="ProjectPentestReportJasperData Template JSON Adapter"/>
<!-- Ignores Issue about not finding a specific font -->
<property name="net.sf.jasperreports.awt.ignore.missing.font" value="true"/>
<style name="Table_TH" mode="Opaque" backcolor="#232B44">
<box>
<pen lineWidth="0.5" lineColor="#151B2E"/>
@ -148,6 +150,8 @@
<field name="relatedFindings" class="java.lang.String"/>
</subDataset>
<parameter name="PentestCommentsDataSource" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
<parameter name="CDATA_WATERMARK" class="java.lang.String"/>
<parameter name="CDATA_CommentsSubreport" class="java.lang.String"/>
<queryString language="JSON">
<![CDATA[projectPentestReport]]>
</queryString>
@ -211,7 +215,7 @@
</ellipse>
<image>
<reportElement x="524" y="13" width="24" height="27" uuid="c8f8490d-ab26-47e3-811f-c3a70a633fd0"/>
<imageExpression><![CDATA["/Users/mhg/Documents/Projects/security-c4po/security-c4po-reporting/src/main/resources/jasper/Watermark.png"]]></imageExpression>
<imageExpression><![CDATA[$P{CDATA_WATERMARK}]]></imageExpression>
</image>
</band>
</title>
@ -220,7 +224,7 @@
<subreport isUsingCache="false" runToBottom="false">
<reportElement x="0" y="0" width="554" height="610" isRemoveLineWhenBlank="true" uuid="48da877f-cf38-4fc2-9104-934c8a528d6e"/>
<dataSourceExpression><![CDATA[$P{PentestCommentsDataSource}]]></dataSourceExpression>
<subreportExpression><![CDATA["./src/main/resources/jasper/subreports/"+"CommentsSubreport.jasper"]]></subreportExpression>
<subreportExpression><![CDATA[$P{CDATA_CommentsSubreport}]]></subreportExpression>
</subreport>
</band>
</detail>

View File

@ -2,6 +2,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_Pentest" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="d4d219cb-f6cb-4f7b-9d33-c00b82eaa1b7">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="ProjectPentestReportJasperData Template JSON Adapter"/>
<!-- Ignores Issue about not finding a specific font -->
<property name="net.sf.jasperreports.awt.ignore.missing.font" value="true"/>
<style name="Table_TH" mode="Opaque" backcolor="#232B44">
<box>
<pen lineWidth="0.5" lineColor="#151B2E"/>
@ -237,6 +239,9 @@
</subDataset>
<parameter name="PentestFindingsDataSource" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
<parameter name="PentestCommentsDataSource" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
<parameter name="CDATA_WATERMARK" class="java.lang.String"/>
<parameter name="CDATA_FindingsSubreport" class="java.lang.String"/>
<parameter name="CDATA_CommentsSubreport" class="java.lang.String"/>
<queryString language="JSON">
<![CDATA[projectPentestReport]]>
</queryString>
@ -300,7 +305,7 @@
</ellipse>
<image>
<reportElement x="524" y="13" width="24" height="27" uuid="afa875b3-5bda-4192-8094-7810edcf25ec"/>
<imageExpression><![CDATA["/Users/mhg/Documents/Projects/security-c4po/security-c4po-reporting/src/main/resources/jasper/Watermark.png"]]></imageExpression>
<imageExpression><![CDATA[$P{CDATA_WATERMARK}]]></imageExpression>
</image>
</band>
</title>
@ -312,12 +317,12 @@
<subreportParameterExpression><![CDATA[]]></subreportParameterExpression>
</subreportParameter>
<dataSourceExpression><![CDATA[$P{PentestFindingsDataSource}]]></dataSourceExpression>
<subreportExpression><![CDATA["./src/main/resources/jasper/subreports/"+"FindingsSubreport.jasper"]]></subreportExpression>
<subreportExpression><![CDATA[$P{CDATA_FindingsSubreport}]]></subreportExpression>
</subreport>
<subreport isUsingCache="false" runToBottom="true">
<reportElement positionType="Float" x="0" y="350" width="554" height="339" isRemoveLineWhenBlank="true" uuid="48da877f-cf38-4fc2-9104-934c8a528d6e"/>
<dataSourceExpression><![CDATA[$P{PentestCommentsDataSource}]]></dataSourceExpression>
<subreportExpression><![CDATA["./src/main/resources/jasper/subreports/"+"CommentsSubreport.jasper"]]></subreportExpression>
<subreportExpression><![CDATA[$P{CDATA_CommentsSubreport}]]></subreportExpression>
</subreport>
</band>
</detail>

View File

@ -2,6 +2,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_Pentest" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="d4d219cb-f6cb-4f7b-9d33-c00b82eaa1b7">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="ProjectPentestReportJasperData Template JSON Adapter"/>
<!-- Ignores Issue about not finding a specific font -->
<property name="net.sf.jasperreports.awt.ignore.missing.font" value="true"/>
<style name="Table_TH" mode="Opaque" backcolor="#232B44">
<box>
<pen lineWidth="0.5" lineColor="#151B2E"/>
@ -193,6 +195,8 @@
<field name="mitigation" class="java.lang.String"/>
</subDataset>
<parameter name="PentestFindingsDataSource" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
<parameter name="CDATA_WATERMARK" class="java.lang.String"/>
<parameter name="CDATA_FindingsSubreport" class="java.lang.String"/>
<queryString language="JSON">
<![CDATA[projectPentestReport]]>
</queryString>
@ -256,7 +260,7 @@
</ellipse>
<image>
<reportElement x="524" y="13" width="24" height="27" uuid="01ae010d-be6b-4696-b696-e27ba95164ae"/>
<imageExpression><![CDATA["/Users/mhg/Documents/Projects/security-c4po/security-c4po-reporting/src/main/resources/jasper/Watermark.png"]]></imageExpression>
<imageExpression><![CDATA[$P{CDATA_WATERMARK}]]></imageExpression>
</image>
</band>
</title>
@ -268,7 +272,7 @@
<subreportParameterExpression><![CDATA[]]></subreportParameterExpression>
</subreportParameter>
<dataSourceExpression><![CDATA[$P{PentestFindingsDataSource}]]></dataSourceExpression>
<subreportExpression><![CDATA["./src/main/resources/jasper/subreports/"+"FindingsSubreport.jasper"]]></subreportExpression>
<subreportExpression><![CDATA[$P{CDATA_FindingsSubreport}]]></subreportExpression>
</subreport>
</band>
</detail>

View File

@ -2,6 +2,9 @@
<!-- 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_StateOfConfidentiality" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="c9281989-500e-499e-a5f4-ede1c502fcbc">
<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"/>
<queryString language="JSON">
<![CDATA[projectReportData]]>
</queryString>
@ -53,7 +56,7 @@
</ellipse>
<image>
<reportElement x="539" y="3" width="23" height="24" uuid="75a577b3-42df-4d40-be10-d0991b2769e2"/>
<imageExpression><![CDATA["/Users/mhg/Documents/Projects/security-c4po/security-c4po-reporting/src/main/resources/jasper/Watermark.png"]]></imageExpression>
<imageExpression><![CDATA[$P{CDATA_WATERMARK}]]></imageExpression>
</image>
<staticText>
<reportElement x="0" y="0" width="432" height="30" forecolor="#FFFFFF" uuid="329f5881-cba9-4418-9ef0-99a6805906ba"/>

View File

@ -0,0 +1,17 @@
#!/bin/sh
# wait-for-keycloak.sh
set -e
host="$1"
shift
printf 'Waiting for keycloak...'
until $(curl --output /dev/null --silent --head --fail $host); do
printf '.'
sleep 4
done
printf '\nKeycloak is up and running - Starting C4PO Reporting'
exec "$@"