MDL-58090 oauth2: API to get a system client

Request an oauth client with an access token retrieved with the stored refresh token from the OAuth issuer.

Part of MDL-58220
This commit is contained in:
Damyon Wiese 2017-02-27 16:19:04 +08:00
parent ddf65b8c05
commit 237fd80cd2
2 changed files with 102 additions and 0 deletions

View File

@ -197,7 +197,50 @@ class api {
return system_account::get_record(['issuerid' => $issuer->get('id')]);
}
public static function get_system_scopes_for_issuer($issuer) {
$scopes = $issuer->get('loginscopesoffline');
$pluginsfunction = get_plugins_with_function('oauth2_system_scopes', 'lib.php');
foreach ($pluginsfunction as $plugintype => $plugins) {
foreach ($plugins as $pluginfunction) {
// Get additional scopes from the plugin.
$pluginscopes = $pluginfunction($issuer);
if (empty($pluginscopes)) {
continue;
}
// Merge the additional scopes with the existing ones.
$additionalscopes = explode(' ', $pluginscopes);
foreach ($additionalscopes as $scope) {
if (!empty($scope)) {
if (strpos(' ' . $scopes . ' ', ' ' . $scope . ' ') === false) {
$scopes .= ' ' . $scope;
}
}
}
}
}
return $scopes;
}
public static function get_system_oauth_client(issuer $issuer) {
$systemaccount = self::get_system_account($issuer);
if (empty($systemaccount)) {
return false;
}
// Get all the scopes!
$scopes = self::get_system_scopes_for_issuer($issuer);
$client = new \core\oauth2\client($issuer, null, $scopes, true);
if (!$client->is_logged_in()) {
if (!$client->update_refresh_token($systemaccount)) {
return false;
}
}
return $client;
}
public static function get_user_oauth_client(issuer $issuer, moodle_url $currenturl, $additionalscopes = '') {

View File

@ -156,6 +156,65 @@ class client extends \oauth2_client {
return $map;
}
/**
* Upgrade a refresh token from oauth 2.0 to an access token
*
* @return boolean true if token is upgraded succesfully
*/
public function upgrade_refresh_token(system_account $systemaccount) {
$refreshtoken = $systemaccount->get('refreshtoken');
$params = array('refresh_token' => $refreshtoken,
'client_id' => $this->clientid,
'client_secret' => $this->clientsecret,
'grant_type' => 'refresh_token'
);
// Requests can either use http GET or POST.
if ($this->use_http_get()) {
$response = $this->get($this->token_url(), $params);
} else {
$response = $this->post($this->token_url(), $this->build_post_data($params));
}
if (!$this->info['http_code'] === 200) {
throw new moodle_exception('Could not upgrade oauth token');
}
$r = json_decode($response);
if (!empty($r->error)) {
throw new moodle_exception($r->error . ' ' . $r->error_description);
}
if (!isset($r->access_token)) {
return false;
}
if (isset($r->refresh_token)) {
$systemaccount->set('refreshtoken', $r->refresh_token);
$systemaccount->update();
$this->refreshtoken = $r->refresh_token;
}
// Store the token an expiry time.
$accesstoken = new stdClass;
$accesstoken->token = $r->access_token;
if (isset($r->expires_in)) {
// Expires 10 seconds before actual expiry.
$accesstoken->expires = (time() + ($r->expires_in - 10));
}
if (isset($r->scope)) {
$accesstoken->scope = $r->scope;
} else {
$accesstoken->scope = $this->scope;
}
// Also add the scopes.
$this->store_token($accesstoken);
return true;
}
public function get_userinfo() {
$url = $this->get_issuer()->get_endpoint_url('userinfo');
$response = $this->get($url);