MDL-58943 oauth2: Split issuer initialization from endpoint creation

* Splitted the initialization of default values for issuers, the
creation of the issuer, and the creation of its endpoints. This is
a fix for following use case:
 1. A user creates a standard issuer.
 2. She cancels the form.
 3. However, the issuer was already created. Thus, the cancel had no
effect.
* The function create_standard_issuer($type) can still be used to create
issuers programmatically if all required data is known beforehand (e.g.,
during upgrade or in tests).
This commit is contained in:
Tobias Reischmann
2018-10-31 10:42:57 +08:00
committed by Damyon Wiese
parent f6df2a884e
commit fa6cd89b24
3 changed files with 154 additions and 20 deletions
+42 -3
View File
@@ -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);
+25 -4
View File
@@ -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();
+87 -13
View File
@@ -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[]