Skip to content

Commit

Permalink
fix(rest) : Closed Project functionalities not uniform with respect t…
Browse files Browse the repository at this point in the history
…o UI and REST

Signed-off-by: Keerthi B L <[email protected]>
  • Loading branch information
keerthi-bl authored and GMishx committed Dec 16, 2024
1 parent 6005fc1 commit c8b2756
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@
*/
package org.eclipse.sw360.datahandler.permissions;

import java.util.Properties;
import java.util.Set;
import java.util.*;

import org.eclipse.sw360.datahandler.common.CommonUtils;
import org.eclipse.sw360.datahandler.common.DatabaseSettings;
import org.eclipse.sw360.datahandler.thrift.components.Component;
import org.eclipse.sw360.datahandler.thrift.components.Release;
import org.eclipse.sw360.datahandler.thrift.licenses.License;
import org.eclipse.sw360.datahandler.thrift.projects.Project;
import org.eclipse.sw360.datahandler.thrift.projects.ProjectClearingState;
import org.eclipse.sw360.datahandler.thrift.users.User;
import org.eclipse.sw360.datahandler.thrift.users.UserGroup;
import org.eclipse.sw360.datahandler.thrift.vendors.Vendor;
Expand Down Expand Up @@ -48,6 +48,17 @@ public class PermissionUtils {
System.getProperty("RunPrivateProjectAccessTest", props.getProperty("admin.private.project.access.enabled", "false")));
}

public static final Set<String> CLOSED_PROJECT_EDITABLE_PARAMS = Set.of(
"enableSvm",
"enableVulnerabilitiesDisplay",
"projectManager",
"projectOwner",
"securityResponsibles",
"externalIds",
"state",
"phaseOutSince"
);

public static boolean isNormalUser(User user) {
return isInGroup(user, UserGroup.USER);
}
Expand Down Expand Up @@ -174,4 +185,31 @@ public static <T> DocumentPermissions<T> makePermission(T document, User user) {
}
}

