You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datalab.apache.org by dy...@apache.org on 2022/09/08 10:04:24 UTC

[incubator-datalab] 01/03: move image sharing to images collection

This is an automated email from the ASF dual-hosted git repository.

dyankiv pushed a commit to branch DATALAB-2995
in repository https://gitbox.apache.org/repos/asf/incubator-datalab.git

commit 2b4480cd29e3d2b054b3ccfa534be30c0046123e
Author: Denys Yankiv <de...@gmail.com>
AuthorDate: Wed Sep 7 12:55:17 2022 +0300

    move image sharing to images collection
---
 .../main/java/com/epam/datalab/dto/SharedWith.java | 15 +++++
 .../com/epam/datalab/model/exploratory/Image.java  |  2 +
 .../backendapi/dao/ImageExploratoryDAO.java        |  3 +
 .../backendapi/dao/ImageExploratoryDAOImpl.java    | 10 +++
 .../backendapi/resources/dto/ImageInfoRecord.java  |  2 +
 .../resources/dto/ImageProjectGroupsShareDTO.java  |  2 +
 .../service/impl/ImageExploratoryServiceImpl.java  | 72 ++++++----------------
 7 files changed, 52 insertions(+), 54 deletions(-)

diff --git a/services/datalab-model/src/main/java/com/epam/datalab/dto/SharedWith.java b/services/datalab-model/src/main/java/com/epam/datalab/dto/SharedWith.java
new file mode 100644
index 000000000..c9d4da861
--- /dev/null
+++ b/services/datalab-model/src/main/java/com/epam/datalab/dto/SharedWith.java
@@ -0,0 +1,15 @@
+package com.epam.datalab.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class SharedWith {
+    private Set<String> users=new HashSet<>();
+    private Set<String> groups=new HashSet<>();
+}
diff --git a/services/datalab-model/src/main/java/com/epam/datalab/model/exploratory/Image.java b/services/datalab-model/src/main/java/com/epam/datalab/model/exploratory/Image.java
index ba338d92c..3fd928b37 100644
--- a/services/datalab-model/src/main/java/com/epam/datalab/model/exploratory/Image.java
+++ b/services/datalab-model/src/main/java/com/epam/datalab/model/exploratory/Image.java
@@ -19,6 +19,7 @@
 
 package com.epam.datalab.model.exploratory;
 
+import com.epam.datalab.dto.SharedWith;
 import com.epam.datalab.dto.aws.computational.ClusterConfig;
 import com.epam.datalab.dto.exploratory.ImageStatus;
 import com.epam.datalab.model.library.Library;
