IdmNotificationAttachmentController extends AbstractReadWriteDtoController<IdmNotificationAttachmentDto, IdmNotificationAttachmentFilter> { @RequestMapping(value = "/{backendId}/download", method = RequestMethod.GET) @ResponseBody @PreAuthorize("hasAuthority('" + NotificationGroupPermission.NOTIFICATION_READ + "')") @ApiOperation( value = "Download notification attachment", nickname = "downloadNotificationAttachment", tags = { IdmNotificationAttachmentController.TAG }, notes = "Returns input stream to notification attachment.", authorizations = { @Authorization(value = SwaggerConfig.AUTHENTICATION_BASIC, scopes = { @AuthorizationScope(scope = NotificationGroupPermission.NOTIFICATION_READ, description = "") }), @Authorization(value = SwaggerConfig.AUTHENTICATION_CIDMST, scopes = { @AuthorizationScope(scope = NotificationGroupPermission.NOTIFICATION_READ, description = "") }) }) public ResponseEntity<InputStreamResource> download( @ApiParam(value = "Notification attachment uuid identifier.", required = true) @PathVariable String backendId) { IdmNotificationAttachmentDto dto = getDto(backendId); if (dto == null) { throw new EntityNotFoundException(getService().getEntityClass(), backendId); } UUID attachmentId = dto.getAttachment(); IdmAttachmentDto attachment = attachmentManager.get(attachmentId); if (attachment == null) { throw new EntityNotFoundException(attachmentManager.getEntityClass(), attachmentId); } InputStream is = attachmentManager.getAttachmentData(attachment.getId()); try { BodyBuilder response = ResponseEntity .ok() .contentLength(is.available()) .header(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment; filename=\"%s\"", attachment.getName())); String mimetype = attachment.getMimetype(); if (StringUtils.isNotBlank(mimetype)) { response = response.contentType(MediaType.valueOf(attachment.getMimetype())); } return response.body(new InputStreamResource(is)); } catch (IOException e) { throw new ResultCodeException(CoreResultCode.INTERNAL_SERVER_ERROR, e); } } @Autowired  IdmNotificationAttachmentController(IdmNotificationAttachmentService service); @Override @ResponseBody @RequestMapping(method = RequestMethod.GET) @PreAuthorize("hasAuthority('" + NotificationGroupPermission.NOTIFICATION_READ + "')") @ApiOperation( value = "Search notification attachments (/search/quick alias)", nickname = "searchNotificationAttachments", tags = { IdmNotificationAttachmentController.TAG }, authorizations = { @Authorization(value = SwaggerConfig.AUTHENTICATION_BASIC, scopes = { @AuthorizationScope(scope = NotificationGroupPermission.NOTIFICATION_READ, description = "") }), @Authorization(value = SwaggerConfig.AUTHENTICATION_CIDMST, scopes = { @AuthorizationScope(scope = NotificationGroupPermission.NOTIFICATION_READ, description = "") }) }) Resources<?> find(
			@RequestParam(required = false) MultiValueMap<String, Object> parameters, 
			@PageableDefault Pageable pageable); @ResponseBody @PreAuthorize("hasAuthority('" + NotificationGroupPermission.NOTIFICATION_READ + "')") @RequestMapping(value = "/search/quick", method = RequestMethod.GET) @ApiOperation( value = "Search notification attachments", nickname = "searchQuickNotificationAttachments", tags = { IdmNotificationAttachmentController.TAG }, authorizations = { @Authorization(value = SwaggerConfig.AUTHENTICATION_BASIC, scopes = { @AuthorizationScope(scope = NotificationGroupPermission.NOTIFICATION_READ, description = "") }), @Authorization(value = SwaggerConfig.AUTHENTICATION_CIDMST, scopes = { @AuthorizationScope(scope = NotificationGroupPermission.NOTIFICATION_READ, description = "") }) }) Resources<?> findQuick(
			@RequestParam(required = false) MultiValueMap<String, Object> parameters,
			@PageableDefault Pageable pageable); @Override @ResponseBody @RequestMapping(value = "/search/count", method = RequestMethod.GET) @PreAuthorize("hasAuthority('" + NotificationGroupPermission.NOTIFICATION_COUNT + "')") @ApiOperation( value = "The number of entities that match the filter", nickname = "countNotificationAttachments", tags = { IdmNotificationAttachmentController.TAG }, authorizations = { @Authorization(value = SwaggerConfig.AUTHENTICATION_BASIC, scopes = { @AuthorizationScope(scope = NotificationGroupPermission.NOTIFICATION_COUNT, description = "") }), @Authorization(value = SwaggerConfig.AUTHENTICATION_CIDMST, scopes = { @AuthorizationScope(scope = NotificationGroupPermission.NOTIFICATION_COUNT, description = "") }) }) long count(@RequestParam(required = false) MultiValueMap<String, Object> parameters); @Override @ResponseBody @PreAuthorize("hasAuthority('" + NotificationGroupPermission.NOTIFICATION_READ + "')") @RequestMapping(value = "/{backendId}", method = RequestMethod.GET) @ApiOperation( value = "Notification attachment detail", nickname = "getNotificationAttachment", response = IdmNotificationAttachmentDto.class, tags = { IdmNotificationAttachmentController.TAG }, authorizations = { @Authorization(value = SwaggerConfig.AUTHENTICATION_BASIC, scopes = { @AuthorizationScope(scope = NotificationGroupPermission.NOTIFICATION_READ, description = "") }), @Authorization(value = SwaggerConfig.AUTHENTICATION_CIDMST, scopes = { @AuthorizationScope(scope = NotificationGroupPermission.NOTIFICATION_READ, description = "") }) }) ResponseEntity<?> get(
			@ApiParam(value = "Notification attachment uuid identifier.", required = true)
			@PathVariable @NotNull String backendId); @Override @ResponseBody @RequestMapping(value = "/{backendId}/permissions", method = RequestMethod.GET) @PreAuthorize("hasAuthority('" + NotificationGroupPermission.NOTIFICATION_READ + "')") @ApiOperation( value = "What logged identity can do with given record", nickname = "getPermissionsOnNotificationAttachment", tags = { IdmNotificationAttachmentController.TAG }, authorizations = { @Authorization(value = SwaggerConfig.AUTHENTICATION_BASIC, scopes = { @AuthorizationScope(scope = NotificationGroupPermission.NOTIFICATION_READ, description = "")}), @Authorization(value = SwaggerConfig.AUTHENTICATION_CIDMST, scopes = { @AuthorizationScope(scope = NotificationGroupPermission.NOTIFICATION_READ, description = "")}) }) Set<String> getPermissions(
			@ApiParam(value = "Notification attachment uuid identifier.", required = true)
			@PathVariable @NotNull String backendId); @RequestMapping(value = "/{backendId}/download", method = RequestMethod.GET) @ResponseBody @PreAuthorize("hasAuthority('" + NotificationGroupPermission.NOTIFICATION_READ + "')") @ApiOperation( value = "Download notification attachment", nickname = "downloadNotificationAttachment", tags = { IdmNotificationAttachmentController.TAG }, notes = "Returns input stream to notification attachment.", authorizations = { @Authorization(value = SwaggerConfig.AUTHENTICATION_BASIC, scopes = { @AuthorizationScope(scope = NotificationGroupPermission.NOTIFICATION_READ, description = "") }), @Authorization(value = SwaggerConfig.AUTHENTICATION_CIDMST, scopes = { @AuthorizationScope(scope = NotificationGroupPermission.NOTIFICATION_READ, description = "") }) }) ResponseEntity<InputStreamResource> download(
			@ApiParam(value = "Notification attachment uuid identifier.", required = true)
			@PathVariable String backendId);  }
