Skip to content
Open
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions docs/en_US/release_notes_9_16.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,4 @@ Bug fixes
| `Issue #9984 <https://github.com/pgadmin-org/pgadmin4/issues/9984>`_ - Fix the Docker entrypoint mishandling a quoted PGADMIN_CONFIG_CONFIG_DATABASE_URI, which caused a SQLAlchemy parse error and silently skipped PGADMIN_DEFAULT_EMAIL/PASSWORD setup.
| `Issue #9987 <https://github.com/pgadmin-org/pgadmin4/issues/9987>`_ - Fix "AttributeError: 'PgAdmin' object has no attribute 'login_manager'" crash when running setup.py user-management commands (add-user, update-user) from the CLI.
| `Issue #9988 <https://github.com/pgadmin-org/pgadmin4/issues/9988>`_ - Provide an actionable error when 'openid' is in OAUTH2_SCOPE but OAUTH2_SERVER_METADATA_URL is not set, instead of a cryptic Authlib failure.
| `Issue #10027 <https://github.com/pgadmin-org/pgadmin4/issues/10027>`_ - Fix the spurious "Crypt key is missing" error and logged traceback in the Query Tool new-connection endpoints after a backend restart, by surfacing it as the standard CRYPTKEY_MISSING response so the client recovers transparently.
10 changes: 10 additions & 0 deletions web/pgadmin/tools/sqleditor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2379,6 +2379,8 @@ def _check_server_connection_status(sgid, sid=None):
}
)

except (ConnectionLost, SSHTunnelConnectionLost, CryptKeyMissing):
raise
except Exception as e:
current_app.logger.exception(e)
return make_json_response(
Expand Down Expand Up @@ -2445,6 +2447,8 @@ def get_new_connection_data(sgid=None, sid=None):
}
)

except (ConnectionLost, SSHTunnelConnectionLost, CryptKeyMissing):
raise
except Exception as e:
current_app.logger.exception(e)
return make_json_response(
Expand Down Expand Up @@ -2519,6 +2523,8 @@ def get_new_connection_database(sgid, sid=None):
}
}
)
except (ConnectionLost, SSHTunnelConnectionLost, CryptKeyMissing):
raise
except Exception as e:
current_app.logger.exception(e)
return make_json_response(
Expand Down Expand Up @@ -2585,6 +2591,8 @@ def get_new_connection_user(sgid, sid=None):
}
}
)
except (ConnectionLost, SSHTunnelConnectionLost, CryptKeyMissing):
raise
except Exception as e:
current_app.logger.exception(e)
return make_json_response(
Expand Down Expand Up @@ -2649,6 +2657,8 @@ def get_new_connection_role(sgid, sid=None):
}
}
)
except (ConnectionLost, SSHTunnelConnectionLost, CryptKeyMissing):
raise
except Exception as e:
current_app.logger.exception(e)
return make_json_response(
Expand Down
38 changes: 27 additions & 11 deletions web/pgadmin/tools/sqleditor/tests/test_new_connection_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
# This software is released under the PostgreSQL Licence
#
##########################################################################
import json
from unittest.mock import patch
from pgadmin.utils.route import BaseTestGenerator
from regression import parent_node_dict
from regression.test_setup import config_data
from regression.python_test_utils import test_utils as utils
from pgadmin.utils.exception import CryptKeyMissing


class TestNewConnectionDialog(BaseTestGenerator):
Expand All @@ -19,15 +19,19 @@ class TestNewConnectionDialog(BaseTestGenerator):
('New connection dialog',
dict(
url="/sqleditor/new_connection_dialog/",
is_positive_test=True,
mocking_required=False,
is_connect_server=False,
test_data={},
mock_data={},
crypt_key_missing=False,
expected_data={
"status_code": 200
}
)),
('New connection dialog when the crypt key is missing',
dict(
url="/sqleditor/new_connection_dialog/",
crypt_key_missing=True,
expected_data={
"status_code": 503
}
)),
]

def setUp(self):
Expand All @@ -43,8 +47,20 @@ def new_connection(self):
return response

def runTest(self):
if self.is_positive_test:
if self.crypt_key_missing:
# When the crypt key is missing (e.g. the backend was restarted),
# the endpoint must surface CryptKeyMissing as a 503
Comment on lines 49 to +52
# CRYPTKEY_MISSING response so the client can transparently
# recover, rather than swallowing it into a generic error and
# logging a traceback. See issue #10027.
with patch('pgadmin.utils.driver.psycopg3.server_manager.'
'ServerManager.connection',
side_effect=CryptKeyMissing()):
response = self.new_connection()
self.assertEqual(response.status_code,
self.expected_data['status_code'])
self.assertIn('CRYPTKEY_MISSING', response.data.decode('utf-8'))
else:
response = self.new_connection()
actual_response_code = response.status_code
expected_response_code = self.expected_data['status_code']
self.assertEqual(actual_response_code, expected_response_code)
self.assertEqual(response.status_code,
self.expected_data['status_code'])
Loading