See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 39 and 401]
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 /** 18 * Class for loading/storing issuers from the DB. 19 * 20 * @package core 21 * @copyright 2017 Damyon Wiese 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 namespace core\oauth2; 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 use core\persistent; 29 use lang_string; 30 31 /** 32 * Class for loading/storing issuer from the DB 33 * 34 * @copyright 2017 Damyon Wiese 35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 36 */ 37 class issuer extends persistent { 38 39 /** @var int Issuer is displayed on both login page and in the services lists */ 40 const EVERYWHERE = 1; 41 /** @var int Issuer is displayed on the login page only */ 42 const LOGINONLY = 2; 43 /** @var int Issuer is displayed only in the services lists and can not be used for login */ 44 const SERVICEONLY = 0; 45 46 const TABLE = 'oauth2_issuer'; 47 48 /** 49 * Return the definition of the properties of this model. 50 * 51 * @return array 52 */ 53 protected static function define_properties() { 54 return array( 55 'name' => array( 56 'type' => PARAM_TEXT 57 ), 58 'image' => array( 59 'type' => PARAM_URL, 60 'null' => NULL_ALLOWED, 61 'default' => null 62 ), 63 'clientid' => array( 64 'type' => PARAM_RAW_TRIMMED, 65 'default' => '' 66 ), 67 'clientsecret' => array( 68 'type' => PARAM_RAW_TRIMMED, 69 'default' => '' 70 ), 71 'baseurl' => array( 72 'type' => PARAM_URL, 73 'default' => '' 74 ), 75 'enabled' => array( 76 'type' => PARAM_BOOL, 77 'default' => true 78 ), 79 'showonloginpage' => array( 80 'type' => PARAM_INT, 81 'default' => self::SERVICEONLY, 82 ), 83 'basicauth' => array( 84 'type' => PARAM_BOOL, 85 'default' => false 86 ), 87 'scopessupported' => array( 88 'type' => PARAM_RAW, 89 'null' => NULL_ALLOWED, 90 'default' => null 91 ), 92 'loginscopes' => array( 93 'type' => PARAM_RAW, 94 'default' => 'openid profile email' 95 ), 96 'loginscopesoffline' => array( 97 'type' => PARAM_RAW, 98 'default' => 'openid profile email' 99 ), 100 'loginparams' => array( 101 'type' => PARAM_RAW, 102 'default' => '' 103 ), 104 'loginparamsoffline' => array( 105 'type' => PARAM_RAW, 106 'default' => '' 107 ), 108 'alloweddomains' => array( 109 'type' => PARAM_RAW, 110 'default' => '' 111 ), 112 'sortorder' => array( 113 'type' => PARAM_INT, 114 'default' => 0, 115 ), 116 'requireconfirmation' => array( 117 'type' => PARAM_BOOL, 118 'default' => true 119 ), 120 'servicetype' => array( 121 'type' => PARAM_ALPHANUM, 122 'null' => NULL_ALLOWED, 123 'default' => null, 124 ), 125 'loginpagename' => array( 126 'type' => PARAM_TEXT, 127 'null' => NULL_ALLOWED, 128 'default' => null, 129 ), 130 ); 131 } 132 133 /** 134 * Hook to execute before validate. 135 * 136 * @return void 137 */ 138 protected function before_validate() { 139 if (($this->get('id') && $this->get('sortorder') === null) || !$this->get('id')) { 140 $this->set('sortorder', $this->count_records()); 141 } 142 } 143 144 /** 145 * Helper the get a named service endpoint. 146 * @param string $type 147 * @return string|false 148 */ 149 public function get_endpoint_url($type) { 150 $endpoint = endpoint::get_record([ 151 'issuerid' => $this->get('id'), 152 'name' => $type . '_endpoint' 153 ]); 154 155 if ($endpoint) { 156 return $endpoint->get('url'); 157 } 158 return false; 159 } 160 161 /** 162 * Perform matching against the list of allowed login domains for this issuer. 163 * 164 * @param string $email The email to check. 165 * @return boolean 166 */ 167 public function is_valid_login_domain($email) { 168 if (empty($this->get('alloweddomains'))) { 169 return true; 170 } 171 172 $validdomains = explode(',', $this->get('alloweddomains')); 173 174 $parts = explode('@', $email, 2); 175 $emaildomain = ''; 176 if (count($parts) > 1) { 177 $emaildomain = $parts[1]; 178 } 179 180 return \core\ip_utils::is_domain_in_allowed_list($emaildomain, $validdomains); 181 } 182 183 /** 184 * Does this OAuth service support user authentication? 185 * @return boolean 186 */ 187 public function is_authentication_supported() { 188 debugging('Method is_authentication_supported() is deprecated, please use is_available_for_login()', 189 DEBUG_DEVELOPER); 190 return (!empty($this->get_endpoint_url('userinfo'))); 191 } 192 193 /** 194 * Is this issue fully configured and enabled and can be used for login/signup 195 * 196 * @return bool 197 * @throws \coding_exception 198 */ 199 public function is_available_for_login(): bool { 200 return $this->get('id') && 201 $this->is_configured() && 202 $this->get('showonloginpage') != self::SERVICEONLY && 203 $this->get('enabled') && 204 !empty($this->get_endpoint_url('userinfo')); 205 } 206 207 /** 208 * Return true if this issuer looks like it has been configured. 209 * 210 * @return boolean 211 */ 212 public function is_configured() { 213 return (!empty($this->get('clientid')) && !empty($this->get('clientsecret'))); 214 } 215 216 /** 217 * Do we have a refresh token for a system account? 218 * @return boolean 219 */ 220 public function is_system_account_connected() { 221 if (!$this->is_configured()) { 222 return false; 223 } 224 $sys = system_account::get_record(['issuerid' => $this->get('id')]); 225 if (empty($sys) || empty($sys->get('refreshtoken'))) { 226 return false; 227 } 228 229 $scopes = api::get_system_scopes_for_issuer($this); 230 231 $grantedscopes = $sys->get('grantedscopes'); 232 233 $scopes = explode(' ', $scopes); 234 235 foreach ($scopes as $scope) { 236 if (!empty($scope)) { 237 if (strpos(' ' . $grantedscopes . ' ', ' ' . $scope . ' ') === false) { 238 // We have not been granted all the scopes that are required. 239 return false; 240 } 241 } 242 } 243 244 return true; 245 } 246 247 /** 248 * Custom validator for end point URLs. 249 * Because we send Bearer tokens we must ensure SSL. 250 * 251 * @param string $value The value to check. 252 * @return lang_string|boolean 253 */ 254 protected function validate_baseurl($value) { 255 global $CFG; 256 include_once($CFG->dirroot . '/lib/validateurlsyntax.php'); 257 if (!empty($value) && !validateUrlSyntax($value, 'S+')) { 258 return new lang_string('sslonlyaccess', 'error'); 259 } 260 return true; 261 } 262 263 /** 264 * Display name for the issuers used on the login page 265 * 266 * @return string 267 */ 268 public function get_display_name(): string { 269 return $this->get('loginpagename') ? $this->get('loginpagename') : $this->get('name'); 270 } 271 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body