def find_enum(
            import_items: ImportEnumItems) -> Tuple[Enum, List[EnumItem]]:
        enum_id = import_items.enumId
        name = import_items.name
        if is_blank(enum_id) and is_blank(name):
            raise_400(
                'At least one of enumeration id and name must be provided.')

        enumeration = None
        if is_not_blank(enum_id):
            # both provided, find by id
            enumeration = enum_service.find_by_id(enum_id)
        elif is_not_blank(name):
            enumeration = enum_service.find_by_name(
                name, principal_service.get_tenant_id())

        if enumeration is not None:
            # found
            if enumeration.tenantId != principal_service.get_tenant_id():
                raise_404(f'Enumeration[id={enum_id}, name={name}] not found.')
        elif is_not_blank(name):
            # not found, but name is given, create one
            enumeration = Enum(enumId=enum_id,
                               name=name,
                               tenantId=principal_service.get_tenant_id(),
                               items=[])
            enum_service.create(enumeration)
        else:
            raise_404(f'Enumeration[id={enum_id}, name={name}] not found.')

        return enumeration, import_items.items
    def action(connected_space: ConnectedSpace) -> ConnectedSpace:
        space_id = connected_space.spaceId
        if is_blank(space_id):
            raise_400('Space id is required.')
        space_service = get_space_service(connected_space_service)
        space: Optional[Space] = space_service.find_by_id(space_id)
        if space is None:
            raise_400('Incorrect space id.')
        if space.tenantId != principal_service.get_tenant_id():
            raise_403()

        connected_space.userId = principal_service.get_user_id()
        connected_space.tenantId = principal_service.get_tenant_id()
        connected_space.lastVisitTime = get_current_time_in_seconds()
        if connected_space_service.is_storable_id_faked(
                connected_space.connectId):
            connected_space_service.redress_storable_id(connected_space)
            # noinspection PyTypeChecker
            connected_space: ConnectedSpace = connected_space_service.create(
                connected_space)
        else:
            # noinspection PyTypeChecker
            existing_connected_space: Optional[ConnectedSpace] = \
             connected_space_service.find_by_id(connected_space.connectId)
            if existing_connected_space is not None:
                if existing_connected_space.tenantId != connected_space.tenantId:
                    raise_403()
                if existing_connected_space.userId != connected_space.userId:
                    raise_403()

            # noinspection PyTypeChecker
            connected_space: ConnectedSpace = connected_space_service.update(
                connected_space)
        return connected_space
async def load_achievement_by_id(
    achievement_id: Optional[AchievementId],
    principal_service: PrincipalService = Depends(get_console_principal)
) -> Achievement:
    if is_blank(achievement_id):
        raise_400('Achievement id is required.')

    achievement_service = get_achievement_service(principal_service)

    # noinspection DuplicatedCode
    def action() -> Achievement:
        # noinspection PyTypeChecker
        achievement: Achievement = achievement_service.find_by_id(
            achievement_id)
        if achievement is None:
            raise_404()
        # user id must match current principal's
        if achievement.userId != principal_service.get_user_id():
            raise_404()
        # tenant id must match current principal's
        if achievement.tenantId != principal_service.get_tenant_id():
            raise_404()
        return achievement

    return trans_readonly(achievement_service, action)
예제 #4
0
    def action() -> ConnectedSpaceWithSubjects:
        space_service = get_space_service(connected_space_service)
        space: Optional[Space] = space_service.find_by_id(space_id)
        if space is None:
            raise_400('Incorrect space id.')
        if space.tenantId != principal_service.get_tenant_id():
            raise_403()

        template_connected_spaces = find_template_connected_spaces_by_ids(
            connected_space_service, template_ids, space_id, space.tenantId)

        connected_space = ConnectedSpace(spaceId=space_id,
                                         name=name,
                                         isTemplate=False)
        connected_space_service.redress_storable_id(connected_space)
        connected_space.userId = principal_service.get_user_id()
        connected_space.tenantId = principal_service.get_tenant_id()
        connected_space.lastVisitTime = get_current_time_in_seconds()
        # noinspection PyTypeChecker
        connected_space: ConnectedSpace = connected_space_service.create(
            connected_space)

        subjects_with_reports = ArrayHelper(template_connected_spaces) \
         .map(lambda x: copy_to_connected_space(x, connected_space, connected_space_service)) \
         .flatten().to_list()

        connected_space_with_subjects = ConnectedSpaceWithSubjects(
            **connected_space.dict())
        connected_space_with_subjects.subjects = subjects_with_reports
        return connected_space_with_subjects
