Uploaded image for project: 'Ibexa IBX'
  1. Ibexa IBX
  2. IBX-7172

loadLocationChildren() not working with multiple objectstate permissions

    XMLWordPrintable

Details

    • Yes

    Description

      Calling $locationService->loadLocationChildren($location) when you have content/read policy with stage limitation on multiple stages returns wrong result

      1. Create an objectstategroup "Group1" with state "State1"
      2. Create a second objectstategroup "Group2" with state "State2"
      3. Limit permission for anonymous to only read contents from "Group1:State1 and Group2:State2"
      4. Create a Content Object Parent1 with State1 and State2 assigned
      5. Create children Child1 and Child2, below Parent1, also with State1 and State2 assigned
      6. Try to fetch the object Parent1 with $locationService->loadLocationChildren($location). (see code below )
      7. See no children are listed
      <?php
      
      /**
       * @copyright Copyright (C) Ibexa AS. All rights reserved.
       * @license For full copyright and license information view LICENSE file distributed with this source code.
       */
      namespace App\Command;
      
      use eZ\Publish\API\Repository\LocationService;
      use eZ\Publish\API\Repository\PermissionResolver;
      use eZ\Publish\API\Repository\UserService;
      use Symfony\Component\Console\Command\Command;
      use Symfony\Component\Console\Input\InputArgument;
      use Symfony\Component\Console\Input\InputInterface;
      use Symfony\Component\Console\Input\InputOption;
      use Symfony\Component\Console\Output\OutputInterface;
      
      class loadLocationCommand extends Command
      {
          private LocationService$locationService;
          private UserService $userService;
          private PermissionResolver $permissionResolver;
      
          public function __construct(
              PermissionResolver $permissionResolver,
              LocationService $locationService,
              UserService $userService
          ) {
              $this->locationService = $locationService;
              $this->userService = $userService;
      
              parent::__construct();
              $this->permissionResolver = $permissionResolver;
          }
      
          protected function configure()
          {
              $this->setName('app:load-location')
                  ->setDescription('Load a given location')
                  ->addArgument(
                      'locationId',
                      InputArgument::REQUIRED,
                      'Parent location ID'
                  )
                  ->addOption(
                  'user',
                  'u',
                  InputOption::VALUE_REQUIRED,
                  'Ibexa DXP username',
                  'admin')
                  ->setHelp(
                      <<<EOT
      The command <info>%command.name%</info> allows you to load a given location
      EOT
                  );
          }
      
          protected function execute(InputInterface $input, OutputInterface $output)
          {
              $this->permissionResolver->setCurrentUserReference(
                  $this->userService->loadUserByLogin($input->getOption('user'))
              );
      
              $locationId = $input->getArgument('locationId');
      
              $location = $this->locationService->loadLocation($locationId);
      
              $output->writeln('Found content: ' . $location->getContent()->getName() );
              $children = $this->locationService->loadLocationChildren($location);
              /** @var \eZ\Publish\API\Repository\Values\Content\Location $child */
              foreach ($children as $child) {
                  $output->writeln(' - ' . $child->getContent()->getName() );
              }
      
              return Command::SUCCESS;
          }
      }
       

       

      Run the command as Admin (works):

      ./bin/console app:load-location 36742 --user admin -v
      Found content: loadLocationChildren() not working with multiple objectstate permissions
       - Child1
       - Child2 

       

      Run the command as user with limitation:

       ./bin/console app:load-location 36742 --user ObjectState1 -v
      Found content: loadLocationChildren() not working with multiple objectstate 
      permissions

       

      See error in in generated SQL when executing the command:

      tail -f var/log/dev.log |grep  ezcobj_state
      [2023-11-23T14:34:02.713003+00:00] doctrine.DEBUG: SELECT DISTINCT COUNT(DISTINCT location.node_id) FROM ezcontentobject_tree location INNER JOIN ezcontentobject content ON content.id = location.contentobject_id INNER JOIN ezcontentobject_version version ON (content.id = version.contentobject_id) AND (content.current_version = version.version) AND (version.status = :dcValue1) INNER JOIN ezcobj_state_link object_state_link ON content.id = object_state_link.contentobject_id INNER JOIN ezcontent_language language ON language.id & version.language_mask = language.id WHERE (location.parent_node_id IN (:dcValue2)) AND ((language.locale IN (:dcValue3)) OR (version.language_mask & 1 = 1)) AND ((content.section_id IN (:dcValue4)) AND ((object_state_link.contentobject_state_id IN (:dcValue5)) AND (object_state_link.contentobject_state_id IN (:dcValue6)))) {"dcValue1":1,"dcValue2":[36742],"dcValue3":["eng-GB"],"dcValue4":[6,3,1],"dcValue5":[4],"dcValue6":[5]} [] 

      The "ezcobj_state_link" table is only joined once but limited to two different IDs at the same time.

      Designs

        Attachments

          Activity

            People

              Unassigned Unassigned
              vidar.langseid@ibexa.co Vidar Langseid
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: