Fix#10 - Add name, surname and username editing
This commit is contained in:
Jan Jon 2018-07-22 21:03:07 +02:00 committed by Vojtěch Sajdl
parent 3d8329137b
commit 9e472db6f9
3 changed files with 378 additions and 206 deletions

View File

@ -16,9 +16,19 @@ if (isset($_POST['password']))
$displayed_user->change_password();
}
if (isset($_POST['username']))
{
$displayed_user->change_username();
}
if (isset($_POST['name']))
{
$displayed_user->change_name();
}
if (isset($_POST['email']))
{
$displayed_user->email_link();
$success = $displayed_user->email_link();
}
if (isset($_POST['permission']))
@ -36,10 +46,19 @@ Template::render_header(_("User"), true);
?>
<div class="text-center">
<h1><?php echo _("User settings");?></h1>
<h1><?php
if ($_SESSION['user'] == $_GET['id'])
{
echo _("User settings");
}else{
echo _("User");
} ?></h1>
</div>
<?php if (isset($message)){?>
<p class="alert alert-danger"><?php echo $message?></p>
<?php }
if (isset($success)){?>
<p class="alert alert-success"><?php echo $success?></p>
<?php }
$displayed_user->render_user_settings();

View File

@ -127,72 +127,72 @@ class User
$messages[] = _("Rank");
}
if (!isset($messages)){
$name = $_POST['name'];
$surname = $_POST['surname'];
$username = $_POST['username'];
$email = $_POST['email'];
$pass = $_POST['password'];
if (!filter_var($email, FILTER_VALIDATE_EMAIL))
{
$message = "Invalid email!";
return;
}
$variables = array();
if (strlen($name)>50){
$variables[] = 'name: 50';
}
if (strlen($surname)>50){
$variables[] = 'surname: 50';
}
if (strlen($username)>50){
$variables[] = 'username: 50';
}
if (strlen($email)>60){
$variables[] = 'email: 60';
}
if (!empty($variables))
{
$message = _("Please mind the following character limits: ");
$message .= implode(", ", $variables);
return;
}
$salt = uniqid(mt_rand(), true);
$hash = hash('sha256', $pass.$salt);
$permission = $_POST['permission'];
$stmt = $mysqli->prepare("INSERT INTO users values (NULL, ?, ?, ?, ?, ?, ?, ?, 1)");
$stmt->bind_param("ssssssi", $email, $username, $name, $surname, $hash, $salt, $permission);
$stmt->execute();
if ($stmt->affected_rows>0)
{
$to = $email;
$subject = _('User account created').' - '.NAME;
$msg = sprintf(_("Hi %s!<br>"."Your account has been created. You can login with your email address at <a href=\"%s\">%s</a> with password %s - please change it as soon as possible."), $name." ".$surname,WEB_URL."/admin", WEB_URL."/admin", $pass);
$headers = "Content-Type: text/html; charset=utf-8 ".PHP_EOL;
$headers .= "MIME-Version: 1.0 ".PHP_EOL;
$headers .= "From: ".MAILER_NAME.' <'.MAILER_ADDRESS.'>'.PHP_EOL;
$headers .= "Reply-To: ".MAILER_NAME.' <'.MAILER_ADDRESS.'>'.PHP_EOL;
mail($to, $subject, $msg, $headers);
if (!INSTALL_OVERRIDE)
{
header("Location: ".WEB_URL."/admin/?do=settings");
}
}
else{
$message = _("Username or email already used");
}
}
else{
if (isset($messages)){
$message = "Please enter ".implode(", ", $messages);
return;
}
$name = $_POST['name'];
$surname = $_POST['surname'];
$username = $_POST['username'];
$email = $_POST['email'];
$pass = $_POST['password'];
if (!filter_var($email, FILTER_VALIDATE_EMAIL))
{
$message = "Invalid email!";
return;
}
$variables = array();
if (strlen($name)>50){
$variables[] = 'name: 50';
}
if (strlen($surname)>50){
$variables[] = 'surname: 50';
}
if (strlen($username)>50){
$variables[] = 'username: 50';
}
if (strlen($email)>60){
$variables[] = 'email: 60';
}
if (!empty($variables))
{
$message = _("Please mind the following character limits: ");
$message .= implode(", ", $variables);
return;
}
$salt = uniqid(mt_rand(), true);
$hash = hash('sha256', $pass.$salt);
$permission = $_POST['permission'];
$stmt = $mysqli->prepare("INSERT INTO users values (NULL, ?, ?, ?, ?, ?, ?, ?, 1)");
$stmt->bind_param("ssssssi", $email, $username, $name, $surname, $hash, $salt, $permission);
$stmt->execute();
if ($stmt->affected_rows==0)
{
$message = _("Username or email already used");
return;
}
$to = $email;
$subject = _('User account created').' - '.NAME;
$msg = sprintf(_("Hi %s!<br>"."Your account has been created. You can login with your email address at <a href=\"%s\">%s</a> with password %s - please change it as soon as possible."), $name." ".$surname,WEB_URL."/admin", WEB_URL."/admin", $pass);
$headers = "Content-Type: text/html; charset=utf-8 ".PHP_EOL;
$headers .= "MIME-Version: 1.0 ".PHP_EOL;
$headers .= "From: ".MAILER_NAME.' <'.MAILER_ADDRESS.'>'.PHP_EOL;
$headers .= "Reply-To: ".MAILER_NAME.' <'.MAILER_ADDRESS.'>'.PHP_EOL;
mail($to, $subject, $msg, $headers);
if (!INSTALL_OVERRIDE)
{
header("Location: ".WEB_URL."/admin/?do=settings");
}
}
else {
@ -210,55 +210,63 @@ class User
public static function login()
{
global $message, $mysqli;
if (isset($_POST['email']))
if (!isset($_POST['email']) && !isset($_POST['email']))
{
$email = $_POST['email'];
$pass = $_POST['pass'];
$stmt = $mysqli->prepare("SELECT id,password_salt as salt,active FROM users WHERE email=?");
$stmt->bind_param("s", $email);
$stmt->execute();
$query = $stmt->get_result();
if ($query->num_rows)
{
$result = $query->fetch_assoc();
$salt = $result["salt"];
$id = $result["id"];
$active = $result["active"];
if (!$active)
{
$message = _("Your account has been disabled. Please contact administrator.");
}
else
{
$hash = hash('sha256', $pass.$salt);
$stmt = $mysqli->prepare("SELECT count(*) as count FROM users WHERE id=? AND password_hash=?");
$stmt->bind_param("is", $id, $hash);
$stmt->execute();
$query = $stmt->get_result();
if (!$query->fetch_assoc()['count'])
{
$message = _("Wrong email or password");
}else
{
if (isset($_POST['remember'])&&$_POST['remember'])
{
$year = strtotime('+356 days', time());
$token = Token::add($id, 'remember', $year);
setcookie('token', $token, $year, "/");
setcookie('user', $id, $year, "/");
}
$_SESSION['user'] = $id;
header("Location: ".WEB_URL."/admin");
}
}
}
else{
$message = _("Wrong email or password");
}
return;
}
if ((!isset($_POST['email']) || !isset($_POST['email'])))
{
$message = _("Please fill in your email and password!");
return;
}
$email = $_POST['email'];
$pass = $_POST['pass'];
$stmt = $mysqli->prepare("SELECT id,password_salt as salt,active FROM users WHERE email=?");
$stmt->bind_param("s", $email);
$stmt->execute();
$query = $stmt->get_result();
if ($query->num_rows<1)
{
$message = _("Wrong email or password");
return;
}
$result = $query->fetch_assoc();
$salt = $result["salt"];
$id = $result["id"];
$active = $result["active"];
if (!$active)
{
$message = _("Your account has been disabled. Please contact administrator.");
return;
}
$hash = hash('sha256', $pass.$salt);
$stmt = $mysqli->prepare("SELECT count(*) as count FROM users WHERE id=? AND password_hash=?");
$stmt->bind_param("is", $id, $hash);
$stmt->execute();
$query = $stmt->get_result();
if (!$query->fetch_assoc()['count'])
{
$message = _("Wrong email or password");
return;
}
if (isset($_POST['remember'])&&$_POST['remember'])
{
$year = strtotime('+356 days', time());
$token = Token::add($id, 'remember', $year);
setcookie('token', $token, $year, "/");
setcookie('user', $id, $year, "/");
}
$_SESSION['user'] = $id;
header("Location: ".WEB_URL."/admin");
}
/**
@ -301,29 +309,70 @@ class User
{
global $permissions, $user;
?>
<div class="row">
<div class="col-md-2 col-md-offset-2"><img src="https://www.gravatar.com/avatar/<?php echo md5( strtolower( trim( $this->email ) ) );?>" alt="<?php echo _("Profile picture");?>"></div>
<div class="col-md-6"><h3><?php echo $this->name." ".$this->surname;?></h3></div>
</div>
<div class="row">
<div class="col-md-2 col-md-offset-2"><strong><?php echo _("ID");?></strong></div>
<div class="col-md-6"><?php echo $this->id; ?></div>
</div>
<div class="row">
<div class="col-md-2 col-md-offset-2"><strong><?php echo _("Username");?></strong></div>
<div class="col-md-6"><?php echo $this->username." "; if ($this->id!=$_SESSION['user'] && $user->get_rank()<=1 && ($user->get_rank()<$this->rank))
{
echo "<a href='".WEB_URL."/admin/?do=user&id=".$this->id."&what=toggle'>";
echo "<i class='fa fa-".($this->active?"check success":"times danger")."'></i></a>";
}else{
echo "<i class='fa fa-".($this->active?"check success":"times danger")."'></i>";
}?></div>
<div class="row user">
<div class="col-md-2 col-md-offset-2"><img src="https://www.gravatar.com/avatar/<?php echo md5( strtolower( trim( $this->email ) ) );?>?s=160"
alt="<?php echo _("Profile picture");?>"></div>
<div class="col-md-6">
<?php if($this->id==$_SESSION['user']||$user->get_rank()<1){
?>
<form action="<?php echo WEB_URL;?>/admin/?do=user&amp;id=<?php echo $this->id; ?>" method="POST">
<div class="input-group">
<div class="col-md-12">
<div class="row">
<label class="form-name" for="name"><?php echo _("Name"); ?></label>
<label class="form-name" for="surname"><?php echo _("Surname"); ?></label>
</div>
<div class="row">
<input type="text" name="name" placeholder="<?php echo _("Name"); ?>"
title="<?php echo _("Name"); ?>" class="form-control form-name"
value=<?php echo htmlspecialchars($this->name, ENT_QUOTES);?>>
<input type="text" name="surname" placeholder="<?php echo _("Surname"); ?>"
title="<?php echo _("Surname"); ?>" class="form-control form-name"
value=<?php echo htmlspecialchars($this->surname, ENT_QUOTES);?>>
</div>
</div>
</div>
<div class="input-group">
<button type="submit" class="btn btn-primary pull-right"><?php echo _("Change name");?></button>
</div>
</form>
<?php
}else{
?>
<h3><?php echo $this->name." ".$this->surname;?></h3>
<?php
}?>
</div>
</div>
<form action="<?php echo WEB_URL;?>/admin/?do=user&amp;id=<?php echo $this->id; ?>" method="POST">
<div class="row user">
<div class="col-md-2 col-md-offset-2"><strong><?php echo _("Username");?></strong></div>
<div class="col-md-6">
<?php
if ($this->id==$_SESSION['user'] || $user->get_rank()<1){?>
<div class="input-group">
<input type="text" class="form-control" name="username" required value="<?php echo htmlspecialchars($this->username, ENT_QUOTES);?>">
<span class="input-group-btn">
<button type="submit" class="btn btn-primary pull-right"><?php echo _("Change username");?></button>
</span>
</div>
<?php
}else{?><?php echo $this->username." ";
if ($user->get_rank()>=1){
echo "<i class='fa fa-".($this->active?"check success":"times danger")."'></i>";
}
}
?>
</div>
</div>
</form>
<form action="<?php echo WEB_URL;?>/admin/?do=user&id=<?php echo $this->id; ?>" method="POST">
<div class="row">
<div class="row user">
<div class="col-md-2 col-md-offset-2"><strong><?php echo _("Role");?></strong></div>
<div class="col-md-6"><?php if ($user->get_rank() == 0 && $this->id != $_SESSION['user']){?> <div class="input-group"><select class="form-control" name="permission"><?php foreach ($permissions as $key => $value) {
<div class="col-md-6"><?php if ($user->get_rank() == 0 && $this->id != $_SESSION['user']){?>
<div class="input-group"><select class="form-control" name="permission">
<?php foreach ($permissions as $key => $value) {
echo "<option value='$key' ".($key==$this->rank?"selected":"").">$value</option>";
} ?>
</select><span class="input-group-btn">
@ -333,10 +382,10 @@ class User
</div>
</form>
<?php if($this->id==$_SESSION['user'])
<?php if($this->id==$_SESSION['user']||$user->get_rank()<1)
{?>
<form action="<?php echo WEB_URL;?>/admin/?do=user" method="POST">
<div class="row">
<form action="<?php echo WEB_URL;?>/admin/?do=user&amp;id=<?php echo $this->id; ?>" method="POST">
<div class="row user">
<div class="col-md-2 col-md-offset-2"><strong>Email</strong></div>
<div class="col-md-6">
<div class="input-group">
@ -348,6 +397,21 @@ class User
</div>
</div>
</form>
<?php }else
{
?>
<div class="row user">
<div class="col-md-2 col-md-offset-2"><strong><?php echo _("Email");?></strong></div>
<div class="col-md-6">
<a href="mailto:<?php echo $this->email; ?>"><?php echo $this->email; ?></a>
</div>
</div>
<?php
}
if($this->id==$_SESSION['user']){
?>
<form action="<?php echo WEB_URL;?>/admin/?do=user" method="POST">
<div class="row">
<div class="col-md-2 col-md-offset-2"><strong><?php echo _("Password");?></strong></div>
@ -364,17 +428,7 @@ class User
</form>
<?php
}
else
{
?>
<div class="row">
<div class="col-md-2 col-md-offset-2"><strong><?php echo _("Email");?></strong></div>
<div class="col-md-6">
<a href="mailto:<?php echo $this->email; ?>"><?php echo $this->email; ?></a>
</div>
</div>
<?php
}
if ($this->id!=$_SESSION['user'] && $user->get_rank()<=1 && ($user->get_rank()<$this->rank))
{?>
<div class="row">
@ -392,6 +446,71 @@ class User
<?php }
}
/**
* Changes username of user by POST[ID].
* @return void
*/
public function change_username()
{
global $mysqli, $message, $user;
$id = $this->id;
$stmt = $mysqli->prepare("SELECT count(*) FROM users WHERE username LIKE ?");
$stmt->bind_param("s",$_POST["username"]);
$stmt->execute();
if ($stmt->num_rows > 0)
{
$message = _("This username is already taken.");
return;
}
$stmt->close();
if ($_SESSION['user'] != $id && $user->get_rank()>0)
{
$message = _("Cannot change username of other users!");
}else{
$stmt = $mysqli->prepare("UPDATE users SET username = ? WHERE id=?");
$stmt->bind_param("si",$_POST["username"],$id);
$stmt->execute();
$stmt->close();
header("Location: /admin/?do=user&id=".$id);
}
}
/**
* Changes name and surname of user by POST[ID].
* @return void
*/
public function change_name()
{
global $mysqli, $message, $user;
if (strlen(trim($_POST['name']))==0) {
$messages[] = _("Name");
}
if(strlen(trim($_POST['surname']))==0) {
$messages[] = _("Surname");
}
if (!empty($messages))
{
$message = "Please enter ".implode(", ", $messages);
return;
}
$id = $this->id;
if ($_SESSION['user'] != $id && $user->get_rank()>0)
{
$message = _("Cannot change names of other users!");
}else{
$stmt = $mysqli->prepare("UPDATE users SET `name` = ?, `surname` = ? WHERE id=?");
$stmt->bind_param("ssi",$_POST["name"],$_POST["surname"],$id);
$stmt->execute();
$stmt->close();
header("Location: /admin/?do=user&id=".$id);
}
}
/**
* Changes user password and deletes all remember tokens so all other sessions
* won't stay logged in without knowing new pass. Uses token when reseting password.
@ -405,72 +524,77 @@ class User
if ($_POST['password']!=$_POST['password_repeat'])
{
$message = _("Passwords do not match!");
}else{
if (!$token)
return;
}
if (!$token)
{
if ($_SESSION['user']!=$id)
{
if ($_SESSION['user']!=$id)
{
$message = _("Cannot change password of other users!");
}else{
$stmt = $mysqli->prepare("SELECT password_salt as salt FROM users WHERE id=?");
$stmt->bind_param("i", $id);
$stmt->execute();
$query = $stmt->get_result();
$result = $query->fetch_assoc();
$salt = $result['salt'];
$pass = $_POST['old_password'];
$hash = hash('sha256', $pass.$salt);
$stmt = $mysqli->prepare("SELECT count(*) as count FROM users WHERE id=? AND password_hash = ?");
$stmt->bind_param("is", $id, $hash);
$stmt->execute();
if ($stmt->get_result()->fetch_assoc()['count'])
{
$pass = $_POST['password'];
$hash = hash('sha256', $pass.$salt);
$stmt = $mysqli->prepare("UPDATE users SET password_hash = ? WHERE id=?");
$stmt->bind_param("si", $hash, $id);
$stmt->execute();
$stmt->close();
$stmt = $mysqli->prepare("DELETE FROM tokens WHERE user = ? AND data = 'remember'");
$stmt->bind_param("d", $id);
$stmt->execute();
$stmt->get_result();
User::logout();
}
else{
$message = _("Wrong password!");
}
}
$message = _("Cannot change password of other users!");
}else{
if (Token::validate($token, $id, "passwd"))
$stmt = $mysqli->prepare("SELECT password_salt as salt FROM users WHERE id=?");
$stmt->bind_param("i", $id);
$stmt->execute();
$query = $stmt->get_result();
$result = $query->fetch_assoc();
$salt = $result['salt'];
$pass = $_POST['old_password'];
$hash = hash('sha256', $pass.$salt);
$stmt = $mysqli->prepare("SELECT count(*) as count FROM users WHERE id=? AND password_hash = ?");
$stmt->bind_param("is", $id, $hash);
$stmt->execute();
if ($stmt->get_result()->fetch_assoc()['count'])
{
$stmt = $mysqli->prepare("SELECT password_salt as salt FROM users WHERE id=?");
$stmt->bind_param("i", $id);
$stmt->execute();
$query = $stmt->get_result();
$result = $query->fetch_assoc();
$salt = $result['salt'];
$pass = $_POST['password'];
$hash = hash('sha256', $pass.$salt);
$stmt = $mysqli->prepare("UPDATE users SET password_hash = ? WHERE id=?");
$stmt->bind_param("si", $hash,$id);
$stmt->bind_param("si", $hash, $id);
$stmt->execute();
$stmt->close();
$stmt = $mysqli->prepare("DELETE FROM tokens WHERE user = ? AND data = 'remember'");
$stmt->bind_param("d", $id);
$stmt->execute();
$stmt->get_result();
}
else
{
$message = _("Invalid token detected, please retry your request from start!");
}
Token::delete($token);
$stmt = $mysqli->prepare("DELETE FROM tokens WHERE user = ? AND data = 'remember'");
$stmt->bind_param("d", $id);
$stmt->execute();
$stmt->get_result();
User::logout();
}
else{
$message = _("Wrong password!");
}
}
}else{
if (Token::validate($token, $id, "passwd"))
{
$stmt = $mysqli->prepare("SELECT password_salt as salt FROM users WHERE id=?");
$stmt->bind_param("i", $id);
$stmt->execute();
$query = $stmt->get_result();
$result = $query->fetch_assoc();
$salt = $result['salt'];
$pass = $_POST['password'];
$hash = hash('sha256', $pass.$salt);
$stmt = $mysqli->prepare("UPDATE users SET password_hash = ? WHERE id=?");
$stmt->bind_param("si", $hash,$id);
$stmt->execute();
$stmt->close();
$stmt = $mysqli->prepare("DELETE FROM tokens WHERE user = ? AND data = 'remember'");
$stmt->bind_param("d", $id);
$stmt->execute();
$stmt->get_result();
}
else
{
$message = _("Invalid token detected, please retry your request from start!");
}
Token::delete($token);
}
}
@ -511,11 +635,23 @@ class User
* @return void
*/
public function email_link(){
global $user;
global $user, $mysqli;
$email = $_POST['email'];
$time = strtotime('+1 day', time());
$id = $this->id;
if ($user->get_rank()<1 && $id!=$_SESSION['user'])
{
$stmt = $mysqli->prepare("UPDATE users SET email = ? WHERE id=?");
$stmt->bind_param("sd", $email, $id);
$stmt->execute();
$stmt->get_result();
header("Location: /admin/?do=user&id=".$id);
return;
}
$time = strtotime('+1 day', time());
$token = Token::add($id, 'email;$email', $time);
$link = WEB_URL."/admin/?do=change-email&id=$id&token=$token";
@ -528,6 +664,7 @@ class User
$headers .= "Reply-To: ".MAILER_NAME.' <'.MAILER_ADDRESS.'>'.PHP_EOL;
mail($to, $subject, $msg, $headers);
return _('Confirmation email sent!');
}
/**

View File

@ -93,7 +93,7 @@ div.center {
#wrapper
{
max-width: 900px;
max-width: 1024px;
min-height: calc(100vh - 157px);
padding-right: 15px;
padding-left: 15px
@ -599,4 +599,20 @@ i.danger{
body .h1,body .h2,body .h3,body h1,body h2,body h3 {
margin-top: 18px;
}
.row.user .input-group
{
width: 100%;
margin-bottom: 5px
}
.row.user .form-name{
width: 50%;
float: left;
}
label.form-name
{
line-height: 20px
}