All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.intuit.graphql.authorization.rules.QueryRuleParser Maven / Gradle / Ivy

package com.intuit.graphql.authorization.rules;

import static com.intuit.graphql.authorization.util.GraphQLUtil.getFieldDefinition;
import static com.intuit.graphql.authorization.util.GraphQLUtil.isNotEmpty;

import com.intuit.graphql.authorization.util.GraphQLUtil;
import graphql.language.Document;
import graphql.language.Field;
import graphql.language.OperationDefinition;
import graphql.language.SelectionSet;
import graphql.parser.Parser;
import graphql.schema.GraphQLFieldDefinition;
import graphql.schema.GraphQLFieldsContainer;
import graphql.schema.GraphQLOutputType;
import graphql.schema.GraphQLSchema;
import graphql.schema.GraphQLType;
import graphql.schema.GraphQLTypeUtil;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class QueryRuleParser implements RuleParser {

  private static final String ERR_MSG = "Unknown field '%s'";

  private final GraphQLSchema schema;

  public QueryRuleParser(GraphQLSchema schema) {
    this.schema = Objects.requireNonNull(schema);
  }

  private void preOrder(GraphQLType graphQLOutputType, SelectionSet selectionSet,
      Map> typeToFieldMap) {
    if (graphQLOutputType instanceof GraphQLFieldsContainer && isNotEmpty(selectionSet)) {
      GraphQLFieldsContainer graphQLFieldsContainer = (GraphQLFieldsContainer) graphQLOutputType;
      selectionSet.getSelections()
          .forEach(node -> {
            if (node instanceof Field) {
              Field field = (Field) node;
              final GraphQLFieldDefinition fieldDefinition = getFieldDefinition(graphQLFieldsContainer,
                  field.getName());
              if (fieldDefinition == null) {
                throw new IllegalStateException(String.format(ERR_MSG, field.getName()));
              }
              Set fields = typeToFieldMap
                  .computeIfAbsent(graphQLFieldsContainer, k -> new HashSet<>());
              fields.add(fieldDefinition);
              preOrder(GraphQLTypeUtil.unwrapAll(fieldDefinition.getType()), field.getSelectionSet(), typeToFieldMap);
            }
          });
    }
  }

  @Override
  public Map> parseRule(final String query) {
    Map> typeToFieldMap = new HashMap<>();
    Document document = new Parser().parseDocument(query);
    document.getDefinitions()
        .forEach(definition -> {
          if (definition instanceof OperationDefinition) {
            OperationDefinition operationDefinition = (OperationDefinition) definition;
            GraphQLOutputType operationType = GraphQLUtil.getRootTypeFromOperation(operationDefinition, schema);
            preOrder(operationType, operationDefinition.getSelectionSet(), typeToFieldMap);
          }
        });
    return typeToFieldMap;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy