diff options
author | TheJackiMonster <thejackimonster@gmail.com> | 2022-03-31 15:40:23 +0200 |
---|---|---|
committer | TheJackiMonster <thejackimonster@gmail.com> | 2022-03-31 15:40:23 +0200 |
commit | 5b266a4c6e22ba210086b6d9759fd8aae01abaaf (patch) | |
tree | 272f926ef806aee3404b7d23b9945f32904b6b4d | |
parent | 2134dfccf8be89fa5e1e595d6ec65a56ac357d78 (diff) |
Added account deletion and adjusted automated tests
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-rw-r--r-- | include/gnunet_chat_lib.h | 15 | ||||
-rw-r--r-- | src/gnunet_chat_handle.c | 22 | ||||
-rw-r--r-- | src/gnunet_chat_handle.h | 6 | ||||
-rw-r--r-- | src/gnunet_chat_handle_intern.c | 8 | ||||
-rw-r--r-- | src/gnunet_chat_lib.c | 74 | ||||
-rw-r--r-- | src/gnunet_chat_lib_intern.c | 54 | ||||
-rw-r--r-- | tests/test_gnunet_chat.h | 4 | ||||
-rw-r--r-- | tests/test_gnunet_chat_handle.c | 146 |
8 files changed, 253 insertions, 76 deletions
diff --git a/include/gnunet_chat_lib.h b/include/gnunet_chat_lib.h index 9e3fd04..135e82e 100644 --- a/include/gnunet_chat_lib.h +++ b/include/gnunet_chat_lib.h @@ -362,6 +362,21 @@ GNUNET_CHAT_account_create (struct GNUNET_CHAT_Handle *handle, const char* name); /** + * Deletes an existing chat account of a given chat <i>handle</i> under a + * unique <i>name</i>. + * + * If there is no account known to this chat handle under the provided name, the + * function will fail and return #GNUNET_NO. + * + * @param[in,out] handle Chat handle + * @param[in] name Account name + * @return #GNUNET_OK on success, #GNUNET_NO on failure and otherwise #GNUNET_SYSERR + */ +int +GNUNET_CHAT_account_delete(struct GNUNET_CHAT_Handle *handle, + const char* name); + +/** * Iterates through the accounts of a given chat <i>handle</i> with a selected * callback and custom closure. * diff --git a/src/gnunet_chat_handle.c b/src/gnunet_chat_handle.c index d23741b..cbbbcc7 100644 --- a/src/gnunet_chat_handle.c +++ b/src/gnunet_chat_handle.c @@ -40,6 +40,8 @@ handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg, on_handle_shutdown, handle ); + handle->destruction = NULL; + handle->internal_head = NULL; handle->internal_tail = NULL; @@ -85,7 +87,6 @@ handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg, handle->accounts_tail = NULL; handle->current = NULL; - handle->creation_op = NULL; handle->monitor = NULL; handle->lobbies_head = NULL; @@ -154,25 +155,36 @@ handle_destroy (struct GNUNET_CHAT_Handle *handle) if (handle->shutdown_hook) GNUNET_SCHEDULER_cancel(handle->shutdown_hook); + if (handle->destruction) + GNUNET_SCHEDULER_cancel(handle->destruction); + if (handle->monitor) GNUNET_NAMESTORE_zone_monitor_stop(handle->monitor); - if (handle->creation_op) - GNUNET_IDENTITY_cancel(handle->creation_op); - if (handle->current) handle_disconnect(handle); if (handle->namestore) GNUNET_NAMESTORE_disconnect(handle->namestore); + struct GNUNET_CHAT_InternalAccounts *accounts; + accounts = handle->accounts_head; + + while (accounts) + { + if (accounts->op) + GNUNET_IDENTITY_cancel(accounts->op); + + accounts->op = NULL; + accounts = accounts->next; + } + if (handle->identity) GNUNET_IDENTITY_disconnect(handle->identity); if (handle->arm) GNUNET_ARM_disconnect(handle->arm); - struct GNUNET_CHAT_InternalAccounts *accounts; while (handle->accounts_head) { accounts = handle->accounts_head; diff --git a/src/gnunet_chat_handle.h b/src/gnunet_chat_handle.h index 5702206..2cc6349 100644 --- a/src/gnunet_chat_handle.h +++ b/src/gnunet_chat_handle.h @@ -56,6 +56,10 @@ struct GNUNET_CHAT_InternalMessages struct GNUNET_CHAT_InternalAccounts { struct GNUNET_CHAT_Account *account; + + struct GNUNET_CHAT_Handle *handle; + struct GNUNET_IDENTITY_Operation *op; + struct GNUNET_CHAT_InternalAccounts *next; struct GNUNET_CHAT_InternalAccounts *prev; }; @@ -82,6 +86,7 @@ struct GNUNET_CHAT_Handle { const struct GNUNET_CONFIGURATION_Handle* cfg; struct GNUNET_SCHEDULER_Task *shutdown_hook; + struct GNUNET_SCHEDULER_Task *destruction; struct GNUNET_CHAT_InternalMessages *internal_head; struct GNUNET_CHAT_InternalMessages *internal_tail; @@ -95,7 +100,6 @@ struct GNUNET_CHAT_Handle struct GNUNET_CHAT_InternalAccounts *accounts_tail; const struct GNUNET_CHAT_Account *current; - struct GNUNET_IDENTITY_Operation *creation_op; struct GNUNET_NAMESTORE_ZoneMonitor *monitor; struct GNUNET_CHAT_InternalLobbies *lobbies_head; diff --git a/src/gnunet_chat_handle_intern.c b/src/gnunet_chat_handle_intern.c index cf8a3b3..63758a8 100644 --- a/src/gnunet_chat_handle_intern.c +++ b/src/gnunet_chat_handle_intern.c @@ -224,6 +224,9 @@ on_handle_gnunet_identity(void *cls, { struct GNUNET_CHAT_Handle* handle = cls; + if (!name) + return; + if (!ego) goto send_refresh; @@ -248,6 +251,8 @@ on_handle_gnunet_identity(void *cls, handle->accounts_tail, accounts ); + + GNUNET_free(accounts); } goto send_refresh; @@ -267,6 +272,9 @@ skip_account: accounts = GNUNET_new(struct GNUNET_CHAT_InternalAccounts); accounts->account = account_create_from_ego(ego, name); + accounts->handle = handle; + accounts->op = NULL; + if (handle->directory) account_update_directory(accounts->account, handle->directory); diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c index 72db7cd..6739d15 100644 --- a/src/gnunet_chat_lib.c +++ b/src/gnunet_chat_lib.c @@ -67,10 +67,12 @@ GNUNET_CHAT_stop (struct GNUNET_CHAT_Handle *handle) { GNUNET_CHAT_VERSION_ASSERT(); - if (!handle) + if ((!handle) || (handle->destruction)) return; - handle_destroy(handle); + handle->destruction = GNUNET_SCHEDULER_add_now( + task_handle_destruction, handle + ); } @@ -93,23 +95,76 @@ GNUNET_CHAT_account_create (struct GNUNET_CHAT_Handle *handle, (0 == strcmp(accounts->account->name, name))) return GNUNET_NO; -skip_account: + skip_account: accounts = accounts->next; } - if (handle->creation_op) - GNUNET_IDENTITY_cancel(handle->creation_op); + accounts = GNUNET_new(struct GNUNET_CHAT_InternalAccounts); + accounts->account = NULL; + accounts->handle = handle; - handle->creation_op = GNUNET_IDENTITY_create( + accounts->op = GNUNET_IDENTITY_create( handle->identity, name, NULL, GNUNET_IDENTITY_TYPE_ECDSA, cb_account_creation, - handle + accounts + ); + + if (!(accounts->op)) + { + GNUNET_free(accounts); + return GNUNET_SYSERR; + } + + GNUNET_CONTAINER_DLL_insert_tail( + handle->accounts_head, + handle->accounts_tail, + accounts + ); + + return GNUNET_OK; +} + + +int +GNUNET_CHAT_account_delete(struct GNUNET_CHAT_Handle *handle, + const char* name) +{ + GNUNET_CHAT_VERSION_ASSERT(); + + if ((!handle) || (!name)) + return GNUNET_SYSERR; + + struct GNUNET_CHAT_InternalAccounts *accounts = handle->accounts_head; + while (accounts) + { + if (!(accounts->account)) + goto skip_account; + + if ((accounts->account->name) && + (0 == strcmp(accounts->account->name, name))) + break; + + skip_account: + accounts = accounts->next; + } + + if (!accounts) + return GNUNET_NO; + + if (accounts->op) + GNUNET_IDENTITY_cancel(accounts->op); + + accounts->op = GNUNET_IDENTITY_delete( + handle->identity, + name, + cb_account_deletion, + accounts ); - return (handle->creation_op? GNUNET_OK : GNUNET_SYSERR); + return (accounts->op? GNUNET_OK : GNUNET_SYSERR); } @@ -129,13 +184,14 @@ GNUNET_CHAT_iterate_accounts (const struct GNUNET_CHAT_Handle *handle, while (accounts) { if (!(accounts->account)) - return GNUNET_SYSERR; + goto skip_account; result++; if ((callback) && (GNUNET_YES != callback(cls, handle, accounts->account))) break; + skip_account: accounts = accounts->next; } diff --git a/src/gnunet_chat_lib_intern.c b/src/gnunet_chat_lib_intern.c index 444f3c0..a430fe5 100644 --- a/src/gnunet_chat_lib_intern.c +++ b/src/gnunet_chat_lib_intern.c @@ -25,15 +25,36 @@ #define GNUNET_UNUSED __attribute__ ((unused)) void +task_handle_destruction (void *cls) +{ + GNUNET_assert(cls); + + struct GNUNET_CHAT_Handle *handle = (struct GNUNET_CHAT_Handle*) cls; + + handle->destruction = NULL; + handle_destroy(handle); +} + +void cb_account_creation (void *cls, const struct GNUNET_IDENTITY_PrivateKey *key, const char *emsg) { GNUNET_assert(cls); - struct GNUNET_CHAT_Handle *handle = (struct GNUNET_CHAT_Handle*) cls; + struct GNUNET_CHAT_InternalAccounts *accounts = ( + (struct GNUNET_CHAT_InternalAccounts*) cls + ); - handle->creation_op = NULL; + struct GNUNET_CHAT_Handle *handle = accounts->handle; + + GNUNET_CONTAINER_DLL_remove( + handle->accounts_head, + handle->accounts_tail, + accounts + ); + + GNUNET_free(accounts); if (emsg) handle_send_internal_message(handle, NULL, GNUNET_CHAT_FLAG_WARNING, emsg); @@ -42,6 +63,35 @@ cb_account_creation (void *cls, } void +cb_account_deletion (void *cls, + const char *emsg) +{ + GNUNET_assert(cls); + + struct GNUNET_CHAT_InternalAccounts *accounts = ( + (struct GNUNET_CHAT_InternalAccounts*) cls + ); + + struct GNUNET_CHAT_Handle *handle = accounts->handle; + + if (emsg) + { + handle_send_internal_message(handle, NULL, GNUNET_CHAT_FLAG_WARNING, emsg); + return; + } + + GNUNET_CONTAINER_DLL_remove( + handle->accounts_head, + handle->accounts_tail, + accounts + ); + + GNUNET_free(accounts); + + handle_send_internal_message(handle, NULL, GNUNET_CHAT_FLAG_REFRESH, NULL); +} + +void cb_lobby_lookup (void *cls, uint32_t count, const struct GNUNET_GNSRECORD_Data *data) diff --git a/tests/test_gnunet_chat.h b/tests/test_gnunet_chat.h index 80803d3..2172611 100644 --- a/tests/test_gnunet_chat.h +++ b/tests/test_gnunet_chat.h @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2021 GNUnet e.V. + Copyright (C) 2021--2022 GNUnet e.V. GNUnet is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published @@ -32,6 +32,8 @@ #include <gnunet/gnunet_chat_lib.h> +#define GNUNET_CHAT_TEST_ACCOUNT "check" + #define CREATE_GNUNET_TEST(test_name, test_call) \ void \ task_##test_call (__attribute__ ((unused)) void *cls, \ diff --git a/tests/test_gnunet_chat_handle.c b/tests/test_gnunet_chat_handle.c index efa2ba9..f8a7b60 100644 --- a/tests/test_gnunet_chat_handle.c +++ b/tests/test_gnunet_chat_handle.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2021 GNUnet e.V. + Copyright (C) 2021--2022 GNUnet e.V. GNUnet is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published @@ -37,104 +37,134 @@ call_gnunet_chat_handle_init(const struct GNUNET_CONFIGURATION_Handle *cfg) CREATE_GNUNET_TEST(test_gnunet_chat_handle_init, call_gnunet_chat_handle_init) -struct GNUNET_CHAT_Handle *login_handle; +struct GNUNET_CHAT_Handle *accounts_handle; +int accounts_stage; int -on_gnunet_chat_handle_login_msg(void *cls, - struct GNUNET_CHAT_Context *context, - const struct GNUNET_CHAT_Message *message) +on_gnunet_chat_handle_accounts_it(__attribute__ ((unused)) void *cls, + __attribute__ ((unused)) const struct GNUNET_CHAT_Handle *handle, + struct GNUNET_CHAT_Account *account) +{ + const char *name = GNUNET_CHAT_account_get_name(account); + + ck_assert_ptr_ne(name, NULL); + + if (0 == strcmp(name, GNUNET_CHAT_TEST_ACCOUNT)) + accounts_stage |= 2; + + return GNUNET_YES; +} + +int +on_gnunet_chat_handle_accounts_msg(void *cls, + struct GNUNET_CHAT_Context *context, + const struct GNUNET_CHAT_Message *message) { enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(message); - ck_assert(kind == GNUNET_CHAT_KIND_LOGIN); + ck_assert(kind == GNUNET_CHAT_KIND_REFRESH); ck_assert_ptr_eq(cls, NULL); ck_assert_ptr_eq(context, NULL); - GNUNET_CHAT_stop(login_handle); + GNUNET_CHAT_iterate_accounts( + accounts_handle, + on_gnunet_chat_handle_accounts_it, + NULL + ); + + if (2 & accounts_stage) + { + if (3 == accounts_stage) + ck_assert_int_eq(GNUNET_CHAT_account_delete( + accounts_handle, + GNUNET_CHAT_TEST_ACCOUNT + ), GNUNET_OK); + + accounts_stage = 4; + } + else if (4 == accounts_stage) + GNUNET_CHAT_stop(accounts_handle); + else if (0 == accounts_stage) + { + ck_assert_int_eq(GNUNET_CHAT_account_create( + accounts_handle, + GNUNET_CHAT_TEST_ACCOUNT + ), GNUNET_OK); + + accounts_stage = 1; + } + return GNUNET_YES; } void -call_gnunet_chat_handle_login(const struct GNUNET_CONFIGURATION_Handle *cfg) +call_gnunet_chat_handle_accounts(const struct GNUNET_CONFIGURATION_Handle *cfg) { - login_handle = GNUNET_CHAT_start(cfg, on_gnunet_chat_handle_login_msg, NULL); - ck_assert_ptr_ne(login_handle, NULL); + accounts_handle = GNUNET_CHAT_start(cfg, on_gnunet_chat_handle_accounts_msg, NULL); + accounts_stage = 0; + + ck_assert_ptr_ne(accounts_handle, NULL); } -CREATE_GNUNET_TEST(test_gnunet_chat_handle_login, call_gnunet_chat_handle_login) +CREATE_GNUNET_TEST(test_gnunet_chat_handle_accounts, call_gnunet_chat_handle_accounts) -struct GNUNET_CHAT_Handle *access_handle; -int access_logins; +struct GNUNET_CHAT_Handle *connection_handle; int -on_gnunet_chat_handle_access_msg(void *cls, - struct GNUNET_CHAT_Context *context, - const struct GNUNET_CHAT_Message *message) +on_gnunet_chat_handle_connection_msg(void *cls, + struct GNUNET_CHAT_Context *context, + const struct GNUNET_CHAT_Message *message) { enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(message); + ck_assert(kind == GNUNET_CHAT_KIND_LOGIN); ck_assert_ptr_eq(cls, NULL); ck_assert_ptr_eq(context, NULL); - const char *key; - const char *name; - int result; - - if (access_logins == 0) - { - ck_assert(kind == GNUNET_CHAT_KIND_LOGIN); - - key = GNUNET_CHAT_get_key(access_handle); - ck_assert_ptr_eq(key, NULL); - - result = GNUNET_CHAT_update(access_handle); - ck_assert_int_eq(result, GNUNET_OK); - - name = GNUNET_CHAT_get_name(access_handle); - ck_assert_str_eq(name, "Access"); - } - else if (access_logins == 1) - { - ck_assert(kind == GNUNET_CHAT_KIND_LOGIN); + GNUNET_CHAT_stop(connection_handle); + return GNUNET_YES; +} - key = GNUNET_CHAT_get_key(access_handle); - ck_assert_ptr_ne(key, NULL); +void +call_gnunet_chat_handle_connection(const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + connection_handle = GNUNET_CHAT_start(cfg, on_gnunet_chat_handle_connection_msg, NULL); + ck_assert_ptr_ne(connection_handle, NULL); +} - result = GNUNET_CHAT_set_name(access_handle, "Bccess"); - ck_assert_int_eq(result, GNUNET_YES); - } - else - { - ck_assert(kind == GNUNET_CHAT_KIND_CONTACT); +CREATE_GNUNET_TEST(test_gnunet_chat_handle_connection, call_gnunet_chat_handle_connection) - ck_assert_int_eq(access_logins, 2); +struct GNUNET_CHAT_Handle *update_handle; - name = GNUNET_CHAT_get_name(access_handle); - ck_assert_str_eq(name, "Bccess"); +int +on_gnunet_chat_handle_update_msg(void *cls, + struct GNUNET_CHAT_Context *context, + const struct GNUNET_CHAT_Message *message) +{ + enum GNUNET_CHAT_MessageKind kind = GNUNET_CHAT_message_get_kind(message); - GNUNET_CHAT_stop(access_handle); - } + ck_assert_ptr_eq(cls, NULL); + ck_assert_ptr_eq(context, NULL); - access_logins++; + GNUNET_CHAT_stop(update_handle); return GNUNET_YES; } void -call_gnunet_chat_handle_access(const struct GNUNET_CONFIGURATION_Handle *cfg) +call_gnunet_chat_handle_update(const struct GNUNET_CONFIGURATION_Handle *cfg) { - access_logins = 0; - - access_handle = GNUNET_CHAT_start(cfg, on_gnunet_chat_handle_access_msg, NULL); - ck_assert_ptr_ne(access_handle, NULL); + update_handle = GNUNET_CHAT_start(cfg, on_gnunet_chat_handle_update_msg, NULL); + ck_assert_ptr_ne(update_handle, NULL); } -CREATE_GNUNET_TEST(test_gnunet_chat_handle_access, call_gnunet_chat_handle_access) +CREATE_GNUNET_TEST(test_gnunet_chat_handle_update, call_gnunet_chat_handle_update) START_SUITE(handle_suite, "Handle") ADD_TEST_TO_SUITE(test_gnunet_chat_handle_init, "Start/Stop") -ADD_TEST_TO_SUITE(test_gnunet_chat_handle_login, "Login") -ADD_TEST_TO_SUITE(test_gnunet_chat_handle_access, "Get/Set") +ADD_TEST_TO_SUITE(test_gnunet_chat_handle_accounts, "Accounts") +ADD_TEST_TO_SUITE(test_gnunet_chat_handle_connection, "Connect/Disconnect") +ADD_TEST_TO_SUITE(test_gnunet_chat_handle_update, "Update") END_SUITE MAIN_SUITE(handle_suite, CK_NORMAL) |