From fdaa958ff7c0882f891759e1aa86d138bb7d6647 Mon Sep 17 00:00:00 2001 From: Sara Arjona Date: Fri, 19 Mar 2021 14:32:15 +0100 Subject: [PATCH] MDL-70722 oauth2: move Microsoft methods to service class --- lib/classes/oauth2/api.php | 82 +------------------- lib/classes/oauth2/service/microsoft.php | 98 ++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 79 deletions(-) create mode 100644 lib/classes/oauth2/service/microsoft.php diff --git a/lib/classes/oauth2/api.php b/lib/classes/oauth2/api.php index 6c1032d3297..046570a1be5 100644 --- a/lib/classes/oauth2/api.php +++ b/lib/classes/oauth2/api.php @@ -40,74 +40,6 @@ use moodle_exception; */ class api { - /** - * Build a microsoft ready OAuth 2 service. - * @return \core\oauth2\issuer - */ - private static function init_microsoft() { - // Microsoft is a custom setup. - $record = (object) [ - 'name' => 'Microsoft', - 'image' => 'https://www.microsoft.com/favicon.ico', - 'baseurl' => '', - 'loginscopes' => 'openid profile email user.read', - 'loginscopesoffline' => 'openid profile email user.read offline_access', - 'showonloginpage' => true, - 'servicetype' => 'microsoft', - ]; - - $issuer = new issuer(0, $record); - return $issuer; - } - - /** - * Create endpoints for microsoft issuers. - * @param issuer $issuer issuer the endpoints should be created for. - * @return mixed - * @throws \coding_exception - * @throws \core\invalid_persistent_exception - */ - private static function create_endpoints_for_microsoft($issuer) { - - $endpoints = [ - 'authorization_endpoint' => 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize', - 'token_endpoint' => 'https://login.microsoftonline.com/common/oauth2/v2.0/token', - 'userinfo_endpoint' => 'https://graph.microsoft.com/v1.0/me/', - 'userpicture_endpoint' => 'https://graph.microsoft.com/v1.0/me/photo/$value', - ]; - - foreach ($endpoints as $name => $url) { - $record = (object) [ - 'issuerid' => $issuer->get('id'), - 'name' => $name, - 'url' => $url - ]; - $endpoint = new endpoint(0, $record); - $endpoint->create(); - } - - // Create the field mappings. - $mapping = [ - 'givenName' => 'firstname', - 'surname' => 'lastname', - 'userPrincipalName' => 'email', - 'displayName' => 'alternatename', - 'officeLocation' => 'address', - 'mobilePhone' => 'phone1', - 'preferredLanguage' => 'lang' - ]; - foreach ($mapping as $external => $internal) { - $record = (object) [ - 'issuerid' => $issuer->get('id'), - 'externalfield' => $external, - 'internalfield' => $internal - ]; - $userfieldmapping = new user_field_mapping(0, $record); - $userfieldmapping->create(); - } - return $issuer; - } - /** * Build a nextcloud ready OAuth 2 service. * @return \core\oauth2\issuer @@ -186,9 +118,7 @@ class api { require_capability('moodle/site:config', context_system::instance()); // TODO: Move these methods to new service classes (to make this API easier to understand and maintain). - if ($type == 'microsoft') { - return self::init_microsoft(); - } else if ($type == 'nextcloud') { + if ($type == 'nextcloud') { return self::init_nextcloud(); } else { $classname = self::get_service_classname($type); @@ -209,9 +139,7 @@ class api { require_capability('moodle/site:config', context_system::instance()); // TODO: Move these methods to new service classes (to make this API easier to understand and maintain). - if ($type == 'microsoft') { - return self::create_endpoints_for_microsoft($issuer); - } else if ($type == 'nextcloud') { + if ($type == 'nextcloud') { return self::create_endpoints_for_nextcloud($issuer); } else { $classname = self::get_service_classname($type); @@ -240,6 +168,7 @@ class api { } case 'google': case 'facebook': + case 'microsoft': $classname = self::get_service_classname($type); $issuer = $classname::init(); if ($baseurl) { @@ -248,11 +177,6 @@ class api { $issuer->create(); return self::create_endpoints_for_standard_issuer($type, $issuer); - case 'microsoft': - $issuer = self::init_microsoft(); - $issuer->create(); - return self::create_endpoints_for_microsoft($issuer); - case 'nextcloud': if (!$baseurl) { throw new moodle_exception('Nextcloud service type requires the baseurl parameter.'); diff --git a/lib/classes/oauth2/service/microsoft.php b/lib/classes/oauth2/service/microsoft.php new file mode 100644 index 00000000000..d5d6e7ff7d2 --- /dev/null +++ b/lib/classes/oauth2/service/microsoft.php @@ -0,0 +1,98 @@ +. + +namespace core\oauth2\service; + +use core\oauth2\issuer; +use core\oauth2\endpoint; +use core\oauth2\user_field_mapping; +use core\oauth2\discovery\openidconnect; + +/** + * Class for Microsoft oAuth service, with the specific methods related to it. + * + * @package core + * @copyright 2021 Sara Arjona (sara@moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class microsoft extends openidconnect implements issuer_interface { + + /** + * Build an OAuth2 issuer, with all the default values for this service. + * + * @return issuer The issuer initialised with proper default values. + */ + public static function init(): issuer { + $record = (object) [ + 'name' => 'Microsoft', + 'image' => 'https://www.microsoft.com/favicon.ico', + 'baseurl' => '', + 'loginscopes' => 'openid profile email user.read', + 'loginscopesoffline' => 'openid profile email user.read offline_access', + 'showonloginpage' => true, + 'servicetype' => 'microsoft', + ]; + + $issuer = new issuer(0, $record); + return $issuer; + } + + /** + * Create endpoints for this issuer. + * + * @param issuer $issuer Issuer the endpoints should be created for. + * @return issuer + */ + public static function create_endpoints(issuer $issuer): issuer { + $endpoints = [ + 'authorization_endpoint' => 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize', + 'token_endpoint' => 'https://login.microsoftonline.com/common/oauth2/v2.0/token', + 'userinfo_endpoint' => 'https://graph.microsoft.com/v1.0/me/', + 'userpicture_endpoint' => 'https://graph.microsoft.com/v1.0/me/photo/$value', + ]; + foreach ($endpoints as $name => $url) { + $record = (object) [ + 'issuerid' => $issuer->get('id'), + 'name' => $name, + 'url' => $url + ]; + $endpoint = new endpoint(0, $record); + $endpoint->create(); + } + + // Create the field mappings. + $mapping = [ + 'givenName' => 'firstname', + 'surname' => 'lastname', + 'userPrincipalName' => 'email', + 'displayName' => 'alternatename', + 'officeLocation' => 'address', + 'mobilePhone' => 'phone1', + 'preferredLanguage' => 'lang' + ]; + foreach ($mapping as $external => $internal) { + $record = (object) [ + 'issuerid' => $issuer->get('id'), + 'externalfield' => $external, + 'internalfield' => $internal + ]; + $userfieldmapping = new user_field_mapping(0, $record); + $userfieldmapping->create(); + } + + return $issuer; + } +}