diff --git a/save-backend/src/main/kotlin/com/saveourtool/save/backend/controllers/vulnerability/event/VulnerabilityMetadataListener.kt b/save-backend/src/main/kotlin/com/saveourtool/save/backend/controllers/vulnerability/event/VulnerabilityMetadataListener.kt new file mode 100644 index 0000000000..98223c6c5c --- /dev/null +++ b/save-backend/src/main/kotlin/com/saveourtool/save/backend/controllers/vulnerability/event/VulnerabilityMetadataListener.kt @@ -0,0 +1,47 @@ +package com.saveourtool.save.backend.controllers.vulnerability.event + +import com.saveourtool.save.backend.service.NotificationService +import com.saveourtool.save.backend.service.UserDetailsService +import com.saveourtool.save.domain.Role +import com.saveourtool.save.entities.Notification +import com.saveourtool.save.entities.cosv.VulnerabilityMetadata +import com.saveourtool.save.entities.cosv.evententities.VulnerabilityMetadataEvent +import com.saveourtool.save.entities.vulnerability.VulnerabilityStatus +import org.springframework.context.event.EventListener +import org.springframework.stereotype.Component + +/** + * A vulnerability metadata listener for sending notifications. + */ +@Component +class VulnerabilityMetadataListener( + private val userDetailsService: UserDetailsService, + private val notificationService: NotificationService, +) { + /** + * @param vulnerabilityEvent new VulnerabilityMetadataEvent + */ + @EventListener + fun createVulnerabilityMetadata(vulnerabilityEvent: VulnerabilityMetadataEvent) { + if (vulnerabilityEvent.vulnerabilityMetadata.status == VulnerabilityStatus.PENDING_REVIEW) { + val recipients = userDetailsService.findByRole(Role.SUPER_ADMIN.asSpringSecurityRole()) + val notifications = recipients.map { + Notification( + message = messageNewVulnerabilityMetadata(vulnerabilityEvent.vulnerabilityMetadata), + user = it, + ) + } + notificationService.saveAll(notifications) + } + } + + companion object { + /** + * @param vulnerability + * @return message + */ + fun messageNewVulnerabilityMetadata(vulnerability: VulnerabilityMetadata) = """ + New vulnerability: ${vulnerability.identifier} is waiting for approve. + """.trimIndent() + } +} diff --git a/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/cosv/evententities/VulnerabilityMetadataEvent.kt b/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/cosv/evententities/VulnerabilityMetadataEvent.kt new file mode 100644 index 0000000000..cd2ee90db2 --- /dev/null +++ b/save-cloud-common/src/jvmMain/kotlin/com/saveourtool/save/entities/cosv/evententities/VulnerabilityMetadataEvent.kt @@ -0,0 +1,10 @@ +package com.saveourtool.save.entities.cosv.evententities + +import com.saveourtool.save.entities.cosv.VulnerabilityMetadata + +/** + * @property vulnerabilityMetadata + **/ +data class VulnerabilityMetadataEvent( + var vulnerabilityMetadata: VulnerabilityMetadata +) diff --git a/save-cosv/src/main/kotlin/com/saveourtool/save/cosv/service/VulnerabilityMetadataService.kt b/save-cosv/src/main/kotlin/com/saveourtool/save/cosv/service/VulnerabilityMetadataService.kt index 401ed17dc4..0760b39c65 100644 --- a/save-cosv/src/main/kotlin/com/saveourtool/save/cosv/service/VulnerabilityMetadataService.kt +++ b/save-cosv/src/main/kotlin/com/saveourtool/save/cosv/service/VulnerabilityMetadataService.kt @@ -11,6 +11,7 @@ import com.saveourtool.save.entities.cosv.CosvFile import com.saveourtool.save.entities.cosv.VulnerabilityMetadata import com.saveourtool.save.entities.cosv.VulnerabilityMetadataDto import com.saveourtool.save.entities.cosv.VulnerabilityMetadataDto.Companion.SUMMARY_LENGTH +import com.saveourtool.save.entities.cosv.evententities.VulnerabilityMetadataEvent import com.saveourtool.save.entities.vulnerability.VulnerabilityLanguage import com.saveourtool.save.entities.vulnerability.VulnerabilityStatus import com.saveourtool.save.utils.ELLIPSIS @@ -22,6 +23,7 @@ import com.saveourtool.save.utils.warn import com.saveourtool.osv4k.Severity import com.saveourtool.osv4k.SeverityType +import org.springframework.context.ApplicationEventPublisher import org.springframework.http.HttpStatus import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @@ -36,6 +38,7 @@ import kotlinx.datetime.toJavaLocalDateTime class VulnerabilityMetadataService( private val vulnerabilityMetadataRepository: VulnerabilityMetadataRepository, private val cosvFileS3KeyManager: CosvFileS3KeyManager, + private val applicationEventPublisher: ApplicationEventPublisher, ) { /** * @param cosvFile @@ -60,7 +63,9 @@ class VulnerabilityMetadataService( existedMetadata.updateBy(cosv, cosvFile, isAutoApprove) } ?: run { - cosv.toNewMetadata(user, organization, cosvFile, isAutoApprove) + val newMetadata = cosv.toNewMetadata(user, organization, cosvFile, isAutoApprove) + applicationEventPublisher.publishEvent(VulnerabilityMetadataEvent(newMetadata)) + newMetadata } return vulnerabilityMetadataRepository.save(metadata)