Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Scheduled Tasks and Admin Login


Reply


8 Posts   3392 Views

Avatar
azt3k

Community Member, 9 Posts

12 April 2011 at 6:49pm

Edited: 12/04/2011 6:52pm

So I need to set up a scheduled task in silverstripe 2.4.5.

I read through the documentation and extended DailyTask / HourlyTask etc - all fine.

Called cli-script.php HourlyTask via ssh - worked fine.

Set up a cron job with the command line as:

php /path/to/site/sapphire/cli-script.php HourlyTask > /path/to/site/logs/logfile.log

The command gets run and a log file is created only the contents of the log are this:

Status: 302 OK
X-Powered-By: PHP/5.2.5
Content-Type: text/html; charset="utf-8"
Location: /Security/login?BackURL=%2FHourlyTask

Visiting the site at http://my.site.com/HourlyTask prompts for admin login - which is to be expected apparently.

So I am having some user permissions problem I'm guessing. Looks like root via the cli doesn't need to log in to silverstripe to run the commands, but http and cron, which I guess runs as nobody do...

So How do I authenticate or bypass authentication.

I looked through these threads:
http://silverstripe.org/general-questions/show/6960
http://silverstripe.org/general-questions/show/13834
http://silverstripe.org/general-questions/show/13053

I have created an _ss_environment.php file with the $_FILE_TO_URL_MAPPING set and put this in my base directory - it made no difference

I have tried using bash / sh / sake instead of php / cli-script.php - still the same problem

I have tried using su to execute the command as a different user which works via the command line but fails to even produce a log file when done through cron. eg.

su username -c '/bin/sh /path/to/my/site/sapphire/sake HourlyTask > /path/to/my/site/silverstripe-logs/silverstripe_hourlytask.log'

Any other ideas??

Avatar
azt3k

Community Member, 9 Posts

14 April 2011 at 8:43am

Okay an Update to this....

Tried going through ssh and setting up a crontab on root (i.e. SSH > Login as Root > crontab -e) rather than the user account that has the silverstripe install on it - Still same result.

Tried "installing" sake and using it the crontab line - same result.

Avatar
azt3k

Community Member, 9 Posts

14 April 2011 at 10:57am

Edited: 14/04/2011 10:59am

Okay, so I have gotten it to work, but not via a tidy or simple method, also my implementation of it is a bit messy, but at least it works...

So I made an http wrapper for the scheduled task using curl called HourlyTask.php - It logs in to silverstripe, saves the cookies and then makes a request to my.site.com/ScheduledTask. I'm sure this could be made tidier by using CURLOPT_COOKIEJAR and CURLOPT_COOKIEFILE - however they were not working properly for some reason so I resorted to manually building a cookie var string. None of it is ideal, but it shouldn't be this complicated to begin with...

/path/to/webroot/mysite/code/cron/HourlyTask.php

//Authenticate
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,"http://my.site.com/Security/LoginForm");
curl_setopt($ch,CURLOPT_POST,TRUE);
curl_setopt($ch,CURLINFO_HEADER_OUT,TRUE);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
curl_setopt($ch,CURLOPT_HEADER,TRUE);
curl_setopt($ch,CURLOPT_POSTFIELDS,"Email=defaultAdmin&Password=defaultAdminPassword");
$result1 = curl_exec($ch);
$headers = preg_replace("/<html.*<\/html>/ims","",$result1);

//Debug
//print_r(curl_getinfo($ch));
//print $headers;

// Get the cookie vars
$cookies = array();
$headers = explode("\n",$headers);
foreach($headers as $h){
   if(preg_match("/Set-Cookie: (.*)/",$h,$m)){
      $vars = explode(";",$m[1]);
      foreach($vars as $v){
         $pieces = explode("=",trim($v));
         $cookies[trim($pieces[0])] = trim($pieces[1]);
      }
   }
}

// Make Cookie String
$cStr = "";
foreach($cookies as $k => $v){
   $cStr.= $k."=".$v.";";
}

