diff --git a/admin/tool/oauth2/tests/behat/basic_settings.feature b/admin/tool/oauth2/tests/behat/basic_settings.feature index 53e6ec12b6324..565cc356d16a5 100644 --- a/admin/tool/oauth2/tests/behat/basic_settings.feature +++ b/admin/tool/oauth2/tests/behat/basic_settings.feature @@ -151,25 +151,25 @@ Feature: Basic OAuth2 functionality | Service base URL | https://dc.imsglobal.org/ | When I press "Save changes" Then I should see "Changes saved" - And I should see "Open Badges" - And "Allow services" "icon" should exist in the "Open Badges" "table_row" - And "Do not allow login" "icon" should exist in the "Open Badges" "table_row" - And "Service discovery successful" "icon" should exist in the "Open Badges" "table_row" + And I should see "IMS Global Reference Implementation" + And I click on "Edit" "link" in the "IMS Global Reference Implementation" "table_row" + And I set the following fields to these values: + | Name | IMS Global | + And I press "Save changes" + And I should see "Changes saved" + And I should see "IMS Global" + And "Allow services" "icon" should exist in the "IMS Global" "table_row" + And "Do not allow login" "icon" should exist in the "IMS Global" "table_row" + And "Service discovery successful" "icon" should exist in the "IMS Global" "table_row" And the "src" attribute of "table.admintable th img" "css_element" should contain "IMS-Global-Logo.png" - And I click on "Configure endpoints" "link" in the "Open Badges" "table_row" + And I click on "Configure endpoints" "link" in the "IMS Global" "table_row" And I should see "https://dc.imsglobal.org/.well-known/badgeconnect.json" in the "discovery_endpoint" "table_row" And I should see "authorization_endpoint" And I navigate to "Server > OAuth 2 services" in site administration - And I click on "Configure user field mappings" "link" in the "Open Badges" "table_row" + And I click on "Configure user field mappings" "link" in the "IMS Global" "table_row" And I should not see "given_name" And I should not see "middle_name" And I navigate to "Server > OAuth 2 services" in site administration - And I click on "Edit" "link" in the "Open Badges" "table_row" - And I set the following fields to these values: - | Name | IMS Global | - And I press "Save changes" - And I should see "Changes saved" - And I should see "IMS Global" And I click on "Delete" "link" in the "IMS Global" "table_row" And I should see "Are you sure you want to delete the identity issuer \"IMS Global\"?" And I press "Continue" diff --git a/badges/classes/backpack_api2p1.php b/badges/classes/backpack_api2p1.php index 1d90b420759b0..f382908925242 100644 --- a/badges/classes/backpack_api2p1.php +++ b/badges/classes/backpack_api2p1.php @@ -36,6 +36,9 @@ use core_badges\oauth2\client; use curl; use stdClass; +use core\oauth2\issuer; +use core\oauth2\endpoint; +use core\oauth2\discovery\imsbadgeconnect; /** * To process badges with backpack and control api request and this class using for Open Badge API v2.1 methods. @@ -61,8 +64,11 @@ class backpack_api2p1 { /** @var null version api of the backpack. */ protected $backpackapiversion; - /** @var null api URL of the backpack. */ - protected $backpackapiurl = ''; + /** @var issuer The OAuth2 Issuer for this backpack */ + protected issuer $issuer; + + /** @var endpoint The apiBase endpoint */ + protected endpoint $apibase; /** * backpack_api2p1 constructor. @@ -75,7 +81,6 @@ public function __construct($externalbackpack) { if (!empty($externalbackpack)) { $this->externalbackpack = $externalbackpack; $this->backpackapiversion = $externalbackpack->apiversion; - $this->backpackapiurl = $externalbackpack->backpackapiurl; $this->get_clientid = $this->get_clientid($externalbackpack->oauth2_issuerid); if (!($this->tokendata = $this->get_stored_token($externalbackpack->id)) @@ -87,6 +92,44 @@ public function __construct($externalbackpack) { $this->define_mappings(); } + /** + * Initialises or returns the OAuth2 issuer associated to this backpack. + * + * @return issuer + */ + protected function get_issuer(): issuer { + if (!isset($this->issuer)) { + $this->issuer = new \core\oauth2\issuer($this->externalbackpack->oauth2_issuerid); + } + return $this->issuer; + } + + /** + * Gets the apiBase url associated to this backpack. + * + * @return string + */ + protected function get_api_base_url(): string { + if (!isset($this->apibase)) { + $apibase = endpoint::get_record([ + 'issuerid' => $this->externalbackpack->oauth2_issuerid, + 'name' => 'apiBase', + ]); + + if (empty($apibase)) { + imsbadgeconnect::create_endpoints($this->get_issuer()); + $apibase = endpoint::get_record([ + 'issuerid' => $this->externalbackpack->oauth2_issuerid, + 'name' => 'apiBase', + ]); + } + + $this->apibase = $apibase; + } + + return $this->apibase->get('url'); + } + /** * Define the mappings supported by this usage and api version. @@ -157,7 +200,7 @@ public function curl_request($action, $postdata = null) { foreach ($this->mappings as $mapping) { if ($mapping->is_match($action)) { return $mapping->request( - $this->backpackapiurl, + $this->get_api_base_url(), $tokenkey, $postdata ); @@ -194,6 +237,7 @@ protected function get_stored_token($externalbackpackid) { private function get_clientid($issuerid) { $issuer = \core\oauth2\api::get_issuer($issuerid); if (!empty($issuer)) { + $this->issuer = $issuer; $this->clientid = $issuer->get('clientid'); } } @@ -212,7 +256,7 @@ public function put_assertions($hash) { return false; } - $issuer = new \core\oauth2\issuer($this->externalbackpack->oauth2_issuerid); + $issuer = $this->get_issuer(); $client = new client($issuer, new moodle_url('/badges/mybadges.php'), '', $this->externalbackpack); if (!$client->is_logged_in()) { $redirecturl = new moodle_url('/badges/mybadges.php', ['error' => 'backpackexporterror']); diff --git a/lib/classes/oauth2/discovery/imsbadgeconnect.php b/lib/classes/oauth2/discovery/imsbadgeconnect.php index 2885f91b90ebc..0c8489b9ec9d3 100644 --- a/lib/classes/oauth2/discovery/imsbadgeconnect.php +++ b/lib/classes/oauth2/discovery/imsbadgeconnect.php @@ -82,6 +82,16 @@ protected static function process_configuration_json(issuer $issuer, stdClass $i $issuer->set('image', $url); $issuer->update(); } + } else if ($key == 'apiBase') { + (new endpoint(0, (object) [ + 'issuerid' => $issuer->get('id'), + 'name' => $key, + 'url' => $value, + ]))->create(); + } else if ($key == 'name') { + // Get and update issuer name. + $issuer->set('name', $value); + $issuer->update(); } } }