Allow simplenews cron to send nodes that anonymous users cannot access

SomebodySysop - May 9, 2008 - 23:40
Project:Simplenews
Version:HEAD
Component:Code
Category:feature request
Priority:normal
Assigned:Unassigned
Status:needs review
Description

This issue was discussed and resolved here: http://drupal.org/node/85959

However, the resolution is to give anonymous users permissions to your newsletters. But, suppose you want to have PRIVATE newsletters? If the user is on the subscription list, he should get the newsletter, whether he is a user or not.

Could this problem be fixed so that Simplenews newsletters will be sent regardless as to whether the newsletter allows anonymous users to view/list it?

Thanks!

#1

SomebodySysop - May 12, 2008 - 18:00

The problem is here:

<?php
/**
* Send the newsletter
*/
function _simplenews_send($timer = FALSE) {
...
 
$result = db_query(db_rewrite_sql('SELECT n.nid, s.vid, s.tid, n.created FROM {node} n INNER JOIN {simplenews_newsletters} s ON n.nid = s.nid WHERE s.s_status = %d ORDER BY n.created ASC'), 1);
...
?>

Since cron runs as an anonymous user, the above sql statement will never allow it to send nodes that anonymous users cannot access.

I believe this limits Simplenews unnecessarily. It is possible that users will want to restrict a newsletter to a private group, but by definition any newsletter sent by cron must be public.

Seems like we could remove the problem by getting rid of the db_rewrite_sql part of the statement. I don't see any reason why we would want to add any access control queries to this one. Or, am I missing something here?

I did look at the 'send newsletter' permission, but I don't believe it as any effect here as there doesn't appear to be any node_grants given as a result of this permission.

#2

Sutharsan - July 4, 2008 - 07:55
Title:Simplenews cron only engages if cron is invoked via URL» Allow simplenews cron to send nodes that anonymous users cannot access
Category:support request» feature request
Assigned to:Anonymous» Sutharsan

The cause of the problem is, as you mention, the access restriction to the node. This is not solved by only leaving out the db_rewrite_sql here.
I found a solution in the mailhandler module. It switches the user when collecting data with restricted access. When simplenews sends emails we need to switch to the author user, load the node and switch the user back. But, this requires some caution not to create any security holes.

#3

Sutharsan - July 6, 2008 - 15:32
Assigned to:Sutharsan» Anonymous
Status:active» needs review

Please try the attached patch to see if it fixes the problem.

AttachmentSize
simplenews.256795.patch 3.16 KB

#4

ron_s - November 1, 2008 - 13:58
Status:needs review» reviewed & tested by the community

This patch fixed the problem for me. Will this be rolled into a future release?

#5

Sutharsan - November 1, 2008 - 16:44

I consider it. Please explain how you have restricted the access to the newsletter. I still need to understand the problem, before I decide for this solution. And I want more people to test this patch.

#6

ron_s - November 5, 2008 - 22:52

Ah ok I guess someone should have explained this. :) I don't know the situation for others, but for us newsletter access is being restricted using the Nodeaccess module.

For example, in Access Control the simplenews module is set for *no* anonymous users to have access to newsletters, then we use Nodeaccess to control who can receive certain types of Newsletters (using the Simplenews Template module to create templates for registered, paid, etc.).

#7

ron_s - November 5, 2008 - 22:53
Version:5.x-1.2» 5.x-1.5

Updating to the version we are using.

#8

Sutharsan - November 5, 2008 - 23:24

This is the kind of situation where the patch is intended for.
1. try so send using cron and see if the nodes appear in the email.
2. if the nodes do not get through, try the #3 patch and pls report the results.

#9

ron_s - November 9, 2008 - 06:24

I'm sorry, I thought my comment in #4 answered it? The patch in #3 worked for us. That's why I was asking if it would be rolled into a future release.

#10

Sutharsan - December 9, 2008 - 10:20
Status:reviewed & tested by the community» needs review

I like to see more test-result before rolling the patch.

#11

enboig - December 9, 2008 - 11:19

My problem is when using simplenews with relatedcontent and taxonomyaccess.
I have some nodes with restricted access using taxonomy; when I send test all the nodes get inserted in the newsletter, but when they are send using cron, the restricted ones aren't included in the newsletter.

I think it is a great idea to save the user, switch to another user, and then restore the initial user; but I would rather switch to the uid=1 user than the author of the node.

#12

Sutharsan - December 9, 2008 - 13:15

@enboig: please test the #3 patch. I want to see more test before this gets in. And, please explain why you want to switch to user/1? I assumed that the node author has full access to the node.

#13

enboig - December 9, 2008 - 15:01

Well, it should work with the node author; but I think its simplier to use always the user 1 than look always for the node author.

