Implement deleting a user
This commit is contained in:
@@ -5,7 +5,7 @@ static Noh_String build_path_(bool url, Noh_String_View *first, ...) {
|
|||||||
va_start(args, first);
|
va_start(args, first);
|
||||||
bool start = true;
|
bool start = true;
|
||||||
Noh_String result = {0};
|
Noh_String result = {0};
|
||||||
if (url) noh_string_append_cstr(&result, "/");
|
if (url || noh_sv_starts_with(*first, noh_sv_from_cstr("/"))) noh_string_append_cstr(&result, "/");
|
||||||
|
|
||||||
while (elem_ != NULL) {
|
while (elem_ != NULL) {
|
||||||
Noh_String_View elem = *elem_;
|
Noh_String_View elem = *elem_;
|
||||||
|
|||||||
102
src/userctl.c
102
src/userctl.c
@@ -1,5 +1,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sha256.h>
|
#include <sha256.h>
|
||||||
|
#include <dirent.h>
|
||||||
#define NOH_IMPLEMENTATION
|
#define NOH_IMPLEMENTATION
|
||||||
#include "noh.h"
|
#include "noh.h"
|
||||||
|
|
||||||
@@ -70,6 +71,38 @@ typedef struct {
|
|||||||
size_t capacity;
|
size_t capacity;
|
||||||
} Users;
|
} Users;
|
||||||
|
|
||||||
|
bool remove_directory(char *path) {
|
||||||
|
noh_arena_save(&temp);
|
||||||
|
bool result = true;
|
||||||
|
|
||||||
|
DIR *dir = opendir(path);
|
||||||
|
if (!dir) return false;
|
||||||
|
|
||||||
|
struct dirent *p;
|
||||||
|
while ((p = readdir(dir))) {
|
||||||
|
// Ignore . and .. file entries.
|
||||||
|
if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) continue;
|
||||||
|
|
||||||
|
char *sub_path = noh_arena_sprintf(&temp, "%s/%s", path, p->d_name);
|
||||||
|
|
||||||
|
// Delete files and recurse subfolders.
|
||||||
|
struct stat statbuf;
|
||||||
|
if (!stat(sub_path, &statbuf)) {
|
||||||
|
if (S_ISDIR(statbuf.st_mode))
|
||||||
|
result &= remove_directory(sub_path);
|
||||||
|
else
|
||||||
|
result &= unlink(sub_path) == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
|
||||||
|
if (result) result = rmdir(path);
|
||||||
|
|
||||||
|
noh_arena_reset(&temp);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
bool read_users_file(char *file_path, Users *users) {
|
bool read_users_file(char *file_path, Users *users) {
|
||||||
Noh_String users_file = {0};
|
Noh_String users_file = {0};
|
||||||
|
|
||||||
@@ -99,11 +132,13 @@ bool read_users_file(char *file_path, Users *users) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool write_users_file(char *file_path, Users *users) {
|
bool write_users_file(char *file_path, Users *users, User *user_to_skip) {
|
||||||
Noh_String users_file = {0};
|
Noh_String users_file = {0};
|
||||||
|
|
||||||
for (size_t i = 0; i < users->count; i++) {
|
for (size_t i = 0; i < users->count; i++) {
|
||||||
User *u = &users->elems[i];
|
User *u = &users->elems[i];
|
||||||
|
if (u == user_to_skip) continue;
|
||||||
|
|
||||||
noh_string_append_sv(&users_file, u->username);
|
noh_string_append_sv(&users_file, u->username);
|
||||||
noh_string_append_cstr(&users_file, ":");
|
noh_string_append_cstr(&users_file, ":");
|
||||||
noh_string_append_sv(&users_file, u->hash);
|
noh_string_append_sv(&users_file, u->hash);
|
||||||
@@ -149,14 +184,14 @@ bool register_user(Noh_String_View library_path, Noh_String_View username, Noh_S
|
|||||||
if (!noh_sv_eq_ci(user->username, username)) continue;
|
if (!noh_sv_eq_ci(user->username, username)) continue;
|
||||||
|
|
||||||
// The user exists. Update password after confirmation.
|
// The user exists. Update password after confirmation.
|
||||||
if (!prompt_user("User already exists. Update password? [yn]")) {
|
if (!prompt_user("User already exists. Update password?")) {
|
||||||
noh_log(NOH_INFO, "Ok, not changing anything.");
|
noh_log(NOH_INFO, "Ok, not changing anything.");
|
||||||
noh_return_defer(true);
|
noh_return_defer(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
noh_log(NOH_INFO, "Updating user password.");
|
noh_log(NOH_INFO, "Updating user password.");
|
||||||
user->hash = noh_sv_from_string(hashed);
|
user->hash = noh_sv_from_string(hashed);
|
||||||
if (!write_users_file(users_file_path.elems, &users)) noh_return_defer(false);
|
if (!write_users_file(users_file_path.elems, &users, NULL)) noh_return_defer(false);
|
||||||
|
|
||||||
noh_return_defer(true);
|
noh_return_defer(true);
|
||||||
}
|
}
|
||||||
@@ -164,7 +199,58 @@ bool register_user(Noh_String_View library_path, Noh_String_View username, Noh_S
|
|||||||
// User was not found, add it to the list.
|
// User was not found, add it to the list.
|
||||||
noh_log(NOH_INFO, "Adding a new user.");
|
noh_log(NOH_INFO, "Adding a new user.");
|
||||||
noh_da_append(&users, ((User){ .username = username, .hash = noh_sv_from_string(hashed) }));
|
noh_da_append(&users, ((User){ .username = username, .hash = noh_sv_from_string(hashed) }));
|
||||||
if (!write_users_file(users_file_path.elems, &users)) noh_return_defer(false);
|
if (!write_users_file(users_file_path.elems, &users, NULL)) noh_return_defer(false);
|
||||||
|
|
||||||
|
defer:
|
||||||
|
noh_da_free(&users);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool delete_user(Noh_String_View library_path, Noh_String_View username) {
|
||||||
|
// Read the file.
|
||||||
|
Noh_String_View file_name = noh_sv_from_cstr("users.conf");
|
||||||
|
Noh_String users_file_path = build_path(false, &library_path, &file_name);
|
||||||
|
noh_string_append_null(&users_file_path);
|
||||||
|
|
||||||
|
// Build users map.
|
||||||
|
Users users = {0};
|
||||||
|
if (!read_users_file(users_file_path.elems, &users)) return false;
|
||||||
|
bool result = true;
|
||||||
|
|
||||||
|
// Check if the user exists.
|
||||||
|
User *user_to_delete = NULL;
|
||||||
|
for (size_t i = 0; i < users.count; i++) {
|
||||||
|
User *user = &users.elems[i];
|
||||||
|
if (!noh_sv_eq_ci(user->username, username)) continue;
|
||||||
|
|
||||||
|
user_to_delete = user;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// User does not exist, don't change anything.
|
||||||
|
if (!user_to_delete) {
|
||||||
|
noh_log(NOH_INFO, "User does not exist.");
|
||||||
|
noh_return_defer(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The user exists. Prompt to confirm deletion.
|
||||||
|
if (!prompt_user("User found, delete the user?")) {
|
||||||
|
noh_log(NOH_INFO, "Ok, not changing anything.");
|
||||||
|
noh_return_defer(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
noh_log(NOH_INFO, "Deleting user.");
|
||||||
|
if (!write_users_file(users_file_path.elems, &users, user_to_delete)) noh_return_defer(false);
|
||||||
|
|
||||||
|
// Prompt to delete the user's library folder.
|
||||||
|
Noh_String user_folder_path = build_path(false, &library_path, &username);
|
||||||
|
noh_string_append_null(&user_folder_path);
|
||||||
|
if (!noh_file_exists(user_folder_path.elems)) noh_return_defer(true);
|
||||||
|
|
||||||
|
if (prompt_user("Library folder exists. Delete it?")) {
|
||||||
|
noh_log(NOH_INFO, "Deleting library folder.");
|
||||||
|
return remove_directory(user_folder_path.elems);
|
||||||
|
}
|
||||||
|
|
||||||
defer:
|
defer:
|
||||||
noh_da_free(&users);
|
noh_da_free(&users);
|
||||||
@@ -218,22 +304,22 @@ int main(int argc, char **argv) {
|
|||||||
if (argc < 1) show_usage(program_name, "Password not provided.");
|
if (argc < 1) show_usage(program_name, "Password not provided.");
|
||||||
Noh_String_View password = noh_sv_from_cstr(noh_shift_args(&argc, &argv));
|
Noh_String_View password = noh_sv_from_cstr(noh_shift_args(&argc, &argv));
|
||||||
|
|
||||||
return register_user(library_path, username, password);
|
return register_user(library_path, username, password) ? 0 : 1;
|
||||||
|
|
||||||
} else if (noh_sv_eq_ci(command, sv("delete"))) {
|
} else if (noh_sv_eq_ci(command, sv("delete"))) {
|
||||||
if (argc < 1) show_usage(program_name, "Username not provided.");
|
if (argc < 1) show_usage(program_name, "Username not provided.");
|
||||||
Noh_String_View username = noh_sv_from_cstr(noh_shift_args(&argc, &argv));
|
Noh_String_View username = noh_sv_from_cstr(noh_shift_args(&argc, &argv));
|
||||||
(void)username;
|
|
||||||
|
|
||||||
noh_assert(false);
|
return delete_user(library_path, username) ? 0 : 1;
|
||||||
|
|
||||||
} else if (noh_sv_eq_ci(command, sv("list"))) {
|
} else if (noh_sv_eq_ci(command, sv("list"))) {
|
||||||
return list_users(library_path);
|
return list_users(library_path) ? 0 : 1;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
noh_arena_save(&temp);
|
noh_arena_save(&temp);
|
||||||
show_usage(program_name, noh_arena_sprintf(&temp, "Unknown command: "Nsv_Fmt, Nsv_Arg(command)));
|
show_usage(program_name, noh_arena_sprintf(&temp, "Unknown command: "Nsv_Fmt, Nsv_Arg(command)));
|
||||||
noh_arena_reset(&temp);
|
noh_arena_reset(&temp);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user