mirror of
https://github.com/simplex-chat/simplexmq.git
synced 2026-03-30 20:45:52 +00:00
* smp: command authorization
* fix encoding, most tests
* remove old tests
* authorize via crypto_box
* extract authenticator to Crypto module
* make TransmissionAuth Maybe
* rfc
* support authenticators in NTF protocol, test matrix (no backwards compatibility yet from new clients to old servers)
* fix/add tests, add version config to "small" agent
* separate client and server versions for SMP protocol
* test batching SMP v7
* do not send session ID in each transmission
* refactor auth verification in the server, split tests
* server "warm up" fixes timing test
* uncomment SUB timing test
* comments, disable two timing tests
* rename version
* increase auth timing test failure threshold
* use different algorithms to authorize snd/rcv commands, use random correlation ID
* transport: fetch and store server certificate (#985)
* THandleParams (WIP, does not compile)
* transport: fetch and store server certificate
* smp: add getOnlinePubKey example to smpClientHandshake
* add server certs and sign authPub
* cleanup
* update
* style
* load server certs from test fixtures
* sign ntf authPubKey
* fix onServerCertificate
* increase delay before sending messages
* require certificate with key in SMP server handshake
---------
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
* remove dhSecret from THandle
* remove v8, merge all changes to one version
* parameterize THandle
* rfc: transmission ecnryption
* Revert "parameterize THandle"
This reverts commit 75adfc94fb.
* use batch syntax for ntf server commands
* separate encodeTransmission when there is no key
* typo
Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>
* rename
* diff
---------
Co-authored-by: Alexander Bondarenko <486682+dpwiz@users.noreply.github.com>
Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>
183 lines
6.5 KiB
Haskell
183 lines
6.5 KiB
Haskell
{-# LANGUAGE DataKinds #-}
|
|
{-# LANGUAGE DuplicateRecordFields #-}
|
|
{-# LANGUAGE NamedFieldPuns #-}
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
{-# LANGUAGE ScopedTypeVariables #-}
|
|
|
|
module FileDescriptionTests where
|
|
|
|
import Control.Exception (bracket_)
|
|
import qualified Data.ByteString.Char8 as B
|
|
import qualified Data.Yaml as Y
|
|
import Simplex.FileTransfer.Description
|
|
import Simplex.FileTransfer.Protocol
|
|
import qualified Simplex.Messaging.Crypto as C
|
|
import Simplex.Messaging.Encoding.String (StrEncoding (..))
|
|
import Simplex.Messaging.ServiceScheme (ServiceScheme (..))
|
|
import System.Directory (removeFile)
|
|
import Test.Hspec
|
|
|
|
fileDescriptionTests :: Spec
|
|
fileDescriptionTests = do
|
|
describe "file description parsing / serializing" $ do
|
|
it "parse YAML file description" testParseYAMLFileDescription
|
|
it "serialize YAML file description" testSerializeYAMLFileDescription
|
|
it "parse file description" testParseFileDescription
|
|
it "serialize file description" testSerializeFileDescription
|
|
describe "file description URIs" $ do
|
|
it "round trip file description URI" testFileDescriptionURI
|
|
it "round trip file description URI with extra JSON" testFileDescriptionURIExtras
|
|
|
|
fileDescPath :: FilePath
|
|
fileDescPath = "tests/fixtures/file_description.yaml"
|
|
|
|
tmpFileDescPath :: FilePath
|
|
tmpFileDescPath = "tests/tmp/file_description.yaml"
|
|
|
|
testSbKey :: C.SbKey
|
|
testSbKey = either error id $ strDecode "00n8p1tJq5E-SGnHcYTOrS4A9I07gTA_WFD6MTFFFOY="
|
|
|
|
testCbNonce :: C.CbNonce
|
|
testCbNonce = either error id $ strDecode "dPSF-wrQpDiK_K6sYv0BDBZ9S4dg-jmu"
|
|
|
|
fileDesc :: FileDescription 'FRecipient
|
|
fileDesc =
|
|
FileDescription
|
|
{ party = SFRecipient,
|
|
size = FileSize $ mb 26,
|
|
digest = FileDigest "abc",
|
|
key = testSbKey,
|
|
nonce = testCbNonce,
|
|
chunkSize = defaultChunkSize,
|
|
chunks =
|
|
[ FileChunk
|
|
{ chunkNo = 1,
|
|
digest = chunkDigest,
|
|
chunkSize = defaultChunkSize,
|
|
replicas =
|
|
[ FileChunkReplica {server = "xftp://abc=@example1.com", replicaId, replicaKey},
|
|
FileChunkReplica {server = "xftp://abc=@example3.com", replicaId, replicaKey}
|
|
]
|
|
},
|
|
FileChunk
|
|
{ chunkNo = 2,
|
|
digest = chunkDigest,
|
|
chunkSize = defaultChunkSize,
|
|
replicas =
|
|
[ FileChunkReplica {server = "xftp://abc=@example2.com", replicaId, replicaKey},
|
|
FileChunkReplica {server = "xftp://abc=@example4.com", replicaId, replicaKey}
|
|
]
|
|
},
|
|
FileChunk
|
|
{ chunkNo = 3,
|
|
digest = chunkDigest,
|
|
chunkSize = defaultChunkSize,
|
|
replicas =
|
|
[ FileChunkReplica {server = "xftp://abc=@example1.com", replicaId, replicaKey},
|
|
FileChunkReplica {server = "xftp://abc=@example4.com", replicaId, replicaKey}
|
|
]
|
|
},
|
|
FileChunk
|
|
{ chunkNo = 4,
|
|
digest = chunkDigest,
|
|
chunkSize = FileSize $ mb 2,
|
|
replicas =
|
|
[ FileChunkReplica {server = "xftp://abc=@example2.com", replicaId, replicaKey},
|
|
FileChunkReplica {server = "xftp://abc=@example3.com", replicaId, replicaKey}
|
|
]
|
|
}
|
|
],
|
|
redirect = Nothing
|
|
}
|
|
where
|
|
defaultChunkSize = FileSize $ mb 8
|
|
replicaId = ChunkReplicaId "abc"
|
|
replicaKey = C.APrivateAuthKey C.SEd25519 "MC4CAQAwBQYDK2VwBCIEIDfEfevydXXfKajz3sRkcQ7RPvfWUPoq6pu1TYHV1DEe"
|
|
chunkDigest = FileDigest "ghi"
|
|
|
|
yamlFileDesc :: YAMLFileDescription
|
|
yamlFileDesc =
|
|
YAMLFileDescription
|
|
{ party = FRecipient,
|
|
size = "26mb",
|
|
chunkSize = "8mb",
|
|
digest = FileDigest "abc",
|
|
key = testSbKey,
|
|
nonce = testCbNonce,
|
|
replicas =
|
|
[ YAMLServerReplicas
|
|
{ server = "xftp://abc=@example1.com",
|
|
chunks =
|
|
[ "1:YWJj:MC4CAQAwBQYDK2VwBCIEIDfEfevydXXfKajz3sRkcQ7RPvfWUPoq6pu1TYHV1DEe:Z2hp",
|
|
"3:YWJj:MC4CAQAwBQYDK2VwBCIEIDfEfevydXXfKajz3sRkcQ7RPvfWUPoq6pu1TYHV1DEe:Z2hp"
|
|
]
|
|
},
|
|
YAMLServerReplicas
|
|
{ server = "xftp://abc=@example2.com",
|
|
chunks =
|
|
[ "2:YWJj:MC4CAQAwBQYDK2VwBCIEIDfEfevydXXfKajz3sRkcQ7RPvfWUPoq6pu1TYHV1DEe:Z2hp",
|
|
"4:YWJj:MC4CAQAwBQYDK2VwBCIEIDfEfevydXXfKajz3sRkcQ7RPvfWUPoq6pu1TYHV1DEe:Z2hp:2mb"
|
|
]
|
|
},
|
|
YAMLServerReplicas
|
|
{ server = "xftp://abc=@example3.com",
|
|
chunks =
|
|
[ "1:YWJj:MC4CAQAwBQYDK2VwBCIEIDfEfevydXXfKajz3sRkcQ7RPvfWUPoq6pu1TYHV1DEe",
|
|
"4:YWJj:MC4CAQAwBQYDK2VwBCIEIDfEfevydXXfKajz3sRkcQ7RPvfWUPoq6pu1TYHV1DEe"
|
|
]
|
|
},
|
|
YAMLServerReplicas
|
|
{ server = "xftp://abc=@example4.com",
|
|
chunks =
|
|
[ "2:YWJj:MC4CAQAwBQYDK2VwBCIEIDfEfevydXXfKajz3sRkcQ7RPvfWUPoq6pu1TYHV1DEe",
|
|
"3:YWJj:MC4CAQAwBQYDK2VwBCIEIDfEfevydXXfKajz3sRkcQ7RPvfWUPoq6pu1TYHV1DEe"
|
|
]
|
|
}
|
|
],
|
|
redirect = Nothing
|
|
}
|
|
|
|
testParseYAMLFileDescription :: IO ()
|
|
testParseYAMLFileDescription = do
|
|
yfd <- Y.decodeFileThrow fileDescPath
|
|
yfd `shouldBe` yamlFileDesc
|
|
|
|
testSerializeYAMLFileDescription :: IO ()
|
|
testSerializeYAMLFileDescription = withRemoveTmpFile $ do
|
|
Y.encodeFile tmpFileDescPath yamlFileDesc
|
|
fdSer <- B.readFile tmpFileDescPath
|
|
fdExp <- B.readFile fileDescPath
|
|
fdSer `shouldBe` fdExp
|
|
|
|
testParseFileDescription :: IO ()
|
|
testParseFileDescription = do
|
|
r <- strDecode <$> B.readFile fileDescPath
|
|
case r of
|
|
Left e -> expectationFailure $ show e
|
|
Right fd -> fd `shouldBe` fileDesc
|
|
|
|
testSerializeFileDescription :: IO ()
|
|
testSerializeFileDescription = withRemoveTmpFile $ do
|
|
B.writeFile tmpFileDescPath $ strEncode fileDesc
|
|
fdSer <- B.readFile tmpFileDescPath
|
|
fdExp <- B.readFile fileDescPath
|
|
fdSer `shouldBe` fdExp
|
|
|
|
testFileDescriptionURI :: IO ()
|
|
testFileDescriptionURI = do
|
|
vfd <- either fail pure $ validateFileDescription fileDesc
|
|
let descr = FileDescriptionURI SSSimplex vfd mempty
|
|
strDecode (strEncode descr) `shouldBe` Right descr
|
|
|
|
testFileDescriptionURIExtras :: IO ()
|
|
testFileDescriptionURIExtras = do
|
|
vfd <- either fail pure $ validateFileDescription fileDesc
|
|
let descr = FileDescriptionURI SSSimplex vfd $ Just "{\"something\":\"extra\",\"more\":true}"
|
|
strDecode (strEncode descr) `shouldBe` Right descr
|
|
|
|
withRemoveTmpFile :: IO () -> IO ()
|
|
withRemoveTmpFile =
|
|
bracket_
|
|
(pure ())
|
|
(removeFile tmpFileDescPath)
|