When a user performs a revert of a node, there is no record of that action in the revision table, or in the UI (although there is a watchdog message logged that contains the current user). For a production site though, its very possible that watchdog is turned off, making it very difficult to see who actually reverted a revision.

Consider the following:

  • User A creates a node (initial revision)
  • User B updates the node, saves and creates an additional revision
  • User C reverts to initial revision

As far as I can see, there is no reference to User C performing the revert, resulting in a sort of 'data loss'.

I believe the user performing the revert should be marked as the revision author. We still have a reference to the original revision, which contains the original revision author (User A above in this example).

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

trwill created an issue. See original summary.

trwill’s picture

I have added a patch which simply sets the revision user to the current user in NodeRevisionRevertForm::submitForm method

trwill’s picture

Issue summary: View changes
dpagini’s picture

Status: Active » Needs review
timmillwood’s picture

Assigned: trwill » Unassigned
Status: Needs review » Needs work
Issue tags: +Needs tests

Looks good, but we need some tests to make sure it does what it says, and make sure we don't get any future regressions.

trwill’s picture

Status: Needs work » Needs review
FileSize
1.71 KB
758 bytes

I believe this is an adequate test - when the revision is reverted, verify that the revision author == user performing revert (eg. current user). Nice and simple. Let me know if I've missed anything here.

Also included interdiff.

trwill’s picture

Giving this some more thought, I realize this test needs a bit more work to be complete. It should set an arbitrary user (different from user performing revert) as revision author for the revisions before the revert. Otherwise, it’s not a valid test since all 3 revisions are already the current user so of course they will be after revert too.

timmillwood’s picture

Status: Needs review » Needs work

Thanks @trwill, moving back to needs work for #7.

trwill’s picture

Alright @timmillwood, believe this is now complete. I created a property and set an arbitrary user ($revisionUser) in the ::setUp() method to access in the assertion itself, as well as the helper to create revisions, and potentially any other tests in the future. Added another assertion to the original test which also ensures the revert revision author is not the revision user. May be a bit redundant, but it feels like a good test there. Let me know if you'd prefer to remove that.

Also removed 'Needs Tests' tag. I can finish this up if anything is left.

trwill’s picture

Anything else needed on this?

timmillwood’s picture

Status: Needs review » Reviewed & tested by the community

Looks good now, thanks @trwill.

trwill’s picture

Great, thanks @timmillwood for the help and quick feedback! My first core patch :)

alexpott’s picture

I think this change makes sense but given the behaviour change it'd be great to have a +1 from an entity API or node maintainer.

Berdir’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: -Needs subsystem maintainer review

@timmillwood actually is a node module maintainer (I didn't know we even have that again :)), so it already had that.

I also agree with the change, however, we also need to update NodeRevisionRevertTranslationForm, as that is used when reverting a translation and the two should work consistently.

Berdir’s picture

My comment was wrong, I accidently looked at an 8.4 code base, the logic isn't duplicated anymore in 8.5.

However, I think we should have test coverage for that, we seem to be testing translation revision revert in \Drupal\node\Tests\NodeRevisionsTest::testRevisionTranslationRevert(), should be easy to add another line there.

timmillwood’s picture

Issue tags: +Needs tests

As you say in #15 NodeRevisionRevertTranslationForm extends NodeRevisionRevertForm and use the same submit handler, but yes, test coverage would be good.

Also, yes, I am Node maintainer, after the shock of seeing Node didn't have a maintainer I volunteered as I seem to be in and out of Node module with Workflow issues.

Berdir’s picture

Yeah, its interesting how we didn't have a node maintainer for a very long time, good thing it's not a very important piece of Drupal, right ;) Even better that it's an exception and that no other equally unimportant parts like the base system, system.module or the database layer also don't have any maintainers :)

timmillwood’s picture

You could almost be British with that sarcasm level :D

trwill’s picture

Berdir’s picture

Looks we don't have separate users here? So you probably need to create another and log in with that for the revert.

Berdir’s picture

Also, you shouldn't add additional test runs unless there is a specific reason to, like something that is PHP/database backend specific. Each test run costs ~1h hour of processing resources.

trwill’s picture

Whoops, we do have a different user for the reverted revision, but I didn't realize an extra node revision was initially being added at the top in the setup (expected 3 elements in $nodes array, actual is 4). My bad, ran the test with only the first line initially. Updated to use the correct revision.

Thanks for the tip on tests - I honestly had never thought about the resources, so used to unlimited builds for our CI.

Berdir’s picture

+++ b/core/modules/node/src/Tests/NodeRevisionsTest.php
@@ -179,6 +179,10 @@ public function testRevisions() {
     $reverted_node = $node_storage->load($node->id());
     $this->assertTrue(($nodes[1]->body->value == $reverted_node->body->value), 'Node reverted correctly.');
+    // Confirm the revision author is the user performing the revert.
+    $this->assertTrue($reverted_node->getRevisionUserId() == $this->loggedInUser->id(), 'Node revision author is user performing revert.');
+    // And that its not the revision author.
+    $this->assertTrue($reverted_node->getRevisionUserId() != $nodes[2]->getRevisionUserId(), 'Node revision author is not original revision author.');

Hm, I'm a bit confused.

The assert right above your code also checks for $nodes[1]. So it seems that piece expects that the reverted node is in fact $nodes[1] ?

trwill’s picture

Yeah, good catch. You are correct $nodes[1] is being reverted. I am getting a bit confused looking at how these nodes are keyed. I think this patch should do it - this now sets a different revision author on $nodes[1] as well, so we can compare revision authors.

trwill’s picture

Oops, should be < 2, not <1. Was only running the single method on my local. Updated patch.

trwill’s picture

It’s funny to me that this passed without the other revision having the editor user - maybe some legacy test set up code?

trwill’s picture

Anything left on this?

timmillwood’s picture

Status: Needs work » Reviewed & tested by the community

I think it'd be good to identify the issue spotted in #26, but I expect this can be done in a follow up.

trwill’s picture

Issue tags: -Needs tests

Removing the needs tests tag

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed f7cd4d7d94 to 8.6.x and caa2970238 to 8.5.x. Thanks!

  • alexpott committed f7cd4d7 on 8.6.x
    Issue #2944531 by trwill, timmillwood, Berdir: User performing revert...

  • alexpott committed caa2970 on 8.5.x
    Issue #2944531 by trwill, timmillwood, Berdir: User performing revert...

Status: Fixed » Closed (fixed)

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