Skip to content

Commit

Permalink
Merge branch 'MDL-42816-master' of https://github.com/StudiUM/moodle
Browse files Browse the repository at this point in the history
  • Loading branch information
stronk7 committed Apr 1, 2014
2 parents 929e324 + 2d35b7d commit 57c92af
Show file tree
Hide file tree
Showing 7 changed files with 309 additions and 6 deletions.
53 changes: 51 additions & 2 deletions auth/manual/auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,17 @@
*/
class auth_plugin_manual extends auth_plugin_base {

/**
* The name of the component. Used by the configuration.
*/
const COMPONENT_NAME = 'auth_manual';

/**
* Constructor.
*/
function auth_plugin_manual() {
$this->authtype = 'manual';
$this->config = get_config('auth/manual');
$this->config = get_config(self::COMPONENT_NAME);
}

/**
Expand Down Expand Up @@ -81,6 +86,7 @@ function user_login($username, $password) {
*/
function user_update_password($user, $newpassword) {
$user = get_complete_user_data('id', $user->id);
set_user_preference('auth_manual_passwordupdatetime', time(), $user->id);
// This will also update the stored hash to the latest algorithm
// if the existing hash is using an out-of-date algorithm (or the
// legacy md5 algorithm).
Expand Down Expand Up @@ -153,13 +159,56 @@ function config_form($config, $err, $user_fields) {
include 'config.html';
}

/**
* Return number of days to user password expires.
*
* If user password does not expire, it should return 0 or a positive value.
* If user password is already expired, it should return negative value.
*
* @param mixed $username username (with system magic quotes)
* @return integer
*/
public function password_expire($username) {
$result = 0;

if (!empty($this->config->expirationtime)) {
$user = core_user::get_user_by_username($username, 'id,timecreated');
$lastpasswordupdatetime = get_user_preferences('auth_manual_passwordupdatetime', $user->timecreated, $user->id);
$expiretime = $lastpasswordupdatetime + $this->config->expirationtime * DAYSECS;
$now = time();
$result = ($expiretime - $now) / DAYSECS;
if ($expiretime > $now) {
$result = ceil($result);
} else {
$result = floor($result);
}
}

return $result;
}

/**
* Processes and stores configuration data for this authentication plugin.
*
* @param array $config
* @param stdClass $config
* @return void
*/
function process_config($config) {
// Set to defaults if undefined.
if (!isset($config->expiration)) {
$config->expiration = '';
}
if (!isset($config->expiration_warning)) {
$config->expiration_warning = '';
}
if (!isset($config->expirationtime)) {
$config->expirationtime = '';
}

// Save settings.
set_config('expiration', $config->expiration, self::COMPONENT_NAME);
set_config('expiration_warning', $config->expiration_warning, self::COMPONENT_NAME);
set_config('expirationtime', $config->expirationtime, self::COMPONENT_NAME);
return true;
}

Expand Down
77 changes: 75 additions & 2 deletions auth/manual/config.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,78 @@
<table cellspacing="0" cellpadding="5" border="0">
<?php
print_auth_lock_options($this->authtype, $user_fields, get_string('auth_fieldlocks_help', 'auth'), false, false);
// Set to defaults if undefined.
if (!isset($config->expiration)) {
$config->expiration = '';
}
if (!isset($config->expiration_warning)) {
$config->expiration_warning = '';
}
if (!isset($config->expirationtime)) {
$config->expirationtime = '';
}
$expirationoptions = array(
new lang_string('no'),
new lang_string('yes'),
);
$expirationtimeoptions = array(
'30' => new lang_string('numdays', '', 30),
'60' => new lang_string('numdays', '', 60),
'90' => new lang_string('numdays', '', 90),
'120' => new lang_string('numdays', '', 120),
'150' => new lang_string('numdays', '', 150),
'180' => new lang_string('numdays', '', 180),
'365' => new lang_string('numdays', '', 365),
);
$expirationwarningoptions = array(
'0' => new lang_string('never'),
'1' => new lang_string('numdays', '', 1),
'2' => new lang_string('numdays', '', 2),
'3' => new lang_string('numdays', '', 3),
'4' => new lang_string('numdays', '', 4),
'5' => new lang_string('numdays', '', 5),
'6' => new lang_string('numdays', '', 6),
'7' => new lang_string('numdays', '', 7),
'10' => new lang_string('numdays', '', 10),
'14' => new lang_string('numdays', '', 14),
);
?>
<table cellspacing="0" cellpadding="5" border="0">
<tr>
<td colspan="3">
<h3><?php print_string('passwdexpire_settings', 'auth_manual') ?></h3>
</td>
</tr>
<tr>
<td align="right">
<label for="menuexpiration">
<?php print_string('expiration', 'auth_manual') ?>
</label>
</td>
<td>
<?php echo html_writer::select($expirationoptions, 'expiration', $config->expiration, false) ?>
</td>
<td><?php print_string('expiration_desc', 'auth_manual') ?></td>
</tr>
<tr>
<td align="right">
<label for="menuexpirationtime">
<?php print_string('passwdexpiretime', 'auth_manual') ?>
</label>
</td>
<td>
<?php echo html_writer::select($expirationtimeoptions, 'expirationtime', $config->expirationtime, false) ?>
</td>
<td><?php print_string('passwdexpiretime_desc', 'auth_manual') ?></td>
</tr>
<tr>
<td align="right">
<label for="menuexpiration_warning">
<?php print_string('expiration_warning', 'auth_manual') ?>
</label>
</td>
<td>
<?php echo html_writer::select($expirationwarningoptions, 'expiration_warning', $config->expiration_warning, false) ?>
</td>
<td><?php print_string('expiration_warning_desc', 'auth_manual') ?></td>
</tr>
<?php print_auth_lock_options($this->authtype, $user_fields, get_string('auth_fieldlocks_help', 'auth'), false, false) ?>
</table>
7 changes: 7 additions & 0 deletions auth/manual/lang/en/auth_manual.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,11 @@
*/

$string['auth_manualdescription'] = 'This method removes any way for users to create their own accounts. All accounts must be manually created by the admin user.';
$string['expiration'] = 'Enable password expiry';
$string['expiration_desc'] = 'Allow passwords to expire after a specified time.';
$string['expiration_warning'] = 'Notification threshold';
$string['expiration_warning_desc'] = 'Number of days before password expiry that a notification is issued.';
$string['passwdexpiretime'] = 'Password duration';
$string['passwdexpiretime_desc'] = 'Length of time for which a password is valid.';
$string['pluginname'] = 'Manual accounts';
$string['passwdexpire_settings'] = 'Password expiry settings';
108 changes: 108 additions & 0 deletions auth/manual/tests/manual_test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?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/>.

/**
* Manual authentication tests.
*
* @package auth_manual
* @category test
* @copyright 2014 Gilles-Philippe Leblanc <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

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

global $CFG;
require_once($CFG->dirroot.'/auth/manual/auth.php');

/**
* Manual authentication tests class.
*
* @package auth_manual
* @category test
* @copyright 2014 Gilles-Philippe Leblanc <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class auth_manual_testcase extends advanced_testcase {

/** @var auth_plugin_manual Keeps the authentication plugin. */
protected $authplugin;

/** @var stdClass Keeps authentication plugin config */
protected $config;

/**
* Setup test data.
*/
protected function setUp() {
$this->resetAfterTest(true);
$this->authplugin = new auth_plugin_manual();
$this->config = new stdClass();
$this->config->expiration = '1';
$this->config->expiration_warning = '2';
$this->config->expirationtime = '30';
$this->authplugin->process_config($this->config);
$this->authplugin->config = get_config(auth_plugin_manual::COMPONENT_NAME);
}

/**
* Test user_update_password method.
*/
public function test_user_update_password() {
$user = $this->getDataGenerator()->create_user();
$expectedtime = time();
$passwordisupdated = $this->authplugin->user_update_password($user, 'MyNewPassword*');

// Assert that the actual time should be equal or a little greater than the expected time.
$this->assertGreaterThanOrEqual($expectedtime, get_user_preferences('auth_manual_passwordupdatetime', 0, $user->id));

// Assert that the password was successfully updated.
$this->assertTrue($passwordisupdated);
}

/**
* Test test_password_expire method.
*/
public function test_password_expire() {
$userrecord = array();
$expirationtime = 31 * DAYSECS;
$userrecord['timecreated'] = time() - $expirationtime;
$user1 = $this->getDataGenerator()->create_user($userrecord);
$user2 = $this->getDataGenerator()->create_user();

// The user 1 was created 31 days ago and has not changed his password yet, so the password has expirated.
$this->assertLessThanOrEqual(-1, $this->authplugin->password_expire($user1->username));

// The user 2 just came to be created and has not changed his password yet, so the password has not expirated.
$this->assertEquals(30, $this->authplugin->password_expire($user2->username));

$this->authplugin->user_update_password($user1, 'MyNewPassword*');

// The user 1 just updated his password so the password has not expirated.
$this->assertEquals(30, $this->authplugin->password_expire($user1->username));
}

/**
* Test test_process_config method.
*/
public function test_process_config() {
$this->assertTrue($this->authplugin->process_config($this->config));
$config = get_config(auth_plugin_manual::COMPONENT_NAME);
$this->assertEquals($this->config->expiration, $config->expiration);
$this->assertEquals($this->config->expiration_warning, $config->expiration_warning);
$this->assertEquals($this->config->expirationtime, $config->expirationtime);
}
}
25 changes: 25 additions & 0 deletions lib/classes/user.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,31 @@ public static function get_user($userid, $fields = '*', $strictness = IGNORE_MIS
}
}


