From 4f5f8de2e8447233d7236c9f024dd1bf0334a3b4 Mon Sep 17 00:00:00 2001 From: Ahmed Awan Date: Mon, 1 Jul 2024 12:36:41 -0500 Subject: [PATCH 1/6] [24.0] Return generic message for password reset email This prevents existence of a user account from being queryable through password reset. We now return `None` and display a generic message regardless of a prt being created or not. Fixes https://github.com/galaxyproject/galaxy/issues/18475 --- lib/galaxy/managers/users.py | 2 +- lib/galaxy/webapps/galaxy/controllers/user.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/managers/users.py b/lib/galaxy/managers/users.py index 2196857cf479..4a9501585ee2 100644 --- a/lib/galaxy/managers/users.py +++ b/lib/galaxy/managers/users.py @@ -609,7 +609,7 @@ def send_reset_email(self, trans, payload, **kwd): log.debug(body) return f"Failed to submit email. Please contact the administrator: {util.unicodify(e)}" else: - return "Failed to produce password reset token. User not found." + return None def get_reset_token(self, trans, email): reset_user = get_user_by_email(trans.sa_session, email, self.app.model.User) diff --git a/lib/galaxy/webapps/galaxy/controllers/user.py b/lib/galaxy/webapps/galaxy/controllers/user.py index e661f3c40afe..d8c1ed5541c4 100644 --- a/lib/galaxy/webapps/galaxy/controllers/user.py +++ b/lib/galaxy/webapps/galaxy/controllers/user.py @@ -342,7 +342,7 @@ def reset_password(self, trans, payload=None, **kwd): payload = payload or {} if message := self.user_manager.send_reset_email(trans, payload): return self.message_exception(trans, message) - return {"message": "Reset link has been sent to your email."} + return {"message": "If an account exists for this email address a confirmation email will be dispatched."} def __get_redirect_url(self, redirect): if not redirect or redirect == "None": From a6e70816f3daa6f867eac7cc16de9196c375b666 Mon Sep 17 00:00:00 2001 From: Ahmed Awan Date: Mon, 1 Jul 2024 13:42:44 -0500 Subject: [PATCH 2/6] adjust `test_reset_email_user_deleted` for `None` instead of str --- test/unit/app/managers/test_UserManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/app/managers/test_UserManager.py b/test/unit/app/managers/test_UserManager.py index b8286838d103..fa93a42a03bc 100644 --- a/test/unit/app/managers/test_UserManager.py +++ b/test/unit/app/managers/test_UserManager.py @@ -240,7 +240,7 @@ def test_reset_email_user_deleted(self): self.user_manager.delete(user) assert user.deleted is True message = self.user_manager.send_reset_email(self.trans, {"email": user_email}) - assert message == "Failed to produce password reset token. User not found." + assert message == None def test_get_user_by_identity(self): # return None if username/email not found From 9727b884b38a7537215ef6f324ef02ba901cef52 Mon Sep 17 00:00:00 2001 From: Ahmed Awan Date: Mon, 1 Jul 2024 13:43:19 -0500 Subject: [PATCH 3/6] remove else block and return `None` by the outer conditional --- lib/galaxy/managers/users.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/galaxy/managers/users.py b/lib/galaxy/managers/users.py index 4a9501585ee2..c905443f4498 100644 --- a/lib/galaxy/managers/users.py +++ b/lib/galaxy/managers/users.py @@ -608,8 +608,7 @@ def send_reset_email(self, trans, payload, **kwd): except Exception as e: log.debug(body) return f"Failed to submit email. Please contact the administrator: {util.unicodify(e)}" - else: - return None + return None def get_reset_token(self, trans, email): reset_user = get_user_by_email(trans.sa_session, email, self.app.model.User) From 077832bc298d74278bee77eaffabc3f0a241a812 Mon Sep 17 00:00:00 2001 From: Ahmed Hamid Awan Date: Mon, 1 Jul 2024 13:56:50 -0500 Subject: [PATCH 4/6] Update test/unit/app/managers/test_UserManager.py Co-authored-by: John Davis --- test/unit/app/managers/test_UserManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/app/managers/test_UserManager.py b/test/unit/app/managers/test_UserManager.py index fa93a42a03bc..8bd1807c50c1 100644 --- a/test/unit/app/managers/test_UserManager.py +++ b/test/unit/app/managers/test_UserManager.py @@ -240,7 +240,7 @@ def test_reset_email_user_deleted(self): self.user_manager.delete(user) assert user.deleted is True message = self.user_manager.send_reset_email(self.trans, {"email": user_email}) - assert message == None + assert message is None def test_get_user_by_identity(self): # return None if username/email not found From 839fd0c5bcce1c9884920fc052179b5d8e827093 Mon Sep 17 00:00:00 2001 From: Ahmed Hamid Awan Date: Fri, 5 Jul 2024 20:16:32 +0500 Subject: [PATCH 5/6] Update lib/galaxy/managers/users.py Co-authored-by: Marius van den Beek --- lib/galaxy/managers/users.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/galaxy/managers/users.py b/lib/galaxy/managers/users.py index c905443f4498..e92aafcd23e4 100644 --- a/lib/galaxy/managers/users.py +++ b/lib/galaxy/managers/users.py @@ -608,6 +608,8 @@ def send_reset_email(self, trans, payload, **kwd): except Exception as e: log.debug(body) return f"Failed to submit email. Please contact the administrator: {util.unicodify(e)}" + if not reset_user: + log.warning(f"Failed to produce password reset token. User with email '{email}' not found.") return None def get_reset_token(self, trans, email): From 4ac6a1e4b40ebcf98886721f23dc5a05d4665d36 Mon Sep 17 00:00:00 2001 From: Nicola Soranzo Date: Mon, 8 Jul 2024 11:47:44 +0100 Subject: [PATCH 6/6] Handle all requests error in ``ApiBiotoolsMetadataSource._raw_get_metadata`` Fix the following traceback when running `planemo lint` if bio.tools is down: ``` File "/opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/site-packages/galaxy/tool\_util/biotools/source.py", line 69, in get\_biotools\_metadata return BiotoolsEntry.from\_json(json.loads(content)) ^^^^^^^^^^^^^^^^^^^ File "/opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/json/**init**.py", line 346, in loads return \_default\_decoder.decode(s) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/json/decoder.py", line 337, in decode obj, end = self.raw\_decode(s, idx=\_w(s, 0).end()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/json/decoder.py", line 355, in raw\_decode raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) ``` --- lib/galaxy/tool_util/biotools/source.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/galaxy/tool_util/biotools/source.py b/lib/galaxy/tool_util/biotools/source.py index 92c8b08a69b7..25838499aa55 100644 --- a/lib/galaxy/tool_util/biotools/source.py +++ b/lib/galaxy/tool_util/biotools/source.py @@ -54,12 +54,13 @@ def __init__(self, cache=None): def _raw_get_metadata(self, biotools_reference) -> Optional[str]: api_url = f"https://bio.tools/api/tool/{biotools_reference}?format=json" - req = requests.get(api_url, timeout=DEFAULT_SOCKET_TIMEOUT) - req.encoding = req.apparent_encoding - if req.status_code == 404: - return None - else: + try: + req = requests.get(api_url, timeout=DEFAULT_SOCKET_TIMEOUT) + req.raise_for_status() + req.encoding = req.apparent_encoding return req.text + except Exception: + return None def get_biotools_metadata(self, biotools_reference: str) -> Optional[BiotoolsEntry]: createfunc = functools.partial(self._raw_get_metadata, biotools_reference)