diff --git a/admin/tool/messageinbound/classes/manager.php b/admin/tool/messageinbound/classes/manager.php index c9925e498a5..6b72ffe5949 100644 --- a/admin/tool/messageinbound/classes/manager.php +++ b/admin/tool/messageinbound/classes/manager.php @@ -103,6 +103,30 @@ class manager { 'debug' => empty($CFG->debugimap) ? null : fopen('php://stderr', 'w'), ); + if (!empty($CFG->messageinbound_xoauth2)) { + // See https://developers.google.com/gmail/imap/xoauth2-protocol for details. + try { + $issuer = \core\oauth2\api::get_issuer($CFG->messageinbound_oauth2issuer); + } catch (dml_missing_record_exception $e) { + $message = $e->getMessage(); + throw new \moodle_exception('oauth2servicefailure', 'tool_messageinbound', '', null, $message); + } + + if ($issuer && !$issuer->get('enabled')) { + $message = get_string('auth2issuer_disabled', 'tool_messageinbound'); + throw new \moodle_exception('oauth2servicefailure', 'tool_messageinbound', '', null, $message); + } + + if (!($oauth2client = \core\oauth2\api::get_system_oauth_client($issuer))) { + $message = get_string('auth2issuer_connectionerror', 'tool_messageinbound'); + throw new \moodle_exception('oauth2servicefailure', 'tool_messageinbound', '', null, $message); + } + + $accesstoken = $oauth2client->get_accesstoken(); + $xoauth2token = new \Horde_Imap_Client_Password_Xoauth2($configuration['username'], $accesstoken->token); + $configuration['xoauth2_token'] = $xoauth2token; + } + if (strpos($configuration['hostspec'], ':')) { $hostdata = explode(':', $configuration['hostspec']); if (count($hostdata) === 2) { diff --git a/admin/tool/messageinbound/lang/en/tool_messageinbound.php b/admin/tool/messageinbound/lang/en/tool_messageinbound.php index c8271f31f8a..6b6bdb1ab19 100644 --- a/admin/tool/messageinbound/lang/en/tool_messageinbound.php +++ b/admin/tool/messageinbound/lang/en/tool_messageinbound.php @@ -88,6 +88,10 @@ $string['messageprovider:messageprocessingerror'] = 'Warning when an inbound mes $string['messageprovider:messageprocessingsuccess'] = 'Confirmation that a message was successfully processed'; $string['noencryption'] = 'Off - No encryption'; $string['noexpiry'] = 'No expiry'; +$string['oauth2issuer'] = 'OAuth2 Service'; +$string['oauth2issuer_desc'] = 'OAuth2 service to use to access the IMAP server, using XOAUTH2 authentication. If the service does not exist yet, you will need to create it.'; +$string['oauth2issuer_disabled'] = 'The configured OAuth2 Service is disabled. Incoming mail processing cannot proceed.'; +$string['oauth2issuer_connectionerror'] = 'The configured OAuth2 service could not connect to the service. Check service configuration and connected system account details.'; $string['oldmessagenotfound'] = 'You tried to manually authenticate a message, but the message could not be found. This could be because it has already been processed, or because the message expired.'; $string['oneday'] = 'One day'; $string['onehour'] = 'One hour'; @@ -97,6 +101,7 @@ $string['pluginname'] = 'Inbound message configuration'; $string['replysubjectprefix'] = 'Re:'; $string['requirevalidation'] = 'Validate sender address'; $string['name'] = 'Name'; +$string['selectissuer'] = 'Select OAuth2 Service...'; $string['ssl'] = 'SSL (Auto-detect SSL version)'; $string['sslv2'] = 'SSLv2 (Force SSL Version 2)'; $string['sslv3'] = 'SSLv2 (Force SSL Version 3)'; @@ -110,3 +115,5 @@ $string['validateaddress_help'] = 'When a message is received from a user, Moodl If the sender does not match, then the user is sent a notification to confirm that they really did send the email. If this setting is disabled, then the email address of the sender is not checked at all.'; +$string['xoauth2'] = 'Use XOAUTH2'; +$string['xoauth2_desc'] = 'Use XOAUTH2 to authenticate to the IMAP server. Gmail has enforced stricter security standards for apps that try to access their IMAP servers, and is blocking access using tradicional authentication methods (based on usernames and passwords). You can change the security settings of your Gmail account to let Moodle connect using traditional methods (this must be allowed by your G Suite Administator if your account is part of a G Suite domain), or you can use XOAUTH2 authentication. You need to specify the OAuth2 Service to be used for this.'; diff --git a/admin/tool/messageinbound/settings.php b/admin/tool/messageinbound/settings.php index 7fe0f1614e8..87ef4de5ed0 100644 --- a/admin/tool/messageinbound/settings.php +++ b/admin/tool/messageinbound/settings.php @@ -67,6 +67,24 @@ if ($hassiteconfig) { new lang_string('messageinboundhostssl', 'tool_messageinbound'), new lang_string('messageinboundhostssl_desc', 'tool_messageinbound'), 'ssl', $options)); + $settings->add(new admin_setting_configcheckbox('messageinbound_xoauth2', + new lang_string('messageinboundxoauth2', 'tool_messageinbound'), + new lang_string('messageinboundxoauth2_desc', 'tool_messageinbound'), 0)); + + $options = []; + $issuers = \core\oauth2\api::get_all_issuers(); + foreach ($issuers as $issuer) { + $options[$issuer->get('id')] = s($issuer->get('name')); + } + // If there are no oauth2 issuers defined yet, the $options array is empty and the + // select element is not rendered. Add an entry with an invitation to select on issuer. + if (!count($options)) { + $options[] = get_string('selectissuer','tool_messageinbound'); + } + $settings->add(new admin_setting_configselect('messageinbound_oauth2issuer', + new lang_string('messageinboundoauth2issuer', 'tool_messageinbound'), + new lang_string('messageinboundoauth2issuer_desc', 'tool_messageinbound'), null, $options)); + $settings->add(new admin_setting_configtext('messageinbound_hostuser', new lang_string('messageinboundhostuser', 'tool_messageinbound'), new lang_string('messageinboundhostuser_desc', 'tool_messageinbound'), '', PARAM_NOTAGS));