Skip to content

Commit

Permalink
Merge pull request #2155 from winged/fix_typename_in_disabled_instros…
Browse files Browse the repository at this point in the history
…pection

fix(validation): do not block __typename when introspection is disabled
  • Loading branch information
winged authored Feb 12, 2024
2 parents a2326ec + 46f2184 commit 71be792
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 1 deletion.
57 changes: 57 additions & 0 deletions caluma/caluma_user/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,60 @@ def test_authentication_view_improperly_configured(rf, settings):
request = rf.get("/graphql", HTTP_AUTHORIZATION="Bearer Token")
with pytest.raises(ImproperlyConfigured):
views.AuthenticationGraphQLView.as_view()(request)


@pytest.mark.parametrize(
"introspect, suppress_introspection, expect_error",
[
("schema", False, False),
("schema", True, True),
("typename", False, False),
("typename", True, False),
("nothing", False, False),
("nothing", True, False),
],
)
def test_suppressed_introspection(
rf,
requests_mock,
settings,
mocker,
# params
introspect,
expect_error,
suppress_introspection,
):
userinfo = {"sub": "1"}
requests_mock.get(settings.OIDC_USERINFO_ENDPOINT, text=json.dumps(userinfo))

if suppress_introspection:
mocker.patch(
"caluma.caluma_user.views.AuthenticationGraphQLView.validation_rules",
(views.SuppressIntrospection,),
)

schema_subquery = "__schema { description }" if introspect == "schema" else ""
inspection_key = "__typename" if introspect == "typename" else ""

# Query gets spiked with some introspection keys depending on parametrisation
query = f"""
query ds {{
{schema_subquery}
allDataSources {{
{inspection_key}
totalCount
edges {{
node {{
{inspection_key}
info
}}
}}
}}
}}
"""

request = rf.post("/graphql", {"query": query, "variables": {}})
response = views.AuthenticationGraphQLView.as_view()(request)
resp_json = json.loads(response.content)

assert ("errors" in resp_json) == expect_error
17 changes: 16 additions & 1 deletion caluma/caluma_user/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,24 @@ class HttpResponseUnauthorized(HttpResponse):
status_code = 401


class SuppressIntrospection(DisableIntrospection):
"""Validate request to reject any introspection, except the bare minimum."""

# The base class, graphene.validation.DisableIntrospection, is too strict:
# It rejects everything starting with double underscores (as per GQL spec)
# but we need `__typename` for our frontends to work correctly.

ALLOWED_INTROSPECTION_KEYS = ["__typename"]

def enter_field(self, node, *_args):
field_name = node.name.value
if field_name not in self.ALLOWED_INTROSPECTION_KEYS:
super().enter_field(node, *_args)


custom_validation_rules = []
if settings.DISABLE_INTROSPECTION: # pragma: no cover
custom_validation_rules.append(DisableIntrospection)
custom_validation_rules.append(SuppressIntrospection)

if settings.QUERY_DEPTH_LIMIT: # pragma: no cover
custom_validation_rules.append(
Expand Down

0 comments on commit 71be792

Please sign in to comment.