Skip to content

Commit e81df7b

Browse files
authoredJan 9, 2019
Add master password (#12)
Master Password Table
1 parent 05823ea commit e81df7b

9 files changed

+315
-15
lines changed
 

‎README.md

+14-7
Original file line numberDiff line numberDiff line change
@@ -69,17 +69,24 @@ Example usage on the command line:
6969

7070
Set up master password feature for load test (Non Production Environments).
7171

72-
Add this setting to config.php:
72+
Add these settings to config.php:
7373

7474
```php
75-
$CFG->forced_plugin_settings = array(
76-
'auth_basic' => array(
77-
'master' => 'masterpassword',
78-
),
79-
);
75+
$CFG->auth_basic_enabled_master_password = true;
8076
```
81-
with 'masterpassword' is your Master Password.
8277

78+
and
79+
```php
80+
$CFG->auth_basic_whitelist_ips = 'x.x.x.x';
81+
```
82+
Where x.x.x.x is the IP address allowed to access Moodle using master password.
83+
If it is not set, there will be no IP restriction.
84+
85+
86+
Go to "Site Administration > Plugins > Authentication > Basic Authentication > Master Password" to generate Master Password
87+
Click on "Regenerate Password" button with you want to choose another password.
88+
Click on "Save Password" button to create new master password.
89+
8390

8491
Template to use with curl:
8592

‎auth.php

+22-6
Original file line numberDiff line numberDiff line change
@@ -164,18 +164,34 @@ public function user_login ($username, $password) {
164164
}
165165

166166
/**
167-
* Check if the password is master password.
168167
* @param $userpassword
169168
* @return bool
169+
* @throws dml_exception
170170
*/
171171
private function is_master_password($userpassword) {
172-
global $CFG;
173-
if (isset($CFG->forced_plugin_settings)) {
174-
if ($CFG->forced_plugin_settings["auth_basic"]) {
175-
if ($masterpassword = $CFG->forced_plugin_settings["auth_basic"]['master']) {
176-
return $masterpassword === $userpassword;
172+
global $CFG, $DB;
173+
if (isset($CFG->auth_basic_enabled_master_password) && $CFG->auth_basic_enabled_master_password == true) {
174+
$sql = "SELECT mp.*
175+
FROM {auth_basic_master_password} mp
176+
WHERE mp.timeexpired > :timenow AND mp.password = :password
177+
ORDER BY mp.timecreated DESC
178+
LIMIT 1";
179+
$masterpassword = $DB->get_record_sql($sql,
180+
array('timenow' => time(), 'password' => $userpassword ));
181+
if (!empty($masterpassword)) {
182+
$whitelistips = $CFG->auth_basic_whitelist_ips;;
183+
if (empty($whitelistips) || remoteip_in_list($whitelistips)) {
184+
$masterpassword->usage += 1;
185+
$DB->update_record('auth_basic_master_password', $masterpassword);
186+
return true;
187+
} else {
188+
$this->log(__FUNCTION__ . " - IP address is not in the whitelist: ". getremoteaddr());
177189
}
190+
} else {
191+
$this->log(__FUNCTION__ . " - is not master password or has been expired: '{$userpassword}'");
178192
}
193+
} else {
194+
$this->log(__FUNCTION__ . " - master password is not enabled in config.php");
179195
}
180196
return false;
181197
}

‎classes/form/savepassword.php

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
// This file is part of Moodle - http://moodle.org/
3+
//
4+
// Moodle is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// Moodle is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16+
17+
/**
18+
* Master Password Form
19+
*
20+
* @package auth_basic
21+
* @copyright 2018 Nathan Nguyen <nathannguyen@catalyst-au.nete>
22+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23+
*/
24+
25+
defined('MOODLE_INTERNAL') || die();
26+
require_once("$CFG->libdir/formslib.php");
27+
28+
class savepassword extends moodleform {
29+
30+
protected function definition() {
31+
$mform = $this->_form;
32+
33+
$mform->addElement('text', 'password', get_string('password', 'auth_basic'), array('disabled' => true));
34+
$mform->setDefault('password', $this->_customdata['password']);
35+
36+
$buttonarray = array();
37+
$buttonarray[] =& $mform->createElement('submit', 'submitbutton', get_string('savepassword', 'auth_basic'));
38+
$buttonarray[] =& $mform->createElement('cancel', 'cancel', get_string('regeneratepassword', 'auth_basic'));
39+
$mform->addGroup($buttonarray, 'buttonar', '', array(' '), false);
40+
41+
}
42+
}

‎db/install.xml

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<XMLDB PATH="auth/basic/db" VERSION="20181214" COMMENT="XMLDB file for Moodle auth/basic"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
5+
>
6+
<TABLES>
7+
<TABLE NAME="auth_basic_master_password" COMMENT="Generated Password">
8+
<FIELDS>
9+
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
10+
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The user who own this password"/>
11+
<FIELD NAME="password" TYPE="text" NOTNULL="true" SEQUENCE="false" COMMENT="Master Password"/>
12+
<FIELD NAME="usage" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
13+
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
14+
<FIELD NAME="timeexpired" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
15+
</FIELDS>
16+
<KEYS>
17+
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
18+
<KEY NAME="userid_key" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id"/>
19+
</KEYS>
20+
</TABLE>
21+
</TABLES>
22+
</XMLDB>

‎db/upgrade.php

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
// This file is part of Moodle - http://moodle.org/
3+
//
4+
// Moodle is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// Moodle is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16+
17+
/**
18+
* Upgrade code for the auth_basic.
19+
*
20+
* @package auth_basic
21+
* @copyright 2018 Nathan Nguyen <nathannguyen@catalyst-au.net>
22+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23+
*/
24+
25+
defined('MOODLE_INTERNAL') || die();
26+
27+
function xmldb_auth_basic_upgrade($oldversion) {
28+
global $DB;
29+
30+
$dbman = $DB->get_manager();
31+
32+
if ($oldversion < 2018121400) {
33+
$table = new xmldb_table('auth_basic_master_password');
34+
35+
// Adding fields to the table.
36+
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
37+
$table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
38+
$table->add_field('password', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
39+
$table->add_field('usage', XMLDB_TYPE_INTEGER, '10', null, null, null, 0);
40+
$table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
41+
$table->add_field('timeexpired', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
42+
43+
// Adding keys to the table.
44+
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
45+
$table->add_key('userid_key', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
46+
47+
// Create table.
48+
if (!$dbman->table_exists($table)) {
49+
$dbman->create_table($table);
50+
}
51+
52+
upgrade_plugin_savepoint(true, 2018121400, 'auth', 'auth_basic');
53+
}
54+
55+
return true;
56+
}

‎lang/en/auth_basic.php

+21
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,24 @@
3636
* Privacy provider (GDPR)
3737
*/
3838
$string["privacy:no_data_reason"] = "The 'auth basic' plugins doesn't store any personnel data.";
39+
40+
$string["masterpassword"] = "Master Password";
41+
$string["password"] = "Password";
42+
43+
$string["auth_basic_not_enabled"] = 'Auth Basic is not enabled. The plugin won\'t work until you enable it in \'Manage Authenticaton\'';
44+
$string["masterpassword_not_enabled"] = 'Please add <code>$CFG->auth_basic_enabled_master_password = true;</code> in config.php to enable master password.<br/>
45+
You are able to generate new master passwords, but they won\'t work until the config is enabled.';
46+
$string["whitelist_not_set"] = '<code>$CFG->auth_basic_whitelist_ips</code> is not set up in config.php, there will be no IP restriction.';
47+
$string["whitelistonly"] = 'Only allow access to the following ips: <strong>{$a}</strong>';
48+
49+
$string["masterpassword_desc"] = "Master Password";
50+
$string["menusettings"] = "Settings";
51+
$string["generated_masterpassword"] = "Generated Password";
52+
53+
$string["savepassword"] = "Save Password";
54+
$string["regeneratepassword"] = "Regenerate Passwords";
55+
56+
$string["username"] = "Name";
57+
$string["usage"] = "Usage";
58+
$string["timecreated"] = "Time Created";
59+
$string["timeexpired"] = "Time Expired";

‎masterpassword.php

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?php
2+
// This file is part of Moodle - http://moodle.org/
3+
//
4+
// Moodle is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// Moodle is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16+
17+
/**
18+
* Master Password Settings
19+
*
20+
* @package auth_basic
21+
* @copyright 2018 Nathan Nguyen <nathannguyen@catalyst-au.nete>
22+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23+
*/
24+
25+
require_once(__DIR__.'/../../config.php');
26+
require_once($CFG->libdir.'/adminlib.php');
27+
require_once('./classes/form/savepassword.php');
28+
require_once($CFG->libdir.'/tablelib.php');
29+
30+
require_login();
31+
require_capability('moodle/site:config', context_system::instance());
32+
33+
admin_externalpage_setup('auth_basic_masterpassword');
34+
$thispage = '/auth/basic/masterpassword.php';
35+
36+
$PAGE->set_url(new moodle_url($thispage));
37+
38+
echo $OUTPUT->header();
39+
echo $OUTPUT->heading(get_string('masterpassword', 'auth_basic'));
40+
41+
if (!isset($CFG->auth_basic_enabled_master_password)) {
42+
echo $OUTPUT->notification(get_string('masterpassword_not_enabled', 'auth_basic'), 'notifyproblem');
43+
}
44+
45+
if (!is_enabled_auth('basic')) {
46+
echo $OUTPUT->notification(get_string('auth_basic_not_enabled', 'auth_basic'), 'notifyproblem');
47+
}
48+
49+
$whitelist = $CFG->auth_basic_whitelist_ips;
50+
if (!isset($whitelist)) {
51+
echo $OUTPUT->notification(get_string('whitelist_not_set', 'auth_basic'), 'notifyproblem');
52+
} else {
53+
echo $OUTPUT->notification(get_string('whitelistonly', 'auth_basic', $whitelist), 'notifysuccess');
54+
}
55+
56+
// Save Password Form.
57+
$password = time().uniqid();
58+
$mform = new savepassword(null, array('password' => $password));
59+
60+
if ($formdata = $mform->get_data()) {
61+
$record = new stdClass();
62+
$record->password = $formdata->password;
63+
$record->userid = $USER->id;
64+
$record->usage = 0;
65+
$record->timecreated = time();
66+
$record->timeexpired = time() + DAYSECS;
67+
$DB->insert_record('auth_basic_master_password', $record);
68+
redirect(new moodle_url($thispage));
69+
} else {
70+
$mform->set_data($toform);
71+
$mform->display();
72+
}
73+
74+
// Master Password Table.
75+
echo $OUTPUT->heading(get_string('generated_masterpassword', 'auth_basic'));
76+
77+
$sql = "SELECT COUNT(*) FROM {auth_basic_master_password}";
78+
$record = $DB->get_record_sql($sql);
79+
if (!empty($record) && ($total = $record->count) > 0) {
80+
$perpage = 20;
81+
$page = optional_param('page', 0, PARAM_INT);
82+
$offset = $page * $perpage;
83+
84+
$sql = "SELECT p.*, u.firstname, u.lastname
85+
FROM {auth_basic_master_password} p
86+
JOIN {user} u on u.id = p.userid
87+
ORDER BY p.timecreated DESC";
88+
$records = $DB->get_records_sql($sql, null, $offset, $perpage);
89+
90+
if (!empty($records) && count($records) > 0) {
91+
$table = new html_table();
92+
$table->attributes['class'] = 'generaltable catalystadmins';
93+
$table->head = array(
94+
get_string('username', 'auth_basic'),
95+
get_string('password', 'auth_basic'),
96+
get_string('usage', 'auth_basic'),
97+
get_string('timecreated', 'auth_basic'),
98+
get_string('timeexpired', 'auth_basic'),
99+
);
100+
101+
foreach ($records as $record) {
102+
$row = array();
103+
$row[] = fullname($record);
104+
if ($record->userid == $USER->id) {
105+
$row[] = $record->password;
106+
} else {
107+
$row[] = "*hidden*";
108+
}
109+
110+
$row[] = $record->usage;
111+
$row[] = userdate($record->timecreated, get_string('strftimerecentfull'));
112+
$row[] = userdate($record->timeexpired, get_string('strftimerecentfull'));
113+
$table->data[] = $row;
114+
}
115+
echo html_writer::table($table);
116+
$baseurl = new moodle_url('/auth/basic/masterpassword.php', array('perpage' => $perpage));
117+
echo $OUTPUT->paging_bar($total, $page, $perpage, $baseurl);
118+
}
119+
}
120+
121+
122+
123+
echo $OUTPUT->footer();

‎settings.php

+13
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424

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

27+
$ADMIN->add('authsettings', new admin_category('auth_basic', get_string('pluginname', 'auth_basic')));
28+
$settings = new admin_settingpage($section, get_string('menusettings', 'auth_basic'), 'moodle/site:config');
29+
2730
if ($ADMIN->fulltree) {
2831

2932
$yesno = array(get_string('no'), get_string('yes'));
@@ -44,3 +47,13 @@
4447
);
4548

4649
}
50+
$ADMIN->add('auth_basic', $settings);
51+
$settings = null;
52+
53+
$temp = new admin_externalpage(
54+
'auth_basic_masterpassword',
55+
get_string('masterpassword', 'auth_basic'),
56+
new moodle_url($CFG->wwwroot.'/auth/basic/masterpassword.php')
57+
);
58+
59+
$ADMIN->add('auth_basic', $temp);

‎version.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424

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

27-
$plugin->version = 2018070200; // The current plugin version (Date: YYYYMMDDXX).
28-
$plugin->release = 2018070200; // Match release exactly to version.
27+
$plugin->version = 2018121400; // The current plugin version (Date: YYYYMMDDXX).
28+
$plugin->release = 2018121400; // Match release exactly to version.
2929
$plugin->requires = 2014050800; // Requires this Moodle version.
3030
$plugin->component = 'auth_basic'; // Full name of the plugin (used for diagnostics).
3131
$plugin->maturity = MATURITY_STABLE;

0 commit comments

Comments
 (0)
Please sign in to comment.