Skip to content

Commit

Permalink
Merge branch 'main' into fix/data-asset-perms
Browse files Browse the repository at this point in the history
# Conflicts:
#	backend/dataall/modules/s3_datasets_shares/api/resolvers.py
#	frontend/src/modules/Folders/components/FolderOverview.js
  • Loading branch information
dlpzx committed Dec 9, 2024
2 parents c6d1896 + 15eae8f commit 6c0a444
Show file tree
Hide file tree
Showing 53 changed files with 1,623 additions and 246 deletions.
19 changes: 19 additions & 0 deletions .checkov.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,25 @@
}
]
},
{
"file": "/checkov_pipeline_synth.json",
"findings": [
{
"resource": "AWS::IAM::Role.PipelineRoleDCFDBB91",
"check_ids": [
"CKV_AWS_107",
"CKV_AWS_108",
"CKV_AWS_111"
]
},
{
"resource": "AWS::S3::Bucket.thistableartifactsbucketDB1C8C64",
"check_ids": [
"CKV_AWS_18"
]
}
]
},
{
"file": "/frontend/docker/prod/Dockerfile",
"findings": [
Expand Down
5 changes: 2 additions & 3 deletions backend/dataall/core/environment/api/resolvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

from dataall.core.organizations.api.resolvers import Context, exceptions, get_organization_simplified


log = logging.getLogger()


Expand Down Expand Up @@ -223,6 +222,7 @@ def generate_environment_access_token(context, source, environmentUri: str = Non
def get_environment_stack(context: Context, source: Environment, **kwargs):
return StackService.resolve_parent_obj_stack(
targetUri=source.environmentUri,
targetType='environment',
environmentUri=source.environmentUri,
)

Expand Down Expand Up @@ -275,8 +275,7 @@ def resolve_environment(context, source, **kwargs):
"""Resolves the environment for a environmental resource"""
if not source:
return None
with context.engine.scoped_session() as session:
return EnvironmentService.get_environment_by_uri(session, source.environmentUri)
return EnvironmentService.find_environment_by_uri(uri=source.environmentUri)


def resolve_parameters(context, source: Environment, **kwargs):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ def resolve_organization_by_env(uri):
context = get_context()
with context.db_engine.scoped_session() as session:
env = EnvironmentRepository.get_environment_by_uri(session, uri)
return OrganizationRepository.find_organization_by_uri(session, env.organizationUri)
return OrganizationService.get_organization(uri=env.organizationUri)

@staticmethod
@ResourcePolicyService.has_resource_permission(GET_ORGANIZATION)
Expand Down
9 changes: 8 additions & 1 deletion backend/dataall/core/stacks/services/stack_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,16 @@ def map_target_type_to_log_config_path(**kwargs):

class StackService:
@staticmethod
def resolve_parent_obj_stack(targetUri: str, environmentUri: str):
def resolve_parent_obj_stack(targetUri: str, targetType: str, environmentUri: str):
context = get_context()
with context.db_engine.scoped_session() as session:
ResourcePolicyService.check_user_resource_permission(
session=session,
username=context.username,
groups=context.groups,
resource_uri=targetUri,
permission_name=TargetType.get_resource_read_permission_name(targetType),
)
env: Environment = EnvironmentRepository.get_environment_by_uri(session, environmentUri)
stack: Stack = StackRepository.find_stack_by_target_uri(session, target_uri=targetUri)
if not stack:
Expand Down
24 changes: 22 additions & 2 deletions backend/dataall/core/vpc/services/vpc_service.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import logging

from dataall.base.context import get_context
from dataall.base.db import exceptions
from dataall.base.db.exceptions import ResourceUnauthorized
from dataall.core.permissions.services.group_policy_service import GroupPolicyService
from dataall.core.environment.db.environment_repositories import EnvironmentRepository
from dataall.core.activity.db.activity_models import Activity
from dataall.core.permissions.services.resource_policy_service import ResourcePolicyService
from dataall.core.permissions.services.tenant_policy_service import TenantPolicyService
from dataall.core.vpc.db.vpc_repositories import VpcRepository
from dataall.core.vpc.db.vpc_models import Vpc
from dataall.core.permissions.services.network_permissions import NETWORK_ALL, DELETE_NETWORK
from dataall.core.permissions.services.network_permissions import NETWORK_ALL, DELETE_NETWORK, GET_NETWORK
from dataall.core.permissions.services.environment_permissions import CREATE_NETWORK
from dataall.core.permissions.services.tenant_permissions import MANAGE_ENVIRONMENTS

log = logging.getLogger(__name__)


def _session():
return get_context().db_engine.scoped_session()
Expand Down Expand Up @@ -90,4 +95,19 @@ def delete_network(uri):
@staticmethod
def get_environment_networks(environment_uri):
with _session() as session:
return VpcRepository.get_environment_networks(session=session, environment_uri=environment_uri)
nets = []
all_nets = VpcRepository.get_environment_networks(session=session, environment_uri=environment_uri)
for net in all_nets:
try:
ResourcePolicyService.check_user_resource_permission(
session=session,
username=get_context().username,
groups=get_context().groups,
resource_uri=net.vpcUri,
permission_name=GET_NETWORK,
)
except ResourceUnauthorized as exc:
log.info(exc)
else:
nets += net
return nets
37 changes: 21 additions & 16 deletions backend/dataall/modules/catalog/services/glossaries_service.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
from functools import wraps
import logging
from functools import wraps

from dataall.base.context import get_context
from dataall.base.db import exceptions
from dataall.core.permissions.services.tenant_policy_service import TenantPolicyService

from dataall.modules.catalog.db.glossary_repositories import GlossaryRepository
from dataall.modules.catalog.db.glossary_models import GlossaryNode
from dataall.modules.catalog.services.glossaries_permissions import MANAGE_GLOSSARIES
from dataall.modules.catalog.db.glossary_repositories import GlossaryRepository
from dataall.modules.catalog.indexers.registry import GlossaryRegistry
from dataall.modules.catalog.services.glossaries_permissions import MANAGE_GLOSSARIES

logger = logging.getLogger(__name__)

Expand All @@ -26,23 +25,29 @@ def wrapper(*args, **kwargs):
uri = kwargs.get('uri')
if not uri:
raise KeyError(f"{f.__name__} doesn't have parameter uri.")
context = get_context()
with context.db_engine.scoped_session() as session:
node = GlossaryRepository.get_node(session=session, uri=uri)
while node.nodeType != 'G':
node = GlossaryRepository.get_node(session=session, uri=node.parentUri)
if node and (node.admin in context.groups):
return f(*args, **kwargs)
else:
raise exceptions.UnauthorizedOperation(
action='GLOSSARY MUTATION',
message=f'User {context.username} is not the admin of the glossary {node.label}.',
)
GlossariesResourceAccess.check_owner(uri)
return f(*args, **kwargs)

return wrapper

return decorator

@staticmethod
def check_owner(uri):
context = get_context()
with context.db_engine.scoped_session() as session:
node = GlossaryRepository.get_node(session=session, uri=uri)
MAX_GLOSSARY_DEPTH = 10
depth = 0
while node.nodeType != 'G' and depth <= MAX_GLOSSARY_DEPTH:
node = GlossaryRepository.get_node(session=session, uri=node.parentUri)
depth += 1
if not node or node.admin not in context.groups:
raise exceptions.UnauthorizedOperation(
action='GLOSSARY MUTATION',
message=f'User {context.username} is not the admin of the glossary {node.label}.',
)


class GlossariesService:
@staticmethod
Expand Down
6 changes: 3 additions & 3 deletions backend/dataall/modules/dashboards/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

from dataall.base.loader import ImportMode, ModuleInterface


log = logging.getLogger(__name__)


Expand Down Expand Up @@ -33,16 +32,17 @@ def __init__(self):
from dataall.modules.catalog.indexers.registry import GlossaryRegistry, GlossaryDefinition
from dataall.modules.vote.services.vote_service import add_vote_type
from dataall.modules.dashboards.indexers.dashboard_indexer import DashboardIndexer
from dataall.modules.dashboards.services.dashboard_permissions import GET_DASHBOARD

FeedRegistry.register(FeedDefinition('Dashboard', Dashboard))
FeedRegistry.register(FeedDefinition('Dashboard', Dashboard, GET_DASHBOARD))

GlossaryRegistry.register(
GlossaryDefinition(
target_type='Dashboard', object_type='Dashboard', model=Dashboard, reindexer=DashboardIndexer
)
)

add_vote_type('dashboard', DashboardIndexer)
add_vote_type('dashboard', DashboardIndexer, GET_DASHBOARD)

EnvironmentResourceManager.register(DashboardRepository())
log.info('Dashboard API has been loaded')
Expand Down
6 changes: 6 additions & 0 deletions backend/dataall/modules/dashboards/api/resolvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ def get_dashboard(context: Context, source, dashboardUri: str = None):
return DashboardService.get_dashboard(uri=dashboardUri)


def get_dashboard_restricted_information(context: Context, source: Dashboard):
if not source:
return None
return DashboardService.get_dashboard_restricted_information(uri=source.dashboardUri, dashboard=source)


def resolve_user_role(context: Context, source: Dashboard):
if context.username and source.owner == context.username:
return DashboardRole.Creator.value
Expand Down
13 changes: 11 additions & 2 deletions backend/dataall/modules/dashboards/api/types.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
from dataall.base.api import gql
from dataall.modules.dashboards.api.resolvers import (
DashboardRole,
get_dashboard_organization,
get_dashboard_restricted_information,
resolve_glossary_terms,
resolve_upvotes,
resolve_user_role,
)

from dataall.core.environment.api.resolvers import resolve_environment

DashboardRestrictedInformation = gql.ObjectType(
name='DashboardRestrictedInformation',
fields=[gql.Field('AwsAccountId', type=gql.String), gql.Field('region', type=gql.String)],
)

Dashboard = gql.ObjectType(
name='Dashboard',
fields=[
Expand All @@ -19,10 +24,14 @@
gql.Field('DashboardId', type=gql.String),
gql.Field('tags', type=gql.ArrayType(gql.String)),
gql.Field('created', type=gql.String),
gql.Field('AwsAccountId', type=gql.String),
gql.Field('updated', type=gql.String),
gql.Field('owner', type=gql.String),
gql.Field('SamlGroupName', type=gql.String),
gql.Field(
'restricted',
type=DashboardRestrictedInformation,
resolver=get_dashboard_restricted_information,
),
gql.Field(
'environment',
type=gql.Ref('EnvironmentSimplified'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,16 @@
from dataall.base.aws.parameter_store import ParameterStoreManager
from dataall.base.aws.sts import SessionHelper
from dataall.base.context import get_context
from dataall.core.environment.services.environment_service import EnvironmentService
from dataall.core.permissions.db.tenant.tenant_policy_repositories import TenantPolicyRepository
from dataall.base.db.exceptions import UnauthorizedOperation, TenantUnauthorized, AWSResourceNotFound
from dataall.core.permissions.services.tenant_permissions import TENANT_ALL
from dataall.base.utils import Parameter
from dataall.core.environment.services.environment_service import EnvironmentService
from dataall.core.permissions.services.resource_policy_service import ResourcePolicyService
from dataall.core.permissions.services.tenant_policy_service import TenantPolicyService
from dataall.modules.dashboards.db.dashboard_repositories import DashboardRepository
from dataall.modules.dashboards.db.dashboard_models import Dashboard
from dataall.core.permissions.services.tenant_permissions import TENANT_ALL
from dataall.core.permissions.services.tenant_policy_service import TenantPolicyService, TenantPolicyValidationService
from dataall.modules.dashboards.aws.dashboard_quicksight_client import DashboardQuicksightClient
from dataall.modules.dashboards.db.dashboard_models import Dashboard
from dataall.modules.dashboards.db.dashboard_repositories import DashboardRepository
from dataall.modules.dashboards.services.dashboard_permissions import GET_DASHBOARD, CREATE_DASHBOARD, MANAGE_DASHBOARDS
from dataall.base.utils import Parameter


class DashboardQuicksightService:
Expand Down Expand Up @@ -128,7 +127,7 @@ def get_quicksight_reader_session(cls, dashboard_uri):
@staticmethod
def _check_user_must_be_admin():
context = get_context()
admin = TenantPolicyRepository.is_tenant_admin(context.groups)
admin = TenantPolicyValidationService.is_tenant_admin(context.groups)

if not admin:
raise TenantUnauthorized(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,15 @@ class DashboardService:
"""Service that serves request related to dashboard"""

@staticmethod
@ResourcePolicyService.has_resource_permission(GET_DASHBOARD)
def get_dashboard(uri: str) -> Dashboard:
with get_context().db_engine.scoped_session() as session:
return DashboardRepository.get_dashboard_by_uri(session, uri)

@staticmethod
@ResourcePolicyService.has_resource_permission(GET_DASHBOARD)
def get_dashboard_restricted_information(uri: str, dashboard: Dashboard):
return dashboard

@staticmethod
@TenantPolicyService.has_tenant_permission(MANAGE_DASHBOARDS)
@ResourcePolicyService.has_resource_permission(CREATE_DASHBOARD)
Expand Down
2 changes: 1 addition & 1 deletion backend/dataall/modules/datapipelines/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def __init__(self):
)
import dataall.modules.datapipelines.api

FeedRegistry.register(FeedDefinition('DataPipeline', DataPipeline))
FeedRegistry.register(FeedDefinition('DataPipeline', DataPipeline, GET_PIPELINE))

TargetType('pipeline', GET_PIPELINE, UPDATE_PIPELINE, MANAGE_PIPELINES)
TargetType('cdkpipeline', GET_PIPELINE, UPDATE_PIPELINE, MANAGE_PIPELINES)
Expand Down
1 change: 1 addition & 0 deletions backend/dataall/modules/datapipelines/api/resolvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,6 @@ def resolve_stack(context, source: DataPipeline, **kwargs):
return None
return StackService.resolve_parent_obj_stack(
targetUri=source.DataPipelineUri,
targetType='pipeline',
environmentUri=source.environmentUri,
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@

from dataall.base.aws.sts import SessionHelper
from dataall.base.context import get_context
from dataall.core.permissions.services.group_policy_service import GroupPolicyService
from dataall.base.db import exceptions
from dataall.core.environment.services.environment_service import EnvironmentService
from dataall.core.permissions.services.group_policy_service import GroupPolicyService
from dataall.core.permissions.services.resource_policy_service import ResourcePolicyService
from dataall.core.permissions.services.tenant_policy_service import TenantPolicyService
from dataall.core.stacks.db.keyvaluetag_repositories import KeyValueTagRepository
from dataall.core.stacks.db.stack_repositories import StackRepository
from dataall.core.stacks.services.stack_service import StackService
from dataall.core.tasks.db.task_models import Task
from dataall.core.tasks.service_handlers import Worker
from dataall.base.db import exceptions
from dataall.modules.datapipelines.db.datapipelines_models import DataPipeline, DataPipelineEnvironment
from dataall.modules.datapipelines.db.datapipelines_repositories import DatapipelinesRepository
from dataall.modules.datapipelines.services.datapipelines_permissions import (
Expand All @@ -25,7 +25,6 @@
UPDATE_PIPELINE,
)


logger = logging.getLogger(__name__)


Expand All @@ -34,6 +33,10 @@ def _session():


class DataPipelineService:
@staticmethod
def _get_pipeline_uri_from_env_uri(session, envPipelineUri):
return DatapipelinesRepository.get_pipeline_environment_by_uri(session, envPipelineUri).pipelineUri

@staticmethod
@TenantPolicyService.has_tenant_permission(MANAGE_PIPELINES)
@ResourcePolicyService.has_resource_permission(CREATE_PIPELINE)
Expand Down Expand Up @@ -255,6 +258,9 @@ def _delete_repository(target_uri, accountid, cdk_role_arn, region, repo_name):

@staticmethod
@TenantPolicyService.has_tenant_permission(MANAGE_PIPELINES)
@ResourcePolicyService.has_resource_permission(
UPDATE_PIPELINE, param_name='envPipelineUri', parent_resource=_get_pipeline_uri_from_env_uri
)
def delete_pipeline_environment(envPipelineUri: str):
with _session() as session:
DatapipelinesRepository.delete_pipeline_environment(session=session, envPipelineUri=envPipelineUri)
Expand Down
4 changes: 2 additions & 2 deletions backend/dataall/modules/datasets_base/api/resolvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ def get_dataset_organization(context, source: DatasetBase, **kwargs):
def get_dataset_environment(context, source: DatasetBase, **kwargs):
if not source:
return None
with context.engine.scoped_session() as session:
return EnvironmentService.get_environment_by_uri(session, source.environmentUri)
return EnvironmentService.find_environment_by_uri(uri=source.environmentUri)


def get_dataset_owners_group(context, source: DatasetBase, **kwargs):
Expand All @@ -79,5 +78,6 @@ def resolve_dataset_stack(context: Context, source: DatasetBase, **kwargs):
return None
return StackService.resolve_parent_obj_stack(
targetUri=source.datasetUri,
targetType='dataset',
environmentUri=source.environmentUri,
)
Loading

0 comments on commit 6c0a444

Please sign in to comment.