MDL-80332 tool_mobile: Fallback por app launches
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace tool_mobile\local\hooks\user;
|
||||
|
||||
/**
|
||||
* Handles mobile app launches when a third-party auth plugin did not properly set $SESSION->wantsurl.
|
||||
*
|
||||
* @package tool_mobile
|
||||
* @copyright 2024 Juan Leyva
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class after_complete_login {
|
||||
|
||||
/**
|
||||
* Callback to recover $SESSION->wantsurl.
|
||||
*
|
||||
* @param \core\hook\user\after_complete_login $hook
|
||||
*/
|
||||
public static function callback(\core\hook\user\after_complete_login $hook): void {
|
||||
global $SESSION, $CFG;
|
||||
|
||||
// Check if the user is doing a mobile app launch, if that's the case, ensure $SESSION->wantsurl is correctly set.
|
||||
if (!NO_MOODLE_COOKIES && !empty($_COOKIE['tool_mobile_launch'])) {
|
||||
if (empty($SESSION->wantsurl) || strpos($SESSION->wantsurl, '/tool/mobile/launch.php') === false) {
|
||||
|
||||
$params = json_decode($_COOKIE['tool_mobile_launch'], true);
|
||||
$SESSION->wantsurl = (new \moodle_url("/$CFG->admin/tool/mobile/launch.php", $params))->out(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace tool_mobile\local\hooks\user;
|
||||
|
||||
/**
|
||||
* Handles mobile app launches when third-party auth plugins are put in front of MFA.
|
||||
*
|
||||
* @package tool_mobile
|
||||
* @copyright 2024 Juan Leyva
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class after_user_passed_mfa {
|
||||
|
||||
/**
|
||||
* Callback to recover $SESSION->wantsurl.
|
||||
*
|
||||
* @param \tool_mfa\hook\after_user_passed_mfa $hook
|
||||
*/
|
||||
public static function callback(\tool_mfa\hook\after_user_passed_mfa $hook): void {
|
||||
global $SESSION, $CFG;
|
||||
|
||||
// Check if the user is doing a mobile app launch, if that's the case, ensure $SESSION->wantsurl is correctly set.
|
||||
if (!NO_MOODLE_COOKIES && !empty($_COOKIE['tool_mobile_launch'])) {
|
||||
if (empty($SESSION->wantsurl) || strpos($SESSION->wantsurl, '/tool/mobile/launch.php') === false) {
|
||||
|
||||
$params = json_decode($_COOKIE['tool_mobile_launch'], true);
|
||||
$SESSION->wantsurl = (new \moodle_url("/$CFG->admin/tool/mobile/launch.php", $params))->out(false);
|
||||
$SESSION->tool_mfa_has_been_redirected = true; // Indicate MFA that they need to follow $SESSION->wantsurl.
|
||||
}
|
||||
// Invalidate cookie as we won't be needing it anymore.
|
||||
unset($_COOKIE['tool_mobile_launch']);
|
||||
if (!headers_sent()) { // Just be very cautios as this is a critical code.
|
||||
setcookie('tool_mobile_launch', '', -1, $CFG->sessioncookiepath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Hook callbacks for Moodle app tools
|
||||
*
|
||||
* @package tool_mobile
|
||||
* @copyright 2024 Juan Leyva
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$callbacks = [
|
||||
[
|
||||
'hook' => core\hook\user\after_complete_login::class,
|
||||
'callback' => 'tool_mobile\local\hooks\user\after_complete_login::callback',
|
||||
'priority' => 500,
|
||||
],
|
||||
[
|
||||
'hook' => tool_mfa\hook\after_user_passed_mfa::class,
|
||||
'callback' => 'tool_mobile\local\hooks\user\after_user_passed_mfa::callback',
|
||||
'priority' => 500,
|
||||
],
|
||||
];
|
||||
@@ -44,6 +44,18 @@ if (!$CFG->enablewebservices) {
|
||||
throw new moodle_exception('enablewsdescription', 'webservice');
|
||||
}
|
||||
|
||||
// Check if the service exists and is enabled.
|
||||
$service = $DB->get_record('external_services', ['shortname' => $serviceshortname, 'enabled' => 1]);
|
||||
if (empty($service)) {
|
||||
throw new moodle_exception('servicenotavailable', 'webservice');
|
||||
}
|
||||
|
||||
// Set a cookie indicating that there was a launch to authenticate via the site from the app.
|
||||
$ldata = json_encode(['service' => $serviceshortname, 'passport' => $passport,
|
||||
'urlscheme' => $urlscheme, 'confirmed' => (int) $confirmed, 'oauthsso' => $oauthsso]);
|
||||
$expires = time() + (15 * MINSECS); // 15 minutes for authentication should be enough.
|
||||
setcookie('tool_mobile_launch', $ldata, $expires, $CFG->sessioncookiepath, $CFG->sessioncookiedomain);
|
||||
|
||||
// We have been requested to start a SSO process via OpenID.
|
||||
if (!empty($oauthsso) && is_enabled_auth('oauth2')) {
|
||||
$wantsurl = new moodle_url('/admin/tool/mobile/launch.php',
|
||||
@@ -63,17 +75,15 @@ if (empty($SESSION->justloggedin) &&
|
||||
throw new moodle_exception('pluginnotenabledorconfigured', 'tool_mobile');
|
||||
}
|
||||
|
||||
// Check if the service exists and is enabled.
|
||||
$service = $DB->get_record('external_services', array('shortname' => $serviceshortname, 'enabled' => 1));
|
||||
if (empty($service)) {
|
||||
throw new moodle_exception('servicenotavailable', 'webservice');
|
||||
}
|
||||
|
||||
require_login(0, false);
|
||||
|
||||
// Require an active user: not guest, not suspended.
|
||||
core_user::require_active_user($USER);
|
||||
|
||||
// Remove cookie.
|
||||
unset($_COOKIE['tool_mobile_launch']);
|
||||
setcookie('tool_mobile_launch', '', -1, $CFG->sessioncookiepath);
|
||||
|
||||
// Get an existing token or create a new one.
|
||||
$timenow = time();
|
||||
$token = \core_external\util::generate_token_for_current_user($service);
|
||||
@@ -126,7 +136,7 @@ if ($confirmed or $isios) {
|
||||
}
|
||||
|
||||
$notice = get_string('clickheretolaunchtheapp', 'tool_mobile');
|
||||
echo html_writer::link($location, $notice, array('id' => 'launchapp'));
|
||||
echo $OUTPUT->box(html_writer::link($location, $notice, ['id' => 'launchapp']), 'generalbox warning centerpara');
|
||||
echo html_writer::script(
|
||||
"window.onload = function() {
|
||||
document.getElementById('launchapp').click();
|
||||
|
||||
@@ -506,7 +506,7 @@ class component_test extends advanced_testcase {
|
||||
$this->assertCount(5, core_component::get_component_classes_in_namespace('core_user', 'output\\myprofile'));
|
||||
|
||||
// Without namespace it returns classes/ classes.
|
||||
$this->assertCount(5, core_component::get_component_classes_in_namespace('tool_mobile', ''));
|
||||
$this->assertCount(7, core_component::get_component_classes_in_namespace('tool_mobile', ''));
|
||||
$this->assertCount(2, core_component::get_component_classes_in_namespace('tool_filetypes'));
|
||||
|
||||
// When no component is specified, classes are returned for the namespace in all components.
|
||||
|
||||
Reference in New Issue
Block a user