Skip to content

Commit

Permalink
[Fix] Sanitize exported terms file name to ASCII to prevent issues wi…
Browse files Browse the repository at this point in the history
…th its downloading.

(cherry picked from commit 092410a)
  • Loading branch information
ledsoft committed Apr 19, 2023
1 parent ebf5e9e commit 3f16496
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 26 deletions.
52 changes: 26 additions & 26 deletions src/main/java/cz/cvut/kbss/termit/rest/TermController.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ private Optional<ResponseEntity<?>> exportTerms(Vocabulary vocabulary, ExportTyp
.contentLength(r.contentLength())
.contentType(MediaType.parseMediaType(mediaType))
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + IdentifierResolver.extractIdentifierFragment(
vocabulary.getUri()) +
"attachment; filename=\"" + IdentifierResolver.normalizeToAscii(IdentifierResolver.extractIdentifierFragment(
vocabulary.getUri())) +
r.getFileExtension().orElse("") + "\"")
.body(r);
} catch (IOException e) {
Expand Down Expand Up @@ -202,9 +202,9 @@ public List<TermDto> getAllRoots(@PathVariable String vocabularyIdFragment,
defaultValue = "") List<URI> includeTerms) {
final Vocabulary vocabulary = getVocabulary(getVocabularyUri(namespace, vocabularyIdFragment));
return includeImported ?
termService
.findAllRootsIncludingImported(vocabulary, createPageRequest(pageSize, pageNo), includeTerms) :
termService.findAllRoots(vocabulary, createPageRequest(pageSize, pageNo), includeTerms);
termService
.findAllRootsIncludingImported(vocabulary, createPageRequest(pageSize, pageNo), includeTerms) :
termService.findAllRoots(vocabulary, createPageRequest(pageSize, pageNo), includeTerms);
}