/**
* Return user object from db based on their username.
*
* @param string $username The username of the user searched.
* @param string $fields A comma separated list of user fields to be returned, support and noreply user.
* @param int $mnethostid The id of the remote host.
* @param int $strictness IGNORE_MISSING means compatible mode, false returned if user not found, debug message if more found;
* IGNORE_MULTIPLE means return first user, ignore multiple user records found(not recommended);
* MUST_EXIST means throw an exception if no user record or multiple records found.
* @return stdClass|bool user record if found, else false.
* @throws dml_exception if user record not found and respective $strictness is set.
*/
public static function get_user_by_username($username, $fields = '*', $mnethostid = null, $strictness = IGNORE_MISSING) {
global $DB, $CFG;

// Because we use the username as the search criteria, we must also restrict our search based on mnet host.
if (empty($mnethostid)) {
// If empty, we restrict to local users.
$mnethostid = $CFG->mnet_localhost_id;
}

return $DB->get_record('user', array('username' => $username, 'mnethostid' => $mnethostid), $fields, $strictness);
}

/**
* Helper function to return dummy noreply user record.
*
Expand Down
5 changes: 4 additions & 1 deletion lib/testing/generator/data_generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,10 @@ public function create_user($record=null, array $options=null) {
$record['deleted'] = 0;
}

$record['timecreated'] = time();
if (!isset($record['timecreated'])) {
$record['timecreated'] = time();
}

$record['timemodified'] = $record['timecreated'];
$record['lastip'] = '0.0.0.0';

Expand Down
40 changes: 39 additions & 1 deletion lib/tests/user_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,16 @@
*/
class core_user_testcase extends advanced_testcase {

/**
* Setup test data.
*/
protected function setUp() {
$this->resetAfterTest(true);
}

public function test_get_user() {
global $CFG;

$this->resetAfterTest(true);

// Create user and try fetach it with api.
$user = $this->getDataGenerator()->create_user();
Expand Down Expand Up @@ -78,4 +84,36 @@ public function test_get_user() {
$this->assertEquals($user, $supportuser);
$this->assertTrue(core_user::is_real_user($supportuser->id));
}

/**
* Test get_user_by_username method.
*/
public function test_get_user_by_username() {
$record = array();
$record['username'] = 'johndoe';
$record['email'] = '[email protected]';
$record['timecreated'] = time();

// Create a default user for the test.
$userexpected = $this->getDataGenerator()->create_user($record);

// Assert that the returned user is the espected one.
$this->assertEquals($userexpected, core_user::get_user_by_username('johndoe'));

// Assert that a subset of fields is correctly returned.
$this->assertEquals((object) $record, core_user::get_user_by_username('johndoe', 'username,email,timecreated'));

// Assert that a user with a different mnethostid will no be returned.
$this->assertFalse(core_user::get_user_by_username('johndoe', 'username,email,timecreated', 2));

// Create a new user from a different host.
$record['mnethostid'] = 2;
$userexpected2 = $this->getDataGenerator()->create_user($record);

// Assert that the new user is returned when specified the correct mnethostid.
$this->assertEquals($userexpected2, core_user::get_user_by_username('johndoe', '*', 2));

// Assert that a user not in the db return false.
$this->assertFalse(core_user::get_user_by_username('janedoe'));
}
}

0 comments on commit 57c92af

Please sign in to comment.