@@ -45,6 +46,7 @@ public class Image {
     private final String instanceName;
     private final String cloudProvider;
     private final String dockerImage;
+    private final SharedWith sharedWith;
     private final List<ClusterConfig> clusterConfig;
     private final List<Library> libraries;
     private final Map<String, List<Library>> computationalLibraries;
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 65ab9755a..94f6e3202 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
@@ -20,6 +20,7 @@
 package com.epam.datalab.backendapi.dao;
 
 import com.epam.datalab.backendapi.resources.dto.ImageInfoRecord;
+import com.epam.datalab.dto.SharedWith;
 import com.epam.datalab.dto.exploratory.ImageStatus;
 import com.epam.datalab.dto.exploratory.LibStatus;
 import com.epam.datalab.model.exploratory.Image;
@@ -51,4 +52,6 @@ public interface ImageExploratoryDAO {
     Optional<ImageInfoRecord> getImage(String user, String name, String project, String endpoint);
 
     List<Library> getLibraries(String imageName,  String project, String endpoint, LibStatus status);
+
+    void updateSharing(SharedWith sharedWith, String imageName, String project, String endpoint);
 }
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 688a02f17..a48b6a4b5 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
@@ -20,6 +20,7 @@
 package com.epam.datalab.backendapi.dao;
 
 import com.epam.datalab.backendapi.resources.dto.ImageInfoRecord;
+import com.epam.datalab.dto.SharedWith;
 import com.epam.datalab.dto.exploratory.ImageStatus;
 import com.epam.datalab.dto.exploratory.LibStatus;
 import com.epam.datalab.model.exploratory.Image;
@@ -35,6 +36,7 @@ import java.util.Objects;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
+import static com.epam.datalab.backendapi.dao.ExploratoryDAO.COMPUTATIONAL_RESOURCES;
 import static com.mongodb.client.model.Filters.and;
 import static com.mongodb.client.model.Filters.eq;
 import static com.mongodb.client.model.Filters.in;
@@ -42,6 +44,7 @@ import static com.mongodb.client.model.Projections.elemMatch;
 import static com.mongodb.client.model.Projections.excludeId;
 import static com.mongodb.client.model.Projections.fields;
 import static com.mongodb.client.model.Projections.include;
+import static com.mongodb.client.model.Updates.push;
 import static com.mongodb.client.model.Updates.set;
 
 @Singleton
@@ -56,6 +59,8 @@ public class ImageExploratoryDAOImpl extends BaseDAO implements ImageExploratory
     private static final String PROJECT = "project";
     private static final String ENDPOINT = "endpoint";
 
+    private static final String SHARED_WITH = "sharedWith";
+
     @Override
     public boolean exist(String image, String project) {
         return findOne(MongoCollections.IMAGES, imageProjectCondition(image, project)).isPresent();
@@ -131,6 +136,11 @@ public class ImageExploratoryDAOImpl extends BaseDAO implements ImageExploratory
                 .collect(Collectors.toList());
     }
 
+    @Override
+    public void updateSharing(SharedWith sharedWith, String imageName, String project, String endpoint) {
+        updateOne(MongoCollections.IMAGES, and(eq(IMAGE_NAME,imageName),eq(PROJECT,project),eq(ENDPOINT,endpoint)), set(SHARED_WITH, convertToBson(sharedWith)));
+    }
+
     private Optional<Document> libDocument(String imageName, String project, String endpoint,
                                            LibStatus status) {
         return findOne(MongoCollections.IMAGES,
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 4b9786194..ca51fe771 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
@@ -20,6 +20,7 @@
 package com.epam.datalab.backendapi.resources.dto;
 
 import com.epam.datalab.cloud.CloudProvider;
+import com.epam.datalab.dto.SharedWith;
 import com.epam.datalab.dto.aws.computational.ClusterConfig;
 import com.epam.datalab.dto.exploratory.ImageSharingStatus;
 import com.epam.datalab.dto.exploratory.ImageStatus;
@@ -49,6 +50,7 @@ public class ImageInfoRecord {
     private final ImageStatus status;
     private ImageSharingStatus sharingStatus;
     private ImageUserPermissions imageUserPermissions;
+    private final SharedWith sharedWith;
     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/ImageProjectGroupsShareDTO.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ImageProjectGroupsShareDTO.java
index 17613954c..b1e682ab5 100644
--- a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ImageProjectGroupsShareDTO.java
+++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/dto/ImageProjectGroupsShareDTO.java
@@ -19,6 +19,7 @@
 
 package com.epam.datalab.backendapi.resources.dto;
 
+import com.epam.datalab.dto.SharedWith;
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import lombok.Data;
 
@@ -28,4 +29,5 @@ public class ImageProjectGroupsShareDTO {
     private final String imageName;
     private final String projectName;
     private final String endpoint;
+    private final SharedWith sharedWith;
 }
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 fe0af1fb4..302a555aa 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
@@ -36,6 +36,7 @@ import com.epam.datalab.backendapi.service.ImageExploratoryService;
 import com.epam.datalab.backendapi.service.ProjectService;
 import com.epam.datalab.backendapi.util.RequestBuilder;
 import com.epam.datalab.constants.ServiceConsts;
+import com.epam.datalab.dto.SharedWith;
 import com.epam.datalab.dto.UserInstanceDTO;
 import com.epam.datalab.dto.UserInstanceStatus;
 import com.epam.datalab.dto.exploratory.ExploratoryStatusDTO;
@@ -72,14 +73,7 @@ public class ImageExploratoryServiceImpl implements ImageExploratoryService {
     private static final String SHARE_OWN_IMAGES_PAGE = "/api/image/share";
     private static final String TERMINATE_OWN_IMAGES_PAGE = "/api/image/terminate";
     private static final String SHARE_RECEIVED_IMAGES_PAGE = "/api/image/shareReceived";
-    private static final String IMAGE_ROLE = "img_%s_%s_%s_%s";
-    private static final String IMAGE_ROLE_DESCRIPTION = "Create Notebook from image %s";
 
-
-    /**
-     * projectName-endpointName-exploratoryName-imageName
-     */
-    private static final String IMAGE_MONIKER = "%s_%s_%s_%s";
     @Inject
     private ExploratoryDAO exploratoryDAO;
     @Inject
@@ -121,6 +115,7 @@ public class ImageExploratoryServiceImpl implements ImageExploratoryService {
                 .description(imageDescription)
                 .status(ImageStatus.CREATING)
                 .user(user.getName())
+                        .sharedWith(new SharedWith())
                 .libraries(fetchExploratoryLibs(libraries))
                 .computationalLibraries(fetchComputationalLibs(libraries))
                 .clusterConfig(userInstance.getClusterConfig())
@@ -180,8 +175,6 @@ public class ImageExploratoryServiceImpl implements ImageExploratoryService {
         imageExploratoryDao.updateImageFields(image);
 
         log.debug("Image {}", image);
-        // Create image roles
-        createImageRole(image, exploratoryName);
 
         if (newNotebookIp != null) {
             log.debug("Changing exploratory ip with name {} for user {} to {}", exploratoryName, image.getUser(),
@@ -290,13 +283,18 @@ public class ImageExploratoryServiceImpl implements ImageExploratoryService {
     public void shareImageWithProjectGroups(UserInfo user, String imageName, String projectName, String endpoint) {
         Set<String> projectGroups = projectService.get(projectName).getGroups();
         Optional<ImageInfoRecord> image = imageExploratoryDao.getImage(user.getName(),imageName,projectName,endpoint);
-        if(image.isPresent()){
-            String exploratoryName = image.get().getInstanceName();
-            userRoleDAO.addGroupToRole(projectGroups,
-                    Collections.singleton(String.format(IMAGE_ROLE,
-                            projectName, endpoint, exploratoryName ,imageName)));
-        }
+        image.ifPresent(img -> {
+            log.info("image {}", img);
+            SharedWith sharedWith = img.getSharedWith();
+            sharedWith.getGroups().addAll(projectGroups);
+            imageExploratoryDao.updateSharing(sharedWith, img.getName() ,img.getProject(), img.getEndpoint());
+        });
+    }
 
+    public boolean hasAccess(String userName, SharedWith sharedWith){
+        boolean accessByUserName = sharedWith.getUsers().contains(userName);
+        boolean accessByGroup = sharedWith.getGroups().stream().anyMatch(groupName -> userGroupDAO.getUsers(groupName).contains(userName));
+        return accessByUserName || accessByGroup;
     }
 
     private Map<String, List<Library>> fetchComputationalLibs(List<Library> libraries) {
@@ -323,10 +321,7 @@ public class ImageExploratoryServiceImpl implements ImageExploratoryService {
     public List<ImageInfoRecord> getSharedImages(UserInfo userInfo) {
         List<ImageInfoRecord> sharedImages = imageExploratoryDao.getAllImages().stream()
                 .filter(img -> !img.getUser().equals(userInfo.getName()))
-                .filter(img ->
-                        UserRoles.checkAccess(userInfo, RoleType.IMAGE,
-                                String.format(IMAGE_MONIKER, img.getProject(), img.getEndpoint(), img.getInstanceName(), img.getName()),
-                                userInfo.getRoles()))
+                .filter(img -> hasAccess(userInfo.getName(),img.getSharedWith()))
                 .collect(Collectors.toList());
         sharedImages.forEach(img -> img.setSharingStatus(getImageSharingStatus(userInfo.getName(),img)));
         log.info("Shared with user {} images : {}", userInfo.getName(), sharedImages);
@@ -338,9 +333,7 @@ public class ImageExploratoryServiceImpl implements ImageExploratoryService {
                 .filter(img -> img.getStatus().equals(ImageStatus.ACTIVE))
                 .filter(img -> !img.getUser().equals(userInfo.getName()))
                 .filter(img -> img.getDockerImage().equals(dockerImage) && img.getProject().equals(project) && img.getEndpoint().equals(endpoint))
-                .filter(img -> UserRoles.checkAccess(userInfo, RoleType.IMAGE,
-                        String.format(IMAGE_MONIKER, img.getProject(), img.getEndpoint(), img.getInstanceName(), img.getName()),
-                        userInfo.getRoles()))
+                .filter(img -> hasAccess(userInfo.getName(),img.getSharedWith()))
                 .collect(Collectors.toList());
         sharedImages.forEach(img -> img.setSharingStatus(getImageSharingStatus(userInfo.getName(),img)));
         log.info("Found shared with user {} images {}", userInfo.getName(), sharedImages);
@@ -366,44 +359,15 @@ public class ImageExploratoryServiceImpl implements ImageExploratoryService {
     }
 
     private ImageSharingStatus getImageSharingStatus(String username, ImageInfoRecord image){
-        String anyUser = "$anyuser";
-        UserRoleDTO role = getImageRole(image);
-        if (role==null){
+        boolean notShared = image.getSharedWith().getUsers().isEmpty() && image.getSharedWith().getGroups().isEmpty();
+        if(notShared && image.getUser().equals(username)){
             return ImageSharingStatus.PRIVATE;
-        }
-        boolean roleHasGroups = (role.getGroups().contains(anyUser) && role.getGroups().size() >= 2)
-                || (!role.getGroups().contains(anyUser) && !role.getGroups().isEmpty());
-        if(!roleHasGroups && image.getUser().equals(username)){
-            return ImageSharingStatus.PRIVATE;
-        } else if (roleHasGroups && image.getUser().equals(username)){
+        } else if (!notShared && image.getUser().equals(username)){
             return ImageSharingStatus.SHARED;
         }
         return ImageSharingStatus.RECEIVED ;
     }
 
-    private UserRoleDTO getImageRole(ImageInfoRecord image){
-        String imageId = String.format(IMAGE_ROLE,
-                image.getProject(), image.getEndpoint(), image.getInstanceName(),image.getName());
-       return userRoleDAO.findById(imageId);
-    }
-
-    private String getImageMoniker(String project, String endpoint, String exploratoryName, String imageName){
-        return String.format(IMAGE_MONIKER, project, endpoint, exploratoryName, imageName);
-    }
-
-    private void createImageRole(Image image, String exploratoryName){
-        if (image.getStatus().equals(ImageStatus.ACTIVE)){
-            UserRoleDTO role = new UserRoleDTO();
-            role.setId(String.format(IMAGE_ROLE, image.getProject(), image.getEndpoint(), exploratoryName ,image.getName()));
-            role.setDescription(String.format(IMAGE_ROLE_DESCRIPTION, getImageMoniker(image.getProject(), image.getEndpoint(), exploratoryName, image.getName()).replaceAll("_","-")));
-            role.setCloud(endpointService.get(image.getEndpoint()).getCloudProvider());
-            role.setImages(new HashSet<>(Collections.singletonList(getImageMoniker(image.getProject(), image.getEndpoint(), exploratoryName, image.getName()))));
-            role.setType(UserRoleDTO.Type.NOTEBOOK);
-            role.setGroups(Collections.emptySet());
-            userRoleDAO.insert(role);
-        }
-    }
-
     private List<ImageInfoRecord> filterImages(List<ImageInfoRecord> images, ImageFilter filter){
         return images.stream()
                 .filter(img -> img.getName().toLowerCase().contains(filter.getImageName().toLowerCase()))


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datalab.apache.org
For additional commands, e-mail: commits-help@datalab.apache.org