예제 #5
0
async def delete_connected_space_by_id(
    connect_id: Optional[ConnectedSpaceId],
    principal_service: PrincipalService = Depends(get_console_principal)
) -> None:
    if is_blank(connect_id):
        raise_400('Connected space id is required.')

    connected_space_service = get_connected_space_service(principal_service)

    # noinspection DuplicatedCode
    def action() -> None:
        # noinspection PyTypeChecker
        existing_connected_space: Optional[
            ConnectedSpace] = connected_space_service.find_by_id(connect_id)
        if existing_connected_space is None:
            raise_404()
        if existing_connected_space.tenantId != principal_service.get_tenant_id(
        ):
            raise_403()
        if not principal_service.is_tenant_admin(
        ) and existing_connected_space.userId != principal_service.get_user_id(
        ):
            raise_403()
        connected_space_service.delete(connect_id)
        subject_service: SubjectService = get_subject_service(
            connected_space_service)
        subject_service.delete_by_connect_id(connect_id)
        report_service: ReportService = get_report_service(
            connected_space_service)
        report_service.delete_by_connect_id(connect_id)

    trans(connected_space_service, action)
async def fetch_topic_data_count(
    topic_id: Optional[TopicId] = None,
    tenant_id: Optional[TenantId] = None,
    criteria: Optional[ParameterJoint] = None,
    principal_service: PrincipalService = Depends(get_any_admin_principal)
) -> List[str]:
    if is_blank(topic_id):
        raise_400('Topic id is required.')
    tenant_id = validate_tenant_id(tenant_id, principal_service)
    principal_service = fake_to_tenant(principal_service, tenant_id)

    schema = get_topic_service(principal_service).find_schema_by_id(
        topic_id, tenant_id)
    storage = ask_topic_storage(schema, principal_service)
    service = ask_topic_data_service(schema, storage, principal_service)

    if criteria is None:
        rows = service.find_distinct_values(None,
                                            [TopicDataColumnNames.ID.value],
                                            False)
    else:
        parsed_criteria = parse_condition_for_storage(criteria, [schema],
                                                      principal_service, False)
        empty_variables = PipelineVariables(None, None, None)
        rows = service.find_distinct_values(
            [parsed_criteria.run(empty_variables, principal_service)],
            [TopicDataColumnNames.ID.value], False)

    return ArrayHelper(rows).map(
        lambda x: str(x.get(TopicDataColumnNames.ID.value))).to_list()
 def to_report_filter(condition: ParameterCondition) -> ParameterCondition:
     if isinstance(condition, ParameterExpression):
         return to_report_expression(condition)
     elif isinstance(condition, ParameterJoint):
         return to_report_joint(condition)
     else:
         raise_400(f'Cannot determine given condition[{condition.dict()}].')
async def delete_catalog_by_id_by_super_admin(
    catalog_id: Optional[CatalogId] = None,
    principal_service: PrincipalService = Depends(get_any_admin_principal)
) -> Catalog:
    if is_blank(catalog_id):
        raise_400('Catalog id is required.')

    catalog_service = get_catalog_service(principal_service)

    def action() -> Catalog:
        if principal_service.is_super_admin():
            # noinspection PyTypeChecker
            catalog: Optional[Catalog] = catalog_service.delete(catalog_id)
        else:
            existing_catalog = catalog_service.find_by_id(catalog_id)
            if existing_catalog is None:
                catalog = existing_catalog
            elif existing_catalog.tenantId != principal_service.get_tenant_id(
            ):
                catalog = None
            else:
                catalog = catalog_service.delete(catalog_id)
        if catalog is None:
            raise_404()
        return catalog

    return trans(catalog_service, action)
    def sync_on_update(self, user_group_id: UserGroupId,
                       indicator_ids: Optional[List[IndicatorId]],
                       removed_indicator_ids: Optional[List[IndicatorId]],
                       tenant_id: TenantId,
                       user_group_service: UserGroupService):
        if removed_indicator_ids is None:
            return

        given_count = len(removed_indicator_ids)
        if given_count == 0:
            # do nothing
            return

        indicator_service = get_indicator_service(user_group_service)
        holders = indicator_service.find_by_ids(removed_indicator_ids,
                                                tenant_id)
        found_count = len(holders)
        if given_count != found_count:
            raise_400('Indicator ids do not match.')

        ArrayHelper(holders) \
         .filter(lambda x: self.has_user_group_id(x, user_group_id)) \
         .map(lambda x: self.remove_user_group_id(x, user_group_id)) \
         .each(lambda x: self.update_indicator(indicator_service, x))

        self.sync_on_create(user_group_id, indicator_ids, tenant_id,
                            user_group_service)
예제 #10
0
async def update_dashboard_name_by_id(
		dashboard_id: Optional[DashboardId], name: Optional[str],
		principal_service: PrincipalService = Depends(get_console_principal)
) -> None:
	"""
	rename dashboard will not increase the optimistic lock version
	"""
	if is_blank(dashboard_id):
		raise_400('Dashboard id is required.')

	dashboard_service = get_dashboard_service(principal_service)

	# noinspection DuplicatedCode
	def action() -> None:
		existing_one = dashboard_service.find_tenant_and_user(dashboard_id)
		if existing_one is None:
			raise_404()
		existing_tenant_id, existing_user_id = existing_one
		if existing_tenant_id != principal_service.get_tenant_id():
			raise_403()
		elif existing_user_id != principal_service.get_user_id():
			raise_403()
		# noinspection PyTypeChecker
		dashboard_service.update_name(
			dashboard_id, name, principal_service.get_user_id(), principal_service.get_tenant_id())

	trans(dashboard_service, action)
예제 #11
0
def validate_user(a_tuple: UserBasedTuple, user_service: UserService,
                  principal_service: PrincipalService) -> None:
    if not principal_service.is_admin():
        raise_403()

    if is_blank(a_tuple.userId):
        if principal_service.is_super_admin():
            raise_400('User id is required.')
        elif principal_service.is_tenant_admin():
            a_tuple.userId = principal_service.get_user_id()
        else:
            raise_403()
    else:
        if a_tuple.userId == principal_service.get_user_id():
            if principal_service.is_super_admin():
                raise_400(f'Incorrect user id[{a_tuple.userId}].')
        else:
            user: Optional[User] = user_service.find_by_id(a_tuple.userId)
            if user is None:
                raise_400('User id is required.')
            if principal_service.is_super_admin():
                if user.tenantId == principal_service.get_tenant_id():
                    raise_400(f'Incorrect user id[{a_tuple.userId}].')
            elif principal_service.is_tenant_admin():
                if user.tenantId != principal_service.get_tenant_id():
                    raise_400(f'Incorrect user id[{a_tuple.userId}].')
예제 #12
0
def validate_reports(
		dashboard: Dashboard, dashboard_service: DashboardService, principal_service: PrincipalService) -> None:
	reports = dashboard.reports
	if reports is None:
		dashboard.reports = []
		return
	if len(reports) == 0:
		return

	report_ids = ArrayHelper(reports).map(lambda x: x.reportId).distinct().to_list()
	if len(report_ids) == 0:
		dashboard.reports = []
		return

	report_service = get_report_service(dashboard_service)

	for report_id in report_ids:
		existing_one = report_service.find_tenant_and_user(report_id)
		if existing_one is None:
			raise_400('Report ids do not match.')
		existing_tenant_id, existing_user_id = existing_one
		if existing_tenant_id != principal_service.get_tenant_id():
			raise_403()
		if existing_user_id != principal_service.get_user_id():
			raise_403()
