Skip to content

Commit

Permalink
MDL-61423 authentication: Add digital minor verification upon signup
Browse files Browse the repository at this point in the history
  • Loading branch information
Mihail Geshoski committed Mar 8, 2018
1 parent 856e07e commit 25dbbdf
Show file tree
Hide file tree
Showing 25 changed files with 1,189 additions and 1 deletion.
37 changes: 37 additions & 0 deletions admin/settings/plugins.php
Expand Up @@ -123,6 +123,43 @@
$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);

Expand Down
106 changes: 106 additions & 0 deletions auth/classes/digital_consent.php
@@ -0,0 +1,106 @@
<?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/>.

/**
* Contains helper class for digital consent.
*
* @package core_auth
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

namespace core_auth;

defined('MOODLE_INTERNAL') || die();

/**
* Helper class for digital consent.
*
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class digital_consent {

/**
* Returns true if age and location verification is enabled in the site.
*
* @return bool
*/
public static function is_age_digital_consent_verification_enabled() {
global $CFG;

return !empty($CFG->agedigitalconsentverification);
}

/**
* Checks if a user is a digital minor.
*
* @param int $age
* @param string $country The country code (ISO 3166-2)
* @return bool
*/
public static function is_minor($age, $country) {
global $CFG;

$ageconsentmap = $CFG->agedigitalconsentmap;
$agedigitalconsentmap = self::parse_age_digital_consent_map($ageconsentmap);

return array_key_exists($country, $agedigitalconsentmap) ?
$age < $agedigitalconsentmap[$country] : $age < $agedigitalconsentmap['*'];
}

/**
* Parse the agedigitalconsentmap setting into an array.
*
* @param string $ageconsentmap The value of the agedigitalconsentmap setting
* @return array $ageconsentmapparsed
*/
public static function parse_age_digital_consent_map($ageconsentmap) {

$ageconsentmapparsed = array();
$countries = get_string_manager()->get_list_of_countries();
$isdefaultvaluepresent = false;
$lines = preg_split('/\r|\n/', $ageconsentmap, -1, PREG_SPLIT_NO_EMPTY);
foreach ($lines as $line) {
$arr = explode(",", $line);
// Handle if there is more or less than one comma separator.
if (count($arr) != 2) {
throw new \moodle_exception('agedigitalconsentmapinvalidcomma', 'error', '', $line);
}
$country = trim($arr[0]);
$age = trim($arr[1]);
// Check if default.
if ($country == "*") {
$isdefaultvaluepresent = true;
}
// Handle if the presented value for country is not valid.
if ($country !== "*" && !array_key_exists($country, $countries)) {
throw new \moodle_exception('agedigitalconsentmapinvalidcountry', 'error', '', $country);
}
// Handle if the presented value for age is not valid.
if (!is_numeric($age)) {
throw new \moodle_exception('agedigitalconsentmapinvalidage', 'error', '', $age);
}
$ageconsentmapparsed[$country] = $age;
}
// Handle if a default value does not exist.
if (!$isdefaultvaluepresent) {
throw new \moodle_exception('agedigitalconsentmapinvaliddefault');
}

return $ageconsentmapparsed;
}
}
72 changes: 72 additions & 0 deletions auth/classes/external.php
Expand Up @@ -215,4 +215,76 @@ public static function request_password_reset_returns() {
)
);
}

/**
* Describes the parameters for the digital minor check.
*
* @return external_function_parameters
* @since Moodle 3.4
*/
public static function is_minor_parameters() {
return new external_function_parameters(
array(
'age' => new external_value(PARAM_INT, 'Age'),
'country' => new external_value(PARAM_ALPHA, 'Country of residence'),
)
);
}

/**
* Requests a check if a user is digital minor.
*
* @param int $age User age
* @param string $country Country of residence
* @return array status (true if the user is a minor, false otherwise)
* @since Moodle 3.4
* @throws moodle_exception
*/
public static function is_minor($age, $country) {
global $CFG, $PAGE;
require_once($CFG->dirroot . '/login/lib.php');

$params = self::validate_parameters(
self::is_minor_parameters(),
array(
'age' => $age,
'country' => $country,
)
);

if (!array_key_exists($params['country'], get_string_manager()->get_list_of_countries())) {
throw new invalid_parameter_exception('Invalid value for country parameter (value: '.
$params['country'] .')');
}

$context = context_system::instance();
$PAGE->set_context($context);

// Check if verification of age and location (minor check) is enabled.
if (!\core_auth\digital_consent::is_age_digital_consent_verification_enabled()) {
throw new moodle_exception('nopermissions', 'error', '',
get_string('agelocationverificationdisabled', 'error'));
}

$status = \core_auth\digital_consent::is_minor($params['age'], $params['country']);

return array(
'status' => $status
);
}

/**
* Describes the is_minor return value.
*
* @return external_single_structure
* @since Moodle 3.4
*/
public static function is_minor_returns() {
return new external_single_structure(
array(
'status' => new external_value(PARAM_BOOL, 'True if the user is considered to be a digital minor,
false if not')
)
);
}
}
62 changes: 62 additions & 0 deletions auth/classes/form/verify_age_location_form.php
@@ -0,0 +1,62 @@
<?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/>.

/**
* Age and location verification mform.
*
* @package core_auth
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

namespace core_auth\form;

defined('MOODLE_INTERNAL') || die();

require_once($CFG->libdir.'/formslib.php');

use moodleform;

/**
* Age and location verification mform class.
*
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class verify_age_location_form extends moodleform {
/**
* Defines the form fields.
*/
public function definition() {
global $CFG;

$mform = $this->_form;

$mform->addElement('text', 'age', get_string('whatisyourage'), array('optional' => false));
$mform->setType('age', PARAM_RAW);
$mform->addRule('age', null, 'required', null, 'client');
$mform->addRule('age', null, 'numeric', null, 'client');

$countries = get_string_manager()->get_list_of_countries();
$defaultcountry[''] = get_string('selectacountry');
$countries = array_merge($defaultcountry, $countries);
$mform->addElement('select', 'country', get_string('wheredoyoulive'), $countries);
$mform->addRule('country', null, 'required', null, 'client');
$mform->setDefault('country', $CFG->country);

$this->add_action_buttons(true, get_string('proceed'));
}
}
63 changes: 63 additions & 0 deletions auth/classes/output/digital_minor_page.php
@@ -0,0 +1,63 @@
<?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/>.

/**
* Digital minor renderable.
*
* @package core_auth
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

namespace core_auth\output;

defined('MOODLE_INTERNAL') || die();

use renderable;
use renderer_base;
use templatable;

/**
* Digital minor renderable class.
*
* @copyright 2018 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class digital_minor_page implements renderable, templatable {

/**
* Export the page data for the mustache template.
*
* @param renderer_base $output renderer to be used to render the page elements.
* @return stdClass
*/
public function export_for_template(renderer_base $output) {
global $SITE, $CFG;

$sitename = format_string($SITE->fullname);
$supportname = $CFG->supportname;
$supportemail = $CFG->supportemail;

$context = [
'sitename' => $sitename,
'supportname' => $supportname,
'supportemail' => $supportemail,
'homelink' => new \moodle_url('/')
];

return $context;
}
}

0 comments on commit 25dbbdf

Please sign in to comment.