Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions web/pgadmin/utils/driver/psycopg3/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,12 +258,20 @@ def _decode_password(self, encpass, manager, password, crypt_key):
if isinstance(password, bytes):
password = password.decode()
except Exception as e:
manager.stop_ssh_tunnel()
current_app.logger.exception(e)
return True, \
_(
"Failed to decrypt the saved password.\nError: {0}"
).format(str(e)), password
# The saved password could not be decrypted. This happens
# when the stored ciphertext was encrypted with a different
# key (e.g. OIDC/OAuth2 logins where the derived encryption
# key changed between sessions), leaving un-decodable bytes
# (typically a "'utf-8' codec can't decode byte 0x.." error).
# Instead of failing every connection attempt permanently,
# discard the bad saved password and continue so the user is
# prompted for the password again.
current_app.logger.warning(
'Ignoring the saved password as it could not be '
'decrypted. The user will be prompted for the password. '
'Error: {0}'.format(str(e))
)
return False, '', None
Comment on lines +261 to +274

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Propagate the invalid-saved-password state to the prompt flow.

Returning (False, '', None) at Line 274 does not clear the ciphertext or identify that the saved credential was unusable. connect() has already stored it in self.password, and the truthy encpass skips the passexec fallback at Lines 323-334. The supplied downstream handler also passes not server.save_password to get_response_for_password; for this stale record that is false, so the SSH path can return prompt_password=False. Clear the cached ciphertext and propagate an explicit invalid-password state so the UI reliably re-prompts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/pgadmin/utils/driver/psycopg3/connection.py` around lines 261 - 274,
Update the invalid saved-password handling in the connection credential flow to
clear the cached ciphertext held by self.password and return an explicit
invalid-password state from the decryption helper. Ensure connect() and the
downstream get_response_for_password/SSH prompt flow consume that state so
passexec fallback is not skipped and the UI reliably prompts for a new password.

return False, '', password

def connect(self, **kwargs):
Expand Down
Loading