async def load_enum_by_id(
    enum_id: Optional[EnumId] = None,
    principal_service: PrincipalService = Depends(get_console_principal)
) -> Enum:
    if is_blank(enum_id):
        raise_400('Enumeration id is required.')

    enum_service = get_enum_service(principal_service)

    def action() -> Enum:
        # noinspection PyTypeChecker
        an_enum: Enum = enum_service.find_by_id(enum_id)
        if an_enum is None:
            raise_404()
        # tenant id must match current principal's
        if an_enum.tenantId != principal_service.get_tenant_id():
            raise_404()
        enum_item_service = get_enum_item_service(enum_service)
        enum_list: List[EnumItem] = enum_item_service.find_by_enum_id(enum_id)
        if ArrayHelper(enum_list).some(
                lambda x: x.tenantId != principal_service.get_tenant_id()):
            raise_500(
                None,
                f'Items of enumeration[enumId={an_enum.enumId}] has incorrect data, '
                'check and correct it at meta storage manually.')
        if enum_list is None:
            an_enum.items = []
        else:
            an_enum.items = enum_list
        return an_enum

    return trans_readonly(enum_service, action)
async def delete_enum_by_id_by_super_admin(
    enum_id: Optional[EnumId] = None,
    principal_service: PrincipalService = Depends(get_super_admin_principal)
) -> Enum:
    if not ask_tuple_delete_enabled():
        raise_404('Not Found')

    if is_blank(enum_id):
        raise_400('Enumeration id is required.')

    enum_service = get_enum_service(principal_service)

    def action() -> Enum:
        # noinspection PyTypeChecker
        an_enum: Enum = enum_service.delete(enum_id)
        if an_enum is None:
            raise_404()
        enum_item_service = get_enum_item_service(enum_service)
        enum_items = enum_item_service.find_by_enum_id(an_enum.enumId)
        if enum_items is None:
            an_enum.items = []
        else:
            an_enum.items = enum_items
        enum_item_service.delete_by_enum_id(an_enum.enumId)
        return an_enum

    return trans(enum_service, action)
def prepare_and_validate_request(
		request: MixImportDataRequest,
		user_service: UserService, principal_service: PrincipalService) -> None:
	tenant_id = validate_tenant_id(request, user_service, principal_service)
	clear_data_source_id(request.topics)
	clear_user_group_ids(request.spaces)

	def set_user_id_to_report(report: Report, user_id: UserId) -> None:
		report.userId = user_id

	def set_user_id_to_subject(subject: SubjectWithReports, user_id: UserId) -> None:
		subject.userId = user_id
		ArrayHelper(subject.reports) \
			.flatten() \
			.filter(lambda x: x is not None) \
			.each(lambda x: set_user_id_to_report(x, user_id))

	def set_user_id_to_connected_space(connected_space: ConnectedSpaceWithSubjects, user_id: UserId) -> None:
		connected_space.userId = user_id
		ArrayHelper(connected_space.subjects) \
			.flatten() \
			.filter(lambda x: x is not None) \
			.each(lambda x: set_user_id_to_subject(x, user_id))

	if principal_service.is_super_admin():
		# to find a tenant admin
		tenant_admin: Optional[User] = user_service.find_admin(tenant_id)
		if tenant_admin is None:
			raise_400(f'Admin user on tenant[{tenant_id}] to receive imported data is not found.')
	elif principal_service.is_tenant_admin():
		ArrayHelper(request.connectedSpaces).each(
			lambda x: set_user_id_to_connected_space(x, principal_service.get_user_id()))
	else:
		raise_403()
