Proposed commit message

Issue #687588 by tsphethean, mirie, Cottser, porchlight, cyborg_572, rgoodine, adci_contributor, joshi.rohit100: Remove access check from submit() in UserCancelForm

Problem/Motivation

Form _submit and _validate callbacks should not call user_access('administer users') (for D7) or ->hasPermission('administer users') (for D8). Having the access checks in _submit and _validate callbacks limits hook_form_alter() because one cannot alter out the permission check without rewriting the callbacks from scratch.

Proposed resolution

Move the access check into the user cancel form by setting a #value, so that it can be altered to some other permission by another module if desired. The permission condition check in _submit and _validate callbacks should check the value set in the form.

Remaining tasks

  1. Create a patch for D8
  2. Backport patch to D7

Original report by @agentrickard

Beta phase evaluation

Reference: https://www.drupal.org/core/beta-changes
Issue category Bug because the current way limits the ability of contrib to alter this form's access
Unfrozen changes Unfrozen because it only changes the way access is checked on the user cancel form to be more consistent with other parts of core
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

agentrickard’s picture

Version: 7.x-dev » 8.x-dev
Issue tags: -D7DX +Novice, +Needs backport to D7

Moving

oriol_e9g’s picture

Assigned: Unassigned » oriol_e9g

First solve and discuss in this issue http://drupal.org/node/687586 and then come back here to apply the same solution.

oriol_e9g’s picture

Assigned: oriol_e9g » Unassigned
dixon_’s picture

subscribing

emclaughlin’s picture

Assigned: Unassigned » emclaughlin

The only place I can find that calls user_cancel_confirm_form_submit() in 8.x is user_multiple_cancel_confirm_submit(). I can't find anything that calls user_multiple_cancel_confirm_submit(). Is this some feature of drupal/php that I'm unaware of where some behind the behind the scenes mojo in user_cancel_confirm_form() calls user_cancel_confirm_form_submit() (or the equivalent for the multiple cancel)? Or are these both just functions that have been deprecated but are still used somewhere I can't find?

pjcdawkins’s picture

@emclaughlin module_formID_submit() is called dynamically when the form generated by module_formID() is submitted successfully.

That's the default submit callback (others can be defined explicitly in $form['#submit']).

tsphethean’s picture

I have reviewed the approach in 687586 and applied the same approach here. Let me know if anything additional is required as I see that despite a successful patch the 687586 issue was re-opened.

tsphethean’s picture

Status: Active » Needs review

Status: Needs review » Needs work

The last submitted patch, user-cancel_submit_remove-687588-7.patch, failed testing.

tsphethean’s picture

Status: Needs work » Needs review
FileSize
1.75 KB

Revised patch attached - now checking for null response from user_access call

Status: Needs review » Needs work

The last submitted patch, user-cancel_submit_remove-687588-10.patch, failed testing.

tsphethean’s picture

Status: Needs work » Needs review
FileSize
1.85 KB

A little confused by why this is failing - I'm not getting the same notice when I test locally and stepping through adding debug output at each step has been successful.

I've added an extra isset check in this patch - hopefully that is ok but let me know if I'm missing something!

agentrickard’s picture

Looks good.

oriol_e9g’s picture

Status: Needs review » Reviewed & tested by the community

Looks good, doesn't add new features and don't break anything, so...

oriol_e9g’s picture

Status: Reviewed & tested by the community » Needs work

Wait!

1) Why use numbers here:

+     '#value' => ($admin_access ? 1 : 0),

And then we use a boolean for the same:

+  $admin_access = FALSE;

Should be more consistent use TRUE/FALSE in both places.

2) Instead of use this:

+  $admin_access = FALSE;
+  
+  if (isset($form_state['values']['administer_users'])) {
+    $admin_access = $form_state['values']['administer_users'];
+  }

I think it's better the compact form:

$admin_access = isset($form_state['values']['administer_users']) ? $form_state['values']['administer_users'] : FALSE;
agentrickard’s picture

I agree with TRUE/FALSE but Drupal coding standards dissuade the use of ternary expressions.

Please don't recommend changes that violate standards.

agentrickard’s picture

For TRUE/FALSE and brevity, we can just use:

  '#value' =>  user_access('administer users'),

