Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 132 additions & 2 deletions _test/helper.test.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,24 @@ class helper_plugin_passpolicy_test extends DokuWikiTest {

protected $pluginsEnabled = array('passpolicy');

public function newPolicy($minl, $minp, $lower, $upper, $num, $special, $ucheck, $pron=true) {
/**
*
* @param int $minl
* @param int $minp
* @param boolean $lower
* @param boolean $upper
* @param boolean $num
* @param boolean $special
* @param boolean $ucheck
* @param boolean $pron
* @param int $oldpass
* @param int $expire_days
* @param int $expirewarn_days
* @param string $data_start date YYYY-MM-DD
* @return helper_plugin_passpolicy
*/
public function newPolicy($minl, $minp, $lower, $upper, $num, $special, $ucheck, $pron=true,$oldpass=0,$date_start='2030-01-01',$expire_days=0,$expirewarn_days=2) {
/* @var $policy helper_plugin_passpolicy */
$policy = plugin_load('helper', 'passpolicy');
$policy->min_pools = $minp;
$policy->min_length = $minl;
Expand All @@ -18,10 +35,25 @@ public function newPolicy($minl, $minp, $lower, $upper, $num, $special, $ucheck,
'special' => $special
);
$policy->usernamecheck = $ucheck;
$policy->pronouncable = $pron;
$policy->pronouncable = $pron;

$policy->oldpass = $oldpass;
$policy->conf['oldpass'] = $oldpass;
$policy->conf['expire'] = $expire_days;
$policy->conf['expirewarn'] = $expirewarn_days;
$policy->conf['date_start'] = $date_start;

return $policy;
}

public function changePass($pass,$user = 'testuser') {
global $auth;

return $auth->triggerUserMod('modify',array(
$user,
array('pass'=>$pass)
));
}

public function test_policies() {
$policy = $this->newPolicy(6, 1, true, true, true, true, 0);
Expand Down Expand Up @@ -173,5 +205,103 @@ public function test_selfcheck() {

//echo "\n$pw1\n$pw2\n";
}

public function test_passhistory() {

$policy = $this->newPolicy(6, 4, true, true, true, true, 0, true,2);
$pw1 = $policy->generatePassword('testuser');
$pw2 = $policy->generatePassword('testuser');
$pw3 = $policy->generatePassword('testuser');

$this->assertTrue($this->changePass($pw1),'cannot change password');
$this->assertNull($this->changePass($pw1),'last password can be used');
$this->assertTrue($this->changePass($pw2),'cannot change password');
$this->assertNull($this->changePass($pw1),'second last password can be used');
$this->assertTrue($this->changePass($pw3),'cannot change password');
$this->assertTrue($this->changePass($pw1),'third last password can be used');
$this->assertNull($this->changePass($pw3),'second last password can be used');

//$policy = $this->newPolicy(18, 1, true, false, false, false, 0, false,0,0,2,date('Y-m-d',time()+3600*2));

}

public function test_pass_expire() {
$policy = $this->newPolicy(6, 4, true, true, true, true, 0, true,
0, //oldpass
'2010-01-01', //$date_start
2,//expire_days=0
0//expirewarn_days
);

$userFile = $policy->passhistorydir .'testuser.txt';

TestUtils::rdelete($userFile);
$this->assertEquals(strtotime($policy->getConf('date_start')),$policy->checkPasswordExpired('testuser'));
$this->assertFalse($policy->checkPasswordExpireWarn('testuser'));

touch($userFile,time());
$this->assertFalse($policy->checkPasswordExpired('testuser'));
$this->assertFalse($policy->checkPasswordExpireWarn('testuser'));
TestUtils::rdelete($userFile);

$changedTime = time() - 3600*48-1;
touch($userFile,$changedTime);
$this->assertEquals($changedTime+3600*48,$policy->checkPasswordExpired('testuser'),'password is not expired');
$this->assertFalse($policy->checkPasswordExpireWarn('testuser'));

}

public function test_pass_expire_warn() {
$policy = $this->newPolicy(6, 4, true, true, true, true, 0, true,
0, //oldpass
'2010-01-01', //$date_start
14,//expire_days=0
2//expirewarn_days
);

$userFile = $policy->passhistorydir .'testuser.txt';

TestUtils::rdelete($userFile);
$this->assertEquals(strtotime($policy->getConf('date_start')),$policy->checkPasswordExpireWarn('testuser'));

touch($userFile,time());
$this->assertFalse($policy->checkPasswordExpired('testuser'));
$this->assertFalse($policy->checkPasswordExpireWarn('testuser'));
TestUtils::rdelete($userFile);

$changedTime = time() - 3600*24*12-1;
touch($userFile,$changedTime);
$this->assertFalse($policy->checkPasswordExpired('testuser'));
$this->assertEquals($changedTime+3600*24*14,$policy->checkPasswordExpireWarn('testuser'),'we have to warn!');

}

public function test_pass_date_start() {
$policy = $this->newPolicy(6, 4, true, true, true, true, 0, true,
0, //oldpass
date('Y-m-d',time()+3600*24*5), //$date_start
2,//expire_days=0
6//expirewarn_days
);

$userFile = $policy->passhistorydir .'testuser.txt';
TestUtils::rdelete($userFile);

$this->assertEquals(strtotime($policy->getConf('date_start')),$policy->checkPasswordExpireWarn('testuser'),'we have to warn!');
$this->assertFalse($policy->checkPasswordExpired('testuser'),'date start is in future');

$policy = $this->newPolicy(6, 4, true, true, true, true, 0, true,
0, //oldpass
date('Y-m-d',time()+3600*24*5), //$date_start
2,//expire_days=0
4//expirewarn_days
);

$userFile = $policy->passhistorydir .'testuser.txt';

$this->assertFalse($policy->checkPasswordExpireWarn('testuser'),'its not time to warn');
$this->assertFalse($policy->checkPasswordExpired('testuser'),'date start is in future');

}
}

69 changes: 68 additions & 1 deletion action.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,75 @@ public function register(Doku_Event_Handler &$controller) {
$controller->register_hook('HTML_RESENDPWDFORM_OUTPUT', 'BEFORE', $this, 'handle_forms');

$controller->register_hook('AUTH_USER_CHANGE', 'BEFORE', $this, 'handle_passchange');
$controller->register_hook('AUTH_USER_CHANGE', 'BEFORE', $this, 'save_pass');

$controller->register_hook('AUTH_PASSWORD_GENERATE', 'BEFORE', $this, 'handle_passgen');

$controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, '_ajax_call');

$controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'check_act');


}

