diff --git a/backend/dataall/core/environment/api/resolvers.py b/backend/dataall/core/environment/api/resolvers.py index 06878cdfc..097e0a405 100644 --- a/backend/dataall/core/environment/api/resolvers.py +++ b/backend/dataall/core/environment/api/resolvers.py @@ -11,7 +11,7 @@ from dataall.base.aws.parameter_store import ParameterStoreManager from dataall.base.aws.sts import SessionHelper from dataall.base.utils import Parameter -from dataall.core.environment.db.environment_models import EnvironmentGroup +from dataall.core.environment.db.environment_models import Environment, EnvironmentGroup from dataall.core.environment.services.environment_resource_manager import EnvironmentResourceManager from dataall.core.environment.services.environment_service import EnvironmentService from dataall.core.environment.api.enums import EnvironmentPermission diff --git a/backend/dataall/core/environment/db/environment_repositories.py b/backend/dataall/core/environment/db/environment_repositories.py index 58e1195d4..420a834f0 100644 --- a/backend/dataall/core/environment/db/environment_repositories.py +++ b/backend/dataall/core/environment/db/environment_repositories.py @@ -44,3 +44,16 @@ def get_environment_by_uri(session, uri): if not environment: raise exceptions.ObjectNotFound(Environment.__name__, uri) return environment + + @staticmethod + def count_environments_with_organization_uri(session, uri): + return session.query(Environment).filter(Environment.organizationUri == uri).count() + + @staticmethod + def count_environments_with_organization_and_group(session, organization, group): + return session.query(Environment).filter( + and_( + Environment.organizationUri == organization.organizationUri, + Environment.SamlGroupName == group, + ) + ).count() diff --git a/backend/dataall/core/environment/services/environment_service.py b/backend/dataall/core/environment/services/environment_service.py index 1b2dbec07..f7d2b3d7e 100644 --- a/backend/dataall/core/environment/services/environment_service.py +++ b/backend/dataall/core/environment/services/environment_service.py @@ -23,7 +23,7 @@ ) from dataall.base.db import exceptions from dataall.core.permissions import permissions -from dataall.core.organizations.db.organization_repositories import Organization +from dataall.core.organizations.db.organization_repositories import OrganizationRepository from dataall.core.environment.db.environment_models import Environment, EnvironmentGroup from dataall.core.environment.api.enums import EnvironmentPermission, EnvironmentType @@ -42,7 +42,7 @@ class EnvironmentService: def create_environment(session, uri, data=None): context = get_context() EnvironmentService._validate_creation_params(data, uri) - organization = Organization.get_organization_by_uri(session, uri) + organization = OrganizationRepository.get_organization_by_uri(session, uri) env = Environment( organizationUri=data.get('organizationUri'), label=data.get('label', 'Unnamed'), diff --git a/backend/dataall/core/groups/api/resolvers.py b/backend/dataall/core/groups/api/resolvers.py index ac1c8f7f0..1e929626f 100644 --- a/backend/dataall/core/groups/api/resolvers.py +++ b/backend/dataall/core/groups/api/resolvers.py @@ -5,7 +5,7 @@ from dataall.base.services.service_provider_factory import ServiceProviderFactory from dataall.core.groups.db.group_models import Group from dataall.core.environment.services.environment_service import EnvironmentService -from dataall.core.organizations.db.organization_repositories import Organization +from dataall.core.organizations.db.organization_repositories import OrganizationRepository from dataall.core.permissions.db.tenant_policy_repositories import TenantPolicy from dataall.base.db import exceptions @@ -61,8 +61,8 @@ def list_groups(context, source, filter: dict = None): ).all() if category == 'organization': with context.engine.scoped_session() as session: - organization = Organization.get_organization_by_uri(session, category_uri) - invited_groups = Organization.query_organization_groups( + organization = OrganizationRepository.get_organization_by_uri(session, category_uri) + invited_groups = OrganizationRepository.query_organization_groups( session=session, uri=organization.organizationUri, filter=None, diff --git a/backend/dataall/core/organizations/api/input_types.py b/backend/dataall/core/organizations/api/input_types.py index 87f69d1cb..2931ad64b 100644 --- a/backend/dataall/core/organizations/api/input_types.py +++ b/backend/dataall/core/organizations/api/input_types.py @@ -55,24 +55,6 @@ class OrganizationSortField(GraphQLEnumMapper): ], ) - -OrganizationTopicFilter = gql.InputType( - name='OrganizationTopicFilter', - arguments=[ - gql.Argument(name='term', type=gql.String), - gql.Argument(name='page', type=gql.Integer), - gql.Argument(name='pageSize', type=gql.Integer), - ], -) - -OrganizationTopicInput = gql.InputType( - name='OrganizationTopicInput', - arguments=[ - gql.Argument(name='label', type=gql.String), - gql.Argument(name='description', type=gql.String), - ], -) - InviteGroupToOrganizationInput = gql.InputType( name='InviteGroupToOrganizationInput', arguments=[ diff --git a/backend/dataall/core/organizations/api/resolvers.py b/backend/dataall/core/organizations/api/resolvers.py index f866b7c72..46553269a 100644 --- a/backend/dataall/core/organizations/api/resolvers.py +++ b/backend/dataall/core/organizations/api/resolvers.py @@ -1,110 +1,74 @@ from dataall.base.api.context import Context -from dataall.core.environment.db.environment_models import Environment -from dataall.core.organizations.api.enums import OrganisationUserRole -from dataall.core.organizations.db.organization_repositories import Organization +from dataall.base.db import exceptions from dataall.core.organizations.db import organization_models as models +from dataall.core.organizations.services.organization_service import OrganizationService def create_organization(context: Context, source, input=None): - with context.engine.scoped_session() as session: - organization = Organization.create_organization( - session=session, - data=input, - ) - return organization + if not input: + raise exceptions.RequiredParameter(input) + if not input.get('SamlGroupName'): + raise exceptions.RequiredParameter('groupUri') + if not input.get('label'): + raise exceptions.RequiredParameter('label') + + return OrganizationService.create_organization(data=input) def update_organization(context, source, organizationUri=None, input=None): - with context.engine.scoped_session() as session: - return Organization.update_organization( - session=session, - uri=organizationUri, - data=input, - ) + return OrganizationService.update_organization( + uri=organizationUri, + data=input, + ) def get_organization(context: Context, source, organizationUri=None): - with context.engine.scoped_session() as session: - return Organization.get_organization_by_uri( - session=session, uri=organizationUri - ) + return OrganizationService.get_organization(uri=organizationUri) def list_organizations(context: Context, source, filter=None): if not filter: filter = {'page': 1, 'pageSize': 5} - with context.engine.scoped_session() as session: - return Organization.paginated_user_organizations( - session=session, - data=filter, - ) + return OrganizationService.list_organizations(filter) def list_organization_environments(context, source, filter=None): if not filter: filter = {'page': 1, 'pageSize': 5} - with context.engine.scoped_session() as session: - return Organization.paginated_organization_environments( - session=session, - uri=source.organizationUri, - data=filter, - ) - -def stats(context, source: models.Organization, **kwargs): - with context.engine.scoped_session() as session: - environments = Organization.count_organization_environments( - session=session, uri=source.organizationUri - ) + return OrganizationService.list_organization_environments(filter=filter, uri=source.organizationUri) - groups = Organization.count_organization_invited_groups( - session=session, uri=source.organizationUri, group=source.SamlGroupName - ) - return {'environments': environments, 'groups': groups, 'users': 0} +def stats(context, source: models.Organization, **kwargs): + return OrganizationService.count_organization_resources( + uri=source.organizationUri, + group=source.SamlGroupName + ) def resolve_user_role(context: Context, source: models.Organization): - if source.owner == context.username: - return OrganisationUserRole.Owner.value - elif source.SamlGroupName in context.groups: - return OrganisationUserRole.Admin.value - else: - with context.engine.scoped_session() as session: - if Organization.find_organization_membership( - session=session, uri=source.organizationUri, groups=context.groups - ): - return OrganisationUserRole.Invited.value - return OrganisationUserRole.NoPermission.value + return OrganizationService.resolve_user_role(organization=source) def archive_organization(context: Context, source, organizationUri: str = None): - with context.engine.scoped_session() as session: - return Organization.archive_organization( - session=session, - uri=organizationUri, - ) + return OrganizationService.archive_organization(uri=organizationUri) def invite_group(context: Context, source, input): - with context.engine.scoped_session() as session: - organization, organization_group = Organization.invite_group( - session=session, - uri=input['organizationUri'], - data=input, - ) - return organization + if not input: + raise exceptions.RequiredParameter(input) + if not input.get('groupUri'): + raise exceptions.RequiredParameter('groupUri') + + return OrganizationService.invite_group(uri=input['organizationUri'], data=input) def remove_group(context: Context, source, organizationUri=None, groupUri=None): - with context.engine.scoped_session() as session: - organization = Organization.remove_group( - session=session, - uri=organizationUri, - group=groupUri - ) - return organization + return OrganizationService.remove_group( + uri=organizationUri, + group=groupUri, + ) def list_organization_groups( @@ -112,12 +76,11 @@ def list_organization_groups( ): if filter is None: filter = {} - with context.engine.scoped_session() as session: - return Organization.paginated_organization_groups( - session=session, - uri=organizationUri, - data=filter, - ) + + return OrganizationService.list_organization_groups( + filter=filter, + uri=organizationUri + ) def resolve_organization_by_env(context, source, **kwargs): @@ -126,8 +89,5 @@ def resolve_organization_by_env(context, source, **kwargs): """ if not source: return None - with context.engine.scoped_session() as session: - env: Environment = session.query(Environment).get( - source.environmentUri - ) - return session.query(models.Organization).get(env.organizationUri) + + return OrganizationService.resolve_organization_by_env(uri=source.environmentUri) diff --git a/backend/dataall/core/organizations/db/organization_repositories.py b/backend/dataall/core/organizations/db/organization_repositories.py index 057496afa..cc404d21d 100644 --- a/backend/dataall/core/organizations/db/organization_repositories.py +++ b/backend/dataall/core/organizations/db/organization_repositories.py @@ -3,25 +3,20 @@ from sqlalchemy import or_, and_ from sqlalchemy.orm import Query -from dataall.core.permissions import permissions from dataall.base.db import exceptions, paginate -from dataall.core.organizations.db.organization_models import OrganizationGroup, OrganisationUserRole from dataall.core.organizations.db import organization_models as models from dataall.core.environment.db.environment_models import Environment -from dataall.core.permissions.permission_checker import has_resource_permission, has_tenant_permission from dataall.base.context import get_context -from dataall.core.permissions.db.resource_policy_repositories import ResourcePolicy -from dataall.core.activity.db.activity_models import Activity logger = logging.getLogger(__name__) -class Organization: +class OrganizationRepository: @staticmethod def get_organization_by_uri(session, uri: str) -> models.Organization: if not uri: raise exceptions.RequiredParameter(param_name='organizationUri') - org = Organization.find_organization_by_uri(session, uri) + org = OrganizationRepository.find_organization_by_uri(session, uri) if not org: raise exceptions.ObjectNotFound('Organization', uri) return org @@ -30,80 +25,6 @@ def get_organization_by_uri(session, uri: str) -> models.Organization: def find_organization_by_uri(session, uri) -> models.Organization: return session.query(models.Organization).get(uri) - @staticmethod - @has_tenant_permission(permissions.MANAGE_ORGANIZATIONS) - def create_organization(session, data=None) -> models.Organization: - if not data: - raise exceptions.RequiredParameter(data) - if not data.get('SamlGroupName'): - raise exceptions.RequiredParameter('groupUri') - if not data.get('label'): - raise exceptions.RequiredParameter('label') - - username = get_context().username - org = models.Organization( - label=data.get('label'), - owner=username, - tags=data.get('tags', []), - description=data.get('description', 'No description provided'), - SamlGroupName=data.get('SamlGroupName'), - userRoleInOrganization=OrganisationUserRole.Owner.value, - ) - session.add(org) - session.commit() - member = models.OrganizationGroup( - organizationUri=org.organizationUri, - groupUri=data['SamlGroupName'], - ) - session.add(member) - - activity = Activity( - action='org:create', - label='org:create', - owner=username, - summary=f'{username} create organization {org.name} ', - targetUri=org.organizationUri, - targetType='org', - ) - session.add(activity) - - ResourcePolicy.attach_resource_policy( - session=session, - group=data['SamlGroupName'], - permissions=permissions.ORGANIZATION_ALL, - resource_uri=org.organizationUri, - resource_type=models.Organization.__name__, - ) - - return org - - @staticmethod - @has_resource_permission(permissions.UPDATE_ORGANIZATION) - def update_organization(session, uri, data=None): - organization = Organization.get_organization_by_uri(session, uri) - for field in data.keys(): - setattr(organization, field, data.get(field)) - session.commit() - - context = get_context() - activity = Activity( - action='org:update', - label='org:create', - owner=context.username, - summary=f'{context.username} updated organization {organization.name} ', - targetUri=organization.organizationUri, - targetType='org', - ) - session.add(activity) - ResourcePolicy.attach_resource_policy( - session=session, - group=organization.SamlGroupName, - permissions=permissions.ORGANIZATION_ALL, - resource_uri=organization.organizationUri, - resource_type=models.Organization.__name__, - ) - return organization - @staticmethod def query_user_organizations(session, username, groups, filter) -> Query: query = ( @@ -133,7 +54,7 @@ def query_user_organizations(session, username, groups, filter) -> Query: def paginated_user_organizations(session, data=None) -> dict: context = get_context() return paginate( - query=Organization.query_user_organizations(session, context.username, context.groups, data), + query=OrganizationRepository.query_user_organizations(session, context.username, context.groups, data), page=data.get('page', 1), page_size=data.get('pageSize', 10), ).to_dict() @@ -151,66 +72,13 @@ def query_organization_environments(session, uri, filter) -> Query: return query @staticmethod - @has_resource_permission(permissions.GET_ORGANIZATION) def paginated_organization_environments(session, uri, data=None) -> dict: return paginate( - query=Organization.query_organization_environments(session, uri, data), + query=OrganizationRepository.query_organization_environments(session, uri, data), page=data.get('page', 1), page_size=data.get('pageSize', 10), ).to_dict() - @staticmethod - @has_tenant_permission(permissions.MANAGE_ORGANIZATIONS) - @has_resource_permission(permissions.DELETE_ORGANIZATION) - def archive_organization(session, uri) -> bool: - org = Organization.get_organization_by_uri(session, uri) - environments = session.query(Environment).filter(Environment.organizationUri == uri).count() - if environments: - raise exceptions.UnauthorizedOperation( - action='ARCHIVE_ORGANIZATION', - message='The organization you tried to delete has linked environments', - ) - session.delete(org) - ResourcePolicy.delete_resource_policy( - session=session, - group=org.SamlGroupName, - resource_uri=org.organizationUri, - resource_type=models.Organization.__name__, - ) - - return True - - @staticmethod - @has_tenant_permission(permissions.MANAGE_ORGANIZATIONS) - @has_resource_permission(permissions.INVITE_ORGANIZATION_GROUP) - def invite_group(session, uri, data=None) -> (models.Organization, models.OrganizationGroup): - Organization.validate_invite_params(data) - - group: str = data['groupUri'] - - organization = Organization.get_organization_by_uri(session, uri) - - group_membership = Organization.find_group_membership(session, group, organization) - if group_membership: - raise exceptions.UnauthorizedOperation( - action='INVITE_TEAM', - message=f'Team {group} is already admin of the organization {organization.name}', - ) - org_group = OrganizationGroup( - organizationUri=organization.organizationUri, - groupUri=group, - invitedBy=get_context().username, - ) - session.add(org_group) - ResourcePolicy.attach_resource_policy( - session=session, - group=group, - resource_uri=organization.organizationUri, - permissions=permissions.ORGANIZATION_INVITED, - resource_type=models.Organization.__name__, - ) - return organization, org_group - @staticmethod def find_group_membership(session, group, organization): membership = ( @@ -227,54 +95,6 @@ def find_group_membership(session, group, organization): ) return membership - @staticmethod - def validate_invite_params(data): - if not data: - raise exceptions.RequiredParameter(data) - if not data.get('groupUri'): - raise exceptions.RequiredParameter('groupUri') - - @staticmethod - @has_tenant_permission(permissions.MANAGE_ORGANIZATIONS) - @has_resource_permission(permissions.REMOVE_ORGANIZATION_GROUP) - def remove_group(session, uri, group): - organization = Organization.get_organization_by_uri(session, uri) - - if group == organization.SamlGroupName: - raise exceptions.UnauthorizedOperation( - action='REMOVE_TEAM', - message=f'Team: {group} is the owner of the organization {organization.name}', - ) - - group_env_objects_count = ( - session.query(Environment) - .filter( - and_( - Environment.organizationUri == organization.organizationUri, - Environment.SamlGroupName == group, - ) - ) - .count() - ) - if group_env_objects_count > 0: - raise exceptions.OrganizationResourcesFound( - action='Remove Team', - message=f'Team: {group} has {group_env_objects_count} linked environments on this environment.', - ) - - group_membership = Organization.find_group_membership(session, group, organization) - if group_membership: - session.delete(group_membership) - session.commit() - - ResourcePolicy.delete_resource_policy( - session=session, - group=group, - resource_uri=organization.organizationUri, - resource_type=models.Organization.__name__, - ) - return organization - @staticmethod def query_organization_groups(session, uri, filter) -> Query: query = session.query(models.OrganizationGroup).filter(models.OrganizationGroup.organizationUri == uri) @@ -287,10 +107,9 @@ def query_organization_groups(session, uri, filter) -> Query: return query @staticmethod - @has_resource_permission(permissions.GET_ORGANIZATION) def paginated_organization_groups(session, uri, data=None) -> dict: return paginate( - query=Organization.query_organization_groups(session, uri, data), + query=OrganizationRepository.query_organization_groups(session, uri, data), page=data.get('page', 1), page_size=data.get('pageSize', 10), ).to_dict() @@ -309,17 +128,6 @@ def count_organization_invited_groups(session, uri, group) -> int: ) return groups - @staticmethod - def count_organization_environments(session, uri) -> int: - envs = ( - session.query(Environment) - .filter( - Environment.organizationUri == uri, - ) - .count() - ) - return envs - @staticmethod def find_organization_membership(session, uri, groups) -> int: groups = ( @@ -332,7 +140,4 @@ def find_organization_membership(session, uri, groups) -> int: ) .count() ) - if groups >= 1: - return True - else: - return False + return groups >= 1 diff --git a/backend/dataall/core/organizations/services/__init__.py b/backend/dataall/core/organizations/services/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/backend/dataall/core/organizations/services/organization_service.py b/backend/dataall/core/organizations/services/organization_service.py new file mode 100644 index 000000000..c81026b9e --- /dev/null +++ b/backend/dataall/core/organizations/services/organization_service.py @@ -0,0 +1,254 @@ +from dataall.base.context import get_context +from dataall.base.db import exceptions +from dataall.core.activity.db.activity_models import Activity +from dataall.core.environment.db.environment_repositories import EnvironmentRepository +from dataall.core.organizations.db.organization_repositories import OrganizationRepository +from dataall.core.organizations.db.organization_models import OrganisationUserRole, OrganizationGroup +from dataall.core.organizations.db import organization_models as models +from dataall.core.permissions import permissions +from dataall.core.permissions.permission_checker import has_tenant_permission, has_resource_permission +from dataall.core.permissions.db.resource_policy_repositories import ResourcePolicy + + +class OrganizationService: + """Service that serves request related to organization""" + + @staticmethod + @has_tenant_permission(permissions.MANAGE_ORGANIZATIONS) + def create_organization(data): + context = get_context() + with context.db_engine.scoped_session() as session: + username = context.username + org = models.Organization( + label=data.get('label'), + owner=username, + tags=data.get('tags', []), + description=data.get('description', 'No description provided'), + SamlGroupName=data.get('SamlGroupName'), + userRoleInOrganization=OrganisationUserRole.Owner.value, + ) + session.add(org) + session.commit() + + member = models.OrganizationGroup( + organizationUri=org.organizationUri, + groupUri=data['SamlGroupName'], + ) + session.add(member) + + activity = Activity( + action='org:create', + label='org:create', + owner=username, + summary=f'{username} create organization {org.name} ', + targetUri=org.organizationUri, + targetType='org', + ) + session.add(activity) + + ResourcePolicy.attach_resource_policy( + session=session, + group=data['SamlGroupName'], + permissions=permissions.ORGANIZATION_ALL, + resource_uri=org.organizationUri, + resource_type=models.Organization.__name__, + ) + + return org + + @staticmethod + @has_resource_permission(permissions.UPDATE_ORGANIZATION) + def update_organization(uri, data): + context = get_context() + with context.db_engine.scoped_session() as session: + organization = OrganizationRepository.get_organization_by_uri(session, uri) + for field in data.keys(): + setattr(organization, field, data.get(field)) + session.commit() + + activity = Activity( + action='org:update', + label='org:create', + owner=context.username, + summary=f'{context.username} updated organization {organization.name} ', + targetUri=organization.organizationUri, + targetType='org', + ) + session.add(activity) + ResourcePolicy.attach_resource_policy( + session=session, + group=organization.SamlGroupName, + permissions=permissions.ORGANIZATION_ALL, + resource_uri=organization.organizationUri, + resource_type=models.Organization.__name__, + ) + return organization + + @staticmethod + @has_resource_permission(permissions.GET_ORGANIZATION) + def get_organization(uri): + context = get_context() + with context.db_engine.scoped_session() as session: + return OrganizationRepository.get_organization_by_uri( + session=session, uri=uri + ) + + @staticmethod + def list_organizations(filter): + context = get_context() + with context.db_engine.scoped_session() as session: + return OrganizationRepository.paginated_user_organizations( + session=session, + data=filter, + ) + + @staticmethod + @has_resource_permission(permissions.GET_ORGANIZATION) + def list_organization_environments(filter, uri): + context = get_context() + with context.db_engine.scoped_session() as session: + return OrganizationRepository.paginated_organization_environments( + session=session, + uri=uri, + data=filter, + ) + + @staticmethod + def count_organization_resources(uri, group): + context = get_context() + with context.db_engine.scoped_session() as session: + environments = EnvironmentRepository.count_environments_with_organization_uri( + session=session, uri=uri + ) + + groups = OrganizationRepository.count_organization_invited_groups( + session=session, uri=uri, group=group + ) + + return {'environments': environments, 'groups': groups, 'users': 0} + + @staticmethod + def resolve_user_role(organization): + context = get_context() + if organization.owner == context.username: + return OrganisationUserRole.Owner.value + elif organization.SamlGroupName in context.groups: + return OrganisationUserRole.Admin.value + else: + with context.db_engine.scoped_session() as session: + if OrganizationRepository.find_organization_membership( + session=session, uri=organization.organizationUri, groups=context.groups + ): + return OrganisationUserRole.Invited.value + return OrganisationUserRole.NoPermission.value + + @staticmethod + @has_tenant_permission(permissions.MANAGE_ORGANIZATIONS) + @has_resource_permission(permissions.DELETE_ORGANIZATION) + def archive_organization(uri): + context = get_context() + with context.db_engine.scoped_session() as session: + org = OrganizationRepository.get_organization_by_uri(session, uri) + environments = EnvironmentRepository.count_environments_with_organization_uri(session, uri) + if environments: + raise exceptions.UnauthorizedOperation( + action='ARCHIVE_ORGANIZATION', + message='The organization you tried to delete has linked environments', + ) + session.delete(org) + ResourcePolicy.delete_resource_policy( + session=session, + group=org.SamlGroupName, + resource_uri=org.organizationUri, + resource_type=models.Organization.__name__, + ) + + return True + + @staticmethod + @has_tenant_permission(permissions.MANAGE_ORGANIZATIONS) + @has_resource_permission(permissions.INVITE_ORGANIZATION_GROUP) + def invite_group(uri, data): + context = get_context() + with context.db_engine.scoped_session() as session: + group: str = data['groupUri'] + + organization = OrganizationRepository.get_organization_by_uri(session, uri) + + group_membership = OrganizationRepository.find_group_membership(session, group, organization) + if group_membership: + raise exceptions.UnauthorizedOperation( + action='INVITE_TEAM', + message=f'Team {group} is already admin of the organization {organization.name}', + ) + org_group = OrganizationGroup( + organizationUri=organization.organizationUri, + groupUri=group, + invitedBy=context.username, + ) + session.add(org_group) + ResourcePolicy.attach_resource_policy( + session=session, + group=group, + resource_uri=organization.organizationUri, + permissions=permissions.ORGANIZATION_INVITED, + resource_type=models.Organization.__name__, + ) + + return organization + + @staticmethod + @has_tenant_permission(permissions.MANAGE_ORGANIZATIONS) + @has_resource_permission(permissions.REMOVE_ORGANIZATION_GROUP) + def remove_group(uri, group): + context = get_context() + with context.db_engine.scoped_session() as session: + organization = OrganizationRepository.get_organization_by_uri(session, uri) + + if group == organization.SamlGroupName: + raise exceptions.UnauthorizedOperation( + action='REMOVE_TEAM', + message=f'Team: {group} is the owner of the organization {organization.name}', + ) + + group_env_objects_count = EnvironmentRepository.count_environments_with_organization_and_group( + session=session, + organization=organization, + group=group + ) + if group_env_objects_count > 0: + raise exceptions.OrganizationResourcesFound( + action='Remove Team', + message=f'Team: {group} has {group_env_objects_count} linked environments on this environment.', + ) + + group_membership = OrganizationRepository.find_group_membership(session, group, organization) + if group_membership: + session.delete(group_membership) + session.commit() + + ResourcePolicy.delete_resource_policy( + session=session, + group=group, + resource_uri=organization.organizationUri, + resource_type=models.Organization.__name__, + ) + return organization + + @staticmethod + @has_resource_permission(permissions.GET_ORGANIZATION) + def list_organization_groups(filter, uri): + context = get_context() + with context.db_engine.scoped_session() as session: + return OrganizationRepository.paginated_organization_groups( + session=session, + uri=uri, + data=filter, + ) + + @staticmethod + 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) diff --git a/backend/dataall/core/stacks/services/runtime_stacks_tagging.py b/backend/dataall/core/stacks/services/runtime_stacks_tagging.py index af9cca2f9..ff9afe0c3 100644 --- a/backend/dataall/core/stacks/services/runtime_stacks_tagging.py +++ b/backend/dataall/core/stacks/services/runtime_stacks_tagging.py @@ -7,7 +7,7 @@ from dataall.base import db from dataall.core.environment.db.environment_models import Environment from dataall.core.environment.services.environment_service import EnvironmentService -from dataall.core.organizations.db.organization_repositories import Organization +from dataall.core.organizations.db.organization_repositories import OrganizationRepository from dataall.core.stacks.db.keyvaluetag_repositories import KeyValueTag from dataall.core.stacks.db.stack_models import KeyValueTag as KeyValueTagModel @@ -123,7 +123,7 @@ def get_target(cls, session, stack, model_name): @classmethod def get_organization(cls, session, environment): - organisation = Organization.get_organization_by_uri( + organisation = OrganizationRepository.get_organization_by_uri( session, environment.organizationUri ) return organisation diff --git a/backend/dataall/modules/dashboards/api/resolvers.py b/backend/dataall/modules/dashboards/api/resolvers.py index eefae4eca..2d8594ce9 100644 --- a/backend/dataall/modules/dashboards/api/resolvers.py +++ b/backend/dataall/modules/dashboards/api/resolvers.py @@ -1,6 +1,6 @@ from dataall.base.api.context import Context from dataall.modules.catalog.db.glossary_repositories import GlossaryRepository -from dataall.core.organizations.db.organization_repositories import Organization +from dataall.core.organizations.db.organization_repositories import OrganizationRepository from dataall.modules.vote.db.vote_repositories import VoteRepository from dataall.base.db.exceptions import RequiredParameter from dataall.modules.dashboards.api.enums import DashboardRole @@ -60,7 +60,7 @@ def resolve_user_role(context: Context, source: Dashboard): def get_dashboard_organization(context: Context, source: Dashboard, **kwargs): with context.engine.scoped_session() as session: - return Organization.get_organization_by_uri(session, source.organizationUri) + return OrganizationRepository.get_organization_by_uri(session, source.organizationUri) def request_dashboard_share( diff --git a/backend/dataall/modules/dashboards/indexers/dashboard_indexer.py b/backend/dataall/modules/dashboards/indexers/dashboard_indexer.py index 448b55812..c1d59bc3d 100644 --- a/backend/dataall/modules/dashboards/indexers/dashboard_indexer.py +++ b/backend/dataall/modules/dashboards/indexers/dashboard_indexer.py @@ -1,7 +1,7 @@ import logging from dataall.core.environment.services.environment_service import EnvironmentService -from dataall.core.organizations.db.organization_repositories import Organization +from dataall.core.organizations.db.organization_repositories import OrganizationRepository from dataall.modules.vote.db.vote_repositories import VoteRepository from dataall.modules.dashboards import DashboardRepository from dataall.modules.catalog.indexers.base_indexer import BaseIndexer @@ -17,7 +17,7 @@ def upsert(cls, session, dashboard_uri: str): if dashboard: env = EnvironmentService.get_environment_by_uri(session, dashboard.environmentUri) - org = Organization.get_organization_by_uri(session, env.organizationUri) + org = OrganizationRepository.get_organization_by_uri(session, env.organizationUri) glossary = BaseIndexer._get_target_glossary_terms(session, dashboard_uri) count_upvotes = VoteRepository.count_upvotes( diff --git a/backend/dataall/modules/dataset_sharing/api/resolvers.py b/backend/dataall/modules/dataset_sharing/api/resolvers.py index d0ae3a568..ab0d94fa7 100644 --- a/backend/dataall/modules/dataset_sharing/api/resolvers.py +++ b/backend/dataall/modules/dataset_sharing/api/resolvers.py @@ -4,7 +4,7 @@ from dataall.base.api.context import Context from dataall.core.environment.db.environment_models import Environment from dataall.core.environment.services.environment_service import EnvironmentService -from dataall.core.organizations.db.organization_repositories import Organization +from dataall.core.organizations.db.organization_repositories import OrganizationRepository from dataall.base.db.exceptions import RequiredParameter from dataall.modules.dataset_sharing.api.enums import ShareObjectPermission from dataall.modules.dataset_sharing.db.share_object_models import ShareObjectItem, ShareObject @@ -143,7 +143,7 @@ def resolve_principal(context: Context, source: ShareObject, **kwargs): with context.engine.scoped_session() as session: if source.principalType in ['Group', 'ConsumptionRole']: environment = EnvironmentService.get_environment_by_uri(session, source.environmentUri) - organization = Organization.get_organization_by_uri( + organization = OrganizationRepository.get_organization_by_uri( session, environment.organizationUri ) if source.principalType in ['ConsumptionRole']: diff --git a/backend/dataall/modules/datasets/api/dataset/resolvers.py b/backend/dataall/modules/datasets/api/dataset/resolvers.py index 48104c48e..8fd19f2c1 100644 --- a/backend/dataall/modules/datasets/api/dataset/resolvers.py +++ b/backend/dataall/modules/datasets/api/dataset/resolvers.py @@ -5,7 +5,7 @@ from dataall.base.feature_toggle_checker import is_feature_enabled from dataall.modules.catalog.db.glossary_repositories import GlossaryRepository from dataall.core.environment.services.environment_service import EnvironmentService -from dataall.core.organizations.db.organization_repositories import Organization +from dataall.core.organizations.db.organization_repositories import OrganizationRepository from dataall.base.db.exceptions import RequiredParameter, InvalidInput from dataall.modules.dataset_sharing.db.share_object_models import ShareObject from dataall.modules.datasets_base.db.dataset_models import Dataset @@ -97,7 +97,7 @@ def get_dataset_organization(context, source: Dataset, **kwargs): if not source: return None with context.engine.scoped_session() as session: - return Organization.get_organization_by_uri(session, source.organizationUri) + return OrganizationRepository.get_organization_by_uri(session, source.organizationUri) def get_dataset_environment(context, source: Dataset, **kwargs): diff --git a/backend/dataall/modules/datasets/indexers/dataset_indexer.py b/backend/dataall/modules/datasets/indexers/dataset_indexer.py index b8db59be8..bf5f15abf 100644 --- a/backend/dataall/modules/datasets/indexers/dataset_indexer.py +++ b/backend/dataall/modules/datasets/indexers/dataset_indexer.py @@ -1,6 +1,6 @@ """Indexes Datasets in OpenSearch""" from dataall.core.environment.services.environment_service import EnvironmentService -from dataall.core.organizations.db.organization_repositories import Organization +from dataall.core.organizations.db.organization_repositories import OrganizationRepository from dataall.modules.vote.db.vote_repositories import VoteRepository from dataall.modules.datasets_base.db.dataset_repositories import DatasetRepository from dataall.modules.datasets.db.dataset_location_repositories import DatasetLocationRepository @@ -13,7 +13,7 @@ class DatasetIndexer(BaseIndexer): def upsert(cls, session, dataset_uri: str): dataset = DatasetRepository.get_dataset_by_uri(session, dataset_uri) env = EnvironmentService.get_environment_by_uri(session, dataset.environmentUri) - org = Organization.get_organization_by_uri(session, dataset.organizationUri) + org = OrganizationRepository.get_organization_by_uri(session, dataset.organizationUri) count_tables = DatasetRepository.count_dataset_tables(session, dataset_uri) count_folders = DatasetLocationRepository.count_dataset_locations(session, dataset_uri) diff --git a/backend/dataall/modules/datasets/indexers/location_indexer.py b/backend/dataall/modules/datasets/indexers/location_indexer.py index cc0c25c43..c470be247 100644 --- a/backend/dataall/modules/datasets/indexers/location_indexer.py +++ b/backend/dataall/modules/datasets/indexers/location_indexer.py @@ -1,6 +1,6 @@ """Indexes DatasetStorageLocation in OpenSearch""" from dataall.core.environment.services.environment_service import EnvironmentService -from dataall.core.organizations.db.organization_repositories import Organization +from dataall.core.organizations.db.organization_repositories import OrganizationRepository from dataall.modules.datasets.db.dataset_location_repositories import DatasetLocationRepository from dataall.modules.datasets_base.db.dataset_repositories import DatasetRepository from dataall.modules.datasets.indexers.dataset_indexer import DatasetIndexer @@ -16,7 +16,7 @@ def upsert(cls, session, folder_uri: str): if folder: dataset = DatasetRepository.get_dataset_by_uri(session, folder.datasetUri) env = EnvironmentService.get_environment_by_uri(session, dataset.environmentUri) - org = Organization.get_organization_by_uri(session, dataset.organizationUri) + org = OrganizationRepository.get_organization_by_uri(session, dataset.organizationUri) glossary = BaseIndexer._get_target_glossary_terms(session, folder_uri) BaseIndexer._index( diff --git a/backend/dataall/modules/datasets/indexers/table_indexer.py b/backend/dataall/modules/datasets/indexers/table_indexer.py index 4c5e624ee..f4eeac0cb 100644 --- a/backend/dataall/modules/datasets/indexers/table_indexer.py +++ b/backend/dataall/modules/datasets/indexers/table_indexer.py @@ -1,7 +1,7 @@ """Indexes DatasetTable in OpenSearch""" from dataall.core.environment.services.environment_service import EnvironmentService -from dataall.core.organizations.db.organization_repositories import Organization +from dataall.core.organizations.db.organization_repositories import OrganizationRepository from dataall.modules.datasets.db.dataset_table_repositories import DatasetTableRepository from dataall.modules.datasets_base.db.dataset_repositories import DatasetRepository from dataall.modules.datasets.indexers.dataset_indexer import DatasetIndexer @@ -17,7 +17,7 @@ def upsert(cls, session, table_uri: str): if table: dataset = DatasetRepository.get_dataset_by_uri(session, table.datasetUri) env = EnvironmentService.get_environment_by_uri(session, dataset.environmentUri) - org = Organization.get_organization_by_uri(session, dataset.organizationUri) + org = OrganizationRepository.get_organization_by_uri(session, dataset.organizationUri) glossary = BaseIndexer._get_target_glossary_terms(session, table_uri) tags = table.tags if table.tags else [] diff --git a/backend/dataall/modules/datasets_base/db/dataset_repositories.py b/backend/dataall/modules/datasets_base/db/dataset_repositories.py index 9bbaf2489..ce268d146 100644 --- a/backend/dataall/modules/datasets_base/db/dataset_repositories.py +++ b/backend/dataall/modules/datasets_base/db/dataset_repositories.py @@ -5,7 +5,7 @@ from dataall.core.activity.db.activity_models import Activity from dataall.core.environment.db.environment_models import Environment from dataall.core.environment.services.environment_service import EnvironmentService -from dataall.core.organizations.db.organization_repositories import Organization +from dataall.core.organizations.db.organization_repositories import OrganizationRepository from dataall.base.db import paginate from dataall.base.db.exceptions import ObjectNotFound from dataall.modules.datasets_base.db.enums import ConfidentialityClassification, Language @@ -76,7 +76,7 @@ def count_resources(session, environment, group_uri) -> int: @staticmethod def create_dataset(session, env: Environment, dataset: Dataset): - organization = Organization.get_organization_by_uri( + organization = OrganizationRepository.get_organization_by_uri( session, env.organizationUri ) diff --git a/tests/modules/datasets/test_dataset_permissions.py b/tests/modules/datasets/test_dataset_permissions.py index 4a7e4c15c..e1e7f94fc 100644 --- a/tests/modules/datasets/test_dataset_permissions.py +++ b/tests/modules/datasets/test_dataset_permissions.py @@ -10,7 +10,7 @@ from dataall.modules.datasets_base.services.permissions import DATASET_TABLE_READ from tests.core.permissions.test_permission import * -from dataall.core.organizations.db.organization_repositories import Organization +from dataall.core.organizations.services.organization_service import OrganizationService def test_attach_resource_policy(db, user, group, dataset_fixture): @@ -76,8 +76,7 @@ def test_create_dataset(db, user, group, dataset_fixture, permissions, tenant): permissions=TENANT_ALL, tenant_name='dataall', ) - org_with_perm = Organization.create_organization( - session=session, + org_with_perm = OrganizationService.create_organization( data={ 'label': 'OrgWithPerm', 'SamlGroupName': group.name,