In the IF, probably simpler to do this:

  $admin_access = !empty($form_state['values']['administer users'];

Clear, concise and avoids the ternary operator.

tsphethean’s picture

Status: Needs work » Needs review
FileSize
1.87 KB

Thanks for the feedback and suggestions. Revised patch attached.

agentrickard’s picture

Status: Needs review » Needs work

Now there are redundant lines:

-
+  
+  $admin_access = !empty($form_state['values']['administer users']);
+  
+  if ($admin_access) {
+    $admin_access = $form_state['values']['administer_users'];
+  }

The first !empty() assumes that the 'administer users' form element is set. If not set and TRUE, admin riggers will not fire.

tsphethean’s picture

Status: Needs work » Needs review
FileSize
1.77 KB

Good point - revised patch attached.

Status: Needs review » Needs work

The last submitted patch, user-cancel_submit_remove-687588-20.patch, failed testing.

tsphethean’s picture

Status: Needs work » Needs review
FileSize
1.77 KB

Gah, sorry - typo on the form state values. Fixed working patch attached.

tsphethean’s picture

Gah, sorry - typo on the form state values. Fixed working patch attached.

tsphethean’s picture

A while since this has moved so re-rolled against latest D8 build, apply cleanly so seeing what testbot makes of it now.

tsphethean’s picture

Sorry, not sure how I thought that last patch would apply... re-rolled now and re-queueing for testing.

tsphethean’s picture

Status: Needs work » Needs review

#25: user-cancel_submit_remove-687588-25.patch queued for re-testing.

Seeing whether testbot still likes this one

Status: Needs review » Needs work
Issue tags: -Novice, -forms api, -Needs backport to D7

The last submitted patch, user-cancel_submit_remove-687588-25.patch, failed testing.

Status: Needs review » Needs work

mirie’s picture

Issue summary: View changes

Ok, did a little investigating with @esod. This needs to be rerolled for D8. Looks like this form + submit handler in D8 is now located in /core/modules/user/src/Form/UserCancelForm.php

line 125 shows that the administer user check is still inside of the submit handler:

if ($this->currentUser()->hasPermission('administer users') && empty($form_state['values']['user_cancel_confirm']) && $this->entity->id() != $this->currentUser()->id()) {
      user_cancel($form_state['values'], $this->entity->id(), $form_state['values']['user_cancel_method']);
mirie’s picture

Title: Remove access check from user_cancel_confirm_form_submit() » Remove access check from submit() in UserCancelForm
Issue tags: -Needs backport to D7
mirie’s picture

Issue summary: View changes
mirie’s picture

Here's a patch @esod and I worked on for D8 to move the user access check out of submit() to $form.

esod’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 33: core-move-admin-access-check-to-form-687588-33.patch, failed testing.

mirie’s picture

Oh whoops. Forgot #value in all of the excitement. Here's a new patch.

mirie’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 36: core-move-admin-access-check-to-form-687588-36.patch, failed testing.

mirie’s picture

Ok, I think I figured out by looking at UserCancelTest and running that test locally.

mirie’s picture

joshi.rohit100’s picture

As i think, in buildForm() method, we have

$user = $this->currentUser();

so why not just use
$user->hasPermission('administer users');

instead of

$this->currentUser()->hasPermission('administer users');

So resubmitted patch.

jhedstrom’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll
adci_contributor’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
FileSize
1.55 KB

Trying to reroll

jhedstrom’s picture

  1. +++ b/core/modules/user/src/Form/UserCancelForm.php
    @@ -110,6 +110,12 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    +    // Store the user permissions so that it can be altered in hook_form_alter() if desired.
    

    This comment goes over the 80-character line-wrap.

  2. +++ b/core/modules/user/src/Form/UserCancelForm.php
    @@ -110,6 +110,12 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    +    ¶
    

    Trailing whitespace here.

adci_contributor’s picture

Thanks.

jhedstrom’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community

This looks good to me. I've updated the issue summary with a beta phase evaluation.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 45: core-move-admin-access-check-to-form-687588-45.patch, failed testing.

Status: Needs work » Needs review
jhedstrom’s picture

Status: Needs review » Reviewed & tested by the community

Back to RTBC.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 45: core-move-admin-access-check-to-form-687588-45.patch, failed testing.

Status: Needs work » Needs review
star-szr’s picture

Status: Needs review » Reviewed & tested by the community
star-szr’s picture

Assigned: adci_contributor » Unassigned
Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests

Actually this could use a small test.

star-szr’s picture

Issue tags: +SprintWeekend2015

We are working on the test during sprint weekend in London Canada!

star-szr’s picture

star-szr’s picture

Issue tags: +Needs backport to D7

Also this could potentially be backported I'd think, not sure why it was removed around #31.

The last submitted patch, 55: 687588-55-tests.patch, failed testing.

jhedstrom’s picture

Status: Needs review » Reviewed & tested by the community

+1 for the new test! I think this is back to RTBC now.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 55: 687588-55.patch, failed testing.

star-szr’s picture

Status: Needs work » Needs review
FileSize
4.61 KB

Thanks @jhedstrom!

Looks like there was just a small context change. Rerolled.

jhedstrom’s picture

Status: Needs review » Reviewed & tested by the community

Back to RTBC assuming bot goes green.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 60: 687588-60.patch, failed testing.

Status: Needs work » Needs review

Cottser queued 60: 687588-60.patch for re-testing.

jhedstrom’s picture

Status: Needs review » Reviewed & tested by the community

And again...

alexpott’s picture

Version: 8.0.x-dev » 7.x-dev
Status: Reviewed & tested by the community » Patch (to be ported)

Committed 20a76f0 and pushed to 8.0.x. Thanks!

Thank you for adding the beta evaluation to the summary.

  • alexpott committed 20a76f0 on 8.0.x
    Issue #687588 by tsphethean, mirie, Cottser, porchlight, cyborg_572,...

  • alexpott committed 20a76f0 on 8.1.x
    Issue #687588 by tsphethean, mirie, Cottser, porchlight, cyborg_572,...

  • alexpott committed 20a76f0 on 8.3.x
    Issue #687588 by tsphethean, mirie, Cottser, porchlight, cyborg_572,...

  • alexpott committed 20a76f0 on 8.3.x
    Issue #687588 by tsphethean, mirie, Cottser, porchlight, cyborg_572,...

  • alexpott committed 20a76f0 on 8.4.x
    Issue #687588 by tsphethean, mirie, Cottser, porchlight, cyborg_572,...

  • alexpott committed 20a76f0 on 8.4.x
    Issue #687588 by tsphethean, mirie, Cottser, porchlight, cyborg_572,...