I will test the patch now.

#14

enboig - December 16, 2008 - 15:52

after applying the patch I recive this error:

Fatal error: Call to undefined function session_save_session() in /home/escolcat/public_html/sites/all/modules/simplenews/simplenews.module on line 2864

#15

enboig - December 16, 2008 - 16:01

Following #1 I changed:

<?php
  $result
= db_query(db_rewrite_sql('SELECT n.nid, s.vid, s.tid, n.created FROM {node} n INNER JOIN {simplenews_newsletters} s ON n.nid = s.nid WHERE s.s_status = %d ORDER BY n.created ASC'), 1);
?>

to
<?php
$result
= db_query('SELECT n.nid, s.vid, s.tid, n.created FROM {node} n INNER JOIN {simplenews_newsletters} s ON n.nid = s.nid WHERE s.s_status = %d ORDER BY n.created ASC', 1);
?>

And now It appear to work. Does this modification has security issues?

#16

Sutharsan - December 16, 2008 - 16:13

The patch does exactly change this code (and more) perhaps you had errors during patching. It is very likely that the patch does not apply cleanly anymore.

#17

enboig - December 16, 2008 - 17:14

I applied manually the patch, the version of simplenews I am using is a little different of this one; what I don't understand is why cron.php fails when calling a function ("session_save_session") that is in api.drupal.org (version 5).

doesn't cron.php do a full bootstrap?

#18

Sutharsan - December 20, 2008 - 17:11

