Skip to content

Commit a6543bf

Browse files
feat(rest) : Endpoint for export SBOM at project detail page
1 parent cb52c1a commit a6543bf

File tree

3 files changed

+91
-2
lines changed

3 files changed

+91
-2
lines changed

libraries/datahandler/src/main/java/org/eclipse/sw360/datahandler/common/SW360Constants.java

+4
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ public class SW360Constants {
138138
public static final String ADD_LIST_EMAIL = "listEmail";
139139
public static final String DEPARTMENT_KEY = "departmentKey";
140140
public static final String DELETE_LIST_EMAIL = "deleteEmail";
141+
public static final String SBOM = "sbom";
142+
141143

142144
/**
143145
* Hashmap containing the name field for each type.
@@ -162,6 +164,8 @@ public class SW360Constants {
162164
AttachmentType.COMPONENT_LICENSE_INFO_COMBINED, AttachmentType.INITIAL_SCAN_REPORT);
163165
public static final Collection<AttachmentType> SOURCE_CODE_ATTACHMENT_TYPES = Arrays.asList(AttachmentType.SOURCE, AttachmentType.SOURCE_SELF);
164166
public static final String CONTENT_TYPE_OPENXML_SPREADSHEET = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
167+
public static final String CONTENT_TYPE_XML = "application/xml";
168+
public static final String CONTENT_TYPE_JSON = "application/json";
165169

166170
public static final String NOTIFICATION_CLASS_RELEASE = "release";
167171
public static final String NOTIFICATION_CLASS_MODERATION_REQUEST = "moderation";

rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/report/SW360ReportController.java

+42-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import static com.google.common.base.Strings.isNullOrEmpty;
99
import static org.eclipse.sw360.datahandler.common.SW360Constants.CONTENT_TYPE_OPENXML_SPREADSHEET;
10+
import static org.eclipse.sw360.datahandler.common.SW360Constants.XML_FILE_EXTENSION;
1011
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
1112

1213
import java.io.IOException;
@@ -35,6 +36,7 @@
3536
import org.springframework.data.rest.webmvc.RepositoryLinksResource;
3637
import org.springframework.hateoas.server.RepresentationModelProcessor;
3738
import org.springframework.http.converter.HttpMessageNotReadableException;
39+
import org.springframework.security.access.AccessDeniedException;
3840
import org.springframework.util.FileCopyUtils;
3941
import org.springframework.web.bind.annotation.GetMapping;
4042
import org.springframework.web.bind.annotation.RequestParam;
@@ -84,7 +86,7 @@ public void getProjectReport(
8486
@Parameter(description = "Module name.", schema = @Schema(allowableValues = {
8587
SW360Constants.PROJECTS, SW360Constants.COMPONENTS, SW360Constants.LICENSES,
8688
LICENSE_INFO, LICENSES_RESOURCE_BUNDLE, SW360Constants.PROJECT_RELEASE_SPREADSHEET_WITH_ECCINFO,
87-
EXPORT_CREATE_PROJ_CLEARING_REPORT
89+
EXPORT_CREATE_PROJ_CLEARING_REPORT,SW360Constants.SBOM
8890
}))
8991
@RequestParam(value = "module", required = true) String module,
9092
@Parameter(description = "Exclude release version from the license info file")
@@ -101,6 +103,8 @@ public void getProjectReport(
101103
@RequestParam(value = "externalIds", required = false, defaultValue = "") String externalIds,
102104
@Parameter(description = "Generate report for only current project or with Sub projects. Can be supplied with modules [" + LICENSE_INFO + ", " + EXPORT_CREATE_PROJ_CLEARING_REPORT + "]")
103105
@RequestParam(value = "withSubProject", required = false, defaultValue = "false") boolean withSubProject,
106+
@Parameter(description = "Type of SBOM file extention")
107+
@RequestParam(value = "bomType", required = false) String bomType,
104108
HttpServletRequest request,
105109
HttpServletResponse response
106110
) throws TException {
@@ -139,10 +143,18 @@ public void getProjectReport(
139143
exportProjectCreateClearingRequest(response, sw360User, module, projectId, excludeReleaseVersion,
140144
generatorClassName, variant, template, externalIds);
141145
break;
146+
case SW360Constants.SBOM:
147+
exportSBOM(response, sw360User, module, projectId,generatorClassName,
148+
bomType,withSubProject);
149+
break;
142150
default:
143151
break;
144152
}
145-
} catch (Exception e) {
153+
}
154+
catch (AccessDeniedException e) {
155+
throw e;
156+
}
157+
catch (Exception e) {
146158
throw new TException(e.getMessage());
147159
}
148160
}
@@ -371,4 +383,32 @@ private String getBaseUrl(HttpServletRequest request) {
371383
String ctx = request.getContextPath();
372384
return url.substring(0, url.length() - uri.length() + ctx.length()) + "/";
373385
}
386+
387+
388+
private void exportSBOM(
389+
HttpServletResponse response, User sw360User, String module, String projectId,
390+
String generatorClassName, String bomType, boolean withSubProject
391+
) throws TException {
392+
try {
393+
String buff = sw360ReportService.getProjectSBOMBuffer(sw360User, projectId, bomType, withSubProject);
394+
response.setContentType(SW360Constants.CONTENT_TYPE_JSON);
395+
String fileName = sw360ReportService.getSBOMFileName(sw360User, projectId, module, bomType);
396+
if (null == buff) {
397+
throw new TException("No data available for the user " + sw360User.getEmail());
398+
}
399+
if (SW360Constants.XML_FILE_EXTENSION.equalsIgnoreCase(bomType)) {
400+
response.setContentType(SW360Constants.CONTENT_TYPE_XML);
401+
}
402+
response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", fileName));
403+
copyDataStreamToResponse(response, ByteBuffer.wrap(buff.getBytes()));
404+
}
405+
catch (AccessDeniedException e) {
406+
log.error(e);
407+
throw e;
408+
}
409+
catch (Exception e) {
410+
log.error(e);
411+
throw new TException(e.getMessage());
412+
}
413+
}
374414
}

rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/report/SW360ReportService.java

+45
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@
3434
import org.eclipse.sw360.datahandler.thrift.users.User;
3535
import org.eclipse.sw360.exporter.ReleaseExporter;
3636
import org.springframework.beans.factory.annotation.Autowired;
37+
import org.springframework.security.access.AccessDeniedException;
3738
import org.springframework.stereotype.Service;
39+
import org.eclipse.sw360.datahandler.thrift.RequestSummary;
40+
import org.eclipse.sw360.datahandler.thrift.RequestStatus;
41+
import org.eclipse.sw360.datahandler.thrift.SW360Exception;
3842

3943
import lombok.RequiredArgsConstructor;
4044

@@ -437,4 +441,45 @@ public ByteBuffer getProjectReleaseSpreadSheetWithEcc(User user, String projectI
437441
}
438442
return ByteBuffer.wrap(IOUtils.toByteArray(exporter.makeExcelExport(releases)));
439443
}
444+
445+
public String getProjectSBOMBuffer(User user, String projectId, String bomType, boolean withSubProject) throws TException {
446+
String bomString = "";
447+
if (CommonUtils.isNotNullEmptyOrWhitespace(projectId)) {
448+
if (CommonUtils.isNullEmptyOrWhitespace(bomType)) {
449+
throw new SW360Exception("Bom type cannot be empty");
450+
}
451+
RequestSummary summary = projectclient.exportCycloneDxSbom(projectId, bomType, withSubProject, user);
452+
RequestStatus status = summary.getRequestStatus();
453+
if (RequestStatus.FAILED_SANITY_CHECK.equals(status)) {
454+
bomString = status.name();
455+
throw new SW360Exception(bomString);
456+
} else if (RequestStatus.ACCESS_DENIED.equals(status)) {
457+
bomString = status.name() + ", only user with role " + SW360Constants.SBOM_IMPORT_EXPORT_ACCESS_USER_ROLE + " can access.";
458+
throw new AccessDeniedException(bomString);
459+
} else if (RequestStatus.FAILURE.equals(status)) {
460+
bomString = status.name() + "-" + summary.getMessage() ;
461+
throw new SW360Exception(bomString);
462+
} else {
463+
bomString = summary.getMessage();
464+
}
465+
}
466+
else{
467+
throw new SW360Exception("Project Id cannot be empty");
468+
}
469+
return bomString;
470+
}
471+
472+
public String getSBOMFileName(User user, String projectId, String module, String bomType) throws TException {
473+
String documentName = "";
474+
if(projectId != null && !projectId.equalsIgnoreCase("null")) {
475+
Project project = projectclient.getProjectById(projectId, user);
476+
documentName = String.format("project_%s(%s)_%s.xml", project.getName(), project.getVersion(),
477+
SW360Utils.getCreatedOnTime(), "_SBOM");
478+
if(SW360Constants.JSON_FILE_EXTENSION.equalsIgnoreCase(bomType)){
479+
documentName = String.format("project_%s(%s)_%s.json", project.getName(), project.getVersion(),
480+
SW360Utils.getCreatedOnTime(), "_SBOM");
481+
}
482+
}
483+
return documentName;
484+
}
440485
}

0 commit comments

Comments
 (0)