Issue #2787479 by Wim Leers, Sam152, quicksketch: Anon users can access editor dialogs because all users have plain_text
parent
61699f011a
commit
413eb51008
|
@ -18,17 +18,17 @@ editor.field_untransformed_text:
|
||||||
_access_quickedit_entity_field: 'TRUE'
|
_access_quickedit_entity_field: 'TRUE'
|
||||||
|
|
||||||
editor.image_dialog:
|
editor.image_dialog:
|
||||||
path: '/editor/dialog/image/{filter_format}'
|
path: '/editor/dialog/image/{editor}'
|
||||||
defaults:
|
defaults:
|
||||||
_form: '\Drupal\editor\Form\EditorImageDialog'
|
_form: '\Drupal\editor\Form\EditorImageDialog'
|
||||||
_title: 'Upload image'
|
_title: 'Upload image'
|
||||||
requirements:
|
requirements:
|
||||||
_entity_access: 'filter_format.use'
|
_entity_access: 'editor.use'
|
||||||
|
|
||||||
editor.link_dialog:
|
editor.link_dialog:
|
||||||
path: '/editor/dialog/link/{filter_format}'
|
path: '/editor/dialog/link/{editor}'
|
||||||
defaults:
|
defaults:
|
||||||
_form: '\Drupal\editor\Form\EditorLinkDialog'
|
_form: '\Drupal\editor\Form\EditorLinkDialog'
|
||||||
_title: 'Add link'
|
_title: 'Add link'
|
||||||
requirements:
|
requirements:
|
||||||
_entity_access: 'filter_format.use'
|
_entity_access: 'editor.use'
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\editor;
|
||||||
|
|
||||||
|
use Drupal\Core\Entity\EntityAccessControlHandler;
|
||||||
|
use Drupal\Core\Entity\EntityInterface;
|
||||||
|
use Drupal\Core\Session\AccountInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the access control handler for the text editor entity type.
|
||||||
|
*
|
||||||
|
* @see \Drupal\editor\Entity\Editor
|
||||||
|
*/
|
||||||
|
class EditorAccessControlHandler extends EntityAccessControlHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function checkAccess(EntityInterface $editor, $operation, AccountInterface $account) {
|
||||||
|
/** @var \Drupal\editor\EditorInterface $editor */
|
||||||
|
return $editor->getFilterFormat()->access($operation, $account, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,6 +11,9 @@ use Drupal\editor\EditorInterface;
|
||||||
* @ConfigEntityType(
|
* @ConfigEntityType(
|
||||||
* id = "editor",
|
* id = "editor",
|
||||||
* label = @Translation("Text Editor"),
|
* label = @Translation("Text Editor"),
|
||||||
|
* handlers = {
|
||||||
|
* "access" = "Drupal\editor\EditorAccessControlHandler",
|
||||||
|
* },
|
||||||
* entity_keys = {
|
* entity_keys = {
|
||||||
* "id" = "format"
|
* "id" = "format"
|
||||||
* },
|
* },
|
||||||
|
|
|
@ -5,7 +5,7 @@ namespace Drupal\editor\Form;
|
||||||
use Drupal\Component\Utility\Bytes;
|
use Drupal\Component\Utility\Bytes;
|
||||||
use Drupal\Core\Form\FormBase;
|
use Drupal\Core\Form\FormBase;
|
||||||
use Drupal\Core\Form\FormStateInterface;
|
use Drupal\Core\Form\FormStateInterface;
|
||||||
use Drupal\filter\Entity\FilterFormat;
|
use Drupal\editor\Entity\Editor;
|
||||||
use Drupal\Core\Ajax\AjaxResponse;
|
use Drupal\Core\Ajax\AjaxResponse;
|
||||||
use Drupal\Core\Ajax\HtmlCommand;
|
use Drupal\Core\Ajax\HtmlCommand;
|
||||||
use Drupal\editor\Ajax\EditorDialogSave;
|
use Drupal\editor\Ajax\EditorDialogSave;
|
||||||
|
@ -54,10 +54,10 @@ class EditorImageDialog extends FormBase {
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*
|
*
|
||||||
* @param \Drupal\filter\Entity\FilterFormat $filter_format
|
* @param \Drupal\editor\Entity\Editor $editor
|
||||||
* The filter format for which this dialog corresponds.
|
* The text editor to which this dialog corresponds.
|
||||||
*/
|
*/
|
||||||
public function buildForm(array $form, FormStateInterface $form_state, FilterFormat $filter_format = NULL) {
|
public function buildForm(array $form, FormStateInterface $form_state, Editor $editor = NULL) {
|
||||||
// This form is special, in that the default values do not come from the
|
// This form is special, in that the default values do not come from the
|
||||||
// server side, but from the client side, from a text editor. We must cache
|
// server side, but from the client side, from a text editor. We must cache
|
||||||
// this data in form state, because when the form is rebuilt, we will be
|
// this data in form state, because when the form is rebuilt, we will be
|
||||||
|
@ -81,8 +81,6 @@ class EditorImageDialog extends FormBase {
|
||||||
$form['#prefix'] = '<div id="editor-image-dialog-form">';
|
$form['#prefix'] = '<div id="editor-image-dialog-form">';
|
||||||
$form['#suffix'] = '</div>';
|
$form['#suffix'] = '</div>';
|
||||||
|
|
||||||
$editor = editor_load($filter_format->id());
|
|
||||||
|
|
||||||
// Construct strings to use in the upload validators.
|
// Construct strings to use in the upload validators.
|
||||||
$image_upload = $editor->getImageUploadSettings();
|
$image_upload = $editor->getImageUploadSettings();
|
||||||
if (!empty($image_upload['max_dimensions']['width']) || !empty($image_upload['max_dimensions']['height'])) {
|
if (!empty($image_upload['max_dimensions']['width']) || !empty($image_upload['max_dimensions']['height'])) {
|
||||||
|
@ -151,7 +149,7 @@ class EditorImageDialog extends FormBase {
|
||||||
|
|
||||||
// When Drupal core's filter_align is being used, the text editor may
|
// When Drupal core's filter_align is being used, the text editor may
|
||||||
// offer the ability to change the alignment.
|
// offer the ability to change the alignment.
|
||||||
if (isset($image_element['data-align']) && $filter_format->filters('filter_align')->status) {
|
if (isset($image_element['data-align']) && $editor->getFilterFormat()->filters('filter_align')->status) {
|
||||||
$form['align'] = array(
|
$form['align'] = array(
|
||||||
'#title' => $this->t('Align'),
|
'#title' => $this->t('Align'),
|
||||||
'#type' => 'radios',
|
'#type' => 'radios',
|
||||||
|
@ -170,7 +168,7 @@ class EditorImageDialog extends FormBase {
|
||||||
|
|
||||||
// When Drupal core's filter_caption is being used, the text editor may
|
// When Drupal core's filter_caption is being used, the text editor may
|
||||||
// offer the ability to in-place edit the image's caption: show a toggle.
|
// offer the ability to in-place edit the image's caption: show a toggle.
|
||||||
if (isset($image_element['hasCaption']) && $filter_format->filters('filter_caption')->status) {
|
if (isset($image_element['hasCaption']) && $editor->getFilterFormat()->filters('filter_caption')->status) {
|
||||||
$form['caption'] = array(
|
$form['caption'] = array(
|
||||||
'#title' => $this->t('Caption'),
|
'#title' => $this->t('Caption'),
|
||||||
'#type' => 'checkbox',
|
'#type' => 'checkbox',
|
||||||
|
|
|
@ -4,7 +4,7 @@ namespace Drupal\editor\Form;
|
||||||
|
|
||||||
use Drupal\Core\Form\FormBase;
|
use Drupal\Core\Form\FormBase;
|
||||||
use Drupal\Core\Form\FormStateInterface;
|
use Drupal\Core\Form\FormStateInterface;
|
||||||
use Drupal\filter\Entity\FilterFormat;
|
use Drupal\editor\Entity\Editor;
|
||||||
use Drupal\Core\Ajax\AjaxResponse;
|
use Drupal\Core\Ajax\AjaxResponse;
|
||||||
use Drupal\Core\Ajax\HtmlCommand;
|
use Drupal\Core\Ajax\HtmlCommand;
|
||||||
use Drupal\editor\Ajax\EditorDialogSave;
|
use Drupal\editor\Ajax\EditorDialogSave;
|
||||||
|
@ -25,10 +25,10 @@ class EditorLinkDialog extends FormBase {
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*
|
*
|
||||||
* @param \Drupal\filter\Entity\FilterFormat $filter_format
|
* @param \Drupal\editor\Entity\Editor $editor
|
||||||
* The filter format for which this dialog corresponds.
|
* The text editor to which this dialog corresponds.
|
||||||
*/
|
*/
|
||||||
public function buildForm(array $form, FormStateInterface $form_state, FilterFormat $filter_format = NULL) {
|
public function buildForm(array $form, FormStateInterface $form_state, Editor $editor = NULL) {
|
||||||
// The default values are set directly from \Drupal::request()->request,
|
// The default values are set directly from \Drupal::request()->request,
|
||||||
// provided by the editor plugin opening the dialog.
|
// provided by the editor plugin opening the dialog.
|
||||||
$user_input = $form_state->getUserInput();
|
$user_input = $form_state->getUserInput();
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\editor\Tests;
|
||||||
|
|
||||||
|
use Drupal\Core\Url;
|
||||||
|
use Drupal\editor\Entity\Editor;
|
||||||
|
use Drupal\Tests\BrowserTestBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test access to the editor dialog forms.
|
||||||
|
*
|
||||||
|
* @group editor
|
||||||
|
*/
|
||||||
|
class EditorDialogAccessTest extends BrowserTestBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modules to install.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public static $modules = ['editor', 'filter', 'ckeditor'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test access to the editor image dialog.
|
||||||
|
*/
|
||||||
|
public function testEditorImageDialogAccess() {
|
||||||
|
$url = Url::fromRoute('editor.image_dialog', ['editor' => 'plain_text']);
|
||||||
|
$session = $this->assertSession();
|
||||||
|
|
||||||
|
// With no text editor, expect a 404.
|
||||||
|
$this->drupalGet($url);
|
||||||
|
$session->statusCodeEquals(404);
|
||||||
|
|
||||||
|
// With a text editor but without image upload settings, expect a 200, but
|
||||||
|
// there should not be an input[type=file].
|
||||||
|
$editor = Editor::create([
|
||||||
|
'editor' => 'ckeditor',
|
||||||
|
'format' => 'plain_text',
|
||||||
|
'settings' => [
|
||||||
|
'toolbar' => [
|
||||||
|
'rows' => [
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'name' => 'Media',
|
||||||
|
'items' => [
|
||||||
|
'DrupalImage',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'plugins' => [],
|
||||||
|
],
|
||||||
|
'image_upload' => [
|
||||||
|
'status' => FALSE,
|
||||||
|
'scheme' => 'public',
|
||||||
|
'directory' => 'inline-images',
|
||||||
|
'max_size' => '',
|
||||||
|
'max_dimensions' => [
|
||||||
|
'width' => 0,
|
||||||
|
'height' => 0,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$editor->save();
|
||||||
|
$this->resetAll();
|
||||||
|
$this->drupalGet($url);
|
||||||
|
$this->assertTrue($this->cssSelect('input[type=text][name="attributes[src]"]'), 'Image uploads disabled: input[type=text][name="attributes[src]"] is present.');
|
||||||
|
$this->assertFalse($this->cssSelect('input[type=file]'), 'Image uploads disabled: input[type=file] is absent.');
|
||||||
|
$session->statusCodeEquals(200);
|
||||||
|
|
||||||
|
// With image upload settings, expect a 200, and now there should be an
|
||||||
|
// input[type=file].
|
||||||
|
$editor->setImageUploadSettings(['status' => TRUE] + $editor->getImageUploadSettings())
|
||||||
|
->save();
|
||||||
|
$this->resetAll();
|
||||||
|
$this->drupalGet($url);
|
||||||
|
$this->assertFalse($this->cssSelect('input[type=text][name="attributes[src]"]'), 'Image uploads enabled: input[type=text][name="attributes[src]"] is absent.');
|
||||||
|
$this->assertTrue($this->cssSelect('input[type=file]'), 'Image uploads enabled: input[type=file] is present.');
|
||||||
|
$session->statusCodeEquals(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -17,11 +17,11 @@ use Drupal\node\Entity\NodeType;
|
||||||
class EditorImageDialogTest extends EntityKernelTestBase {
|
class EditorImageDialogTest extends EntityKernelTestBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter format for testing.
|
* Text editor config entity for testing.
|
||||||
*
|
*
|
||||||
* @var \Drupal\filter\FilterFormatInterface
|
* @var \Drupal\editor\EditorInterface
|
||||||
*/
|
*/
|
||||||
protected $format;
|
protected $editor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modules to enable.
|
* Modules to enable.
|
||||||
|
@ -42,7 +42,7 @@ class EditorImageDialogTest extends EntityKernelTestBase {
|
||||||
$this->installConfig(['node']);
|
$this->installConfig(['node']);
|
||||||
|
|
||||||
// Add text formats.
|
// Add text formats.
|
||||||
$this->format = FilterFormat::create([
|
$format = FilterFormat::create([
|
||||||
'format' => 'filtered_html',
|
'format' => 'filtered_html',
|
||||||
'name' => 'Filtered HTML',
|
'name' => 'Filtered HTML',
|
||||||
'weight' => 0,
|
'weight' => 0,
|
||||||
|
@ -51,7 +51,7 @@ class EditorImageDialogTest extends EntityKernelTestBase {
|
||||||
'filter_caption' => ['status' => TRUE],
|
'filter_caption' => ['status' => TRUE],
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
$this->format->save();
|
$format->save();
|
||||||
|
|
||||||
// Set up text editor.
|
// Set up text editor.
|
||||||
$editor = Editor::create([
|
$editor = Editor::create([
|
||||||
|
@ -65,6 +65,7 @@ class EditorImageDialogTest extends EntityKernelTestBase {
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
$editor->save();
|
$editor->save();
|
||||||
|
$this->editor = $editor;
|
||||||
|
|
||||||
// Create a node type for testing.
|
// Create a node type for testing.
|
||||||
$type = NodeType::create(['type' => 'page', 'name' => 'page']);
|
$type = NodeType::create(['type' => 'page', 'name' => 'page']);
|
||||||
|
@ -104,7 +105,7 @@ class EditorImageDialogTest extends EntityKernelTestBase {
|
||||||
$form_state = (new FormState())
|
$form_state = (new FormState())
|
||||||
->setRequestMethod('POST')
|
->setRequestMethod('POST')
|
||||||
->setUserInput($input)
|
->setUserInput($input)
|
||||||
->addBuildInfo('args', [$this->format]);
|
->addBuildInfo('args', [$this->editor]);
|
||||||
|
|
||||||
$form_builder = $this->container->get('form_builder');
|
$form_builder = $this->container->get('form_builder');
|
||||||
$form_object = new EditorImageDialog(\Drupal::entityManager()->getStorage('file'));
|
$form_object = new EditorImageDialog(\Drupal::entityManager()->getStorage('file'));
|
||||||
|
|
Loading…
Reference in New Issue