Problem/Motivation

Changing the access permissions for a newly created view from the default "Permission" to "Role" and clicking Apply causes an AJAX error message re getRoles() in Role.php (see below). The change to "Role" is applied, but the settings for "Role" can't be changed as clicking on the "Settings" link causes the same AJAX error. Tried in IE, FF and Chrome, same error and line 69 referenced in all browsers.

Error message in Chrome:

An AJAX HTTP error occurred.HTTP Result Code: 200Debugging information follows.Path: /drupal8/admin/structure/views/ajax/display/bug_test_view/default/access_optionsStatusText: OKResponseText: ( ! ) Fatal error: Call to undefined method Drupal\user\Plugin\views\access\Role::getRoles() in C:\wamp\www\drupal8\core\modules\user\lib\Drupal\user\Plugin\views\access\Role.php on line 69Call Stack#TimeMemoryFunctionLocation10.0011412328{main}( )..\index.php:020.00711052664drupal_handle_request( )..\index.php:1730.217319228392Symfony\Component\HttpKernel\Kernel->handle( )..\bootstrap.inc:220440.221919454056Drupal\Core\HttpKernel->handle( )..\Kernel.php:19750.221919454728Symfony\Component\HttpKernel\HttpKernel->handle( )..\HttpKernel.php:5260.221919454728Symfony\Component\HttpKernel\HttpKernel->handleRaw( )..\HttpKernel.php:7370.366622410704call_user_func_array( )..\HttpKernel.php:12980.366622411144Drupal\views_ui\Routing\ViewsUIController->ajaxForm( )..\HttpKernel.php:12990.381223937384views_ui_ajax_form( )..\ViewsUIController.php:377100.382824008192views_ajax_form_wrapper( )..\admin.inc:577110.382824008744drupal_build_form( )..\ajax.inc:104120.382824010528drupal_retrieve_form( )..\form.inc:368130.382924011712call_user_func_array( )..\form.inc:839140.382924011944views_ui_edit_display_form( )..\form.inc:839150.400825191872Drupal\views\Plugin\views\display\DisplayPluginBase->buildOptionsForm( )..\admin.inc:726160.404725250952Drupal\user\Plugin\views\access\Role->buildOptionsForm( )..\DisplayPluginBase.php:1496

Steps to get there:

  • Install 8.x from scratch
  • Menu -- Structure -- Views -- [create a new view]
  • Click on Permission link next to access
  • Choose Roles and click Apply
  • AJAX error displayed

Proposed resolution

Remaining tasks

User interface changes

API changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dawehner’s picture

Status: Active » Needs review
FileSize
811 bytes

Here is a fix for that.

kerasai’s picture

#1: drupal-1912602-1.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, drupal-1912602-1.patch, failed testing.

bdone’s picture

Status: Needs work » Needs review
FileSize
811 bytes

i've manually tested and verified that the ajax error is removed using patch in #1. not sure why it failed, so here's a re-roll against head.

Status: Needs review » Needs work

The last submitted patch, drupal-1912602-2.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
FileSize
4.19 KB

Added a test.

tim.plunkett’s picture

FileSize
18.15 KB
+++ b/core/modules/user/lib/Drupal/user/Tests/Views/AccessRoleUITest.phpundefined
@@ -0,0 +1,70 @@
+    $result = $entity_manager->getStorageController('view')->load(array('test_access_role'));
+    $view = reset($result);
+
+    $display = $view->getDisplay('default');
+    debug($display);
+    debug($display['display_options']['access_options']);

This seems to be missing an assert

dawehner’s picture

FileSize
670 bytes
4.23 KB

Oh you and I seemed to have uploaded the wrong patch.

Status: Needs review » Needs work

The last submitted patch, drupal-1912602-8.patch, failed testing.

dagmar’s picture

Status: Needs work » Needs review
FileSize
589 bytes
3.65 KB

setUp() already call to enableViewsTestModule() in the parent function. This reason test data is being created twice.

Status: Needs review » Needs work

The last submitted patch, drupal-1912602-10.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
Issue tags: +VDC
FileSize
1.66 KB
3.66 KB

Hi dagmar!

Let's fix it.

dawehner’s picture

I kind of consider this more like a critical as the roles access plugin don't work with that.

s_gupta_14’s picture

Tested this patch #12 but not working completely. I am not getting any ajax error but after I save the view on selecting role access it gives following error

