added update user change user and change password
This commit is contained in:
1 parent
33e8bed178
commit
9c3a8d796a
14 files changed
+278
-45
No files matched your search
@@ -23,6 +23,9 @@ executable(
|
||||
'src/db_get_user_by_username.c',
|
||||
'src/db_get_users_from_file.c',
|
||||
'src/file.c',
|
||||
'src/db_insert_user.c',
|
||||
'src/db_update_user.c',
|
||||
'src/db_delete_user.c',
|
||||
include_directories: include_dirs,
|
||||
dependencies: deps,
|
||||
)
|
||||
+40
-1
@@ -10,8 +10,47 @@ void add_user(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
MG_ESC("invalid token"));
|
||||
return;
|
||||
}
|
||||
cJSON *jsonbody = cJSON_Parse(hm->body.buf);
|
||||
cJSON *username = cJSON_GetObjectItem(jsonbody, "username");
|
||||
cJSON *password = cJSON_GetObjectItem(jsonbody, "password");
|
||||
cJSON *email = cJSON_GetObjectItem(jsonbody, "email");
|
||||
cJSON *group = cJSON_GetObjectItem(jsonbody, "group");
|
||||
cJSON *is_superuser = cJSON_GetObjectItem(jsonbody, "is_superuser");
|
||||
if (username == nullptr || password == nullptr || email == nullptr ||
|
||||
is_superuser == nullptr || group == nullptr) {
|
||||
mg_http_reply(c, 400, "", "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("must have <username>, <password>, <email>, <group, "
|
||||
"optional>, <is_superuser, optional>"));
|
||||
return;
|
||||
}
|
||||
cJSON *payload = jwt_get_payload(requestdata->token);
|
||||
bool jwt_is_superuser =
|
||||
cJSON_GetObjectItem(payload, "is_superuser")->valueint;
|
||||
if (!jwt_is_superuser) {
|
||||
mg_http_reply(c, 403, "", "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("not authorized"));
|
||||
cJSON_Delete(payload);
|
||||
return;
|
||||
}
|
||||
const bool user_is_superuser = is_superuser->valueint ? true : false;
|
||||
User *new_db_user = db_insert_user(
|
||||
username->valuestring, email->valuestring, password->valuestring,
|
||||
group->valuestring,
|
||||
&user_is_superuser);
|
||||
if (!new_db_user) {
|
||||
mg_http_reply(c, 500, "", "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("failed to create user"));
|
||||
cJSON_Delete(payload);
|
||||
return;
|
||||
}
|
||||
char responsedata[2048] = {0};
|
||||
snprintf(responsedata, sizeof(responsedata), "{\"success\": true}");
|
||||
snprintf(responsedata, sizeof(responsedata),
|
||||
"{\"username\":\"%s\",\"email\":\"%s\",\"group\":\"%s\",\"is_"
|
||||
"superuser\":%s}",
|
||||
username->valuestring, email->valuestring, group->valuestring,
|
||||
is_superuser->valueint ? "true" : "false");
|
||||
|
||||
|
||||
mg_http_reply(c, 200, "Content-Type: application/json\r\n", responsedata);
|
||||
cJSON_Delete(payload);
|
||||
}
|
||||
@@ -10,8 +10,39 @@ void change_password(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
MG_ESC("invalid token"));
|
||||
return;
|
||||
}
|
||||
cJSON *jsonbody = cJSON_Parse(hm->body.buf);
|
||||
cJSON *old_password = cJSON_GetObjectItem(jsonbody, "old_password");
|
||||
cJSON *new_password = cJSON_GetObjectItem(jsonbody, "new_password");
|
||||
if (old_password == nullptr || new_password == nullptr) {
|
||||
mg_http_reply(c, 400, "", "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("must have <old_password>, <new_password>"));
|
||||
return;
|
||||
}
|
||||
cJSON *payload = jwt_get_payload(requestdata->token);
|
||||
char *username = cJSON_GetObjectItem(payload, "username")->valuestring;
|
||||
User *old_user_data = db_get_user_by_username(username);
|
||||
char *password = old_user_data->password;
|
||||
|
||||
if (strcmp(password, old_password->valuestring)) {
|
||||
mg_http_reply(c, 400, "", "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("invalid old password"));
|
||||
return;
|
||||
}
|
||||
const bool old_is_superuser = old_user_data->is_superuser;
|
||||
User *new_user_data = db_update_user(
|
||||
old_user_data->id, old_user_data->username, old_user_data->email,
|
||||
new_password->valuestring, old_user_data->group, &old_is_superuser);
|
||||
if (!new_user_data) {
|
||||
mg_http_reply(c, 500, "", "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("failed to update user"));
|
||||
return;
|
||||
}
|
||||
|
||||
char responsedata[64] = {0};
|
||||
snprintf(responsedata, sizeof(responsedata), "{\"success\": true}");
|
||||
|
||||
mg_http_reply(c, 200, "Content-Type: application/json\r\n", responsedata);
|
||||
// free(username);
|
||||
free_user(old_user_data);
|
||||
cJSON_Delete(payload);
|
||||
}
|
||||
+51
-1
@@ -10,8 +10,58 @@ void change_user(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
MG_ESC("invalid token"));
|
||||
return;
|
||||
}
|
||||
cJSON *jsonbody = cJSON_Parse(hm->body.buf);
|
||||
cJSON *username = cJSON_GetObjectItem(jsonbody, "username");
|
||||
cJSON *email = cJSON_GetObjectItem(jsonbody, "email");
|
||||
cJSON *group = cJSON_GetObjectItem(jsonbody, "group");
|
||||
cJSON *is_superuser = cJSON_GetObjectItem(jsonbody, "is_superuser");
|
||||
User *old_user_data = db_get_user_by_username(username->valuestring);
|
||||
if (!old_user_data) {
|
||||
mg_http_reply(c, 404, "", "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("user not found"));
|
||||
return;
|
||||
}
|
||||
char *password = old_user_data->password;
|
||||
if (!password) {
|
||||
mg_http_reply(c, 400, "", "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("password is required"));
|
||||
return;
|
||||
}
|
||||
if (username == nullptr || email == nullptr ||
|
||||
is_superuser == nullptr || group == nullptr) {
|
||||
mg_http_reply(c, 400, "", "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("must have <username>, <email>, <group, "
|
||||
"optional>, <is_superuser, optional>"));
|
||||
free_user(old_user_data);
|
||||
free(password);
|
||||
return;
|
||||
}
|
||||
cJSON *payload = jwt_get_payload(requestdata->token);
|
||||
int id = cJSON_GetObjectItem(payload, "id")->valueint;
|
||||
const bool user_is_superuser = is_superuser->valueint ? true : false;
|
||||
User *updated_user_data = db_update_user(
|
||||
id, username->valuestring, email->valuestring, password,
|
||||
group->valuestring, &user_is_superuser);
|
||||
|
||||
if (!updated_user_data) {
|
||||
mg_http_reply(c, 500, "", "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("failed to update user"));
|
||||
cJSON_Delete(payload);
|
||||
free_user(old_user_data);
|
||||
free(password);
|
||||
return;
|
||||
}
|
||||
|
||||
char responsedata[2048] = {0};
|
||||
snprintf(responsedata, sizeof(responsedata), "{\"success\": true}");
|
||||
snprintf(responsedata, sizeof(responsedata),
|
||||
"{\"username\":\"%s\",\"email\":\"%s\",\"group\":\"%s\",\"is_"
|
||||
"superuser\":%s}",
|
||||
username->valuestring, email->valuestring, group->valuestring,
|
||||
is_superuser->valueint ? "true" : "false");
|
||||
|
||||
mg_http_reply(c, 200, "Content-Type: application/json\r\n", responsedata);
|
||||
free_user(updated_user_data);
|
||||
free_user(old_user_data);
|
||||
cJSON_Delete(payload);
|
||||
free(password);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#include "database.h"
|
||||
#include "sql.h"
|
||||
#include "user.h"
|
||||
|
||||
bool db_delete_user(const int id) {
|
||||
pthread_mutex_lock(&db_mutex);
|
||||
if (!db) {
|
||||
fprintf(stderr, "Database not initialized\n");
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return false;
|
||||
}
|
||||
sqlite3_stmt *stmt;
|
||||
int rc;
|
||||
|
||||
rc = sqlite3_prepare_v2(db, DELETE_USER_SQL, -1, &stmt, 0);
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "Failed to prepare statement: %s\n", sqlite3_errmsg(db));
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
sqlite3_bind_int(stmt, 1, id);
|
||||
|
||||
rc = sqlite3_step(stmt);
|
||||
if (rc != SQLITE_DONE) {
|
||||
fprintf(stderr, "Execution failed: %s\n", sqlite3_errmsg(db));
|
||||
sqlite3_finalize(stmt);
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
int changes = sqlite3_changes(db);
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
if (changes > 0) {
|
||||
printf("User deleted successfully. ID: %d\n", id);
|
||||
} else {
|
||||
printf("No user found with ID: %d\n", id);
|
||||
return false;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return true;
|
||||
}
|
||||
@@ -1,14 +1,11 @@
|
||||
#include <cJSON.h>
|
||||
#include <sqlite3.h>
|
||||
#include "sql.h"
|
||||
#include "user.h"
|
||||
#include "file.h"
|
||||
#include "database.h"
|
||||
#include "user.h"
|
||||
|
||||
void db_get_users_from_file(const char *path) {
|
||||
char *users_string = read_file(path);
|
||||
cJSON *json_array = cJSON_Parse(users_string);
|
||||
pthread_mutex_lock(&db_mutex);
|
||||
for (int i = 0; i < cJSON_GetArraySize(json_array); i++) {
|
||||
cJSON *json_object = cJSON_GetArrayItem(json_array, i);
|
||||
const char *username =
|
||||
@@ -19,32 +16,14 @@ void db_get_users_from_file(const char *path) {
|
||||
const char *group = cJSON_GetObjectItem(json_object, "group")->valuestring;
|
||||
const bool is_superuser =
|
||||
cJSON_GetObjectItem(json_object, "is_superuser")->valueint;
|
||||
|
||||
sqlite3_stmt *stmt;
|
||||
int rc = sqlite3_prepare_v2(db, INSERT_USER_SQL, -1, &stmt, nullptr);
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "Cannot prepare statement: %s\n", sqlite3_errmsg(db));
|
||||
sqlite3_close(db);
|
||||
exit(1);
|
||||
User *new_db_user =
|
||||
db_insert_user(username, email, password, group, &is_superuser);
|
||||
if (!new_db_user) {
|
||||
fprintf(stderr, "Cannot insert user: %s\n", username);
|
||||
}
|
||||
|
||||
sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);
|
||||
sqlite3_bind_text(stmt, 2, email, -1, SQLITE_STATIC);
|
||||
sqlite3_bind_text(stmt, 3, password, -1, SQLITE_STATIC);
|
||||
sqlite3_bind_text(stmt, 4, group, -1, SQLITE_STATIC);
|
||||
sqlite3_bind_int(stmt, 5, is_superuser);
|
||||
|
||||
rc = sqlite3_step(stmt);
|
||||
if (rc != SQLITE_DONE) {
|
||||
fprintf(stderr, "Cannot insert data: %s\n", sqlite3_errmsg(db));
|
||||
} else {
|
||||
printf("Record inserted successfully. Row ID: %lld\n",
|
||||
sqlite3_last_insert_rowid(db));
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
free_user(new_db_user);
|
||||
}
|
||||
|
||||
cJSON_Delete(json_array);
|
||||
free(users_string);
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
}
|
||||
+10
-3
@@ -4,14 +4,16 @@
|
||||
|
||||
User *db_insert_user(const char *username, const char *email,
|
||||
const char *password, const char *group,
|
||||
bool *is_superuser) {
|
||||
const bool *is_superuser) {
|
||||
pthread_mutex_lock(&db_mutex);
|
||||
if (!db) {
|
||||
fprintf(stderr, "Databse not initialized\n");
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return nullptr;
|
||||
}
|
||||
if (!username || !email || !password) {
|
||||
fprintf(stderr, "username, email, password connot be empty\n");
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return nullptr;
|
||||
}
|
||||
const char *sql = nullptr;
|
||||
@@ -27,6 +29,7 @@ User *db_insert_user(const char *username, const char *email,
|
||||
rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "Cannot prepare statement: %s\n", sqlite3_errmsg(db));
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -38,13 +41,14 @@ User *db_insert_user(const char *username, const char *email,
|
||||
sqlite3_bind_text(stmt, 4, group, -1, SQLITE_STATIC);
|
||||
}
|
||||
if (is_superuser) {
|
||||
sqlite3_bind_int(stmt, 5, is_superuser);
|
||||
sqlite3_bind_int(stmt, 5, *is_superuser);
|
||||
}
|
||||
|
||||
rc = sqlite3_step(stmt);
|
||||
if (rc != SQLITE_DONE) {
|
||||
fprintf(stderr, "Execution failed: %s\n", sqlite3_errmsg(db));
|
||||
sqlite3_finalize(stmt);
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -53,4 +57,7 @@ User *db_insert_user(const char *username, const char *email,
|
||||
sqlite3_finalize(stmt);
|
||||
printf("User inserted successfully. ID: %d\n", inserted_id);
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
}
|
||||
User *new_db_user =
|
||||
new_user(inserted_id, username, email, password, group, is_superuser);
|
||||
return new_db_user;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "database.h"
|
||||
#include "sql.h"
|
||||
#include "user.h"
|
||||
|
||||
User *db_update_user(const int userid, const char *username, const char *email,
|
||||
const char *password, const char *group,
|
||||
const bool *is_superuser) {
|
||||
pthread_mutex_lock(&db_mutex);
|
||||
if (!db) {
|
||||
fprintf(stderr, "Databse not initialized\n");
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return nullptr;
|
||||
}
|
||||
if (!username || !email || !password || !group || !is_superuser) {
|
||||
fprintf(stderr,
|
||||
"username, email, password, group, is_superuser connot be empty\n");
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return nullptr;
|
||||
}
|
||||
sqlite3_stmt *stmt;
|
||||
int rc;
|
||||
|
||||
rc = sqlite3_prepare_v2(db, UPDATE_USER_FULL_SQL, -1, &stmt, 0);
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "Failed to prepare statement: %s\n", sqlite3_errmsg(db));
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return nullptr;
|
||||
}
|
||||
sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);
|
||||
sqlite3_bind_text(stmt, 2, email, -1, SQLITE_STATIC);
|
||||
sqlite3_bind_text(stmt, 3, password, -1, SQLITE_STATIC);
|
||||
sqlite3_bind_text(stmt, 4, group, -1, SQLITE_STATIC);
|
||||
sqlite3_bind_int(stmt, 5, *is_superuser);
|
||||
sqlite3_bind_int(stmt, 6, userid);
|
||||
|
||||
rc = sqlite3_step(stmt);
|
||||
if (rc != SQLITE_DONE) {
|
||||
fprintf(stderr, "Execution failed: %s\n", sqlite3_errmsg(db));
|
||||
sqlite3_finalize(stmt);
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int changes = sqlite3_changes(db);
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
if (changes > 0) {
|
||||
printf("User updated successfully. ID: %d\n", userid);
|
||||
} else {
|
||||
printf("No user found with ID: %d\n", userid);
|
||||
return nullptr;
|
||||
}
|
||||
pthread_mutex_unlock(&db_mutex);
|
||||
return new_user(userid, username, email, password, group, is_superuser);
|
||||
}
|
||||
+5
-1
@@ -10,8 +10,12 @@ void delete_user(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
MG_ESC("invalid token"));
|
||||
return;
|
||||
}
|
||||
cJSON *payload = jwt_get_payload(requestdata->token);
|
||||
int id = cJSON_GetObjectItem(payload, "id")->valueint;
|
||||
bool user_deleted = db_delete_user(id);
|
||||
char responsedata[2048] = {0};
|
||||
snprintf(responsedata, sizeof(responsedata), "{\"success\": true}");
|
||||
snprintf(responsedata, sizeof(responsedata), "{\"success\": %s}",
|
||||
user_deleted ? "true" : "false");
|
||||
|
||||
mg_http_reply(c, 200, "Content-Type: application/json\r\n", responsedata);
|
||||
}
|
||||
+1
-2
@@ -2,7 +2,6 @@
|
||||
#include <sqlite3.h>
|
||||
#include "database.h"
|
||||
#include "route.h"
|
||||
#include "sql.h"
|
||||
#include "user.h"
|
||||
|
||||
static void root_handler(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
@@ -18,7 +17,7 @@ static const struct route routes[] = {
|
||||
{"POST", "/api/users/user", get_user},
|
||||
{"POST", "/api/users/delete", delete_user},
|
||||
{"POST", "/api/users/password", change_password},
|
||||
{"POST", "/api/users/change", change_password},
|
||||
{"POST", "/api/users/change", change_user},
|
||||
{"POST", "/api/users/add", add_user},
|
||||
{"POST", "/api/register", register_user},
|
||||
{nullptr, nullptr, nullptr}};
|
||||
|
||||
+5
-3
@@ -25,9 +25,10 @@ void register_user(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
if (is_superuser == nullptr) {
|
||||
is_superuser = cJSON_CreateBool(false);
|
||||
}
|
||||
const User *new_user_data =
|
||||
new_user(0, username->valuestring, password->valuestring, email->valuestring,
|
||||
group->valuestring, is_superuser->valueint);
|
||||
const bool is_superuser_value = is_superuser->valueint ? true : false;
|
||||
User *new_user_data = db_insert_user(
|
||||
username->valuestring, email->valuestring, password->valuestring,
|
||||
group->valuestring, (const bool*)is_superuser_value);
|
||||
if (new_user_data == nullptr) {
|
||||
mg_http_reply(c, 500, "", "{%m:%m}", MG_ESC("error"),
|
||||
MG_ESC("failed to create user"));
|
||||
@@ -41,4 +42,5 @@ void register_user(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
new_user_data->group, new_user_data->is_superuser);
|
||||
|
||||
mg_http_reply(c, 200, "Content-Type: application/json\r\n", responsedata);
|
||||
free_user(new_user_data);
|
||||
}
|
||||
@@ -24,3 +24,8 @@
|
||||
#define INSERT_USER_FULL_SQL \
|
||||
"insert into users (username, email, password, user_group, is_superuser) " \
|
||||
"values (?, ?, ?, ?, ?)"
|
||||
#define UPDATE_USER_FULL_SQL \
|
||||
"update users set username = ?, email = ?, password = ?, user_group = ?, " \
|
||||
"is_superuser = ? where id = ?"
|
||||
#define DELETE_USER_SQL "delete from users where id = ?"
|
||||
#define UPDATE_USER_PASSWORD_SQL "update users set password = ? where id = ?"
|
||||
+17
-6
@@ -24,8 +24,8 @@ void free_request_with_token(request_with_token *data) {
|
||||
free(data);
|
||||
}
|
||||
|
||||
User *new_user(int id, const char *username, const char *password, const char *email,
|
||||
const char *group, bool is_superuser) {
|
||||
User *new_user(int id, const char *username, const char *password,
|
||||
const char *email, const char *group, bool is_superuser) {
|
||||
User *user = malloc(sizeof(User));
|
||||
if (user == NULL) {
|
||||
return NULL;
|
||||
@@ -40,9 +40,20 @@ User *new_user(int id, const char *username, const char *password, const char *e
|
||||
}
|
||||
|
||||
void free_user(User *user) {
|
||||
free(user->username);
|
||||
free(user->password);
|
||||
free(user->email);
|
||||
free(user->group);
|
||||
if (!user) {
|
||||
return;
|
||||
}
|
||||
if (user->username != nullptr) {
|
||||
free(user->username);
|
||||
}
|
||||
if (user->password != nullptr) {
|
||||
free(user->password);
|
||||
}
|
||||
if (user->email != nullptr) {
|
||||
free(user->email);
|
||||
}
|
||||
if (user->group != nullptr) {
|
||||
free(user->group);
|
||||
}
|
||||
free(user);
|
||||
}
|
||||
+5
-1
@@ -57,4 +57,8 @@ char *db_get_all_users();
|
||||
User *db_get_user_by_username(const char *username);
|
||||
User *db_insert_user(const char *username, const char *email,
|
||||
const char *password, const char *group,
|
||||
bool *is_superuser);
|
||||
const bool *is_superuser);
|
||||
User *db_update_user(const int userid, const char *username, const char *email,
|
||||
const char *password, const char *group,
|
||||
const bool *is_superuser);
|
||||
bool db_delete_user(const int id);
|
||||
Reference in new issue
Block a user