-
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.
Redshift data sharing - Added methods from sharing back to redshift d…
…atasets (check_on_delete, list_shared_datasets...) (#1511) ### Feature or Bugfix - Feature ### Detail Complete design in #955. This particular PR is focused on adding missing functionalities in redshift_datasets that need to be implemented inside redshift_datasets. For example, when we delete a redshift dataset we would want to first check if there are any share requests shared for that dataset. To avoid circular dependencies it is required to use an interface in the same way it was implemented for S3. In this PR: - Add `RedshiftShareDatasetService(DatasetServiceInterface)` class and implement required abstract methods (check_on_delete, resolve_user_shared_datasets..... - Use this class in redshift_Datasets module in resolvers, on dataset deletion... - Some of the code was very similar to the db queries implemented by S3 datasets; for this reason in this PR some of the queries are moved to the generic ShareObjectRepository to be reused by both types of dataset ### Relates - #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
11 changed files
with
263 additions
and
104 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
97 changes: 97 additions & 0 deletions
97
backend/dataall/modules/redshift_datasets_shares/services/redshift_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,97 @@ | ||
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.shares_base.db.share_object_repositories import ShareObjectRepository | ||
from dataall.modules.shares_base.db.share_state_machines_repositories import ShareStatusRepository | ||
from dataall.modules.shares_base.services.share_permissions import SHARE_OBJECT_APPROVER | ||
from dataall.modules.redshift_datasets.services.redshift_dataset_permissions import DELETE_REDSHIFT_DATASET | ||
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 RedshiftShareDatasetService(DatasetServiceInterface): | ||
@property | ||
def dataset_type(self): | ||
return DatasetTypes.Redshift | ||
|
||
@staticmethod | ||
def resolve_additional_dataset_user_role(session, uri, username, groups): | ||
"""Implemented as part of the DatasetServiceInterface""" | ||
share = ShareObjectRepository.find_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_REDSHIFT_DATASET]: | ||
share_item_shared_states = ShareStatusRepository.get_share_item_shared_states() | ||
shares = ShareObjectRepository.list_dataset_shares_with_existing_shared_items( | ||
session=session, dataset_uri=uri, share_item_shared_states=share_item_shared_states | ||
) | ||
log.info(f'Found {len(shares)} shares for dataset {uri}') | ||
for share in shares: | ||
log.info(f'Share {share.shareUri} items, {share.status}') | ||
if shares: | ||
raise exceptions.ResourceShared( | ||
action=DELETE_REDSHIFT_DATASET, | ||
message='Revoke all dataset shares before deletion.', | ||
) | ||
return True | ||
|
||
@staticmethod | ||
def execute_on_delete(session, uri, **kwargs): | ||
"""Implemented as part of the DatasetServiceInterface""" | ||
action = kwargs.get('action') | ||
if action in [DELETE_REDSHIFT_DATASET]: | ||
share_item_shared_states = ShareStatusRepository.get_share_item_shared_states() | ||
ShareObjectRepository.delete_dataset_shares_with_no_shared_items(session, uri, share_item_shared_states) | ||
return True | ||
|
||
@staticmethod | ||
def append_to_list_user_datasets(session, username, groups): | ||
"""Implemented as part of the DatasetServiceInterface""" | ||
share_item_shared_states = ShareStatusRepository.get_share_item_shared_states() | ||
return ShareObjectRepository.list_user_shared_datasets( | ||
session, username, groups, share_item_shared_states, DatasetTypes.Redshift | ||
) | ||
|
||
@staticmethod | ||
def extend_attach_steward_permissions(session, dataset, new_stewards, **kwargs): | ||
"""Implemented as part of the DatasetServiceInterface""" | ||
dataset_shares = ShareObjectRepository.find_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 = ShareObjectRepository.find_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, | ||
) |
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
Oops, something went wrong.