Skip to content
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

[Improvement]: Option to disable GraphQL introspection via config #716

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/01_Installation_and_Upgrade/01_Upgrade_Notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
to the settings store, use the provided `datahub:configuration:migrate-legacy-config` command.
- Added the ability to import and export each type of data-hub configuration.
Be sure to include the `supported_types` configuration in any custom implementation to use the import functionality!
- Added possibility to disable the introspection for GraphQL via configuration tree.

## 1.5.0
- When "Skip Permission Check" is active in a GraphQL configuration, the "Workspaces" settings are also skipped
Expand Down
9 changes: 9 additions & 0 deletions doc/10_GraphQL/01_Configuration/03_Security_Settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ Defines how users are authenticated when accessing the endpoint.
* API Key: needs to be sent with every request.
* ... more to come

## Introspection settings

Introspection provides an information about queries which are supported by GraphQl schema. This is currently enabled by default. It can be disabled via security settings or in the symfony configuration tree:
```
pimcore_data_hub:
graphql:
allow_introspection: false
```

## Workspace Settings

Defines workspaces for data that should be accessible via the endpoint.
Expand Down
9 changes: 7 additions & 2 deletions src/Controller/WebserviceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,14 @@ public function webonyxAction(
$variableValues = $event->getRequest()->get('variables', $variableValues);
}

$disableIntrospection = $configuration->getSecurityConfig()['disableIntrospection'] ?? false;
$configAllowIntrospection = true;
if (isset($config['graphql']) && isset($config['graphql']['allow_introspection'])) {
$configAllowIntrospection = $config['graphql']['allow_introspection'];
}

$disableIntrospection = !$configAllowIntrospection || (isset($configuration->getSecurityConfig()['disableIntrospection']) && $configuration->getSecurityConfig()['disableIntrospection']);

DocumentValidator::addRule(new DisableIntrospection($disableIntrospection));
DocumentValidator::addRule(new DisableIntrospection((int)$disableIntrospection));

$result = GraphQL::executeQuery(
$event->getSchema(),
Expand Down
1 change: 1 addition & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public function getConfigTreeBuilder()
->scalarNode('not_allowed_policy')->info('throw exception = 1, return null = 2')->defaultValue(2)->end()
->booleanNode('output_cache_enabled')->info('enables output cache for graphql responses. It is disabled by default')->defaultValue(false)->end()
->integerNode('output_cache_lifetime')->info('output cache in seconds. Default is 30 seconds')->defaultValue(30)->end()
->booleanNode('allow_introspection')->info('enables introspection for graphql. It is enabled by default')->defaultValue(true)->end()
->end()
->end()
->end()
Expand Down
12 changes: 12 additions & 0 deletions src/EventListener/AdminListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@

class AdminListener
{
private array $config;

public function __construct(array $config)
{
$this->config = $config;
}

/**
* Handles INDEX_ACTION_SETTINGS event and adds custom admin UI settings
*
Expand All @@ -27,5 +34,10 @@ class AdminListener
public function addIndexSettings(IndexActionSettingsEvent $event)
{
$event->addSetting('data-hub-writeable', (new \Pimcore\Bundle\DataHubBundle\Configuration(null, null))->isWriteable());
$allowIntrospection = true;
if (isset($this->config['graphql']) && isset($this->config['graphql']['allow_introspection'])) {
$allowIntrospection = $this->config['graphql']['allow_introspection'];
}
$event->addSetting('allow_introspection', $allowIntrospection);
}
}
2 changes: 2 additions & 0 deletions src/Resources/config/eventlistener.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ services:
- { name: kernel.event_subscriber }

Pimcore\Bundle\DataHubBundle\EventListener\AdminListener:
bind:
$config: '%pimcore_data_hub%'
tags:
- { name: kernel.event_listener, event: pimcore.admin.indexAction.settings, method: addIndexSettings }
62 changes: 34 additions & 28 deletions src/Resources/public/js/configuration/graphql/configItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,6 @@ pimcore.plugin.datahub.configuration.graphql.configItem = Class.create(pimcore.e
value: this.data.security ? this.data.security.skipPermissionCheck : ""
});

var disableIntrospection = new Ext.form.Checkbox({
fieldLabel: t('plugin_pimcore_datahub_disable_introspection'),
labelWidth: 200,
name: "disableIntrospection",
value: this.data.security ? this.data.security.disableIntrospection : ""
});

this.securityForm = new Ext.form.FormPanel({
bodyStyle: "padding:10px;",
autoScroll: true,
Expand Down Expand Up @@ -281,30 +274,43 @@ pimcore.plugin.datahub.configuration.graphql.configItem = Class.create(pimcore.e
readOnly: true,
disabled: true
},
skipPermissionCheck,
disableIntrospection,
{
xtype: 'displayfield',
hideLabel: true,
value: t("plugin_pimcore_datahub_security_introspection_description"),
cls: "pimcore_extra_label_bottom",
style: "padding-bottom: 0px",
readOnly: true,
disabled: true
},
{
xtype: 'fieldset',
width: 800,
title: t("workspaces"),
items: [
this.documentWorkspace.getPanel(),
this.assetWorkspace.getPanel(),
this.objectWorkspace.getPanel()
]
}
skipPermissionCheck
]
});

if (pimcore.settings.allow_introspection) {
let disableIntrospection = new Ext.form.Checkbox({
fieldLabel: t('plugin_pimcore_datahub_disable_introspection'),
labelWidth: 200,
name: "disableIntrospection",
value: this.data.security ? this.data.security.disableIntrospection : ""
});
let introspectionDescription = {
xtype: 'displayfield',
hideLabel: true,
value: t("plugin_pimcore_datahub_security_introspection_description"),
cls: "pimcore_extra_label_bottom",
style: "padding-bottom: 0px",
readOnly: true,
disabled: true
};

this.securityForm.add(disableIntrospection, introspectionDescription);
}

let workspaces = {
xtype: 'fieldset',
width: 800,
title: t("workspaces"),
items: [
this.documentWorkspace.getPanel(),
this.assetWorkspace.getPanel(),
this.objectWorkspace.getPanel()
]
};

this.securityForm.add(workspaces);

return this.securityForm;
},

Expand Down