Problem/Motivation

When a registered users receives a newsletter and uses the "manage-url" link to change their subscriptions, they are told to log into their user account after (!) completing the form.

Steps to reproduce

Create a user. Add subscriptions for some newsletter types. Receive a newsletter email. Click the link from the [simplenews-subscriber:manage-url] token. Having followed the link, make some changes in the form and submit.

It results in the following error: There is an account registered for the e-mail address %mail. Please log in to manage your newsletter subscriptions.

Proposed resolution

Accept the verification via the access hash from the link as sufficient validation, and do not require additional login for registered users.

Remaining tasks

None

User interface changes

None.

API changes

None.

Data model changes

None.

Comments

PhilippVerpoort created an issue. See original summary.

PhilippVerpoort’s picture

Status: Active » Needs review
StatusFileSize
new3.94 KB

This does the desired. An update function still needs to be added to create the config entry for require_user_login in simplenews.settings.

Otherwise, this needs review.

The last submitted patch, , failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Status: Needs review » Needs work

The last submitted patch, 2: simplenews-require-login-3169019-2.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

adamps’s picture

Thanks. I suggest that we don't even need a config option.

  1. The unsubscribe link is a very similar case yet AFAIK does not require login.
  2. Requiring someone to log-in before they can unsubscribe is bad UX, perhaps even illegal.
  3. If an attacker has access to another users Mail account then they can easily log in anyway with a forgotten password link.

I guess the possible danger case is that I forward my newsletter to someone and they maliciously take the chance to alter my subscription. However I guess that this same risk is present in many major online newsletters.

Ideally this would have a test. It definitely would need one if adding a config option:-).

adamps’s picture

Updated answer:

The current code insists that users log in to manage their subscription. This is the correct behaviour in almost all cases. NB the code that this patch is altering is on the base subscription form used by all 4 different sub-forms. The only exception to the need to log in is the case that a valid token has been used for SubscriptionsPageForm. In this case SubscriptionsPageForm::buildForm() loaded the entity. Also SubscriptionsAccountForm::buildForm() tries to load an entity. SubscriberForm will always have an entity I would expect. I didn't check all the others but I expect it will be similar. So the correct fix to SubscriptionsFormBase::validateForm() should be to replace the call to \Drupal::currentUser()->isAnonymous() with something that checks if there is a valid entity loaded. There is no need to introduce a config option.

PhilippVerpoort’s picture

OK cool! I'll work something out and upload another patch when I find the time. :)

And agreed, we don't necessarily need a config option for this. (And if somebody *really* insists that they want people to log in first, they can always patch it up themselves in the code, it should then be just altering a single line of code.)

PhilippVerpoort’s picture

StatusFileSize
new2.6 KB

I'm uploading a new patch, which aims to implement the suggested changes by Adam in #6.

I've removed the config option, as I agree it's not necessary.

@AdamPS, could you confirm that what I did is vaguely what you were expecting?

I did a quick manual check to confirm it at least resolves the reported bug. It's possible it'll introduce new bugs though. Let's find out what the tests are going to say.

PhilippVerpoort’s picture

Status: Needs work » Needs review
adamps’s picture

Title: Add option to allow changes without login for registered users » Don't require login if already authenticated by token
Category: Feature request » Bug report
Status: Needs review » Needs work

What you have produces the right answer but it can be simpler/clearer. I think that if a user is loaded then the email address is always taken from that user so it can't possibly be wrong. Here is my suggestion:

Starting from the existing code, replace this:
\Drupal::currentUser()->isAnonymous()

with this:
!$this->isAuthenticated()

And add something like this

<strong>protected</strong> function isAuthenticated() {
  $user_loaded = $this->getEntity()->getUser();
  return ($user_loaded && $user_loaded->id());
}
PhilippVerpoort’s picture

StatusFileSize
new1.31 KB

Okay, makes sense! Here goes another attempt. I tested this patch it manually, and worked fine on my end.

Let's see what the tests say.

PhilippVerpoort’s picture

Status: Needs work » Needs review

Adam, can you review and then commit?

adamps’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

Great thanks. A minor comment:

$user_loaded->id()

would be better as

$user_loaded->isAuthenticated()

Then sorry to be tedious but it would be really great to have a quick test for this case as it would be easy for it to break in future.

PhilippVerpoort’s picture

Could you confirm what exactly you were referring to when you were saying:

Great thanks. A minor comment:

$user_loaded->id()

would be better as

$user_loaded->isAuthenticated()

Because I wasn't able to find $user_loaded->isAuthenticated() anywhere in file SubscriptionsFormBase.php.

jonathanshaw’s picture

Adam is referring to the isAuthenticated method you've added,

+++ b/src/Form/SubscriptionsFormBase.php
@@ -231,6 +231,14 @@ abstract class SubscriptionsFormBase extends ContentEntityForm {
+    return ($user_loaded && $user_loaded->id());

This could be
return ($user_loaded && $user_loaded->isAuthenticated())

adamps’s picture

Assigned: PhilippVerpoort » adamps

Thanks Philipp for your work on this. I have a need for it now so I am happy to finish it off.

adamps’s picture

Title: Don't require login if already authenticated by token » Don't require login if already authenticated by hash
Issue summary: View changes
Status: Needs work » Needs review
Issue tags: -Needs tests
StatusFileSize
new1.39 KB
adamps’s picture

StatusFileSize
new2.43 KB
adamps’s picture

Status: Needs review » Needs work
adamps’s picture

Status: Needs work » Needs review
adamps’s picture

jonathanshaw’s picture

Status: Needs review » Reviewed & tested by the community

Looks good to me.

  • AdamPS committed 3b088b6 on 3.x
    Issue #3169019 by PhilippVerpoort, AdamPS: Don't require login if...
adamps’s picture

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

Status: Fixed » Closed (fixed)

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

PhilippVerpoort’s picture

Amazing, thanks for finishing this off!