diff --git a/Makefile b/Makefile index 8b3aa49..5a7cb2f 100644 --- a/Makefile +++ b/Makefile @@ -23,16 +23,16 @@ OBJS = $(OBJDIR)/*.o all: $(LIBMX) $(UTILSLIB) $(CJSON) $(SQLITE) $(SERVER) $(CLIENT) $(LIBMX): - make -sC $(LIBMX_DIR) + # make -sC $(LIBMX_DIR) $(UTILSLIB): make -sC $(UTILSLIB_DIR) $(CJSON): - make -sC $(CJSON_DIR) + # make -sC $(CJSON_DIR) $(SQLITE): - make -sC $(SQLITE_DIR) + # make -sC $(SQLITE_DIR) $(SERVER): make -sC $(SERVER_DIR) @@ -51,9 +51,9 @@ uninstall: make -sC $(SERVER_DIR) $@ make -sC $(CLIENT_DIR) $@ make -sC $(UTILSLIB_DIR) $@ - make -sC $(LIBMX_DIR) $@ - make -sC $(CJSON_DIR) $@ - make -sC $(SQLITE_DIR) $@ + # make -sC $(LIBMX_DIR) $@ + # make -sC $(CJSON_DIR) $@ + # make -sC $(SQLITE_DIR) $@ make clean rm -f $(UCHAT) diff --git a/client/inc/client.h b/client/inc/client.h index 3c789ae..5c21b1a 100644 --- a/client/inc/client.h +++ b/client/inc/client.h @@ -129,11 +129,14 @@ void handle_logout_request(bool is_client_exit); void* handle_server_updates(void* arg); int handle_delete_chat_request(const char* chat_name); void handle_delete_msg_request(int message_id); -t_msg* get_msg_from_json(cJSON* json); +t_response_code handle_delete_account_request(); void handle_edit_msg_request(int message_id, const char* new_msg_text); t_response_code handle_edit_chat_request(int chat_id, const char* new_name); t_response_code handle_edit_username_request(const char* new_name); t_response_code handle_edit_password_request(const char* new_pass, const char* old_pass); +t_response_code handle_leave_chat_request(const char* chat_name); + +t_msg* get_msg_from_json(cJSON* json); void handle_edit_password_response_code(int response_code, GtkWidget *change_password_notify_label); void handle_edit_username_response_code(int response_code, GtkWidget *change_login_notify_label); void handle_edit_chat_response_code(int response_code, GtkWidget *change_chat_name_notify_label); diff --git a/client/src/gui/delete_account_event.c b/client/src/gui/delete_account_event.c index cb5d041..2fe6ac0 100644 --- a/client/src/gui/delete_account_event.c +++ b/client/src/gui/delete_account_event.c @@ -2,5 +2,10 @@ void delete_account_btn_click(GtkWidget *widget, gpointer data) { if (widget){}; -} + if (handle_delete_account_request() == R_SUCCESS) { + client_cleanup(false); + build_authorizatioin_window(); + } + +} diff --git a/client/src/gui/leave_chat_events.c b/client/src/gui/leave_chat_events.c index c1b5bc2..6bbb844 100644 --- a/client/src/gui/leave_chat_events.c +++ b/client/src/gui/leave_chat_events.c @@ -1,6 +1,15 @@ #include "../../inc/client.h" void leave_chat_btn_click(GtkWidget *widget, gpointer data) { - + + int response_code = handle_leave_chat_request(utils->current_chat->name); + + if (response_code == R_SUCCESS) + { + utils->current_chat = NULL; + update_chatlist(); + // build_start_messaging_label(); + } + } diff --git a/client/src/request_handlers/delete_account.c b/client/src/request_handlers/delete_account.c new file mode 100644 index 0000000..de90eb2 --- /dev/null +++ b/client/src/request_handlers/delete_account.c @@ -0,0 +1,19 @@ +#include "../../inc/client.h" + +t_response_code handle_delete_account_request() { + + utils->is_suspended = true; + + cJSON *json = cJSON_CreateObject(); + cJSON_AddNumberToObject(json, "type", REQ_DELETE_ACCOUNT); + char* json_str = cJSON_PrintUnformatted(json); + cJSON_Delete(json); + + char* response = send_and_recv_from_server(utils->ssl, json_str); + int error_code = handle_server_response(response); + logger(get_response_str(error_code), error_code == R_SUCCESS ? INFO_LOG : ERROR_LOG); + + free(json_str); + free(response); + return error_code; +} diff --git a/client/src/request_handlers/get_msg.c b/client/src/request_handlers/get_msg.c index 0ed54b0..ebf0b6b 100644 --- a/client/src/request_handlers/get_msg.c +++ b/client/src/request_handlers/get_msg.c @@ -32,7 +32,6 @@ t_msg* handle_get_msg_response() { int error_code = get_response_code(json); if (error_code != R_SUCCESS) { - printf("not success -- %d\n", error_code); cJSON_Delete(json); logger(get_response_str(error_code), ERROR_LOG); return NULL; @@ -41,7 +40,6 @@ t_msg* handle_get_msg_response() { t_msg* new_msg = get_msg_from_json(msg_json); if (new_msg == NULL || new_msg->sender_id == utils->current_user->user_id) { - printf("not valid msg\n"); cJSON_Delete(json); logger(get_response_str(R_JSON_FAILURE), ERROR_LOG); return NULL; diff --git a/client/src/request_handlers/get_new_msg_count.c b/client/src/request_handlers/last_msg_id.c similarity index 90% rename from client/src/request_handlers/get_new_msg_count.c rename to client/src/request_handlers/last_msg_id.c index 08b088d..ebdeb33 100644 --- a/client/src/request_handlers/get_new_msg_count.c +++ b/client/src/request_handlers/last_msg_id.c @@ -1,6 +1,6 @@ #include "../../inc/client.h" -t_response_code get_new_msg_count_response(const char* response_str, int* i_last_msg_id) { +t_response_code last_msg_id_response(const char* response_str, int* i_last_msg_id) { if (response_str == NULL) { return R_INVALID_INPUT; @@ -57,7 +57,7 @@ int handle_last_msg_id_request(int chat_id) { free(json_str); int last_msg_id = 0; - if ((error_code = get_new_msg_count_response(response, &last_msg_id)) != R_SUCCESS) { + if ((error_code = last_msg_id_response(response, &last_msg_id)) != R_SUCCESS) { // if (error_code == R_CHAT_NOENT) { // remove_chat_from_list(chat_id); // } diff --git a/client/src/request_handlers/leave_chat.c b/client/src/request_handlers/leave_chat.c new file mode 100644 index 0000000..f693ce2 --- /dev/null +++ b/client/src/request_handlers/leave_chat.c @@ -0,0 +1,28 @@ +#include "../../inc/client.h" + +t_response_code handle_leave_chat_request(const char* chat_name) { + + utils->is_suspended = true; + + cJSON *json = cJSON_CreateObject(); + cJSON_AddStringToObject(json, "name", chat_name); + cJSON_AddNumberToObject(json, "type", REQ_LEAVE_CHAT); + char* json_str = cJSON_PrintUnformatted(json); + cJSON_Delete(json); + + char* response = send_and_recv_from_server(utils->ssl, json_str); + int error_code = handle_server_response(response); + logger(get_response_str(error_code), error_code == R_SUCCESS ? INFO_LOG : ERROR_LOG); + + if (error_code == R_SUCCESS) { + + handle_get_chats_request(); + + } + + free(json_str); + free(response); + + utils->is_suspended = false; + return error_code; +} diff --git a/client/src/request_handlers/server_updates.c b/client/src/request_handlers/server_updates.c index a2a2c64..042e02a 100644 --- a/client/src/request_handlers/server_updates.c +++ b/client/src/request_handlers/server_updates.c @@ -90,11 +90,11 @@ void* handle_server_updates(void* arg) { (void)arg; while (1) { - if (utils && utils->is_suspended) - continue; - if (!utils) break; + + if (utils && utils->is_suspended) + continue; pthread_mutex_lock(&utils->lock); t_chat* curr_chat = utils->chatlist; diff --git a/client/src/request_handlers/signup.c b/client/src/request_handlers/signup.c index 8114ce1..ecdf8b0 100644 --- a/client/src/request_handlers/signup.c +++ b/client/src/request_handlers/signup.c @@ -28,8 +28,6 @@ t_response_code handle_signup_request(const char* user_name, const char* user_pa free(json_str); free(response); - - utils->is_suspended = false; return error_code; } diff --git a/server/inc/server.h b/server/inc/server.h index ea3e4a9..97bfae0 100644 --- a/server/inc/server.h +++ b/server/inc/server.h @@ -62,6 +62,8 @@ void handle_edit_message(const cJSON* message_info, t_server_utils* utils); void handle_edit_chat(const cJSON* chat_info, t_server_utils* utils); void handle_edit_username(const cJSON* user_info, t_server_utils* utils); void handle_edit_password(const cJSON* pass_info, t_server_utils* utils); +void handle_delete_account(const cJSON* chat_info, t_server_utils* utils); +void handle_leave_chat(const cJSON* chat_info, t_server_utils* utils); t_request_type handle_usr_logout(const cJSON* logout_info, t_server_utils* utils); // SQL @@ -103,6 +105,7 @@ static const t_req_handler request_handlers[] = { handle_create_chat, handle_join_chat, handle_send_message, + handle_leave_chat, handle_delete_chat, handle_delete_message, handle_edit_message, @@ -114,6 +117,7 @@ static const t_req_handler request_handlers[] = { handle_edit_chat, handle_edit_username, handle_edit_password, + handle_delete_account, NULL }; diff --git a/server/src/api/handle_delete_account.c b/server/src/api/handle_delete_account.c new file mode 100644 index 0000000..3c5650c --- /dev/null +++ b/server/src/api/handle_delete_account.c @@ -0,0 +1,68 @@ +#include "../../inc/server.h" + +t_response_code db_delete_user(int user_id) { + + if (!db_get_username_by_id(user_id)) { + return R_USR_NOENT; + } + + char query[QUERY_LEN]; + sprintf(query, "DELETE FROM `users` WHERE `id` = '%d'", user_id); + + if (db_execute_query(query) != 0) { + return R_DB_FAILURE; + } + return R_SUCCESS; + +} + +t_response_code db_delete_member_by_user_id(int user_id) { + + char query[QUERY_LEN]; + sprintf(query, "DELETE FROM `members` WHERE `user_id` = '%d'", user_id); + if (db_execute_query(query) != 0) { + return R_DB_FAILURE; + } + + return R_SUCCESS; + +} + +static t_response_code db_delete_messages(int user_id) { + + char query[QUERY_LEN]; + sprintf(query, "DELETE FROM `messages` WHERE `user_id` = '%d'", user_id); + if (db_execute_query(query) != 0) { + return R_DB_FAILURE; + } + return R_SUCCESS; + +} + +void handle_delete_account(const cJSON* chat_info, t_server_utils* utils) { + + (void)chat_info; + if (database_init() != 0) { + send_server_response(utils->ssl, R_DB_FAILURE, REQ_DELETE_ACCOUNT); + return; + } + + int error_code = 0; + if ((error_code = db_delete_user(utils->user->user_id)) != R_SUCCESS) { + send_server_response(utils->ssl, error_code, REQ_DELETE_ACCOUNT); + } + + if ((error_code = db_delete_member_by_user_id(utils->user->user_id)) != R_SUCCESS) { + send_server_response(utils->ssl, error_code, REQ_DELETE_ACCOUNT); + } + + if ((error_code = db_delete_messages(utils->user->user_id)) != R_SUCCESS) { + send_server_response(utils->ssl, error_code, REQ_DELETE_ACCOUNT); + } + + send_server_response(utils->ssl, R_SUCCESS, REQ_DELETE_ACCOUNT); + + logger("User has been removed\n", INFO_LOG); + client_cleanup(utils, false); + +} diff --git a/server/src/api/handle_new_msg_count.c b/server/src/api/handle_last_msg_id.c similarity index 100% rename from server/src/api/handle_new_msg_count.c rename to server/src/api/handle_last_msg_id.c diff --git a/server/src/api/handle_leave_chat.c b/server/src/api/handle_leave_chat.c new file mode 100644 index 0000000..d80b031 --- /dev/null +++ b/server/src/api/handle_leave_chat.c @@ -0,0 +1,50 @@ +#include "../../inc/server.h" + +static t_response_code db_delete_member(int user_id, int chat_id) { + + if (!db_chat_exists(chat_id)) { + return R_CHAT_NOENT; + } + + if (!db_is_chat_member(user_id, chat_id)) { + return R_ISNT_CHAT_MEMBER; + } + + if (!db_has_chat_perms(user_id, chat_id, NORMAL_MEMBER)) { + return R_NO_CHAT_PERMS; + } + + char query[QUERY_LEN]; + sprintf(query, "DELETE FROM `members` WHERE `user_id` = '%d' AND `chat_id` = '%d'", user_id, chat_id); + if (db_execute_query(query) != 0) { + return R_DB_FAILURE; + } + + return R_SUCCESS; + +} + +void handle_leave_chat(const cJSON* chat_info, t_server_utils* utils) { + + if (database_init() != 0) { + send_server_response(utils->ssl, R_DB_FAILURE, REQ_LEAVE_CHAT); + return; + } + + const cJSON *chat_name = cJSON_GetObjectItemCaseSensitive(chat_info, "name"); + + if (!cJSON_IsString(chat_name)) { + send_server_response(utils->ssl, R_JSON_FAILURE, REQ_LEAVE_CHAT); + return; + } + + int chat_id = db_get_chat_id_by_name(chat_name->valuestring); + int error_code = 0; + + if ((error_code = db_delete_member(utils->user->user_id, chat_id)) != 0) { + send_server_response(utils->ssl, error_code, REQ_LEAVE_CHAT); + return; + } + send_server_response(utils->ssl, R_SUCCESS, REQ_LEAVE_CHAT); + +} diff --git a/server/src/database/db_user.c b/server/src/database/db_user.c index 9eb8c24..2c1184b 100644 --- a/server/src/database/db_user.c +++ b/server/src/database/db_user.c @@ -19,13 +19,13 @@ char* db_get_username_by_id(int user_id) { sqlite3* db = open_database(); sqlite3_stmt* stmt; - sqlite3_prepare_v2(db, "SELECT `name` FROM `users` WHERE `id` = ?", -1, &stmt, NULL); + sqlite3_prepare_v2(db, "SELECT `username` FROM `users` WHERE `id` = ?", -1, &stmt, NULL); sqlite3_bind_int64(stmt, 1, user_id); char* user_name = NULL; if (sqlite3_step(stmt) == SQLITE_ROW) { - user_name = mx_strdup((const char*)sqlite3_column_text(stmt, 1)); + user_name = mx_strdup((const char*)sqlite3_column_text(stmt, 0)); } sqlite3_finalize(stmt); diff --git a/server/src/thread_handler.c b/server/src/thread_handler.c index 56d2b9d..80b06b0 100644 --- a/server/src/thread_handler.c +++ b/server/src/thread_handler.c @@ -36,10 +36,10 @@ char* read_client_data(SSL *ssl) { char buffer[SENT_DATA_LEN]; int n_bytes = 0; - if ((n_bytes = SSL_read(ssl, buffer, SENT_DATA_LEN)) <= 0) { + while ((n_bytes = SSL_read(ssl, buffer, SENT_DATA_LEN)) <= 0) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { - return NULL; + continue; } return NULL; diff --git a/utils/inc/const.h b/utils/inc/const.h index ed3a047..3165fa9 100644 --- a/utils/inc/const.h +++ b/utils/inc/const.h @@ -5,7 +5,7 @@ #define LOGFILE_NAME "server_utils/uchat.log" #define CLIENTLOG_NAME "client/logs/client" -#define QUERY_LEN 200 +#define QUERY_LEN 500 #define SENT_DATA_LEN 4000 // Both for a chat and a user name diff --git a/utils/inc/utils.h b/utils/inc/utils.h index f578d02..ddbda25 100644 --- a/utils/inc/utils.h +++ b/utils/inc/utils.h @@ -51,6 +51,7 @@ typedef enum e_request_type { REQ_CREATE_CHAT, REQ_JOIN_CHAT, REQ_SEND_MESSAGE, + REQ_LEAVE_CHAT, REQ_DELETE_CHAT, REQ_DELETE_MESSAGE, REQ_EDIT_MESSAGE, @@ -63,6 +64,7 @@ typedef enum e_request_type { REQ_EDIT_CHAT, REQ_EDIT_USERNAME, REQ_EDIT_PASSWORD, + REQ_DELETE_ACCOUNT, REQ_USR_LOGOUT, REQ_CLIENT_EXIT, diff --git a/utils/src/db_lists/chat_list.c b/utils/src/db_lists/chat_list.c index b1ec2ae..bec66b2 100644 --- a/utils/src/db_lists/chat_list.c +++ b/utils/src/db_lists/chat_list.c @@ -161,7 +161,7 @@ void mx_clear_chat_list(t_chat **list) { next = node->next; mx_clear_msg_list(&node->messages); - // mx_clear_msg_list(&node->last_new_msg); + mx_clear_msg_list(&node->new_messages); mx_clear_chat(&node); node = next; }