pqi-native 1.0.1.10 → 1.0.1.11
raw patch · 4 files changed
+25/−6 lines, 4 filesdep ~pqi-conformancePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: pqi-conformance
API changes (from Hackage documentation)
Files
- CHANGELOG.md +6/−0
- pqi-native.cabal +2/−2
- src/library/Pqi/Native.hs +4/−2
- src/library/Pqi/Native/Connection.hs +13/−2
CHANGELOG.md view
@@ -1,3 +1,9 @@+# v1.0.1.11++## Fixes++- Fixed `Pqi.connectionNeedsPassword` and `Pqi.connectionUsedPassword` tracking the conninfo `password=` field instead of libpq's `password_needed` auth-exchange state. `connectionNeedsPassword` was hardcoded `pure False`; `connectionUsedPassword` was `not (ByteString.null password)`, so it reported `True` whenever a password string was merely present in the conninfo, trust auth or not, and `connectionNeedsPassword` never reported `True` even when SCRAM authentication was challenged for and no password was supplied. `Pqi.Native.Connection.Connection` now carries a `passwordNeeded` flag, set during the handshake only when the server actually sends `AuthenticationCleartextPassword`/`MD5Password`/`SASL`, and reset on `reconnect`; both functions now derive from that state, matching `fe-auth.c`'s `password_needed` semantics exactly. Caught by the `pqi-conformance` specs `Pqi.Conformance.Operation.ConnectionNeedsPassword` and `Pqi.Conformance.Operation.ConnectionUsedPassword`.+ # v1.0.1.10 ## Fixes
pqi-native.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: pqi-native-version: 1.0.1.10+version: 1.0.1.11 category: Database, PostgreSQL synopsis: Native (pure-Haskell) adapter for pqi description:@@ -158,5 +158,5 @@ build-depends: base >=4.11 && <5, hspec >=2.11 && <2.12,- pqi-conformance ^>=1.0.9,+ pqi-conformance ^>=1.0.11, pqi-native,
src/library/Pqi/Native.hs view
@@ -101,8 +101,10 @@ fd <- Transport.socketFd transport pure (Just (fromIntegral fd :: Fd)), Pqi.backendPID = maybe 0 fst <$> readIORef (Connection.backendKey connection),- Pqi.connectionNeedsPassword = pure False,- Pqi.connectionUsedPassword = pure (not (ByteString.null (Connection.password (Connection.info connection)))),+ Pqi.connectionNeedsPassword = do+ needed <- readIORef (Connection.passwordNeeded connection)+ pure (needed && ByteString.null (Connection.password (Connection.info connection))),+ Pqi.connectionUsedPassword = readIORef (Connection.passwordNeeded connection), Pqi.exec = \sql -> fmap mkResult <$> Query.exec connection sql, Pqi.execParams = \sql params resultFormat -> fmap mkResult <$> Query.execParams connection sql params resultFormat,
src/library/Pqi/Native/Connection.hs view
@@ -314,7 +314,13 @@ -- | The SQL text of the most recently sent query (set by sendQuery / -- sendQueryParams). Used when formatting error messages for async results -- so that @LINE N:@ position context can be reproduced.- currentQuery :: IORef ByteString+ currentQuery :: IORef ByteString,+ -- | Set during the handshake when the server actually challenges for a+ -- password (@AuthenticationCleartextPassword@\/@MD5Password@\/@SASL@),+ -- mirroring libpq's @password_needed@. Trust\/peer\/GSS authentication+ -- never sets this, regardless of whether a password was supplied in the+ -- conninfo.+ passwordNeeded :: IORef Bool } -- | Send a serialized frontend message.@@ -532,6 +538,7 @@ writeIORef (txStatus connection) 0x49 writeIORef (connStatus connection) ConnectionBad writeIORef (lastError connection) (Just "")+ writeIORef (passwordNeeded connection) False sendMessage connection (startupMessage (startupParams (info connection))) handshake connection @@ -564,6 +571,7 @@ <*> newIORef Seq.empty <*> newIORef ErrorsDefault <*> newIORef ""+ <*> newIORef False -- | The startup\/authentication state machine, ending at the first -- @ReadyForQuery@ (success) or @ErrorResponse@ (failure).@@ -575,13 +583,16 @@ case message of AuthenticationOk -> startingUp AuthenticationCleartextPassword -> do+ writeIORef (passwordNeeded connection) True sendMessage connection (passwordMessage (password (info connection))) authenticating AuthenticationMD5Password salt -> do+ writeIORef (passwordNeeded connection) True let response = Auth.md5Password (user (info connection)) (password (info connection)) salt sendMessage connection (passwordMessage response) authenticating- AuthenticationSASL mechanisms ->+ AuthenticationSASL mechanisms -> do+ writeIORef (passwordNeeded connection) True Auth.scram (user (info connection)) (password (info connection)) mechanisms (saslExchange connection) >>= \case Left problem -> setError connection problem Right () -> startingUp