async def patch_topic_data(
    topic_name: Optional[str] = None,
    patch_type: Optional[PipelineTriggerType] = PipelineTriggerType.MERGE,
    tenant_id: Optional[TenantId] = None,
    data=Body(...),
    principal_service: PrincipalService = Depends(get_any_admin_principal)
) -> None:
    """
	data patch will not trigger any pipeline
	"""
    if is_blank(topic_name):
        raise_400('Topic name is required.')
    if patch_type is None:
        patch_type = PipelineTriggerType.MERGE
    if patch_type == PipelineTriggerType.INSERT_OR_MERGE:
        raise_400('Patch type can be one of insert/merge/delete.')
    tenant_id = validate_tenant_id(tenant_id, principal_service)
    principal_service = fake_to_tenant(principal_service, tenant_id)

    schema = get_topic_schema(topic_name, tenant_id, principal_service)
    storage = ask_topic_storage(schema, principal_service)
    service = ask_topic_data_service(schema, storage, principal_service)
    if patch_type == PipelineTriggerType.INSERT:
        service.trigger_by_insert(data)
    elif patch_type == PipelineTriggerType.MERGE:
        service.trigger_by_merge(data)
    elif patch_type == PipelineTriggerType.DELETE:
        service.trigger_by_delete(data)
    else:
        raise DataKernelException(
            f'Patch type [{patch_type}] is not supported.')
    def to_report_indicator(
            indicator: SubjectDatasetCriteriaIndicator) -> ReportIndicator:
        name = indicator.name
        dataset_column = subject_column_map.get(name)
        if dataset_column is None:
            raise_400(f'Cannot find column[name={name}] from subject.')

        arithmetic = ReportIndicatorArithmetic.NONE
        if indicator.arithmetic == SubjectDatasetCriteriaIndicatorArithmetic.COUNT:
            arithmetic = ReportIndicatorArithmetic.COUNT
        elif indicator.arithmetic == SubjectDatasetCriteriaIndicatorArithmetic.SUMMARY:
            arithmetic = ReportIndicatorArithmetic.SUMMARY
        elif indicator.arithmetic == SubjectDatasetCriteriaIndicatorArithmetic.AVERAGE:
            arithmetic = ReportIndicatorArithmetic.AVERAGE
        elif indicator.arithmetic == SubjectDatasetCriteriaIndicatorArithmetic.MAXIMUM:
            arithmetic = ReportIndicatorArithmetic.MAXIMUM
        elif indicator.arithmetic == SubjectDatasetCriteriaIndicatorArithmetic.MINIMUM:
            arithmetic = ReportIndicatorArithmetic.MINIMUM
        elif indicator.arithmetic == SubjectDatasetCriteriaIndicatorArithmetic.NONE or indicator.arithmetic is None:
            arithmetic = ReportIndicatorArithmetic.NONE
        else:
            raise_400(
                f'Indicator arithmetic[{indicator.arithmetic}] is not supported.'
            )

        return ReportIndicator(columnId=dataset_column.columnId,
                               arithmetic=arithmetic,
                               name=indicator.alias)
예제 #18
0
    def action(user: User) -> User:
        # crypt password
        pwd = user.password
        if is_not_blank(pwd):
            user.password = crypt_password(pwd)

        if user.isActive is None:
            user.isActive = True

        if user_service.is_storable_id_faked(user.userId):
            if principal_service.is_super_admin() and check_user_group:
                if user.groupIds is not None and len(user.groupIds) != 0:
                    # for super admin create user, there is no user group allowed
                    raise_400(
                        'No user group allowed for creating user by super admin.'
                    )
            user_service.redress_storable_id(user)
            user_group_ids = ArrayHelper(user.groupIds).distinct().to_list()
            user.groupIds = user_group_ids
            # noinspection PyTypeChecker
            user: User = user_service.create(user)
            # synchronize user to user groups
            sync_user_to_groups(user_service, user.userId, user_group_ids,
                                user.tenantId)
        else:
            # noinspection PyTypeChecker
            existing_user: Optional[User] = user_service.find_by_id(
                user.userId)
            if existing_user is not None:
                if existing_user.tenantId != user.tenantId:
                    raise_403()
                elif is_blank(user.password):
                    # keep original password
                    user.password = existing_user.password

            if principal_service.is_super_admin() and check_user_group:
                # for super admin update user, simply keep user group
                user.groupIds = existing_user.groupIds
            else:
                user_group_ids = ArrayHelper(
                    user.groupIds).distinct().to_list()
                user.groupIds = user_group_ids
            user_group_ids = user.groupIds
            # noinspection PyTypeChecker
            user: User = user_service.update(user)

            if principal_service.is_tenant_admin():
                # remove user from user groups, in case user groups are removed
                removed_user_group_ids = ArrayHelper(
                    existing_user.groupIds).difference(
                        user_group_ids).to_list()
                remove_user_from_groups(user_service, user.userId,
                                        removed_user_group_ids, user.tenantId)
                # synchronize user to user groups
                sync_user_to_groups(user_service, user.userId, user_group_ids,
                                    user.tenantId)

        # remove password
        clear_pwd(user)
        return user
