Problem/Motivation

Despite #3327791: Fix incorrect access check in WebformSubmissionExporter::generate being fixed, our tests on 6.1 started failing again. Looks like I didn't properly investigate that last time.

I did some digging and the situation is a bit a mess and currently inconsistent between 6.1 and 6.2:

git diff 6.1.x..6.2.x src/WebformSubmissionExporter.php
[...]
   public function generate() {
-    $entity_ids = $this->getQuery()->accessCheck(TRUE)->execute();
+    $entity_ids = $this->getQuery()->execute();
     $webform_submissions = WebformSubmission::loadMultiple($entity_ids);
 
     $this->writeHeader();
@@ -911,7 +949,10 @@ class WebformSubmissionExporter implements WebformSubmissionExporterInterface {
     $webform = $this->getWebform();
     $source_entity = $this->getSourceEntity();
 
-    $query = $this->getSubmissionStorage()->getQuery()->condition('webform_id', $webform->id());
+    $query = $this->getSubmissionStorage()
+      ->getQuery()
+      ->accessCheck(FALSE)
+      ->condition('webform_id', $webform->id()); 

This isn't good.

The exporter used to have this snippet:

// Do not check access to submission since the exporter UI and Drush
// already have access checking.
// @see webform_query_webform_submission_access_alter()
$query->accessCheck(FALSE);

But this was removed in #3302623: Disabling the access check in WebformSubmissionExporter bypasses domain.

Then, 6.2.x D10 compatibility work happened and was partially backported to 6.1.x. I then reported #3327791: Fix incorrect access check in WebformSubmissionExporter::generate which I noticed on 6.2 but actually not _only_ a D10 porting issue, I wasn't aware of the domain issue. That removed the accessCheck(TRUE) and kept the one on FALSE, but that accessCheck(FALSE) was not backported to 6.1. Then #3335851: Webform 6.1.4 breaks drush data export re-added it on both branches, but only for CLI.

That means that currently on 6.2, access checks are always disabled and on 6.1 only on CLI.

To be honest, I'm unsure if the exporter should ever assume that access checks shouldn't be done or at least it should expose that decision and not hardcode it. See proposed solution.

Steps to reproduce

Proposed resolution

Add a new public method on the exporter that allows to explicitly disable access checks, default to doing access checks. The drush integration should then disable it. Our own integration that does the partial export for usually-not-authorized-users will need to be adjusted too but I can live with that.

Note that this the combination of using domain module *and* drush is going to be weird then, as it will not be domain-limited, but I'm not sure what the expectation in that situation even is. An alternative would be to always do access checks, but have an additional query metadata property that allows to skip only your own access check.

6.1 and 6.2 will need different patches then to align them again.

Remaining tasks

User interface changes

API changes

Data model changes

Comments

Berdir created an issue. See original summary.

berdir’s picture

Issue summary: View changes
berdir’s picture

Status: Active » Needs review
StatusFileSize
new3.09 KB
new3.08 KB

Patches for 6.1 and 6.2 for the proposed change. This is adding a method to WebformSubmissionExporterInterface, so it's a BC break, Core has the 1:1 rule that allows to add methods to interfaces that have a 1:1 relationship to a class and implementations are expected to subclass from that, but also only does that in minor versions.

That part is a bit tricky, but this is IMHO the sensible way forward long-term. You could only commit this to 6.2, 6.1 users that had custom processes that relied on this not doing access checks in 6.1 and earlier like us will need to use a patch or other workaround or switch to 6.2.

berdir’s picture

Remove the extra empty line that snuck in the patches.

Also no tests yet, considering the number of times that these went back and forth on, that would be a good idea, didn't check if you already have tests for submission query access, if so then combining that with export tests should be doable.

mathilde_dumond’s picture

The latest 6.1 patch does not apply to 6.1.4 so I rerolled it.

jrockowitz’s picture

I am open to committing the 6.2.x patch AS-IS.

jrockowitz’s picture

ivnish’s picture

The first patch #4 applied to 6.1.x branch

The second patch #4 applied to 6.2.x branch

How can I test this code?

jrockowitz’s picture

Status: Needs review » Reviewed & tested by the community
tgoeg’s picture

Status: Reviewed & tested by the community » Needs work

Patch in #3345191-4: Export and access checks applied to current 6.2.0-beta6 breaks drush wfx for me.
This seems related to the already mentioned #3335851: Webform 6.1.4 breaks drush data export.

I get infinite loops of

>  [notice] Exported 0 of 7 submissions…
>  [notice] Exported 0 of 7 submissions…
>  [notice] Exported 0 of 7 submissions…

with this patch applied. No further info when using --debug.

berdir’s picture

Status: Needs work » Needs review
StatusFileSize
new3.7 KB

Ah, good find, thanks for testing. I didn't properly test that. The drush export also reuses the export controller and its batch methods and that was inconsistent. it had a hardcoded queryAccess(FALSE), so the total was always without query access while the actual export wasn't. I changed that to use getTotal(), I also refactored the whole patch to put the access check flag in export options, that is easier to pass around and makes more sense I think.

I also added a safety guard to that batch method, because even with consistent access checks, someone adding or removing a submission while you are batch-exporting could also cause an endless loop. I prefer progress < max over progress !== max in such a case, but didn't make that change.

Only adding a patch for 6.2.x for now, I don't think if you want to make that kind of change to 6.1.x anymore at this point.

Status: Needs review » Needs work

The last submitted patch, 11: webform-export-access-6.2-3345191-11.patch, failed testing. View results

berdir’s picture

Status: Needs work » Needs review
StatusFileSize
new4.08 KB
new1.08 KB

Hm, that was based on an incomplete local patch. The test fail shows that access check needs to be further up, because there is a case with the range latest where the query gets cloned.

tgoeg’s picture

I can confirm my exports now work on 6.2.0-beta6 plus the patch in #3345191-13: Export and access checks, thanks!

However, I cannot test/verify whether the actual issue at hand here is actually (still) fixed as I only partly understand the problem and do not have an existing problem caused by it which would be fixed (and neither do I use the domain module).

berdir’s picture

Our tests are working fine with the patch in #13. We did have to change our implementation of course, instead of calling accessCheck(FALSE), you need to pass it in as an exporter option, in case people were already relying on that.

jrockowitz’s picture

Status: Needs review » Reviewed & tested by the community

Let's get this committed because it fixed the immediate issue

  • Liam Morland committed 7770f11e on 6.2.x authored by Berdir
    Issue #3345191 by Berdir, mathilde_dumond, jrockowitz, tgoeg: Fix export...
liam morland’s picture

Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

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