Skip to content
Open
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 @@ -30,6 +30,7 @@ public class ReportDownloadHelper implements Serializable {
private static final Trace LOGGER = TraceManager.getTrace(ReportDownloadHelper.class);
private static final String DOT_CLASS = ReportDownloadHelper.class.getName() + ".";
private static final String OPERATION_DOWNLOAD_REPORT = DOT_CLASS + ".downloadReport";
private static final String ZIP_EXTENSION = "zip";

private static final Map<FileFormatTypeType, String> REPORT_EXPORT_TYPE_MAP = new HashMap<>();
static {
Expand Down Expand Up @@ -61,11 +62,26 @@ public static String getReportFileName(ReportDataType currentReport) {
if (StringUtils.isNotEmpty(name)) {
// Sanitize to remove any path components for defense in depth
// (browsers also ignore path components, but better to be safe)
return FilenameUtils.getName(name);
String sanitizedName = FilenameUtils.getName(name);
if (isZipReport(currentReport) && !hasZipExtension(sanitizedName)) {
return sanitizedName + "." + ZIP_EXTENSION;
}
return sanitizedName;
}
return "report"; // A fallback - this should not really occur
}

private static boolean isZipReport(ReportDataType report) {
// ReportDataType has no ZIP file-format enum value, tracing stores ZIP outputs as files with .zip suffix.
return report != null
&& report.getFilePath() != null
&& hasZipExtension(report.getFilePath());
}

private static boolean hasZipExtension(String fileName) {
return ZIP_EXTENSION.equalsIgnoreCase(FilenameUtils.getExtension(fileName));
}

public static InputStream createReport(ReportDataType report,
AjaxDownloadBehaviorFromStream ajaxDownloadBehaviorFromStream, PageBase pageBase) {
OperationResult result = new OperationResult(OPERATION_DOWNLOAD_REPORT);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright (C) 2026 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.web;

import static org.testng.Assert.assertEquals;

import com.evolveum.midpoint.web.page.admin.reports.ReportDownloadHelper;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.testng.Assert;
import org.testng.annotations.Test;

import com.evolveum.midpoint.gui.test.TestMidPointSpringApplication;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ReportDataType;
import com.evolveum.prism.xml.ns._public.types_3.PolyStringType;

@ActiveProfiles("test")
@SpringBootTest(classes = TestMidPointSpringApplication.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class ReportDownloadHelperTest extends AbstractGuiIntegrationTest {

@Test
public void zipReportFileNameHasZipExtension() {
ReportDataType report = report("trace-2026", "C:\\midpoint\\trace\\trace-2026.zip");

Assert.assertEquals(ReportDownloadHelper.getReportFileName(report), "trace-2026.zip");
}

@Test
public void zipReportFileNameDoesNotDuplicateZipExtension() {
ReportDataType report = report("trace-2026.zip", "C:\\midpoint\\trace\\trace-2026.zip");

assertEquals(ReportDownloadHelper.getReportFileName(report), "trace-2026.zip");
}

@Test
public void nonZipReportFileNameIsNotChanged() {
ReportDataType report = report("report-output", "C:\\midpoint\\export\\report-output.csv");

assertEquals(ReportDownloadHelper.getReportFileName(report), "report-output");
}

@Test
public void pathComponentsAreRemovedBeforeAppendingZipExtension() {
ReportDataType report = report("C:\\tmp\\trace-2026", "C:\\midpoint\\trace\\trace-2026.zip");

assertEquals(ReportDownloadHelper.getReportFileName(report), "trace-2026.zip");
}

@Test
public void reportWithoutFilePathDoesNotGetZipExtension() {
ReportDataType report = report("trace-2026", null);

assertEquals(ReportDownloadHelper.getReportFileName(report), "trace-2026");
}

private static ReportDataType report(String name, String filePath) {
ReportDataType report = new ReportDataType()
.filePath(filePath);
if (name != null) {
report.name(new PolyStringType(name));
}
return report;
}
}
1 change: 1 addition & 0 deletions gui/admin-gui/testng-integration.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<class name="com.evolveum.midpoint.web.RequestAccessTest"/>
<class name="com.evolveum.midpoint.web.TestDisplayLabelLocalization"/>
<class name="com.evolveum.midpoint.web.component.FileValidatorTest"/>
<class name="com.evolveum.midpoint.web.ReportDownloadHelperTest"/>
</classes>
</test>
</suite>
1 change: 1 addition & 0 deletions release-notes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ Overall, midPoint 4.10 opens up the world of identity management and governance
* Delineation suggestions: filter parsing broken after recent GUI change. See bug:MID-11175[]
* Fixed work item search by name causing repository mapping error. See bug:MID-8834[]
* Fixed translation of archetype display labels in assignment picker and summary panel. See bug:MID-11177[]
* Fixed missing .zip extension when downloading tracing report files. See bug:MID-11096[]

=== Releases Of Other Components

Expand Down
Loading