DEV Community

Discussion on: WP schedule event role and permissions (capabilities)

Collapse
 
ingosteinke profile image
Ingo Steinke, web developer • Edited

I installed WP Crontrol to show more information about scheduled jobs and intervals. There are much more than I expected, and there is the one scheduled by my report mailer plugin.

cron jobs overview screenshot

And it's got an unexpected problem: it's got no action!

I must have made a mistake in my callback definition.

Revisiting the documentation

wp_schedule_event( int $timestamp, string $recurrence, string $hook, array $args = array(), bool $wp_error = false ): bool|WP_Error
Enter fullscreen mode Exit fullscreen mode

I see that my implicit assumption about the third parameter was wrong.

$hook string Required Action hook to execute when the event is run

makes it quite clear that wp_schedule_event doesn't expect a function but an action hook. That's basically an additional wrapper around the existing function. I could have copied the first user provided code example in the comments.

if (! wp_next_scheduled ( 'my_hourly_event', $args )) {
    wp_schedule_event( time(), 'hourly', 'my_hourly_event', $args );
}

add_action( 'my_hourly_event', 'do_this_hourly', 10, 2 );
function do_this_hourly($args_1, $args_2 ) {
    // do something every hour
}
Enter fullscreen mode Exit fullscreen mode

We can even pass arguments (and if we don't, we need to change the 2 to 0 in add_action).

But we still can't pass user sessions and their permissions.

Collapse
 
ingosteinke profile image
Ingo Steinke, web developer • Edited

I discovered that we can fire a single scheduled event immediately from the WP Crontrol list view. Although the callback action evaluates to the existing function name, nothing happens. No empty mail, no echo output. So there is still something wrong with my schedule or callback.

Meanwhile, I had another idea.

If I had access to the SQL database, I could write a simple query like

SELECT * FROM wp_posts WHERE post_type = 'flamingo_inbound' AND post_date > '2023-10-09 08:07'

That would also assume that I know the current table prefix and the connection details.

But $wpdb knows.

global $wpdb;
$results = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}posts WHERE post_type = 'flamingo_inbound'", OBJECT );
Enter fullscreen mode Exit fullscreen mode

Of course, it wouldn't let me retrieve arbitrary data using a custom SQL statement without adding a capability constraint.

Or would it?

Collapse
 
ingosteinke profile image
Ingo Steinke, web developer

Proceeding to talk to myself, hoping for a solution to set WP schedule event role and permissions (capabilities):

  • [ ] WordPress custom user role for cron schedule callback

So we still can't pass user sessions and their permissions when scheduling our cron job.
And I still don't get how WordPress offers no best practice how to handle this requirement safely.

Allowing everyone access to the inbox items is no solution. Even if there are no public pages exposing this data, someone might still try and access it via an API call.

Running all cron schedule callbacks with administrator rights is no good solution either. We shouldn't even run this very specific job as an administrator.

Using a real cron job with file access on a UNIX system, I would create a unique new user and add it to a group of users. Then I would let this user group own the required file and set group permissions accordingly.

There are equivalent concepts in WordPress. User roles correspond to user groups, permissions correspond to their capabilities. As an administrator, which is roughly equivalent to an Administrator on Windows, not to a UNIX root, we should have sufficient capabilities to set permissions accordingly. But if the schedule callback runs as nobody, changing its role to anybody would be a privilege escalation. Do we have any chance to run a callback as somebody under any circumstances at all?

Thread Thread
 
ingosteinke profile image
Ingo Steinke, web developer • Edited

Several days later, suddenly, some mails in my inbox!

nothing to report, but the mail interval works

screenshot of the above mail subject

Maybe "hourly" means "daily" or "weekly" on a WordPress website with few visitors? Or maybe frontend caching prevents triggering the wp cron job schedule?

Some people seemed to have caching vs. wp cron issues.

But in my case, the "next scheduled" time changed and still it seemed that my cron callback was not executed.

Thread Thread
 
ingosteinke profile image
Ingo Steinke, web developer

After talking to myself in support issues, like I often do, logging erratic plugin behavior, and nobody seems to be able to help, I will test alternative solutions:

  • switch caching plugins to verify if it is W3TC related or if the same problems occurs with WP Rocket or other alternatives,
  • use an alternative to WP_Cron which seems like an unrealiable hack anyway.