예제 #19
0
async def update_pipeline_enabled_by_id(
    pipeline_id: Optional[PipelineId],
    enabled: Optional[bool],
    principal_service: PrincipalService = Depends(get_admin_principal)
) -> None:
    """
	enable/disable pipeline will not increase the optimistic lock version
	"""
    if is_blank(pipeline_id):
        raise_400('Pipeline id is required.')
    if enabled is None:
        raise_400('Enabled is required.')

    pipeline_service = get_pipeline_service(principal_service)

    def action() -> None:
        existing_tenant_id: Optional[
            TenantId] = pipeline_service.find_tenant_id(pipeline_id)
        if existing_tenant_id is None:
            raise_404()
        elif existing_tenant_id != principal_service.get_tenant_id():
            raise_403()
        # noinspection PyTypeChecker
        pipeline: Pipeline = pipeline_service.update_enablement(
            pipeline_id, enabled, principal_service.get_tenant_id())
        post_update_pipeline_enablement(pipeline, pipeline_service)

    trans(pipeline_service, action)
예제 #20
0
async def delete_user_by_id_by_super_admin(
    user_id: Optional[UserId] = None,
    principal_service: PrincipalService = Depends(get_super_admin_principal)
) -> User:
    if not ask_tuple_delete_enabled():
        raise_404('Not Found')

    if is_blank(user_id):
        raise_400('User id is required.')

    user_service = get_user_service(principal_service)

    def action() -> User:
        # noinspection PyTypeChecker
        user: User = user_service.delete(user_id)
        if user is None:
            raise_404()
        user_group_ids = user.groupIds
        if user_group_ids is not None and len(user_group_ids) != 0:
            user_group_ids = ArrayHelper(user_group_ids).filter(
                lambda x: is_not_blank(x)).to_list()
            remove_user_from_groups(user_service, user.userId, user_group_ids,
                                    user.tenantId)
        return user

    return trans(user_service, action)
async def init_tenant(
    tenant_id: Optional[TenantId],
    principal_service: PrincipalService = Depends(get_any_admin_principal)
) -> None:
    if is_blank(tenant_id):
        if principal_service.is_super_admin():
            raise_400('Tenant id is required.')
        elif principal_service.is_tenant_admin():
            tenant_id = principal_service.get_tenant_id()
    else:
        if principal_service.get_tenant_id(
        ) != tenant_id and principal_service.is_tenant_admin():
            raise_400(f'Tenant[{tenant_id}] does not match principal.')
        elif principal_service.is_super_admin():
            tenant: Optional[Tenant] = get_tenant_service(
                principal_service).find_by_id(tenant_id)
            if tenant is None:
                raise_404(f'Tenant[id={tenant_id}] not found.')

    meta_tenant_service = get_meta_tenant_service(principal_service)

    def action() -> None:
        topics = ask_pipeline_monitor_topics()
        create_topics_and_pipelines(
            topics, lambda source_topics: ask_pipeline_monitor_pipelines(
                source_topics), tenant_id, meta_tenant_service,
            principal_service)
        topics = ask_dqc_topics()
        create_topics_and_pipelines(
            topics, lambda source_topics: ask_dqc_pipelines(source_topics),
            tenant_id, meta_tenant_service, principal_service)

    trans(meta_tenant_service, action)
