From d247a63dfa49661c00499be26b352009ef3d4ef0 Mon Sep 17 00:00:00 2001 From: Damyon Wiese Date: Sun, 5 Mar 2017 14:28:33 +0800 Subject: [PATCH] MDL-58128 oauth2: Add a scheduled task for refresh We need to make sure our refresh tokens do not expire. We run a scheduled task to update the refresh token once per hour. Part of MDL-58220 --- lang/en/admin.php | 3 + .../oauth2/refresh_system_tokens_task.php | 88 +++++++++++++++++++ lib/db/tasks.php | 9 ++ 3 files changed, 100 insertions(+) create mode 100644 lib/classes/oauth2/refresh_system_tokens_task.php diff --git a/lang/en/admin.php b/lang/en/admin.php index 3b5f902b6ec..9559b7003d1 100644 --- a/lang/en/admin.php +++ b/lang/en/admin.php @@ -795,6 +795,8 @@ $string['notifyloginthreshold'] = 'Threshold for email notifications'; $string['notloggedinroleid'] = 'Role for visitors'; $string['numberofmissingstrings'] = 'Number of missing strings: {$a}'; $string['numberofstrings'] = 'Total number of strings: {$a->strings}
Missing: {$a->missing} ({$a->missingpercent} %)'; +$string['oauthrefreshtokenexpired'] = 'The refresh token for one of the OAuth services {$a->issuer} on your site {$a->siteurl} has expired. This will limit the functionality of any plugins that use this service. To fix this issue, visit the OAuth 2 Services configuration page and click on the "Connect system account" icon in the table row for this service. Be sure to login using the same service account for the OAuth system each time.'; +$string['oauthrefreshtokenexpiredshort'] = 'OAuth refresh token expired for {$a->issuer} on your site {$a->siteurl}.'; $string['onlynoreply'] = 'Only when from a no-reply address'; $string['opcacherecommended'] = 'PHP opcode caching improves performance and lowers memory requirements, OPcache extension is recommended and fully supported.'; $string['opensslrecommended'] = 'Installing the optional OpenSSL library is highly recommended -- it enables Moodle Networking functionality.'; @@ -1094,6 +1096,7 @@ $string['taskpasswordresetcleanup'] = 'Cleanup password reset attempts'; $string['taskplagiarismcron'] = 'Background processing for legacy cron in plagiarism plugins'; $string['taskportfoliocron'] = 'Background processing for portfolio plugins'; $string['taskquestioncron'] = 'Background processing for question engine'; +$string['taskrefreshoauthtokens'] = 'Refresh OAuth tokens for service accounts'; $string['taskregistrationcron'] = 'Site registration'; $string['tasksendfailedloginnotifications'] = 'Send failed login notifications'; $string['tasksendnewuserpasswords'] = 'Send new user passwords'; diff --git a/lib/classes/oauth2/refresh_system_tokens_task.php b/lib/classes/oauth2/refresh_system_tokens_task.php new file mode 100644 index 00000000000..c6e3db8fc08 --- /dev/null +++ b/lib/classes/oauth2/refresh_system_tokens_task.php @@ -0,0 +1,88 @@ +. + +/** + * A scheduled task. + * + * @package core + * @copyright 2017 Damyon Wiese + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace core\oauth2; + +use \core\task\scheduled_task; + +/** + * Simple task to delete old messaging records. + */ +class refresh_system_tokens_task extends scheduled_task { + + /** + * Get a descriptive name for this task (shown to admins). + * + * @return string + */ + public function get_name() { + return get_string('taskrefreshsystemtokens', 'admin'); + } + + /** + * Notify admins when an OAuth refresh token expires. Should not happen if cron is running regularly. + * @param \core\oauth2\issuer $issuer + */ + protected function notify_admins(\core\oauth2\issuer $issuer) { + $admins = get_admins(); + + if (empty($admins)) { + return; + } + foreach ($admins as $admin) { + $strparams = ['siteurl' => $CFG->wwwroot, 'issuer' => $issuer->get('name')]; + $long = get_string('oauthrefreshtokenexpired', 'core_admin', $strparams); + $short = get_string('oauthrefreshtokenexpiredshort', 'core_admin', $strparams); + $message = new \core\message\message(); + $message->courseid = SITEID; + $message->component = 'moodle'; + $message->name = 'oauthrefreshtokenexpired'; + $message->userfrom = core\user::get_noreply_user(); + $message->userto = $admin; + $message->subject = $short; + $message->fullmessage = $long; + $message->fullmessageformat = FORMAT_PLAIN; + $message->fullmessagehtml = $long; + $message->smallmessage = $short; + $message->notification = 1; + message_send($message); + } + } + + + /** + * Do the job. + * Throw exceptions on errors (the job will be retried). + */ + public function execute() { + $issuers = \core\oauth2\api::get_all_issuers(); + foreach ($issuers as $issuer) { + if ($issuer->is_system_account_connected()) { + if (!\core\oauth2\api::get_system_oauth_client($issuer)) { + $this->notify_admins($issuer); + } + } + } + } + +} diff --git a/lib/db/tasks.php b/lib/db/tasks.php index c820348d6c2..4366f69fb45 100644 --- a/lib/db/tasks.php +++ b/lib/db/tasks.php @@ -347,4 +347,13 @@ $tasks = array( 'dayofweek' => '*', 'month' => '*' ), + array( + 'classname' => 'core\oauth2\refresh_system_tokens_task', + 'blocking' => 0, + 'minute' => 'R', + 'hour' => '*', + 'day' => '*', + 'dayofweek' => '*', + 'month' => '*' + ), );