def resolve_recursive_set_members(_, info: GraphQLResolveInfo, set_names: List[str], depth: int = 0, sources: Optional[List[str]] = None, exclude_sets: Optional[List[str]] = None, sql_trace: bool = False): """Resolve an recursiveSetMembers query""" query_resolver = QueryResolver( info.context['request'].app.state.preloader, info.context['request'].app.state.database_handler) if sql_trace: query_resolver.enable_sql_trace() set_names_set = {i.upper() for i in set_names} exclude_sets_set = {i.upper() for i in exclude_sets} if exclude_sets else set() query_resolver.set_query_sources(sources) for set_name in set_names_set: results = query_resolver.members_for_set_per_source( set_name, exclude_sets=exclude_sets_set, depth=depth, recursive=True) for source, members in results.items(): yield dict(rpslPk=set_name, rootSource=source, members=members) if sql_trace: info.context['sql_queries'] = query_resolver.retrieve_sql_trace()
def resolve_as_set_prefixes(_, info: GraphQLResolveInfo, set_names: List[str], sources: Optional[List[str]] = None, ip_version: Optional[int] = None, exclude_sets: Optional[List[str]] = None, sql_trace: bool = False): """Resolve an asSetPrefixes query""" query_resolver = QueryResolver( info.context['request'].app.state.preloader, info.context['request'].app.state.database_handler) if sql_trace: query_resolver.enable_sql_trace() set_names_set = {i.upper() for i in set_names} exclude_sets_set = {i.upper() for i in exclude_sets} if exclude_sets else set() query_resolver.set_query_sources(sources) for set_name in set_names_set: prefixes = list( query_resolver.routes_for_as_set(set_name, ip_version, exclude_sets=exclude_sets_set)) yield dict(rpslPk=set_name, prefixes=prefixes) if sql_trace: info.context['sql_queries'] = query_resolver.retrieve_sql_trace()
def create_resolve_info(schema, request_string, variables=None, return_type=None): exe_context = create_execution_context(schema, request_string, variables) parent_type = get_operation_root_type(schema, exe_context.operation) field_asts = get_field_asts_from_execution_context(exe_context) field_ast = field_asts[0] field_name = field_ast.name.value if return_type is None: field_def = get_field_def(schema, parent_type, field_name) if not field_def: return Undefined return_type = field_def.type # The resolve function's optional third argument is a context value that # is provided to every resolve function within an execution. It is commonly # used to represent an authenticated user, or request-specific caches. return GraphQLResolveInfo( field_name, field_asts, return_type, parent_type, Path(None, 0, None), schema, exe_context.fragments, exe_context.root_value, exe_context.operation, exe_context.variable_values, exe_context.context_value, exe_context.is_awaitable, )
def _create_resolve_info(self, field_name, field_asts, return_type, parent_type): return GraphQLResolveInfo( field_name, field_asts, return_type, parent_type, Path(None, 0, None), schema=self.root_info.schema, fragments=self.root_info.fragments, root_value=self.root_info.root_value, operation=self.root_info.operation, variable_values=self.root_info.variable_values, context=self.root_info.context, is_awaitable=self.root_info.is_awaitable, )
def _rpsl_db_query_to_graphql_out(query: RPSLDatabaseQuery, info: GraphQLResolveInfo): """ Given an RPSL database query, execute it and clean up the output to be suitable to return to GraphQL. Main changes are: - Enum handling - Adding the asn and prefix fields if applicable - Ensuring the right fields are returned as a list of strings or a string """ database_handler = info.context['request'].app.state.database_handler if info.context.get('sql_trace'): if 'sql_queries' not in info.context: info.context['sql_queries'] = [repr(query)] else: info.context['sql_queries'].append(repr(query)) for row in database_handler.execute_query(query, refresh_on_error=True): graphql_result = { snake_to_camel_case(k): v for k, v in row.items() if k != 'parsed_data' } if 'object_text' in row: graphql_result['objectText'] = remove_auth_hashes( row['object_text']) if 'rpki_status' in row: graphql_result['rpkiStatus'] = row['rpki_status'] if row.get('ip_first') is not None and row.get('prefix_length'): graphql_result['prefix'] = row['ip_first'] + '/' + str( row['prefix_length']) if row.get('asn_first') is not None and row.get( 'asn_first') == row.get('asn_last'): graphql_result['asn'] = row['asn_first'] object_type = resolve_rpsl_object_type(row) for key, value in row.get('parsed_data', dict()).items(): if key == 'auth': value = [remove_auth_hashes(v) for v in value] graphql_type = schema.graphql_types[object_type][key] if graphql_type == 'String' and isinstance(value, list): value = '\n'.join(value) graphql_result[snake_to_camel_case(key)] = value yield graphql_result
def resolve_rpsl_objects(_, info: GraphQLResolveInfo, **kwargs): """ Resolve a `rpslObjects` query. This query has a considerable number of parameters, each of which is applied to an RPSL database query. """ low_specificity_kwargs = { 'object_class', 'rpki_status', 'scope_filter_status', 'sources', 'sql_trace' } # A query is sufficiently specific if it has other fields than listed above, # except that rpki_status is sufficient if it is exclusively selecting on # valid or invalid. low_specificity = all([ not (set(kwargs.keys()) - low_specificity_kwargs), kwargs.get('rpki_status', []) not in [[RPKIStatus.valid], [RPKIStatus.invalid]], ]) if low_specificity: raise ValueError('Your query must be more specific.') if kwargs.get('sql_trace'): info.context['sql_trace'] = True query = RPSLDatabaseQuery( column_names=_columns_for_graphql_selection(info), ordered_by_sources=False, enable_ordering=False) if 'record_limit' in kwargs: query.limit(kwargs['record_limit']) if 'rpsl_pk' in kwargs: query.rpsl_pks(kwargs['rpsl_pk']) if 'object_class' in kwargs: query.object_classes(kwargs['object_class']) if 'asn' in kwargs: query.asns_first(kwargs['asn']) if 'text_search' in kwargs: query.text_search(kwargs['text_search']) if 'rpki_status' in kwargs: query.rpki_status(kwargs['rpki_status']) else: query.rpki_status([RPKIStatus.not_found, RPKIStatus.valid]) if 'scope_filter_status' in kwargs: query.scopefilter_status(kwargs['scope_filter_status']) else: query.scopefilter_status([ScopeFilterStatus.in_scope]) all_valid_sources = set(get_setting('sources', {}).keys()) if get_setting('rpki.roa_source'): all_valid_sources.add(RPKI_IRR_PSEUDO_SOURCE) sources_default = set(get_setting('sources_default', [])) if 'sources' in kwargs: query.sources(kwargs['sources']) elif sources_default and sources_default != all_valid_sources: query.sources(list(sources_default)) # All other parameters are generic lookup fields, like `members` for attr, value in kwargs.items(): attr = attr.replace('_', '-') if attr in lookup_fields: query.lookup_attrs_in([attr], value) ip_filters = [ 'ip_exact', 'ip_less_specific', 'ip_more_specific', 'ip_less_specific_one_level', 'ip_any' ] for ip_filter in ip_filters: if ip_filter in kwargs: getattr(query, ip_filter)(IP(kwargs[ip_filter])) return _rpsl_db_query_to_graphql_out(query, info)
async def check_auth(obj: Any, info: GraphQLResolveInfo, **kwargs: Any) -> Any: # type: ignore if not info.context.get("auth", False): await authenticate(info.context["request"]) info.context["auth"] = True return await f(obj, info, **kwargs)