diff --git a/CMakeLists.txt b/CMakeLists.txt index fe39a1d..eae9502 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,13 @@ set(USE_CALLBACK_API ON) set(USE_SET_DNS_SERVERS ON) set(USE_IPV6 ON) set(USE_SUBSCRIBE_EVENT_ENGINE ON) +set(USE_REVOKE_TOKEN_API ON) +set(USE_CRYPTO_API ON) +set(PUBNUB_CRYPTO_API ON) +set(OPENSSL ON) +set(OPENSSL_ROOT_DIR "C:/Program Files/Epic Games/UE_5.4/Engine/Source/ThirdParty/OpenSSL/1.1.1t") +set(CUSTOM_OPENSSL_LIB_DIR "lib/Win64/VS2015/Release") +set(CUSTOM_OPENSSL_INCLUDE_DIR "include/Win64/VS2015") if(WIN32 OR WIN64 OR MSVC) set(CUSTOM_BOOL_TYPE _Bool) @@ -198,7 +205,14 @@ set(SOURCES add_library(pubnub-chat SHARED ${SOURCES}) -target_compile_options(pubnub-chat PRIVATE -DPUBNUB_NTF_RUNTIME_SELECTION -DPUBNUB_USE_SUBSCRIBE_EVENT_ENGINE=1 -DPUBNUB_USE_SUBSCRIBE_V2=1 -DPUBNUB_CALLBACK_API=1 -DPUBNUB_SYNC_API=1 -DPUBNUB_SET_DNS_SERVERS=1 -DPUBNUB_USE_IPV6=1) +target_compile_options(pubnub-chat PRIVATE -DPUBNUB_NTF_RUNTIME_SELECTION -DPUBNUB_USE_SUBSCRIBE_EVENT_ENGINE=1 -DPUBNUB_USE_SUBSCRIBE_V2=1 -DPUBNUB_CALLBACK_API=1 -DPUBNUB_SYNC_API=1 -DPUBNUB_SET_DNS_SERVERS=1 -DPUBNUB_USE_IPV6=1 -DUSE_GRANT_TOKEN_API=1 -DUSE_REVOKE_TOKEN_API=1 -DUSE_CRYPTO_API=1 -DPUBNUB_CRYPTO_API=1 -DOPENSSL=1 -DOPENSSL_ROOT_DIR="C:/Program Files/Epic Games/UE_5.4/Engine/Source/ThirdParty/OpenSSL/1.1.1t" -DCUSTOM_OPENSSL_LIB_DIR="lib/Win64/VS2015/Release" -DCUSTOM_OPENSSL_INCLUDE_DIR="include/Win64/VS2015") +set(USE_GRANT_TOKEN_API ON) +set(USE_REVOKE_TOKEN_API ON) +set(USE_CRYPTO_API ON) +set(OPENSSL ON) +set(OPENSSL_ROOT_DIR "C:/Program Files/Epic Games/UE_5.4/Engine/Source/ThirdParty/OpenSSL/1.1.1t") +set(CUSTOM_OPENSSL_LIB_DIR "lib/Win64/VS2015/Release") +set(CUSTOM_OPENSSL_INCLUDE_DIR "include/Win64/VS2015") target_link_libraries(pubnub-chat PRIVATE -lpthread pubnub) diff --git a/example/main.cpp b/example/main.cpp index b02678e..3709750 100644 --- a/example/main.cpp +++ b/example/main.cpp @@ -1,3 +1,1591 @@ +#include "pubnub_chat/message.hpp" +#include "pubnub_chat/chat.hpp" +#include "pubnub_chat/chat_helpers.hpp" +#include "pubnub_chat/message_draft.hpp" +#include +#include +#include +#include + +#define TOKEN_TTL 10 +#define TOKEN_AUTH_USER_ID "pam_ccp_chat_user" + +Pubnub::String get_init_chat_token(Pubnub::AccessManager& token_access_manager, Pubnub::String user_id); +Pubnub::String get_empty_token(Pubnub::AccessManager& token_access_manager); +Pubnub::String get_create_pub_conversation_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id); +Pubnub::String get_create_user_token(Pubnub::AccessManager& token_access_manager, Pubnub::String user_id); +Pubnub::String get_get_user_token(Pubnub::AccessManager& token_access_manager, Pubnub::String user_id); +Pubnub::String get_get_users_token(Pubnub::AccessManager& token_access_manager, std::vector user_ids); +Pubnub::String get_create_dir_conversation_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, Pubnub::String current_user_id, Pubnub::String invitee_id); +Pubnub::String get_create_group_conversation_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, Pubnub::String current_user_id, std::vector invitee_ids); +Pubnub::String get_get_channel_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id); +Pubnub::String get_read_channel_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id); +Pubnub::String get_get_channels_token(Pubnub::AccessManager& token_access_manager, std::vector channel_ids); +Pubnub::String get_update_channel_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id); +Pubnub::String get_delete_channel_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id); +Pubnub::String get_update_user_token(Pubnub::AccessManager& token_access_manager, Pubnub::String user_id); +Pubnub::String get_delete_user_token(Pubnub::AccessManager& token_access_manager, Pubnub::String user_id); +Pubnub::String get_join_channel_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, Pubnub::String user_id); +Pubnub::String get_leave_channel_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, Pubnub::String user_id); +Pubnub::String get_channel_read_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id); +Pubnub::String get_channel_write_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id); +Pubnub::String get_channel_connect_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id); +Pubnub::String get_send_text_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, Pubnub::String mentioned_user_id); +Pubnub::String get_set_restrictions_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, Pubnub::String user_id); +Pubnub::String get_invite_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, Pubnub::String invitee_id); +Pubnub::String get_invite_multiple_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, std::vector invitee_ids); +Pubnub::String get_unread_messages_counts_token(Pubnub::AccessManager& token_access_manager, Pubnub::String current_user_id, std::vector channels); +Pubnub::String get_mark_all_messages_as_read_token(Pubnub::AccessManager& token_access_manager, Pubnub::String current_user_id, std::vector channels); +Pubnub::String get_thread_send_text_token(Pubnub::AccessManager& token_access_manager, Pubnub::String thread_channel_id, Pubnub::String parent_channel_id, Pubnub::String mentioned_user_id); +Pubnub::String get_remove_thread_token(Pubnub::AccessManager& token_access_manager, Pubnub::String thread_channel_id, Pubnub::String parent_channel_id); +Pubnub::String get_channel_stream_receipts_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id); +Pubnub::String get_membership_update_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, Pubnub::String user_id); +Pubnub::String get_membership_set_last_read_message_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, Pubnub::String user_id); +Pubnub::String get_message_pin_token(Pubnub::AccessManager& token_access_manager, Pubnub::String message_channel_id); +Pubnub::String get_message_unpin_token(Pubnub::AccessManager& token_access_manager, Pubnub::String message_channel_id); +Pubnub::String get_message_toggle_reaction_token(Pubnub::AccessManager& token_access_manager, Pubnub::String message_channel_id); + + int main() { - // TODO: proper examples + + auto publish_key = std::getenv("PUBNUB_PUBLISH_KEY"); + auto subscribe_key = std::getenv("PUBNUB_SUBSCRIBE_KEY"); + auto secret_key = std::getenv("PUBNUB_SECRET_KEY"); + + + //This token is needed to init chat + auto initial_auth_token = "p0F2AkF0GmfOvB5DdHRsGajAQ3Jlc6VEY2hhbqBDZ3JwoENzcGOgQ3VzcqBEdXVpZKFxcGFtX2NjcF9jaGF0X3VzZXIYaENwYXSlRGNoYW6gQ2dycKBDc3BjoEN1c3KgRHV1aWSgRG1ldGGgQ3NpZ1ggUA6E8e1Jps1cPGkW6lpzOKYzc-bjUtlLDyeUdiyv_uw="; + + auto config = Pubnub::ChatConfig(); + config.auth_key = initial_auth_token; + + auto token_chat = Pubnub::Chat::init(publish_key, subscribe_key, TOKEN_AUTH_USER_ID, config); + auto token_access_manager = token_chat.access_manager(); + token_access_manager.set_secret_key(secret_key); + + + //INIT CHAT + std::cout << "Init Test" << std::endl; + + auto user_id = "cpp_chat_user"; + + Pubnub::String init_chat_token = get_init_chat_token(token_access_manager, user_id); + auto init_chat_config = Pubnub::ChatConfig(); + init_chat_config.auth_key = init_chat_token; + auto chat = Pubnub::Chat::init(publish_key, subscribe_key, user_id, init_chat_config); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + auto chat_access_manager = chat.access_manager(); + + + + //CURRENT USER + std::cout << "Current User Test" << std::endl; + + chat_access_manager.set_auth_token(get_get_user_token(token_access_manager, user_id)); + auto current_user = chat.current_user(); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //CREATE USER + std::cout << "Create User Test" << std::endl; + + Pubnub::String create_user_id = Pubnub::String("cpp_chat_test_created_user"); + + chat_access_manager.set_auth_token(get_create_user_token(token_access_manager, create_user_id)); + auto created_user = chat.create_user(create_user_id, Pubnub::ChatUserData()); + + Pubnub::String another_user_id = Pubnub::String("cpp_chat_test_another_user"); + + chat_access_manager.set_auth_token(get_create_user_token(token_access_manager, another_user_id)); + auto another_user = chat.create_user(another_user_id, Pubnub::ChatUserData()); + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //GET USER + std::cout << "Get User Test" << std::endl; + + Pubnub::String invitee_user_id = "cpp_chat_test_invited_user"; + + chat_access_manager.set_auth_token(get_get_user_token(token_access_manager, invitee_user_id)); + auto invitee_user = chat.get_user(invitee_user_id); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //GET USERS + std::cout << "Get Users Test" << std::endl; + + //This shouldn't require any permissions + auto users_from_get = chat.get_users("id LIKE \"cpp_chat_test\"", "", 5); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //CREATE PUBLIC CONVERSATION + std::cout << "Create Public Conversation Test" << std::endl; + + Pubnub::String public_channel_id = "cpp_chat_test_public_channel"; + + chat_access_manager.set_auth_token(get_create_pub_conversation_token(token_access_manager, public_channel_id)); + auto public_channel = chat.create_public_conversation(public_channel_id, Pubnub::ChatChannelData()); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //CREATE DIRECT CONVERSATION + std::cout << "Create Direct Conversation Test" << std::endl; + + Pubnub::String direct_channel_id = "cpp_chat_test_direct_channel"; + + chat_access_manager.set_auth_token(get_create_dir_conversation_token(token_access_manager, direct_channel_id, current_user.user_id(), invitee_user_id)); + auto direct_channel = chat.create_direct_conversation(invitee_user, direct_channel_id, Pubnub::ChatChannelData()); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //CREATE GROUP CONVERSATION + std::cout << "Create Group Conversation Test" << std::endl; + + Pubnub::String group_channel_id = "cpp_chat_test_group_channel"; + + chat_access_manager.set_auth_token(get_create_group_conversation_token(token_access_manager, group_channel_id, current_user.user_id(), std::vector{invitee_user_id, create_user_id})); + auto group_channel = chat.create_group_conversation(std::vector{invitee_user, created_user}, group_channel_id, Pubnub::ChatChannelData()); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //GET CHANNEL + std::cout << "Get Channel Test" << std::endl; + + chat_access_manager.set_auth_token(get_get_channel_token(token_access_manager, public_channel_id)); + auto channel_from_get = chat.get_channel(public_channel_id); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //GET CHANNELS + std::cout << "Get Channels" << std::endl; + + //This shouldn't require any permissions + auto channels_from_get = chat.get_channels("id LIKE \"cpp_chat_test\"", "", 5); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //UPDATE CHANNEL + std::cout << "Update Channel" << std::endl; + + chat_access_manager.set_auth_token(get_update_channel_token(token_access_manager, public_channel_id)); + auto new_channel_data = Pubnub::ChatChannelData(); + new_channel_data.description = Pubnub::get_now_timetoken(); + chat.update_channel(public_channel_id, new_channel_data); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //UPDATE USER + std::cout << "Update User" << std::endl; + + chat_access_manager.set_auth_token(get_update_user_token(token_access_manager, invitee_user_id)); + auto new_user_data = Pubnub::ChatUserData(); + new_user_data.external_id = Pubnub::get_now_timetoken(); + chat.update_user(invitee_user_id, new_user_data); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + +/* + + + //CHANNEL JOIN + std::cout << "Channel.Join" << std::endl; + + chat_access_manager.set_auth_token(get_join_channel_token(token_access_manager, public_channel_id, user_id)); + auto join_lambda = [](Pubnub::Message message){}; + auto current_user_membership = public_channel.join(join_lambda); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //THESE FUNCTIONS DON'T REQUIRE PERMISSIONS + chat_access_manager.set_auth_token(get_empty_token(token_access_manager)); + std::cout << "Get Channel Suggestions" << std::endl; + chat.get_channel_suggestions("cpp"); + std::cout << "Get User Suggestions" << std::endl; + chat.get_user_suggestions("cpp"); + std::cout << "Where Present" << std::endl; + chat.where_present(user_id); + std::cout << "Is present" << std::endl; + chat.is_present(user_id, public_channel_id); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + //CHANNEL LEAVE + std::cout << "Channel.Leave" << std::endl; + + chat_access_manager.set_auth_token(get_leave_channel_token(token_access_manager, public_channel_id, user_id)); + public_channel.leave(); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //EMIT CHAT EVENT + std::cout << "Emit chat event" << std::endl; + + chat_access_manager.set_auth_token(get_channel_write_token(token_access_manager, public_channel_id)); + chat.emit_chat_event(Pubnub::pubnub_chat_event_type::PCET_CUSTOM, public_channel_id, "{\"abc\": \"bcd\"}"); + + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //WHO IS PRESENT + std::cout << "Who is present" << std::endl; + + chat_access_manager.set_auth_token(get_channel_read_token(token_access_manager, public_channel_id)); + chat.who_is_present(public_channel_id); + public_channel.who_is_present(); + + //GET EVENTS HISTORY + std::cout << "Get events history" << std::endl; + //the same permissions as who is present + chat.get_events_history(public_channel_id, Pubnub::get_now_timetoken(), "16417695239108460", 10); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //LISTEN FOR EVENTS + std::cout << "Listen for events" << std::endl; + chat_access_manager.set_auth_token(get_channel_connect_token(token_access_manager, public_channel_id)); + auto listen_for_events_lambda = [](Pubnub::Event event){}; + auto stop_listening = chat.listen_for_events(public_channel_id, Pubnub::pubnub_chat_event_type::PCET_CUSTOM, listen_for_events_lambda); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + stop_listening(); + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //CHANNEL CONNECT + + std::cout << "Channel Connect" << std::endl; + chat_access_manager.set_auth_token(get_channel_connect_token(token_access_manager, group_channel_id)); + auto connect_lambda = [](Pubnub::Message message){}; + group_channel.created_channel.connect(connect_lambda); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //CHANNEL DISCONNECT + + std::cout << "Channel Disconnect" << std::endl; + //chat_access_manager.set_auth_token(get_empty_token(token_access_manager)); + group_channel.created_channel.disconnect(); + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //CHANNEL SEND TEXT + + std::cout << "Send text" << std::endl; + + Pubnub::String mentioned_user_id = "cpp_chat_test_user_to_mention"; + Pubnub::String time_before_send_text = Pubnub::get_now_timetoken(); + + chat_access_manager.set_auth_token(get_send_text_token(token_access_manager, public_channel_id, mentioned_user_id)); + + Pubnub::SendTextParams send_params; + std::map mentioned_users; + Pubnub::MentionedUser mentioned_user; + mentioned_user.id = mentioned_user_id; + mentioned_user.name = "cpp_chat_test_user_to_mention_name"; + mentioned_users[2] = mentioned_user; + Pubnub::Map pn_mentioned_user(mentioned_users); + send_params.mentioned_users = pn_mentioned_user; + public_channel.send_text("message from test", send_params); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //CHANNEL GET HISTORY + std::cout << "Get history" << std::endl; + chat_access_manager.set_auth_token(get_channel_read_token(token_access_manager, public_channel_id)); + + auto history_messages = public_channel.get_history(Pubnub::get_now_timetoken(), time_before_send_text, 1); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //CHANNEL PIN/UNPIN MESSAGE + std::cout << "Pin message" << std::endl; + + chat_access_manager.set_auth_token(get_update_channel_token(token_access_manager, public_channel_id)); + chat.pin_message_to_channel(history_messages[0], public_channel); + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + std::cout << "Channel get pinned message" << std::endl; + + chat_access_manager.set_auth_token(get_get_channel_token(token_access_manager, public_channel_id)); + public_channel = chat.get_channel(public_channel_id); + + chat_access_manager.set_auth_token(get_read_channel_token(token_access_manager, public_channel_id)); + public_channel.get_pinned_message(); + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + std::cout << "Unpin message" << std::endl; + + chat_access_manager.set_auth_token(get_update_channel_token(token_access_manager, public_channel_id)); + chat.unpin_message_from_channel(public_channel); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //FORWARD MESSAGE + std::cout << "Forward message" << std::endl; + + chat_access_manager.set_auth_token(get_channel_write_token(token_access_manager, group_channel_id)); + chat.forward_message(history_messages[0], group_channel.created_channel); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //GET MEMBERS + std::cout << "Channel Get Members" << std::endl; + + chat_access_manager.set_auth_token(get_get_channel_token(token_access_manager, public_channel_id)); + public_channel.get_members(); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //RESTRICTIONS + std::cout << "Set restrictions" << std::endl; + + chat_access_manager.set_auth_token(get_set_restrictions_token(token_access_manager, public_channel_id, user_id)); + + Pubnub::Restriction ban_restriction; + ban_restriction.ban = true; + chat.set_restrictions(user_id, public_channel_id, ban_restriction); + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + std::cout << "Get user restrictions" << std::endl; + + chat_access_manager.set_auth_token(get_get_user_token(token_access_manager, user_id)); + public_channel.get_user_restrictions(current_user); + + std::cout << "Get users restrictions" << std::endl; + + chat_access_manager.set_auth_token(get_get_channel_token(token_access_manager, Pubnub::String("PUBNUB_INTERNAL_MODERATION_") + public_channel_id)); + public_channel.get_users_restrictions(); + + std::cout << "Lift restrictions" << std::endl; + + chat_access_manager.set_auth_token(get_set_restrictions_token(token_access_manager, public_channel_id, user_id)); + Pubnub::Restriction lift_restriction; + lift_restriction.reason = "lift"; + chat.set_restrictions(user_id, public_channel_id, lift_restriction); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //INVITE + std::cout << "Invite not member" << std::endl; + + chat_access_manager.set_auth_token(get_invite_token(token_access_manager, group_channel_id, another_user_id)); + group_channel.created_channel.invite(another_user); + + std::cout << "Invite member" << std::endl; + chat_access_manager.set_auth_token(get_invite_token(token_access_manager, group_channel_id, invitee_user_id)); + auto invitee_membership = group_channel.created_channel.invite(invitee_user); + + std::cout << "Invite multiple" << std::endl; + + chat_access_manager.set_auth_token(get_invite_multiple_token(token_access_manager, group_channel_id, std::vector{user_id, another_user_id})); + group_channel.created_channel.invite_multiple(std::vector{current_user, another_user}); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //GET UNREAD MESSAGES COUNT + std::cout << "Get Unread Messages Count" << std::endl; + + + chat_access_manager.set_auth_token(get_unread_messages_counts_token(token_access_manager, user_id, std::vector{group_channel_id, direct_channel_id, public_channel_id})); + chat.get_unread_messages_counts(); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //MARK ALL MESSAGES AS READ + std::cout << "Mark All Messages as Read" << std::endl; + + chat_access_manager.set_auth_token(get_mark_all_messages_as_read_token(token_access_manager, user_id, std::vector{group_channel_id, direct_channel_id, public_channel_id})); + chat.mark_all_messages_as_read(); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //CREATE THREAD CHANNEL + std::cout << "Create thread channel" << std::endl; + auto thread_channel_id = "PUBNUB_INTERNAL_THREAD_" + history_messages[0].message_data().channel_id + "_" + history_messages[0].timetoken(); + + chat_access_manager.set_auth_token(get_get_channel_token(token_access_manager, thread_channel_id)); + auto created_thread = chat.create_thread_channel(history_messages[0]); + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //THREAD CHANNEL: SEND MESSAGE + std::cout << "Thread channel send message" << std::endl; + + chat_access_manager.set_auth_token(get_thread_send_text_token(token_access_manager, thread_channel_id, created_thread.parent_channel_id(), mentioned_user_id)); + created_thread.send_text("message from thread", send_params); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + //GET THREAD CHANNEL + std::cout << "Get thread channel" << std::endl; + + chat_access_manager.set_auth_token(get_get_channel_token(token_access_manager, thread_channel_id)); + chat.get_thread_channel(history_messages[0]); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //GET MESSAGE + std::cout << "Channel Get Message" << std::endl; + + chat_access_manager.set_auth_token(get_channel_read_token(token_access_manager, public_channel_id)); + auto message = public_channel.get_message(history_messages[0].timetoken()); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //REMOVE THREAD CHANNEL + std::cout << "Remove thread channel" << std::endl; + + chat_access_manager.set_auth_token(get_remove_thread_token(token_access_manager, thread_channel_id, created_thread.parent_channel_id())); + chat.remove_thread_channel(message); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //CHANNEL TYPING + std::cout << "Channel: Start Typing" << std::endl; + + chat_access_manager.set_auth_token(get_channel_write_token(token_access_manager, group_channel_id)); + group_channel.created_channel.start_typing(); + + std::cout << "Channel: Get Typing" << std::endl; + + chat_access_manager.set_auth_token(get_channel_connect_token(token_access_manager, group_channel_id)); + auto typing_lambda = [](Pubnub::Vector typing){}; + auto get_typing_stop = group_channel.created_channel.get_typing(typing_lambda); + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + get_typing_stop(); + + std::cout << "Channel: Stop Typing" << std::endl; + chat_access_manager.set_auth_token(get_channel_write_token(token_access_manager, group_channel_id)); + group_channel.created_channel.stop_typing(); + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + + + //CHANNEL EMIT USER MENTION + std::cout << "Channel: Emit user mention" << std::endl; + + chat_access_manager.set_auth_token(get_channel_write_token(token_access_manager, another_user_id)); + public_channel.emit_user_mention(another_user_id, Pubnub::get_now_timetoken(), "cpp_test user mention"); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + //CHANNEL STREAM UPDATES + std::cout << "Channel: Stream updates" << std::endl; + + chat_access_manager.set_auth_token(get_channel_connect_token(token_access_manager, public_channel_id)); + auto stream_updates_lambda = [](Pubnub::Channel channel){}; + public_channel.stream_updates(stream_updates_lambda); + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + std::cout << "Channel: Stream updates on" << std::endl; + auto stream_updates_on_lambda = [](Pubnub::Vector channels){}; + public_channel.stream_updates_on(Pubnub::Vector{public_channel}, stream_updates_on_lambda); + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + std::cout << "Channel: Stream presence" << std::endl; + chat_access_manager.set_auth_token(get_channel_connect_token(token_access_manager, public_channel_id)); + auto stream_presence_lambda = [](Pubnub::Vector presence){}; + public_channel.stream_presence(stream_presence_lambda); + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + std::cout << "Channel: Stream read receipts" << std::endl; + chat_access_manager.set_auth_token(get_channel_stream_receipts_token(token_access_manager, public_channel_id)); + auto stream_receipts_lambda = [](Pubnub::Map, Pubnub::StringComparer> receipts){}; + public_channel.stream_read_receipts(stream_receipts_lambda); + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //CHANNEL GET MESSAGE REPORTS HISTORY + std::cout << "Channel: get message reports history" << std::endl; + + chat_access_manager.set_auth_token(get_channel_read_token(token_access_manager, "PUBNUB_INTERNAL_MODERATION_" + public_channel_id)); + public_channel.get_messsage_reports_history(Pubnub::get_now_timetoken(), "00000000000000000"); + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + std::cout << "Channel: Stream Message Reports" << std::endl; + + chat_access_manager.set_auth_token(get_channel_connect_token(token_access_manager, "PUBNUB_INTERNAL_MODERATION_" + public_channel_id)); + auto stream_reports_lambda = [](Pubnub::Event event){}; + public_channel.stream_message_reports(stream_reports_lambda); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + + + + //UPDATE MEMBERSHIP + std::cout << "Update Membership" << std::endl; + + chat_access_manager.set_auth_token(get_membership_update_token(token_access_manager, group_channel_id, invitee_user_id)); + invitee_membership.update("{\"abc\": \"dca\"}"); + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + //SET LAST READ MESSAGE TIMETOKEN + std::cout << "Set last read message timetoken" << std::endl; + + chat_access_manager.set_auth_token(get_membership_set_last_read_message_token(token_access_manager, group_channel_id, invitee_user_id)); + invitee_membership.set_last_read_message_timetoken(Pubnub::get_now_timetoken()); + + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + + //GET UNREAD MESSAGE COUNTS + std::cout << "Get unread message counts" << std::endl; + + chat_access_manager.set_auth_token(get_channel_read_token(token_access_manager, group_channel_id)); + invitee_membership.get_unread_messages_count(); + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + //MEMBERSHIP STREAM UPDATES + std::cout << "Membership: Stream Updates" << std::endl; + + chat_access_manager.set_auth_token(get_channel_connect_token(token_access_manager, group_channel_id)); + auto membership_stream_lambda = [](Pubnub::Membership membership){}; + auto membership_updates_stop_streaming = invitee_membership.stream_updates(membership_stream_lambda); + + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + + //MEMBERSHIP STREAM UPDATES ON + std::cout << "Membership: Stream Updates On" << std::endl; + + auto membership_stream_on_lambda = [](Pubnub::Vector memberships){}; + auto membership_updates_on_stop_streaming = invitee_membership.stream_updates_on(Pubnub::Vector{invitee_membership}, membership_stream_on_lambda); + + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + membership_updates_stop_streaming.close(); + membership_updates_on_stop_streaming.close(); + + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + + + auto message_to_test = history_messages[0]; + + //EDIT MESSAGE + std::cout << "Edit Message" << std::endl; + + chat_access_manager.set_auth_token(get_channel_write_token(token_access_manager, message_to_test.message_data().channel_id)); + message_to_test = message_to_test.edit_text("new message text" + Pubnub::get_now_timetoken()); + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + //DELETE MESSAGE + std::cout << "Delete Message" << std::endl; + + message_to_test = message_to_test.delete_message(); + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + //RESTORE MESSAGE + std::cout << "Restore Message" << std::endl; + + chat_access_manager.set_auth_token(get_delete_channel_token(token_access_manager, message_to_test.message_data().channel_id)); + message_to_test.restore(); + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + //PIN MESSAGE + std::cout << "Pin Message" << std::endl; + + chat_access_manager.set_auth_token(get_message_pin_token(token_access_manager, message_to_test.message_data().channel_id)); + message_to_test.pin(); + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + //UNPIN MESSAGE + std::cout << "Unpin Message" << std::endl; + + chat_access_manager.set_auth_token(get_message_unpin_token(token_access_manager, message_to_test.message_data().channel_id)); + message_to_test.unpin(); + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + //TOGGLE REACTION + std::cout << "Toggle reaction" << std::endl; + + chat_access_manager.set_auth_token(get_message_toggle_reaction_token(token_access_manager, message_to_test.message_data().channel_id)); + message_to_test = message_to_test.toggle_reaction("happy"); + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + message_to_test = message_to_test.toggle_reaction("happy"); + + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + + //REPORT MESSAGE + std::cout << "Report message" << std::endl; + + chat_access_manager.set_auth_token(get_channel_write_token(token_access_manager, "PUBNUB_INTERNAL_MODERATION_" + message_to_test.message_data().channel_id)); + message_to_test.report("for cpp test"); + + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + + //MESSAGE STREAM UPDATES + std::cout << "Message: Stream Updates" << std::endl; + + chat_access_manager.set_auth_token(get_channel_connect_token(token_access_manager, message_to_test.message_data().channel_id)); + auto message_stream_lambda = [](Pubnub::Message message){}; + auto message_updates_stop_streaming = message_to_test.stream_updates(message_stream_lambda); + + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + + //MESSAGE STREAM UPDATES ON + std::cout << "Message: Stream Updates On" << std::endl; + + auto message_stream_on_lambda = [](Pubnub::Vector messages){}; + auto message_updates_on_stop_streaming = message_to_test.stream_updates_on(Pubnub::Vector{message_to_test}, message_stream_on_lambda); + + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + message_updates_stop_streaming.close(); + message_updates_on_stop_streaming.close(); + +*/ + + //MESSAGE DRAFT + std::cout << "Create message draft" << std::endl; + + chat_access_manager.set_auth_token(get_empty_token(token_access_manager)); + Pubnub::MessageDraftConfig draft_config; + draft_config.is_typing_indicator_triggered = true; + auto message_draft = public_channel.create_message_draft(draft_config); + + std::cout << "Create message draft listeners" << std::endl; + + auto add_change_lambda = [](Pubnub::Vector elements) + { + std::cout << "Draft Change, no suggestions " << std::endl; + for(auto element : elements) + { + std::cout << "Element: " << element.text << std::endl; + } + + }; + + auto add_change_suggestions_lambda = [&message_draft](Pubnub::Vector elements ,Pubnub::Vector suggested_mentions) + { + std::cout << "Draft Change, with suggestions " << std::endl; + for(auto element : elements) + { + std::cout << "Element: " << element.text << std::endl; + } + + if(suggested_mentions.size() > 0) + { + message_draft.insert_suggested_mention(suggested_mentions[0], "inserted mention"); + } + + }; + message_draft.add_change_listener(add_change_lambda); + message_draft.add_change_listener(add_change_suggestions_lambda); + + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + //MESSAGE DRAFT INSERT TEXT + std::cout << "Message draft insert text" << std::endl; + + message_draft.insert_text(0, "cpp_test draft text"); + message_draft.insert_text(5, "@cpp_test"); + message_draft.insert_text(15, "#cpp_test"); + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + //MESSAGE DRAFT REMOVE TEXT + std::cout << "Message draft remove text" << std::endl; + + message_draft.remove_text(2, 2); + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + //MESSAGE DRAFT ADD MENTION + std::cout << "Message draft add mention" << std::endl; + + Pubnub::MentionTarget mention_target; + mention_target.channel(group_channel_id); + message_draft.add_mention(9, 10, mention_target); + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + //MESSAGE DRAFT UPDATE + std::cout << "Message draft update" << std::endl; + + message_draft.update("cpp_test draft updated"); + + //MESSAGE DRAFT INSERT SUGGESTED MENTION + std::cout << "Message draft insert suggested mention" << std::endl; + + Pubnub::SuggestedMention suggested_mention; + suggested_mention.target = mention_target; + suggested_mention.offset = 0; + suggested_mention.replace_from = "cpp_test"; + suggested_mention.replace_to = "inserted_mention"; + + message_draft.insert_suggested_mention(suggested_mention, "inserted_mention"); + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + //MESSAGE DRAFT REMOVE MENTION + std::cout << "Message draft remove mention" << std::endl; + message_draft.remove_mention(9); + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + //MESSAGE DRAFT SEND + std::cout << "Message draft send" << std::endl; + + chat_access_manager.set_auth_token(get_send_text_token(token_access_manager, public_channel_id, user_id)); + message_draft.send(); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + //DELETE USER + std::cout << "Delete User" << std::endl; + + chat_access_manager.set_auth_token(get_delete_user_token(token_access_manager, create_user_id)); + chat.delete_user(create_user_id); + + chat_access_manager.set_auth_token(get_delete_user_token(token_access_manager, another_user_id)); + chat.delete_user(another_user_id); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + //DELETE CHANNEL + std::cout << "Delete Channel" << std::endl; + + chat_access_manager.set_auth_token(get_delete_channel_token(token_access_manager, direct_channel_id)); + chat.delete_channel(direct_channel_id); + + + + std::this_thread::sleep_for(std::chrono::milliseconds(500));; + + + + + std::cout << "End of Tests" << std::endl; + std::this_thread::sleep_for(std::chrono::seconds(5)); + std::cout << "End of main" << std::endl; + + return 0; } + + +Pubnub::String get_init_chat_token(Pubnub::AccessManager& token_access_manager, Pubnub::String user_id) +{ + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::UserPermissions user_permissions; + user_permissions.get = true; + user_permissions.update = true; + permission_object.users.push_back(user_id); + permission_object.user_permissions.push_back(user_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_empty_token(Pubnub::AccessManager& token_access_manager) +{ + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::UserPermissions user_permissions; + user_permissions.update = true; + permission_object.users.push_back("aaaaaaaaaaaaaa"); + permission_object.user_permissions.push_back(user_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_create_pub_conversation_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id) +{ + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.update = true; + permission_object.channels.push_back(channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_create_user_token(Pubnub::AccessManager& token_access_manager, Pubnub::String user_id) +{ + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::UserPermissions user_permissions; + user_permissions.get = true; + user_permissions.update = true; + permission_object.users.push_back(user_id); + permission_object.user_permissions.push_back(user_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_get_user_token(Pubnub::AccessManager& token_access_manager, Pubnub::String user_id) +{ + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::UserPermissions user_permissions; + user_permissions.get = true; + permission_object.users.push_back(user_id); + permission_object.user_permissions.push_back(user_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_get_users_token(Pubnub::AccessManager& token_access_manager, std::vector user_ids) +{ + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::UserPermissions user_permissions; + user_permissions.get = true; + for(auto user_id : user_ids) {permission_object.users.push_back(user_id);} + permission_object.user_permissions.push_back(user_permissions); + + return token_access_manager.grant_token(permission_object); +} + + +Pubnub::String get_create_dir_conversation_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, Pubnub::String current_user_id, Pubnub::String invitee_id) +{ + //ChannelID: UPDATE, JOIN, WRITE, GET + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.update = true; + channel_permissions.join = true; + channel_permissions.write = true; + channel_permissions.get = true; + permission_object.channels.push_back(channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + //Current User ID: UPDATE, GET + Pubnub::UserPermissions invitee_permissions; + invitee_permissions.update = true; + invitee_permissions.get = true; + permission_object.users.push_back(current_user_id); + + //Invitee ID: UPDATE, GET + permission_object.users.push_back(invitee_id); + permission_object.user_permissions.push_back(invitee_permissions); + + //Channel(Invitee_IDs): WRITE + Pubnub::ChannelPermissions channel_invitee_permissions; + channel_invitee_permissions.write = true; + permission_object.channels.push_back(invitee_id); + permission_object.channel_permissions.push_back(channel_invitee_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_create_group_conversation_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, Pubnub::String current_user_id, std::vector invitee_ids) +{ + //ChannelID: UPDATE, JOIN, MANAGE, WRITE + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.update = true; + channel_permissions.manage = true; + channel_permissions.join = true; + channel_permissions.write = true; + permission_object.channels.push_back(channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + //Current User ID: UPDATE, GET + Pubnub::UserPermissions invitee_permissions; + invitee_permissions.update = true; + invitee_permissions.get = true; + permission_object.users.push_back(current_user_id); + + //Invitees IDs: UPDATE, GET + for(auto invitee_id : invitee_ids) {permission_object.users.push_back(invitee_id);} + + permission_object.user_permissions.push_back(invitee_permissions); + + //Channel(Invitees_IDs): WRITE + Pubnub::ChannelPermissions channel_invitee_permissions; + channel_invitee_permissions.write = true; + for(auto invitee_id : invitee_ids) { + permission_object.channels.push_back(invitee_id); + permission_object.channel_permissions.push_back(channel_invitee_permissions); + } + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_get_channel_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id) +{ + //Channel ID: GET + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.get = true; + permission_object.channels.push_back(channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_read_channel_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id) +{ + //Channel ID: READ + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.read = true; + permission_object.channels.push_back(channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_get_channels_token(Pubnub::AccessManager& token_access_manager, std::vector channel_ids) +{ + //Channel IDs: GET + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.get = true; + for(auto channel_id : channel_ids) {permission_object.channels.push_back(channel_id);} + permission_object.channel_permissions.push_back(channel_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_update_channel_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id) +{ + //Channel ID: UPDATE + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.update = true; + permission_object.channels.push_back(channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_delete_channel_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id) +{ + //Channel ID: DELETE + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.del = true; + permission_object.channels.push_back(channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_update_user_token(Pubnub::AccessManager& token_access_manager, Pubnub::String user_id) +{ + //User ID: UPDATE + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::UserPermissions user_permissions; + user_permissions.update = true; + permission_object.users.push_back(user_id); + permission_object.user_permissions.push_back(user_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_delete_user_token(Pubnub::AccessManager& token_access_manager, Pubnub::String user_id) +{ + //User ID: DELETE + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::UserPermissions user_permissions; + user_permissions.del = true; + permission_object.users.push_back(user_id); + permission_object.user_permissions.push_back(user_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_join_channel_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, Pubnub::String user_id) +{ + //Channel ID: READ, JOIN, WRITE + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.read = true; + channel_permissions.join = true; + channel_permissions.write = true; + permission_object.channels.push_back(channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + //Channel ID + -pnpres: READ + Pubnub::ChannelPermissions pres_channel_permissions; + pres_channel_permissions.read = true; + permission_object.channels.push_back(channel_id + Pubnub::String("-pnpres")); + permission_object.channel_permissions.push_back(pres_channel_permissions); + + //User ID: UPDATE, GET + Pubnub::UserPermissions user_permissions; + user_permissions.update = true; + user_permissions.get = true; + permission_object.users.push_back(user_id); + permission_object.user_permissions.push_back(user_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_leave_channel_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, Pubnub::String user_id) +{ + //Channel ID: JOIN, READ + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.join = true; + channel_permissions.read = true; + permission_object.channels.push_back(channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + //Channel ID + -pnpres: READ + Pubnub::ChannelPermissions pres_channel_permissions; + pres_channel_permissions.read = true; + permission_object.channels.push_back(channel_id + Pubnub::String("-pnpres")); + permission_object.channel_permissions.push_back(pres_channel_permissions); + + //User ID: UPDATE + Pubnub::UserPermissions user_permissions; + user_permissions.update = true; + permission_object.users.push_back(user_id); + permission_object.user_permissions.push_back(user_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_channel_read_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id) +{ + //Channel ID: READ + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.read = true; + permission_object.channels.push_back(channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_channel_write_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id) +{ + //Channel ID: WRITE + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.write = true; + permission_object.channels.push_back(channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_channel_connect_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id) +{ + //Channel ID: READ + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.read = true; + permission_object.channels.push_back(channel_id); + //Channel ID + -pnpres: READ + permission_object.channels.push_back(channel_id + Pubnub::String("-pnpres")); + permission_object.channel_permissions.push_back(channel_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_send_text_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, Pubnub::String mentioned_user_id) +{ + //Channel ID: WRITE + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.write = true; + permission_object.channels.push_back(channel_id); + //Channel mentioned_user_id: WRITE + permission_object.channels.push_back(mentioned_user_id); + permission_object.channel_permissions.push_back(channel_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_set_restrictions_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, Pubnub::String user_id) +{ + //Channel PUBNUB_INTERNAL_MODERATION_{CHANNEL_ID}: MANAGE, UPDATE + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.manage = true; + channel_permissions.update = true; + permission_object.channels.push_back(Pubnub::String("PUBNUB_INTERNAL_MODERATION_") + channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + //Channel user_id: WRITE + Pubnub::ChannelPermissions user_channel_permissions; + user_channel_permissions.write = true; + permission_object.channels.push_back(Pubnub::String("PUBNUB_INTERNAL_MODERATION.") + user_id); + permission_object.channel_permissions.push_back(user_channel_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_invite_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, Pubnub::String invitee_id) +{ + //ChannelID: GET, JOIN, WRITE + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.get = true; + channel_permissions.join = true; + channel_permissions.write = true; + permission_object.channels.push_back(channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + //User invitee_id: UPDATE + Pubnub::UserPermissions invitee_permissions; + invitee_permissions.update = true; + invitee_permissions.get = true; + permission_object.users.push_back(invitee_id); + + permission_object.user_permissions.push_back(invitee_permissions); + + //Channel(Invitee_IDs): WRITE + Pubnub::ChannelPermissions channel_invitee_permissions; + channel_invitee_permissions.write = true; + permission_object.channels.push_back(invitee_id); + permission_object.channel_permissions.push_back(channel_invitee_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_invite_multiple_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, std::vector invitee_ids) +{ + //ChannelID: JOIN, WRITE, MANAGE + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.manage = true; + channel_permissions.join = true; + channel_permissions.write = true; + permission_object.channels.push_back(channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + //Invitees IDs: UPDATE, GET + Pubnub::UserPermissions invitee_permissions; + invitee_permissions.update = true; + //invitee_permissions.get = true; + + for(auto invitee_id : invitee_ids) {permission_object.users.push_back(invitee_id);} + + permission_object.user_permissions.push_back(invitee_permissions); + + //Channel(Invitees_IDs): WRITE + Pubnub::ChannelPermissions channel_invitee_permissions; + channel_invitee_permissions.write = true; + for(auto invitee_id : invitee_ids) { + permission_object.channels.push_back(invitee_id); + permission_object.channel_permissions.push_back(channel_invitee_permissions); + } + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_unread_messages_counts_token(Pubnub::AccessManager& token_access_manager, Pubnub::String current_user_id, std::vector channels) +{ + //Channels: READ + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.read = true; + for(auto channel : channels) {permission_object.channels.push_back(channel);} + permission_object.channel_permissions.push_back(channel_permissions); + + //Current user: GET + Pubnub::UserPermissions user_permissions; + user_permissions.get = true; + permission_object.users.push_back(current_user_id); + permission_object.user_permissions.push_back(user_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_mark_all_messages_as_read_token(Pubnub::AccessManager& token_access_manager, Pubnub::String current_user_id, std::vector channels) +{ + //Channels: JOIN, WRITE + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.join = true; + channel_permissions.write = true; + for(auto channel : channels) {permission_object.channels.push_back(channel);} + permission_object.channel_permissions.push_back(channel_permissions); + + //Current user: GET, UPDATE + Pubnub::UserPermissions user_permissions; + user_permissions.get = true; + user_permissions.update = true; + permission_object.users.push_back(current_user_id); + permission_object.user_permissions.push_back(user_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_thread_send_text_token(Pubnub::AccessManager& token_access_manager, Pubnub::String thread_channel_id, Pubnub::String parent_channel_id, Pubnub::String mentioned_user_id) +{ + //Parent Channel ID: WRITE + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.write = true; + permission_object.channels.push_back(parent_channel_id); + + //Channel mentioned_user_id: WRITE + permission_object.channels.push_back(mentioned_user_id); + permission_object.channel_permissions.push_back(channel_permissions); + permission_object.channel_permissions.push_back(channel_permissions); + + //Thread Channel ID: WRITE, UPDATE + Pubnub::ChannelPermissions thread_channel_permissions; + thread_channel_permissions.write = true; + thread_channel_permissions.update = true; + permission_object.channel_permissions.push_back(thread_channel_permissions); + permission_object.channels.push_back(thread_channel_id); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_remove_thread_token(Pubnub::AccessManager& token_access_manager, Pubnub::String thread_channel_id, Pubnub::String parent_channel_id) +{ + //Parent Channel ID: DELETE + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.del = true; + permission_object.channels.push_back(parent_channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + //Thread Channel ID: GET, DELETE + Pubnub::ChannelPermissions thread_channel_permissions; + thread_channel_permissions.get = true; + thread_channel_permissions.del = true; + permission_object.channel_permissions.push_back(thread_channel_permissions); + permission_object.channels.push_back(thread_channel_id); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_channel_stream_receipts_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id) +{ + //Channel ID: READ, GET + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.read = true; + channel_permissions.get = true; + permission_object.channels.push_back(channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + //Channel ID + -pnpres: READ + Pubnub::ChannelPermissions pres_channel_permissions; + pres_channel_permissions.read = true; + permission_object.channels.push_back(channel_id + Pubnub::String("-pnpres")); + permission_object.channel_permissions.push_back(pres_channel_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_membership_update_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, Pubnub::String user_id) +{ + //ChannelID: JOIN + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.join = true; + permission_object.channels.push_back(channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + //User user_id: UPDATE + Pubnub::UserPermissions user_permissions; + user_permissions.update = true; + permission_object.users.push_back(user_id); + permission_object.user_permissions.push_back(user_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_membership_set_last_read_message_token(Pubnub::AccessManager& token_access_manager, Pubnub::String channel_id, Pubnub::String user_id) +{ + //ChannelID: JOIN, WRITE + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.write = true; + channel_permissions.join = true; + permission_object.channels.push_back(channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + //User user_id: UPDATE + Pubnub::UserPermissions user_permissions; + user_permissions.update = true; + permission_object.users.push_back(user_id); + permission_object.user_permissions.push_back(user_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_message_pin_token(Pubnub::AccessManager& token_access_manager, Pubnub::String message_channel_id) +{ + //ChannelID: GET, UPDATE + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.get = true; + channel_permissions.update = true; + permission_object.channels.push_back(message_channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_message_unpin_token(Pubnub::AccessManager& token_access_manager, Pubnub::String message_channel_id) +{ + //ChannelID: GET, UPDATE, READ + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.get = true; + channel_permissions.update = true; + channel_permissions.read = true; + permission_object.channels.push_back(message_channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + return token_access_manager.grant_token(permission_object); +} + +Pubnub::String get_message_toggle_reaction_token(Pubnub::AccessManager& token_access_manager, Pubnub::String message_channel_id) +{ + //ChannelID: DELETE, WRITE + Pubnub::GrantTokenPermissionObject permission_object; + permission_object.authorized_user = TOKEN_AUTH_USER_ID; + permission_object.ttl_minutes = TOKEN_TTL; + Pubnub::ChannelPermissions channel_permissions; + channel_permissions.del = true; + channel_permissions.write = true; + permission_object.channels.push_back(message_channel_id); + permission_object.channel_permissions.push_back(channel_permissions); + + return token_access_manager.grant_token(permission_object); +} \ No newline at end of file diff --git a/include/pubnub_chat/access_manager.hpp b/include/pubnub_chat/access_manager.hpp index 8875646..f9d5e03 100644 --- a/include/pubnub_chat/access_manager.hpp +++ b/include/pubnub_chat/access_manager.hpp @@ -3,12 +3,85 @@ #include "string.hpp" #include +#include "vector.hpp" class AccessManagerService; namespace Pubnub { class Chat; + +struct ChannelPermissions +{ + //Read permission. Applies to Subscribe, History, and Presence. + bool read = false; + //Write permission. Applies to Publish. + bool write = false; + //Delete permission. Applies to History and App Context. (delete is keyword in C++ so we use del) + bool del = false; + //Get permission. Applies to App Context. + bool get = false; + //Update permission. Applies to App Context. + bool update = false; + //Manage permission. Applies to Channel Groups and App Context. + bool manage = false; + //Join permission. Applies to App Context. + bool join = false; +}; + + +struct ChannelGroupPermissions +{ + //Read permission. Applies to presence and history access for the group. + bool read = false; + //Manage permission. Applies to modifying members of the group. + bool manage = false; +}; + + +struct UserPermissions +{ + //Delete permission. Allows deletion of user metadata. + bool del = false; + //Get permission. Allows retrieval of user metadata. + bool get = false; + //Update permission. Allows updating of user metadata. + bool update = false; +}; + + struct GrantTokenPermissionObject + { + //Time-To-Live (TTL) in minutes for the granted token. + int ttl_minutes = 0; + //The User that is authorized by this grant. + Pubnub::String authorized_user = ""; + //List of channel names included in this grant. + Pubnub::Vector channels; + //Permissions applied to the listed channels. Has to be either 1 or the same amount as Channels. + Pubnub::Vector channel_permissions; + //List of channel group names included in this grant. + Pubnub::Vector channel_groups; + //Permissions applied to the listed channel groups. Has to be either 1 or the same amount as ChannelGroups. + Pubnub::Vector channel_group_permissions; + //List of Users included in this grant. + Pubnub::Vector users; + //Permissions applied to the listed Users. Has to be either 1 or the same amount as Users. + Pubnub::Vector user_permissions; + //List of channel name patterns included in this grant. + Pubnub::Vector channel_patterns; + //Permissions applied to the listed channel name patterns. Has to be either 1 or the same amount as ChannelPatterns. + Pubnub::Vector channel_pattern_permissions; + //List of channel group name patterns included in this grant. + Pubnub::Vector channel_group_patterns; + //Permissions applied to the listed channel group name patterns. Has to be either 1 or the same amount as ChannelGroupPatterns. + Pubnub::Vector channel_group_pattern_permissions; + //List of User name patterns included in this grant. + Pubnub::Vector user_patterns; + //Permissions applied to the listed User name patterns. Has to be either 1 or the same amount as UserPatterns. + Pubnub::Vector user_pattern_permissions; + }; + + class AccessManager { public: enum class ResourceType { UUIDS, CHANNELS }; @@ -23,9 +96,12 @@ namespace Pubnub { PN_CHAT_EXPORT bool can_i(AccessManager::Permission permission, AccessManager::ResourceType resource_type, const Pubnub::String& resource_name) const; + PN_CHAT_EXPORT void set_secret_key(const Pubnub::String secret_key) const; PN_CHAT_EXPORT Pubnub::String parse_token(const Pubnub::String token) const; PN_CHAT_EXPORT void set_auth_token(const Pubnub::String token) const; PN_CHAT_EXPORT int set_pubnub_origin(const Pubnub::String origin) const; + PN_CHAT_EXPORT Pubnub::String grant_token(Pubnub::String permission_object) const; + PN_CHAT_EXPORT Pubnub::String grant_token(Pubnub::GrantTokenPermissionObject permission_object); private: AccessManager(std::shared_ptr access_manager_service); diff --git a/include/pubnub_chat/chat_helpers.hpp b/include/pubnub_chat/chat_helpers.hpp index c3bfda5..ec7876d 100644 --- a/include/pubnub_chat/chat_helpers.hpp +++ b/include/pubnub_chat/chat_helpers.hpp @@ -70,7 +70,7 @@ namespace Pubnub Pubnub::String chat_message_to_publish_string(Pubnub::String message, Pubnub::pubnub_chat_message_type message_type); - Pubnub::String get_now_timetoken(); + PN_CHAT_EXPORT Pubnub::String get_now_timetoken(); } diff --git a/src/application/access_manager_service.cpp b/src/application/access_manager_service.cpp index 56e5f86..2548f2d 100644 --- a/src/application/access_manager_service.cpp +++ b/src/application/access_manager_service.cpp @@ -2,6 +2,9 @@ #include "access_manager.hpp" #include "domain/access_manager_logic.hpp" #include "domain/json.hpp" +extern "C" { + #include +} AccessManagerService::AccessManagerService(ThreadSafePtr pubnub): pubnub(pubnub) @@ -37,6 +40,12 @@ bool AccessManagerService::can_i(Pubnub::AccessManager::Permission permission, P return AccessManagerLogic::can_i(permission, resource_type, json_token, resource_name); } +void AccessManagerService::set_secret_key(const Pubnub::String key) const +{ + auto pubnub_handle = this->pubnub->lock(); + pubnub_handle->set_secret_key(key); +} + Pubnub::String AccessManagerService::parse_token(const Pubnub::String auth_key) const { auto pubnub_handle = this->pubnub->lock(); @@ -54,3 +63,213 @@ int AccessManagerService::set_pubnub_origin(const Pubnub::String origin) const auto pubnub_handle = this->pubnub->lock(); return pubnub_handle->set_pubnub_origin(origin); } + +Pubnub::String AccessManagerService::grant_token(Pubnub::String permission_object) const +{ + auto pubnub_handle = this->pubnub->lock(); + return pubnub_handle->grant_token(permission_object); +} +Pubnub::String AccessManagerService::grant_token_permission_struct_to_string(GrantTokenPermissionObjectInternal permission_object_struct) const +{ + //Make sure token data is provided in correct form. There must be the same amount of object and permissions or just one permission, + //then one permission is used for every object + + if(permission_object_struct.channels.size() != permission_object_struct.channel_permissions.size() && permission_object_struct.channel_permissions.size() != 1) + { + throw std::runtime_error("Grant Token Structure To JsonString - Provide the same amount of channel_permissions and Channels (or only 1 ChannelPermission)."); + return ""; + } + + if(permission_object_struct.channel_groups.size() != permission_object_struct.channel_group_permissions.size() && permission_object_struct.channel_group_permissions.size() != 1) + { + throw std::runtime_error("Grant Token Structure To JsonString - Provide the same amount of channel_group_permissions and channel_groups (or only 1 channel_group_permissions)."); + return ""; + } + + if(permission_object_struct.users.size() != permission_object_struct.user_permissions.size() && permission_object_struct.user_permissions.size() != 1) + { + throw std::runtime_error("Grant Token Structure To JsonString - Provide the same amount of user_permissions and users (or only 1 user_permissions)."); + return ""; + } + + if(permission_object_struct.channel_patterns.size() != permission_object_struct.channel_pattern_permissions.size() && permission_object_struct.channel_pattern_permissions.size() != 1) + { + throw std::runtime_error("Grant Token Structure To JsonString - Provide the same amount of channel_pattern_permissions and ChannelsPatterns (or only 1 channel_pattern_permissions)."); + return ""; + } + + if(permission_object_struct.channel_group_patterns.size() != permission_object_struct.channel_group_pattern_permissions.size() && permission_object_struct.channel_group_pattern_permissions.size() != 1) + { + throw std::runtime_error("Grant Token Structure To JsonString - Provide the same amount of channel_group_pattern_permissions and channel_groupsPatterns (or only 1 channel_group_pattern_permissions)."); + return ""; + } + + if(permission_object_struct.user_patterns.size() != permission_object_struct.user_pattern_permissions.size() && permission_object_struct.user_pattern_permissions.size() != 1) + { + throw std::runtime_error("Grant Token Structure To JsonString - Provide the same amount of user_pattern_permissions and usersPatterns (or only 1 user_pattern_permissions)."); + return ""; + } + + Json permission_object_json; + + //Create Json objects with channels, groups, users permissions and their patterns + Json channels_json_object = add_channel_permissions_to_json(permission_object_struct.channels, permission_object_struct.channel_permissions); + Json channel_groups_json_object = add_channel_group_permissions_to_json(permission_object_struct.channel_groups, permission_object_struct.channel_group_permissions); + Json users_json_object = add_user_permissions_to_json(permission_object_struct.users, permission_object_struct.user_permissions); + Json channel_patterns_json_object = add_channel_permissions_to_json(permission_object_struct.channel_patterns, permission_object_struct.channel_pattern_permissions); + Json channel_group_patterns_json_object = add_channel_group_permissions_to_json(permission_object_struct.channel_group_patterns, permission_object_struct.channel_group_pattern_permissions); + Json user_patterns_json_object= add_user_permissions_to_json(permission_object_struct.user_patterns, permission_object_struct.user_pattern_permissions); + + //Add resources fields + Json resources_json_object; + if(permission_object_struct.channels.size() > 0) + { + resources_json_object.insert_or_update("channels", channels_json_object); + } + if(permission_object_struct.channel_groups.size() > 0) + { + resources_json_object.insert_or_update("groups", channel_groups_json_object); + } + if(permission_object_struct.users.size() > 0) + { + resources_json_object.insert_or_update("uuids", users_json_object); + } + + //Add patterns fields + Json patterns_json_object; + if(permission_object_struct.channel_patterns.size() > 0) + { + patterns_json_object.insert_or_update("channels", channel_patterns_json_object); + } + if(permission_object_struct.channel_group_patterns.size() > 0) + { + patterns_json_object.insert_or_update("groups", channel_group_patterns_json_object); + } + if(permission_object_struct.user_patterns.size() > 0) + { + patterns_json_object.insert_or_update("uuids", user_patterns_json_object); + } + + Json permission_object_struct_json_object; + if(!resources_json_object.is_null()) + { + permission_object_struct_json_object.insert_or_update("resources", resources_json_object); + } + if(!patterns_json_object.is_null()) + { + permission_object_struct_json_object.insert_or_update("patterns", patterns_json_object); + } + + Json permissions_json_object; + permissions_json_object.insert_or_update("ttl", permission_object_struct.ttl_minutes); + permissions_json_object.insert_or_update("authorized_uuid", permission_object_struct.authorized_user); + permissions_json_object.insert_or_update("permissions", permission_object_struct_json_object); + + //Convert created Json object to string + return permissions_json_object.dump(); +} + + + +Json AccessManagerService::add_channel_permissions_to_json(std::vector channels, std::vector channel_permissions) const +{ + Json json_object; + bool use_one_permission = channel_permissions.size() == 1; + + for(int i = 0; i < channels.size(); i++) + { + if(channels[i].empty()) + { + continue; + } + + //For permissions use the first index if this is the only valid index or corresponding channel index + Pubnub::ChannelPermissions current_permissions; + use_one_permission ? current_permissions = channel_permissions[0] : current_permissions = channel_permissions[i]; + + //Create bit mask value from all permissions + struct pam_permission ChPerm; + ChPerm.read = current_permissions.read; + ChPerm.write = current_permissions.write; + ChPerm.del = current_permissions.del; + ChPerm.get = current_permissions.get; + ChPerm.update = current_permissions.update; + ChPerm.manage = current_permissions.manage; + ChPerm.join = current_permissions.join; + ChPerm.create = false; + int perm_bit_mask = pubnub_get_grant_bit_mask_value(ChPerm); + + json_object.insert_or_update(channels[i], perm_bit_mask); + } + + return json_object; +} + +Json AccessManagerService::add_channel_group_permissions_to_json(std::vector channel_groups, std::vector channel_group_permissions) const +{ + Json json_object; + bool use_one_permission = channel_group_permissions.size() == 1; + + for(int i = 0; i < channel_groups.size(); i++) + { + if(channel_groups[i].empty()) + { + continue; + } + + //For permissions use the first index if this is the only valid index or corresponding channel index + Pubnub::ChannelGroupPermissions current_permissions; + use_one_permission ? current_permissions = channel_group_permissions[0] : current_permissions = channel_group_permissions[i]; + + //Create bit mask value from all permissions + struct pam_permission ChPerm; + ChPerm.read = current_permissions.read; + ChPerm.manage = current_permissions.manage; + ChPerm.write = false; + ChPerm.del = false; + ChPerm.get = false; + ChPerm.update = false; + ChPerm.join = false; + ChPerm.create = false; + int perm_bit_mask = pubnub_get_grant_bit_mask_value(ChPerm); + + json_object.insert_or_update(channel_groups[i], perm_bit_mask); + } + + return json_object; +} + +Json AccessManagerService::add_user_permissions_to_json(std::vectorusers, std::vector user_permissions) const +{ + Json json_object; + bool use_one_permission = user_permissions.size() == 1; + + + for(int i = 0; i < users.size(); i++) + { + if(users[i].empty()) + { + continue; + } + + //For permissions use the first index if this is the only valid index or corresponding channel index + Pubnub::UserPermissions current_permissions; + use_one_permission ? current_permissions = user_permissions[0] : current_permissions = user_permissions[i]; + + //Create bit mask value from all permissions + struct pam_permission ChPerm; + ChPerm.del = current_permissions.del; + ChPerm.get = current_permissions.get; + ChPerm.update = current_permissions.update; + ChPerm.read = false; + ChPerm.write = false; + ChPerm.manage = false; + ChPerm.join = false; + ChPerm.create = false; + int perm_bit_mask = pubnub_get_grant_bit_mask_value(ChPerm); + + json_object.insert_or_update(users[i], perm_bit_mask); + } + + return json_object; +} \ No newline at end of file diff --git a/src/application/access_manager_service.hpp b/src/application/access_manager_service.hpp index 9ce92ea..3524ccd 100644 --- a/src/application/access_manager_service.hpp +++ b/src/application/access_manager_service.hpp @@ -6,6 +6,43 @@ #include "access_manager.hpp" #include "infra/pubnub.hpp" #include "infra/sync.hpp" +#include + +struct GrantTokenPermissionObjectInternal +{ + int ttl_minutes = 0; + Pubnub::String authorized_user = ""; + std::vector channels; + std::vector channel_permissions; + std::vector channel_groups; + std::vector channel_group_permissions; + std::vector users; + std::vector user_permissions; + std::vector channel_patterns; + std::vector channel_pattern_permissions; + std::vector channel_group_patterns; + std::vector channel_group_pattern_permissions; + std::vector user_patterns; + std::vector user_pattern_permissions; + + GrantTokenPermissionObjectInternal() = default; + + GrantTokenPermissionObjectInternal(Pubnub::GrantTokenPermissionObject permission_object): + ttl_minutes(permission_object.ttl_minutes), + authorized_user(permission_object.authorized_user), + channels(permission_object.channels.into_std_vector()), + channel_permissions(permission_object.channel_permissions.into_std_vector()), + channel_groups(permission_object.channel_groups.into_std_vector()), + channel_group_permissions(permission_object.channel_group_permissions.into_std_vector()), + users(permission_object.users.into_std_vector()), + user_permissions(permission_object.user_permissions.into_std_vector()), + channel_patterns(permission_object.channel_patterns.into_std_vector()), + channel_pattern_permissions(permission_object.channel_pattern_permissions.into_std_vector()), + channel_group_patterns(permission_object.channel_group_patterns.into_std_vector()), + channel_group_pattern_permissions(permission_object.channel_group_pattern_permissions.into_std_vector()), + user_patterns(permission_object.user_patterns.into_std_vector()), + user_pattern_permissions(permission_object.user_pattern_permissions.into_std_vector()){}; +}; class AccessManagerService { public: @@ -13,9 +50,16 @@ class AccessManagerService { bool can_i(Pubnub::AccessManager::Permission permission, Pubnub::AccessManager::ResourceType resource_type, const Pubnub::String& resource_name) const; + void set_secret_key(const Pubnub::String secret_key) const; Pubnub::String parse_token(const Pubnub::String auth_key) const; void set_auth_token(const Pubnub::String token) const; int set_pubnub_origin(const Pubnub::String origin) const; + Pubnub::String grant_token(Pubnub::String permission_object) const; + Pubnub::String grant_token_permission_struct_to_string(GrantTokenPermissionObjectInternal permission_object_struct) const; + + Json add_channel_permissions_to_json(std::vector channels, std::vector channel_permissions) const; + Json add_channel_group_permissions_to_json(std::vector channel_groups, std::vector channel_group_permissions) const; + Json add_user_permissions_to_json(std::vectorusers, std::vector user_permissions) const; private: ThreadSafePtr pubnub; diff --git a/src/application/channel_service.cpp b/src/application/channel_service.cpp index 1a2050a..08bc2ea 100644 --- a/src/application/channel_service.cpp +++ b/src/application/channel_service.cpp @@ -138,7 +138,7 @@ Channel ChannelService::get_channel(const String& channel_id) const { throw std::runtime_error("can't get channel, response is incorrect"); } - if(parsed_response["data"].is_null()) { + if(!parsed_response.contains("data") || parsed_response["data"].is_null()) { throw std::runtime_error("can't get channel, response doesn't have data field"); } diff --git a/src/application/user_service.cpp b/src/application/user_service.cpp index d95acc9..ac8072f 100644 --- a/src/application/user_service.cpp +++ b/src/application/user_service.cpp @@ -81,7 +81,7 @@ User UserService::get_user(const String& user_id) const throw std::runtime_error("can't get user, response is incorrect"); } - if (response_json["data"].is_null()) { + if (!response_json.contains("data") || response_json["data"].is_null()) { throw std::runtime_error("can't get user, response doesn't have data field"); } diff --git a/src/domain/json.cpp b/src/domain/json.cpp index f038aa2..1fdd49c 100644 --- a/src/domain/json.cpp +++ b/src/domain/json.cpp @@ -100,6 +100,10 @@ void Json::insert_or_update(Pubnub::String key, Pubnub::String value) { this->json[key] = value.c_str(); } +void Json::insert_or_update(Pubnub::String key, int value) { + this->json[key] = value; +} + Json::Iterator Json::begin() { return Json::Iterator(this->json.begin()); } diff --git a/src/domain/json.hpp b/src/domain/json.hpp index 45e37d2..efa2989 100644 --- a/src/domain/json.hpp +++ b/src/domain/json.hpp @@ -44,6 +44,7 @@ class Json { void insert_or_update(Pubnub::String key, Json value); void insert_or_update(Pubnub::String key, Pubnub::String value); + void insert_or_update(Pubnub::String key, int value); int as_int() const; diff --git a/src/infra/pubnub.cpp b/src/infra/pubnub.cpp index ed4916b..150f25d 100644 --- a/src/infra/pubnub.cpp +++ b/src/infra/pubnub.cpp @@ -27,6 +27,7 @@ extern "C" { #include #include #include +#include #include #include #include @@ -836,4 +837,25 @@ int PubNub::set_pubnub_origin(const Pubnub::String origin) custom_origin = origin; return pubnub_origin_set(this->main_context.get(), custom_origin.c_str()); return pubnub_origin_set(this->long_poll_context.get(), custom_origin.c_str()); +} + +Pubnub::String PubNub::grant_token(const Pubnub::String permission_object) +{ + auto result = pubnub_grant_token(this->main_context.get(), permission_object.c_str()); + + this->await_and_handle_error(result); + + pubnub_chamebl_t grant_token_resp = pubnub_get_grant_token(this->main_context.get()); + if(!grant_token_resp.ptr) + { + return ""; + } + + return grant_token_resp.ptr; +} + +void PubNub::set_secret_key(const Pubnub::String key) +{ + this->secret_key = key; + pubnub_set_secret_key(this->main_context.get(), secret_key.c_str()); } \ No newline at end of file diff --git a/src/infra/pubnub.hpp b/src/infra/pubnub.hpp index 9f8bf75..e286cf4 100644 --- a/src/infra/pubnub.hpp +++ b/src/infra/pubnub.hpp @@ -75,6 +75,8 @@ class PubNub { Pubnub::String get_current_auth_token(); void set_auth_token(const Pubnub::String token); int set_pubnub_origin(const Pubnub::String origin); + Pubnub::String grant_token(const Pubnub::String permission_object); + void set_secret_key(const Pubnub::String secret_key); private: void await_and_handle_error(pubnub_res result); @@ -87,6 +89,7 @@ class PubNub { Pubnub::String publish_key; Pubnub::String subscribe_key; + Pubnub::String secret_key; Pubnub::String user_id; Pubnub::String auth_key; Pubnub::String custom_origin; diff --git a/src/presentation/access_manager.cpp b/src/presentation/access_manager.cpp index f8eb0a2..bf08074 100644 --- a/src/presentation/access_manager.cpp +++ b/src/presentation/access_manager.cpp @@ -26,6 +26,11 @@ bool Pubnub::AccessManager::can_i(Pubnub::AccessManager::Permission permission, return this->access_manager_service->can_i(permission, resource_type, resource_name); } +void Pubnub::AccessManager::set_secret_key(const Pubnub::String key) const +{ + return this->access_manager_service->set_secret_key(key); +} + Pubnub::String Pubnub::AccessManager::parse_token(const Pubnub::String token) const { return this->access_manager_service->parse_token(token); @@ -40,3 +45,13 @@ int Pubnub::AccessManager::set_pubnub_origin(const Pubnub::String origin) const { return this->access_manager_service->set_pubnub_origin(origin); } + +Pubnub::String Pubnub::AccessManager::grant_token(const Pubnub::String permission_object) const +{ + return this->access_manager_service->grant_token(permission_object); +} + +Pubnub::String Pubnub::AccessManager::grant_token(Pubnub::GrantTokenPermissionObject permission_object) +{ + return this->access_manager_service->grant_token(this->access_manager_service->grant_token_permission_struct_to_string(permission_object)); +} \ No newline at end of file