This module allows users to concurrently edit the same nodes without overwriting each other's changes. When one user modifies a field on the node the field will be marked changed and read only until the node has been saved. Any other user editing the same node will see those fields locked, but can still edit other fields.

When a field in the node edit form is changed an ajax call is made saving a cache entry that marks that field as changed by the current user.
The fields are checked on node edit page load and at 3 second intervals so users already editing a node will see fields get locked while they are working on the node.

Concurrency is defined per node type.

Other modules have tried working around this by either totally blocking other users from the node edit form if the node is being worked on, or showing a diff on save asking the user to confirm changes. But this module should allow multiple user to work on the same nodes and save their own changes without too much hassle.

Link to project page: https://www.drupal.org/sandbox/cnikolajsen/2493453

git clone --branch 7.x-1.x http://git.drupal.org/sandbox/cnikolajsen/2493453.git

Comments

cnikolajsen’s picture

ayesh’s picture

Status: Needs review » Needs work
Issue tags: +PAreview: security

Hi there,
This is a really nice module idea, and I'm sure many sites with serious content moderation needs will find this module super useful.

I went through your code, and found a few potential issues and a security issue in it.

- In your hook_menu implementation, the Ajax communication paths do not utilize any access protection. This makes it possible for anyone to forge a request to maliciously lock fields of a node.
I think the best solution would be inherit the access callback and access argumentsof the node/%node/edit page.

- concurrent_form_article_node_form_alter hook is only for the article content type, which may or may not be present. This is unnecessary since you already have concurrent_form_node_form_alter. Its hook is hook_form_base_form_id_alter.

- In your JS implementation, there are few potential issues that can make the module not work properly in different sites.
-- First, it's not safe to assume that the current URL will be in node/*/edit pattern. The node edit form can be embedded anywhere, so it is not safe to rely on the current URL.
-- Given the current JS workflow, let me suggest you a workaround:

In your form alter hook, you can add an Ajax button, with the custom path set to your custom Ajax path. At this step, you can add your CSS and JS file too. However, the JS file only triggers a $(element).click() in 3 second intervals. This way, you offload the Ajax request to Drupal. Drupal will take care to resolve the correct URL. This button can be hidden by CSS. It doesn't hurt even if the user manually click this button, because we have access validation in place already.

The response can contain zero or many Ajax commands.

Some advantages of this method include you allowing other modules to alter the Ajax response, Passing additional CSS/JS, etc. If you have any questions, I'm ready to help you as much as possible to me.

- concurrent_form_node_form_alter(): Please use the #attached instead of calling drupal_add_js directly.

- Also, I think a screenshot of a disabled field shown in the project page would be helpful.

cnikolajsen’s picture

Thank you for the feedback.

I've changed the access protection for the ajax path in my hook_menu.
I've removed concurrent_form_article_node_form_alter and moved the functionality to concurrent_form_node_form_alter.
Also changed the drupal_add_js in concurrent_form_node_form_alter to #attached.
I've added a screenshot to the project page :)

I've still to try out your JS workaround, that's in the works.

PA robot’s picture

Status: Needs work » Closed (won't fix)

Closing due to lack of activity. If you are still working on this application, you should fix all known problems and then set the status to "Needs review". (See also the project application workflow).

I'm a robot and this is an automated message from Project Applications Scraper.