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