public static boolean checkEditablePermission(String name, User user, Map<String, Object> reqBodyMap, Project sw360Project) {
if (!name.equals(ProjectClearingState.CLOSED.name()) || PermissionUtils.isAdmin(user)) {
return true;
} else {
if ((reqBodyMap.containsKey("attachments") || reqBodyMap.containsKey("obligationsText")
|| reqBodyMap.containsKey("linkedObligationId")) && !PermissionUtils.isAdmin(user)) {
return false;
}
String createdBy = sw360Project.getCreatedBy();
String projectResponsible = sw360Project.getProjectResponsible();
Set<String> projModerators = sw360Project.getModerators();
Set<String> projContributors = sw360Project.getContributors();
String leadArchitect = sw360Project.getLeadArchitect();
Optional<String> match = CLOSED_PROJECT_EDITABLE_PARAMS.stream()
.filter(reqBodyMap::containsKey)
.findAny();
if (match.isPresent() && (PermissionUtils.isAdmin(user)
|| PermissionUtils.isClearingAdmin(user)
|| user.getUserGroup().name().equalsIgnoreCase(UserGroup.CLEARING_EXPERT.name())
|| PermissionUtils.isClearingExpert(user)) || user.getEmail().equals(createdBy)
|| user.getEmail().equals(projectResponsible) || user.getEmail().equals(leadArchitect)
|| projModerators.contains(user.getEmail()) || projContributors.contains(user.getEmail())) {
return true;
}
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
import org.eclipse.sw360.datahandler.thrift.projects.ProjectDTO;
import org.eclipse.sw360.datahandler.thrift.projects.ClearingRequest;
import org.eclipse.sw360.datahandler.thrift.users.User;
import org.eclipse.sw360.datahandler.thrift.users.UserGroup;
import org.eclipse.sw360.datahandler.thrift.vendors.Vendor;
import org.eclipse.sw360.datahandler.thrift.vulnerabilities.ProjectVulnerabilityRating;
import org.eclipse.sw360.datahandler.thrift.vulnerabilities.VulnerabilityCheckStatus;
Expand Down Expand Up @@ -125,6 +126,7 @@
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.PathVariable;
Expand Down Expand Up @@ -1573,21 +1575,26 @@ public ResponseEntity<EntityModel<Project>> patchProject(
@Parameter(description = "Updated values", schema = @Schema(implementation = Project.class))
@RequestBody Map<String, Object> reqBodyMap
) throws TException {
User user = restControllerHelper.getSw360UserFromAuthentication();
Project sw360Project = projectService.getProjectForUserById(id, user);
Project updateProject = convertToProject(reqBodyMap);
updateProject.unsetReleaseRelationNetwork();
sw360Project = this.restControllerHelper.updateProject(sw360Project, updateProject, reqBodyMap, mapOfProjectFieldsToRequestBody);
if (SW360Constants.ENABLE_FLEXIBLE_PROJECT_RELEASE_RELATIONSHIP && updateProject.getReleaseIdToUsage() != null) {
sw360Project.unsetReleaseRelationNetwork();
projectService.syncReleaseRelationNetworkAndReleaseIdToUsage(sw360Project, user);
}
RequestStatus updateProjectStatus = projectService.updateProject(sw360Project, user);
HalResource<Project> userHalResource = createHalProject(sw360Project, user);
if (updateProjectStatus == RequestStatus.SENT_TO_MODERATOR) {
return new ResponseEntity(RESPONSE_BODY_FOR_MODERATION_REQUEST, HttpStatus.ACCEPTED);
}
return new ResponseEntity<>(userHalResource, HttpStatus.OK);
User user = restControllerHelper.getSw360UserFromAuthentication();
Project sw360Project = projectService.getProjectForUserById(id, user);
boolean editPermitted = PermissionUtils.checkEditablePermission(sw360Project.getClearingState().name(),user,reqBodyMap, sw360Project);
if (!editPermitted) {
log.error("No write permission for project");
throw new AccessDeniedException("No write permission for project");
}
Project updateProject = convertToProject(reqBodyMap);
updateProject.unsetReleaseRelationNetwork();
sw360Project = this.restControllerHelper.updateProject(sw360Project, updateProject, reqBodyMap, mapOfProjectFieldsToRequestBody);
if (SW360Constants.ENABLE_FLEXIBLE_PROJECT_RELEASE_RELATIONSHIP && updateProject.getReleaseIdToUsage() != null) {
sw360Project.unsetReleaseRelationNetwork();
projectService.syncReleaseRelationNetworkAndReleaseIdToUsage(sw360Project, user);
}
RequestStatus updateProjectStatus = projectService.updateProject(sw360Project, user);
HalResource<Project> userHalResource = createHalProject(sw360Project, user);
if (updateProjectStatus == RequestStatus.SENT_TO_MODERATOR) {
return new ResponseEntity(RESPONSE_BODY_FOR_MODERATION_REQUEST, HttpStatus.ACCEPTED);
}
return new ResponseEntity<>(userHalResource, HttpStatus.OK);
}

@Operation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1958,14 +1958,15 @@ public void should_document_create_duplicate_project() throws Exception {

@Test
public void should_document_update_project() throws Exception {
project.setClearingState(ProjectClearingState.OPEN);
Project updateProject = new Project();
updateProject.setName("updated project");
updateProject.setDescription("Project description updated");
updateProject.setVersion("1.0");
updateProject.setState(ProjectState.PHASE_OUT);
updateProject.setPhaseOutSince("2020-06-24");
this.mockMvc
.perform(patch("/api/projects/376576").contentType(MediaTypes.HAL_JSON)
.perform(patch("/api/projects/"+project.getId()).contentType(MediaTypes.HAL_JSON)
.content(this.objectMapper.writeValueAsString(updateProject))
.header("Authorization", TestHelper.generateAuthHeader(testUserId, testUserPassword)).accept(MediaTypes.HAL_JSON))
.andExpect(status().isOk())
Expand Down Expand Up @@ -2041,6 +2042,7 @@ public void should_document_update_project() throws Exception {
subsectionWithPath("externalUrls").description("A place to store additional data used by external URLs"),
fieldWithPath("considerReleasesFromExternalList").description("Consider list of releases from existing external list"),
fieldWithPath("enableVulnerabilitiesDisplay").description("Displaying vulnerabilities flag."),
fieldWithPath("clearingState").description("The clearingState of the project"),
subsectionWithPath("_embedded.sw360:moderators").description("An array of moderators"),
subsectionWithPath("_embedded.sw360:projects").description("An array of <<resources-projects, Projects resources>>"),
subsectionWithPath("_embedded.sw360:releases").description("An array of <<resources-releases, Releases resources>>"),
Expand Down

0 comments on commit c8b2756

Please sign in to comment.