예제 #22
0
async def load_user_by_id(
    user_id: Optional[UserId] = None,
    principal_service: PrincipalService = Depends(get_any_principal)
) -> User:
    if is_blank(user_id):
        raise_400('User id is required.')
    if not principal_service.is_admin():
        # console user cannot visit other users
        if user_id != principal_service.get_user_id():
            raise_403()

    user_service = get_user_service(principal_service)

    def action() -> User:
        # noinspection PyTypeChecker
        user: User = user_service.find_by_id(user_id)
        if user is None:
            raise_404()
        # check tenant id
        if not principal_service.is_super_admin():
            # tenant id must match current principal's, except current is super admin
            if user.tenantId != principal_service.get_tenant_id():
                raise_404()
        # remove password
        clear_pwd(user)
        return user

    return trans_readonly(user_service, action)
예제 #23
0
async def update_connected_space_name_by_id(
    connect_id: Optional[ConnectedSpaceId],
    name: Optional[str],
    principal_service: PrincipalService = Depends(get_console_principal)
) -> None:
    """
	rename connected space will not increase the optimistic lock version
	"""
    if is_blank(connect_id):
        raise_400('Connected space id is required.')

    connected_space_service = get_connected_space_service(principal_service)

    # noinspection DuplicatedCode
    def action() -> None:
        existing_one = connected_space_service.find_tenant_and_user(connect_id)
        if existing_one is None:
            raise_404()
        existing_tenant_id, existing_user_id = existing_one
        if existing_tenant_id != principal_service.get_tenant_id():
            raise_403()
        elif existing_user_id != principal_service.get_user_id():
            raise_403()
        # noinspection PyTypeChecker
        connected_space_service.update_name(connect_id, name,
                                            principal_service.get_user_id(),
                                            principal_service.get_tenant_id())

    trans(connected_space_service, action)
예제 #24
0
async def delete_subject_by_id(
    subject_id: Optional[SubjectId],
    principal_service: PrincipalService = Depends(get_console_principal)
) -> None:
    if is_blank(subject_id):
        raise_400('Subject id is required.')

    subject_service = get_subject_service(principal_service)

    # noinspection DuplicatedCode
    def action() -> None:
        # noinspection PyTypeChecker
        existing_subject: Optional[Subject] = subject_service.find_by_id(
            subject_id)
        if existing_subject is None:
            raise_404()
        if existing_subject.tenantId != principal_service.get_tenant_id():
            raise_403()
        if not principal_service.is_tenant_admin(
        ) and existing_subject.userId != principal_service.get_user_id():
            raise_403()
        subject_service.delete(subject_id)
        report_service: ReportService = get_report_service(subject_service)
        report_service.delete_by_subject_id(subject_id)

    trans(subject_service, action)
