Skip to content

Commit

Permalink
feat(license): Update Whitelist
Browse files Browse the repository at this point in the history
Signed-off-by: tuannn2 <tuan2.nguyennhu@toshiba.co.jp>
  • Loading branch information
tuannn2 committed Feb 2, 2024
1 parent 325ac54 commit 0e39dc1
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 11 deletions.
14 changes: 14 additions & 0 deletions rest/resource-server/src/docs/asciidoc/licenses.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,20 @@ include::{snippets}/should_document_update_license/http-response.adoc[]
===== Links
include::{snippets}/should_document_update_license/links.adoc[]

[[resources-update-whitelist-license]]
==== Update whitelist a license

A `PATCH` request will update external link license.

===== Response structure
include::{snippets}/should_document_update_whitelist_license/response-fields.adoc[]

===== Example request
include::{snippets}/should_document_update_whitelist_license/curl-request.adoc[]

===== Example response
include::{snippets}/should_document_update_whitelist_license/http-response.adoc[]

[[resources-license-link-obligation]]
==== Link obligations to license

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1099,7 +1099,6 @@ static abstract class VendorMixin extends Vendor {
"id",
"revision",
"reviewdate",
"obligations",
"obligationListId",
"osiapproved",
"fsflibre",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,13 @@ public void addEmbeddedLicenses(HalResource<Release> halComponent, Set<String> l
}
}

public Set<String> getObligationIdsFromRequestWithValueTrue(Map<String, Boolean> reqBodyMaps) {
Map<String, Boolean> obligationIdsRequest = reqBodyMaps.entrySet().stream()
.filter(reqBodyMap-> reqBodyMap.getValue().equals(true))
.collect(Collectors.toMap(reqBodyMap-> reqBodyMap.getKey(),reqBodyMap -> reqBodyMap.getValue()));
return obligationIdsRequest.keySet();
}

