Ensure that form ids are unique
Add an unique prefix to each Form- or FormElement id, unless id protection is disabled explicitly, to prevent id collisions between different containers. fixes #8460
This commit is contained in:
parent
cc403806f7
commit
89451f3086
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
||||
|
||||
/**
|
||||
* Class Zend_View_Helper_Util
|
||||
*/
|
||||
class Zend_View_Helper_ProtectId extends Zend_View_Helper_Abstract
|
||||
{
|
||||
public function protectId($id) {
|
||||
return Zend_Controller_Front::getInstance()->getRequest()->protectId($id);
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
<?= $tabs; ?>
|
||||
</div>
|
||||
<div class="content" data-base-target="_next">
|
||||
<h1 tabindex="-1" id="authentication-reorder">
|
||||
<h1 tabindex="-1" id="authentication-configuration">
|
||||
<?= $this->translate('Authentication Configuration'); ?>
|
||||
</h1>
|
||||
<h2 tabindex="-1" id="authentication-new-backend" class="sr-only">
|
||||
|
|
|
@ -9,8 +9,8 @@ use Icinga\Web\Url;
|
|||
|
||||
if ($this->pageCount <= 1) return;
|
||||
|
||||
?><p id="paginationlabel" class="audible"><?= t('Pagination') ?></p>
|
||||
<ul class="pagination" aria-labelledby="paginationlabel" role="navigation"
|
||||
?><p id="<?= $this->protectId('paginationlabel'); ?>" class="audible"><?= t('Pagination') ?></p>
|
||||
<ul class="pagination" aria-labelledby="<?= $this->protectId('paginationlabel'); ?>" role="navigation"
|
||||
<?php
|
||||
|
||||
$fromto = t('Show rows %u to %u out of %u');
|
||||
|
|
|
@ -112,6 +112,13 @@ class Form extends Zend_Form
|
|||
*/
|
||||
protected $validatePartial = false;
|
||||
|
||||
/**
|
||||
* Whether element ids will be protected against collisions by appending a request-specific unique identifier
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $protectIds = true;
|
||||
|
||||
/**
|
||||
* Authentication manager
|
||||
*
|
||||
|
@ -903,6 +910,28 @@ class Form extends Zend_Form
|
|||
public function render(Zend_View_Interface $view = null)
|
||||
{
|
||||
$this->create();
|
||||
if ($this->protectIds) {
|
||||
if (null !== $this->getAttrib('id')) {
|
||||
$this->setAttrib('id', $this->getRequest()->protectId($this->getAttrib('id')));
|
||||
} else {
|
||||
$this->setAttrib('id', $this->getRequest()->protectId($this->name));
|
||||
}
|
||||
|
||||
/** @var Zend_Form_Element $element */
|
||||
foreach ($this->getElements() as $element) {
|
||||
if (null !== $element->getAttrib('id')) {
|
||||
$element->setAttrib(
|
||||
'id',
|
||||
$this->getRequest()->protectId($this->getName() . '-' . $element->getAttrib('id'))
|
||||
);
|
||||
} else {
|
||||
$element->setAttrib(
|
||||
'id',
|
||||
$this->getRequest()->protectId($this->getName() . '-' . $element->getName())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return parent::render($view);
|
||||
}
|
||||
|
||||
|
@ -944,4 +973,29 @@ class Form extends Zend_Form
|
|||
throw new SecurityException('No permission for %s', $permission);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable whether ids should be altered to guard them against duplications
|
||||
*
|
||||
* @param $value boolean Whether or not protect ids against collisions through other requests
|
||||
*/
|
||||
public function setProtectIds($value)
|
||||
{
|
||||
$this->protectIds = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the id that is written into the output html when rendering this form
|
||||
*
|
||||
* This will return the protected id, in case $protectIds is enabled.
|
||||
*
|
||||
* @return string The id
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
if ($this->protectIds) {
|
||||
return $this->getRequest()->protectId($this->getName());
|
||||
}
|
||||
return $this->getName();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,11 @@ class Request extends Zend_Controller_Request_Http
|
|||
*/
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $uniqueId;
|
||||
|
||||
private $url;
|
||||
|
||||
public function getUrl()
|
||||
|
@ -47,4 +52,19 @@ class Request extends Zend_Controller_Request_Http
|
|||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes an ID unique to this request, to prevent id collisions in different containers
|
||||
*
|
||||
* Call this whenever an ID might show up multiple times in different containers. This function is useful
|
||||
* for ensuring unique ids on sites, even if we combine the HTML of different requests into one site,
|
||||
* while still being able to reference elements uniquely in the same request.
|
||||
*/
|
||||
public function protectId($id)
|
||||
{
|
||||
if (! isset($this->uniqueId)) {
|
||||
$this->uniqueId = Window::generateId();
|
||||
}
|
||||
return $id . '-' . $this->uniqueId;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -702,7 +702,7 @@ class Monitoring_ListController extends Controller
|
|||
private function setupSortControl(array $columns)
|
||||
{
|
||||
$this->view->sortControl = new SortBox(
|
||||
$this->getRequest()->getActionName(),
|
||||
'sortbox-' . $this->getRequest()->getActionName(),
|
||||
$columns
|
||||
);
|
||||
$this->view->sortControl->applyRequest($this->getRequest());
|
||||
|
|
Loading…
Reference in New Issue