diff --git a/admin/tool/oauth2/classes/form/issuer.php b/admin/tool/oauth2/classes/form/issuer.php index 23874bb2042..0b63271a940 100644 --- a/admin/tool/oauth2/classes/form/issuer.php +++ b/admin/tool/oauth2/classes/form/issuer.php @@ -41,7 +41,38 @@ class issuer extends persistent { protected static $persistentclass = 'core\\oauth2\\issuer'; /** @var array $fieldstoremove */ - protected static $fieldstoremove = array('submitbutton', 'action'); + protected static $fieldstoremove = array('type', 'submitbutton', 'action'); + + /** @var string $type */ + protected $type; + + /** + * Constructor. + * + * The 'persistent' has to be passed as custom data when 'editing'. + * If a standard issuer is created the type can be passed as custom data, which alters the form according to the + * type. + * + * Note that in order for your persistent to be reloaded after form submission you should + * either override the URL to include the ID to your resource, or add the ID to the form + * fields. + * + * @param mixed $action + * @param mixed $customdata + * @param string $method + * @param string $target + * @param mixed $attributes + * @param bool $editable + * @param array $ajaxformdata + */ + public function __construct($action = null, $customdata = null, $method = 'post', $target = '', $attributes = null, + $editable = true, array $ajaxformdata = null) { + // The type variable defines, if we are in the creation process of a standard issuer. + if (array_key_exists('type', $customdata)) { + $this->type = $customdata['type']; + } + parent::__construct($action, $customdata, $method, $target, $attributes, $editable, $ajaxformdata); + } /** * Define the form - called by parent constructor @@ -130,8 +161,16 @@ class issuer extends persistent { $mform->addElement('hidden', 'sortorder'); $mform->setType('sortorder', PARAM_INT); - $mform->addElement('hidden', 'action', 'edit'); - $mform->setType('action', PARAM_ALPHA); + if ($this->type) { + $mform->addElement('hidden', 'action', 'savetemplate'); + $mform->setType('action', PARAM_ALPHA); + + $mform->addElement('hidden', 'type', $this->_customdata['type']); + $mform->setType('type', PARAM_ALPHA); + } else { + $mform->addElement('hidden', 'action', 'edit'); + $mform->setType('action', PARAM_ALPHA); + } $mform->addElement('hidden', 'enabled', $issuer->get('enabled')); $mform->setType('enabled', PARAM_BOOL); diff --git a/admin/tool/oauth2/issuers.php b/admin/tool/oauth2/issuers.php index 5bb4c4f9dc9..bc59186809f 100644 --- a/admin/tool/oauth2/issuers.php +++ b/admin/tool/oauth2/issuers.php @@ -86,15 +86,36 @@ if ($mform && $mform->is_cancelled()) { $mform->display(); echo $OUTPUT->footer(); } +} else if ($action == 'savetemplate') { + + $type = required_param('type', PARAM_ALPHA); + $mform = new \tool_oauth2\form\issuer(null, ['persistent' => $issuer, 'type' => $type]); + if ($mform->is_cancelled()) { + redirect(new moodle_url('/admin/tool/oauth2/issuers.php')); + } + if ($mform->is_submitted() && $data = $mform->get_data()) { + $issuer = new core\oauth2\issuer(0, $data); + $issuer->create(); + $issuer = core\oauth2\api::create_endpoints_for_standard_issuer($type, $issuer); + redirect($PAGE->url, get_string('changessaved'), null, \core\output\notification::NOTIFY_SUCCESS); + } else { + echo $OUTPUT->header(); + $mform->display(); + echo $OUTPUT->footer(); + } + } else if ($action == 'edittemplate') { $type = required_param('type', PARAM_ALPHA); $docs = required_param('docslink', PARAM_ALPHAEXT); require_sesskey(); - $issuer = core\oauth2\api::create_standard_issuer($type); - $params = ['action' => 'edit', 'id' => $issuer->get('id'), 'docslink' => $docs]; - $editurl = new moodle_url('/admin/tool/oauth2/issuers.php', $params); - redirect($editurl, get_string('changessaved'), null, \core\output\notification::NOTIFY_SUCCESS); + $issuer = core\oauth2\api::init_standard_issuer($type); + $mform = new \tool_oauth2\form\issuer(null, ['persistent' => $issuer, 'type' => $type]); + + echo $OUTPUT->header(); + $mform->display(); + echo $OUTPUT->footer(); + } else if ($action == 'enable') { require_sesskey(); diff --git a/lib/classes/oauth2/api.php b/lib/classes/oauth2/api.php index 6c39562e996..4a4c12a0f6c 100644 --- a/lib/classes/oauth2/api.php +++ b/lib/classes/oauth2/api.php @@ -43,10 +43,10 @@ use moodle_url; class api { /** - * Create a google ready OAuth 2 service. + * Build a google ready OAuth 2 service. * @return \core\oauth2\issuer */ - private static function create_google() { + private static function init_google() { $record = (object) [ 'name' => 'Google', 'image' => 'https://accounts.google.com/favicon.ico', @@ -56,7 +56,17 @@ class api { ]; $issuer = new issuer(0, $record); - $issuer->create(); + return $issuer; + } + + /** + * Create endpoints for google issuers. + * @param issuer $issuer issuer the endpoints should be created for. + * @return mixed + * @throws \coding_exception + * @throws \core\invalid_persistent_exception + */ + private static function create_endpoints_for_google($issuer) { $record = (object) [ 'issuerid' => $issuer->get('id'), @@ -69,10 +79,10 @@ class api { } /** - * Create a facebook ready OAuth 2 service. + * Build a facebook ready OAuth 2 service. * @return \core\oauth2\issuer */ - private static function create_facebook() { + private static function init_facebook() { // Facebook is a custom setup. $record = (object) [ 'name' => 'Facebook', @@ -84,8 +94,17 @@ class api { ]; $issuer = new issuer(0, $record); - $issuer->create(); + return $issuer; + } + /** + * Create endpoints for facebook issuers. + * @param issuer $issuer issuer the endpoints should be created for. + * @return mixed + * @throws \coding_exception + * @throws \core\invalid_persistent_exception + */ + private static function create_endpoints_for_facebook($issuer) { // The Facebook API version. $apiversion = '2.12'; // The Graph API URL. @@ -138,10 +157,10 @@ class api { } /** - * Create a microsoft ready OAuth 2 service. + * Build a microsoft ready OAuth 2 service. * @return \core\oauth2\issuer */ - private static function create_microsoft() { + private static function init_microsoft() { // Microsoft is a custom setup. $record = (object) [ 'name' => 'Microsoft', @@ -153,7 +172,17 @@ class api { ]; $issuer = new issuer(0, $record); - $issuer->create(); + return $issuer; + } + + /** + * Create endpoints for microsoft issuers. + * @param issuer $issuer issuer the endpoints should be created for. + * @return mixed + * @throws \coding_exception + * @throws \core\invalid_persistent_exception + */ + private static function create_endpoints_for_microsoft($issuer) { $endpoints = [ 'authorization_endpoint' => 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize', @@ -195,23 +224,68 @@ class api { } /** - * Create one of the standard issuers. + * Initializes a record for one of the standard issuers to be displayed in the settings. + * The issuer is not yet created in the database. * @param string $type One of google, facebook, microsoft * @return \core\oauth2\issuer */ + public static function init_standard_issuer($type) { + require_capability('moodle/site:config', context_system::instance()); + if ($type == 'google') { + return self::init_google(); + } else if ($type == 'microsoft') { + return self::init_microsoft(); + } else if ($type == 'facebook') { + return self::init_facebook(); + } else { + throw new moodle_exception('OAuth 2 service type not recognised: ' . $type); + } + } + + /** + * Create endpoints for standard issuers, based on the issuer created from submitted data. + * @param string $type One of google, facebook, microsoft + * @param issuer $issuer issuer the endpoints should be created for. + * @return \core\oauth2\issuer + */ + public static function create_endpoints_for_standard_issuer($type, $issuer) { + require_capability('moodle/site:config', context_system::instance()); + if ($type == 'google') { + return self::create_endpoints_for_google($issuer); + } else if ($type == 'microsoft') { + return self::create_endpoints_for_microsoft($issuer); + } else if ($type == 'facebook') { + return self::create_endpoints_for_facebook($issuer); + } else { + throw new moodle_exception('OAuth 2 service type not recognised: ' . $type); + } + } + + /** + * Create one of the standard issuers. + * @param string $type One of google, facebook, or microsoft + * @return \core\oauth2\issuer + */ public static function create_standard_issuer($type) { require_capability('moodle/site:config', context_system::instance()); if ($type == 'google') { - return self::create_google(); + $issuer = self::init_google(); + $issuer->create(); + return self::create_endpoints_for_google($issuer); } else if ($type == 'microsoft') { - return self::create_microsoft(); + $issuer = self::init_microsoft(); + $issuer->create(); + return self::create_endpoints_for_microsoft($issuer); } else if ($type == 'facebook') { - return self::create_facebook(); + $issuer = self::init_facebook(); + $issuer->create(); + return self::create_endpoints_for_facebook($issuer); } else { throw new moodle_exception('OAuth 2 service type not recognised: ' . $type); } } + /** * List all the issuers, ordered by the sortorder field * @return \core\oauth2\issuer[]