Add user maintenance CLI (#9)

- Add CLI infrastructure
- Add user to index page query
- Strip tags from title
- Move item parsing to FeedItem
This commit is contained in:
2024-04-27 13:01:57 -04:00
parent 7b21b86550
commit c1790b58fd
8 changed files with 318 additions and 76 deletions

177
src/util/user.php Normal file
View File

@@ -0,0 +1,177 @@
<?php
use JetBrains\PhpStorm\NoReturn;
require __DIR__ . '/../cli-start.php';
cli_title('USER MAINTENANCE');
/**
* Display the options for this utility and exit
*/
#[NoReturn]
function display_help(): void {
printfn('Options:');
printfn(' - add-user [e-mail] [password]');
printfn(' Adds a new user to this instance');
printfn(' - set-password [e-mail] [password]');
printfn(' Sets the password for the given user');
printfn(' - delete-user [e-mail]');
printfn(' Deletes a user and all their data' . PHP_EOL);
printfn('To assist with migrating from single-user to multi-user mode:');
printfn(' - migrate-single-user [e-mail] [password]');
printfn(' Changes the e-mail address and password for the single-user mode user');
printfn(' - remove-single-user');
printfn(' Removes the single-user mode user and its data');
exit(0);
}
if ($argc < 2) display_help();
switch ($argv[1]) {
case 'add-user':
if ($argc < 4) {
printfn('Missing parameters: add-user requires e-mail and password');
exit(-1);
}
add_user();
break;
case 'set-password':
if ($argc < 4) {
printfn('Missing parameters: set-password requires e-mail and password');
exit(-1);
}
set_password();
break;
case 'delete-user':
if ($argc < 3) {
printfn('Missing parameters: delete-user requires e-mail address');
exit(-1);
}
delete_user();
break;
case 'migrate-single-user':
printfn('TODO: single-user migration');
break;
case 'remove-single-user':
printfn('TODO: single-user removal');
break;
default:
printfn('Unrecognized option "%s"', $argv[1]);
display_help();
}
/**
* Add a new user
*/
function add_user(): void {
global $argv;
$db = Data::getConnection();
try {
// Ensure there is not already a user with this e-mail address
$existsQuery = $db->prepare('SELECT COUNT(*) FROM frc_user WHERE email = :email');
$existsQuery->bindValue(':email', $argv[2]);
$existsResult = $existsQuery->execute();
if (!$existsResult) {
printfn('SQLite error: %s', $db->lastErrorMsg());
return;
}
if ($existsResult->fetchArray(SQLITE3_NUM)[0] != 0) {
printfn('A user with e-mail address "%s" already exists', $argv[2]);
return;
}
Security::addUser($argv[2], $argv[3], $db);
printfn('User "%s" with password "%s" added successfully', $argv[2], $argv[3]);
} finally {
$db->close();
}
}
/**
* Set a user's password
*/
function set_password(): void {
global $argv;
$db = Data::getConnection();
try {
// Ensure this user exists
$existsQuery = $db->prepare('SELECT COUNT(*) FROM frc_user WHERE email = :email');
$existsQuery->bindValue(':email', $argv[2]);
$existsResult = $existsQuery->execute();
if (!$existsResult) {
printfn('SQLite error: %s', $db->lastErrorMsg());
return;
}
if ($existsResult->fetchArray(SQLITE3_NUM)[0] == 0) {
printfn('No user exists with e-mail address "%s"', $argv[2]);
return;
}
Security::updatePassword($argv[2], $argv[3], $db);
printfn('User "%s" password set to "%s" successfully', $argv[2], $argv[3]);
} finally {
$db->close();
}
}
/**
* Delete a user
*/
function delete_user(): void {
global $argv;
$db = Data::getConnection();
try {
// Get the ID for the provided e-mail address
$idQuery = $db->prepare('SELECT id FROM frc_user WHERE email = :email');
$idQuery->bindValue(':email', $argv[2]);
$idResult = $idQuery->execute();
if (!$idResult) {
printfn('SQLite error: %s', $db->lastErrorMsg());
return;
}
$id = $idResult->fetchArray(SQLITE3_NUM);
if (!$id) {
printfn('No user exists with e-mail address "%s"', $argv[2]);
return;
}
$feedCountQuery = $db->prepare('SELECT COUNT(*) FROM feed WHERE user_id = :user');
$feedCountQuery->bindValue(':user', $id[0]);
$feedCountResult = $feedCountQuery->execute();
if (!$feedCountResult) {
printfn('SQLite error: %s', $db->lastErrorMsg());
return;
}
$feedCount = $feedCountResult->fetchArray(SQLITE3_NUM);
$proceed = readline("Delete user \"$argv[2]\" and their $feedCount[0] feed(s)? (y/N)" . PHP_EOL);
if (!$proceed || !str_starts_with(strtolower($proceed), 'y')) {
printfn('Deletion canceled');
return;
}
$itemDelete = $db->prepare('DELETE FROM item WHERE feed_id IN (SELECT id FROM feed WHERE user_id = :user)');
$itemDelete->bindValue(':user', $id[0]);
$itemDelete->execute();
$feedDelete = $db->prepare('DELETE FROM feed WHERE user_id = :user');
$feedDelete->bindValue(':user', $id[0]);
$feedDelete->execute();
$userDelete = $db->prepare('DELETE FROM frc_user WHERE id = :user');
$userDelete->bindValue(':user', $id[0]);
$userDelete->execute();
printfn('User "%s" deleted successfully', $argv[2]);
} finally {
$db->close();
}
}