A new editor needs a username and a password of at least 12 characters. A persistent login needs an unexpired key and an existing account. Removing an account revokes its persistent logins, and its sessions end.
136 lines
4.6 KiB
PHP
136 lines
4.6 KiB
PHP
<?php
|
|
require_once('../config.lib.php');
|
|
require_https();
|
|
require_once("../session.lib.php");
|
|
$added = FALSE;
|
|
$csrf_failed = FALSE;
|
|
$hash_failed = FALSE;
|
|
$exists = FALSE;
|
|
$invalid = array();
|
|
if (!isset($_SESSION['editor'])) {
|
|
header("Location: /publish/login");
|
|
return;
|
|
} else if (isset($_POST['adduser']) && !csrf_valid()) {
|
|
$csrf_failed = TRUE;
|
|
} else if (isset($_POST['adduser']) && ($invalid = new_editor_problems($_POST['username'] ?? NULL, $_POST['password'] ?? NULL))) {
|
|
// Nothing is stored; the page lists the problems
|
|
} else if (isset($_POST['adduser'])) {
|
|
require_once('../open_db.lib.php');
|
|
open_db('open');
|
|
$table = "editors";
|
|
|
|
$username = $_POST['username'];
|
|
$password = password_hash($_POST['password'], password_algorithm());
|
|
$email = is_string($_POST['email'] ?? NULL) ? $_POST['email'] : '';
|
|
$found = $db->execute_query("SELECT username FROM $table WHERE username = ?", array($username));
|
|
$query = "INSERT INTO $table SET `username` = ?, `password` = ?, `email` = ?";
|
|
if ($found && $found->fetch_assoc()) {
|
|
$exists = TRUE;
|
|
} else if ($result = $db->execute_query($query, array($username, $password, $email))) {
|
|
// If the password column cut the hash short, the editor could never log in
|
|
if (password_hash_is_stored($username, $password)) {
|
|
$added = TRUE;
|
|
} else {
|
|
remove_editor($username);
|
|
$hash_failed = TRUE;
|
|
}
|
|
$is_admin = TRUE;
|
|
}
|
|
open_db('close');
|
|
}
|
|
|
|
/*
|
|
* The problems with a new username and password, as messages; an empty
|
|
* list means that both are fine. The persistent login cookie holds
|
|
* "username|key", so a username cannot contain "|".
|
|
*/
|
|
function new_editor_problems($username, $password) {
|
|
$problems = array();
|
|
if (!is_string($username) || trim($username) === '')
|
|
$problems[] = 'Please enter a username.';
|
|
else if ($username !== trim($username) || strlen($username) > 64 || preg_match('/[|\p{Cc}]/u', $username) !== 0)
|
|
$problems[] = 'A username has at most 64 characters, with no spaces at the ends and no "|".';
|
|
if (!is_string($password) || mb_strlen($password, 'UTF-8') < 12)
|
|
$problems[] = 'A password needs at least 12 characters.';
|
|
else if (strlen($password) > 1024)
|
|
$problems[] = 'A password has at most 1024 characters.';
|
|
else if (is_string($username) && strcasecmp($password, $username) === 0)
|
|
$problems[] = 'The password cannot be the username.';
|
|
return $problems;
|
|
}
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>x.x.x [add editor]</title>
|
|
<link rel="icon" href="favicon.png" />
|
|
<link rel="shortcut icon" href="favicon.png" />
|
|
<link rel="stylesheet" type="text/css" href="../style.css" />
|
|
<link rel='stylesheet' type='text/css' href='../publish/style.css' />
|
|
<script type="text/javascript" src="../utilities.js"></script>
|
|
<link rel="alternate" type="application/rss+xml" title="xxx.org.za RSS feed" href="/feed" />
|
|
</head>
|
|
<?php flush(); ?>
|
|
<body>
|
|
<div id="container">
|
|
<?php include_once("../sidebar.inc.php"); ?>
|
|
<main id="main">
|
|
<div id="maintext">
|
|
|
|
<H1>add editor</H1>
|
|
|
|
<?php if ($added) { ?>
|
|
<p>Added editor <?= form_value($username) ?></p>
|
|
<?php } else { ?>
|
|
<?php if ($csrf_failed) { ?>
|
|
<p><strong>Your session has expired. Please try again.</strong></p>
|
|
<?php } ?>
|
|
<?php if ($exists) { ?>
|
|
<p><strong>An editor with that username already exists.</strong></p>
|
|
<?php } ?>
|
|
<?php foreach ($invalid as $problem) { ?>
|
|
<p><strong><?= form_value($problem) ?></strong></p>
|
|
<?php } ?>
|
|
<?php if ($hash_failed) { ?>
|
|
<p><strong>The editor was not added: the editors.password column is too short for the password hash. Widen it to VARCHAR(255).</strong></p>
|
|
<?php } ?>
|
|
|
|
<form action="" method="post">
|
|
<?= csrf_field() ?>
|
|
<div class="grid">
|
|
|
|
<label for="username">Username: </label>
|
|
<div class="rightcolumn">
|
|
<input type="text" id="username" name="username" required maxlength="64" autocomplete="off" />
|
|
</div>
|
|
|
|
<label for="password">Password: </label>
|
|
<div class="rightcolumn">
|
|
<input type="password" id="password" name="password" required minlength="12" autocomplete="new-password" />
|
|
</div>
|
|
|
|
<label for="email">Email: </label>
|
|
<div class="rightcolumn">
|
|
<input type="text" id="email" name="email" />
|
|
</div>
|
|
|
|
<div class="leftcolumn"></div>
|
|
<div class="submission">
|
|
<button type="submit" id="adduser" name="adduser" value="1">Add editor</button>
|
|
</div>
|
|
|
|
</div><!-- .grid -->
|
|
</form>
|
|
<?php } ?>
|
|
|
|
</div> <!-- .maintext -->
|
|
</main> <!-- .main -->
|
|
</div> <!-- .container -->
|
|
<?php include_once("../bottombar.inc.php"); ?>
|
|
|
|
</body>
|
|
</html>
|
|
|