Differences Between: [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]
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 * Communicate with backpacks. 19 * 20 * @copyright 2020 Tung Thai based on Totara Learning Solutions Ltd {@link http://www.totaralms.com/} dode 21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 22 * @author Tung Thai <Tung.ThaiDuc@nashtechglobal.com> 23 */ 24 25 namespace core_badges; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 require_once($CFG->libdir . '/filelib.php'); 30 31 use cache; 32 use coding_exception; 33 use context_system; 34 use moodle_url; 35 use core_badges\backpack_api2p1_mapping; 36 use core_badges\oauth2\client; 37 use curl; 38 use stdClass; 39 40 /** 41 * To process badges with backpack and control api request and this class using for Open Badge API v2.1 methods. 42 * 43 * @package core_badges 44 * @copyright 2020 Tung Thai 45 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 46 */ 47 class backpack_api2p1 { 48 49 /** @var object is the external backpack. */ 50 private $externalbackpack; 51 52 /** @var array define api mapping. */ 53 private $mappings = []; 54 55 /** @var false|null|stdClass|\core_badges\backpack_api2p1 to */ 56 private $tokendata; 57 58 /** @var null clienid. */ 59 private $clientid = null; 60 61 /** @var null version api of the backpack. */ 62 protected $backpackapiversion; 63 64 /** @var null api URL of the backpack. */ 65 protected $backpackapiurl = ''; 66 67 /** 68 * backpack_api2p1 constructor. 69 * 70 * @param object $externalbackpack object 71 * @throws coding_exception error message 72 */ 73 public function __construct($externalbackpack) { 74 75 if (!empty($externalbackpack)) { 76 $this->externalbackpack = $externalbackpack; 77 $this->backpackapiversion = $externalbackpack->apiversion; 78 $this->backpackapiurl = $externalbackpack->backpackapiurl; 79 $this->get_clientid = $this->get_clientid($externalbackpack->oauth2_issuerid); 80 81 if (!($this->tokendata = $this->get_stored_token($externalbackpack->id)) 82 && $this->backpackapiversion != OPEN_BADGES_V2P1) { 83 throw new coding_exception('Backpack incorrect'); 84 } 85 } 86 87 $this->define_mappings(); 88 } 89 90 91 /** 92 * Define the mappings supported by this usage and api version. 93 */ 94 private function define_mappings() { 95 if ($this->backpackapiversion == OPEN_BADGES_V2P1) { 96 97 $mapping = []; 98 $mapping[] = [ 99 'post.assertions', // Action. 100 '[URL]/assertions', // URL 101 '[PARAM]', // Post params. 102 false, // Multiple. 103 'post', // Method. 104 true, // JSON Encoded. 105 true // Auth required. 106 ]; 107 108 $mapping[] = [ 109 'get.assertions', // Action. 110 '[URL]/assertions', // URL 111 '[PARAM]', // Post params. 112 false, // Multiple. 113 'get', // Method. 114 true, // JSON Encoded. 115 true // Auth required. 116 ]; 117 118 foreach ($mapping as $map) { 119 $map[] = false; // Site api function. 120 $map[] = OPEN_BADGES_V2P1; // V2 function. 121 $this->mappings[] = new backpack_api2p1_mapping(...$map); 122 } 123 124 } 125 } 126 127 /** 128 * Disconnect the backpack from this user. 129 * 130 * @param object $backpack to disconnect. 131 * @return bool 132 * @throws \dml_exception 133 */ 134 public function disconnect_backpack($backpack) { 135 global $USER, $DB; 136 137 if ($backpack) { 138 $DB->delete_records_select('badge_external', 'backpackid = :backpack', ['backpack' => $backpack->id]); 139 $DB->delete_records('badge_backpack', ['id' => $backpack->id]); 140 $DB->delete_records('badge_backpack_oauth2', ['externalbackpackid' => $this->externalbackpack->id, 141 'userid' => $USER->id]); 142 143 return true; 144 } 145 return false; 146 } 147 148 /** 149 * Make an api request. 150 * 151 * @param string $action The api function. 152 * @param string $postdata The body of the api request. 153 * @return mixed 154 */ 155 public function curl_request($action, $postdata = null) { 156 $tokenkey = $this->tokendata->token; 157 foreach ($this->mappings as $mapping) { 158 if ($mapping->is_match($action)) { 159 return $mapping->request( 160 $this->backpackapiurl, 161 $tokenkey, 162 $postdata 163 ); 164 } 165 } 166 167 throw new coding_exception('Unknown request'); 168 } 169 170 /** 171 * Get token. 172 * 173 * @param int $externalbackpackid ID of external backpack. 174 * @return oauth2\badge_backpack_oauth2|false|stdClass|null 175 */ 176 protected function get_stored_token($externalbackpackid) { 177 global $USER; 178 179 $token = \core_badges\oauth2\badge_backpack_oauth2::get_record( 180 ['externalbackpackid' => $externalbackpackid, 'userid' => $USER->id]); 181 if ($token !== false) { 182 $token = $token->to_record(); 183 return $token; 184 } 185 return null; 186 } 187 188 /** 189 * Get client id. 190 * 191 * @param int $issuerid id of Oauth2 service. 192 * @throws coding_exception 193 */ 194 private function get_clientid($issuerid) { 195 $issuer = \core\oauth2\api::get_issuer($issuerid); 196 if (!empty($issuer)) { 197 $this->clientid = $issuer->get('clientid'); 198 } 199 } 200 201 /** 202 * Export a badge to the backpack site. 203 * 204 * @param string $hash of badge issued. 205 * @return array 206 * @throws \moodle_exception 207 * @throws coding_exception 208 */ 209 public function put_assertions($hash) { 210 $data = []; 211 if (!$hash) { 212 return false; 213 } 214 215 $issuer = new \core\oauth2\issuer($this->externalbackpack->oauth2_issuerid); 216 $client = new client($issuer, new moodle_url('/badges/mybadges.php'), '', $this->externalbackpack); 217 if (!$client->is_logged_in()) { 218 $redirecturl = new moodle_url('/badges/mybadges.php', ['error' => 'backpackexporterror']); 219 redirect($redirecturl); 220 } 221 222 $this->tokendata = $this->get_stored_token($this->externalbackpack->id); 223 224 $assertion = new \core_badges_assertion($hash, OPEN_BADGES_V2); 225 $data['assertion'] = $assertion->get_badge_assertion(); 226 $response = $this->curl_request('post.assertions', $data); 227 if ($response && isset($response->status->statusCode) && $response->status->statusCode == 200) { 228 $msg['status'] = \core\output\notification::NOTIFY_SUCCESS; 229 $msg['message'] = get_string('addedtobackpack', 'badges'); 230 } else { 231 $msg['status'] = \core\output\notification::NOTIFY_ERROR; 232 $msg['message'] = get_string('backpackexporterror', 'badges', $data['assertion']['badge']['name']); 233 } 234 return $msg; 235 } 236 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body