{"version":1,"upstream":"MagicStack/asyncpg","fork":"aryansk/asyncpg","base":"master","branch":"fix/1286-missing-password-error","commitMessage":"fix: handle missing cleartext password cleanly","prTitle":"Handle missing password authentication cleanly","prBody":"## Summary\n\nAvoid an internal AttributeError when PostgreSQL requests cleartext password authentication but the connection parameters do not contain a password.\n\n## Changes\n\n- detect a missing password before building the cleartext password message\n- raise an asyncpg InterfaceError with an actionable message instead of calling .encode() on None\n- add regression coverage for connecting to a password-authenticated role without supplying a password\n\n## Test plan\n\npython -m unittest tests.test_connect.TestAuthentication.test_auth_password_cleartext_without_password\n\nFixes #1286","patch":"diff --git a/asyncpg/protocol/coreproto.pyx b/asyncpg/protocol/coreproto.pyx\n--- a/asyncpg/protocol/coreproto.pyx\n+++ b/asyncpg/protocol/coreproto.pyx\n@@ -574,8 +574,14 @@ cdef class CoreProtocol:\n elif status == AUTH_REQUIRED_PASSWORD:\n # AuthenticationCleartextPassword\n- self.result_type = RESULT_OK\n- self.auth_msg = self._auth_password_message_cleartext()\n+ if self.password is None:\n+ self.result_type = RESULT_FAILED\n+ self.result = apg_exc.InterfaceError(\n+ 'password authentication requested by server, '\n+ 'but no password was supplied')\n+ else:\n+ self.result_type = RESULT_OK\n+ self.auth_msg = self._auth_password_message_cleartext()\n \n elif status == AUTH_REQUIRED_PASSWORDMD5:\n # AuthenticationMD5Password\ndiff --git a/tests/test_connect.py b/tests/test_connect.py\n--- a/tests/test_connect.py\n+++ b/tests/test_connect.py\n@@ -274,6 +274,12 @@ class TestAuthentication(BaseTestAuthentication):\n user='password_user',\n password='wrongpassword')\n \n+ async def test_auth_password_cleartext_without_password(self):\n+ with self.assertRaisesRegex(\n+ asyncpg.InterfaceError, 'no password was supplied'):\n+ await self._try_connect(\n+ user='password_user', password=None)\n+\n async def test_auth_password_cleartext_callable(self):\n def get_correctpassword():\n return CORRECT_PASSWORD\n","draft":true,"upstreamIssue":1286}
{"version":1,"upstream":"MagicStack/asyncpg","fork":"aryansk/asyncpg","base":"master","branch":"fix/1286-missing-password-error","commitMessage":"fix: handle missing cleartext password cleanly","prTitle":"Handle missing password authentication cleanly","prBody":"## Summary\n\nAvoid an internal
AttributeErrorwhen PostgreSQL requests cleartext password authentication but the connection parameters do not contain a password.\n\n## Changes\n\n- detect a missing password before building the cleartext password message\n- raise an asyncpgInterfaceErrorwith an actionable message instead of calling.encode()onNone\n- add regression coverage for connecting to a password-authenticated role without supplying a password\n\n## Test plan\n\npython -m unittest tests.test_connect.TestAuthentication.test_auth_password_cleartext_without_password\n\nFixes #1286","patch":"diff --git a/asyncpg/protocol/coreproto.pyx b/asyncpg/protocol/coreproto.pyx\n--- a/asyncpg/protocol/coreproto.pyx\n+++ b/asyncpg/protocol/coreproto.pyx\n@@ -574,8 +574,14 @@ cdef class CoreProtocol:\n elif status == AUTH_REQUIRED_PASSWORD:\n # AuthenticationCleartextPassword\n- self.result_type = RESULT_OK\n- self.auth_msg = self._auth_password_message_cleartext()\n+ if self.password is None:\n+ self.result_type = RESULT_FAILED\n+ self.result = apg_exc.InterfaceError(\n+ 'password authentication requested by server, '\n+ 'but no password was supplied')\n+ else:\n+ self.result_type = RESULT_OK\n+ self.auth_msg = self._auth_password_message_cleartext()\n \n elif status == AUTH_REQUIRED_PASSWORDMD5:\n # AuthenticationMD5Password\ndiff --git a/tests/test_connect.py b/tests/test_connect.py\n--- a/tests/test_connect.py\n+++ b/tests/test_connect.py\n@@ -274,6 +274,12 @@ class TestAuthentication(BaseTestAuthentication):\n user='password_user',\n password='wrongpassword')\n \n+ async def test_auth_password_cleartext_without_password(self):\n+ with self.assertRaisesRegex(\n+ asyncpg.InterfaceError, 'no password was supplied'):\n+ await self._try_connect(\n+ user='password_user', password=None)\n+\n async def test_auth_password_cleartext_callable(self):\n def get_correctpassword():\n return CORRECT_PASSWORD\n","draft":true,"upstreamIssue":1286}