Add edit/delete user menus

This commit is contained in:
Bartek Fabiszewski 2017-04-12 20:16:39 +02:00
parent 6049832b03
commit 87d760e4a2
11 changed files with 202 additions and 32 deletions

View File

@ -263,6 +263,16 @@ button {
cursor: pointer; cursor: pointer;
} }
.red-button {
color: white;
float: right;
background-color: red;
padding: .1em .4em;
border-radius: 10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
}
.dropdown { .dropdown {
display: none; display: none;
position: absolute; position: absolute;

View File

@ -101,6 +101,27 @@
return $positionId; return $positionId;
} }
/**
* Delete all user's positions
*
* @param string $userId User id
* @return bool True if success, false otherwise
*/
public function deleteAll($userId) {
$ret = false;
if (!empty($userId)) {
$query = "DELETE FROM positions WHERE user_id = ?";
$stmt = self::$db->prepare($query);
$stmt->bind_param('i', $userId);
$stmt->execute();
if (!self::$db->error && !$stmt->errno) {
$ret = true;
}
$stmt->close();
}
return $ret;
}
/** /**
* Fill class properties with last position data from database * Fill class properties with last position data from database
* (for given user if specified) * (for given user if specified)

View File

@ -77,6 +77,27 @@
return $trackId; return $trackId;
} }
/**
* Delete all user's tracks
*
* @param string $userId User id
* @return bool True if success, false otherwise
*/
public function deleteAll($userId) {
$ret = false;
if (!empty($userId)) {
$query = "DELETE FROM tracks WHERE user_id = ?";
$stmt = self::$db->prepare($query);
$stmt->bind_param('i', $userId);
$stmt->execute();
if (!self::$db->error && !$stmt->errno) {
$ret = true;
}
$stmt->close();
}
return $ret;
}
/** /**
* Get all tracks * Get all tracks
* *

View File

@ -16,8 +16,10 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>. * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/ */
require_once (ROOT_DIR . "/helpers/config.php"); require_once(ROOT_DIR . "/helpers/config.php");
require_once (ROOT_DIR . "/helpers/db.php"); require_once(ROOT_DIR . "/helpers/db.php");
require_once(ROOT_DIR . "/helpers/track.php");
require_once(ROOT_DIR . "/helpers/position.php");
/** /**
* User handling routines * User handling routines
@ -73,6 +75,38 @@
return $userid; return $userid;
} }
/**
* Delete user
* This will also delete all user's positions and tracks
*
* @return bool True if success, false otherwise
*/
public function delete() {
$ret = false;
if ($this->isValid) {
// remove positions
$position = new uPosition();
if ($position->deleteAll($this->id) === false) {
return false;
}
// remove tracks
$track = new uTrack();
if ($track->deleteAll($this->id) === false) {
return false;
}
// remove user
$sql = "DELETE FROM users WHERE id = ?";
$stmt = self::$db->prepare($sql);
$stmt->bind_param('i', $this->id);
$stmt->execute();
if (!self::$db->error && !$stmt->errno) {
$ret = true;
}
$stmt->close();
}
return $ret;
}
/** /**
* Set user password * Set user password
* *

View File

@ -72,6 +72,7 @@
var init_latitude = '<?= $config::$init_latitude ?>'; var init_latitude = '<?= $config::$init_latitude ?>';
var init_longitude = '<?= $config::$init_longitude ?>'; var init_longitude = '<?= $config::$init_longitude ?>';
var lang = <?= json_encode($lang) ?>; var lang = <?= json_encode($lang) ?>;
var auth = '<?= ($user->isValid) ? $user->login : "null" ?>';
</script> </script>
<script type="text/javascript" src="js/main.js"></script> <script type="text/javascript" src="js/main.js"></script>
@ -133,7 +134,7 @@
<input id="latest" type="checkbox" onchange="toggleLatest();"> <?= $lang["latest"] ?><br> <input id="latest" type="checkbox" onchange="toggleLatest();"> <?= $lang["latest"] ?><br>
</form> </form>
<input type="checkbox" onchange="autoReload();"><?= $lang["autoreload"] ?> (<a href="javascript:void(0);" onclick="setTime();"><span id="auto"><?= $config::$interval ?></span></a> s)<br> <input type="checkbox" onchange="autoReload();"><?= $lang["autoreload"] ?> (<a href="javascript:void(0);" onclick="setTime();"><span id="auto"><?= $config::$interval ?></span></a> s)<br>
<a href="javascript:void(0);" onclick="loadTrack(userid, trackid, 0);"><?= $lang["reload"] ?></a><br> <a href="javascript:void(0);" onclick="loadTrack(userid, trackid, 0);"> <?= $lang["reload"] ?></a><br>
</div> </div>
<div id="summary"></div> <div id="summary"></div>
@ -184,6 +185,7 @@
<div id="admin_menu"> <div id="admin_menu">
<u><?= $lang["adminmenu"] ?></u><br> <u><?= $lang["adminmenu"] ?></u><br>
<a href="javascript:void(0);" onclick="addUser()"><?= $lang["adduser"] ?></a><br> <a href="javascript:void(0);" onclick="addUser()"><?= $lang["adduser"] ?></a><br>
<a href="javascript:void(0);" onclick="editUser()"><?= $lang["edituser"] ?></a><br>
</div> </div>
<?php endif; ?> <?php endif; ?>

View File

@ -17,7 +17,7 @@
*/ */
function addUser() { function addUser() {
var form = '<form id="userForm" method="post" onsubmit="submitUser(); return false">'; var form = '<form id="userForm" method="post" onsubmit="submitUser(\'add\'); return false">';
form += '<label><b>' + lang['username'] + '</b></label><input type="text" placeholder="' + lang['usernameenter'] + '" name="login" required>'; form += '<label><b>' + lang['username'] + '</b></label><input type="text" placeholder="' + lang['usernameenter'] + '" name="login" required>';
form += '<label><b>' + lang['password'] + '</b></label><input type="password" placeholder="' + lang['passwordenter'] + '" name="pass" required>'; form += '<label><b>' + lang['password'] + '</b></label><input type="password" placeholder="' + lang['passwordenter'] + '" name="pass" required>';
form += '<label><b>' + lang['passwordrepeat'] + '</b></label><input type="password" placeholder="' + lang['passwordenter'] + '" name="pass2" required>'; form += '<label><b>' + lang['passwordrepeat'] + '</b></label><input type="password" placeholder="' + lang['passwordenter'] + '" name="pass2" required>';
@ -26,12 +26,43 @@ function addUser() {
showModal(form); showModal(form);
} }
function submitUser() { function editUser() {
var userForm = document.getElementsByName('user')[0];
var userLogin = userForm.options[userForm.selectedIndex].text;
if (userLogin == auth) {
alert('Your can\'t edit your own user with this tool');
return;
}
var message = '<div style="float:left">You are editing user <b>' + userLogin + '</b></div>';
message += '<div class="red-button"><b><a href="javascript:void(0);" onclick="submitUser(\'delete\'); return false">Delete user</a></b></div>';
message += '<div style="clear: both; padding-bottom: 1em;"></div>';
var form = '<form id="userForm" method="post" onsubmit="submitUser(\'update\'); return false">';
form += '<input type="hidden" name="login" value="' + userLogin + '">';
form += '<label><b>' + lang['password'] + '</b></label><input type="password" placeholder="' + lang['passwordenter'] + '" name="pass" required>';
form += '<label><b>' + lang['passwordrepeat'] + '</b></label><input type="password" placeholder="' + lang['passwordenter'] + '" name="pass2" required>';
form += '<div class="buttons"><button type="button" onclick="removeModal()">' + lang['cancel'] + '</button><button type="submit">' + lang['submit'] + '</button></div>';
form += '</form>';
showModal(message + form);
}
function confirmedDelete(login) {
return confirm('Warning!\n\nYou are going to permanently delete user "' + login + '", together with all their routes and positions.\n\nAre you sure?');
}
function submitUser(action) {
var form = document.getElementById('userForm'); var form = document.getElementById('userForm');
var login = form.elements['login'].value; var login = form.elements['login'].value;
var pass = form.elements['pass'].value; if (!login) {
var pass2 = form.elements['pass2'].value; alert("All fields are required");
if (!login || !pass || !pass2) { return;
}
var pass = null;
var pass2 = null;
if (action != 'delete') {
pass = form.elements['pass'].value;
pass2 = form.elements['pass2'].value;
if (!pass || !pass2) {
alert("All fields are required"); alert("All fields are required");
return; return;
} }
@ -39,8 +70,13 @@ function submitUser() {
alert("Passwords don't match"); alert("Passwords don't match");
return; return;
} }
} else {
if (!confirmedDelete(login)) {
return;
}
}
var xhr = getXHR(); var xhr = getXHR();
xhr.onreadystatechange = function () { xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) { if (xhr.readyState == 4 && xhr.status == 200) {
var xml = xhr.responseXML; var xml = xhr.responseXML;
var message = ""; var message = "";
@ -48,7 +84,13 @@ function submitUser() {
var root = xml.getElementsByTagName('root'); var root = xml.getElementsByTagName('root');
if (root.length && getNode(root[0], 'error') == 0) { if (root.length && getNode(root[0], 'error') == 0) {
removeModal(); removeModal();
alert("User successfully added"); alert("Action completed successfully");
if (action == 'delete') {
// select current user in users form
var f = document.getElementsByName('user')[0];
f.remove(f.selectedIndex);
selectUser(f);
}
return; return;
} }
errorMsg = getNode(root[0], 'message'); errorMsg = getNode(root[0], 'message');
@ -58,8 +100,10 @@ function submitUser() {
xhr = null; xhr = null;
} }
} }
xhr.open('POST', 'utils/adduser.php', true); xhr.open('POST', 'utils/handleuser.php', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send('login=' + login + '&pass=' + pass); var params = 'action=' + action + '&login=' + encodeURIComponent(login) + '&pass=' + encodeURIComponent(pass);
params = params.replace(/%20/g, '+');
xhr.send(params);
return; return;
} }

View File

@ -236,7 +236,7 @@ function getNode(p, name) {
} }
// seconds to (d) H:M:S // seconds to (d) H:M:S
Number.prototype.toHMS = function () { Number.prototype.toHMS = function() {
var s = this; var s = this;
var d = Math.floor(s / 86400); var d = Math.floor(s / 86400);
var h = Math.floor((s % 86400) / 3600); var h = Math.floor((s % 86400) / 3600);
@ -244,17 +244,17 @@ Number.prototype.toHMS = function () {
s = ((s % 86400) % 3600) % 60; s = ((s % 86400) % 3600) % 60;
return ((d > 0) ? (d + ' d ') : '') + (('00' + h).slice(-2)) + ':' + (('00' + m).slice(-2)) + ':' + (('00' + s).slice(-2)) + ''; return ((d > 0) ? (d + ' d ') : '') + (('00' + h).slice(-2)) + ':' + (('00' + m).slice(-2)) + ':' + (('00' + s).slice(-2)) + '';
} };
// meters to km // meters to km
Number.prototype.toKm = function () { Number.prototype.toKm = function() {
return Math.round(this / 10) / 100; return Math.round(this / 10) / 100;
} };
// m/s to km/h // m/s to km/h
Number.prototype.toKmH = function () { Number.prototype.toKmH = function() {
return Math.round(this * 3600 / 10) / 100; return Math.round(this * 3600 / 10) / 100;
} };
// negate value // negate value
function toggleLatest() { function toggleLatest() {

View File

@ -60,6 +60,8 @@ function submitPass() {
} }
xhr.open('POST', 'utils/changepass.php', true); xhr.open('POST', 'utils/changepass.php', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send('oldpass=' + oldpass + '&pass=' + pass); var params = 'oldpass=' + encodeURIComponent(oldpass) + '&pass=' + encodeURIComponent(pass);
params = params.replace(/%20/g, '+');
xhr.send(params);
return; return;
} }

View File

@ -66,5 +66,7 @@ $lang["newpasswordrepeat"] = "Repeat new password";
$lang["changepass"] = "Change password"; $lang["changepass"] = "Change password";
$lang["gps"] = "GPS"; $lang["gps"] = "GPS";
$lang["network"] = "Network"; $lang["network"] = "Network";
$lang["deluser"] = "Remove user";
$lang["edituser"] = "Edit user";
?> ?>

View File

@ -64,5 +64,7 @@ $lang["newpasswordrepeat"] = "Powtórz nowe hasło";
$lang["changepass"] = "Zmień hasło"; $lang["changepass"] = "Zmień hasło";
$lang["gps"] = "GPS"; $lang["gps"] = "GPS";
$lang["network"] = "Sieć"; $lang["network"] = "Sieć";
$lang["deluser"] = "Usuń użytkownika";
$lang["edituser"] = "Edytuj użytkownika";
?> ?>

View File

@ -41,17 +41,49 @@
exit; exit;
} }
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : NULL;
$login = isset($_REQUEST['login']) ? trim($_REQUEST['login']) : NULL; $login = isset($_REQUEST['login']) ? trim($_REQUEST['login']) : NULL;
$hash = isset($_REQUEST['pass']) ? password_hash($_REQUEST['pass'], PASSWORD_DEFAULT) : NULL; $hash = isset($_REQUEST['pass']) ? password_hash($_REQUEST['pass'], PASSWORD_DEFAULT) : NULL;
if ($user->isAdmin && !empty($login) && !empty($hash)) { if (!$user->isAdmin || empty($action) || empty($login) || $user->login == $login) {
$newUser = new uUser($login); exitWithStatus(true, "Server error");
if ($newUser->isValid) { }
$aUser = new uUser($login);
switch ($action) {
case 'add':
if (empty($hash)) {
exitWithStatus(true, "Server error");
}
if ($aUser->isValid) {
exitWithStatus(true, $lang["userexists"]); exitWithStatus(true, $lang["userexists"]);
} }
if ($newUser->add($login, $hash) === false) { if ($aUser->add($login, $hash) === false) {
exitWithStatus(true, $mysqli->error); exitWithStatus(true, $mysqli->error);
} }
break;
case 'update':
// update password
if (empty($hash)) {
exitWithStatus(true, "Server error");
} }
if ($aUser->setPass($hash) === false) {
exitWithStatus(true, $mysqli->error);
}
break;
case 'delete':
if ($aUser->delete() === false) {
exitWithStatus(true, $mysqli->error);
}
break;
default:
exitWithStatus(true, "Server error");
break;
}
exitWithStatus(false); exitWithStatus(false);
?> ?>