pqi-conformance 1.0.10.0 → 1.0.11.0
raw patch · 4 files changed
+102/−11 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG.md +6/−0
- pqi-conformance.cabal +1/−1
- src/library/Pqi/Conformance/Operation/ConnectionNeedsPassword.hs +60/−5
- src/library/Pqi/Conformance/Operation/ConnectionUsedPassword.hs +35/−5
CHANGELOG.md view
@@ -1,3 +1,9 @@+# v1.0.11.0++## Non-breaking++- Added `connectionNeedsPassword` and `connectionUsedPassword` specs covering trust auth with a `password=` field present in the conninfo (expected `False` for both, since the server never actually challenged for one) and a SCRAM-auth container both with and without a password supplied. Found `pqi-native`'s implementations tracked the conninfo `password=` field instead of libpq's `password_needed` auth-exchange state (`connectionNeedsPassword` was hardcoded `False`; `connectionUsedPassword` was `True` whenever a password string was merely present, trust auth or not).+ # v1.0.10.0 ## Non-breaking
pqi-conformance.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: pqi-conformance-version: 1.0.10.0+version: 1.0.11.0 category: Database, PostgreSQL, Testing synopsis: Differential conformance tests for pqi adapters description:
src/library/Pqi/Conformance/Operation/ConnectionNeedsPassword.hs view
@@ -1,17 +1,72 @@--- | Coverage for 'Pqi.connectionNeedsPassword': whether authentication--- needed a password that was unavailable (False under trust auth).+-- | Coverage for 'Pqi.connectionNeedsPassword': whether the server actually+-- challenged for a password during authentication and none was available+-- (mirroring libpq's @password_needed@ state, not merely whether a+-- @password=@ field was present in the conninfo). module Pqi.Conformance.Operation.ConnectionNeedsPassword ( spec, ) where +import Control.Exception (bracket)+import qualified Data.ByteString.Char8 as ByteString.Char8+import qualified Data.Text as Text import qualified Pqi import Pqi.Conformance.Harness import Pqi.Conformance.Prelude+import qualified Pqi.Conformance.Reference as Reference import Test.Hspec+import qualified TestcontainersPostgresql as TcPg spec :: Pqi.Adapter -> SpecWith ByteString-spec adapter =+spec adapter = do describe "connectionNeedsPassword" do- it "reports whether a password was needed" \conninfo ->- differential adapter conninfo Pqi.connectionNeedsPassword+ it "reports False under trust auth even when a password is supplied" \conninfo ->+ differential adapter (conninfo <> " password=irrelevant") Pqi.connectionNeedsPassword++ it "reports False once SCRAM authentication succeeded with the right password" \_ ->+ let scramConfig =+ TcPg.Config+ { TcPg.tagName = "postgres:17",+ TcPg.forwardLogs = False,+ TcPg.auth = TcPg.CredentialsAuth "scram" "secret"+ }+ in TcPg.run scramConfig \(host, port) -> do+ let conninfo = scramConninfo host port "secret"+ candidate <- bracket (Pqi.connectdb adapter conninfo) Pqi.finish Pqi.connectionNeedsPassword+ reference <- bracket (Pqi.connectdb Reference.adapter conninfo) Pqi.finish Pqi.connectionNeedsPassword+ candidate `shouldBe` reference++ it "reports True when SCRAM authentication is challenged for but no password was supplied" \_ ->+ let scramConfig =+ TcPg.Config+ { TcPg.tagName = "postgres:17",+ TcPg.forwardLogs = False,+ TcPg.auth = TcPg.CredentialsAuth "scram" "secret"+ }+ in TcPg.run scramConfig \(host, port) -> do+ let conninfo = scramConninfoNoPassword host port+ candidate <- bracket (Pqi.connectdb adapter conninfo) Pqi.finish Pqi.connectionNeedsPassword+ reference <- bracket (Pqi.connectdb Reference.adapter conninfo) Pqi.finish Pqi.connectionNeedsPassword+ candidate `shouldBe` reference++scramConninfo :: Text -> Word16 -> ByteString -> ByteString+scramConninfo host port password =+ ByteString.Char8.pack+ ( "host="+ <> Text.unpack host+ <> " port="+ <> show port+ <> " user=scram password="+ <> ByteString.Char8.unpack password+ <> " dbname=scram"+ )++scramConninfoNoPassword :: Text -> Word16 -> ByteString+scramConninfoNoPassword host port =+ ByteString.Char8.pack+ ( "host="+ <> Text.unpack host+ <> " port="+ <> show port+ <> " user=scram dbname=scram"+ )
src/library/Pqi/Conformance/Operation/ConnectionUsedPassword.hs view
@@ -1,17 +1,47 @@--- | Coverage for 'Pqi.connectionUsedPassword': whether authentication--- used a password (False under trust auth).+-- | Coverage for 'Pqi.connectionUsedPassword': whether the server actually+-- challenged for a password during authentication (mirroring libpq's+-- @password_needed@ state, not merely whether a @password=@ field was+-- present in the conninfo). module Pqi.Conformance.Operation.ConnectionUsedPassword ( spec, ) where +import Control.Exception (bracket)+import qualified Data.ByteString.Char8 as ByteString.Char8+import qualified Data.Text as Text import qualified Pqi import Pqi.Conformance.Harness import Pqi.Conformance.Prelude+import qualified Pqi.Conformance.Reference as Reference import Test.Hspec+import qualified TestcontainersPostgresql as TcPg spec :: Pqi.Adapter -> SpecWith ByteString-spec adapter =+spec adapter = do describe "connectionUsedPassword" do- it "reports whether a password was used" \conninfo ->- differential adapter conninfo Pqi.connectionUsedPassword+ it "reports False under trust auth even when a password is supplied" \conninfo ->+ differential adapter (conninfo <> " password=irrelevant") Pqi.connectionUsedPassword++ it "reports True once SCRAM authentication was actually challenged for" \_ ->+ let scramConfig =+ TcPg.Config+ { TcPg.tagName = "postgres:17",+ TcPg.forwardLogs = False,+ TcPg.auth = TcPg.CredentialsAuth "scram" "secret"+ }+ in TcPg.run scramConfig \(host, port) -> do+ let conninfo = scramConninfo host port+ candidate <- bracket (Pqi.connectdb adapter conninfo) Pqi.finish Pqi.connectionUsedPassword+ reference <- bracket (Pqi.connectdb Reference.adapter conninfo) Pqi.finish Pqi.connectionUsedPassword+ candidate `shouldBe` reference++scramConninfo :: Text -> Word16 -> ByteString+scramConninfo host port =+ ByteString.Char8.pack+ ( "host="+ <> Text.unpack host+ <> " port="+ <> show port+ <> " user=scram password=secret dbname=scram"+ )