Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,11 @@ public void eventHandlers(CdsRuntimeConfigurer configurer) {
new EndTransactionMalwareScanRunner(null, null, malwareScanner, runtime);
configurer.eventHandler(
new ReadAttachmentsHandler(
attachmentService, new AttachmentStatusValidator(), scanRunner, persistenceService));
attachmentService,
new AttachmentStatusValidator(),
scanRunner,
persistenceService,
scanClient != null));
} else {
logger.debug(
"No application service is available. Application service event handlers will not be registered.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,21 @@ public class ReadAttachmentsHandler implements EventHandler {
private final AttachmentStatusValidator statusValidator;
private final AsyncMalwareScanExecutor scanExecutor;
private final PersistenceService persistenceService;
private final boolean scannerAvailable;

public ReadAttachmentsHandler(
AttachmentService attachmentService,
AttachmentStatusValidator statusValidator,
AsyncMalwareScanExecutor scanExecutor,
PersistenceService persistenceService) {
PersistenceService persistenceService,
boolean scannerAvailable) {
this.attachmentService =
requireNonNull(attachmentService, "attachmentService must not be null");
this.statusValidator = requireNonNull(statusValidator, "statusValidator must not be null");
this.scanExecutor = requireNonNull(scanExecutor, "scanExecutor must not be null");
this.persistenceService =
requireNonNull(persistenceService, "persistenceService must not be null");
this.scannerAvailable = scannerAvailable;
}

@Before
Expand Down Expand Up @@ -174,7 +177,7 @@ private void verifyStatus(Path path, Attachments attachment) {
"In verify status for content id {} and status {}",
attachment.getContentId(),
currentStatus);
if (needsScan(currentStatus, attachment.getScannedAt())) {
if (scannerAvailable && needsScan(currentStatus, attachment.getScannedAt())) {
if (StatusCode.CLEAN.equals(currentStatus)) {
transitionToScanning(path.target().entity(), attachment);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ void setup() {
attachmentService,
attachmentStatusValidator,
asyncMalwareScanExecutor,
persistenceService);
persistenceService,
true);

readEventContext = mock(CdsReadEventContext.class);
}
Expand Down Expand Up @@ -423,6 +424,79 @@ void emptyContentIdAndEmptyContentReturnNullContent() {
assertThat(attachment.getContent()).isNull();
}

@Test
void scannerNotAvailable_staleCleanAttachmentIsNotRescanned() {
var handlerWithoutScanner =
new ReadAttachmentsHandler(
attachmentService,
attachmentStatusValidator,
asyncMalwareScanExecutor,
persistenceService,
false);
Comment thread
Schmarvinius marked this conversation as resolved.
mockEventContext(Attachment_.CDS_NAME, mock(CqnSelect.class));
var attachment = Attachments.create();
attachment.setContentId("some ID");
attachment.setContent(mock(InputStream.class));
attachment.setStatus(StatusCode.CLEAN);
attachment.setScannedAt(Instant.now().minus(4, ChronoUnit.DAYS));

handlerWithoutScanner.processAfter(readEventContext, List.of(attachment));

verifyNoInteractions(asyncMalwareScanExecutor);
verifyNoInteractions(persistenceService);
assertThat(attachment.getStatus()).isEqualTo(StatusCode.CLEAN);
}

@Test
void scannerNotAvailable_cleanAttachmentWithNullScannedAtIsNotRescanned() {
var handlerWithoutScanner =
new ReadAttachmentsHandler(
attachmentService,
attachmentStatusValidator,
asyncMalwareScanExecutor,
persistenceService,
false);
mockEventContext(Attachment_.CDS_NAME, mock(CqnSelect.class));
var attachment = Attachments.create();
attachment.setContentId("some ID");
attachment.setContent(mock(InputStream.class));
attachment.setStatus(StatusCode.CLEAN);
attachment.setScannedAt(null);

handlerWithoutScanner.processAfter(readEventContext, List.of(attachment));

verifyNoInteractions(asyncMalwareScanExecutor);
verifyNoInteractions(persistenceService);
assertThat(attachment.getStatus()).isEqualTo(StatusCode.CLEAN);
}

@Test
void scannerNotAvailable_unscannedAttachmentStillFailsValidation() {
var handlerWithoutScanner =
new ReadAttachmentsHandler(
attachmentService,
attachmentStatusValidator,
asyncMalwareScanExecutor,
persistenceService,
false);
mockEventContext(Attachment_.CDS_NAME, mock(CqnSelect.class));
var attachment = Attachments.create();
attachment.setContentId("some ID");
attachment.setContent(mock(InputStream.class));
attachment.setStatus(StatusCode.UNSCANNED);
doThrow(AttachmentStatusException.class)
.when(attachmentStatusValidator)
.verifyStatus(StatusCode.UNSCANNED);

List<CdsData> attachments = List.of(attachment);
assertThrows(
AttachmentStatusException.class,
() -> handlerWithoutScanner.processAfter(readEventContext, attachments));

verifyNoInteractions(asyncMalwareScanExecutor);
verifyNoInteractions(persistenceService);
}

private void mockEventContext(String entityName, CqnSelect select) {
var serviceEntity = runtime.getCdsModel().findEntity(entityName);
when(readEventContext.getTarget()).thenReturn(serviceEntity.orElseThrow());
Expand Down
Loading