From 13bd51b97df88f749a024eda0bf434d49a1c4294 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> Date: Tue, 31 Jan 2023 12:24:18 +0000 Subject: [PATCH] core: prevent making all users inactive when duplicate user is created (#1862) * core: prevent making all users inactive when duplicate user is created * skip async group test --- src/Simplex/Chat.hs | 7 +++++-- src/Simplex/Chat/Controller.hs | 1 + src/Simplex/Chat/View.hs | 1 + tests/ChatTests.hs | 2 +- tests/MobileTests.hs | 6 +++--- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/Simplex/Chat.hs b/src/Simplex/Chat.hs index d121bd8da..d2ef0930a 100644 --- a/src/Simplex/Chat.hs +++ b/src/Simplex/Chat.hs @@ -273,13 +273,16 @@ toView event = do processChatCommand :: forall m. ChatMonad m => ChatCommand -> m ChatResponse processChatCommand = \case ShowActiveUser -> withUser' $ pure . CRActiveUser - CreateActiveUser p sameServers -> do + CreateActiveUser p@Profile {displayName} sameServers -> do u <- asks currentUser (smp, smpServers) <- chooseServers auId <- withStore' getUsers >>= \case [] -> pure 1 - _ -> withAgent (`createUser` smp) + users -> do + when (any (\User {localDisplayName = n} -> n == displayName) users) $ + throwChatError $ CEUserExists displayName + withAgent (`createUser` smp) user <- withStore $ \db -> createUserRecord db (AgentUserId auId) p True unless (null smpServers) $ withStore $ \db -> overwriteSMPServers db user smpServers diff --git a/src/Simplex/Chat/Controller.hs b/src/Simplex/Chat/Controller.hs index c48de9332..b1e7a139f 100644 --- a/src/Simplex/Chat/Controller.hs +++ b/src/Simplex/Chat/Controller.hs @@ -645,6 +645,7 @@ data ChatErrorType = CENoActiveUser | CENoConnectionUser {agentConnId :: AgentConnId} | CEActiveUserExists -- TODO delete + | CEUserExists {contactName :: ContactName} | CEDifferentActiveUser {commandUserId :: UserId, activeUserId :: UserId} | CECantDeleteActiveUser {userId :: UserId} | CECantDeleteLastUser {userId :: UserId} diff --git a/src/Simplex/Chat/View.hs b/src/Simplex/Chat/View.hs index 802a4cebb..9088ccd4b 100644 --- a/src/Simplex/Chat/View.hs +++ b/src/Simplex/Chat/View.hs @@ -1185,6 +1185,7 @@ viewChatError logLevel = \case CENoActiveUser -> ["error: active user is required"] CENoConnectionUser agentConnId -> ["error: message user not found, conn id: " <> sShow agentConnId | logLevel <= CLLError] CEActiveUserExists -> ["error: active user already exists"] + CEUserExists name -> ["user with the name " <> ttyContact name <> " already exists"] CEDifferentActiveUser commandUserId activeUserId -> ["error: different active user, command user id: " <> sShow commandUserId <> ", active user id: " <> sShow activeUserId] CECantDeleteActiveUser _ -> ["cannot delete active user"] CECantDeleteLastUser _ -> ["cannot delete last user"] diff --git a/tests/ChatTests.hs b/tests/ChatTests.hs index d82d00560..b577f5826 100644 --- a/tests/ChatTests.hs +++ b/tests/ChatTests.hs @@ -166,7 +166,7 @@ chatTests = do xdescribe "send and receive file, fully asynchronous" $ do it "v2" testAsyncFileTransfer it "v1" testAsyncFileTransferV1 - it "send and receive file to group, fully asynchronous" testAsyncGroupFileTransfer + xit "send and receive file to group, fully asynchronous" testAsyncGroupFileTransfer describe "webrtc calls api" $ do it "negotiate call" testNegotiateCall describe "maintenance mode" $ do diff --git a/tests/MobileTests.hs b/tests/MobileTests.hs index fb61a9db9..b18cba744 100644 --- a/tests/MobileTests.hs +++ b/tests/MobileTests.hs @@ -25,9 +25,9 @@ noActiveUser = "{\"resp\":{\"type\":\"chatCmdError\",\"chatError\":{\"type\":\"e activeUserExists :: String #if defined(darwin_HOST_OS) && defined(swiftJSON) -activeUserExists = "{\"resp\":{\"chatCmdError\":{\"user_\":{\"userId\":1,\"agentUserId\":\"1\",\"userContactId\":1,\"localDisplayName\":\"alice\",\"profile\":{\"profileId\":1,\"displayName\":\"alice\",\"fullName\":\"Alice\",\"localAlias\":\"\"},\"fullPreferences\":{\"timedMessages\":{\"allow\":\"no\"},\"fullDelete\":{\"allow\":\"no\"},\"voice\":{\"allow\":\"yes\"}},\"activeUser\":true},\"chatError\":{\"errorStore\":{\"storeError\":{\"duplicateName\":{}}}}}}}" +activeUserExists = "{\"resp\":{\"chatCmdError\":{\"user_\":{\"userId\":1,\"agentUserId\":\"1\",\"userContactId\":1,\"localDisplayName\":\"alice\",\"profile\":{\"profileId\":1,\"displayName\":\"alice\",\"fullName\":\"Alice\",\"localAlias\":\"\"},\"fullPreferences\":{\"timedMessages\":{\"allow\":\"no\"},\"fullDelete\":{\"allow\":\"no\"},\"voice\":{\"allow\":\"yes\"}},\"activeUser\":true},\"chatError\":{\"error\":{\"errorType\":{\"userExists\":{\"contactName\":\"alice\"}}}}}}}" #else -activeUserExists = "{\"resp\":{\"type\":\"chatCmdError\",\"user_\":{\"userId\":1,\"agentUserId\":\"1\",\"userContactId\":1,\"localDisplayName\":\"alice\",\"profile\":{\"profileId\":1,\"displayName\":\"alice\",\"fullName\":\"Alice\",\"localAlias\":\"\"},\"fullPreferences\":{\"timedMessages\":{\"allow\":\"no\"},\"fullDelete\":{\"allow\":\"no\"},\"voice\":{\"allow\":\"yes\"}},\"activeUser\":true},\"chatError\":{\"type\":\"errorStore\",\"storeError\":{\"type\":\"duplicateName\"}}}}" +activeUserExists = "{\"resp\":{\"type\":\"chatCmdError\",\"user_\":{\"userId\":1,\"agentUserId\":\"1\",\"userContactId\":1,\"localDisplayName\":\"alice\",\"profile\":{\"profileId\":1,\"displayName\":\"alice\",\"fullName\":\"Alice\",\"localAlias\":\"\"},\"fullPreferences\":{\"timedMessages\":{\"allow\":\"no\"},\"fullDelete\":{\"allow\":\"no\"},\"voice\":{\"allow\":\"yes\"}},\"activeUser\":true},\"chatError\":{\"type\":\"error\",\"errorType\":{\"type\":\"userExists\",\"contactName\":\"alice\"}}}}" #endif activeUser :: String @@ -73,7 +73,7 @@ pendingSubSummary = "{\"resp\":{\"type\":\"pendingSubSummary\"," <> userJSON <> #endif userJSON :: String -userJSON = "\"user\":{\"userId\":1,\"agentUserId\":\"1\",\"userContactId\":1,\"localDisplayName\":\"alice\",\"profile\":{\"profileId\":1,\"displayName\":\"alice\",\"fullName\":\"Alice\",\"localAlias\":\"\"},\"fullPreferences\":{\"timedMessages\":{\"allow\":\"no\"},\"fullDelete\":{\"allow\":\"no\"},\"voice\":{\"allow\":\"yes\"}},\"activeUser\":false}" +userJSON = "\"user\":{\"userId\":1,\"agentUserId\":\"1\",\"userContactId\":1,\"localDisplayName\":\"alice\",\"profile\":{\"profileId\":1,\"displayName\":\"alice\",\"fullName\":\"Alice\",\"localAlias\":\"\"},\"fullPreferences\":{\"timedMessages\":{\"allow\":\"no\"},\"fullDelete\":{\"allow\":\"no\"},\"voice\":{\"allow\":\"yes\"}},\"activeUser\":true}" parsedMarkdown :: String #if defined(darwin_HOST_OS) && defined(swiftJSON)