The attached patch is the D6 version of the same functionality.
(it does not address the #14 error)

AttachmentSize
simplenews.d6_256795.patch 5.23 KB

#19

enboig - January 7, 2009 - 12:32

Any updates in this issue? I am using Drupal5 and I couldn't apply the patch provided.

Thanks

#20

enboig - February 3, 2009 - 11:53

Are the patches applied to the dev version so I could test them?

#21

Sutharsan - February 3, 2009 - 12:14

no, patches are not committed.
How to patch: http://drupal.org/patch/apply

#22

enboig - March 4, 2009 - 08:41

I could apply the patch "manually". My problem was because old versions of Drupal5 session_save_session(); updated the whole site and now it works ok.

Thanks.

#23

Sutharsan - March 15, 2009 - 22:43
Version:5.x-1.5» HEAD
Status:needs review» needs work

Change version to HEAD, new functionality will now only be added to HEAD.
Patch requires minor rework.

#24

Sutharsan - March 16, 2009 - 13:57
Status:needs work» needs review

Patch reworked for HEAD.
Changes:
- changed comment
- select element changed to radios

AttachmentSize
simplenews.256795_1.patch 15.56 KB

#25

Sutharsan - March 16, 2009 - 14:00

oops, mixed up with other patch.

AttachmentSize
simplenews.256795_2.patch 4.34 KB

#26

enboig - March 20, 2009 - 11:19

I was thinking that maybe the user which should be used to create the mail should be the "receiver" and not the creator of the newsletter.
In my association I have multiple users with different role and access to different content using "Taxonomy access". The way mails are generated now I understand some users could get a mail where they cannot click on "Read more" to read the full article.

#27

joachim - July 22, 2009 - 16:12

Tried the patch on the latest rc, where it applies with fuzz.

When cron runs, I get this:

    * warning: array_fill() [function.array-fill]: Number of elements must be positive in /Users/Sheila/Sites/drupal-name/includes/database.inc on line 241.
    * warning: implode() [function.implode]: Invalid arguments passed in /Users/Sheila/Sites/drupal-name/includes/database.inc on line 241.
    * warning: array_keys() [function.array-keys]: The first argument should be an array in /Users/Sheila/Sites/drupal-name/modules/user/user.module on line 502.
    * user warning: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1 query: SELECT p.perm FROM role r INNER JOIN permission p ON p.rid = r.rid WHERE r.rid IN () in /Users/Sheila/Sites/drupal-name/modules/user/user.module on line 502.

I suspect this is because the newsletter is made by uid 1 and I've not bothered to give the superuser any roles.

I'm not sure about the use of the 'cron user' setting -- why woud you want to send as the cron anonymous user? It just adds a complication because the way the newsletter is send is different depending on whether cron is being used or not.

Also -- how do I reproduce this anyway?
Does running cron with devel module run it as superuser? In which case that's no good for testing.
I've reversed the patch and emails are getting through, running cron on the command line with curl. Totally confused now!!!

#28

ccprog - August 21, 2009 - 18:06

While the function simplenews_switch_user in the patches above is declared as
function simplenews_switch_user($uid = NULL) {
it is called from simplenews_mail_mail for the user switch with
simplenews_switch_user($node->nid, $node->vid);

This will obviously not work. The single parameter should be $uid.

In addition, I support #26. This would open up the publication of a "public" and a "internal" version of the same newsletter, where one user sees some nodes, and the other not. Also, if someone who has received a newsletter with one role and now gets another role or additional rights, he could get the same newsletter in another version without having to unsubribe from the old and subscribing to a new series. (Think of a chronological list of events with public and internal events intermixed)

#29

Sutharsan - August 23, 2009 - 11:26

This patch is re-rolled for the current HEAD and has the error found by ccprog corrected.

AttachmentSize
simplenews.256795_3.patch 4.32 KB

#30

sgabe - August 31, 2009 - 19:10

Patch reworked for the current DRUPAL-6--1 branch.

AttachmentSize
simplenews.d6_256795_2.patch 4.84 KB

#31

anoopjohn - September 14, 2009 - 17:18

The simplenews.d6_256795_2.patch had the same issue pointed out by ccprog. I am attaching a modified version with this issue fixed.

AttachmentSize
simplenews.d6_256795_3.patch 4.83 KB

#32

Kweeks - September 22, 2009 - 16:04

I'm having the same issue. I've applied the patch in #31, and tried setting the cron user to be the newsletter author, but at cron time it doesn't send, it's still permanently pending. When I run cron manually, it sends immediately, although it's sending it twice. Does the patch work for others - am I missing something in set up?

All my content, and therefore the newsletter, is private.

#33

sgabe - September 22, 2009 - 16:33

The current 6.x-1.x-dev branch has simplenews.module revision 1.76.2.136, but the patch applies correctly only on 1.76.2.134. With the latest branch I got the same error as you.

#34

Kweeks - September 23, 2009 - 09:02

I'm actually using the latest stable release 6.x-1.0-rc6 rather than dev. This has simplenews.module revision 1.76.2.129. Is it worth updating to dev if it's still not solved the cron issue?

#35

Sutharsan - September 23, 2009 - 12:30

@Kweeks, sgabe: Try testing without Mime mail or other mail back-end like SMTP. Try debugging the code to see why the emails are not sent by cron.

AttachmentSize
simplenews.d6_256795_4.patch 4.92 KB

#36

Kweeks - September 23, 2009 - 16:49

Thanks for the revised patch Sutharsan.

I'm just using plain not MIME emails. My limited cron debugging skills seem to show:

  • module_invoke_all in includes/module.inc shows that simplenews_cron is being called at the 10 minute cron run
  • But the watchdog I put in simplenews_cron itself is not being called (which makes no sense to me?!)
  • Running cron.php manually calls the watchdog I put in simplenews_cron though, and the emails are sent

So it seems to me that the cron run is not calling hook_cron properly but the manual cron is. I can't see how that can be the case?!

#37

enboig - September 24, 2009 - 07:11

Make sure you logout before callin cron.php manually; to ensure it is not a permission problem.

#38

Kweeks - September 24, 2009 - 09:46

I've managed to solve my problem now and the patch works great, thanks Sutharsan.

@enboig, thanks for that reminder, I hadn't tried that. It worked even when logged out so wasn't a permission problem at least not that side.

I eventually tracked it down to my crontab - it was in root's crontab and needed to be in apache's to run properly. So actually cron on the site had not been running at all for any hook_crons, and it was only simplenews that alerted me to the fact. (the emails being sent twice was a silly oversight on my part - two test subscribers with the same address :-))

#39

Sutharsan - September 24, 2009 - 13:43

@Kweeks: Thanks very much for reporting the cause of your problem! (believe it or not, but not many people report back once their problem is fixed.) Can you explain a bit more on "it was in root's crontab and needed to be in apache's to run properly." Was cron triggered by user 'root' instead of user 'apache'? How did you notice and how did you solve? Perhaps you want to add a description to the (simplenews) handbook.

#40

Kweeks - September 24, 2009 - 15:24

It's exactly as you said. The cron was in the crontab of the Linux root user, when it needed to be in the crontab for the user 'apache' in order to run with the way our web servers are set up.

I added a watchdog into module_invoke_all in includes/module.inc to see what hook_crons were being called at cron time (a very useful tip from a DrupalCon Paris session, Debugging Drupal).

From that I could see that no cron functions were being called on the scheduled run, only when I ran it manually - meaning there's probably something wrong with the crontab. I hadn't even realised it wasn't running properly. Also because the emails sent manually (because that was the user 'apache' calling it) it wasn't a problem with cron just crashing on some module.

The cron log files (usually in /var/log/cron) show who's running the cron tab - it was root so I changed the crontabs and it worked.

Good idea I'll add something to the handbook - it might help someone else debug their cron problems even if it's not the same issue.

 
 

Drupal is a registered trademark of Dries Buytaert.