See Release Notes
Long Term Support Release
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 namespace core\oauth2\discovery; 18 19 use curl; 20 use stdClass; 21 use moodle_exception; 22 use core\oauth2\issuer; 23 use core\oauth2\endpoint; 24 25 /** 26 * Class for provider discovery definition, to allow services easily discover and process information. 27 * This abstract class is called from core\oauth2\api when discovery points need to be updated. 28 * 29 * @package core 30 * @since Moodle 3.11 31 * @copyright 2021 Sara Arjona (sara@moodle.com) 32 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 33 */ 34 abstract class base_definition { 35 36 /** 37 * Get the URL for the discovery manifest. 38 * 39 * @param issuer $issuer The OAuth issuer the endpoints should be discovered for. 40 * @return string The URL of the discovery file, containing the endpoints. 41 */ 42 public abstract static function get_discovery_endpoint_url(issuer $issuer): string; 43 44 /** 45 * Process the discovery information and create endpoints defined with the expected format. 46 * 47 * @param issuer $issuer The OAuth issuer the endpoints should be discovered for. 48 * @param stdClass $info The discovery information, with the endpoints to process and create. 49 * @return void 50 */ 51 protected abstract static function process_configuration_json(issuer $issuer, stdClass $info): void; 52 53 /** 54 * Process how to map user field information. 55 * 56 * @param issuer $issuer The OAuth issuer the endpoints should be discovered for. 57 * @return void 58 */ 59 protected abstract static function create_field_mappings(issuer $issuer): void; 60 61 /** 62 * Self-register the issuer if the 'registration' endpoint exists and client id and secret aren't defined. 63 * 64 * @param issuer $issuer The OAuth issuer to register. 65 * @return void 66 */ 67 protected abstract static function register(issuer $issuer): void; 68 69 /** 70 * Create endpoints for this issuer. 71 * 72 * @param issuer $issuer Issuer the endpoints should be created for. 73 * @return issuer 74 */ 75 public static function create_endpoints(issuer $issuer): issuer { 76 static::discover_endpoints($issuer); 77 78 return $issuer; 79 } 80 81 /** 82 * If the discovery endpoint exists for this issuer, try and determine the list of valid endpoints. 83 * 84 * @param issuer $issuer 85 * @return int The number of discovered services. 86 */ 87 public static function discover_endpoints($issuer): int { 88 // Early return if baseurl is empty. 89 if (empty($issuer->get('baseurl'))) { 90 return 0; 91 } 92 93 // Get the discovery URL and check if it has changed. 94 $creatediscoveryendpoint = false; 95 $url = $issuer->get_endpoint_url('discovery'); 96 $providerurl = static::get_discovery_endpoint_url($issuer); 97 if (!$url || $url != $providerurl) { 98 $url = $providerurl; 99 $creatediscoveryendpoint = true; 100 } 101 102 // Remove the existing endpoints before starting discovery. 103 foreach (endpoint::get_records(['issuerid' => $issuer->get('id')]) as $endpoint) { 104 // Discovery endpoint will be removed only if it will be created later, once we confirm it's working as expected. 105 if ($creatediscoveryendpoint || $endpoint->get('name') != 'discovery_endpoint') { 106 $endpoint->delete(); 107 } 108 } 109 110 // Early return if discovery URL is empty. 111 if (empty($url)) { 112 return 0; 113 } 114 115 $curl = new curl(); 116 if (!$json = $curl->get($url)) { 117 $msg = 'Could not discover end points for identity issuer: ' . $issuer->get('name') . " [URL: $url]"; 118 throw new moodle_exception($msg); 119 } 120 121 if ($msg = $curl->error) { 122 throw new moodle_exception('Could not discover service endpoints: ' . $msg); 123 } 124 125 $info = json_decode($json); 126 if (empty($info)) { 127 $msg = 'Could not discover end points for identity issuer: ' . $issuer->get('name') . " [URL: $url]"; 128 throw new moodle_exception($msg); 129 } 130 131 if ($creatediscoveryendpoint) { 132 // Create the discovery endpoint (because it didn't exist and the URL exists and is returning some valid JSON content). 133 static::create_discovery_endpoint($issuer, $url); 134 } 135 136 static::process_configuration_json($issuer, $info); 137 static::create_field_mappings($issuer); 138 static::register($issuer); 139 140 return endpoint::count_records(['issuerid' => $issuer->get('id')]); 141 } 142 143 /** 144 * Helper method to create discovery endpoint. 145 * 146 * @param issuer $issuer Issuer the endpoints should be created for. 147 * @param string $url Discovery endpoint URL. 148 * @return endpoint The endpoint created. 149 * 150 * @throws \core\invalid_persistent_exception 151 */ 152 protected static function create_discovery_endpoint(issuer $issuer, string $url): endpoint { 153 $record = (object) [ 154 'issuerid' => $issuer->get('id'), 155 'name' => 'discovery_endpoint', 156 'url' => $url, 157 ]; 158 $endpoint = new endpoint(0, $record); 159 $endpoint->create(); 160 161 return $endpoint; 162 } 163 164 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body