Skip to content

Commit

Permalink
Merge pull request #845 from emoncms/delete_user_feature
Browse files Browse the repository at this point in the history
delete user feature
  • Loading branch information
TrystanLea authored May 21, 2018
2 parents 8f8ee8c + dbe309d commit 5959153
Show file tree
Hide file tree
Showing 4 changed files with 214 additions and 12 deletions.
91 changes: 91 additions & 0 deletions Modules/user/deleteuser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

defined('EMONCMS_EXEC') or die('Restricted access');

function delete_user($userid,$mode) {

global $mysqli,$redis,$user,$feed_settings;

$result1 = $mysqli->query("SELECT id,apikey_read,apikey_write FROM users WHERE id=$userid");
if ($user_row = $result1->fetch_object()){
$result = "User $userid\n";

require "Modules/feed/feed_model.php";
$feed = new Feed($mysqli,$redis,$feed_settings);

require "Modules/input/input_model.php";
$input = new Input($mysqli,$redis,$feed);

$result .= "Feeds:\n";
$result2 = $mysqli->query("SELECT id,name FROM feeds WHERE userid=$userid");
while ($row2 = $result2->fetch_object())
{
$feedid = $row2->id;
$result .= " $feedid:$row2->name\n";
if ($mode=="permanentdelete") $feed->delete($feedid);
}

$result .= "Inputs:\n";
$result2 = $mysqli->query("SELECT id,name FROM input WHERE userid=$userid");
while ($row2 = $result2->fetch_object())
{
$inputid = $row2->id;
$result .= " $inputid:$row2->name\n";
if ($mode=="permanentdelete") $input->delete($userid, $inputid);
}

$apikey = $user_row->apikey_read;
if ($redis->exists("readapikey:$apikey")) {
$result .= "- readapikey from redis\n";
if ($mode=="permanentdelete") $redis->del("readapikey:$apikey");
}

$apikey = $user_row->apikey_write;
if ($redis->exists("writeapikey:$apikey")) {
$result .= "- writeapikey from redis\n";
if ($mode=="permanentdelete") $redis->del("writeapikey:$apikey");
}

$tables = array("app_config","autoconfig","dashboard","emailreport","graph","multigraph","myip","node","statico","rememberme","group_users","assessment","assessment_access","organisation_membership","mhep_library_access");
foreach ($tables as $tablename) {
$result .= delete_entry_in_table($tablename,$userid,$mode);
}

$result .= "- user entry\n";
if ($mode=="permanentdelete") $mysqli->query("DELETE FROM users WHERE `id` = '$userid'");

// $user->logout();
} else {
$result = "user does not exist";
}

if ($mode=="permanentdelete") {
$fh = fopen("/var/log/emoncms/userdelete.log","a");
fwrite($fh,$result);
fclose($fh);
}


return $result;
}

function delete_entry_in_table($tablename,$userid,$mode) {
global $mysqli;

$result = "";

if ($result1 = $mysqli->query("SELECT * FROM $tablename WHERE `userid`='$userid'")) {
if ($result1->num_rows>0) {
$result = "- $tablename entry\n";
if ($mode=="permanentdelete") $mysqli->query("DELETE FROM $tablename WHERE `userid`='$userid'");
}
}
return $result;
}

function check_entry_in_table($tablename,$userid) {
global $mysqli;
$result = $mysqli->query("SELECT * FROM $tablename WHERE `userid`='$userid'");
if ($result && $result->num_rows>0) return true;
return false;
}
83 changes: 77 additions & 6 deletions Modules/user/profile/profile.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
defined('EMONCMS_EXEC') or die('Restricted access');

global $path;
$v=1;