private HalResource<License> addEmbeddedLicense(String licenseId) {
License embeddedLicense = convertToEmbeddedLicense(licenseId);
HalResource<License> halLicense = new HalResource<>(embeddedLicense);
Expand Down Expand Up @@ -882,6 +889,7 @@ public Release convertToEmbeddedRelease(Release release, List<String> fields) {
return embeddedRelease;
}


public License convertToEmbeddedLicense(License license) {
License embeddedLicense = new License();
embeddedLicense.setId(license.getId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
package org.eclipse.sw360.rest.resourceserver.license;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
Expand All @@ -20,6 +21,7 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.thrift.TException;
import org.eclipse.sw360.datahandler.common.CommonUtils;
import org.eclipse.sw360.datahandler.thrift.RequestStatus;
import org.eclipse.sw360.datahandler.thrift.RequestSummary;
import org.eclipse.sw360.datahandler.thrift.licenses.License;
Expand All @@ -38,6 +40,7 @@
import org.springframework.http.HttpStatus.Series;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.HttpClientErrorException;
Expand All @@ -48,10 +51,8 @@
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;

Expand Down Expand Up @@ -178,6 +179,43 @@ public ResponseEntity<EntityModel<License>> updateLicense(
return new ResponseEntity<>(halResource, HttpStatus.OK);
}

@PreAuthorize("hasAuthority('WRITE')")
@RequestMapping(value = LICENSES_URL+ "/{id}/whitelist", method = RequestMethod.PATCH)
public ResponseEntity<EntityModel<License>> updateWhitelist(
@PathVariable("id") String licenseId,
@RequestBody Map<String, Boolean> reqBodyMaps) throws TException {
User sw360User = restControllerHelper.getSw360UserFromAuthentication();
License license = licenseService.getLicenseById(licenseId);
Set<String> obligationIdsByLicense = new HashSet<>();
if (!CommonUtils.isNullOrEmptyCollection(license.getObligationDatabaseIds())) {
obligationIdsByLicense = license.getObligationDatabaseIds();
}
Map<String, Boolean> obligationIdsRequest = reqBodyMaps.entrySet().stream()
.collect(Collectors.toMap(reqBodyMap-> reqBodyMap.getKey(), reqBodyMap -> reqBodyMap.getValue()));
Set<String> obligationIds = obligationIdsRequest.keySet();

Set<String> commonExtIds = Sets.intersection(obligationIdsByLicense, obligationIds);
Set<String> diffIds = Sets.difference(obligationIdsByLicense, obligationIds);
if (commonExtIds.size() != obligationIds.size()) {
throw new HttpMessageNotReadableException("Obligation Ids not in license!" + license.getShortname());
}

Set<String> obligationIdTrue = licenseService.getIdObligationsContainWhitelist(sw360User, licenseId, diffIds);
obligationIdTrue.addAll(restControllerHelper.getObligationIdsFromRequestWithValueTrue(reqBodyMaps));

RequestStatus requestStatus = licenseService.updateWhitelist(obligationIdTrue, licenseId, sw360User);
HalResource<License> halResource;
if (requestStatus == RequestStatus.SENT_TO_MODERATOR) {
return new ResponseEntity(RESPONSE_BODY_FOR_MODERATION_REQUEST, HttpStatus.ACCEPTED);
} else if (requestStatus == RequestStatus.SUCCESS) {
License licenseUpdate = licenseService.getLicenseById(licenseId);
halResource = createHalLicense(licenseUpdate);
return new ResponseEntity<>(halResource, HttpStatus.OK);
} else {
return new ResponseEntity("Update Whitelist to Obligation Fail!",HttpStatus.INTERNAL_SERVER_ERROR);
}
}

@Operation(
summary = "Link obligations to a license.",
description = "Link a set of obligations to a license.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import lombok.NonNull;
import lombok.RequiredArgsConstructor;

import com.google.common.collect.ImmutableSet;
import org.apache.commons.lang.StringUtils;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TCompactProtocol;
Expand Down Expand Up @@ -48,12 +49,7 @@
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.zip.ZipOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
Expand Down Expand Up @@ -153,6 +149,26 @@ public RequestStatus updateLicense(License license, User sw360User) throws TExce
return sw360LicenseClient.updateLicense(license, sw360User, sw360User);
}

public Set<String> getIdObligationsContainWhitelist(User sw360User, String licenseId, Set<String> diffIds) throws TException {
Set<String> obligationIdTrue = new HashSet<>();
String organisation = sw360User.getDepartment();
String businessUnit = SW360Utils.getBUFromOrganisation(organisation);
List<Obligation> obligations = getObligationsByLicenseId(licenseId);
for (Obligation obligation : obligations) {
String obligationId = obligation.getId();
Set<String> currentWhitelist = obligation.whitelist != null ? obligation.whitelist : new HashSet<>();
if (diffIds.contains(obligationId) && currentWhitelist.contains(businessUnit)) {
obligationIdTrue.add(obligationId);
}
}
return obligationIdTrue;
}

public RequestStatus updateWhitelist(Set<String> obligationIds, String licenseId, User user) throws TException {
LicenseService.Iface sw360LicenseClient = getThriftLicenseClient();
return sw360LicenseClient.updateWhitelist(licenseId, ImmutableSet.copyOf(obligationIds), user);
}

public List<Obligation> getObligationsByLicenseId(String id) throws TException {
LicenseService.Iface sw360LicenseClient = getThriftLicenseClient();
List<Obligation> obligations = sw360LicenseClient.getObligationsByLicenseId(id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ public void before() throws TException, IOException {
given(this.licenseServiceMock.getLicenseById(eq(license.getId()))).willReturn(license);
given(this.licenseServiceMock.createLicense(any(), any())).willReturn(license3);
given(this.licenseServiceMock.updateLicense(any(),any())).willReturn(RequestStatus.SUCCESS);
given(this.licenseServiceMock.updateWhitelist(any(),any(),any())).willReturn(RequestStatus.SUCCESS);
Mockito.doNothing().when(licenseServiceMock).deleteLicenseById(any(), any());
Mockito.doNothing().when(licenseServiceMock).deleteAllLicenseInfo(any());
Mockito.doNothing().when(licenseServiceMock).importSpdxInformation(any());
Expand All @@ -131,13 +132,15 @@ public void before() throws TException, IOException {
obligation1.setId("0001");
obligation1.setTitle("Obligation 1");
obligation1.setText("This is text of Obligation 1");
obligation1.setWhitelist(Collections.singleton("Department"));
obligation1.setObligationType(ObligationType.PERMISSION);
obligation1.setObligationLevel(ObligationLevel.LICENSE_OBLIGATION);

obligation2 = new Obligation();
obligation2.setId("0002");
obligation2.setTitle("Obligation 2");
obligation2.setText("This is text of Obligation 2");
obligation2.setWhitelist(Collections.singleton("Department2"));
obligation2.setObligationType(ObligationType.OBLIGATION);
obligation2.setObligationLevel(ObligationLevel.LICENSE_OBLIGATION);

Expand Down Expand Up @@ -165,6 +168,48 @@ public void should_document_get_licenses() throws Exception {
)));
}

@Test
public void should_document_update_whitelist_license() throws Exception {
List<Obligation> obligationList = new ArrayList<>();
obligationList.add(obligation1);
obligationList.add(obligation2);
license.setObligations(obligationList);

Set<String> obligationIds = new HashSet<String>();
obligationIds.add(obligation1.getId());
obligationIds.add(obligation2.getId());
license.setObligationDatabaseIds(obligationIds);

Map<String, Boolean> requestBody = new HashMap<>();
requestBody.put("0001",true);
requestBody.put("0002",true);

String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword);
mockMvc.perform(MockMvcRequestBuilders.patch("/api/licenses/" + license.getId() +"/whitelist")
.contentType(MediaTypes.HAL_JSON)
.content(this.objectMapper.writeValueAsString(requestBody))
.header("Authorization", "Bearer" + accessToken)
.accept(MediaTypes.HAL_JSON))
.andExpect(status().isOk())
.andDo(this.documentationHandler.document(
responseFields(
fieldWithPath("fullName").description("The full name of the license"),
fieldWithPath("shortName").description("The short name of the license, optional"),
subsectionWithPath("externalIds").description("When releases are imported from other tools, the external ids can be stored here"),
fieldWithPath("externalLicenseLink").description("The external license link of the license"),
subsectionWithPath("additionalData").description("A place to store additional data used by external tools"),
subsectionWithPath("obligations").description("The obligations license link of the license"),
subsectionWithPath("obligationDatabaseIds").description("The obligationDatabaseIds license link of the license"),
fieldWithPath("text").description("The license's original text"),
fieldWithPath("checked").description("The information, whether the license is already checked, optional and defaults to true"),
subsectionWithPath("OSIApproved").description("The OSI aprroved information, possible values are: " + Arrays.asList(Quadratic.values())),
fieldWithPath("FSFLibre").description("The FSF libre information, possible values are: " + Arrays.asList(Quadratic.values())),
subsectionWithPath("_embedded.sw360:obligations").description("An array of <<resources-obligations, Obligations obligations>>"),
subsectionWithPath("_links").description("<<resources-index-links,Links>> to other resources"),
fieldWithPath("note").description("The license's note")
)));
}

@Test
public void should_document_get_license() throws Exception {
List<Obligation> obligationList = new ArrayList<>();
Expand Down Expand Up @@ -192,6 +237,7 @@ public void should_document_get_license() throws Exception {
subsectionWithPath("externalIds").description("When releases are imported from other tools, the external ids can be stored here"),
fieldWithPath("externalLicenseLink").description("The external license link of the license"),
subsectionWithPath("additionalData").description("A place to store additional data used by external tools"),
subsectionWithPath("obligations").description("The obligations license link of the license"),
subsectionWithPath("obligationDatabaseIds").description("The obligationDatabaseIds license link of the license"),
fieldWithPath("text").description("The license's original text"),
fieldWithPath("checked").description("The information, whether the license is already checked, optional and defaults to true"),
Expand Down

0 comments on commit 0e39dc1

Please sign in to comment.