From 7afda52e62d40353dc396bc2d5687ba13de0252f Mon Sep 17 00:00:00 2001 From: Sara Arjona Date: Fri, 19 Mar 2021 14:51:27 +0100 Subject: [PATCH] MDL-70722 oauth2: move Nextcloud methods to service class --- lib/classes/oauth2/api.php | 109 +++-------------------- lib/classes/oauth2/service/nextcloud.php | 100 +++++++++++++++++++++ 2 files changed, 113 insertions(+), 96 deletions(-) create mode 100644 lib/classes/oauth2/service/nextcloud.php diff --git a/lib/classes/oauth2/api.php b/lib/classes/oauth2/api.php index 046570a1be5..6219c8dc98c 100644 --- a/lib/classes/oauth2/api.php +++ b/lib/classes/oauth2/api.php @@ -40,74 +40,6 @@ use moodle_exception; */ class api { - /** - * Build a nextcloud ready OAuth 2 service. - * @return \core\oauth2\issuer - */ - private static function init_nextcloud() { - // Nextcloud has a custom baseurl. Thus, the creation of endpoints has to be done later. - $record = (object) [ - 'name' => 'Nextcloud', - 'image' => 'https://nextcloud.com/wp-content/themes/next/assets/img/common/favicon.png?x16328', - 'basicauth' => 1, - 'servicetype' => 'nextcloud', - ]; - - $issuer = new issuer(0, $record); - - return $issuer; - } - - /** - * Create endpoints for nextcloud 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_nextcloud($issuer) { - $baseurl = $issuer->get('baseurl'); - // Add trailing slash to baseurl, if needed. - if (substr($baseurl, -1) !== '/') { - $baseurl .= '/'; - } - - $endpoints = [ - // Baseurl will be prepended later. - 'authorization_endpoint' => 'index.php/apps/oauth2/authorize', - 'token_endpoint' => 'index.php/apps/oauth2/api/v1/token', - 'userinfo_endpoint' => 'ocs/v2.php/cloud/user?format=json', - 'webdav_endpoint' => 'remote.php/webdav/', - 'ocs_endpoint' => 'ocs/v1.php/apps/files_sharing/api/v1/shares', - ]; - - foreach ($endpoints as $name => $url) { - $record = (object) [ - 'issuerid' => $issuer->get('id'), - 'name' => $name, - 'url' => $baseurl . $url, - ]; - $endpoint = new \core\oauth2\endpoint(0, $record); - $endpoint->create(); - } - - // Create the field mappings. - $mapping = [ - 'ocs-data-email' => 'email', - 'ocs-data-id' => 'username', - ]; - foreach ($mapping as $external => $internal) { - $record = (object) [ - 'issuerid' => $issuer->get('id'), - 'externalfield' => $external, - 'internalfield' => $internal - ]; - $userfieldmapping = new \core\oauth2\user_field_mapping(0, $record); - $userfieldmapping->create(); - } - return $issuer; - } - /** * Initializes a record for one of the standard issuers to be displayed in the settings. * The issuer is not yet created in the database. @@ -117,16 +49,11 @@ class api { public static function init_standard_issuer($type) { 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 == 'nextcloud') { - return self::init_nextcloud(); - } else { - $classname = self::get_service_classname($type); - if (class_exists($classname)) { - return $classname::init(); - } - throw new moodle_exception('OAuth 2 service type not recognised: ' . $type); + $classname = self::get_service_classname($type); + if (class_exists($classname)) { + return $classname::init(); } + throw new moodle_exception('OAuth 2 service type not recognised: ' . $type); } /** @@ -138,17 +65,12 @@ class api { public static function create_endpoints_for_standard_issuer($type, $issuer) { 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 == 'nextcloud') { - return self::create_endpoints_for_nextcloud($issuer); - } else { - $classname = self::get_service_classname($type); - if (class_exists($classname)) { - $classname::create_endpoints($issuer); - return $issuer; - } - throw new moodle_exception('OAuth 2 service type not recognised: ' . $type); + $classname = self::get_service_classname($type); + if (class_exists($classname)) { + $classname::create_endpoints($issuer); + return $issuer; } + throw new moodle_exception('OAuth 2 service type not recognised: ' . $type); } /** @@ -166,6 +88,10 @@ class api { if (!$baseurl) { throw new moodle_exception('IMS OBv2.1 service type requires the baseurl parameter.'); } + case 'nextcloud': + if (!$baseurl) { + throw new moodle_exception('Nextcloud service type requires the baseurl parameter.'); + } case 'google': case 'facebook': case 'microsoft': @@ -176,15 +102,6 @@ class api { } $issuer->create(); return self::create_endpoints_for_standard_issuer($type, $issuer); - - case 'nextcloud': - if (!$baseurl) { - throw new moodle_exception('Nextcloud service type requires the baseurl parameter.'); - } - $issuer = self::init_nextcloud(); - $issuer->set('baseurl', $baseurl); - $issuer->create(); - return self::create_endpoints_for_nextcloud($issuer); } throw new moodle_exception('OAuth 2 service type not recognised: ' . $type); diff --git a/lib/classes/oauth2/service/nextcloud.php b/lib/classes/oauth2/service/nextcloud.php new file mode 100644 index 00000000000..51784fa5e33 --- /dev/null +++ b/lib/classes/oauth2/service/nextcloud.php @@ -0,0 +1,100 @@ +. + +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 Nextcloud 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 nextcloud 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' => 'Nextcloud', + 'image' => 'https://nextcloud.com/wp-content/themes/next/assets/img/common/favicon.png?x16328', + 'basicauth' => 1, + 'servicetype' => 'nextcloud', + ]; + + $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 { + // Nextcloud has a custom baseurl. Thus, the creation of endpoints has to be done later. + $baseurl = $issuer->get('baseurl'); + // Add trailing slash to baseurl, if needed. + if (substr($baseurl, -1) !== '/') { + $baseurl .= '/'; + } + + $endpoints = [ + // Baseurl will be prepended later. + 'authorization_endpoint' => 'index.php/apps/oauth2/authorize', + 'token_endpoint' => 'index.php/apps/oauth2/api/v1/token', + 'userinfo_endpoint' => 'ocs/v2.php/cloud/user?format=json', + 'webdav_endpoint' => 'remote.php/webdav/', + 'ocs_endpoint' => 'ocs/v1.php/apps/files_sharing/api/v1/shares', + ]; + + foreach ($endpoints as $name => $url) { + $record = (object) [ + 'issuerid' => $issuer->get('id'), + 'name' => $name, + 'url' => $baseurl . $url, + ]; + $endpoint = new \core\oauth2\endpoint(0, $record); + $endpoint->create(); + } + + // Create the field mappings. + $mapping = [ + 'ocs-data-email' => 'email', + 'ocs-data-id' => 'username', + ]; + foreach ($mapping as $external => $internal) { + $record = (object) [ + 'issuerid' => $issuer->get('id'), + 'externalfield' => $external, + 'internalfield' => $internal + ]; + $userfieldmapping = new \core\oauth2\user_field_mapping(0, $record); + $userfieldmapping->create(); + } + return $issuer; + } +}