$languages = get_available_languages();
$languages_name = languagecode_to_name($languages);
Expand Down Expand Up @@ -41,17 +42,21 @@ function languagecode_to_name($langs) {

?>

<script type="text/javascript" src="<?php echo $path; ?>Modules/user/profile/md5.js"></script>
<script type="text/javascript" src="<?php echo $path; ?>Lib/misc/qrcode.js"></script>
<script type="text/javascript" src="<?php echo $path; ?>Lib/misc/clipboard.js"></script>
<script type="text/javascript" src="<?php echo $path; ?>Modules/user/user.js"></script>
<script type="text/javascript" src="<?php echo $path; ?>Lib/listjs/list.js"></script>
<script type="text/javascript" src="<?php echo $path; ?>Modules/user/profile/md5.js?v=<?php echo $v; ?>"></script>
<script type="text/javascript" src="<?php echo $path; ?>Lib/misc/qrcode.js?v=<?php echo $v; ?>"></script>
<script type="text/javascript" src="<?php echo $path; ?>Lib/misc/clipboard.js?v=<?php echo $v; ?>"></script>
<script type="text/javascript" src="<?php echo $path; ?>Modules/user/user.js?v=<?php echo $v; ?>"></script>
<script type="text/javascript" src="<?php echo $path; ?>Lib/listjs/list.js?v=<?php echo $v; ?>"></script>

<div class="row-fluid">
<div class="span4">
<h3><?php echo _('My account'); ?></h3>

<div id="account">
<div class="account-item">
<span class="muted"><?php echo _('User ID'); ?></span><br><span class="userid"></span>
</div>

<div class="account-item">
<span class="muted"><?php echo _('Username'); ?></span>
<span id="username-view"><br><span class="username"></span> <a id="edit-username" style="float:right"><?php echo _('Edit'); ?></a></span>
Expand Down Expand Up @@ -107,6 +112,11 @@ function languagecode_to_name($langs) {
<span id="msg"></span>
</div>
</div>
<br>
<div class="account-item">
<button class="btn btn-danger" id="deleteall">Delete my account</button>
</div>

</div>
<div class="span8">
<h3><?php echo _('My Profile'); ?></h3>
Expand All @@ -133,6 +143,34 @@ function languagecode_to_name($langs) {
</div>
</div>

<div id="myModal" class="modal hide" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="false">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel"><?php echo _('WARNING deleting an account is permanent'); ?></h3>
</div>
<div class="modal-body">
<div class="delete-account-s1">
<p><?php echo _('Are you sure you want to delete your account?'); ?></p>
</div>

<div class="delete-account-s2" style="display:none">
<p><b>Your account has been successfully deleted.</b></p>
</div>

<pre id="deleteall-output"></pre>

<div class="delete-account-s1">
<p>Confirm password to delete:<br>
<input id="delete-account-password" type="password" /></p>
</div>
</div>
<div class="modal-footer">
<button id="canceldelete" class="btn" data-dismiss="modal" aria-hidden="true"><?php echo _('Cancel'); ?></button>
<button id="confirmdelete" class="btn btn-primary"><?php echo _('Delete permanently'); ?></button>
<button id="logoutdelete" class="btn btn-primary" style="display:none"><?php echo _('Logout'); ?></button>
</div>
</div>

<script>

var path = "<?php echo $path; ?>";
Expand Down Expand Up @@ -195,6 +233,7 @@ function languagecode_to_name($langs) {
//------------------------------------------------------
// Username
//------------------------------------------------------
$(".userid").html(list.data['id']);
$(".username").html(list.data['username']);
$("#input-username").val(list.data['username']);

Expand Down Expand Up @@ -307,8 +346,9 @@ function languagecode_to_name($langs) {
else
{
$.ajax({
type: 'POST',
url: path+"user/changepassword.json",
data: "old="+oldpassword+"&new="+newpassword,
data: "old="+encodeURIComponent(oldpassword)+"&new="+encodeURIComponent(newpassword),
dataType: 'json',
success: function(result)
{
Expand Down Expand Up @@ -340,6 +380,37 @@ function languagecode_to_name($langs) {
$("#change-password-form").hide();
$("#changedetails").show();
});


$("#deleteall").click(function(){
$('#myModal').modal('show');

$.ajax({type:"POST",url: path+"user/deleteall.json", data: "mode=dryrun", dataType: 'text', success: function(result){
$("#deleteall-output").html(result);
}});
});

$("#confirmdelete").click(function() {

var password = $("#delete-account-password").val();

$.ajax({type:"POST", url: path+"user/deleteall.json", data: "mode=permanentdelete&password="+encodeURIComponent(password), dataType: 'text', success: function(result){
$("#deleteall-output").html(result);

if (result!="invalid password") {
$("#canceldelete").hide();
$("#confirmdelete").hide();
$("#logoutdelete").show();
$(".delete-account-s1").hide();
$(".delete-account-s2").show();
}
}});
});

$("#logoutdelete").click(function() {
$.ajax({url: path+"user/logout.json", dataType: 'text', success: function(result){
window.location = path;
}});
});

</script>
2 changes: 1 addition & 1 deletion Modules/user/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ var user = {
'set':function(data)
{
var result = {};
$.ajax({ url: path+"user/set.json", data: "&data="+encodeURIComponent(JSON.stringify(data)) ,dataType: "json", async: false, success: function(data) {result = data;} });
$.ajax({ type: "POST", url: path+"user/set.json", data: "&data="+encodeURIComponent(JSON.stringify(data)) ,dataType: "json", async: false, success: function(data) {result = data;} });
return result;
},

Expand Down
50 changes: 45 additions & 5 deletions Modules/user/user_controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

function user_controller()
{
global $user, $path, $session, $route , $enable_multi_user, $email_verification;
global $mysqli, $redis, $user, $path, $session, $route , $enable_multi_user, $email_verification;

$result = false;

Expand Down Expand Up @@ -51,26 +51,66 @@ function user_controller()
if ($route->action == 'register' && $allowusersregister) $result = $user->register(post('username'),post('password'),post('email'));
if ($route->action == 'logout' && $session['read']) $user->logout();

if ($route->action == 'resend-verify' && $email_verification) $result = $user->send_verification_email(get('username'));
if ($route->action == 'resend-verify' && $email_verification) {
if (isset($_GET['username'])) $username = $_GET['username']; else $username = $session["username"];
$result = $user->send_verification_email($username);
}

if ($route->action == 'changeusername' && $session['write']) $result = $user->change_username($session['userid'],get('username'));
if ($route->action == 'changeemail' && $session['write']) $result = $user->change_email($session['userid'],get('email'));
if ($route->action == 'changepassword' && $session['write']) $result = $user->change_password($session['userid'],get('old'),get('new'));
if ($route->action == 'changepassword' && $session['write']) $result = $user->change_password($session['userid'],post('old'),post('new'));

if ($route->action == 'passwordreset') $result = $user->passwordreset(get('username'),get('email'));
// Apikey
if ($route->action == 'newapikeyread' && $session['write']) $result = $user->new_apikey_read($session['userid']);
if ($route->action == 'newapikeywrite' && $session['write']) $result = $user->new_apikey_write($session['userid']);

if ($route->action == 'auth') $result = $user->get_apikeys_from_login(post('username'),post('password'));
if ($route->action == 'auth' && !$session['read']) $result = $user->get_apikeys_from_login(post('username'),post('password'));

// Get and set - user by profile client
if ($route->action == 'get' && $session['write']) $result = $user->get($session['userid']);
if ($route->action == 'set' && $session['write']) $result = $user->set($session['userid'],json_decode(get('data')));
if ($route->action == 'set' && $session['write']) $result = $user->set($session['userid'],json_decode(post('data')));

if ($route->action == 'timezone' && $session['read']) $result = $user->get_timezone_offset($session['userid']); // to maintain compatibility but in seconds
if ($route->action == 'gettimezone' && $session['read']) $result = $user->get_timezone($session['userid']);
if ($route->action == 'gettimezones' && $session['read']) $result = $user->get_timezones();

if ($route->action == "deleteall" && $session['write']) {
$route->format = "text";
$userid = $session['userid'];
require "Modules/user/deleteuser.php";

if (isset($_POST['mode'])) {

$mode = "dryrun";
if ($_POST['mode']=="permanentdelete") $mode = "permanentdelete";

if ($mode=="permanentdelete") {
if (isset($_POST['password'])) {
// Check password
$result = $mysqli->query("SELECT password, salt FROM users WHERE id = '$userid'");
$row = $result->fetch_object();
$hash = hash('sha256', $row->salt . hash('sha256', $_POST['password']));

if ($hash == $row->password || $session['admin']==1) {
$result = "PERMANENT DELETE:\n";
$result .= delete_user($userid,"permanentdelete");

$user->logout();
} else {
$result = "invalid password";
}
} else {
$result = "missing password field";
}
} else {
$result = "DRY RUN:\n";
$result .= delete_user($userid,"dryrun");
}
} else {
$result = "missing mode field";
}
}
}

return array('content'=>$result);
Expand Down

0 comments on commit 5959153

Please sign in to comment.