-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generic shares_base module and specific s3_datasets_shares module - p…
…art 11 (renaming and cleaning up s3_shares) (#1359) ### Feature or Bugfix - Refactoring ### Detail As explained in the design for #1123 and #1283 we are trying to implement generic `datasets_base` and `shares_base` modules that can be used by any type of datasets and by any type of shareable object in a generic way. This is one of the last PRs focused on renaming files and cleaning-up the s3_datasets_shares module. The first step is a consolidation of the file and classes names in the services to clearly refer to s3_shares: - `services.managed_share_policy_service.SharePolicyService` ---> `services.s3_share_managed_policy_service.S3SharePolicyService` - `services.dataset_sharing_alarm_service.DatasetSharingAlarmService` --> `services.s3_share_alarm_service.S3ShareAlarmService` - `services.managed_share_policy_service.SharePolicyService` --> `services.s3_share_managed_policy_service.S3SharePolicyService` 👀 The main refactoring happens in what is used to be `services.dataset_sharing_service`. - The part that implements the `DatasetServiceInterface` has been moved to `services/s3_share_dataset_service.py` as the `S3ShareDatasetService` - The part used in the resolvers and by other methods has been renamed as `services.s3_share_service.py` and the methods for the folder/table permissions are also added to the S3ShareService (from share_item_service) Lastly, there is one method previously in share_item_service that has been moved to the GlueClient directly as `get_glue_database_from_catalog`. ### Relates - #1283 - #1123 - #955 ### Security Please answer the questions below briefly where applicable, or write `N/A`. Based on [OWASP 10](https://owasp.org/Top10/en/). - Does this PR introduce or modify any input fields or queries - this includes fetching data from storage outside the application (e.g. a database, an S3 bucket)? - Is the input sanitized? - What precautions are you taking before deserializing the data you consume? - Is injection prevented by parametrizing queries? - Have you ensured no `eval` or similar functions are used? - Does this PR introduce any functionality or component that requires authorization? - How have you ensured it respects the existing AuthN/AuthZ mechanisms? - Are you logging failed auth attempts? - Are you using or adding any cryptographic features? - Do you use a standard proven implementations? - Are the used keys controlled by the customer? Where are they stored? - Are you introducing any new policies/roles/users? - Have you used the least-privilege principle? How? By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
- Loading branch information
Showing
20 changed files
with
371 additions
and
497 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
backend/dataall/modules/s3_datasets_shares/services/s3_share_dataset_service.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
from dataall.core.permissions.services.resource_policy_service import ResourcePolicyService | ||
from dataall.base.db import exceptions | ||
from dataall.modules.shares_base.db.share_object_models import ShareObject | ||
from dataall.modules.s3_datasets_shares.db.s3_share_object_repositories import S3ShareObjectRepository | ||
from dataall.modules.shares_base.services.share_permissions import SHARE_OBJECT_APPROVER | ||
from dataall.modules.s3_datasets.services.dataset_permissions import ( | ||
DELETE_DATASET, | ||
DELETE_DATASET_TABLE, | ||
DELETE_DATASET_FOLDER, | ||
) | ||
from dataall.modules.datasets_base.services.datasets_enums import DatasetRole, DatasetTypes | ||
from dataall.modules.datasets_base.services.dataset_service_interface import DatasetServiceInterface | ||
|
||
|
||
import logging | ||
|
||
log = logging.getLogger(__name__) | ||
|
||
|
||
class S3ShareDatasetService(DatasetServiceInterface): | ||
@property | ||
def dataset_type(self): | ||
return DatasetTypes.S3 | ||
|
||
@staticmethod | ||
def resolve_additional_dataset_user_role(session, uri, username, groups): | ||
"""Implemented as part of the DatasetServiceInterface""" | ||
share = S3ShareObjectRepository.get_share_by_dataset_attributes(session, uri, username, groups) | ||
if share is not None: | ||
return DatasetRole.Shared.value | ||
return None | ||
|
||
@staticmethod | ||
def check_before_delete(session, uri, **kwargs): | ||
"""Implemented as part of the DatasetServiceInterface""" | ||
action = kwargs.get('action') | ||
if action in [DELETE_DATASET_FOLDER, DELETE_DATASET_TABLE]: | ||
existing_s3_shared_items = S3ShareObjectRepository.check_existing_s3_shared_items(session, uri) | ||
if existing_s3_shared_items: | ||
raise exceptions.ResourceShared( | ||
action=action, | ||
message='Revoke all shares for this item before deletion', | ||
) | ||
elif action in [DELETE_DATASET]: | ||
shares = S3ShareObjectRepository.list_s3_dataset_shares_with_existing_shared_items( | ||
session=session, dataset_uri=uri | ||
) | ||
if shares: | ||
raise exceptions.ResourceShared( | ||
action=DELETE_DATASET, | ||
message='Revoke all dataset shares before deletion.', | ||
) | ||
else: | ||
raise exceptions.RequiredParameter('Delete action') | ||
return True | ||
|
||
@staticmethod | ||
def execute_on_delete(session, uri, **kwargs): | ||
"""Implemented as part of the DatasetServiceInterface""" | ||
action = kwargs.get('action') | ||
if action in [DELETE_DATASET_FOLDER, DELETE_DATASET_TABLE]: | ||
S3ShareObjectRepository.delete_s3_share_item(session, uri) | ||
elif action in [DELETE_DATASET]: | ||
S3ShareObjectRepository.delete_s3_shares_with_no_shared_items(session, uri) | ||
else: | ||
raise exceptions.RequiredParameter('Delete action') | ||
return True | ||
|
||
@staticmethod | ||
def append_to_list_user_datasets(session, username, groups): | ||
"""Implemented as part of the DatasetServiceInterface""" | ||
return S3ShareObjectRepository.list_user_s3_shared_datasets(session, username, groups) | ||
|
||
@staticmethod | ||
def extend_attach_steward_permissions(session, dataset, new_stewards, **kwargs): | ||
"""Implemented as part of the DatasetServiceInterface""" | ||
dataset_shares = S3ShareObjectRepository.find_s3_dataset_shares(session, dataset.datasetUri) | ||
if dataset_shares: | ||
for share in dataset_shares: | ||
ResourcePolicyService.attach_resource_policy( | ||
session=session, | ||
group=new_stewards, | ||
permissions=SHARE_OBJECT_APPROVER, | ||
resource_uri=share.shareUri, | ||
resource_type=ShareObject.__name__, | ||
) | ||
if dataset.stewards != dataset.SamlAdminGroupName: | ||
ResourcePolicyService.delete_resource_policy( | ||
session=session, | ||
group=dataset.stewards, | ||
resource_uri=share.shareUri, | ||
) | ||
|
||
@staticmethod | ||
def extend_delete_steward_permissions(session, dataset, **kwargs): | ||
"""Implemented as part of the DatasetServiceInterface""" | ||
dataset_shares = S3ShareObjectRepository.find_s3_dataset_shares(session, dataset.datasetUri) | ||
if dataset_shares: | ||
for share in dataset_shares: | ||
if dataset.stewards != dataset.SamlAdminGroupName: | ||
ResourcePolicyService.delete_resource_policy( | ||
session=session, | ||
group=dataset.stewards, | ||
resource_uri=share.shareUri, | ||
) |
Oops, something went wrong.