This is an automated email from the ASF dual-hosted git repository. dyankiv pushed a commit to branch DATALAB-2968 in repository https://gitbox.apache.org/repos/asf/incubator-datalab.git
commit 125dd67589dfb23a1d9be4aaea869287d88e6671 Author: Denys Yankiv <[email protected]> AuthorDate: Tue Aug 9 13:36:38 2022 +0300 add user image rights, fix reading image filter from db bug --- .../backendapi/dao/ImageExploratoryDAO.java | 2 +- .../backendapi/dao/ImageExploratoryDAOImpl.java | 5 +- .../datalab/backendapi/dao/UserSettingsDAO.java | 11 ++- .../resources/ImageExploratoryResource.java | 10 +- .../backendapi/resources/dto/ImageFilter.java | 13 +-- .../resources/dto/ImageFilterFormData.java | 27 ++++++ .../backendapi/resources/dto/ImageInfoRecord.java | 1 + .../resources/dto/ImageUserPermissions.java | 20 ++++ .../resources/dto/ProjectImagesInfo.java | 7 +- .../service/ImageExploratoryService.java | 6 +- .../service/impl/ImageExploratoryServiceImpl.java | 107 ++++++++++++--------- 11 files changed, 139 insertions(+), 70 deletions(-) diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ImageExploratoryDAO.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ImageExploratoryDAO.java index 9638dec8e..4b67166b6 100644 --- a/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ImageExploratoryDAO.java +++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ImageExploratoryDAO.java @@ -40,7 +40,7 @@ public interface ImageExploratoryDAO { List<ImageInfoRecord> getImages(String project, String endpoint, String dockerImage); - List<ImageInfoRecord> getImagesOfUser(String user, String project); + List<ImageInfoRecord> getImagesOfUser(String user); List<ImageInfoRecord> getImagesForProject(String project); diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ImageExploratoryDAOImpl.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ImageExploratoryDAOImpl.java index cc93a4b01..d4fde8042 100644 --- a/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ImageExploratoryDAOImpl.java +++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ImageExploratoryDAOImpl.java @@ -86,10 +86,11 @@ public class ImageExploratoryDAOImpl extends BaseDAO implements ImageExploratory ImageInfoRecord.class); } + @Override - public List<ImageInfoRecord> getImagesOfUser(String user, String project) { + public List<ImageInfoRecord> getImagesOfUser(String user) { return find(MongoCollections.IMAGES, - imageUserProjectCondition(user, project), + eq(USER, user), ImageInfoRecord.class); } diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/UserSettingsDAO.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/UserSettingsDAO.java index d12b9f851..2ae4fadea 100644 --- a/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/UserSettingsDAO.java +++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/UserSettingsDAO.java @@ -30,6 +30,7 @@ import org.bson.Document; import java.util.Optional; import static com.epam.datalab.backendapi.dao.MongoCollections.USER_SETTINGS; +import static com.mongodb.client.model.Filters.and; import static com.mongodb.client.model.Filters.eq; import static com.mongodb.client.model.Projections.*; import static com.mongodb.client.model.Updates.set; @@ -81,9 +82,15 @@ public class UserSettingsDAO extends BaseDAO { } public Optional<ImageFilter> getImageFilter(String user){ - return findOne(USER_SETTINGS, eq(ID, user), + return findOne(USER_SETTINGS, and(eq(ID, user), notNull(USER_IMAGE_FILTER)), fields(include(USER_IMAGE_FILTER), excludeId())) - .map(d -> convertFromDocument((Document) d.get(USER_IMAGE_FILTER), ImageFilter.class)); + .map(d -> convertFromDocument((Document) d.get(USER_IMAGE_FILTER), ImageFilter.class)); + +// if(doc.isPresent()){ +// return doc.map(d -> convertFromDocument((Document) d.get(USER_IMAGE_FILTER), ImageFilter.class)).get(); +// } +// return new ImageFilter(); + } diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/ImageExploratoryResource.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/ImageExploratoryResource.java index ec0ed7b7f..ae1f798df 100644 --- a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/ImageExploratoryResource.java +++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/ImageExploratoryResource.java @@ -102,7 +102,7 @@ public class ImageExploratoryResource { @Path("user") public Response getImagesForUser(@Auth UserInfo ui) { log.debug("Getting images for user {}", ui.getName()); - final List<ProjectImagesInfo> images = imageExploratoryService.getImagesOfUser(ui); + final ProjectImagesInfo images = imageExploratoryService.getImagesOfUser(ui); return Response.ok(images).build(); } @@ -110,7 +110,7 @@ public class ImageExploratoryResource { @Path("user") public Response getImagesForUser(@Auth UserInfo ui, @Valid @NotNull ImageFilter imageFilter) { log.debug("Getting images for user {} with filter {}", ui.getName(), imageFilter); - final List<ProjectImagesInfo> images = imageExploratoryService.getImagesOfUserWithFilter(ui, imageFilter); + final ProjectImagesInfo images = imageExploratoryService.getImagesOfUserWithFilter(ui, imageFilter); return Response.ok(images).build(); } @@ -133,10 +133,4 @@ public class ImageExploratoryResource { return Response.ok(imageExploratoryService.getImagesOfUser(ui)).build(); } - @POST - @Path("roles") - public Response getUserImagePermissions(@Auth UserInfo ui, @Valid @NotNull ImageProjectGroupsShareDTO dto){ - return Response.ok( - imageExploratoryService.getUserImagePermissions(ui,dto.getImageName(),dto.getProjectName(), dto.getEndpoint())).build(); - } } diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ImageFilter.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ImageFilter.java index 2d924b4da..3ee650d2b 100644 --- a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ImageFilter.java +++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ImageFilter.java @@ -26,21 +26,22 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.NonNull; -import java.util.List; +import java.util.HashSet; +import java.util.Set; @Data @NoArgsConstructor @JsonIgnoreProperties(ignoreUnknown = true) public class ImageFilter { @NonNull - private String imageName; + private String imageName = ""; @NonNull - private List<ImageStatus> statuses; + private Set<ImageStatus> statuses = new HashSet<>(); @NonNull - private List<String> endpoints; + private Set<String> endpoints = new HashSet<>(); @NonNull - private List<String> templateNames; + private Set<String> templateNames = new HashSet<>(); @NonNull - private List<ImageSharingStatus> sharingStatuses; + private Set<ImageSharingStatus> sharingStatuses = new HashSet<>(); } diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ImageFilterFormData.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ImageFilterFormData.java new file mode 100644 index 000000000..639939075 --- /dev/null +++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ImageFilterFormData.java @@ -0,0 +1,27 @@ +package com.epam.datalab.backendapi.resources.dto; + +import com.epam.datalab.dto.exploratory.ImageSharingStatus; +import com.epam.datalab.dto.exploratory.ImageStatus; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; + + +import java.util.Set; + +@Data +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class ImageFilterFormData { + @NonNull + private Set<String> imageNames; + @NonNull + private Set<ImageStatus> statuses; + @NonNull + private Set<String> endpoints; + @NonNull + private Set<String> templateNames; + @NonNull + private Set<ImageSharingStatus> sharingStatuses; +} diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ImageInfoRecord.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ImageInfoRecord.java index f13f1b199..4b9786194 100644 --- a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ImageInfoRecord.java +++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ImageInfoRecord.java @@ -48,6 +48,7 @@ public class ImageInfoRecord { private final String fullName; private final ImageStatus status; private ImageSharingStatus sharingStatus; + private ImageUserPermissions imageUserPermissions; private final List<ClusterConfig> clusterConfig; private final String exploratoryURL; private final List<Library> libraries; diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ImageUserPermissions.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ImageUserPermissions.java index 5577444f3..1de9ec29e 100644 --- a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ImageUserPermissions.java +++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ImageUserPermissions.java @@ -1,3 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + package com.epam.datalab.backendapi.resources.dto; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ProjectImagesInfo.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ProjectImagesInfo.java index 06da51f28..d561a78f1 100644 --- a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ProjectImagesInfo.java +++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ProjectImagesInfo.java @@ -26,6 +26,7 @@ import lombok.EqualsAndHashCode; import lombok.ToString; import java.util.List; +import java.util.Map; @AllArgsConstructor @Builder @@ -33,7 +34,9 @@ import java.util.List; @ToString public class ProjectImagesInfo { @JsonProperty - private String project; + private Map<String,List<ImageInfoRecord>> projectImages; @JsonProperty - private List<ImageInfoRecord> images; + private ImageFilter imageFilter; + @JsonProperty + private ImageFilterFormData filterData; } diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ImageExploratoryService.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ImageExploratoryService.java index 363dc9d16..b9cf922c1 100644 --- a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ImageExploratoryService.java +++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ImageExploratoryService.java @@ -42,8 +42,8 @@ public interface ImageExploratoryService { List<ImageInfoRecord> getImagesForProject(String project); - List<ProjectImagesInfo> getImagesOfUser(UserInfo user); - List<ProjectImagesInfo> getImagesOfUserWithFilter(UserInfo user, ImageFilter imageFilter); + ProjectImagesInfo getImagesOfUser(UserInfo user); + ProjectImagesInfo getImagesOfUserWithFilter(UserInfo user, ImageFilter imageFilter); void shareImageWithProjectGroups(UserInfo user, String imageName, String projectName, String endpoint); @@ -51,6 +51,6 @@ public interface ImageExploratoryService { List<ImageInfoRecord> getSharedImages(UserInfo userInfo, String dockerImage, String project, String endpoint); - ImageUserPermissions getUserImagePermissions(UserInfo userInfo, String imageName, String projectName, String endpoint); + ImageUserPermissions getUserImagePermissions(UserInfo userInfo, ImageInfoRecord image); } diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ImageExploratoryServiceImpl.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ImageExploratoryServiceImpl.java index c103fb7c6..c5ee95534 100644 --- a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ImageExploratoryServiceImpl.java +++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ImageExploratoryServiceImpl.java @@ -48,7 +48,6 @@ import com.epam.datalab.model.exploratory.Image; import com.epam.datalab.model.library.Library; import com.epam.datalab.rest.client.RESTService; import com.epam.datalab.rest.contracts.ExploratoryAPI; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.Lists; import com.google.inject.Inject; import com.google.inject.Singleton; @@ -80,7 +79,6 @@ public class ImageExploratoryServiceImpl implements ImageExploratoryService { * projectName-endpointName-exploratoryName-imageName */ private static final String IMAGE_MONIKER = "%s_%s_%s_%s"; - private static final ObjectMapper MAPPER = new ObjectMapper(); @Inject private ExploratoryDAO exploratoryDAO; @Inject @@ -102,6 +100,8 @@ public class ImageExploratoryServiceImpl implements ImageExploratoryService { private EndpointService endpointService; @Inject private ProjectService projectService; + @Inject + private UserSettingsDAO userSettingsDAO; @Audit(action = CREATE, type = IMAGE) @Override @@ -190,39 +190,58 @@ public class ImageExploratoryServiceImpl implements ImageExploratoryService { } @Override - public List<ProjectImagesInfo> getImagesOfUser(UserInfo user) { + public ProjectImagesInfo getImagesOfUser(UserInfo user) { log.debug("Loading list of images for user {}", user.getName()); - return projectService.getUserProjects(user, Boolean.FALSE) - .stream() - .map(p -> { - List<ImageInfoRecord> images = imageExploratoryDao.getImagesOfUser(user.getName(), p.getName()); - images.forEach(img -> img.setSharingStatus(getImageSharingStatus(user.getName(),img))); - images.addAll(getSharedImages(user, p.getName())); - return ProjectImagesInfo.builder() - .project(p.getName()) - .images(images) - .build(); - }) - .collect(Collectors.toList()); + Map<String, List<ImageInfoRecord>> projectImages = new HashMap<>(); + projectService.getUserProjects(user, Boolean.FALSE).stream() + .map(ProjectDTO::getName) + .forEach(name->projectImages.put(name, new ArrayList<>())); + + List<ImageInfoRecord> images = imageExploratoryDao.getImagesOfUser(user.getName()); + images.forEach(img -> img.setSharingStatus(getImageSharingStatus(user.getName(),img))); + images.addAll(getSharedImages(user)); + + ImageFilterFormData filterData = getDataForFilter(images); + ImageFilter imageFilter = new ImageFilter(); + if(userSettingsDAO.getImageFilter(user.getName()).isPresent()){ + imageFilter = userSettingsDAO.getImageFilter(user.getName()).get(); + images = filterImages(images, imageFilter); + } + userSettingsDAO.setUserImageFilter(user.getName(),imageFilter); + images.forEach(img -> img.setImageUserPermissions(getUserImagePermissions(user,img))); + + projectImages.putAll(images.stream().collect(Collectors.groupingBy(ImageInfoRecord::getProject))); + return ProjectImagesInfo.builder() + .projectImages(projectImages) + .imageFilter(userSettingsDAO.getImageFilter(user.getName()).get()) + .filterData(filterData).build(); } @Override - public List<ProjectImagesInfo> getImagesOfUserWithFilter(UserInfo user, ImageFilter imageFilter) { + public ProjectImagesInfo getImagesOfUserWithFilter(UserInfo user, ImageFilter imageFilter) { log.debug("Loading list of images for user {}", user.getName()); - return projectService.getUserProjects(user, Boolean.FALSE) - .stream() - .map(p -> { - List<ImageInfoRecord> images = imageExploratoryDao.getImagesOfUser(user.getName(), p.getName()); - images.forEach(img -> img.setSharingStatus(getImageSharingStatus(user.getName(),img))); - List<ImageInfoRecord> sharedImages = getSharedImages(user, p.getName()); - images.addAll(sharedImages); - images = filterImages(images, imageFilter); - return ProjectImagesInfo.builder() - .project(p.getName()) - .images(images) - .build(); - }) - .collect(Collectors.toList()); + Map<String, List<ImageInfoRecord>> projectImages = new HashMap<>(); + projectService.getUserProjects(user, Boolean.FALSE).stream() + .map(ProjectDTO::getName) + .forEach(name->projectImages.put(name, new ArrayList<>())); + + List<ImageInfoRecord> images = imageExploratoryDao.getImagesOfUser(user.getName()); + images.forEach(img -> img.setSharingStatus(getImageSharingStatus(user.getName(),img))); + images.addAll(getSharedImages(user)); + + ImageFilterFormData filterData = getDataForFilter(images); + images = filterImages(images, imageFilter); + + userSettingsDAO.setUserImageFilter(user.getName(),imageFilter); + + images.forEach(img -> img.setImageUserPermissions(getUserImagePermissions(user,img))); + + projectImages.putAll(images.stream().collect(Collectors.groupingBy(ImageInfoRecord::getProject))); + return ProjectImagesInfo.builder() + .projectImages(projectImages) + .filterData(filterData) + .imageFilter(imageFilter) + .build(); } @Override @@ -287,10 +306,10 @@ public class ImageExploratoryServiceImpl implements ImageExploratoryService { } @Override - public ImageUserPermissions getUserImagePermissions(UserInfo userInfo, String imageName, String projectName, String endpoint) { + public ImageUserPermissions getUserImagePermissions(UserInfo userInfo, ImageInfoRecord image) { boolean canShare; boolean canTerminate = false; - if(imageExploratoryDao.getImage(userInfo.getName(), imageName, projectName, endpoint).isPresent()){ + if(image.getUser().equals(userInfo.getName())){ canShare = UserRoles.checkAccess(userInfo, RoleType.PAGE, SHARE_OWN_IMAGES_PAGE,userInfo.getRoles()); } else { canShare = UserRoles.checkAccess(userInfo, RoleType.PAGE, SHARE_RECEIVED_IMAGES_PAGE,userInfo.getRoles()); @@ -298,20 +317,6 @@ public class ImageExploratoryServiceImpl implements ImageExploratoryService { return new ImageUserPermissions(canShare,canTerminate); } - public List<ImageInfoRecord> getSharedImages(UserInfo userInfo, String project){ - List<ImageInfoRecord> sharedImages = imageExploratoryDao.getAllImages().stream() - .filter(img -> img.getStatus().equals(ImageStatus.ACTIVE)) - .filter(img -> !img.getUser().equals(userInfo.getName())) - .filter(img -> img.getProject().equals(project) ) - .filter(img -> UserRoles.checkAccess(userInfo, RoleType.IMAGE, - String.format(IMAGE_MONIKER, img.getProject(), img.getEndpoint(), img.getInstanceName(), img.getName()), - userInfo.getRoles())) - .collect(Collectors.toList()); - sharedImages.forEach(img -> img.setSharingStatus(getImageSharingStatus(userInfo.getName(),img))); - log.info("Found shared with user {} images {}", userInfo.getName(), sharedImages); - return sharedImages; - } - private ImageSharingStatus getImageSharingStatus(String username, ImageInfoRecord image){ String anyUser = "$anyuser"; UserRoleDTO role = getImageRole(image); @@ -361,4 +366,14 @@ public class ImageExploratoryServiceImpl implements ImageExploratoryService { .collect(Collectors.toList()); } + + private ImageFilterFormData getDataForFilter(List<ImageInfoRecord> images){ + ImageFilterFormData filterData = new ImageFilterFormData(); + filterData.setImageNames(images.stream().map(ImageInfoRecord::getName).collect(Collectors.toSet())); + filterData.setStatuses(images.stream().map(ImageInfoRecord::getStatus).collect(Collectors.toSet())); + filterData.setEndpoints(images.stream().map(ImageInfoRecord::getEndpoint).collect(Collectors.toSet())); + filterData.setTemplateNames(images.stream().map(ImageInfoRecord::getTemplateName).collect(Collectors.toSet())); + filterData.setSharingStatuses(images.stream().map(ImageInfoRecord::getSharingStatus).collect(Collectors.toSet())); + return filterData; + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