예제 #25
0
def run_topics_rules(
    topic_name: Optional[str] = None,
    frequency: Optional[MonitorRuleStatisticalInterval] = None,
    process_date: Optional[str] = None,
    tenant_id: Optional[TenantId] = None,
    principal_service: PrincipalService = Depends(get_any_admin_principal)
) -> None:
    principal_service = ask_principal_service(principal_service, tenant_id)

    if is_not_blank(topic_name):
        schema = get_topic_service(principal_service).find_schema_by_name(
            topic_name, principal_service.get_tenant_id())
        if schema is None:
            raise_404(f'Topic[name={topic_name}] not found.')
        topic_id = schema.get_topic().topicId
    else:
        topic_id = None

    if is_not_blank(process_date):
        parsed, parsed_date = is_date(process_date, ask_all_date_formats())
        if not parsed:
            raise_400(f'Given process date[{process_date}] cannot be parsed.')
        process_date = parsed_date
    else:
        process_date = get_current_time_in_seconds()
    process_date = truncate_time(process_date)
    now = truncate_time(get_current_time_in_seconds())
    if process_date.year > now.year:
        raise_400(f'Given process date[{process_date}] cannot be in future.')
    if process_date.year == now.year and process_date.month > now.month:
        raise_400(f'Given process date[{process_date}] cannot be in future.')
    if process_date.year == now.year and process_date.month == now.month and process_date.day > now.day:
        raise_400(f'Given process date[{process_date}] cannot be in future.')

    if frequency == MonitorRuleStatisticalInterval.MONTHLY:
        # given process date is in this month, run previous month
        # otherwise, run the given month
        if process_date.year == now.year and process_date.month == now.month:
            process_date = to_previous_month(process_date)
        SelfCleaningMonitorRulesRunner(principal_service) \
         .run(process_date, topic_id, MonitorRuleStatisticalInterval.MONTHLY)
    elif frequency == MonitorRuleStatisticalInterval.WEEKLY:
        # given process date is in this week, run previous week
        # otherwise, run the given week
        if process_date.year == now.year and int(
                process_date.strftime('%U')) == int(now.strftime('%U')):
            process_date = to_previous_week(process_date)
        SelfCleaningMonitorRulesRunner(principal_service) \
         .run(process_date, topic_id, MonitorRuleStatisticalInterval.WEEKLY)
    elif frequency == MonitorRuleStatisticalInterval.DAILY:
        # given process date is today, run yesterday
        # otherwise, run the given day
        if process_date.year == now.year and process_date.month == now.month and process_date.day == now.day:
            process_date = to_yesterday(process_date)
        SelfCleaningMonitorRulesRunner(principal_service) \
         .run(process_date, topic_id, MonitorRuleStatisticalInterval.DAILY)
    else:
        raise_400(f'Given frequency[{frequency}] is not supported.')
 def translate_topic_factor(
         param: TopicFactorParameter) -> TopicFactorParameter:
     factor_id = param.factorId  # alias name on subject
     dataset_column = subject_column_map.get(factor_id)
     if dataset_column is None:
         raise_400(f'Cannot find column[name={factor_id}] from subject.')
     # topicId is not need here since subject will be build as a sub query
     return TopicFactorParameter(kind=ParameterKind.TOPIC,
                                 factorId=dataset_column.columnId)
예제 #27
0
def validate_topics(space_service: SpaceService, topic_ids: List[TopicId], tenant_id: TenantId) -> None:
	if topic_ids is None:
		return
	given_count = len(topic_ids)
	if given_count == 0:
		return
	topic_service = get_topic_service(space_service)
	existing_topic_ids = topic_service.find_ids_by_ids(topic_ids, tenant_id)
	if given_count != len(existing_topic_ids):
		raise_400('Topic ids do not match')
 def translate_parameter(parameter: Parameter) -> Parameter:
     if isinstance(parameter, TopicFactorParameter):
         return translate_topic_factor(parameter)
     elif isinstance(parameter, ConstantParameter):
         return translate_constant(parameter)
     elif isinstance(parameter, ComputedParameter):
         return translate_computed(parameter)
     else:
         raise_400(
             f'Cannot determine given expression[{parameter.dict()}].')
async def fetch_inspection_data(
		inspection_id: Optional[InspectionId],
		principal_service: PrincipalService = Depends(get_console_principal)) -> DataResultSet:
	if is_blank(inspection_id):
		raise_400('Inspection id is required.')

	inspection_service = get_inspection_service(principal_service)
	inspection = trans_readonly(
		inspection_service, lambda: do_load_inspection_by_id(inspection_id, inspection_service, principal_service))

	return get_inspection_data_service(inspection, principal_service).find_data()
def validate_tenant_id(tenant_id: Optional[TenantId],
                       principal_service: PrincipalService) -> TenantId:
    if principal_service.is_tenant_admin():
        if is_not_blank(
                tenant_id) and tenant_id != principal_service.get_tenant_id():
            raise_400('Tenant id is incorrect.')
        return principal_service.get_tenant_id()
    elif principal_service.is_super_admin():
        if is_blank(tenant_id):
            raise_400('Tenant id is required.')
        return tenant_id