]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Added needs_password, used_password, ssl_in_use on PGconn
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sat, 14 Mar 2020 12:38:49 +0000 (01:38 +1300)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sat, 14 Mar 2020 12:38:49 +0000 (01:38 +1300)
psycopg3/_pq_ctypes.py
psycopg3/pq_ctypes.py
tests/fix_tempenv.py
tests/test_pq.py

index 6fcac518434612906b40ea10b4e692108b9eb7ba..21358b72639bee57499d319382e3a74439717157 100644 (file)
@@ -161,6 +161,18 @@ PQbackendPID = pq.PQbackendPID
 PQbackendPID.argtypes = [PGconn_ptr]
 PQbackendPID.restype = c_int
 
+PQconnectionNeedsPassword = pq.PQconnectionNeedsPassword
+PQconnectionNeedsPassword.argtypes = [PGconn_ptr]
+PQconnectionNeedsPassword.restype = c_int
+
+PQconnectionUsedPassword = pq.PQconnectionUsedPassword
+PQconnectionUsedPassword.argtypes = [PGconn_ptr]
+PQconnectionUsedPassword.restype = c_int
+
+PQsslInUse = pq.PQsslInUse
+PQsslInUse.argtypes = [PGconn_ptr]
+PQsslInUse.restype = c_int
+
 
 # 33.11. Miscellaneous Functions
 
index 77448a2206c586f08a028cff44c3cfd5b6d8c9b9..fba097c81c752159127e297b00f0e45c955e03bc 100644 (file)
@@ -193,6 +193,18 @@ class PGconn:
     def backend_pid(self):
         return impl.PQbackendPID(self.pgconn_ptr)
 
+    @property
+    def needs_password(self):
+        return bool(impl.PQconnectionNeedsPassword(self.pgconn_ptr))
+
+    @property
+    def used_password(self):
+        return bool(impl.PQconnectionUsedPassword(self.pgconn_ptr))
+
+    @property
+    def ssl_in_use(self):
+        return bool(impl.PQsslInUse(self.pgconn_ptr))
+
     def _encode(self, s):
         if isinstance(s, bytes):
             return s
index 2f1e0897a8b6b8d580e183fbeb0fa3556f0397d4..9f3f35bd7f2090cdca97186b41f3f2a83bdf1e40 100644 (file)
@@ -20,6 +20,9 @@ class TempEnv:
         self._prev.setdefault(item, os.environ.get(item))
         del os.environ[item]
 
+    def __contains__(self, item):
+        return item in os.environ
+
     def restore(self):
         for k, v in self._prev.items():
             if v is not None:
index 9a4e5a76c3128ac1906a2fe9e223a2bb6279a00b..e77f1d5ae3ce8fbea8cde5e6166dd8f3dce2144c 100644 (file)
@@ -177,8 +177,8 @@ def test_transaction_status(pq, pgconn):
 def test_parameter_status(pq, dsn, tempenv):
     tempenv["PGAPPNAME"] = "psycopg3 tests"
     pgconn = pq.PGconn.connect(dsn)
-    assert pgconn.parameter_status('application_name') == "psycopg3 tests"
-    assert pgconn.parameter_status('wat') is None
+    assert pgconn.parameter_status("application_name") == "psycopg3 tests"
+    assert pgconn.parameter_status("wat") is None
 
 
 def test_protocol_version(pgconn):
@@ -191,3 +191,38 @@ def test_server_version(pgconn):
 
 def test_backend_pid(pgconn):
     assert 2 <= pgconn.backend_pid <= 65535  # Unless increased in kernel?
+
+
+def test_needs_password(pgconn):
+    # assume connection worked so an eventually needed password wasn't missing
+    assert pgconn.needs_password is False
+
+
+def test_used_password(pgconn, tempenv, dsn):
+    assert isinstance(pgconn.used_password, bool)
+
+    # Assume that if a password was passed then it was needed.
+    # Note that the server may still need a password passed via pgpass
+    # so it may be that has_password is false but still a password was
+    # requested by the server and passed by libpq.
+    info = pgconn.parse_conninfo(dsn)
+    has_password = (
+        "PGPASSWORD" in tempenv
+        or [i for i in info if i.keyword == "password"][0].val is not None
+    )
+    if has_password:
+        assert pgconn.used_password
+
+
+def test_ssl_in_use(pgconn):
+    assert isinstance(pgconn.ssl_in_use, bool)
+
+    # If connecting via socket then ssl is not in use
+    if pgconn.host.startswith("/"):
+        assert not pgconn.ssl_in_use
+    else:
+        sslmode = [i.val for i in pgconn.info if i.keyword == "sslmode"][0]
+        if sslmode not in ("disable", "allow"):
+            # 'prefer' may still connect without ssl
+            # but maybe unlikely in the tests environment?
+            assert pgconn.ssl_in_use