InvalidArgumentException: Routing requirement for "_role_id" must be a string. in Symfony\Component\Routing\Route->sanitizeRequirement() (line 570 of /usr/share/nginx/www/trial-d8/core/vendor/symfony/routing/Symfony/Component/Routing/Route.php).

s_gupta_14’s picture

Issue summary: View changes
Status: Needs review » Needs work
marthinal’s picture

Status: Needs work » Needs review

12: vdc-1912602-12.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, 12: vdc-1912602-12.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
FileSize
6.69 KB
9.63 KB

Good point, let's actually fix all of it and write tests.

Wow, this shows a lot of problems all over the place.

Status: Needs review » Needs work

The last submitted patch, 18: vdc-1912602.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review

18: vdc-1912602.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, 18: vdc-1912602.patch, failed testing.

dawehner’s picture

Priority: Major » Critical
Status: Needs work » Needs review
FileSize
5.14 KB
12.71 KB

Some of the ascci arts of http://www.ascii-art.de/ascii/def/finger.txt might apply here.

In simpletest we use a ContainerBuilder ... sadly a Container needs to be dumped
to have a working synchronized service: https://github.com/symfony/symfony/issues/9595

Additional I realized some bug in the access manager, which adds multiple access checkers
and calls applies() more than needed.

Status: Needs review » Needs work

The last submitted patch, 22: vdc-1912602.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review

22: vdc-1912602.patch queued for re-testing.

