diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/configuration/SchemaConfiguration.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/configuration/SchemaConfiguration.kt index b513a80f..7e2e3f15 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/configuration/SchemaConfiguration.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/configuration/SchemaConfiguration.kt @@ -19,6 +19,7 @@ data class SchemaConfiguration( val executor: Executor, val timeout: Long?, + val introspection: Boolean = true, val plugins: MutableMap, Any> ) { @Suppress("UNCHECKED_CAST") diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/DefaultSchema.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/DefaultSchema.kt index a6afb5e1..f1cfebe1 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/DefaultSchema.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/DefaultSchema.kt @@ -44,6 +44,10 @@ class DefaultSchema ( ?.let { VariablesJson.Defined(configuration.objectMapper, variables) } ?: VariablesJson.Empty() + if (!configuration.introspection && request.isIntrospection()) { + throw GraphQLError("GraphQL introspection is not allowed") + } + val document = Parser(request).parseDocument() val executor = options.executor?.let(this@DefaultSchema::getExecutor) ?: defaultRequestExecutor @@ -55,6 +59,8 @@ class DefaultSchema ( ) } + private fun String.isIntrospection() = this.contains("__schema") || this.contains("__type") + override fun typeByKClass(kClass: KClass<*>): Type? = model.queryTypes[kClass] override fun typeByKType(kType: KType): Type? = typeByKClass(kType.jvmErasure) diff --git a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/SchemaConfigurationDSL.kt b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/SchemaConfigurationDSL.kt index f4aa6f69..d4087a1a 100644 --- a/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/SchemaConfigurationDSL.kt +++ b/kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/SchemaConfigurationDSL.kt @@ -20,6 +20,7 @@ open class SchemaConfigurationDSL { var wrapErrors: Boolean = true var executor: Executor = Executor.Parallel var timeout: Long? = null + var introspection: Boolean = true private val plugins: MutableMap, Any> = mutableMapOf() @@ -42,6 +43,7 @@ open class SchemaConfigurationDSL { wrapErrors, executor, timeout, + introspection, plugins ) } diff --git a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/schema/SchemaBuilderTest.kt b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/schema/SchemaBuilderTest.kt index 66d04ccb..71b0e5ad 100644 --- a/kgraphql/src/test/kotlin/com/apurebase/kgraphql/schema/SchemaBuilderTest.kt +++ b/kgraphql/src/test/kotlin/com/apurebase/kgraphql/schema/SchemaBuilderTest.kt @@ -337,6 +337,28 @@ class SchemaBuilderTest { assertThat(introspection.extract("data/__schema/queryType/fields[0]/args[0]/description"), equalTo(expectedDescription)) } + @Test + fun `introspections query should be disabled`(){ + val expectedDescription = "Int Argument" + val expectedDefaultValue = 33 + val schema = defaultSchema { + + configure { + introspection = false + } + + query("data"){ + resolver { int: Int -> int }.withArgs { + arg { name = "int"; defaultValue = expectedDefaultValue; description = expectedDescription } + } + } + } + + expect { + schema.executeBlocking("{__schema{queryType{fields{name, args{name, description, defaultValue}}}}}") + } + } + @Test @Suppress("UNUSED_ANONYMOUS_PARAMETER") fun `arg name must match exactly one of type property`(){