This is an automated email from the ASF dual-hosted git repository. dyankiv pushed a commit to branch DATALAB-2988 in repository https://gitbox.apache.org/repos/asf/incubator-datalab.git
commit 72bd7176d7501bdd7c13e8f9ee2e7394a789c288 Author: Denys Yankiv <[email protected]> AuthorDate: Mon Sep 12 13:16:48 2022 +0300 grant roles as per notebook creation --- .../backendapi/dao/ImageExploratoryDAO.java | 2 ++ .../backendapi/dao/ImageExploratoryDAOImpl.java | 9 ++++++ .../backendapi/resources/ExploratoryResource.java | 13 +++++++- .../service/ImageExploratoryService.java | 4 +++ .../service/impl/ExploratoryServiceImpl.java | 1 + .../service/impl/ImageExploratoryServiceImpl.java | 37 +++++++++++++++++++--- .../main/resources/mongo/general/mongo_roles.json | 24 ++++++++++++++ .../resources/ExploratoryResourceTest.java | 6 ++-- 8 files changed, 88 insertions(+), 8 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 94f6e3202..946b2fbfb 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 @@ -51,6 +51,8 @@ public interface ImageExploratoryDAO { List<ImageInfoRecord> getAllImages(); Optional<ImageInfoRecord> getImage(String user, String name, String project, String endpoint); + Optional<ImageInfoRecord> getImage(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 994f2ef12..12c0ec669 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 @@ -125,6 +125,11 @@ public class ImageExploratoryDAOImpl extends BaseDAO implements ImageExploratory return findOne(MongoCollections.IMAGES, userImageCondition(user, name, project, endpoint), ImageInfoRecord.class); } + @Override + public Optional<ImageInfoRecord> getImage(String name, String project, String endpoint) { + return findOne(MongoCollections.IMAGES, imageProjectEndpointCondition(name, project, endpoint), ImageInfoRecord.class); + } + @Override public List<Library> getLibraries(String imageName, String project, String endpoint, LibStatus status) { return ((List<Document>) libDocument(imageName, project, endpoint, status) @@ -183,6 +188,10 @@ public class ImageExploratoryDAOImpl extends BaseDAO implements ImageExploratory return and(eq(IMAGE_NAME, image), eq(PROJECT, project)); } + private Bson imageProjectEndpointCondition(String image, String project, String endpoint) { + return and(eq(IMAGE_NAME, image), eq(PROJECT, project), eq(ENDPOINT, endpoint)); + } + private Bson imageUserProjectCondition(String user, String project) { return and(eq(USER, user), eq(PROJECT, project)); } diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/ExploratoryResource.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/ExploratoryResource.java index 39bfb893d..c83875e1e 100644 --- a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/ExploratoryResource.java +++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/ExploratoryResource.java @@ -22,9 +22,12 @@ package com.epam.datalab.backendapi.resources; import com.epam.datalab.auth.UserInfo; import com.epam.datalab.backendapi.resources.dto.ExploratoryActionFormDTO; import com.epam.datalab.backendapi.resources.dto.ExploratoryCreateFormDTO; +import com.epam.datalab.backendapi.resources.dto.ImageInfoRecord; import com.epam.datalab.backendapi.roles.RoleType; import com.epam.datalab.backendapi.roles.UserRoles; import com.epam.datalab.backendapi.service.ExploratoryService; +import com.epam.datalab.backendapi.service.ImageExploratoryService; +import com.epam.datalab.backendapi.service.impl.ImageExploratoryServiceImpl; import com.epam.datalab.dto.aws.computational.ClusterConfig; import com.epam.datalab.exceptions.DatalabException; import com.epam.datalab.model.exploratory.Exploratory; @@ -51,9 +54,12 @@ public class ExploratoryResource implements ExploratoryAPI { private final ExploratoryService exploratoryService; + private final ImageExploratoryService imageExploratoryService; + @Inject - public ExploratoryResource(ExploratoryService exploratoryService) { + public ExploratoryResource(ExploratoryService exploratoryService, ImageExploratoryService imageExploratoryService) { this.exploratoryService = exploratoryService; + this.imageExploratoryService = imageExploratoryService; } @GET @@ -78,6 +84,11 @@ public class ExploratoryResource implements ExploratoryAPI { log.warn("Unauthorized attempt to create a {} by user {}", formDTO.getImage(), userInfo.getName()); throw new DatalabException("You do not have the privileges to create a " + formDTO.getTemplateName()); } + if(formDTO.getImageName() != null + && !imageExploratoryService.canCreateFromImage(userInfo, formDTO.getImageName(),formDTO.getProject() , formDTO.getEndpoint())){ + log.warn("Unauthorized attempt to create notebook from image {} by user {}", formDTO.getImageName(), userInfo.getName()); + throw new DatalabException("You do not have the privileges to create notebook from image " + formDTO.getImageName()); + } String uuid = exploratoryService.create(userInfo, getExploratory(formDTO), formDTO.getProject(), formDTO.getName()); return Response.ok(uuid).build(); 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 f2fd52b4e..b66d65077 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 @@ -41,6 +41,8 @@ public interface ImageExploratoryService { ImageInfoRecord getImage(String user, String name, String project, String endpoint); + ImageInfoRecord getImage(String name, String project, String endpoint); + List<ImageInfoRecord> getImagesForProject(String project); ImagesPageInfo getImagesOfUser(UserInfo user, ImageFilter imageFilter); @@ -54,4 +56,6 @@ public interface ImageExploratoryService { Set<SharedWithDTO> getImageSharingInfo(String userName, String imageName, String project, String endpoint); + boolean canCreateFromImage(UserInfo userInfo, String imageName, String project, String endpoint); + } diff --git a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ExploratoryServiceImpl.java b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ExploratoryServiceImpl.java index 05bdd8b5f..0626df997 100644 --- a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ExploratoryServiceImpl.java +++ b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ExploratoryServiceImpl.java @@ -27,6 +27,7 @@ import com.epam.datalab.backendapi.dao.ExploratoryDAO; import com.epam.datalab.backendapi.dao.GitCredsDAO; import com.epam.datalab.backendapi.dao.ImageExploratoryDAO; import com.epam.datalab.backendapi.domain.*; +import com.epam.datalab.backendapi.resources.dto.ExploratoryCreateFormDTO; import com.epam.datalab.backendapi.resources.dto.ExploratoryCreatePopUp; import com.epam.datalab.backendapi.service.*; import com.epam.datalab.backendapi.util.RequestBuilder; 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 c9201d8c1..0db9023c3 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 @@ -42,6 +42,7 @@ import com.epam.datalab.dto.UserInstanceStatus; import com.epam.datalab.dto.exploratory.ExploratoryStatusDTO; import com.epam.datalab.dto.exploratory.ImageSharingStatus; import com.epam.datalab.dto.exploratory.ImageStatus; +import com.epam.datalab.exceptions.DatalabException; import com.epam.datalab.exceptions.ResourceAlreadyExistException; import com.epam.datalab.exceptions.ResourceNotFoundException; import com.epam.datalab.model.ResourceType; @@ -68,11 +69,15 @@ import static com.epam.datalab.backendapi.domain.AuditResourceTypeEnum.IMAGE; @Slf4j public class ImageExploratoryServiceImpl implements ImageExploratoryService { private static final String IMAGE_EXISTS_MSG = "Image with name %s is already exist in project %s"; - private static final String IMAGE_NOT_FOUND_MSG = "Image with name %s was not found for user %s"; + private static final String IMAGE_NOT_FOUND_FOR_USER_MSG = "Image with name %s was not found for user %s"; + private static final String IMAGE_NOT_FOUND_MSG = "Image with name %s was not found "; 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 CREATE_NOTEBOOK_BASED_ON_OWN_IMAGES = "/api/exploratory/createFromOwnCustomImage"; + private static final String CREATE_NOTEBOOK_BASED_ON_SHARED_IMAGES = "/api/exploratory/createFromSharedCustomImage"; + @Inject private ExploratoryDAO exploratoryDAO; @Inject @@ -181,8 +186,13 @@ public class ImageExploratoryServiceImpl implements ImageExploratoryService { @Override public List<ImageInfoRecord> getNotFailedImages(UserInfo user, String dockerImage, String project, String endpoint) { - List<ImageInfoRecord> images = imageExploratoryDao.getImages(user.getName(), dockerImage, project, endpoint, ImageStatus.ACTIVE, ImageStatus.CREATING); - images.addAll(getSharedImages(user,dockerImage,project,endpoint)); + List<ImageInfoRecord> images = new ArrayList<>(); + if(UserRoles.checkAccess(user, RoleType.PAGE,CREATE_NOTEBOOK_BASED_ON_OWN_IMAGES,user.getRoles())){ + images.addAll(imageExploratoryDao.getImages(user.getName(), dockerImage, project, endpoint, ImageStatus.ACTIVE, ImageStatus.CREATING)); + } + if (UserRoles.checkAccess(user,RoleType.PAGE, CREATE_NOTEBOOK_BASED_ON_SHARED_IMAGES,user.getRoles())){ + images.addAll(getSharedImages(user,dockerImage,project,endpoint)); + } return images; } @@ -194,7 +204,13 @@ public class ImageExploratoryServiceImpl implements ImageExploratoryService { @Override public ImageInfoRecord getImage(String user, String name, String project, String endpoint) { return imageExploratoryDao.getImage(user, name, project, endpoint).orElseThrow(() -> - new ResourceNotFoundException(String.format(IMAGE_NOT_FOUND_MSG, name, user))); + new ResourceNotFoundException(String.format(IMAGE_NOT_FOUND_FOR_USER_MSG, name, user))); + } + + @Override + public ImageInfoRecord getImage(String name, String project, String endpoint) { + return imageExploratoryDao.getImage(name, project, endpoint).orElseThrow(() -> + new ResourceNotFoundException(String.format(IMAGE_NOT_FOUND_MSG, name))); } @Override @@ -257,7 +273,7 @@ public class ImageExploratoryServiceImpl implements ImageExploratoryService { if(image.isPresent()){ return toSharedWithDTOs(image.get().getSharedWith()); } else { - throw new ResourceNotFoundException(IMAGE_NOT_FOUND_MSG); + throw new ResourceNotFoundException(IMAGE_NOT_FOUND_FOR_USER_MSG); } } @@ -341,6 +357,17 @@ public class ImageExploratoryServiceImpl implements ImageExploratoryService { return new ImageUserPermissions(canShare,canTerminate); } + @Override + public boolean canCreateFromImage(UserInfo userInfo, String imageName, String project, String endpoint){ + ImageInfoRecord image = getImage(imageName, project, endpoint); + if(image.getUser().equals(userInfo.getName())){ + return UserRoles.checkAccess(userInfo,RoleType.PAGE, CREATE_NOTEBOOK_BASED_ON_OWN_IMAGES, userInfo.getRoles() ); + } else { + return hasAccess(userInfo.getName(), image.getSharedWith()) + && UserRoles.checkAccess(userInfo, RoleType.PAGE,CREATE_NOTEBOOK_BASED_ON_SHARED_IMAGES, userInfo.getRoles()); + } + } + private ImageSharingStatus getImageSharingStatus(String username, ImageInfoRecord image){ boolean notShared = image.getSharedWith().getUsers().isEmpty() && image.getSharedWith().getGroups().isEmpty(); if(notShared && image.getUser().equals(username)){ diff --git a/services/self-service/src/main/resources/mongo/general/mongo_roles.json b/services/self-service/src/main/resources/mongo/general/mongo_roles.json index f6bb344c9..e9e53433e 100644 --- a/services/self-service/src/main/resources/mongo/general/mongo_roles.json +++ b/services/self-service/src/main/resources/mongo/general/mongo_roles.json @@ -23,6 +23,30 @@ "$anyuser" ] }, + { + "_id": "nbCreateBasedOnCustomOwnImages", + "description": "Create Notebook based on custom own images", + "type": "NOTEBOOK", + "cloud": "GENERAL", + "pages": [ + "/api/exploratory/createFromOwnCustomImage" + ], + "groups": [ + "$anyuser" + ] + }, + { + "_id": "nbCreateBasedOnSharedImages", + "description": "Create Notebook based on custom shared images", + "type": "NOTEBOOK", + "cloud": "GENERAL", + "pages": [ + "/api/exploratory/createFromSharedCustomImage" + ], + "groups": [ + "$anyuser" + ] + }, { "_id": "nbBillingReportFull", "description": "View full billing report for all users", diff --git a/services/self-service/src/test/java/com/epam/datalab/backendapi/resources/ExploratoryResourceTest.java b/services/self-service/src/test/java/com/epam/datalab/backendapi/resources/ExploratoryResourceTest.java index 0f2a8f0df..3577798e8 100644 --- a/services/self-service/src/test/java/com/epam/datalab/backendapi/resources/ExploratoryResourceTest.java +++ b/services/self-service/src/test/java/com/epam/datalab/backendapi/resources/ExploratoryResourceTest.java @@ -23,6 +23,7 @@ import com.epam.datalab.auth.UserInfo; import com.epam.datalab.backendapi.resources.dto.ExploratoryActionFormDTO; import com.epam.datalab.backendapi.resources.dto.ExploratoryCreateFormDTO; import com.epam.datalab.backendapi.service.ExploratoryService; +import com.epam.datalab.backendapi.service.ImageExploratoryService; import com.epam.datalab.dto.aws.computational.ClusterConfig; import com.epam.datalab.exceptions.DatalabException; import com.epam.datalab.model.exploratory.Exploratory; @@ -59,9 +60,10 @@ import static org.mockito.Mockito.when; public class ExploratoryResourceTest extends TestBase { private ExploratoryService exploratoryService = mock(ExploratoryService.class); + private ImageExploratoryService imageExploratoryService = mock(ImageExploratoryService.class); @Rule - public final ResourceTestRule resources = getResourceTestRuleInstance(new ExploratoryResource(exploratoryService)); + public final ResourceTestRule resources = getResourceTestRuleInstance(new ExploratoryResource(exploratoryService,imageExploratoryService)); @Before public void setup() throws AuthenticationException { @@ -297,7 +299,7 @@ public class ExploratoryResourceTest extends TestBase { ecfDto.setName("someName"); ecfDto.setShape("someShape"); ecfDto.setVersion("someVersion"); - ecfDto.setImageName("someImageName"); + //ecfDto.setImageName("someImageName"); ecfDto.setProject("project"); ecfDto.setEndpoint("endpoint"); return ecfDto; --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