damiankloip’s picture

  1. +++ b/core/modules/user/lib/Drupal/user/Plugin/views/access/Role.php
    @@ -74,7 +77,7 @@ public function buildOptionsForm(&$form, &$form_state) {
    +      '#options' => array_map(array('\Drupal\Component\Utility\String', 'checkPlain'), user_role_names()),
    

    I prefer the '\Drupal\Component\Utility\String::checkPlain' syntax, but that's up to you.

  2. +++ b/core/modules/user/lib/Drupal/user/Tests/Views/AccessRoleTest.php
    @@ -35,19 +38,43 @@ public static function getInfo() {
    +    /** @var \Drupal\views\ViewStorageInterface $view */
    ...
    +    /** @var \Symfony\Component\HttpKernel\HttpKernelInterface $kernel */
    

    This inline commenting is weird. Is this a new thing?

  3. +++ b/core/modules/user/lib/Drupal/user/Tests/Views/AccessRoleUITest.php
    @@ -0,0 +1,68 @@
    +  public static function getInfo() {
    

    Don't we inheritdoc this too now.

  4. +++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/PathPluginBase.php
    @@ -185,6 +185,8 @@ protected function getRoute($view_id, $display_id) {
    +    $route->setOption('_access_mode', 'ANY');
    

    Does this change work fine for all cases? seems like a big change, maybe a comment is needed just so future me will know whats going on.

  5. +++ b/core/tests/Drupal/Tests/Core/Access/AccessManagerTest.php
    @@ -149,6 +149,34 @@ public function testSetChecks() {
    +    $access_check->expects($this->exactly(2))
    +      ->method('applies')
    +      ->will($this->returnCallback(function (Route $route) {
    

    Worth adding a ->with($this->isInstanceOf('Route'))?

dawehner’s picture

Thank you for the review, sadly I cannot upload a new patch now.

This inline commenting is weird. Is this a new thing?

Yes we indeed do that now, in quite some places. This is pretty cool for static code analyse tools as well as IDE users.

dawehner’s picture

FileSize
12.93 KB
2.82 KB

Really great review!

tim.plunkett’s picture

+++ b/core/modules/user/lib/Drupal/user/Plugin/views/access/Role.php
@@ -42,7 +42,10 @@ public function access(AccountInterface $account) {
+      debug($route->setRequirement('_role', (string) implode(',', $this->options['role'])));

Stray debug

dawehner’s picture

FileSize
12.84 KB

Hacked the patch file.

Status: Needs review » Needs work

The last submitted patch, 29: vdc-1912602.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
FileSize
665 bytes
12.84 KB

I don't often hack patch files, but when I do I fail completely!

damiankloip’s picture

  1. +++ b/core/lib/Drupal/Core/Access/AccessManager.php
    @@ -159,13 +159,11 @@ protected function applies(Route $route) {
    +    // Finally ask the dynamic access checkers whether they do apply.
    

    "Finally, see if any dynamic access checkers apply."

  2. +++ b/core/tests/Drupal/Tests/Core/Access/AccessManagerTest.php
    @@ -149,6 +149,35 @@ public function testSetChecks() {
    +  public function testSetChecksWithDynamicAccessChecker() {
    

    Nice, this looks like some coverage that was missing originally - sorry about that!

    Worth asserting the expected _access_checks array on the route options too here?

dawehner’s picture

FileSize
1.18 KB
12.97 KB

Worth asserting the expected _access_checks array on the route options too here?

This is a good point! Let's do it.

In general views is one of the usecases where things gets complicated pretty fast, so we find bugs fast.

damiankloip’s picture

Status: Needs review » Reviewed & tested by the community

Great, RTBC for me. I don't see why this would not come back green.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 33: vdc-1912602.patch, failed testing.

dawehner’s picture

FileSize
921 bytes
12.96 KB

Great, RTBC for me. I don't see why this would not come back green.

Haha

dawehner’s picture

Status: Needs work » Needs review

.

vijaycs85’s picture

Status: Needs review » Reviewed & tested by the community

Though we are going back to procedural code, this is critical issue (as it throws fatal) and would be great to move forward, (i.e. discuss and update this patch or create follow up(s) etc)...

catch’s picture

+++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/PathPluginBase.php
@@ -185,6 +185,10 @@ protected function getRoute($view_id, $display_id) {
+    $route->setOption('_access_mode', 'ANY');

This looks like it could easily end up as an information disclosure vulnerability down the line, so I'm not really comfortable doing it in a follow-up - or at least that follow-up also needs to be critical.

dawehner’s picture

This looks like it could easily end up as an information disclosure vulnerability down the line, so I'm not really comfortable doing it in a follow-up - or at least that follow-up also needs to be critical.

Well, this is the intended behavior ... what should we do? At least at the moment views does not allow you to configure multiple access plugins + the one for the "administer views" permission.

catch’s picture

Maybe critical follow-up? I definitely don't have my head around what happens with overriding routes from the UI and how that interacts with multiple access checkers so it feels like its own discussion.

vijaycs85’s picture

catch’s picture

Status: Reviewed & tested by the community » Fixed

OK. Committed/pushed to 8.x, thanks!

catch’s picture

Status: Fixed » Needs review

Head broken:


* Drupal\user\Tests\Views\AccessRoleTest (20 pass(es), 0 fail(s), and 1 exception(s))
   - [exception] [Uncaught exception] "Symfony\Component\DependencyInjection\Exception\RuntimeException: You have requested a synthetic service ("request"). The DIC does not know how to construct this service. in Symfony\Component\DependencyInjection\ContainerBuilder->createService() (line 922 of /var/lib/drupaltestbot/sites/default/files/checkout/core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/ContainerBuilder.php). Symfony\Component\DependencyInjection\ContainerBuilder->createService(Object, 'request')
Symfony\Component\DependencyInjection\ContainerBuilder->get('request')
Drupal::request()
Drupal\simpletest\WebTestBase->curlExec(Array)
Drupal\simpletest\WebTestBase->drupalGet('user/logout', Array)
Drupal\simpletest\WebTestBase->drupalLogout()
Drupal\simpletest\WebTestBase->drupalLogin(Object)
Drupal\user\Tests\Views\AccessRoleTest->testAccessRole()
Drupal\simpletest\TestBase->run()
simpletest_script_run_one_test('812', 'Drupal\user\Tests\Views\AccessRoleTest')
" in ContainerBuilder.php on line 922 of Symfony\Component\DependencyInjection\ContainerBuilder->createService().
catch’s picture

36: vdc-1912602.patch queued for re-testing.

damiankloip’s picture

FileSize
12.56 KB
1.47 KB

This is the calls to handle() on the http kernel in the tests.

So we could just use drupalGet() calls, as this is a web test anyway?

Unless someone wants to fix what handle() is doing with the container request service that is set?

catch’s picture

Status: Needs review » Reviewed & tested by the community

That's worth fixing, but not here. I missed that we were doing kernel->handle() in the tests and probably would've pushed back against that anyway had I noticed.

RTBC pending bot coming back green.

The last submitted patch, 36: vdc-1912602.patch, failed testing.

catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 8.x, thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.