@Override public PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria) { CriteriaQueryGenerator generator = new CriteriaQueryGenerator(subject, criteria); if (!authorizationManager.hasGlobalPermission(subject, Permission.VIEW_BUNDLES)) { generator.setAuthorizationBundleFragment(CriteriaQueryGenerator.AuthorizationTokenType.BUNDLE, subject.getId(), null); } CriteriaQueryRunner<Bundle> queryRunner = new CriteriaQueryRunner<Bundle>(criteria, generator, entityManager); PageList<Bundle> result = queryRunner.execute(); // If asking for optional data that the subject may not be able to see then ensure that the optional // data is filtered appropriately. In this case only destinations viewable by the subject can be returned. // The result currently holds bundles viewable by the caller, but the bundle may have been deployed to // destinations for which the user does not have access to the destination's resource group. (BZ 694741) if (!result.isEmpty() && criteria.isInventoryManagerRequired() && !authorizationManager.isInventoryManager(subject)) { // this works because findBundleDestinationsByCriteria() authorizes against resource group associations for (Bundle bundle : result) { if (bundle.getDestinations().isEmpty()) { continue; } BundleDestinationCriteria destinationCriteria = new BundleDestinationCriteria(); destinationCriteria.clearPaging(); //disable paging as the code assumes all the results will be returned. destinationCriteria.addFilterBundleId(bundle.getId()); List<BundleDestination> destinations = findBundleDestinationsByCriteria(subject, destinationCriteria); entityManager.detach(bundle); // make sure the narrowed set of destinations does not get persisted bundle.setDestinations(destinations); } } return result; }