diff --git a/backend/src-common/src/main/resources/sw360.properties b/backend/src-common/src/main/resources/sw360.properties index d236e8e0b1..590841eeec 100644 --- a/backend/src-common/src/main/resources/sw360.properties +++ b/backend/src-common/src/main/resources/sw360.properties @@ -124,8 +124,10 @@ textForRejectedClearingRequest= your clearing request with id: %s for the projec enable.sw360.change.log=false sw360changelog.output.path=sw360changelog/sw360changelog auto.set.ecc.status=false -send.project.spreadsheet.export.to.mail.enabled=false -send.component.spreadsheet.export.to.mail.enabled=false + +##This property is used to enable mail request for projects/components report. +#send.project.spreadsheet.export.to.mail.enabled=false +#send.component.spreadsheet.export.to.mail.enabled=false ## This property is used to enable the bulk release deleting feature. #bulk.release.deleting.enabled=true diff --git a/libraries/datahandler/src/main/java/org/eclipse/sw360/datahandler/common/SW360Constants.java b/libraries/datahandler/src/main/java/org/eclipse/sw360/datahandler/common/SW360Constants.java index b4a80e4d29..68c63596fa 100644 --- a/libraries/datahandler/src/main/java/org/eclipse/sw360/datahandler/common/SW360Constants.java +++ b/libraries/datahandler/src/main/java/org/eclipse/sw360/datahandler/common/SW360Constants.java @@ -123,6 +123,8 @@ public class SW360Constants { public static final String SRC_ATTACHMENT_UPLOADER_EMAIL; public static final String SRC_ATTACHMENT_DOWNLOAD_LOCATION; public static final String PREFERRED_CLEARING_DATE_LIMIT; + public static final Boolean MAIL_REQUEST_FOR_PROJECT_REPORT; + public static final Boolean MAIL_REQUEST_FOR_COMPONENT_REPORT; /** * Hashmap containing the name field for each type. @@ -228,6 +230,8 @@ private SW360Constants() { SRC_ATTACHMENT_UPLOADER_EMAIL = props.getProperty("source.code.attachment.uploader.email", ""); SRC_ATTACHMENT_DOWNLOAD_LOCATION = props.getProperty("src.attachment.download.location", ""); PREFERRED_CLEARING_DATE_LIMIT = props.getProperty("preferred.clearing.date.limit",""); + MAIL_REQUEST_FOR_PROJECT_REPORT = Boolean.parseBoolean(props.getProperty("send.project.spreadsheet.export.to.mail.enabled", "false")); + MAIL_REQUEST_FOR_COMPONENT_REPORT = Boolean.parseBoolean(props.getProperty("send.component.spreadsheet.export.to.mail.enabled", "false")); } private static Map.Entry pair(TFieldIdEnum field, String displayName){ diff --git a/rest/resource-server/src/docs/asciidoc/components.adoc b/rest/resource-server/src/docs/asciidoc/components.adoc index 79763e851a..8f82ab896c 100644 --- a/rest/resource-server/src/docs/asciidoc/components.adoc +++ b/rest/resource-server/src/docs/asciidoc/components.adoc @@ -560,20 +560,3 @@ include::{snippets}/should_document_get_component_report/curl-request.adoc[] ===== Example response include::{snippets}/should_document_get_component_report/http-response.adoc[] - -[[resources-components-download-report-mail_req]] -==== Downloading component report with mail request - -A `GET` request help to download the components report with mail request. - -===== Request parameter -include::{snippets}/should_document_get_component_report_with_mail_req/request-parameters.adoc[] - -===== Response structure -include::{snippets}/should_document_get_component_report_with_mail_req/response-fields.adoc[] - -===== Example request -include::{snippets}/should_document_get_component_report_with_mail_req/curl-request.adoc[] - -===== Example response -include::{snippets}/should_document_get_component_report_with_mail_req/http-response.adoc[] diff --git a/rest/resource-server/src/docs/asciidoc/projects.adoc b/rest/resource-server/src/docs/asciidoc/projects.adoc index af0f308960..dd9f23f3d1 100644 --- a/rest/resource-server/src/docs/asciidoc/projects.adoc +++ b/rest/resource-server/src/docs/asciidoc/projects.adoc @@ -851,28 +851,11 @@ include::{snippets}/should_document_create_summary_administration/http-response. [[resources-projects-download-report]] ==== Downloading project report -A `GET` request help to download the projects report with mail request false. - -===== Request parameter -include::{snippets}/should_document_get_project_report_without_mail_req/request-parameters.adoc[] - -===== Example request -include::{snippets}/should_document_get_project_report_without_mail_req/curl-request.adoc[] - -===== Example response -include::{snippets}/should_document_get_project_report_without_mail_req/http-response.adoc[] - -[[resources-projects-download-report-mail-request]] -==== Downloading project report with mail request - -A `GET` request help to download the projects report with mail request true. +A `GET` request help to download the projects report. ===== Request parameter include::{snippets}/should_document_get_project_report/request-parameters.adoc[] -===== Response structure -include::{snippets}/should_document_get_project_report/response-fields.adoc[] - ===== Example request include::{snippets}/should_document_get_project_report/curl-request.adoc[] @@ -932,29 +915,11 @@ include::{snippets}/should_document_update_project_with_network/http-response.ad [[resources-projects-download-licenseclearing-report]] ==== Downloading project license clearing report -A `GET` request help to download the projects report with mail request false. - -===== Request parameter -include::{snippets}/should_document_get_project_licenseclearing_spreadsheet_without_mail_req/request-parameters.adoc[] - -===== Example request -include::{snippets}/should_document_get_project_licenseclearing_spreadsheet_without_mail_req/curl-request.adoc[] - -===== Example response -include::{snippets}/should_document_get_project_licenseclearing_spreadsheet_without_mail_req/http-response.adoc[] - - -[[resources-projects-download-licenseclearing-report-mail-request]] -==== Downloading project license clearing report with mail request - -A `GET` request help to download the projects report with mail request true. +A `GET` request help to download project license clearing report. ===== Request parameter include::{snippets}/should_document_get_project_licenseclearing_spreadsheet/request-parameters.adoc[] -===== Response structure -include::{snippets}/should_document_get_project_licenseclearing_spreadsheet/response-fields.adoc[] - ===== Example request include::{snippets}/should_document_get_project_licenseclearing_spreadsheet/curl-request.adoc[] @@ -977,3 +942,4 @@ include::{snippets}/should_document_create_clearing_request/curl-request.adoc[] ===== Example response include::{snippets}/should_document_create_clearing_request/http-response.adoc[] + diff --git a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/report/SW360ReportController.java b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/report/SW360ReportController.java index c7f0ff95a6..bed7fe04b5 100644 --- a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/report/SW360ReportController.java +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/report/SW360ReportController.java @@ -11,6 +11,7 @@ import java.nio.ByteBuffer; import java.util.Arrays; import java.util.List; +import java.util.Properties; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -22,6 +23,8 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import org.apache.thrift.TException; +import org.eclipse.sw360.datahandler.common.CommonUtils; +import org.eclipse.sw360.datahandler.common.SW360Constants; import org.eclipse.sw360.datahandler.common.SW360Utils; import org.eclipse.sw360.datahandler.thrift.users.User; import org.eclipse.sw360.rest.resourceserver.core.RestControllerHelper; @@ -79,8 +82,6 @@ public void getProjectReport( @RequestParam(value = "withlinkedreleases", required = false, defaultValue = "false") boolean withLinkedReleases, @Parameter(description = "Report download format.", schema = @Schema(allowableValues = {"xls", "xlsx"})) @RequestParam(value = "mimetype", required = false, defaultValue = "xlsx") String mimeType, - @Parameter(description = "Downloading project report required mail link.") - @RequestParam(value = "mailrequest", required = false, defaultValue = "false") boolean mailRequest, @Parameter(description = "Project id.") @RequestParam(value = "projectId", required = false) String projectId, @Parameter(description = "Module name.", schema = @Schema(allowableValues = {PROJECTS, COMPONENTS})) @@ -93,17 +94,19 @@ public void getProjectReport( try { if (validateMimeType(mimeType)) { switch (module) { - case PROJECTS: - getProjectReports(withLinkedReleases, mailRequest, response, request, sw360User, module, projectId); - break; - case COMPONENTS: - getComponentsReports(withLinkedReleases, mailRequest, response, request, sw360User, module); - break; - case LICENSES: - getLicensesReports(response, sw360User, module); - break; - default: - break; + case PROJECTS: + getProjectReports(withLinkedReleases, SW360Constants.MAIL_REQUEST_FOR_PROJECT_REPORT, response, + request, sw360User, module, projectId); + break; + case COMPONENTS: + getComponentsReports(withLinkedReleases, SW360Constants.MAIL_REQUEST_FOR_COMPONENT_REPORT, response, + request, sw360User, module); + break; + case LICENSES: + getLicensesReports(response, sw360User, module); + break; + default: + break; } } else { throw new TException("Error : Mimetype either should be : xls/xlsx"); @@ -119,7 +122,7 @@ private void getProjectReports(boolean withLinkedReleases, boolean mailRequest, if (mailRequest) { sw360ReportService.getUploadedProjectPath(sw360User, withLinkedReleases,getBaseUrl(request), projectId); JsonObject responseJson = new JsonObject(); - responseJson.addProperty("response", "Project report download link will get send to the end user."); + responseJson.addProperty("response", "The downloaded report link will be send to the end user."); response.getWriter().write(responseJson.toString()); } else { downloadExcelReport(withLinkedReleases, response, sw360User, module, projectId); @@ -210,6 +213,7 @@ private boolean validateMimeType(String mimeType) { ) @GetMapping(value = REPORTS_URL + "/download") public void downloadExcel( + HttpServletRequest request, HttpServletResponse response, @Parameter(description = "Module name.", schema = @Schema(allowableValues = {PROJECTS, COMPONENTS})) @RequestParam(value = "module", required = true) String module, @@ -218,9 +222,7 @@ public void downloadExcel( @Parameter(description = "Extended by releases.") @RequestParam(value = "extendedByReleases", required = false, defaultValue = "false") boolean extendedByReleases ) throws TException { - final User sw360User = restControllerHelper.getSw360UserFromAuthentication(); - User user = restControllerHelper.getUserByEmail(sw360User.getEmail()); - String fileConstant = module+"-%s.xlsx"; + final User user = restControllerHelper.getUserByEmail(request.getParameter("user")); try { ByteBuffer buffer = null; switch (module) { @@ -239,9 +241,16 @@ public void downloadExcel( if (null == buffer) { throw new TException("No data available for the user " + user.getEmail()); } - String filename = String.format(fileConstant, SW360Utils.getCreatedOn()); + String fileName; + if(module.equals(LICENSES)) { + fileName = String.format("licenses-%s.xlsx", SW360Utils.getCreatedOn()); + } else if(module.equals(PROJECTS)) { + fileName = sw360ReportService.getDocumentName(user, request.getParameter("projectId")); + }else { + fileName = sw360ReportService.getDocumentName(user, null); + } response.setContentType(CONTENT_TYPE); - response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", filename)); + response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", fileName)); copyDataStreamToResponse(response, buffer); } catch (Exception e) { throw new TException(e.getMessage()); diff --git a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/report/SW360ReportService.java b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/report/SW360ReportService.java index 872c663066..9c850eba8e 100644 --- a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/report/SW360ReportService.java +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/report/SW360ReportService.java @@ -33,23 +33,43 @@ public class SW360ReportService { LicenseService.Iface licenseClient = thriftClients.makeLicenseClient(); public ByteBuffer getProjectBuffer(User user, boolean extendedByReleases, String projectId) throws TException { + if (projectId != null && validateProject(projectId, user)) { + throw new TException("No project record found for the project Id : " + projectId); + } return projectclient.getReportDataStream(user, extendedByReleases, projectId); } + private boolean validateProject(String projectId, User user) throws TException { + boolean validProject = true; + try { + Project project = projectclient.getProjectById(projectId, user); + if (project == null) { + return false; + } + } catch (Exception e) { + validProject = false; + } + return validProject; + } + public String getDocumentName(User user, String projectId) throws TException { - if (projectId != null) { + if (projectId != null && !projectId.equalsIgnoreCase("null")) { Project project = projectclient.getProjectById(projectId, user); return String.format("project-%s-%s-%s.xlsx", project.getName(), project.getVersion(), SW360Utils.getCreatedOn()); } return String.format("projects-%s.xlsx", SW360Utils.getCreatedOn()); } - public void getUploadedProjectPath(User user, boolean withLinkedReleases, String base, String projectId){ + public void getUploadedProjectPath(User user, boolean withLinkedReleases, String base, String projectId) + throws TException { + if (projectId!=null && !validateProject(projectId, user)) { + throw new TException("No project record found for the project Id : " + projectId); + } Runnable asyncRunnable = () -> wrapTException(() -> { try { String projectPath = projectclient.getReportInEmail(user, withLinkedReleases, projectId); String backendURL = base + "api/reports/download?user=" + user.getEmail() + "&module=projects" - + "&extendedByReleases=" + withLinkedReleases + "&token="; + + "&extendedByReleases=" + withLinkedReleases + "&projectId=" + projectId + "&token="; URL emailURL = new URL(backendURL + projectPath); if (!CommonUtils.isNullEmptyOrWhitespace(projectPath)) { sendExportSpreadsheetSuccessMail(emailURL.toString(), user.getEmail()); diff --git a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/security/ResourceServerConfiguration.java b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/security/ResourceServerConfiguration.java index 5ea9ac09b8..1e33994efc 100644 --- a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/security/ResourceServerConfiguration.java +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/security/ResourceServerConfiguration.java @@ -96,6 +96,7 @@ public void configure(HttpSecurity http) throws Exception { .antMatchers(HttpMethod.GET, "/health").permitAll() .antMatchers(HttpMethod.GET, "/info").hasAuthority("WRITE") .antMatchers(HttpMethod.GET, "/api").permitAll() + .antMatchers(HttpMethod.GET, "/api/reports/download").permitAll() .antMatchers(HttpMethod.GET, "/api/**").hasAuthority("READ") .antMatchers(HttpMethod.POST, "/api/**").hasAuthority("WRITE") .antMatchers(HttpMethod.PUT, "/api/**").hasAuthority("WRITE") diff --git a/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ComponentSpecTest.java b/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ComponentSpecTest.java index 07b89b904f..30c9a26f46 100644 --- a/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ComponentSpecTest.java +++ b/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ComponentSpecTest.java @@ -1355,7 +1355,6 @@ public void should_document_get_component_report() throws Exception{ .header("Authorization", "Bearer " + accessToken) .param("withlinkedreleases", "true") .param("mimetype", "xlsx") - .param("mailrequest", "false") .param("module", "components") .accept(MediaTypes.HAL_JSON)) .andExpect(status().isOk()) @@ -1363,31 +1362,8 @@ public void should_document_get_component_report() throws Exception{ requestParameters( parameterWithName("withlinkedreleases").description("Projects with linked releases. Possible values are ``"), parameterWithName("mimetype").description("Projects download format. Possible values are ``"), - parameterWithName("mailrequest").description("Downloading project report requirted mail link. Possible values are ``"), parameterWithName("module").description("module represent the project or component. Possible values are ``") ))); } - @Test - public void should_document_get_component_report_with_mail_req() throws Exception{ - String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword); - mockMvc.perform(get("/api/reports") - .header("Authorization", "Bearer " + accessToken) - .param("withlinkedreleases", "true") - .param("mimetype", "xlsx") - .param("mailrequest", "true") - .param("module", "components") - .accept(MediaTypes.HAL_JSON)) - .andExpect(status().isOk()) - .andDo(this.documentationHandler.document( - requestParameters( - parameterWithName("withlinkedreleases").description("components with linked releases. Possible values are ``"), - parameterWithName("mimetype").description("components download format. Possible values are ``"), - parameterWithName("module").description("module represent the project or component. Possible values are ``"), - parameterWithName("mailrequest").description("Downloading components report requirted mail link. Possible values are ``") - ),responseFields( - subsectionWithPath("response").description("The response message displayed").optional() - ) - )); - } } diff --git a/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ProjectSpecTest.java b/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ProjectSpecTest.java index 90b60e5df0..0994916f9f 100644 --- a/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ProjectSpecTest.java +++ b/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ProjectSpecTest.java @@ -541,6 +541,8 @@ public void before() throws TException, IOException { RequestSummary requestSummaryForCycloneDX = new RequestSummary(); requestSummaryForCycloneDX.setMessage("{\"projectId\":\"" + cycloneDXProject.getId() + "\"}"); + + String projectName="project_name_version_createdOn.xlsx"; AddDocumentRequestSummary requestSummaryForCR = new AddDocumentRequestSummary(); requestSummaryForCR.setMessage("Clearing request created successfully"); @@ -552,6 +554,7 @@ public void before() throws TException, IOException { given(this.projectServiceMock.importSPDX(any(),any())).willReturn(requestSummaryForSPDX); given(this.projectServiceMock.importCycloneDX(any(),any(),any())).willReturn(requestSummaryForCycloneDX); + given(this.sw360ReportServiceMock.getDocumentName(any(), any())).willReturn(projectName); given(this.sw360ReportServiceMock.getProjectBuffer(any(),anyBoolean(),any())).willReturn(ByteBuffer.allocate(10000)); given(this.projectServiceMock.getProjectsForUser(any(), any())).willReturn(projectList); given(this.projectServiceMock.getProjectForUserById(eq(project.getId()), any())).willReturn(project); @@ -2270,46 +2273,21 @@ public void should_document_create_summary_administration() throws Exception { } @Test - public void should_document_get_project_report() throws Exception{ - String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword); - mockMvc.perform(get("/api/reports") - .header("Authorization", "Bearer " + accessToken) - .param("withlinkedreleases", "true") - .param("mimetype", "xlsx") - .param("mailrequest", "true") - .param("module", "projects") - .accept(MediaTypes.HAL_JSON)) - .andExpect(status().isOk()) - .andDo(this.documentationHandler.document( - requestParameters( - parameterWithName("withlinkedreleases").description("Projects with linked releases. Possible values are ``"), - parameterWithName("mimetype").description("Projects download format. Possible values are ``"), - parameterWithName("mailrequest").description("Downloading project report requirted mail link. Possible values are ``"), - parameterWithName("module").description("module represent the project or component. Possible values are ``") - ),responseFields( - subsectionWithPath("response").description("The response message displayed").optional() - ) - )); - } - - @Test - public void should_document_get_project_report_without_mail_req() throws Exception { + public void should_document_get_project_report() throws Exception { String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword); - mockMvc.perform(get("/api/reports") - .header("Authorization", "Bearer " + accessToken) - .param("withlinkedreleases", "true") - .param("mimetype", "xlsx") - .param("mailrequest", "false") - .param("module", "projects") - .accept("application/xhtml+xml")) + mockMvc.perform(get("/api/reports"). + header("Authorization", "Bearer " + accessToken) + .param("withlinkedreleases", "true") + .param("mimetype", "xlsx") + .param("module", "projects") + .accept(MediaTypes.HAL_JSON)) .andExpect(status().isOk()) .andDo(this.documentationHandler.document( - requestParameters( - parameterWithName("withlinkedreleases").description("Projects with linked releases. Possible values are ``"), - parameterWithName("mimetype").description("Projects download format. Possible values are ``"), - parameterWithName("mailrequest").description("Downloading project report requirted mail link. Possible values are ``"), - parameterWithName("module").description("module represent the project or component. Possible values are ``") - ))); + requestParameters( + parameterWithName("withlinkedreleases").description("Projects with linked releases. Possible values are ``"), + parameterWithName("mimetype").description("Projects download format. Possible values are ``"), + parameterWithName("module").description("module represent the project or component. Possible values are ``")) + )); } @Test @@ -2319,7 +2297,6 @@ public void should_document_get_project_licenseclearing_spreadsheet() throws Exc .header("Authorization", "Bearer " + accessToken) .param("withlinkedreleases", "true") .param("mimetype", "xlsx") - .param("mailrequest", "true") .param("module", "projects") .param("projectId", project.getId()) .accept(MediaTypes.HAL_JSON)) @@ -2328,37 +2305,11 @@ public void should_document_get_project_licenseclearing_spreadsheet() throws Exc requestParameters( parameterWithName("withlinkedreleases").description("Projects with linked releases. Possible values are ``"), parameterWithName("mimetype").description("Projects download format. Possible values are ``"), - parameterWithName("mailrequest").description("Downloading project report requirted mail link. Possible values are ``"), parameterWithName("module").description("module represent the project or component. Possible values are ``"), - parameterWithName("projectId").description("Id of a project") - ),responseFields( - subsectionWithPath("response").description("The response message displayed").optional() - ) + parameterWithName("projectId").description("Id of a project")) )); } - @Test - public void should_document_get_project_licenseclearing_spreadsheet_without_mail_req() throws Exception{ - String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword); - mockMvc.perform(get("/api/reports") - .header("Authorization", "Bearer " + accessToken) - .param("withlinkedreleases", "true") - .param("mimetype", "xlsx") - .param("mailrequest", "false") - .param("module", "projects") - .param("projectId", project.getId()) - .accept("application/xhtml+xml")) - .andExpect(status().isOk()) - .andDo(this.documentationHandler.document( - requestParameters( - parameterWithName("withlinkedreleases").description("Projects with linked releases. Possible values are ``"), - parameterWithName("mimetype").description("Projects download format. Possible values are ``"), - parameterWithName("mailrequest").description("Downloading project report requirted mail link. Possible values are ``"), - parameterWithName("module").description("module represent the project or component. Possible values are ``"), - parameterWithName("projectId").description("Id of a project") - ))); - } - @Test public void should_document_import_cyclonedx() throws Exception { MockMultipartFile file = new MockMultipartFile("file","file=@/sampleBOM.xml".getBytes());