/**
Expand Down Expand Up @@ -264,10 +264,10 @@ public Term getById(@PathVariable("termIdFragment") String termIdFragment,

private URI getTermUri(String vocabIdFragment, String termIdFragment, Optional<String> namespace) {
return idResolver.resolveIdentifier(idResolver
.buildNamespace(
getVocabularyUri(namespace, vocabIdFragment).toString(),
config.getNamespace().getTerm().getSeparator()),
termIdFragment);
.buildNamespace(
getVocabularyUri(namespace, vocabIdFragment).toString(),
config.getNamespace().getTerm().getSeparator()),
termIdFragment);
}

/**
Expand Down Expand Up @@ -469,7 +469,7 @@ public void runTextAnalysisOnTerm(@PathVariable String vocabularyIdFragment,
@RequestParam(name = QueryParams.NAMESPACE, required = false)
Optional<String> namespace) {
termService.analyzeTermDefinition(getById(vocabularyIdFragment, termIdFragment, namespace),
getVocabularyUri(namespace, vocabularyIdFragment));
getVocabularyUri(namespace, vocabularyIdFragment));
}

@PutMapping(value = "/terms/{termIdFragment}/definition-source",
Expand Down Expand Up @@ -548,8 +548,8 @@ public List<Comment> getComments(@PathVariable("vocabularyIdFragment") String vo
required = false) Optional<String> namespace) {
final URI termUri = getTermUri(vocabularyIdFragment, termIdFragment, namespace);
return termService.getComments(termService.getRequiredReference(termUri),
from.map(RestUtils::parseTimestamp).orElse(Constants.EPOCH_TIMESTAMP),
to.map(RestUtils::parseTimestamp).orElse(Utils.timestamp()));
from.map(RestUtils::parseTimestamp).orElse(Constants.EPOCH_TIMESTAMP),
to.map(RestUtils::parseTimestamp).orElse(Utils.timestamp()));
}

/**
Expand All @@ -567,8 +567,8 @@ public List<Comment> getComments(@PathVariable("termIdFragment") String termIdFr
@RequestParam(name = QueryParams.NAMESPACE) String namespace) {
final URI termUri = idResolver.resolveIdentifier(namespace, termIdFragment);
return termService.getComments(termService.getRequiredReference(termUri),
from.map(RestUtils::parseTimestamp).orElse(Constants.EPOCH_TIMESTAMP),
to.map(RestUtils::parseTimestamp).orElse(Utils.timestamp()));
from.map(RestUtils::parseTimestamp).orElse(Constants.EPOCH_TIMESTAMP),
to.map(RestUtils::parseTimestamp).orElse(Utils.timestamp()));
}

/**
Expand All @@ -586,12 +586,12 @@ public ResponseEntity<Void> addComment(@PathVariable("vocabularyIdFragment") Str
termService.addComment(comment, term);
LOG.debug("Comment added to term {}.", term);
return ResponseEntity.created(RestUtils
.createLocationFromCurrentContextWithPathAndQuery("/comments/{name}",
QueryParams.NAMESPACE,
IdentifierResolver.extractIdentifierNamespace(
comment.getUri()),
IdentifierResolver.extractIdentifierFragment(
comment.getUri())))
.createLocationFromCurrentContextWithPathAndQuery("/comments/{name}",
QueryParams.NAMESPACE,
IdentifierResolver.extractIdentifierNamespace(
comment.getUri()),
IdentifierResolver.extractIdentifierFragment(
comment.getUri())))
.build();
}

Expand All @@ -612,12 +612,12 @@ public ResponseEntity<Void> addComment(@PathVariable("termIdFragment") String te
termService.addComment(comment, term);
LOG.debug("Comment added to term {}.", term);
return ResponseEntity.created(RestUtils
.createLocationFromCurrentContextWithPathAndQuery("/comments/{name}",
QueryParams.NAMESPACE,
IdentifierResolver.extractIdentifierNamespace(
comment.getUri()),
IdentifierResolver.extractIdentifierFragment(
comment.getUri())))
.createLocationFromCurrentContextWithPathAndQuery("/comments/{name}",
QueryParams.NAMESPACE,
IdentifierResolver.extractIdentifierNamespace(
comment.getUri()),
IdentifierResolver.extractIdentifierFragment(
comment.getUri())))
.build();
}

Expand Down
24 changes: 24 additions & 0 deletions src/test/java/cz/cvut/kbss/termit/rest/TermControllerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1189,4 +1189,28 @@ void getSnapshotsThrowsBadRequestWhenAtIsNotValidInstantString() throws Exceptio
void getTermsReturnsNotAcceptableWhenAskingForUnsupportedMediaType() throws Exception {
mockMvc.perform(get("/terms").accept(MediaType.APPLICATION_PDF_VALUE)).andExpect(status().isNotAcceptable());
}

@Test
void getAllSanitizesFilenameInContentDispositionHeaderToAscii() throws Exception {
final String name = "metropolitní-plán";
final String sanitizedName = "metropolitni-plan";
final URI vocabularyUri = URI.create(Environment.BASE_URI + "/" + name);
when(idResolverMock.resolveIdentifier(config.getNamespace().getVocabulary(), name))
.thenReturn(vocabularyUri);
final cz.cvut.kbss.termit.model.Vocabulary vocabulary = Generator.generateVocabulary();
vocabulary.setUri(vocabularyUri);
when(termServiceMock.findVocabularyRequired(vocabulary.getUri())).thenReturn(vocabulary);
final TypeAwareByteArrayResource export = prepareTurtle();
when(termServiceMock.exportGlossary(vocabulary, new ExportConfig(ExportType.SKOS,
ExportFormat.TURTLE.getMediaType()))).thenReturn(
Optional.of(export));

final MvcResult mvcResult = mockMvc
.perform(get(URI.create(PATH + name + "/terms")).accept(ExportFormat.TURTLE.getMediaType())
.queryParam("exportType", ExportType.SKOS.toString()))
.andReturn();
assertThat(mvcResult.getResponse().getHeader(HttpHeaders.CONTENT_DISPOSITION), containsString("attachment"));
assertThat(mvcResult.getResponse().getHeader(HttpHeaders.CONTENT_DISPOSITION),
containsString("filename=\"" + sanitizedName + ExportFormat.TURTLE.getFileExtension() + "\""));
}
}

0 comments on commit 3f16496

Please sign in to comment.