packages feed

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 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"+    )