mirror of
https://github.com/moodle/moodle.git
synced 2025-08-06 09:26:35 +02:00
MDL-61477 admin: sitepolicy handler API
- Define sitepolicy handler manager class, base class and the core handler - Allow to set a plugin as sitepolicyhandler that implements the sitepolicy API - Modify web services to return information from the 3rd party handler instead of core if needed
This commit is contained in:
parent
94e7b022c7
commit
aef659d1e2
24 changed files with 919 additions and 120 deletions
|
@ -123,43 +123,6 @@ if ($hassiteconfig) {
|
|||
$temp->add($setting);
|
||||
$ADMIN->add('authsettings', $temp);
|
||||
|
||||
$options = array(
|
||||
0 => get_string('no'),
|
||||
1 => get_string('yes')
|
||||
);
|
||||
$url = new moodle_url('/admin/settings.php?section=supportcontact');
|
||||
$url = $url->out();
|
||||
$setting = new admin_setting_configselect('agedigitalconsentverification',
|
||||
new lang_string('agedigitalconsentverification', 'admin'),
|
||||
new lang_string('agedigitalconsentverification_desc', 'admin', $url), 0, $options);
|
||||
$setting->set_force_ltr(true);
|
||||
$temp->add($setting);
|
||||
|
||||
$setting = new admin_setting_agedigitalconsentmap('agedigitalconsentmap',
|
||||
new lang_string('ageofdigitalconsentmap', 'admin'),
|
||||
new lang_string('ageofdigitalconsentmap_desc', 'admin'),
|
||||
// See {@link https://gdpr-info.eu/art-8-gdpr/}.
|
||||
implode(PHP_EOL, [
|
||||
'*, 16',
|
||||
'AT, 14',
|
||||
'CZ, 13',
|
||||
'DE, 14',
|
||||
'DK, 13',
|
||||
'ES, 13',
|
||||
'FI, 15',
|
||||
'GB, 13',
|
||||
'HU, 14',
|
||||
'IE, 13',
|
||||
'LT, 16',
|
||||
'LU, 16',
|
||||
'NL, 16',
|
||||
'PL, 13',
|
||||
'SE, 13',
|
||||
]),
|
||||
PARAM_RAW
|
||||
);
|
||||
$temp->add($setting);
|
||||
|
||||
$temp = new admin_externalpage('authtestsettings', get_string('testsettings', 'core_auth'), new moodle_url("/auth/test_settings.php"), 'moodle/site:config', true);
|
||||
$ADMIN->add('authsettings', $temp);
|
||||
|
||||
|
|
80
admin/settings/privacy.php
Normal file
80
admin/settings/privacy.php
Normal file
|
@ -0,0 +1,80 @@
|
|||
<?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/>.
|
||||
|
||||
/**
|
||||
* Adds privacy and policies links to admin tree.
|
||||
*
|
||||
* @package core_privacy
|
||||
* @copyright 2018 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
if ($hassiteconfig) {
|
||||
// Privacy settings.
|
||||
$temp = new admin_settingpage('privacysettings', new lang_string('privacysettings', 'admin'));
|
||||
|
||||
$options = array(
|
||||
0 => get_string('no'),
|
||||
1 => get_string('yes')
|
||||
);
|
||||
$url = new moodle_url('/admin/settings.php?section=supportcontact');
|
||||
$url = $url->out();
|
||||
$setting = new admin_setting_configselect('agedigitalconsentverification',
|
||||
new lang_string('agedigitalconsentverification', 'admin'),
|
||||
new lang_string('agedigitalconsentverification_desc', 'admin', $url), 0, $options);
|
||||
$setting->set_force_ltr(true);
|
||||
$temp->add($setting);
|
||||
|
||||
$setting = new admin_setting_agedigitalconsentmap('agedigitalconsentmap',
|
||||
new lang_string('ageofdigitalconsentmap', 'admin'),
|
||||
new lang_string('ageofdigitalconsentmap_desc', 'admin'),
|
||||
// See {@link https://gdpr-info.eu/art-8-gdpr/}.
|
||||
implode(PHP_EOL, [
|
||||
'*, 16',
|
||||
'AT, 14',
|
||||
'CZ, 13',
|
||||
'DE, 14',
|
||||
'DK, 13',
|
||||
'ES, 13',
|
||||
'FI, 15',
|
||||
'GB, 13',
|
||||
'HU, 14',
|
||||
'IE, 13',
|
||||
'LT, 16',
|
||||
'LU, 16',
|
||||
'NL, 16',
|
||||
'PL, 13',
|
||||
'SE, 13',
|
||||
]),
|
||||
PARAM_RAW
|
||||
);
|
||||
$temp->add($setting);
|
||||
|
||||
$ADMIN->add('privacy', $temp);
|
||||
|
||||
// Policy settings.
|
||||
$temp = new admin_settingpage('policysettings', new lang_string('policysettings', 'admin'));
|
||||
$temp->add(new admin_settings_sitepolicy_handler_select('sitepolicyhandler', new lang_string('sitepolicyhandler', 'core_admin'),
|
||||
new lang_string('sitepolicyhandler_desc', 'core_admin')));
|
||||
$temp->add(new admin_setting_configtext('sitepolicy', new lang_string('sitepolicy', 'core_admin'),
|
||||
new lang_string('sitepolicy_help', 'core_admin'), '', PARAM_RAW));
|
||||
$temp->add(new admin_setting_configtext('sitepolicyguest', new lang_string('sitepolicyguest', 'core_admin'),
|
||||
new lang_string('sitepolicyguest_help', 'core_admin'), (isset($CFG->sitepolicy) ? $CFG->sitepolicy : ''), PARAM_RAW));
|
||||
|
||||
$ADMIN->add('privacy', $temp);
|
||||
}
|
|
@ -55,20 +55,6 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
|||
|
||||
$temp->add(new admin_setting_configcheckbox('extendedusernamechars', new lang_string('extendedusernamechars', 'admin'), new lang_string('configextendedusernamechars', 'admin'), 0));
|
||||
|
||||
$sitepolicyhandlers = ['' => new lang_string('sitepolicyhandlercore', 'core_admin')];
|
||||
foreach (get_plugins_with_function('site_policy_handler') as $ptype => $pnames) {
|
||||
foreach ($pnames as $pname => $fname) {
|
||||
$sitepolicyhandlers[$ptype.'_'.$pname] = new lang_string('sitepolicyhandlerplugin', 'core_admin',
|
||||
['name' => new lang_string('pluginname', $ptype.'_'.$pname), 'component' => $ptype.'_'.$pname]);
|
||||
}
|
||||
}
|
||||
$temp->add(new admin_setting_configselect('sitepolicyhandler', new lang_string('sitepolicyhandler', 'core_admin'),
|
||||
new lang_string('sitepolicyhandler_desc', 'core_admin'), '', $sitepolicyhandlers));
|
||||
$temp->add(new admin_setting_configtext('sitepolicy', new lang_string('sitepolicy', 'core_admin'),
|
||||
new lang_string('sitepolicy_help', 'core_admin'), '', PARAM_RAW));
|
||||
$temp->add(new admin_setting_configtext('sitepolicyguest', new lang_string('sitepolicyguest', 'core_admin'),
|
||||
new lang_string('sitepolicyguest_help', 'core_admin'), (isset($CFG->sitepolicy) ? $CFG->sitepolicy : ''), PARAM_RAW));
|
||||
|
||||
$temp->add(new admin_setting_configcheckbox('extendedusernamechars', new lang_string('extendedusernamechars', 'admin'), new lang_string('configextendedusernamechars', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('keeptagnamecase', new lang_string('keeptagnamecase','admin'),new lang_string('configkeeptagnamecase', 'admin'),'1'));
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ $ADMIN->add('root', new admin_category('badges', new lang_string('badges'), empt
|
|||
$ADMIN->add('root', new admin_category('location', new lang_string('location','admin')));
|
||||
$ADMIN->add('root', new admin_category('language', new lang_string('language')));
|
||||
$ADMIN->add('root', new admin_category('modules', new lang_string('plugins', 'admin')));
|
||||
$ADMIN->add('root', new admin_category('privacy', new lang_string('privacyandpolicies', 'admin')));
|
||||
$ADMIN->add('root', new admin_category('security', new lang_string('security','admin')));
|
||||
$ADMIN->add('root', new admin_category('appearance', new lang_string('appearance','admin')));
|
||||
$ADMIN->add('root', new admin_category('frontpage', new lang_string('frontpage','admin')));
|
||||
|
|
|
@ -223,7 +223,9 @@ class api {
|
|||
}
|
||||
|
||||
if (empty($section) or $section == 'sitepolicies') {
|
||||
$settings->sitepolicy = $CFG->sitepolicy;
|
||||
$manager = new \core_privacy\local\sitepolicy\manager();
|
||||
$settings->sitepolicy = ($sitepolicy = $manager->get_embed_url()) ? $sitepolicy->out(false) : '';
|
||||
$settings->sitepolicyhandler = $CFG->sitepolicyhandler;
|
||||
$settings->disableuserimages = $CFG->disableuserimages;
|
||||
}
|
||||
|
||||
|
|
|
@ -150,6 +150,7 @@ class tool_mobile_external_testcase extends externallib_advanced_testcase {
|
|||
array('name' => 'newsitems', 'value' => $SITE->newsitems),
|
||||
array('name' => 'commentsperpage', 'value' => $CFG->commentsperpage),
|
||||
array('name' => 'sitepolicy', 'value' => $mysitepolicy),
|
||||
array('name' => 'sitepolicyhandler', 'value' => ''),
|
||||
array('name' => 'disableuserimages', 'value' => $CFG->disableuserimages),
|
||||
array('name' => 'mygradesurl', 'value' => user_mygrades_url()->out(false)),
|
||||
array('name' => 'tool_mobile_forcelogout', 'value' => 0),
|
||||
|
|
|
@ -88,8 +88,9 @@ class auth_email_external extends external_api {
|
|||
if (!empty($CFG->passwordpolicy)) {
|
||||
$result['passwordpolicy'] = print_password_policy();
|
||||
}
|
||||
if (!empty($CFG->sitepolicy)) {
|
||||
$result['sitepolicy'] = $CFG->sitepolicy;
|
||||
$manager = new \core_privacy\local\sitepolicy\manager();
|
||||
if ($sitepolicy = $manager->get_embed_url()) {
|
||||
$result['sitepolicy'] = $sitepolicy->out(false);
|
||||
}
|
||||
if (!empty($CFG->defaultcity)) {
|
||||
$result['defaultcity'] = $CFG->defaultcity;
|
||||
|
@ -287,7 +288,8 @@ class auth_email_external extends external_api {
|
|||
$data = $params;
|
||||
$data['email2'] = $data['email'];
|
||||
// Force policy agreed if a site policy is set. The client is responsible of implementing the interface check.
|
||||
if (!empty($CFG->sitepolicy)) {
|
||||
$manager = new \core_privacy\local\sitepolicy\manager();
|
||||
if (!$manager->is_defined()) {
|
||||
$data['policyagreed'] = 1;
|
||||
}
|
||||
unset($data['recaptcharesponse']);
|
||||
|
|
|
@ -6,7 +6,7 @@ Feature: Test validation of 'Age of digital consent' setting.
|
|||
|
||||
Background:
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Manage authentication" node in "Site administration > Plugins > Authentication"
|
||||
And I navigate to "Privacy settings" node in "Site administration > Privacy and policies"
|
||||
|
||||
Scenario: Admin provides valid value for 'Age of digital consent'.
|
||||
Given I set the field "s__agedigitalconsentmap" to multiline:
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
This files describes API changes in /auth/* - plugins,
|
||||
information provided here is intended especially for developers.
|
||||
|
||||
=== 3.4.2 ===
|
||||
|
||||
* Self registration plugins should use core_privacy\local\sitepolicy\manager instead of directly checking
|
||||
$CFG->sitepolicy , especially in custom signup forms. See https://docs.moodle.org/dev/Site_policy_handler
|
||||
|
||||
=== 3.3 ===
|
||||
|
||||
* Authentication plugins have been migrated to use the admin settings API. Plugins should use a settings.php file to
|
||||
|
|
2
file.php
2
file.php
|
@ -68,7 +68,7 @@ if ($course->id != SITEID) {
|
|||
require_login($course, true, null, false);
|
||||
|
||||
} else if ($CFG->forcelogin) {
|
||||
if (!empty($CFG->sitepolicy)
|
||||
if (empty($CFG->sitepolicyhandler) and !empty($CFG->sitepolicy)
|
||||
and ($CFG->sitepolicy == $CFG->wwwroot.'/file.php/'.$relativepath
|
||||
or $CFG->sitepolicy == $CFG->wwwroot.'/file.php?file=/'.$relativepath)) {
|
||||
//do not require login for policy file
|
||||
|
|
|
@ -857,6 +857,9 @@ $string['pluginscheckfailed'] = 'Dependencies check failed for {$a->pluginslist}
|
|||
$string['pluginschecktodo'] = 'You must solve all the plugin requirements before proceeding to install this Moodle version!';
|
||||
$string['pluginsoverview'] = 'Plugins overview';
|
||||
$string['pluginsoverviewsee'] = 'See <a href="{$a->url}">plugins overview</a> page for more details.';
|
||||
$string['policysettings'] = 'Policy settings';
|
||||
$string['privacyandpolicies'] = 'Privacy and policies';
|
||||
$string['privacysettings'] = 'Privacy settings';
|
||||
$string['profilecategory'] = 'Category';
|
||||
$string['profilecategoryname'] = 'Category name (must be unique)';
|
||||
$string['profilecategorynamenotunique'] = 'This category name is already in use';
|
||||
|
|
|
@ -10626,3 +10626,46 @@ class admin_setting_agedigitalconsentmap extends admin_setting_configtextarea {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Selection of plugins that can work as site policy handlers
|
||||
*
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @copyright 2018 Marina Glancy
|
||||
*/
|
||||
class admin_settings_sitepolicy_handler_select extends admin_setting_configselect {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param string $name unique ascii name, either 'mysetting' for settings that in config, or 'myplugin/mysetting'
|
||||
* for ones in config_plugins.
|
||||
* @param string $visiblename localised
|
||||
* @param string $description long localised info
|
||||
* @param string $defaultsetting
|
||||
*/
|
||||
public function __construct($name, $visiblename, $description, $defaultsetting = '') {
|
||||
parent::__construct($name, $visiblename, $description, $defaultsetting, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy-load the available choices for the select box
|
||||
*/
|
||||
public function load_choices() {
|
||||
if (during_initial_install()) {
|
||||
return false;
|
||||
}
|
||||
if (is_array($this->choices)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->choices = ['' => new lang_string('sitepolicyhandlercore', 'core_admin')];
|
||||
$manager = new \core_privacy\local\sitepolicy\manager();
|
||||
$plugins = $manager->get_all_handlers();
|
||||
foreach ($plugins as $pname => $unused) {
|
||||
$this->choices[$pname] = new lang_string('sitepolicyhandlerplugin', 'core_admin',
|
||||
['name' => new lang_string('pluginname', $pname), 'component' => $pname]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2723,40 +2723,16 @@ function require_login($courseorid = null, $autologinguest = true, $cm = null, $
|
|||
|
||||
// Check that the user has agreed to a site policy if there is one - do not test in case of admins.
|
||||
// Do not test if the script explicitly asked for skipping the site policies check.
|
||||
// Also do not check during AJAX requests as they may be actually performed on pages where policies are accepted.
|
||||
if (!$USER->policyagreed && !is_siteadmin() && !NO_SITEPOLICY_CHECK && !AJAX_SCRIPT) {
|
||||
if (!empty($CFG->sitepolicyhandler)) {
|
||||
try {
|
||||
$handler = component_callback($CFG->sitepolicyhandler, 'site_policy_handler');
|
||||
} catch (Exception $e) {
|
||||
debugging('Error while trying to execute the site_policy_handler callback!');
|
||||
$handler = false;
|
||||
}
|
||||
if (!empty($handler) && (empty($PAGE->url) || !$PAGE->url->compare(new moodle_url($handler), URL_MATCH_BASE))) {
|
||||
if ($preventredirect) {
|
||||
throw new moodle_exception('sitepolicynotagreed', 'error', '', $handler);
|
||||
}
|
||||
if ($setwantsurltome) {
|
||||
$SESSION->wantsurl = qualified_me();
|
||||
}
|
||||
redirect($handler);
|
||||
}
|
||||
} else if (!empty($CFG->sitepolicy) and !isguestuser()) {
|
||||
if (!$USER->policyagreed && !is_siteadmin() && !NO_SITEPOLICY_CHECK) {
|
||||
$manager = new \core_privacy\local\sitepolicy\manager();
|
||||
if ($policyurl = $manager->get_redirect_url(isguestuser())) {
|
||||
if ($preventredirect) {
|
||||
throw new moodle_exception('sitepolicynotagreed', 'error', '', $CFG->sitepolicy);
|
||||
throw new moodle_exception('sitepolicynotagreed', 'error', '', $policyurl->out());
|
||||
}
|
||||
if ($setwantsurltome) {
|
||||
$SESSION->wantsurl = qualified_me();
|
||||
}
|
||||
redirect($CFG->wwwroot .'/user/policy.php');
|
||||
} else if (!empty($CFG->sitepolicyguest) and isguestuser()) {
|
||||
if ($preventredirect) {
|
||||
throw new moodle_exception('sitepolicynotagreed', 'error', '', $CFG->sitepolicyguest);
|
||||
}
|
||||
if ($setwantsurltome) {
|
||||
$SESSION->wantsurl = qualified_me();
|
||||
}
|
||||
redirect($CFG->wwwroot .'/user/policy.php');
|
||||
redirect($policyurl);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,9 +3,9 @@ information provided here is intended especially for developers.
|
|||
|
||||
=== 3.4.2 ===
|
||||
|
||||
* Plugins can provide a new callback 'site_policy_handler' if they implement an alternative mechanisms for site policies
|
||||
managements and agreements. Administrators can define which component is to be used for handling site policies and
|
||||
agreements.
|
||||
* Plugins can define class 'PLUGINNAME\privacy\local\sitepolicy\handler' if they implement an alternative mechanisms for
|
||||
site policies managements and agreements. Administrators can define which component is to be used for handling site
|
||||
policies and agreements. See https://docs.moodle.org/dev/Site_policy_handler
|
||||
* Scripts can define a constant NO_SITEPOLICY_CHECK and set it to true before requiring the main config.php file. It
|
||||
will make the require_login() skipping the test for the user's policyagreed status. This is useful for plugins that
|
||||
act as a site policy handler.
|
||||
|
|
|
@ -97,13 +97,10 @@ class login_signup_form extends moodleform implements renderable, templatable {
|
|||
$mform->closeHeaderBefore('recaptcha_element');
|
||||
}
|
||||
|
||||
if (!empty($CFG->sitepolicy)) {
|
||||
$mform->addElement('header', 'policyagreement', get_string('policyagreement'), '');
|
||||
$mform->setExpanded('policyagreement');
|
||||
$mform->addElement('static', 'policylink', '', '<a href="'.$CFG->sitepolicy.'" onclick="this.target=\'_blank\'">'.get_String('policyagreementclick').'</a>');
|
||||
$mform->addElement('checkbox', 'policyagreed', get_string('policyaccept'));
|
||||
$mform->addRule('policyagreed', get_string('policyagree'), 'required', null, 'client');
|
||||
}
|
||||
// Add "Agree to sitepolicy" controls. By default it is a link to the policy text and a checkbox but
|
||||
// it can be implemented differently in custom sitepolicy handlers.
|
||||
$manager = new \core_privacy\local\sitepolicy\manager();
|
||||
$manager->signup_form($mform);
|
||||
|
||||
// buttons
|
||||
$this->add_action_buttons(true, get_string('createaccount'));
|
||||
|
|
|
@ -36,7 +36,8 @@ function message_popup_render_navbar_output(\renderer_base $renderer) {
|
|||
// Early bail out conditions.
|
||||
if (!isloggedin() || isguestuser() || user_not_fully_set_up($USER) ||
|
||||
get_user_preferences('auth_forcepasswordchange') ||
|
||||
($CFG->sitepolicy && !$USER->policyagreed && !is_siteadmin())) {
|
||||
(!$USER->policyagreed && !is_siteadmin() &&
|
||||
($manager = new \core_privacy\local\sitepolicy\manager()) && $manager->is_defined())) {
|
||||
return '';
|
||||
}
|
||||
|
||||
|
|
86
privacy/classes/local/sitepolicy/default_handler.php
Normal file
86
privacy/classes/local/sitepolicy/default_handler.php
Normal file
|
@ -0,0 +1,86 @@
|
|||
<?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/>.
|
||||
|
||||
/**
|
||||
* Default (core) handler for site policies.
|
||||
*
|
||||
* @package core_privacy
|
||||
* @copyright 2018 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace core_privacy\local\sitepolicy;
|
||||
|
||||
use moodle_url;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Default (core) handler for site policies.
|
||||
*
|
||||
* @package core_privacy
|
||||
* @copyright 2018 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class default_handler extends handler {
|
||||
|
||||
/**
|
||||
* Checks if the site has site policy defined
|
||||
*
|
||||
* @param bool $forguests
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_defined($forguests = false) {
|
||||
global $CFG;
|
||||
if (!$forguests) {
|
||||
return !empty($CFG->sitepolicy);
|
||||
} else {
|
||||
return !empty($CFG->sitepolicyguest);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns URL to redirect user to when user needs to agree to site policy
|
||||
*
|
||||
* This is a regular interactive page for web users. It should have normal Moodle header/footers, it should
|
||||
* allow user to view policies and accept them.
|
||||
*
|
||||
* @param bool $forguests
|
||||
* @return moodle_url|null (returns null if site policy is not defined)
|
||||
*/
|
||||
public static function get_redirect_url($forguests = false) {
|
||||
return static::is_defined($forguests) ? new moodle_url('/user/policy.php') : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns URL of the site policy that needs to be displayed to the user (inside iframe or to use in WS such as mobile app)
|
||||
*
|
||||
* This page should not have any header/footer, it does not also have any buttons/checkboxes. The caller needs to implement
|
||||
* the "Accept" button and call {@link self::accept()} on completion.
|
||||
*
|
||||
* @param bool $forguests
|
||||
* @return moodle_url|null
|
||||
*/
|
||||
public static function get_embed_url($forguests = false) {
|
||||
global $CFG;
|
||||
if ($forguests && !empty($CFG->sitepolicyguest)) {
|
||||
return new moodle_url($CFG->sitepolicyguest);
|
||||
} else if (!$forguests && !empty($CFG->sitepolicy)) {
|
||||
return new moodle_url($CFG->sitepolicy);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
113
privacy/classes/local/sitepolicy/handler.php
Normal file
113
privacy/classes/local/sitepolicy/handler.php
Normal file
|
@ -0,0 +1,113 @@
|
|||
<?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/>.
|
||||
|
||||
/**
|
||||
* Base class for site policy handlers.
|
||||
*
|
||||
* @package core_privacy
|
||||
* @copyright 2018 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace core_privacy\local\sitepolicy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Base class for site policy handlers.
|
||||
*
|
||||
* If a plugin wants to act as a site policy handler it has to define class
|
||||
* PLUGINNAME\privacy\sitepolicy\handler that extends \core_privacy\sitepolicy\handler
|
||||
*
|
||||
* @package core_privacy
|
||||
* @copyright 2018 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class handler {
|
||||
/**
|
||||
* Checks if the site has site policy defined
|
||||
*
|
||||
* @param bool $forguests
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_defined($forguests = false) {
|
||||
$url = static::get_redirect_url($forguests);
|
||||
return !empty($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns URL to redirect user to when user needs to agree to site policy
|
||||
*
|
||||
* This is a regular interactive page for web users. It should have normal Moodle header/footers, it should
|
||||
* allow user to view policies and accept them.
|
||||
*
|
||||
* @param bool $forguests
|
||||
* @return moodle_url|null (returns null if site policy is not defined)
|
||||
*/
|
||||
abstract public static function get_redirect_url($forguests = false);
|
||||
|
||||
/**
|
||||
* Returns URL of the site policy that needs to be displayed to the user (inside iframe or to use in WS such as mobile app)
|
||||
*
|
||||
* This page should not have any header/footer, it does not also have any buttons/checkboxes. The caller needs to implement
|
||||
* the "Accept" button and call {@link self::accept()} on completion.
|
||||
*
|
||||
* @param bool $forguests
|
||||
* @return moodle_url|null
|
||||
*/
|
||||
abstract public static function get_embed_url($forguests = false);
|
||||
|
||||
/**
|
||||
* Accept site policy for the current user
|
||||
*
|
||||
* @return bool - false if sitepolicy not defined, user is not logged in or user has already agreed to site policy;
|
||||
* true - if we have successfully marked the user as agreed to the site policy
|
||||
*/
|
||||
public static function accept() {
|
||||
global $USER, $DB;
|
||||
if (!isloggedin()) {
|
||||
return false;
|
||||
}
|
||||
if ($USER->policyagreed || !static::is_defined(isguestuser())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isguestuser()) {
|
||||
// For the guests agreement in stored in session only, for other users - in DB.
|
||||
$DB->set_field('user', 'policyagreed', 1, array('id' => $USER->id));
|
||||
}
|
||||
$USER->policyagreed = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds "Agree to site policy" checkbox to the signup form.
|
||||
*
|
||||
* Sitepolicy handlers can override the simple checkbox with their own controls.
|
||||
*
|
||||
* @param \MoodleQuickForm $mform
|
||||
*/
|
||||
public static function signup_form($mform) {
|
||||
if ($url = static::get_embed_url()) {
|
||||
$mform->addElement('header', 'policyagreement', get_string('policyagreement'), '');
|
||||
$mform->setExpanded('policyagreement');
|
||||
$mform->addElement('static', 'policylink', '', '<a href="' . $url .
|
||||
'" onclick="this.target=\'_blank\'">' . get_string('policyagreementclick') . '</a>');
|
||||
$mform->addElement('checkbox', 'policyagreed', get_string('policyaccept'));
|
||||
$mform->addRule('policyagreed', get_string('policyagree'), 'required', null, 'client');
|
||||
}
|
||||
}
|
||||
}
|
137
privacy/classes/local/sitepolicy/manager.php
Normal file
137
privacy/classes/local/sitepolicy/manager.php
Normal file
|
@ -0,0 +1,137 @@
|
|||
<?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/>.
|
||||
|
||||
/**
|
||||
* Site policy management class.
|
||||
*
|
||||
* @package core_privacy
|
||||
* @copyright 2018 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace core_privacy\local\sitepolicy;
|
||||
|
||||
use moodle_url;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Site policy management class.
|
||||
*
|
||||
* @package core_privacy
|
||||
* @copyright 2018 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class manager {
|
||||
|
||||
/**
|
||||
* Returns the list of plugins that can work as sitepolicy handlers (have class PLUGINNAME\privacy\sitepolicy\handler)
|
||||
* @return array
|
||||
*/
|
||||
public function get_all_handlers() {
|
||||
$sitepolicyhandlers = [];
|
||||
foreach (\core_component::get_plugin_types() as $ptype => $unused) {
|
||||
$plugins = \core_component::get_plugin_list_with_class($ptype, 'privacy\local\sitepolicy\handler') +
|
||||
\core_component::get_plugin_list_with_class($ptype, 'privacy_local_sitepolicy_handler');
|
||||
// Allow plugins to have the class either with namespace or without (useful for unittest).
|
||||
foreach ($plugins as $pname => $class) {
|
||||
$sitepolicyhandlers[$pname] = $class;
|
||||
}
|
||||
}
|
||||
return $sitepolicyhandlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current site policy handler
|
||||
*
|
||||
* @return handler
|
||||
*/
|
||||
public function get_handler_classname() {
|
||||
global $CFG;
|
||||
if (!empty($CFG->sitepolicyhandler)) {
|
||||
$sitepolicyhandlers = $this->get_all_handlers();
|
||||
$classname = $sitepolicyhandlers[$CFG->sitepolicyhandler];
|
||||
return $classname;
|
||||
} else {
|
||||
return default_handler::class;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the site has site policy defined
|
||||
*
|
||||
* @param bool $forguests
|
||||
* @return bool
|
||||
*/
|
||||
public function is_defined($forguests = false) {
|
||||
return component_class_callback($this->get_handler_classname(), 'is_defined', [$forguests]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns URL to redirect user to when user needs to agree to site policy
|
||||
*
|
||||
* This is a regular interactive page for web users. It should have normal Moodle header/footers, it should
|
||||
* allow user to view policies and accept them.
|
||||
*
|
||||
* @param bool $forguests
|
||||
* @return moodle_url|null (returns null if site policy is not defined)
|
||||
*/
|
||||
public function get_redirect_url($forguests = false) {
|
||||
$url = component_class_callback($this->get_handler_classname(), 'get_redirect_url', [$forguests]);
|
||||
if ($url && !($url instanceof moodle_url)) {
|
||||
$url = new moodle_url($url);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns URL of the site policy that needs to be displayed to the user (inside iframe or to use in WS such as mobile app)
|
||||
*
|
||||
* This page should not have any header/footer, it does not also have any buttons/checkboxes. The caller needs to implement
|
||||
* the "Accept" button and call {@link self::accept()} on completion.
|
||||
*
|
||||
* @param bool $forguests
|
||||
* @return moodle_url|null
|
||||
*/
|
||||
public function get_embed_url($forguests = false) {
|
||||
$url = component_class_callback($this->get_handler_classname(), 'get_embed_url', [$forguests]);
|
||||
if ($url && !($url instanceof moodle_url)) {
|
||||
$url = new moodle_url($url);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept site policy for the current user
|
||||
*
|
||||
* @return bool - false if sitepolicy not defined, user is not logged in or user has already agreed to site policy;
|
||||
* true - if we have successfully marked the user as agreed to the site policy
|
||||
*/
|
||||
public function accept() {
|
||||
return component_class_callback($this->get_handler_classname(), 'accept', []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds "Agree to site policy" checkbox to the signup form.
|
||||
*
|
||||
* Sitepolicy handlers can override the simple checkbox with their own controls.
|
||||
*
|
||||
* @param \MoodleQuickForm $mform
|
||||
*/
|
||||
public function signup_form($mform) {
|
||||
component_class_callback($this->get_handler_classname(), 'signup_form', [$mform]);
|
||||
}
|
||||
}
|
77
privacy/tests/fixtures/mock_sitepolicy_handler.php
vendored
Normal file
77
privacy/tests/fixtures/mock_sitepolicy_handler.php
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
<?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/>.
|
||||
|
||||
/**
|
||||
* Mock handler for site policies
|
||||
*
|
||||
* @package core_privacy
|
||||
* @copyright 2018 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Mock handler for site policies
|
||||
*
|
||||
* @package core_privacy
|
||||
* @copyright 2018 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class mock_sitepolicy_handler extends \core_privacy\local\sitepolicy\handler {
|
||||
|
||||
/**
|
||||
* Returns URL to redirect user to when user needs to agree to site policy
|
||||
*
|
||||
* This is a regular interactive page for web users. It should have normal Moodle header/footers, it should
|
||||
* allow user to view policies and accept them.
|
||||
*
|
||||
* @param bool $forguests
|
||||
* @return moodle_url|null (returns null if site policy is not defined)
|
||||
*/
|
||||
public static function get_redirect_url($forguests = false) {
|
||||
return 'http://example.com/policy.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns URL of the site policy that needs to be displayed to the user (inside iframe or to use in WS such as mobile app)
|
||||
*
|
||||
* This page should not have any header/footer, it does not also have any buttons/checkboxes. The caller needs to implement
|
||||
* the "Accept" button and call {@link self::accept()} on completion.
|
||||
*
|
||||
* @param bool $forguests
|
||||
* @return moodle_url|null
|
||||
*/
|
||||
public static function get_embed_url($forguests = false) {
|
||||
return 'http://example.com/view.htm';
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept site policy for the current user
|
||||
*
|
||||
* @return bool - false if sitepolicy not defined, user is not logged in or user has already agreed to site policy;
|
||||
* true - if we have successfully marked the user as agreed to the site policy
|
||||
*/
|
||||
public static function accept() {
|
||||
global $USER, $DB;
|
||||
// Accepts policy on behalf of the current user. We set it to 2 here to check that this callback was called.
|
||||
$USER->policyagreed = 2;
|
||||
if (!isguestuser()) {
|
||||
$DB->update_record('user', ['policyagreed' => 2, 'id' => $USER->id]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
324
privacy/tests/sitepolicy_test.php
Normal file
324
privacy/tests/sitepolicy_test.php
Normal file
|
@ -0,0 +1,324 @@
|
|||
<?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/>.
|
||||
|
||||
/**
|
||||
* Unit Tests for sitepolicy manager
|
||||
*
|
||||
* @package core_privacy
|
||||
* @category test
|
||||
* @copyright 2018 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
|
||||
/**
|
||||
* Unit Tests for sitepolicy manager
|
||||
*
|
||||
* @package core_privacy
|
||||
* @category test
|
||||
* @copyright 2018 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class sitepolicy_test extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Tests for \core_privacy\local\sitepolicy\manager::is_defined()
|
||||
*/
|
||||
public function test_is_defined() {
|
||||
global $CFG;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$manager = new \core_privacy\local\sitepolicy\manager();
|
||||
|
||||
$this->assertFalse($manager->is_defined(true));
|
||||
$this->assertFalse($manager->is_defined(false));
|
||||
|
||||
$CFG->sitepolicy = 'http://example.com/sitepolicy.html';
|
||||
$this->assertFalse($manager->is_defined(true));
|
||||
$this->assertTrue($manager->is_defined(false));
|
||||
|
||||
$CFG->sitepolicyguest = 'http://example.com/sitepolicyguest.html';
|
||||
$this->assertTrue($manager->is_defined(true));
|
||||
$this->assertTrue($manager->is_defined(false));
|
||||
|
||||
$CFG->sitepolicy = null;
|
||||
$this->assertTrue($manager->is_defined(true));
|
||||
$this->assertFalse($manager->is_defined(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for \core_privacy\local\sitepolicy\manager::get_redirect_url()
|
||||
*/
|
||||
public function test_get_redirect_url() {
|
||||
global $CFG;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$manager = new \core_privacy\local\sitepolicy\manager();
|
||||
|
||||
$this->assertEquals(null, $manager->get_redirect_url(true));
|
||||
$this->assertEquals(null, $manager->get_redirect_url(false));
|
||||
|
||||
$CFG->sitepolicy = 'http://example.com/sitepolicy.html';
|
||||
$this->assertEquals(null, $manager->get_redirect_url(true));
|
||||
$this->assertEquals($CFG->wwwroot.'/user/policy.php', $manager->get_redirect_url(false)->out(false));
|
||||
|
||||
$CFG->sitepolicyguest = 'http://example.com/sitepolicyguest.html';
|
||||
$this->assertEquals($CFG->wwwroot.'/user/policy.php', $manager->get_redirect_url(true)->out(false));
|
||||
$this->assertEquals($CFG->wwwroot.'/user/policy.php', $manager->get_redirect_url(false)->out(false));
|
||||
|
||||
$CFG->sitepolicy = null;
|
||||
$this->assertEquals($CFG->wwwroot.'/user/policy.php', $manager->get_redirect_url(true)->out(false));
|
||||
$this->assertEquals(null, $manager->get_redirect_url(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for \core_privacy\local\sitepolicy\manager::get_redirect_url()
|
||||
*/
|
||||
public function test_get_embed_url() {
|
||||
global $CFG;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$manager = new \core_privacy\local\sitepolicy\manager();
|
||||
|
||||
$this->assertEquals(null, $manager->get_embed_url(true));
|
||||
$this->assertEquals(null, $manager->get_embed_url(false));
|
||||
|
||||
$CFG->sitepolicy = 'http://example.com/sitepolicy.html';
|
||||
$this->assertEquals(null, $manager->get_embed_url(true));
|
||||
$this->assertEquals($CFG->sitepolicy, $manager->get_embed_url(false)->out(false));
|
||||
|
||||
$CFG->sitepolicyguest = 'http://example.com/sitepolicyguest.html';
|
||||
$this->assertEquals($CFG->sitepolicyguest, $manager->get_embed_url(true)->out(false));
|
||||
$this->assertEquals($CFG->sitepolicy, $manager->get_embed_url(false)->out(false));
|
||||
|
||||
$CFG->sitepolicy = null;
|
||||
$this->assertEquals($CFG->sitepolicyguest, $manager->get_embed_url(true)->out(false));
|
||||
$this->assertEquals(null, $manager->get_embed_url(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for \core_privacy\local\sitepolicy\manager::get_redirect_url()
|
||||
*/
|
||||
public function test_accept() {
|
||||
global $CFG, $USER, $DB;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$manager = new \core_privacy\local\sitepolicy\manager();
|
||||
|
||||
// No site policy.
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$this->setUser($user1);
|
||||
$this->assertFalse($manager->accept());
|
||||
$this->assertEquals(0, $USER->policyagreed);
|
||||
|
||||
// With site policy.
|
||||
$CFG->sitepolicy = 'http://example.com/sitepolicy.html';
|
||||
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
$this->setUser($user2);
|
||||
|
||||
$this->assertEquals(0, $USER->policyagreed);
|
||||
$this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $USER->id]));
|
||||
$this->assertTrue($manager->accept());
|
||||
$this->assertEquals(1, $USER->policyagreed);
|
||||
$this->assertEquals(1, $DB->get_field('user', 'policyagreed', ['id' => $USER->id]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for \core_privacy\local\sitepolicy\manager::get_redirect_url() for guests
|
||||
*/
|
||||
public function test_accept_guests() {
|
||||
global $CFG, $USER, $DB;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$manager = new \core_privacy\local\sitepolicy\manager();
|
||||
|
||||
$this->setGuestUser();
|
||||
|
||||
// No site policy.
|
||||
$this->assertFalse($manager->accept());
|
||||
$this->assertEquals(0, $USER->policyagreed);
|
||||
|
||||
// With site policy.
|
||||
$CFG->sitepolicyguest = 'http://example.com/sitepolicy.html';
|
||||
|
||||
$this->assertEquals(0, $USER->policyagreed);
|
||||
$this->assertTrue($manager->accept());
|
||||
$this->assertEquals(1, $USER->policyagreed);
|
||||
$this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $USER->id]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to spoof the results of the internal function get_all_handlers, allowing mock handler to be tested.
|
||||
*
|
||||
* @return PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected function get_mock_manager_with_handler() {
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot.'/privacy/tests/fixtures/mock_sitepolicy_handler.php');
|
||||
|
||||
$mock = $this->getMockBuilder(\core_privacy\local\sitepolicy\manager::class)
|
||||
->setMethods(['get_all_handlers'])
|
||||
->getMock();
|
||||
$mock->expects($this->any())
|
||||
->method('get_all_handlers')
|
||||
->will($this->returnValue(['testtool_testhandler' => 'mock_sitepolicy_handler']));
|
||||
return $mock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for \core_privacy\local\sitepolicy\manager::is_defined() with a handler
|
||||
*/
|
||||
public function test_is_defined_with_handler() {
|
||||
global $CFG;
|
||||
$this->resetAfterTest(true);
|
||||
$CFG->sitepolicyhandler = 'testtool_testhandler';
|
||||
$manager = $this->get_mock_manager_with_handler();
|
||||
$this->assertTrue($manager->is_defined(true));
|
||||
$this->assertTrue($manager->is_defined(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for \core_privacy\local\sitepolicy\manager::get_redirect_url() with a handler
|
||||
*/
|
||||
public function test_get_redirect_url_with_handler() {
|
||||
global $CFG;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$CFG->sitepolicyhandler = 'testtool_testhandler';
|
||||
$manager = $this->get_mock_manager_with_handler();
|
||||
|
||||
$this->assertEquals('http://example.com/policy.php', $manager->get_redirect_url(true)->out(false));
|
||||
$this->assertEquals('http://example.com/policy.php', $manager->get_redirect_url(false)->out(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for \core_privacy\local\sitepolicy\manager::get_redirect_url() with a handler
|
||||
*/
|
||||
public function test_get_embed_url_with_handler() {
|
||||
global $CFG;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$CFG->sitepolicyhandler = 'testtool_testhandler';
|
||||
$manager = $this->get_mock_manager_with_handler();
|
||||
|
||||
$this->assertEquals('http://example.com/view.htm', $manager->get_embed_url(true)->out(false));
|
||||
$this->assertEquals('http://example.com/view.htm', $manager->get_embed_url(false)->out(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for \core_privacy\local\sitepolicy\manager::get_redirect_url() with a handler
|
||||
*/
|
||||
public function test_accept_with_handler() {
|
||||
global $CFG, $USER, $DB;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$CFG->sitepolicyhandler = 'testtool_testhandler';
|
||||
$manager = $this->get_mock_manager_with_handler();
|
||||
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
$this->setUser($user2);
|
||||
|
||||
$this->assertEquals(0, $USER->policyagreed);
|
||||
$this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $USER->id]));
|
||||
$this->assertTrue($manager->accept());
|
||||
$this->assertEquals(2, $USER->policyagreed);
|
||||
$this->assertEquals(2, $DB->get_field('user', 'policyagreed', ['id' => $USER->id]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for \core_privacy\local\sitepolicy\manager::get_redirect_url() for guests with a handler
|
||||
*/
|
||||
public function test_accept_guests_with_handler() {
|
||||
global $CFG, $USER, $DB;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$CFG->sitepolicyhandler = 'testtool_testhandler';
|
||||
$manager = $this->get_mock_manager_with_handler();
|
||||
|
||||
$this->setGuestUser();
|
||||
|
||||
$this->assertEquals(0, $USER->policyagreed);
|
||||
$this->assertTrue($manager->accept());
|
||||
$this->assertEquals(2, $USER->policyagreed);
|
||||
$this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $USER->id]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock handler for site policies
|
||||
*
|
||||
* @package core_privacy
|
||||
* @copyright 2018 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class handler extends \core_privacy\local\sitepolicy\handler {
|
||||
|
||||
/**
|
||||
* Checks if the site has site policy defined
|
||||
*
|
||||
* @param bool $forguests
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_defined($forguests = false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns URL to redirect user to when user needs to agree to site policy
|
||||
*
|
||||
* This is a regular interactive page for web users. It should have normal Moodle header/footers, it should
|
||||
* allow user to view policies and accept them.
|
||||
*
|
||||
* @param bool $forguests
|
||||
* @return moodle_url|null (returns null if site policy is not defined)
|
||||
*/
|
||||
public static function get_redirect_url($forguests = false) {
|
||||
return 'http://example.com/policy.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns URL of the site policy that needs to be displayed to the user (inside iframe or to use in WS such as mobile app)
|
||||
*
|
||||
* This page should not have any header/footer, it does not also have any buttons/checkboxes. The caller needs to implement
|
||||
* the "Accept" button and call {@link self::accept()} on completion.
|
||||
*
|
||||
* @param bool $forguests
|
||||
* @return moodle_url|null
|
||||
*/
|
||||
public static function get_embed_url($forguests = false) {
|
||||
return 'http://example.com/view.htm';
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept site policy for the current user
|
||||
*
|
||||
* @return bool - false if sitepolicy not defined, user is not logged in or user has already agreed to site policy;
|
||||
* true - if we have successfully marked the user as agreed to the site policy
|
||||
*/
|
||||
public static function accept() {
|
||||
global $USER, $DB;
|
||||
// Accepts policy on behalf of the current user. We set it to 2 here to check that this callback was called.
|
||||
$USER->policyagreed = 2;
|
||||
if (!isguestuser()) {
|
||||
$DB->update_record('user', ['policyagreed' => 2, 'id' => $USER->id]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -72,7 +72,8 @@ class user_profile_set extends \core_analytics\local\indicator\linear {
|
|||
// Nothing set results in -1.
|
||||
$calculatedvalue = self::MIN_VALUE;
|
||||
|
||||
if (!empty($CFG->sitepolicy) && !$user->policyagreed) {
|
||||
$sitepolicymanager = new \core_privacy\local\sitepolicy\manager();
|
||||
if ($sitepolicymanager->is_defined() && !$user->policyagreed) {
|
||||
return self::MIN_VALUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -1828,15 +1828,8 @@ class core_user_external extends external_api {
|
|||
}
|
||||
}
|
||||
|
||||
if (empty($CFG->sitepolicy)) {
|
||||
$status = false;
|
||||
$warnings[] = array(
|
||||
'item' => 'user',
|
||||
'itemid' => $USER->id,
|
||||
'warningcode' => 'nositepolicy',
|
||||
'message' => 'The site does not have a site policy configured.'
|
||||
);
|
||||
} else if (!empty($USER->policyagreed)) {
|
||||
$manager = new \core_privacy\local\sitepolicy\manager();
|
||||
if (!empty($USER->policyagreed)) {
|
||||
$status = false;
|
||||
$warnings[] = array(
|
||||
'item' => 'user',
|
||||
|
@ -1844,10 +1837,16 @@ class core_user_external extends external_api {
|
|||
'warningcode' => 'alreadyagreed',
|
||||
'message' => 'The user already agreed the site policy.'
|
||||
);
|
||||
} else if (!$manager->is_defined()) {
|
||||
$status = false;
|
||||
$warnings[] = array(
|
||||
'item' => 'user',
|
||||
'itemid' => $USER->id,
|
||||
'warningcode' => 'nositepolicy',
|
||||
'message' => 'The site does not have a site policy configured.'
|
||||
);
|
||||
} else {
|
||||
$DB->set_field('user', 'policyagreed', 1, array('id' => $USER->id));
|
||||
$USER->policyagreed = 1;
|
||||
$status = true;
|
||||
$status = $manager->accept();
|
||||
}
|
||||
|
||||
$result = array();
|
||||
|
|
|
@ -38,28 +38,30 @@ if (!isloggedin()) {
|
|||
require_login();
|
||||
}
|
||||
|
||||
if (isguestuser()) {
|
||||
$sitepolicy = $CFG->sitepolicyguest;
|
||||
} else {
|
||||
$sitepolicy = $CFG->sitepolicy;
|
||||
}
|
||||
|
||||
if (!empty($SESSION->wantsurl)) {
|
||||
$return = $SESSION->wantsurl;
|
||||
} else {
|
||||
$return = $CFG->wwwroot.'/';
|
||||
}
|
||||
|
||||
$sitepolicymanager = new \core_privacy\local\sitepolicy\manager();
|
||||
if (!empty($CFG->sitepolicyhandler)) {
|
||||
// We are on the wrong page, site policies are managed by somebody else.
|
||||
if ($sitepolicyurl = $sitepolicymanager->get_redirect_url(isguestuser())) {
|
||||
redirect($sitepolicyurl);
|
||||
} else {
|
||||
redirect($return);
|
||||
}
|
||||
}
|
||||
|
||||
$sitepolicy = $sitepolicymanager->get_embed_url(isguestuser());
|
||||
if (empty($sitepolicy)) {
|
||||
// Nothing to agree to, sorry, hopefully we will not get to infinite loop.
|
||||
redirect($return);
|
||||
}
|
||||
|
||||
if ($agree and confirm_sesskey()) { // User has agreed.
|
||||
if (!isguestuser()) { // Don't remember guests.
|
||||
$DB->set_field('user', 'policyagreed', 1, array('id' => $USER->id));
|
||||
}
|
||||
$USER->policyagreed = 1;
|
||||
$sitepolicymanager->accept();
|
||||
unset($SESSION->wantsurl);
|
||||
redirect($return);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue