-
Notifications
You must be signed in to change notification settings - Fork 822
add support for query validation #1357
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
aa11681
add depth limit validator
aryaniyaps fc2967e
remove unused imports
aryaniyaps 4259502
update docs
aryaniyaps 5977b16
fix typo
aryaniyaps a784ef1
add disable introspection
aryaniyaps d7b4747
add depth limit validator tests
aryaniyaps 7be4bd6
update docs
aryaniyaps ac5dd90
fix typo in docs
aryaniyaps c680719
mention how to implement custom validators
aryaniyaps ec982ac
update docs typo
aryaniyaps 4e32dac
add tests and docs for disable introspection rule
aryaniyaps b4be4a6
add notice to failing tests
aryaniyaps 467b1f8
add workflow: tests
aryaniyaps c0ddbbf
update workflow matrix
aryaniyaps 8ae4369
remove build matrix wherever not needed
aryaniyaps 0e4c14b
update workflow: tests
aryaniyaps 7d890bf
Update graphene/validation/disable_introspection.py
syrusakbary 946c2a3
Update schema.py
aryaniyaps 18cd345
Update test_schema.py
aryaniyaps ea4e6d6
Update schema.py
aryaniyaps 57a4394
Update depth_limit.py
aryaniyaps 98980b5
Update depth_limit.py
aryaniyaps 74a6565
Update depth_limit.py
aryaniyaps File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
name: 📄 Tests | ||
on: | ||
push: | ||
branches: | ||
- master | ||
- '*.x' | ||
paths-ignore: | ||
- 'docs/**' | ||
- '*.md' | ||
- '*.rst' | ||
pull_request: | ||
branches: | ||
- master | ||
- '*.x' | ||
paths-ignore: | ||
- 'docs/**' | ||
- '*.md' | ||
- '*.rst' | ||
jobs: | ||
tests: | ||
# runs the test suite | ||
name: ${{ matrix.name }} | ||
runs-on: ${{ matrix.os }} | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
include: | ||
- {name: '3.8', python: '3.8', os: ubuntu-latest, tox: py38} | ||
- {name: '3.7', python: '3.7', os: ubuntu-latest, tox: py37} | ||
- {name: '3.6', python: '3.6', os: ubuntu-latest, tox: py36} | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: actions/setup-python@v2 | ||
with: | ||
python-version: ${{ matrix.python }} | ||
|
||
- name: update pip | ||
run: | | ||
pip install -U wheel | ||
pip install -U setuptools | ||
python -m pip install -U pip | ||
|
||
- name: get pip cache dir | ||
id: pip-cache | ||
run: echo "::set-output name=dir::$(pip cache dir)" | ||
|
||
- name: cache pip dependencies | ||
uses: actions/cache@v2 | ||
with: | ||
path: ${{ steps.pip-cache.outputs.dir }} | ||
key: pip|${{ runner.os }}|${{ matrix.python }}|${{ hashFiles('setup.py') }} | ||
|
||
- run: pip install tox | ||
- run: tox -e ${{ matrix.tox }} | ||
|
||
coveralls_finish: | ||
# check coverage increase/decrease | ||
needs: tests | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Coveralls Finished | ||
uses: AndreMiras/coveralls-python-action@develop | ||
|
||
deploy: | ||
# builds and publishes to PyPi | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Set up Python | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: '3.7' | ||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
pip install build | ||
- name: Build package | ||
run: python -m build | ||
- name: Publish package | ||
uses: pypa/gh-action-pypi-publish@release/v1 | ||
with: | ||
user: __token__ | ||
password: ${{ secrets.PYPI_API_TOKEN }} |
File renamed without changes.
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,3 +10,4 @@ Execution | |
dataloader | ||
fileuploading | ||
subscriptions | ||
queryvalidation |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
Query Validation | ||
========== | ||
GraphQL uses query validators to check if Query AST is valid and can be executed. Every GraphQL server implements | ||
standard query validators. For example, there is an validator that tests if queried field exists on queried type, that | ||
makes query fail with "Cannot query field on type" error if it doesn't. | ||
|
||
To help with common use cases, graphene provides a few validation rules out of the box. | ||
|
||
|
||
Depth limit Validator | ||
----------------- | ||
The depth limit validator helps to prevent execution of malicious | ||
queries. It takes in the following arguments. | ||
|
||
- ``max_depth`` is the maximum allowed depth for any operation in a GraphQL document. | ||
- ``ignore`` Stops recursive depth checking based on a field name. Either a string or regexp to match the name, or a function that returns a boolean | ||
- ``callback`` Called each time validation runs. Receives an Object which is a map of the depths for each operation. | ||
|
||
Usage | ||
------- | ||
|
||
Here is how you would implement depth-limiting on your schema. | ||
|
||
.. code:: python | ||
from graphql import validate, parse | ||
from graphene import ObjectType, Schema, String | ||
from graphene.validation import depth_limit_validator | ||
|
||
|
||
class MyQuery(ObjectType): | ||
name = String(required=True) | ||
|
||
|
||
schema = Schema(query=MyQuery) | ||
|
||
# queries which have a depth more than 20 | ||
# will not be executed. | ||
|
||
validation_errors = validate( | ||
schema=schema, | ||
document_ast=parse('THE QUERY'), | ||
rules=( | ||
depth_limit_validator( | ||
max_depth=20 | ||
), | ||
) | ||
) | ||
|
||
|
||
Disable Introspection | ||
--------------------- | ||
the disable introspection validation rule ensures that your schema cannot be introspected. | ||
This is a useful security measure in production environments. | ||
|
||
Usage | ||
------- | ||
|
||
Here is how you would disable introspection for your schema. | ||
|
||
.. code:: python | ||
from graphql import validate, parse | ||
from graphene import ObjectType, Schema, String | ||
from graphene.validation import DisableIntrospection | ||
|
||
|
||
class MyQuery(ObjectType): | ||
name = String(required=True) | ||
|
||
|
||
schema = Schema(query=MyQuery) | ||
|
||
# introspection queries will not be executed. | ||
|
||
validation_errors = validate( | ||
schema=schema, | ||
document_ast=parse('THE QUERY'), | ||
rules=( | ||
DisableIntrospection, | ||
) | ||
) | ||
|
||
|
||
Implementing custom validators | ||
------------------------------ | ||
All custom query validators should extend the `ValidationRule <https://github.com/graphql-python/graphql-core/blob/v3.0.5/src/graphql/validation/rules/__init__.py#L37>`_ | ||
base class importable from the graphql.validation.rules module. Query validators are visitor classes. They are | ||
instantiated at the time of query validation with one required argument (context: ASTValidationContext). In order to | ||
perform validation, your validator class should define one or more of enter_* and leave_* methods. For possible | ||
enter/leave items as well as details on function documentation, please see contents of the visitor module. To make | ||
validation fail, you should call validator's report_error method with the instance of GraphQLError describing failure | ||
reason. Here is an example query validator that visits field definitions in GraphQL query and fails query validation | ||
if any of those fields are blacklisted: | ||
|
||
.. code:: python | ||
from graphql import GraphQLError | ||
from graphql.language import FieldNode | ||
from graphql.validation import ValidationRule | ||
|
||
|
||
my_blacklist = ( | ||
"disallowed_field", | ||
) | ||
|
||
|
||
def is_blacklisted_field(field_name: str): | ||
return field_name.lower() in my_blacklist | ||
|
||
|
||
class BlackListRule(ValidationRule): | ||
def enter_field(self, node: FieldNode, *_args): | ||
field_name = node.name.value | ||
if not is_blacklisted_field(field_name): | ||
return | ||
|
||
self.report_error( | ||
GraphQLError( | ||
f"Cannot query '{field_name}': field is blacklisted.", node, | ||
) | ||
) | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.