// Request
curl_setopt($ch,CURLOPT_URL,"http://ss.abcdigital.co.nz/HourlyTask");
curl_setopt($ch,CURLOPT_COOKIE, $cStr);
curl_setopt($ch,CURLOPT_HEADER,FALSE);
$result2 = curl_exec($ch);

//Debug
//print_r(curl_getinfo($ch));
//print preg_replace("/<html.*<\/html>/ims","",$result2);

//Close Session
curl_close($ch);

//Output Result
print $result2;

I then set up an entry in crontab

0 * * * * php /path/to/webroot/mysite/code/cron/HourlyTask.php > /path/to/webroot/silverstripe-logs/silverstripe_hourlytask.log

and it works...

Avatar
swaiba

Forum Moderator, 1805 Posts

14 April 2011 at 7:13pm

I have several cron jobs - I'm curious what is the advantage of doing this to essentially just run a php script? or a page like dev/build (not in the site tree, but can be run when logged in as admin)? or as a page that requires http auth? or a page that requires a spcific GET/POST vars to run?

Do you have some control within the CMS to turn on/off? Is it more secure?

Avatar
azt3k

Community Member, 9 Posts

15 April 2011 at 4:51pm

As far as I'm aware the only advantage of using a ScheduledTask over an autonomous php script is that it works within the silverstripe frame work - so you have access to all your DataObjects, Controllers etc. Its theoretically what you should use when setting up a task in silverstripe.

Also ScheduledTasks have some predefined behaviour i.e. there are a number of child objects like DailyTask and HourlyTask - so when you extend off of them you can for example call DailyTask (http://my.site.com/DailyTask || php cli-script.php DailyTask || bash sake DailyTask) and it runs all of the daily tasks - i.e. every child class of DailyTask

Strictly speaking you shouldn't have to deal with authentication like this for cron jobs - unless that's part of the actual script. Tasks really shouldn't prompt for authentication when being run from cron - I'm sure I must be missing something obvious, because this seems like a glaring flaw and my solution is a bit of a hack at best.

More secure? - well I guess its more secure in the sense that it has authentication - but only in the sense that a 3rd party can't run ur tasks through a web browser with out admin access - I'd be happier if the tasks weren't mapped to a url that could be accessed by anyone and when called by sake or cli-script.php bypassed authentication.

Control? - no control to turn them on / off via the CMS - but there are SS modules that allow you to do that (I haven't tried them and can't comment on how well they work or if the tasks need to be set up as a child class of ScheduledTask)

You could use my script to access any page that requires authentication through curl, but I only resorted to using that method because I had already written the cron script as an extension of HourlyTask and nothing else was working for me.

Avatar
Jarek

Community Member, 30 Posts

19 May 2011 at 11:21pm

Task authentication can be omitted by small modification of CliController:

   function init() {
      parent::init();
      // Unless called from the command line, all CliControllers need ADMIN privileges
      if(!Director::is_cli() && !Permission::check("ADMIN") && $_SERVER['REMOTE_ADDR'] != $_SERVER['SERVER_ADDR']) {
         return Security::permissionFailure();
      }
   }

Third condition checks if caller address is not equal to address of page server. Safer condition is $_SERVER['REMOTE_ADDR'] != 'xx.xx.xx.xx(server IP)';

Avatar
BenWu

Community Member, 92 Posts

22 May 2012 at 11:24pm

Works very well. thanks a lot azt3k. I try to use the Lucent plugin to index the website for search daily and tried to find out how to use wget to index the file. Your codes work perfectly for me.

Avatar
BenWu

Community Member, 92 Posts

25 January 2013 at 1:48pm

found this https://github.com/nyeholt/silverstripe-queuedjobs/issues/2

instead of

sudo -u webaccount php sapphire/cli-script.php /dev/tasks/ProcessJobQueueTask

you need to run

sudo -u webaccount php-cli sapphire/cli-script.php /dev/tasks/ProcessJobQueueTask

that way, you don't have to hack around and expose your admin's password!