@Test public void testDownload() throws Exception { NotificationConfigurationDto config = createConfig(); IdmNotificationTemplateDto template = createTestTemplate(); IdmIdentityDto identity = getHelper().createIdentity((GuardedString) null); IdmAttachmentDto attachmentOne = DefaultAttachmentManagerIntegrationTest.prepareDtoWithoutContent(); attachmentOne.setInputData(IOUtils.toInputStream(getHelper().createName())); IdmAttachmentDto attachment = DefaultAttachmentManagerIntegrationTest.prepareDtoWithoutContent(); String content = getHelper().createName(); attachment.setInputData(IOUtils.toInputStream(content)); IdmAttachmentDto attachmentTwo = attachmentManager.saveAttachment(identity, attachment); List<IdmAttachmentDto> attachments = Lists.newArrayList(attachmentOne, attachmentTwo); List<IdmNotificationLogDto> notifications = notificationManager.send( config.getTopic(), new IdmMessageDto.Builder().setTemplate(template).build(), null, Lists.newArrayList(identity), attachments); Assert.assertEquals(1, notifications.size()); Assert.assertTrue(notifications.stream().anyMatch(n -> n.getType().equals(IdmEmailLog.NOTIFICATION_TYPE))); IdmNotificationLogDto notification = notifications.get(0); IdmNotificationAttachmentFilter notificationAttachmentFilter = new IdmNotificationAttachmentFilter(); notificationAttachmentFilter.setNotification(notification.getId()); List<IdmNotificationAttachmentDto> notificationAttachments = notificationAttachmentService.find(notificationAttachmentFilter, null).getContent(); Assert.assertEquals(2, notificationAttachments.size()); Assert.assertTrue(notificationAttachments.stream().allMatch(na -> na.getAttachment() != null)); Assert.assertTrue(notificationAttachments.stream().anyMatch(na -> na.getAttachment().equals(attachmentTwo.getId()))); IdmNotificationAttachmentDto notificationAttachment = notificationAttachments .stream() .filter(na -> na.getAttachment().equals(attachmentTwo.getId())) .findFirst() .get(); String response = getMockMvc().perform(MockMvcRequestBuilders.get(getDetailUrl(notificationAttachment.getId()) + "/download") .with(authentication(getAdminAuthentication()))) .andExpect(status().isOk()) .andReturn() .getResponse() .getContentAsString(); Assert.assertEquals(content, response); getMockMvc().perform(MockMvcRequestBuilders.get(getDetailUrl(UUID.randomUUID()) + "/download") .with(authentication(getAdminAuthentication()))) .andExpect(status().isNotFound()); attachmentManager.delete(attachmentTwo); getMockMvc().perform(MockMvcRequestBuilders.get(getDetailUrl(notificationAttachment.getId()) + "/download") .with(authentication(getAdminAuthentication()))) .andExpect(status().isNotFound()); }