feat: include reporting service in docker-compose

This commit is contained in:
Marcel Haag 2023-04-24 14:48:55 +02:00 committed by Cel
parent 65985e5ef3
commit 061b93ff5e
24 changed files with 1017 additions and 643 deletions

View File

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

View File

@ -107,11 +107,11 @@ export class PentestHeaderComponent implements OnInit, OnDestroy {
next: (pentest: Pentest) => { next: (pentest: Pentest) => {
this.store.dispatch(new ChangePentest(pentest)); this.store.dispatch(new ChangePentest(pentest));
this.initialTimeSpent = pentest.timeSpent; this.initialTimeSpent = pentest.timeSpent;
this.notificationService.showPopup('pentest.popup.complete.success', PopupType.SUCCESS); this.notificationService.showPopup('pentest.popup.update.success', PopupType.SUCCESS);
}, },
error: err => { error: err => {
console.log(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> { public redirectToChangePasswordAction(): Promise<void> {
// https://keycloak.discourse.group/t/integrate-change-password-from-account-console-into-own-webapp/12300 // https://keycloak.discourse.group/t/integrate-change-password-from-account-console-into-own-webapp/12300
return this.keycloakService.login({ return this.keycloakService.login({
action: 'UPDATE_PASSWORD', action: 'UPDATE_PASSWORD'
}); });
} }

View File

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

View File

@ -15,6 +15,7 @@ COPY ./build/libs/security-c4po-reporting-0.0.1-SNAPSHOT.jar /
USER security-c4po-reporting USER security-c4po-reporting
EXPOSE 8444 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" ] # 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-webflux")
implementation("org.springframework.boot:spring-boot-starter-actuator") implementation("org.springframework.boot:spring-boot-starter-actuator")
// Security
implementation("org.springframework.boot:spring-boot-starter-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-client")
implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server") 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) ResponseEntity.ok().body(reportClassLoaderFilePath)
}.switchIfEmpty { }.switchIfEmpty {
Mono.just(notFound().build<ByteArray>()) 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.extensions.getLoggerFor
import com.securityc4po.reporting.remote.model.* 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.*
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource
import org.apache.commons.io.FileUtils
import org.apache.pdfbox.io.MemoryUsageSetting import org.apache.pdfbox.io.MemoryUsageSetting
import org.apache.pdfbox.multipdf.PDFMergerUtility import org.apache.pdfbox.multipdf.PDFMergerUtility
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import org.springframework.util.ResourceUtils
import reactor.core.publisher.Flux import reactor.core.publisher.Flux
import reactor.core.publisher.Mono import reactor.core.publisher.Mono
import java.io.ByteArrayOutputStream import java.io.*
import java.io.File
@Service @Service
@ -26,59 +22,68 @@ class ReportService {
var logger = getLoggerFor<ReportService>() var logger = getLoggerFor<ReportService>()
private val reportCoverDesignTemplate = "./src/main/resources/jasper/reports/c4po_cover.jrxml" // Jasper Design template file Paths
private val reportContentDesignTemplate = "./src/main/resources/jasper/reports/c4po_content.jrxml" @Value("\${reportCoverDesignTemplate}")
private val reportStateOfConfidentialityDesignTemplate = lateinit var reportCoverDesignTemplate: String
"./src/main/resources/jasper/reports/c4po_state_of_confidentiality.jrxml"
private val reportExecutiveSummaryDesignTemplate = @Value("\${reportContentDesignTemplate}")
"./src/main/resources/jasper/reports/c4po_executive_summary.jrxml" lateinit var reportContentDesignTemplate: String
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" @Value("\${reportStateOfConfidentialityDesignTemplate}")
private val reportPentestsCommentsOnlyDesignTemplate = "./src/main/resources/jasper/reports/c4po_pentests_comments_only.jrxml" lateinit var reportStateOfConfidentialityDesignTemplate: String
private val reportAppendenciesDesignTemplate = "./src/main/resources/jasper/reports/c4po_appendencies.jrxml"
@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 // 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 // Image paths
private val reportDestination = "./src/main/resources/jasper/reportPDFs/" @Value("\${CDATA_WATERMARK}")
lateinit var waterMarkPath: String
// Path where the completed Report is saved @Value("\${CDATA_C4POCoverBackground}")
private val reportFileDestination = "./src/main/resources/jasper/finalReport/" lateinit var coverBackgroundPath: String
// Path where the completed Report can be found by class loader // Subreport paths
private val reportFileForClassLoader = "/jasper/finalReport/" @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> { fun createReport(projectReportCollection: ProjectReport, reportFormat: String): Mono<ByteArray> {
// Setup Filepath destination
val reportFilePathDestination: String =
reportFileDestination + projectReportCollection.title.replace(" ", "_") + "_report.pdf"
// 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 pdfDocOutputstream = ByteArrayOutputStream()
// Try to create report files & merge them together // Try to create report files & merge them together
return createPentestReportFiles(projectReportCollection, reportFormat, mergedC4POPentestReport).collectList().map { return createPentestReportFiles(projectReportCollection, reportFormat, mergedC4POPentestReport).collectList()
// Merge report files .map {
mergedC4POPentestReport.destinationFileName = reportFilePathDestination // Merge report files
mergedC4POPentestReport.destinationStream = pdfDocOutputstream mergedC4POPentestReport.destinationStream = pdfDocOutputstream
mergedC4POPentestReport.mergeDocuments(MemoryUsageSetting.setupTempFileOnly()) mergedC4POPentestReport.mergeDocuments(MemoryUsageSetting.setupTempFileOnly())
}.flatMap { }.flatMap {
return@flatMap Mono.just(pdfDocOutputstream.toByteArray()) return@flatMap Mono.just(pdfDocOutputstream.toByteArray())
}.doOnError { }.doOnError {
logger.error("Report generation failed.") 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)
}
} }
private fun createPentestReportFiles( private fun createPentestReportFiles(
@ -87,7 +92,7 @@ class ReportService {
mergedC4POPentestReport: PDFMergerUtility mergedC4POPentestReport: PDFMergerUtility
): Flux<Unit> { ): Flux<Unit> {
return Flux.just( return Flux.just(
// Create report files // Create byte arrays of report files
createCover(projectReportCollection, reportFormat), createCover(projectReportCollection, reportFormat),
createTableOfContent(projectReportCollection, reportFormat), createTableOfContent(projectReportCollection, reportFormat),
createStateOfConfidentiality(projectReportCollection, reportFormat), createStateOfConfidentiality(projectReportCollection, reportFormat),
@ -95,298 +100,358 @@ class ReportService {
createPentestReports(projectReportCollection, reportFormat), createPentestReports(projectReportCollection, reportFormat),
createAppendencies(reportFormat) createAppendencies(reportFormat)
).map { jasperObject -> ).map { jasperObject ->
if (jasperObject is File) { if (jasperObject is ByteArray) {
mergedC4POPentestReport.addSource(jasperObject) val pdfInputSteam = ByteArrayInputStream(jasperObject)
mergedC4POPentestReport.addSource(pdfInputSteam)
} else if (jasperObject is List<*>) { } else if (jasperObject is List<*>) {
jasperObject.forEach { jasperFile -> jasperObject.forEach { jasperFile ->
if (jasperFile is File) { if (jasperFile is ByteArray) {
mergedC4POPentestReport.addSource(jasperFile) 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 // Load Jasper Files
val fileCover: File = ResourceUtils.getFile(reportCoverDesignTemplate) val fileCoverStream = javaClass.getResourceAsStream(reportCoverDesignTemplate)
// Compile Jasper Reports // Open file stream
val jasperReportCover: JasperReport = JasperCompileManager.compileReport(fileCover.absolutePath) fileCoverStream.use { stream ->
// Setup Main Datasource val inputStream = ByteArrayInputStream(stream.readAllBytes())
val dataSource: JRBeanCollectionDataSource = JRBeanCollectionDataSource(mutableListOf(projectReportCollection)) // Compile Jasper Reports
// Setup Parameter & add Sub-datasets val jasperReportCover: JasperReport = JasperCompileManager.compileReport(inputStream)
val parameters = HashMap<String, Any>() // Setup Main Datasource
// Fill Reports val dataSource: JRBeanCollectionDataSource =
val jasperPrintCover: JasperPrint = JasperFillManager.fillReport(jasperReportCover, parameters, dataSource) JRBeanCollectionDataSource(mutableListOf(projectReportCollection))
// Create File // Setup Parameter & add Sub-datasets
var finalFile: File = File(reportDefaultPdf) val parameters = HashMap<String, Any>()
return if (reportFormat.equals("pdf")) { parameters["CDATA_WATERMARK"] = waterMarkPath
JasperExportManager.exportReportToPdfFile(jasperPrintCover, reportDestination + "A_Cover.pdf") parameters["CDATA_C4POCoverBackground"] = coverBackgroundPath
finalFile = File(reportDestination + "A_Cover.pdf") // Fill Reports
finalFile val jasperPrintCover: JasperPrint = JasperFillManager.fillReport(jasperReportCover, parameters, dataSource)
} else { // Create File
// ToDo: Implement different report formats var finalFile: ByteArray = javaClass.getResourceAsStream(reportDefaultPdfPropertyPath).readAllBytes()
finalFile // 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 // Load Jasper Files
val fileContent: File = ResourceUtils.getFile(reportContentDesignTemplate) val fileContentStream = javaClass.getResourceAsStream(reportContentDesignTemplate)
// Compile Jasper Reports // Open file stream
val jasperReportContent: JasperReport = JasperCompileManager.compileReport(fileContent.absolutePath) fileContentStream.use { stream ->
// Setup Sub-dataset for Table of Content generation val inputStream = ByteArrayInputStream(stream.readAllBytes())
val projectPentestReportDataSource: JRBeanCollectionDataSource = // Compile Jasper Reports
JRBeanCollectionDataSource(projectReportCollection.projectPentestReport) val jasperReportContent: JasperReport = JasperCompileManager.compileReport(inputStream)
// Setup Parameter & add Sub-datasets // Setup Sub-dataset for Table of Content generation
val parameters = HashMap<String, Any>() val projectPentestReportDataSource: JRBeanCollectionDataSource =
parameters["ProjectPentestReportDataSource"] = projectPentestReportDataSource JRBeanCollectionDataSource(projectReportCollection.projectPentestReport)
// Fill Reports // Setup Parameter & add Sub-datasets
val jasperPrintContent: JasperPrint = val parameters = HashMap<String, Any>()
JasperFillManager.fillReport(jasperReportContent, parameters, JREmptyDataSource()) parameters["ProjectPentestReportDataSource"] = projectPentestReportDataSource
// Create File parameters["CDATA_WATERMARK"] = waterMarkPath
var finalFile: File = File(reportDefaultPdf) // Fill Reports
return if (reportFormat.equals("pdf")) { val jasperPrintContent: JasperPrint =
JasperExportManager.exportReportToPdfFile(jasperPrintContent, reportDestination + "B_Content.pdf") JasperFillManager.fillReport(jasperReportContent, parameters, JREmptyDataSource())
finalFile = File(reportDestination + "B_Content.pdf") // Create File
finalFile var finalFile: ByteArray = javaClass.getResourceAsStream(reportDefaultPdfPropertyPath).readAllBytes()
} else { // Export Report
// ToDo: Implement different report formats return if (reportFormat.equals("pdf")) {
finalFile 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 // Load Jasper Files
val fileContent: File = ResourceUtils.getFile(reportStateOfConfidentialityDesignTemplate) val fileStateOfConfidentialityStream = javaClass.getResourceAsStream(reportStateOfConfidentialityDesignTemplate)
// Compile Jasper Reports // Open file stream
val jasperReportContent: JasperReport = JasperCompileManager.compileReport(fileContent.absolutePath) fileStateOfConfidentialityStream.use { stream ->
// Setup Main Datasource val inputStream = ByteArrayInputStream(stream.readAllBytes())
val dataSource: JRBeanCollectionDataSource = JRBeanCollectionDataSource(mutableListOf(projectReportCollection)) // Compile Jasper Reports
// Setup Parameter & add Sub-datasets val jasperReportContent: JasperReport = JasperCompileManager.compileReport(inputStream)
val parameters = HashMap<String, Any>() // Setup Main Datasource
// Fill Reports val dataSource: JRBeanCollectionDataSource =
val jasperPrintContent: JasperPrint = JasperFillManager.fillReport(jasperReportContent, parameters, dataSource) JRBeanCollectionDataSource(mutableListOf(projectReportCollection))
// Create File // Setup Parameter & add Sub-datasets
var finalFile: File = File(reportDefaultPdf) val parameters = HashMap<String, Any>()
return if (reportFormat.equals("pdf")) { parameters["CDATA_WATERMARK"] = waterMarkPath
JasperExportManager.exportReportToPdfFile( // Fill Reports
jasperPrintContent, val jasperPrintStateOfConfidentiality: JasperPrint =
reportDestination + "C_StateOfConfidentiality.pdf" 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") // Fill data for CategoryPieDataSet
finalFile for (i in 0 until projectReportCollection.projectPentestReport.size) {
} else { when (projectReportCollection.projectPentestReport[i].category) {
// ToDo: Implement different report formats "INFORMATION_GATHERING" -> {
finalFile categoryFindings[0].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
}
}
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
} }
"MEDIUM" -> { "CONFIGURATION_AND_DEPLOY_MANAGEMENT_TESTING" -> {
severityFindings[1].numberOfFindings += 1 categoryFindings[1].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
} }
"HIGH" -> { "IDENTITY_MANAGEMENT_TESTING" -> {
severityFindings[2].numberOfFindings += 1 categoryFindings[2].numberOfFindings += projectReportCollection.projectPentestReport[i].findings.size
} }
"CRITICAL" -> { "AUTHENTICATION_TESTING" -> {
severityFindings[3].numberOfFindings += 1 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 -> { else -> {
severityFindings.add( categoryFindings.add(
SeverityPieData( CategoryPieData(
"UNKNOWN_SEVERITY", "UNKNOWN_CATEGORY",
projectReportCollection.projectPentestReport[i].findings.size projectReportCollection.projectPentestReport[i].findings.size
) )
) )
} }
} }
} }
} val categoryFindingsDataSource: JRBeanCollectionDataSource = JRBeanCollectionDataSource(categoryFindings)
val severityFindingsDataSource: JRBeanCollectionDataSource = JRBeanCollectionDataSource(severityFindings) // Setup SeverityPieData for each Severity
// Setup Parameter & add Sub-datasets val severityFindings: MutableList<SeverityPieData> = mutableListOf<SeverityPieData>(
val parameters = HashMap<String, Any>() SeverityPieData("LOW", 0),
parameters["CategoryFindingsPieChartDataSource"] = categoryFindingsDataSource SeverityPieData("MEDIUM", 0),
parameters["SeverityFindingsPieChartDataSource"] = severityFindingsDataSource SeverityPieData("HIGH", 0),
// Fill Reports SeverityPieData("CRITICAL", 0)
val jasperPrintContent: JasperPrint = JasperFillManager.fillReport(jasperReportContent, parameters, dataSource) )
// Create File // Fill data for SeverityPieData
var finalFile: File = File(reportDefaultPdf) for (i in 0 until projectReportCollection.projectPentestReport.size) {
return if (reportFormat.equals("pdf")) { for (j in 0 until projectReportCollection.projectPentestReport[i].findings.size) {
JasperExportManager.exportReportToPdfFile(jasperPrintContent, reportDestination + "D_ExecutiveSummary.pdf") when (projectReportCollection.projectPentestReport[i].findings[j].severity) {
finalFile = File(reportDestination + "D_ExecutiveSummary.pdf") "LOW" -> {
finalFile severityFindings[0].numberOfFindings += 1
} else { }
// ToDo: Implement different report formats
finalFile "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 // Create List of Files
var finalFiles: List<File> = emptyList() var finalFiles: List<ByteArray> = emptyList()
// Load Jasper Files // Load Jasper Files
val filePentestsFindingsAndComments: File = ResourceUtils.getFile(reportPentestsFindingsAndCommentsDesignTemplate) val filePentestsFindingsAndCommentsStream =
val filePentestsFindingsOnly: File = ResourceUtils.getFile(reportPentestsFindingsOnlyDesignTemplate) javaClass.getResourceAsStream(reportPentestsFindingsAndCommentsDesignTemplate)
val filePentestsCommentsOnly: File = ResourceUtils.getFile(reportPentestsCommentsOnlyDesignTemplate) val filePentestsFindingsOnlyStream = javaClass.getResourceAsStream(reportPentestsFindingsOnlyDesignTemplate)
// Compile Jasper Reports val filePentestsCommentsOnlyStream = javaClass.getResourceAsStream(reportPentestsCommentsOnlyDesignTemplate)
val jasperReportPentestsFindingsAndComments: JasperReport = JasperCompileManager.compileReport(filePentestsFindingsAndComments.absolutePath) // Open file stream for findings & comments
val jasperReportPentestsFindingsOnly: JasperReport = JasperCompileManager.compileReport(filePentestsFindingsOnly.absolutePath) filePentestsFindingsAndCommentsStream.use { pentestsFindingsAndCommentsStream ->
val jasperReportPentestsCommentsOnly: JasperReport = JasperCompileManager.compileReport(filePentestsCommentsOnly.absolutePath) val inputFindingsAndCommentsStream = ByteArrayInputStream(pentestsFindingsAndCommentsStream.readAllBytes())
// Create pentestReport content for every objective // Setup Jasper Report
for (i in 0 until projectReportCollection.projectPentestReport.size) { val jasperReportPentestsFindingsAndComments =
val projectSinglePentestReportDataSource: JRBeanCollectionDataSource = JasperCompileManager.compileReport(inputFindingsAndCommentsStream)
JRBeanCollectionDataSource(mutableListOf(projectReportCollection.projectPentestReport[i])) // Open file stream for findings only
// Setup Parameter & add Sub-datasets filePentestsFindingsOnlyStream.use { pentestsFindingsOnlyStream ->
val parameters = HashMap<String, Any>() val inputFindingsOnlyStream = ByteArrayInputStream(pentestsFindingsOnlyStream.readAllBytes())
// Setup Sub-dataset for Findings of Pentest // Setup Jasper Report
parameters["PentestFindingsDataSource"] = JRBeanCollectionDataSource(projectReportCollection.projectPentestReport[i].findings) val jasperReportPentestsFindingsOnly: JasperReport =
// Setup Sub-dataset for Comments of Pentest JasperCompileManager.compileReport(inputFindingsOnlyStream)
parameters["PentestCommentsDataSource"] = JRBeanCollectionDataSource(projectReportCollection.projectPentestReport[i].comments) // Open file stream for comments only
// Fill Reports filePentestsCommentsOnlyStream.use { pentestsCommentsOnlyStream ->
// Print one report for each objective and merge them together afterwards val inputCommentsOnlyStream = ByteArrayInputStream(pentestsCommentsOnlyStream.readAllBytes())
val jasperPrintPentests: JasperPrint = if (projectReportCollection.projectPentestReport[i].findings.isEmpty()) { // Setup Jasper Report
JasperFillManager.fillReport(jasperReportPentestsCommentsOnly, parameters, projectSinglePentestReportDataSource) val jasperReportPentestsCommentsOnly: JasperReport =
} else if (projectReportCollection.projectPentestReport[i].comments.isEmpty()) { JasperCompileManager.compileReport(inputCommentsOnlyStream)
JasperFillManager.fillReport(jasperReportPentestsFindingsOnly, parameters, projectSinglePentestReportDataSource) // Create pentestReport content for every objective
} else { for (i in 0 until projectReportCollection.projectPentestReport.size) {
JasperFillManager.fillReport(jasperReportPentestsFindingsAndComments, parameters, projectSinglePentestReportDataSource) val projectSinglePentestReportDataSource: JRBeanCollectionDataSource =
} JRBeanCollectionDataSource(mutableListOf(projectReportCollection.projectPentestReport[i]))
// Create File // Setup Parameter & add Sub-datasets
var finalFile: File = File(reportDefaultPdf) val parameters = HashMap<String, Any>()
if (reportFormat.equals("pdf")) { // Setup Sub-dataset for Findings of Pentest
JasperExportManager.exportReportToPdfFile( parameters["PentestFindingsDataSource"] =
jasperPrintPentests, JRBeanCollectionDataSource(projectReportCollection.projectPentestReport[i].findings)
reportDestination + "E" + i.toString() + "_Pentestreport.pdf" // Setup Sub-dataset for Comments of Pentest
) parameters["PentestCommentsDataSource"] =
finalFile = File(reportDestination + "E" + i.toString() + "_Pentestreport.pdf") JRBeanCollectionDataSource(projectReportCollection.projectPentestReport[i].comments)
finalFiles += (finalFile) parameters["CDATA_WATERMARK"] = waterMarkPath
} else { parameters["CDATA_FindingsSubreport"] = findingsSubreportPath
println("NONONO") parameters["CDATA_CommentsSubreport"] = commentsSubreportPath
// ToDo: Implement different report formats // Fill Reports
finalFiles += (finalFile) // 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 return finalFiles
} }
private fun createAppendencies(reportFormat: String): File { private fun createAppendencies(reportFormat: String): ByteArray {
// Load Jasper Files // Load Jasper Files
val fileCover: File = ResourceUtils.getFile(reportAppendenciesDesignTemplate) val fileAppendenciesStream = javaClass.getResourceAsStream(reportAppendenciesDesignTemplate)
// Compile Jasper Reports // Open file stream
val jasperReportCover: JasperReport = JasperCompileManager.compileReport(fileCover.absolutePath) fileAppendenciesStream.use { stream ->
// Setup Parameter & add Sub-datasets val inputStream = ByteArrayInputStream(stream.readAllBytes())
val parameters = HashMap<String, Any>() // Compile Jasper Reports
parameters["SeverityRatingDefinition"] = JREmptyDataSource() val jasperReportCover: JasperReport = JasperCompileManager.compileReport(inputStream)
// Fill Reports // Setup Parameter & add Sub-datasets
val jasperPrintCover: JasperPrint = val parameters = HashMap<String, Any>()
JasperFillManager.fillReport(jasperReportCover, parameters, JREmptyDataSource()) parameters["SeverityRatingDefinition"] = JREmptyDataSource()
// Create File parameters["CDATA_WATERMARK"] = waterMarkPath
var finalFile: File = File(reportDefaultPdf) parameters["CDATA_SeverityRatingTable"] = severityRatingTablePath
return if (reportFormat.equals("pdf")) { // Fill Reports
JasperExportManager.exportReportToPdfFile(jasperPrintCover, reportDestination + "F_Appendencies.pdf") val jasperPrintAppendencies: JasperPrint =
finalFile = File(reportDestination + "F_Appendencies.pdf") JasperFillManager.fillReport(jasperReportCover, parameters, JREmptyDataSource())
finalFile // Create File
} else { var finalFile: ByteArray = javaClass.getResourceAsStream(reportDefaultPdfPropertyPath).readAllBytes()
// ToDo: Implement different report formats return if (reportFormat.equals("pdf")) {
finalFile 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 keycloakhost=c4po-keycloak
keycloak.client.url=http://c4po-keycloak:8080 keycloak.client.url=http://c4po-keycloak:8080
keycloak.client.realm.path=auth/realms/c4po_realm_local/ 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 ## 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 ## 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 --> <!-- 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"> <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"/> <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> <queryString>
<![CDATA[]]> <![CDATA[]]>
</queryString> </queryString>
@ -24,7 +28,7 @@
</ellipse> </ellipse>
<image> <image>
<reportElement x="539" y="3" width="23" height="24" uuid="74214b7e-f089-49f2-9ef9-ef134386750c"/> <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> </image>
<staticText> <staticText>
<reportElement x="0" y="0" width="432" height="30" forecolor="#FFFFFF" uuid="cb237865-2647-4ee2-a85c-ebc5c8f84f9e"/> <reportElement x="0" y="0" width="432" height="30" forecolor="#FFFFFF" uuid="cb237865-2647-4ee2-a85c-ebc5c8f84f9e"/>
@ -54,7 +58,7 @@
<subreport> <subreport>
<reportElement positionType="Float" x="-3" y="510" width="553" height="30" uuid="ca9b0ff4-30c6-43d0-8da2-458d1960ef0b"/> <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> <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> </subreport>
<staticText> <staticText>
<reportElement x="0" y="83" width="280" height="20" forecolor="#232B44" uuid="147e164e-f290-4751-82ca-e4b55508408f"/> <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 --> <!-- 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"> <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"/> <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"> <style name="Table_TH" mode="Opaque" backcolor="#FFFFFF">
<box> <box>
<pen lineWidth="0.5" lineColor="#FFFFFF"/> <pen lineWidth="0.5" lineColor="#FFFFFF"/>
@ -42,6 +44,7 @@
<field name="status" class="java.lang.String"/> <field name="status" class="java.lang.String"/>
</subDataset> </subDataset>
<parameter name="ProjectPentestReportDataSource" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/> <parameter name="ProjectPentestReportDataSource" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
<parameter name="CDATA_WATERMARK" class="java.lang.String"/>
<queryString language="JSON"> <queryString language="JSON">
<![CDATA[projectReportData]]> <![CDATA[projectReportData]]>
</queryString> </queryString>
@ -71,7 +74,7 @@
</ellipse> </ellipse>
<image> <image>
<reportElement x="539" y="3" width="23" height="24" uuid="2ca905b3-37c8-40ae-a9ea-3beb016b504c"/> <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> </image>
</band> </band>
</title> </title>

View File

@ -4,6 +4,8 @@
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="ProjectReportJasperData Template JSON Adapter"/> <property name="com.jaspersoft.studio.data.defaultdataadapter" value="ProjectReportJasperData Template JSON Adapter"/>
<!-- Ignores Issue about not finding a specific font --> <!-- Ignores Issue about not finding a specific font -->
<property name="net.sf.jasperreports.awt.ignore.missing.font" value="true"/> <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"> <queryString language="JSON">
<![CDATA[projectReportData]]> <![CDATA[projectReportData]]>
</queryString> </queryString>
@ -47,7 +49,7 @@
<band height="390" splitType="Stretch"> <band height="390" splitType="Stretch">
<image> <image>
<reportElement x="-20" y="-20" width="595" height="409" uuid="7b8866c7-8b72-43a8-9428-2404a75e803e"/> <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> </image>
<rectangle> <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"/> <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> </ellipse>
<image> <image>
<reportElement x="-14" y="224" width="31" height="37" uuid="ae84d484-ee44-436a-a0cd-e94a265ed665"/> <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> </image>
<staticText> <staticText>
<reportElement mode="Transparent" x="22" y="226" width="82" height="20" forecolor="#FEFEFF" backcolor="#151B2E" uuid="b40755db-f42b-47cf-9e73-57cd092f7bde"/> <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 --> <!-- 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"> <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"/> <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"> <style name="PieChart">
<conditionalStyle> <conditionalStyle>
<conditionExpression><![CDATA["LOW"]]></conditionExpression> <conditionExpression><![CDATA["LOW"]]></conditionExpression>
@ -70,6 +72,7 @@
</subDataset> </subDataset>
<parameter name="CategoryFindingsPieChartDataSource" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/> <parameter name="CategoryFindingsPieChartDataSource" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
<parameter name="SeverityFindingsPieChartDataSource" 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"> <queryString language="json">
<![CDATA[projectReportData]]> <![CDATA[projectReportData]]>
</queryString> </queryString>
@ -153,7 +156,7 @@
</ellipse> </ellipse>
<image> <image>
<reportElement x="539" y="3" width="23" height="24" uuid="e47a59e3-90b6-43d3-9d42-930a6d497a05"/> <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> </image>
</band> </band>
</title> </title>

View File

@ -2,6 +2,8 @@
<!-- Created with Jaspersoft Studio version 6.20.0.final using JasperReports Library version 6.20.0-2bc7ab61c56f459e8176eb05c7705e145cd400ad --> <!-- 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"> <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"/> <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"> <style name="Table_TH" mode="Opaque" backcolor="#232B44">
<box> <box>
<pen lineWidth="0.5" lineColor="#151B2E"/> <pen lineWidth="0.5" lineColor="#151B2E"/>
@ -148,6 +150,8 @@
<field name="relatedFindings" class="java.lang.String"/> <field name="relatedFindings" class="java.lang.String"/>
</subDataset> </subDataset>
<parameter name="PentestCommentsDataSource" 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_CommentsSubreport" class="java.lang.String"/>
<queryString language="JSON"> <queryString language="JSON">
<![CDATA[projectPentestReport]]> <![CDATA[projectPentestReport]]>
</queryString> </queryString>
@ -211,7 +215,7 @@
</ellipse> </ellipse>
<image> <image>
<reportElement x="524" y="13" width="24" height="27" uuid="c8f8490d-ab26-47e3-811f-c3a70a633fd0"/> <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> </image>
</band> </band>
</title> </title>
@ -220,7 +224,7 @@
<subreport isUsingCache="false" runToBottom="false"> <subreport isUsingCache="false" runToBottom="false">
<reportElement x="0" y="0" width="554" height="610" isRemoveLineWhenBlank="true" uuid="48da877f-cf38-4fc2-9104-934c8a528d6e"/> <reportElement x="0" y="0" width="554" height="610" isRemoveLineWhenBlank="true" uuid="48da877f-cf38-4fc2-9104-934c8a528d6e"/>
<dataSourceExpression><![CDATA[$P{PentestCommentsDataSource}]]></dataSourceExpression> <dataSourceExpression><![CDATA[$P{PentestCommentsDataSource}]]></dataSourceExpression>
<subreportExpression><![CDATA["./src/main/resources/jasper/subreports/"+"CommentsSubreport.jasper"]]></subreportExpression> <subreportExpression><![CDATA[$P{CDATA_CommentsSubreport}]]></subreportExpression>
</subreport> </subreport>
</band> </band>
</detail> </detail>

View File

@ -2,6 +2,8 @@
<!-- Created with Jaspersoft Studio version 6.20.0.final using JasperReports Library version 6.20.0-2bc7ab61c56f459e8176eb05c7705e145cd400ad --> <!-- 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"> <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"/> <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"> <style name="Table_TH" mode="Opaque" backcolor="#232B44">
<box> <box>
<pen lineWidth="0.5" lineColor="#151B2E"/> <pen lineWidth="0.5" lineColor="#151B2E"/>
@ -237,6 +239,9 @@
</subDataset> </subDataset>
<parameter name="PentestFindingsDataSource" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/> <parameter name="PentestFindingsDataSource" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
<parameter name="PentestCommentsDataSource" 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"> <queryString language="JSON">
<![CDATA[projectPentestReport]]> <![CDATA[projectPentestReport]]>
</queryString> </queryString>
@ -300,7 +305,7 @@
</ellipse> </ellipse>
<image> <image>
<reportElement x="524" y="13" width="24" height="27" uuid="afa875b3-5bda-4192-8094-7810edcf25ec"/> <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> </image>
</band> </band>
</title> </title>
@ -312,12 +317,12 @@
<subreportParameterExpression><![CDATA[]]></subreportParameterExpression> <subreportParameterExpression><![CDATA[]]></subreportParameterExpression>
</subreportParameter> </subreportParameter>
<dataSourceExpression><![CDATA[$P{PentestFindingsDataSource}]]></dataSourceExpression> <dataSourceExpression><![CDATA[$P{PentestFindingsDataSource}]]></dataSourceExpression>
<subreportExpression><![CDATA["./src/main/resources/jasper/subreports/"+"FindingsSubreport.jasper"]]></subreportExpression> <subreportExpression><![CDATA[$P{CDATA_FindingsSubreport}]]></subreportExpression>
</subreport> </subreport>
<subreport isUsingCache="false" runToBottom="true"> <subreport isUsingCache="false" runToBottom="true">
<reportElement positionType="Float" x="0" y="350" width="554" height="339" isRemoveLineWhenBlank="true" uuid="48da877f-cf38-4fc2-9104-934c8a528d6e"/> <reportElement positionType="Float" x="0" y="350" width="554" height="339" isRemoveLineWhenBlank="true" uuid="48da877f-cf38-4fc2-9104-934c8a528d6e"/>
<dataSourceExpression><![CDATA[$P{PentestCommentsDataSource}]]></dataSourceExpression> <dataSourceExpression><![CDATA[$P{PentestCommentsDataSource}]]></dataSourceExpression>
<subreportExpression><![CDATA["./src/main/resources/jasper/subreports/"+"CommentsSubreport.jasper"]]></subreportExpression> <subreportExpression><![CDATA[$P{CDATA_CommentsSubreport}]]></subreportExpression>
</subreport> </subreport>
</band> </band>
</detail> </detail>

View File

@ -2,6 +2,8 @@
<!-- Created with Jaspersoft Studio version 6.20.0.final using JasperReports Library version 6.20.0-2bc7ab61c56f459e8176eb05c7705e145cd400ad --> <!-- 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"> <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"/> <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"> <style name="Table_TH" mode="Opaque" backcolor="#232B44">
<box> <box>
<pen lineWidth="0.5" lineColor="#151B2E"/> <pen lineWidth="0.5" lineColor="#151B2E"/>
@ -193,6 +195,8 @@
<field name="mitigation" class="java.lang.String"/> <field name="mitigation" class="java.lang.String"/>
</subDataset> </subDataset>
<parameter name="PentestFindingsDataSource" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/> <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"> <queryString language="JSON">
<![CDATA[projectPentestReport]]> <![CDATA[projectPentestReport]]>
</queryString> </queryString>
@ -256,7 +260,7 @@
</ellipse> </ellipse>
<image> <image>
<reportElement x="524" y="13" width="24" height="27" uuid="01ae010d-be6b-4696-b696-e27ba95164ae"/> <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> </image>
</band> </band>
</title> </title>
@ -268,7 +272,7 @@
<subreportParameterExpression><![CDATA[]]></subreportParameterExpression> <subreportParameterExpression><![CDATA[]]></subreportParameterExpression>
</subreportParameter> </subreportParameter>
<dataSourceExpression><![CDATA[$P{PentestFindingsDataSource}]]></dataSourceExpression> <dataSourceExpression><![CDATA[$P{PentestFindingsDataSource}]]></dataSourceExpression>
<subreportExpression><![CDATA["./src/main/resources/jasper/subreports/"+"FindingsSubreport.jasper"]]></subreportExpression> <subreportExpression><![CDATA[$P{CDATA_FindingsSubreport}]]></subreportExpression>
</subreport> </subreport>
</band> </band>
</detail> </detail>

View File

@ -2,6 +2,9 @@
<!-- Created with Jaspersoft Studio version 6.20.0.final using JasperReports Library version 6.20.0-2bc7ab61c56f459e8176eb05c7705e145cd400ad --> <!-- 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"> <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"/> <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"> <queryString language="JSON">
<![CDATA[projectReportData]]> <![CDATA[projectReportData]]>
</queryString> </queryString>
@ -53,7 +56,7 @@
</ellipse> </ellipse>
<image> <image>
<reportElement x="539" y="3" width="23" height="24" uuid="75a577b3-42df-4d40-be10-d0991b2769e2"/> <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> </image>
<staticText> <staticText>
<reportElement x="0" y="0" width="432" height="30" forecolor="#FFFFFF" uuid="329f5881-cba9-4418-9ef0-99a6805906ba"/> <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 "$@"