Skip to content
Snippets Groups Projects
Commit 395e7d8e authored by Andreas Gohr's avatar Andreas Gohr
Browse files

Merge branch 'pull-request-245'

* pull-request-245:
  coding corrections. correct type hint, remove unused variable assignment
  HTTPClient don't pull too much bytes when no content-length is given
  de/de-informal: localization updates (delete user function)
  unit tests for self deleting of user accounts
  FS#2751 - self deletion of user account

Conflicts:
	inc/lang/de-informal/lang.php
	inc/lang/de/lang.php
parents 5b230a45 836a1762
No related branches found
No related tags found
No related merge requests found
<?php
class Mock_Auth_Plugin extends DokuWiki_Auth_Plugin {
public $loggedOff = false;
public function __construct($canDeleteUser = true) {
$this->cando['delUser'] = $canDeleteUser;
}
public function checkPass($user, $pass) {
return $pass == 'password';
}
public function deleteUsers($users) {
return in_array($_SERVER['REMOTE_USER'], $users);
}
public function logoff() {
$this->loggedOff = true;
}
}
class auth_deleteprofile_test extends DokuWikiTest {
/*
* Tests:
*
* 1. It works and the user is logged off
* 2. Password matches when config requires it
* 3,4. Auth plugin can prevent & wiki config can prevent
* 5. Any of invalid security token, missing/not set 'delete' flag, missing/unchecked 'confirm_delete'
*
*/
function test_success() {
global $ACT, $INPUT, $conf, $auth;
$ACT = 'profile_delete';
$conf['profileconfirm'] = false;
$_SERVER['REMOTE_USER'] = 'testuser';
$input = array(
'do' => $ACT,
'sectok' => getSecurityToken(),
'delete' => '1',
'confirm_delete' => '1',
);
$_POST = $input;
$_REQUEST = $input;
$INPUT = new Input();
$auth = new Mock_Auth_Plugin();
$this->assertTrue(auth_deleteprofile());
$this->assertTrue($auth->loggedOff);
}
function test_confirmation_required() {
global $ACT, $INPUT, $conf, $auth;
$ACT = 'profile_delete';
$conf['profileconfirm'] = true;
$_SERVER['REMOTE_USER'] = 'testuser';
$input = array(
'do' => $ACT,
'sectok' => getSecurityToken(),
'delete' => '1',
'confirm_delete' => '1',
'oldpass' => 'wrong',
);
$_POST = $input;
$_REQUEST = $input;
$INPUT = new Input();
$auth = new Mock_Auth_Plugin();
// password check required - it fails, so don't delete profile
$this->assertFalse(auth_deleteprofile());
// now it passes, we're good to go
$INPUT->set('oldpass','password');
$INPUT->post->set('oldpass','password');
$this->assertTrue(auth_deleteprofile());
}
function test_authconfig_prevents() {
global $ACT, $INPUT, $conf, $auth;
$ACT = 'profile_delete';
$conf['profileconfirm'] = false;
$_SERVER['REMOTE_USER'] = 'testuser';
$input = array(
'do' => $ACT,
'sectok' => getSecurityToken(),
'delete' => '1',
'confirm_delete' => '1',
);
$_POST = $input;
$_REQUEST = $input;
$INPUT = new Input();
$auth = new Mock_Auth_Plugin(false);
$conf['disableactions'] = '';
$this->assertFalse(auth_deleteprofile());
}
function test_wikiconfig_prevents() {
global $ACT, $INPUT, $conf, $auth;
$ACT = 'profile_delete';
$conf['profileconfirm'] = false;
$_SERVER['REMOTE_USER'] = 'testuser';
$input = array(
'do' => $ACT,
'sectok' => getSecurityToken(),
'delete' => '1',
'confirm_delete' => '1',
);
$_POST = $input;
$_REQUEST = $input;
$INPUT = new Input();
$auth = new Mock_Auth_Plugin();
$conf['disableactions'] = 'profile_delete';
$this->assertFalse(actionOK('profile_delete'));
$this->assertTrue($auth->canDo('delUser'));
$this->assertFalse(auth_deleteprofile());
}
function test_basic_parameters() {
global $ACT, $INPUT, $conf, $auth;
$ACT = 'profile_delete';
$conf['profileconfirm'] = true;
$_SERVER['REMOTE_USER'] = 'testuser';
$input = array(
'do' => $ACT,
'sectok' => getSecurityToken(),
'delete' => '1',
'confirm_delete' => '1',
'oldpass' => 'password',
);
$_POST = $input;
$_REQUEST = $input;
$input_foundation = new Input();
$auth = new Mock_Auth_Plugin();
$INPUT = clone $input_foundation;
$INPUT->remove('delete');
$this->assertFalse(auth_deleteprofile());
$INPUT = clone $input_foundation;
$INPUT->set('sectok','wrong');
$this->assertFalse(auth_deleteprofile());
$INPUT = clone $input_foundation;
$INPUT->remove('confirm_delete');
$this->assertFalse(auth_deleteprofile());
}
}
\ No newline at end of file
......@@ -92,14 +92,26 @@ function act_dispatch(){
$ACT = 'login';
}
//update user profile
if ($ACT == 'profile') {
// user profile changes
if (in_array($ACT, array('profile','profile_delete'))) {
if(!$_SERVER['REMOTE_USER']) {
$ACT = 'login';
} else {
if(updateprofile()) {
msg($lang['profchanged'],1);
$ACT = 'show';
switch ($ACT) {
case 'profile' :
if(updateprofile()) {
msg($lang['profchanged'],1);
$ACT = 'show';
}
break;
case 'profile_delete' :
if(auth_deleteprofile()){
msg($lang['profdeleted'],1);
$ACT = 'show';
} else {
$ACT = 'profile';
}
break;
}
}
}
......@@ -247,7 +259,7 @@ function act_validate($act) {
//disable all acl related commands if ACL is disabled
if(!$conf['useacl'] && in_array($act,array('login','logout','register','admin',
'subscribe','unsubscribe','profile','revert',
'resendpwd'))){
'resendpwd','profile_delete'))){
msg('Command unavailable: '.htmlspecialchars($act),-1);
return 'show';
}
......@@ -258,7 +270,7 @@ function act_validate($act) {
if(!in_array($act,array('login','logout','register','save','cancel','edit','draft',
'preview','search','show','check','index','revisions',
'diff','recent','backlink','admin','subscribe','revert',
'unsubscribe','profile','resendpwd','recover',
'unsubscribe','profile','profile_delete','resendpwd','recover',
'draftdel','sitemap','media')) && substr($act,0,7) != 'export_' ) {
msg('Command unknown: '.htmlspecialchars($act),-1);
return 'show';
......@@ -287,7 +299,7 @@ function act_permcheck($act){
}else{
$permneed = AUTH_CREATE;
}
}elseif(in_array($act,array('login','search','recent','profile','index', 'sitemap'))){
}elseif(in_array($act,array('login','search','recent','profile','profile_delete','index', 'sitemap'))){
$permneed = AUTH_NONE;
}elseif($act == 'revert'){
$permneed = AUTH_ADMIN;
......
......@@ -1042,6 +1042,45 @@ function updateprofile() {
return false;
}
function auth_deleteprofile(){
global $conf;
global $lang;
/* @var DokuWiki_Auth_Plugin $auth */
global $auth;
/* @var Input $INPUT */
global $INPUT;
if(!$INPUT->post->bool('delete')) return false;
if(!checkSecurityToken()) return false;
// action prevented or auth module disallows
if(!actionOK('profile_delete') || !$auth->canDo('delUser')) {
msg($lang['profnodelete'], -1);
return false;
}
if(!$INPUT->post->bool('confirm_delete')){
msg($lang['profconfdeletemissing'], -1);
return false;
}
if($conf['profileconfirm']) {
if(!$auth->checkPass($_SERVER['REMOTE_USER'], $INPUT->post->str('oldpass'))) {
msg($lang['badpassconfirm'], -1);
return false;
}
}
$deleted[] = $_SERVER['REMOTE_USER'];
if($auth->triggerUserMod('delete', array($deleted))) {
// force and immediate logout including removing the sticky cookie
auth_logoff();
return true;
}
return false;
}
/**
* Send a new password
*
......
......@@ -241,7 +241,7 @@ function getConfigFiles($type) {
*/
function actionOK($action){
static $disabled = null;
if(is_null($disabled)){
if(is_null($disabled) || defined('SIMPLE_TEST')){
global $conf;
/** @var auth_basic $auth */
global $auth;
......@@ -261,6 +261,9 @@ function actionOK($action){
if (is_null($auth) || !$auth->canDo('Profile')) {
$disabled[] = 'profile';
}
if (is_null($auth) || !$auth->canDo('delUser')) {
$disabled[] = 'profile_delete';
}
if (is_null($auth)) {
$disabled[] = 'login';
}
......
......@@ -1390,6 +1390,23 @@ function html_updateprofile(){
$form->endFieldset();
html_form('updateprofile', $form);
if ($auth->canDo('delUser') && actionOK('profile_delete')) {
$form_profiledelete = new Doku_Form(array('id' => 'dw__profiledelete'));
$form_profiledelete->startFieldset($lang['profdeleteuser']);
$form_profiledelete->addHidden('do', 'profile_delete');
$form_profiledelete->addHidden('delete', '1');
$form_profiledelete->addElement(form_makeCheckboxField('confirm_delete', '1', $lang['profconfdelete'],'dw__confirmdelete','', array('required' => 'required')));
if ($conf['profileconfirm']) {
$form_profiledelete->addElement(form_makeTag('br'));
$form_profiledelete->addElement(form_makePasswordField('oldpass', $lang['oldpass'], '', 'block', array('size'=>'50', 'required' => 'required')));
}
$form_profiledelete->addElement(form_makeButton('submit', '', $lang['btn_deleteuser']));
$form_profiledelete->endFieldset();
html_form('profiledelete', $form_profiledelete);
}
print '</div>'.NL;
}
......
......@@ -64,6 +64,7 @@ $lang['btn_revert'] = 'Wiederherstellen';
$lang['btn_register'] = 'Registrieren';
$lang['btn_apply'] = 'Übernehmen';
$lang['btn_media'] = 'Medien-Manager';
$lang['btn_deleteuser'] = 'Benutzerprofil löschen';
$lang['loggedinas'] = 'Angemeldet als';
$lang['user'] = 'Benutzername';
$lang['pass'] = 'Passwort';
......@@ -75,6 +76,7 @@ $lang['fullname'] = 'Voller Name';
$lang['email'] = 'E-Mail';
$lang['profile'] = 'Benutzerprofil';
$lang['badlogin'] = 'Benutzername oder Passwort sind falsch.';
$lang['badpassconfirm'] = 'Das Passwort war falsch.';
$lang['minoredit'] = 'Kleine Änderung';
$lang['draftdate'] = 'Entwurf gespeichert am';
$lang['nosecedit'] = 'Diese Seite wurde in der Zwischenzeit geändert, da das Sektionsinfo veraltet ist. Die ganze Seite wird stattdessen geladen.';
......@@ -91,6 +93,11 @@ $lang['profna'] = 'Änderung des Benutzerprofils in diesem Wiki n
$lang['profnochange'] = 'Keine Änderungen, nichts zu tun.';
$lang['profnoempty'] = 'Es muss ein Name oder eine E-Mail Adresse angegeben werden.';
$lang['profchanged'] = 'Benutzerprofil erfolgreich geändert.';
$lang['profnodelete'] = 'Dieses Wiki unterstützt nicht das Löschen von Benutzern.';
$lang['profdeleteuser'] = 'Benutzerprofil löschen';
$lang['profdeleted'] = 'Dein Benutzerprofil wurde im Wiki gelöscht.';
$lang['profconfdelete'] = 'Ich möchte mein Benutzerprofil löschen.<br/> Diese Aktion ist nicht umkehrbar.';
$lang['profconfdeletemissing'] = 'Bestätigungs-Checkbox wurde nicht angehakt.';
$lang['pwdforget'] = 'Passwort vergessen? Fordere ein neues an';
$lang['resendna'] = 'Passwörter versenden ist in diesem Wiki nicht möglich.';
$lang['resendpwd'] = 'Neues Passwort setzen für';
......
......@@ -65,6 +65,7 @@ $lang['btn_revert'] = 'Wiederherstellen';
$lang['btn_register'] = 'Registrieren';
$lang['btn_apply'] = 'Übernehmen';
$lang['btn_media'] = 'Medien-Manager';
$lang['btn_deleteuser'] = 'Benutzerprofil löschen';
$lang['loggedinas'] = 'Angemeldet als';
$lang['user'] = 'Benutzername';
$lang['pass'] = 'Passwort';
......@@ -76,6 +77,7 @@ $lang['fullname'] = 'Voller Name';
$lang['email'] = 'E-Mail';
$lang['profile'] = 'Benutzerprofil';
$lang['badlogin'] = 'Benutzername oder Passwort sind falsch.';
$lang['badpassconfirm'] = 'Das Passwort war falsch.';
$lang['minoredit'] = 'kleine Änderung';
$lang['draftdate'] = 'Entwurf gespeichert am';
$lang['nosecedit'] = 'Diese Seite wurde in der Zwischenzeit geändert, Sektionsinfo ist veraltet, lade stattdessen volle Seite.';
......@@ -92,6 +94,11 @@ $lang['profna'] = 'Änderung des Benutzerprofils in diesem Wiki n
$lang['profnochange'] = 'Keine Änderungen, nichts zu tun.';
$lang['profnoempty'] = 'Es muss ein Name und eine E-Mail-Adresse angegeben werden.';
$lang['profchanged'] = 'Benutzerprofil erfolgreich geändert.';
$lang['profnodelete'] = 'Dieses Wiki unterstützt nicht das Löschen von Benutzern.';
$lang['profdeleteuser'] = 'Benutzerprofil löschen';
$lang['profdeleted'] = 'Ihr Benutzerprofil wurde im Wiki gelöscht.';
$lang['profconfdelete'] = 'Ich möchte mein Benutzerprofil löschen.<br/> Diese Aktion ist nicht umkehrbar.';
$lang['profconfdeletemissing'] = 'Bestätigungs-Checkbox wurde nicht angehakt.';
$lang['pwdforget'] = 'Passwort vergessen? Fordere ein neues an';
$lang['resendna'] = 'Passwörter versenden ist in diesem Wiki nicht möglich.';
$lang['resendpwd'] = 'Neues Passwort setzen für';
......
......@@ -51,6 +51,7 @@ $lang['btn_revert'] = 'Restore';
$lang['btn_register'] = 'Register';
$lang['btn_apply'] = 'Apply';
$lang['btn_media'] = 'Media Manager';
$lang['btn_deleteuser'] = 'Remove My Account';
$lang['loggedinas'] = 'Logged in as';
$lang['user'] = 'Username';
......@@ -63,6 +64,7 @@ $lang['fullname'] = 'Real name';
$lang['email'] = 'E-Mail';
$lang['profile'] = 'User Profile';
$lang['badlogin'] = 'Sorry, username or password was wrong.';
$lang['badpassconfirm'] = 'Sorry, the password was wrong';
$lang['minoredit'] = 'Minor Changes';
$lang['draftdate'] = 'Draft autosaved on'; // full dformat date will be added
$lang['nosecedit'] = 'The page was changed in the meantime, section info was out of date loaded full page instead.';
......@@ -81,6 +83,11 @@ $lang['profna'] = 'This wiki does not support profile modificatio
$lang['profnochange'] = 'No changes, nothing to do.';
$lang['profnoempty'] = 'An empty name or email address is not allowed.';
$lang['profchanged'] = 'User profile successfully updated.';
$lang['profnodelete'] = 'This wiki does not support deleting users';
$lang['profdeleteuser'] = 'Delete Account';
$lang['profdeleted'] = 'Your user account has been deleted from this wiki';
$lang['profconfdelete'] = 'I wish to remove my account from this wiki. <br/> This action can not be undone.';
$lang['profconfdeletemissing'] = 'Confirmation check box not ticked';
$lang['pwdforget'] = 'Forgotten your password? Get a new one';
$lang['resendna'] = 'This wiki does not support password resending.';
......
......@@ -99,6 +99,7 @@ $lang['disableactions'] = 'Disable DokuWiki actions';
$lang['disableactions_check'] = 'Check';
$lang['disableactions_subscription'] = 'Subscribe/Unsubscribe';
$lang['disableactions_wikicode'] = 'View source/Export Raw';
$lang['disableactions_profile_delete'] = 'Delete Own Account';
$lang['disableactions_other'] = 'Other actions (comma separated)';
$lang['auth_security_timeout'] = 'Authentication Security Timeout (seconds)';
$lang['securecookie'] = 'Should cookies set via HTTPS only be sent via HTTPS by the browser? Disable this option when only the login of your wiki is secured with SSL but browsing the wiki is done unsecured.';
......
......@@ -128,7 +128,7 @@ $meta['manager'] = array('string');
$meta['profileconfirm'] = array('onoff');
$meta['rememberme'] = array('onoff');
$meta['disableactions'] = array('disableactions',
'_choices' => array('backlink','index','recent','revisions','search','subscription','register','resendpwd','profile','edit','wikicode','check'),
'_choices' => array('backlink','index','recent','revisions','search','subscription','register','resendpwd','profile','profile_delete','edit','wikicode','check'),
'_combine' => array('subscription' => array('subscribe','unsubscribe'), 'wikicode' => array('source','export_raw')));
$meta['auth_security_timeout'] = array('numeric');
$meta['securecookie'] = array('onoff');
......
......@@ -79,7 +79,10 @@
#dw__register fieldset {
padding-bottom: 0.7em;
}
#dw__profiledelete {
display: block;
margin-top: 2.8em;
}
/**
* Styles for the subscription page
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment