fix/add tests, add version config to "small" agent

This commit is contained in:
Evgeny Poberezkin
2024-02-08 19:57:45 +00:00
parent 64e772bfb0
commit c029b715fb
9 changed files with 47 additions and 29 deletions
+1 -2
View File
@@ -48,5 +48,4 @@ As this new scheme breaks backward compatibility, as the new scheme requires add
2. Add support for handshake and version negotiation to XFTP - 5.5.4 or 5.6.
3. Upgrade clients to drop support of SMP earlier than v4 (batching) and also drop support of old double ratchet protocol and old handshake - 5.6.
4. Upgrade servers to offer SMP v7 with support for new authorization - by the time 5.6 is released.
5. Upgrade clients to use SMP v7 / new authorization - 5.6.2 or 5.7.
6. Upgrade clients to require support for new authorization scheme - 5.7
5. Upgrade clients to require server support for SMP v7 / new authorization scheme and start using it - 5.7 or 5.8. At this point the old version of the servers will not be supported, as maintaining this backward compatibility would substantially increase the complexity and logic of the client - at the point of generating the key we do not even know which server version will be used.
+2 -2
View File
@@ -84,7 +84,6 @@ data InitialAgentServers = InitialAgentServers
data AgentConfig = AgentConfig
{ tcpPort :: ServiceName,
cmdAuthAlg :: C.AuthAlg,
cmdAuthAlgV6 :: C.AuthAlg,
connIdBytes :: Int,
tbqSize :: Natural,
smpCfg :: ProtocolClientConfig,
@@ -149,8 +148,9 @@ defaultAgentConfig :: AgentConfig
defaultAgentConfig =
AgentConfig
{ tcpPort = "5224",
-- while the current client version supports X25519, it can only be enabled once support for SMP v6 is dropped,
-- and all servers are required to support v7 to be compatible.
cmdAuthAlg = C.AuthAlg C.SEd448,
cmdAuthAlgV6 = C.AuthAlg C.SEd448,
connIdBytes = 12,
tbqSize = 64,
smpCfg = defaultSMPClientConfig {defaultTransport = (show defaultSMPPort, transport @TLS)},
@@ -88,7 +88,8 @@ ntfServer cfg@NtfServerConfig {transports, transportConfig = tCfg} started = do
runClient _ h = do
kh <- asks serverIdentity
ks <- atomically . C.generateKeyPair =<< asks random
liftIO (runExceptT $ ntfServerHandshake h ks kh supportedNTFServerVRange) >>= \case
NtfServerConfig {ntfServerVRange} <- asks config
liftIO (runExceptT $ ntfServerHandshake h ks kh ntfServerVRange) >>= \case
Right th -> runNtfClientTransport th
Left _ -> pure ()
@@ -35,6 +35,7 @@ import Simplex.Messaging.TMap (TMap)
import qualified Simplex.Messaging.TMap as TM
import Simplex.Messaging.Transport (ATransport)
import Simplex.Messaging.Transport.Server (TransportServerConfig, loadFingerprint, loadTLSServerParams)
import Simplex.Messaging.Version (VersionRange)
import System.IO (IOMode (..))
import System.Mem.Weak (Weak)
import UnliftIO.STM
@@ -60,6 +61,7 @@ data NtfServerConfig = NtfServerConfig
logStatsStartTime :: Int64,
serverStatsLogFile :: FilePath,
serverStatsBackupFile :: Maybe FilePath,
ntfServerVRange :: VersionRange,
transportConfig :: TransportServerConfig
}
@@ -19,6 +19,7 @@ import qualified Simplex.Messaging.Crypto as C
import Simplex.Messaging.Notifications.Server (runNtfServer)
import Simplex.Messaging.Notifications.Server.Env (NtfServerConfig (..), defaultInactiveClientExpiration)
import Simplex.Messaging.Notifications.Server.Push.APNS (defaultAPNSPushClientConfig)
import Simplex.Messaging.Notifications.Transport (supportedNTFServerVRange)
import Simplex.Messaging.Protocol (ProtoServerWithAuth (..), pattern NtfServer)
import Simplex.Messaging.Server.CLI
import Simplex.Messaging.Server.Expiration
@@ -135,6 +136,7 @@ ntfServerCLI cfgPath logPath =
logStatsStartTime = 0, -- seconds from 00:00 UTC
serverStatsLogFile = combine logPath "ntf-server-stats.daily.log",
serverStatsBackupFile = logStats $> combine logPath "ntf-server-stats.log",
ntfServerVRange = supportedNTFServerVRange,
transportConfig =
defaultTransportServerConfig
{ logTLSErrors = fromMaybe False $ iniOnOff "TRANSPORT" "log_tls_errors" ini
+1 -1
View File
@@ -41,7 +41,7 @@ agentTests (ATransport t) = do
describe "Connection request" connectionRequestTests
describe "Double ratchet tests" doubleRatchetTests
describe "Functional API" $ functionalAPITests (ATransport t)
fdescribe "Notification tests" $ notificationTests (ATransport t)
describe "Notification tests" $ notificationTests (ATransport t)
describe "SQLite store" storeTests
describe "Migration tests" migrationTests
describe "SMP agent protocol syntax" $ syntaxTests t
+6 -1
View File
@@ -61,6 +61,7 @@ import Simplex.Messaging.Agent.Store.SQLite.Common (withTransaction')
import Simplex.Messaging.Client (NetworkConfig (..), ProtocolClientConfig (..), TransportSessionMode (TSMEntity, TSMUser), defaultSMPClientConfig)
import qualified Simplex.Messaging.Crypto as C
import Simplex.Messaging.Encoding.String
import Simplex.Messaging.Notifications.Transport (authEncryptCmdsNTFVersion)
import Simplex.Messaging.Protocol (BasicAuth, ErrorType (..), MsgBody, ProtocolServer (..), SubscriptionMode (..), supportedSMPClientVRange)
import qualified Simplex.Messaging.Protocol as SMP
import Simplex.Messaging.Server.Env.STM (ServerConfig (..))
@@ -134,6 +135,9 @@ smpCfgV4 = (smpCfg agentCfg) {serverVRange = mkVersionRange 4 4}
smpCfgV7 :: ProtocolClientConfig
smpCfgV7 = (smpCfg agentCfg) {serverVRange = mkVersionRange 4 authEncryptCmdsSMPVersion}
ntfCfgV2 :: ProtocolClientConfig
ntfCfgV2 = (smpCfg agentCfg) {serverVRange = mkVersionRange 1 authEncryptCmdsNTFVersion}
agentCfgVPrev :: AgentConfig
agentCfgVPrev =
agentCfg
@@ -147,7 +151,8 @@ agentCfgV7 :: AgentConfig
agentCfgV7 =
agentCfg
{ cmdAuthAlg = C.AuthAlg C.SX25519,
smpCfg = smpCfgV7
smpCfg = smpCfgV7,
ntfCfg = ntfCfgV2
}
agentCfgV1 :: AgentConfig
+20 -20
View File
@@ -26,10 +26,10 @@ import Data.ByteString.Char8 (ByteString)
import Data.Text.Encoding (encodeUtf8)
import NtfClient
import SMPAgentClient (agentCfg, initAgentServers, initAgentServers2, testDB, testDB2, testDB3, testNtfServer2)
import SMPClient (cfg, testPort, testPort2, testStoreLogFile2, withSmpServer, withSmpServerConfigOn, withSmpServerStoreLogOn)
import SMPClient (cfg, cfgV7, testPort, testPort2, testStoreLogFile2, withSmpServer, withSmpServerConfigOn, withSmpServerStoreLogOn)
import Simplex.Messaging.Agent
import Simplex.Messaging.Agent.Client (withStore')
import Simplex.Messaging.Agent.Env.SQLite (AgentConfig, InitialAgentServers)
import Simplex.Messaging.Agent.Env.SQLite (AgentConfig, Env (..), InitialAgentServers)
import Simplex.Messaging.Agent.Protocol
import Simplex.Messaging.Agent.Store.SQLite (getSavedNtfToken)
import qualified Simplex.Messaging.Crypto as C
@@ -73,12 +73,10 @@ notificationTests t = do
withAPNSMockServer $ \apns ->
testNtfTokenChangeServers t apns
describe "Managing notification subscriptions" $ do
fdescribe "should create notification subscription for existing connection" $
describe "should create notification subscription for existing connection" $
testNtfMatrix t testNotificationSubscriptionExistingConnection
it "should create notification subscription for new connection" $
withSmpServer t $
withAPNSMockServer $ \apns ->
withNtfServer t $ testNotificationSubscriptionNewConnection apns
describe "should create notification subscription for new connection" $
testNtfMatrix t testNotificationSubscriptionNewConnection
it "should change notifications mode" $
withSmpServer t $
withAPNSMockServer $ \apns ->
@@ -117,11 +115,17 @@ notificationTests t = do
testNtfMatrix :: ATransport -> (APNSMockServer -> AgentClient -> AgentClient -> IO ()) -> Spec
testNtfMatrix t runTest = do
-- it "v7 clients, v7 smp, v2 ntf server" $ runNtfTest cfg ntfServerCfg agentCfgV7 agentCfgV7 runTest
it "v6 clients, v6 smp, v1 ntf server" $ runNtfTestCfg t cfg ntfServerCfg agentCfg agentCfg runTest
-- it "v7 clients, v6 smp, v1 ntf server" $ runNtfTestCfg t cfg ntfServerCfg agentCfgV7 agentCfgV7 runTest
-- it "v7 to current" $ withSmpServerV7 t $ runTestCfg2 agentCfgV7 agentCfg 3 runTest
-- it "current to v7" $ withSmpServerV7 t $ runTestCfg2 agentCfg agentCfgV7 3 runTest
it "new servers: SMP v7, NTF v2; new clients: v7/v2" $ runNtfTestCfg t cfgV7 ntfServerCfgV2 agentCfgV7 agentCfgV7 runTest
it "new servers: SMP v7, NTF v2; old clients: v6/v1" $ runNtfTestCfg t cfgV7 ntfServerCfgV2 agentCfg agentCfg runTest
it "old servers: SMP v6, NTF v1; old clients: v6/v1" $ runNtfTestCfg t cfg ntfServerCfg agentCfg agentCfg runTest
-- this case will cannot be supported - see RFC
xit "servers: SMP v6, NTF v1; clients: v7/v2 (not supported)" $ runNtfTestCfg t cfg ntfServerCfg agentCfgV7 agentCfgV7 runTest
-- servers can be migrated in any order
it "servers: new SMP v7, old NTF v1; old clients: v6/v1" $ runNtfTestCfg t cfgV7 ntfServerCfg agentCfg agentCfg runTest
it "servers: old SMP v6, new NTF v2; old clients: v6/v1" $ runNtfTestCfg t cfg ntfServerCfgV2 agentCfg agentCfg runTest
-- clients can be partially migrated
it "servers: new SMP v7, old NTF v2; clients: new/old" $ runNtfTestCfg t cfgV7 ntfServerCfgV2 agentCfgV7 agentCfg runTest
it "servers: new SMP v7, old NTF v2; clients: old/new" $ runNtfTestCfg t cfgV7 ntfServerCfgV2 agentCfg agentCfgV7 runTest
runNtfTestCfg :: ATransport -> ServerConfig -> NtfServerConfig -> AgentConfig -> AgentConfig -> (APNSMockServer -> AgentClient -> AgentClient -> IO ()) -> IO ()
runNtfTestCfg t smpCfg ntfCfg aCfg bCfg runTest =
@@ -309,7 +313,7 @@ testNtfTokenChangeServers t APNSMockServer {apnsQ} =
checkNtfToken a tkn >>= \r -> liftIO $ r `shouldBe` NTActive
testNotificationSubscriptionExistingConnection :: APNSMockServer -> AgentClient -> AgentClient -> IO ()
testNotificationSubscriptionExistingConnection APNSMockServer {apnsQ} alice bob = do
testNotificationSubscriptionExistingConnection APNSMockServer {apnsQ} alice@AgentClient {agentEnv = Env {config = aliceCfg}} bob = do
(bobId, aliceId, nonce, message) <- runRight $ do
-- establish connection
(bobId, qInfo) <- createConnection alice 1 True SCMInvitation Nothing SMSubscribe
@@ -341,7 +345,7 @@ testNotificationSubscriptionExistingConnection APNSMockServer {apnsQ} alice bob
Left (CMD PROHIBITED) <- runExceptT $ getNotificationMessage alice nonce message
-- aliceNtf client doesn't have subscription and is allowed to get notification message
aliceNtf <- getSMPAgentClient' 3 agentCfg initAgentServers testDB
aliceNtf <- getSMPAgentClient' 3 aliceCfg initAgentServers testDB
runRight_ $ do
(_, [SMPMsgMeta {msgFlags = MsgFlags True}]) <- getNotificationMessage aliceNtf nonce message
pure ()
@@ -362,10 +366,8 @@ testNotificationSubscriptionExistingConnection APNSMockServer {apnsQ} alice bob
baseId = 3
msgId = subtract baseId
testNotificationSubscriptionNewConnection :: APNSMockServer -> IO ()
testNotificationSubscriptionNewConnection APNSMockServer {apnsQ} = do
alice <- getSMPAgentClient' 1 agentCfg initAgentServers testDB
bob <- getSMPAgentClient' 2 agentCfg initAgentServers testDB2
testNotificationSubscriptionNewConnection :: APNSMockServer -> AgentClient -> AgentClient -> IO ()
testNotificationSubscriptionNewConnection APNSMockServer {apnsQ} alice bob =
runRight_ $ do
-- alice registers notification token
DeviceToken {} <- registerTestToken alice "abcd" NMInstant apnsQ
@@ -401,8 +403,6 @@ testNotificationSubscriptionNewConnection APNSMockServer {apnsQ} = do
ackMessage bob aliceId (baseId + 2) Nothing
-- no unexpected notifications should follow
noNotification apnsQ
disconnectAgentClient alice
disconnectAgentClient bob
where
baseId = 3
msgId = subtract baseId
+11 -2
View File
@@ -30,8 +30,8 @@ import qualified Network.HTTP.Types as N
import qualified Network.HTTP2.Server as H
import Network.Socket
import SMPClient (serverBracket)
import Simplex.Messaging.Client (chooseTransportHost, defaultNetworkConfig)
import Simplex.Messaging.Client.Agent (defaultSMPClientAgentConfig)
import Simplex.Messaging.Client (ProtocolClientConfig (..), chooseTransportHost, defaultNetworkConfig)
import Simplex.Messaging.Client.Agent (SMPClientAgentConfig (..), defaultSMPClientAgentConfig)
import qualified Simplex.Messaging.Crypto as C
import Simplex.Messaging.Encoding
import Simplex.Messaging.Notifications.Server (runNtfServerBlocking)
@@ -45,6 +45,7 @@ import Simplex.Messaging.Transport.Client
import Simplex.Messaging.Transport.HTTP2 (HTTP2Body (..), http2TLSParams)
import Simplex.Messaging.Transport.HTTP2.Server
import Simplex.Messaging.Transport.Server
import Simplex.Messaging.Version (mkVersionRange)
import Test.Hspec
import UnliftIO.Async
import UnliftIO.Concurrent
@@ -106,9 +107,17 @@ ntfServerCfg =
logStatsStartTime = 0,
serverStatsLogFile = "tests/ntf-server-stats.daily.log",
serverStatsBackupFile = Nothing,
ntfServerVRange = supportedNTFServerVRange,
transportConfig = defaultTransportServerConfig
}
ntfServerCfgV2 :: NtfServerConfig
ntfServerCfgV2 =
ntfServerCfg
{ ntfServerVRange = mkVersionRange 1 authEncryptCmdsNTFVersion,
smpAgentCfg = defaultSMPClientAgentConfig {smpCfg = (smpCfg defaultSMPClientAgentConfig) {serverVRange = mkVersionRange 4 authEncryptCmdsSMPVersion}}
}
withNtfServerStoreLog :: ATransport -> (ThreadId -> IO a) -> IO a
withNtfServerStoreLog t = withNtfServerCfg ntfServerCfg {storeLogFile = Just ntfTestStoreLogFile, transports = [(ntfTestPort, t)]}