/**
* Handles the warn message and redirects user to the profile page in case of password expired
*
* @param Doku_Event $event
* @param unknown $param
*/
function check_act(Doku_Event &$event,$param) {
if(!$_SERVER['REMOTE_USER']) return;

if(in_array($event->data,array('login','logout','profile','admin'))) return;

/* @var $passpolicy helper_plugin_passpolicy */
$passpolicy = $this->loadHelper('passpolicy');

if($expireDate = $passpolicy->checkPasswordExpired()) { //password is expired
msg(sprintf($this->getLang('expired'), dformat($expireDate)));
$event->data = 'profile';
} else if($expireDate = $passpolicy->checkPasswordExpireWarn()) { //show warn message
if(!isset($_COOKIE['passpolicy_msg_hide'])) {
msg(sprintf($this->getLang('expirewarn'), dformat($expireDate),tpl_action('profile',1,false,true)));
}

}

}

/**
* Save the password to the pass history
*
* @param Doku_Event $event
* @param unknown $param
*/
function save_pass(Doku_Event &$event,$param) {
if($event->data['type'] == 'create') {
$user = $event->data['params'][0];
$pass = $event->data['params'][1];
} elseif($event->data['type'] == 'modify') {
$user = $event->data['params'][0];
if(!isset($event->data['params'][1]['pass'])) {
return; //password is not changed, nothing to do
}
$pass = $event->data['params'][1]['pass'];
} else {
return;
}

/* @var $passpolicy helper_plugin_passpolicy */
$passpolicy = $this->loadHelper('passpolicy');

$passpolicy->savePassword2PassHistory($user,$pass);
}

/**
* Check for password policy
*
* @param Doku_Event $event
* @param unknown $param
*/
function _ajax_call(Doku_Event &$event,$param) {
if ($event->data !== 'plugin_passpolicy') {
return;
Expand All @@ -42,10 +105,13 @@ function _ajax_call(Doku_Event &$event,$param) {

/* @var $INPUT \Input */
global $INPUT;
$user = $INPUT->post->str('user',$_SERVER['REMOTE_USER']);
$pass = $INPUT->post->str('pass');



$passpolicy = $this->loadHelper('passpolicy');
if(!$passpolicy->checkPolicy($pass, $_SERVER['REMOTE_USER'])) {
if(!$passpolicy->checkPolicy($pass, $user)) {
// passpolicy not matched, throw error
echo '0';
} else {
Expand All @@ -70,6 +136,7 @@ public function handle_forms(Doku_Event &$event, $param) {
$passpolicy = plugin_load('helper', 'passpolicy');
$html = '<p class="passpolicy_hint">'.$passpolicy->explainPolicy().'</p>';
$event->data->insertElement(++$pos, $html);

}

/**
Expand Down
6 changes: 6 additions & 0 deletions conf/default.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,9 @@

$conf['autotype'] = 'random';
$conf['autobits'] = 44;


$conf['oldpass'] = 0;
$conf['expire'] = 90;
$conf['expirewarn'] = 2;
$conf['date_start'] = '2030-01-01';
7 changes: 7 additions & 0 deletions conf/metadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,10 @@

$meta['autotype'] = array('multichoice', '_choices' => array('random', 'phrase', 'pronouncable'));
$meta['autobits'] = array('numeric', '_min' => 24);

$meta['oldpass'] = array('numeric', '_min' => 0);
$meta['expire'] = array('numeric', '_min' => 0); //days
$meta['expirewarn'] = array('numeric', '_min' => 0); //days before expire
$meta['date_start'] = array('string', '_pattern' => '/20\d{2}-\d{2}-\d{2}/');


Loading