File 0001-Fixed-Multi-Factor-Authentication-bypass-vulnerability.patch of Package pgadmin4.34492

From f4761f55f7cf6d56d6c5129f921393b0b47fd976 Mon Sep 17 00:00:00 2001
From: Khushboo Vashi <khushboo.vashi@enterprisedb.com>
Date: Mon, 29 Apr 2024 13:41:02 +0530
Subject: [PATCH] Fixed Multi-Factor Authentication bypass vulnerability
 (CVE-2024-4215). #7425

---
 docs/en_US/release_notes_8_6.rst              |  5 +-
 web/pgadmin/about/__init__.py                 |  7 +-
 web/pgadmin/authenticate/__init__.py          | 14 ++--
 web/pgadmin/authenticate/kerberos.py          |  6 +-
 web/pgadmin/authenticate/mfa/utils.py         |  6 +-
 web/pgadmin/browser/__init__.py               | 17 ++--
 web/pgadmin/browser/server_groups/__init__.py | 25 +++---
 .../browser/server_groups/servers/__init__.py | 29 +++----
 web/pgadmin/dashboard/__init__.py             | 28 +++----
 web/pgadmin/misc/__init__.py                  |  6 +-
 web/pgadmin/misc/bgprocess/__init__.py        | 12 +--
 web/pgadmin/misc/cloud/__init__.py            | 17 ++--
 web/pgadmin/misc/cloud/azure/__init__.py      | 26 +++---
 web/pgadmin/misc/cloud/biganimal/__init__.py  | 22 +++---
 web/pgadmin/misc/cloud/google/__init__.py     | 20 ++---
 web/pgadmin/misc/cloud/rds/__init__.py        | 10 +--
 web/pgadmin/misc/file_manager/__init__.py     | 18 ++---
 web/pgadmin/preferences/__init__.py           | 12 +--
 web/pgadmin/redirects/__init__.py             |  4 +-
 web/pgadmin/settings/__init__.py              | 20 ++---
 web/pgadmin/tools/backup/__init__.py          | 13 +--
 web/pgadmin/tools/debugger/__init__.py        | 38 ++++-----
 web/pgadmin/tools/erd/__init__.py             | 12 +--
 web/pgadmin/tools/grant_wizard/__init__.py    | 14 ++--
 web/pgadmin/tools/import_export/__init__.py   | 13 +--
 .../tools/import_export_servers/__init__.py   | 13 +--
 web/pgadmin/tools/maintenance/__init__.py     | 11 +--
 web/pgadmin/tools/psql/__init__.py            |  7 +-
 web/pgadmin/tools/restore/__init__.py         | 11 +--
 web/pgadmin/tools/schema_diff/__init__.py     | 21 ++---
 web/pgadmin/tools/search_objects/__init__.py  |  8 +-
 web/pgadmin/tools/sqleditor/__init__.py       | 79 ++++++++++---------
 web/pgadmin/tools/sqleditor/utils/macros.py   |  3 +-
 web/pgadmin/tools/user_management/__init__.py |  9 ++-
 web/pgadmin/user_login_check.py               | 24 ++++++
 35 files changed, 309 insertions(+), 271 deletions(-)
 create mode 100644 web/pgadmin/user_login_check.py

#diff --git a/docs/en_US/release_notes_8_6.rst b/docs/en_US/release_notes_8_6.rst
#index a67ee22579a..ff67067bd0d 100644
#--- a/docs/en_US/release_notes_8_6.rst
#+++ b/docs/en_US/release_notes_8_6.rst
#@@ -35,10 +35,11 @@ Bug fixes
#   | `Issue #2410 <https://github.com/pgadmin-org/pgadmin4/issues/2410>`_ -  Fixed all input boxes in pgAdmin to show browser auto-fill only where it is relevant.
#   | `Issue #7173 <https://github.com/pgadmin-org/pgadmin4/issues/7173>`_ -  Install dbus-python, an in-direct dependency of the Keyring package as a system package for Debian platforms.
#   | `Issue #7275 <https://github.com/pgadmin-org/pgadmin4/issues/7275>`_ -  Fixed an issue where debugger was not scrolling automatically on stepping.
#-  | `Issue #7282 <https://github.com/pgadmin-org/pgadmin4/issues/7282>`_ -  Fixed an XSS vulnerability in the /settings/store endpoint.
#+  | `Issue #7282 <https://github.com/pgadmin-org/pgadmin4/issues/7282>`_ -  Fixed an XSS vulnerability in the /settings/store endpoint (CVE-2024-4216).
#   | `Issue #7294 <https://github.com/pgadmin-org/pgadmin4/issues/7294>`_ -  Fixed an issue where double dollar quoted code is treated as string in syntax highlighter.
#   | `Issue #7317 <https://github.com/pgadmin-org/pgadmin4/issues/7317>`_ -  Fixed an issue where pressing backspace should remove the spaces and not the entire tab width, on enabling 'Use spaces?' in the preferences.
#   | `Issue #7334 <https://github.com/pgadmin-org/pgadmin4/issues/7334>`_ -  Fixed an issue where incorrect select/exec scripts were generated for functions/procedures.
#   | `Issue #7372 <https://github.com/pgadmin-org/pgadmin4/issues/7372>`_ -  Fixed an issue where connection to the database is not automatically re-established after connectivity drop.
#   | `Issue #7384 <https://github.com/pgadmin-org/pgadmin4/issues/7384>`_ -  Fixed an issue when closing the view data second tab; it raises the error that the 'ViewCommand' object has no attribute 'auto_commit'.
#-  | `Issue #7390 <https://github.com/pgadmin-org/pgadmin4/issues/7390>`_ -  Fixed violates check constraint issue when creating a pgAgent schedule.
#\ No newline at end of file
#+  | `Issue #7390 <https://github.com/pgadmin-org/pgadmin4/issues/7390>`_ -  Fixed violates check constraint issue when creating a pgAgent schedule.
#+  | `Issue #7425 <https://github.com/pgadmin-org/pgadmin4/issues/7425>`_ -  Fixed Multi-Factor Authentication bypass vulnerability (CVE-2024-4215).
#\ No newline at end of file
diff --git a/web/pgadmin/about/__init__.py b/web/pgadmin/about/__init__.py
index 628e245c9e4..4739922a5d2 100644
--- a/web/pgadmin/about/__init__.py
+++ b/web/pgadmin/about/__init__.py
@@ -11,7 +11,8 @@
 
 from flask import Response, render_template, request
 from flask_babel import gettext
-from flask_security import current_user, login_required
+from flask_security import current_user
+from pgadmin.user_login_check import pga_login_required
 from pgadmin.utils import PgAdminModule
 from pgadmin.utils.menu import MenuItem
 from pgadmin.utils.constants import MIMETYPE_APP_JS
@@ -53,7 +54,7 @@ def get_exposed_url_endpoints(self):
 # A test page
 ##########################################################################
 @blueprint.route("/", endpoint='index')
-@login_required
+@pga_login_required
 def index():
     """Render the about box."""
     info = {}
@@ -138,7 +139,7 @@ def detect_browser(request):
 
 
 @blueprint.route("/about.js")
-@login_required
+@pga_login_required
 def script():
     """render the required javascript"""
     return Response(
diff --git a/web/pgadmin/authenticate/__init__.py b/web/pgadmin/authenticate/__init__.py
index 54a49597bf1..cd76bf30911 100644
--- a/web/pgadmin/authenticate/__init__.py
+++ b/web/pgadmin/authenticate/__init__.py
@@ -23,12 +23,10 @@
 from flask_login import current_user
 from flask_socketio import disconnect, ConnectionRefusedError
 
-
 from pgadmin.model import db, User
-from pgadmin.utils import PgAdminModule, get_safe_post_login_redirect, \
-    get_safe_post_logout_redirect
 from pgadmin.utils.constants import KERBEROS, INTERNAL, OAUTH2, LDAP,\
     MessageType
+import pgadmin.utils as pga_utils
 from pgadmin.authenticate.registry import AuthSourceRegistry
 
 MODULE_NAME = 'authenticate'
@@ -84,7 +82,7 @@ def wrapped(*args, **kwargs):
     return wrapped
 
 
-class AuthenticateModule(PgAdminModule):
+class AuthenticateModule(pga_utils.PgAdminModule):
     def get_exposed_url_endpoints(self):
         return ['authenticate.login']
 
@@ -135,7 +133,7 @@ def _login():
                           'Administrator.'),
                   MessageType.WARNING)
             logout_user()
-            return redirect(get_safe_post_logout_redirect())
+            return redirect(pga_utils.get_safe_post_logout_redirect())
 
     # Validate the user
     if not auth_obj.validate():
@@ -161,7 +159,7 @@ def _login():
                     flash_login_attempt_error = None
                 flash(error, MessageType.WARNING)
 
-        return redirect(get_safe_post_logout_redirect())
+        return redirect(pga_utils.get_safe_post_logout_redirect())
 
     # Authenticate the user
     status, msg = auth_obj.authenticate()
@@ -177,7 +175,7 @@ def _login():
                     'authenticate.kerberos_login'), url_for('browser.index')))
 
             flash(msg, MessageType.ERROR)
-            return redirect(get_safe_post_logout_redirect())
+            return redirect(pga_utils.get_safe_post_logout_redirect())
 
         session['auth_source_manager'] = current_auth_obj
 
@@ -187,7 +185,7 @@ def _login():
 
         if 'auth_obj' in session:
             session.pop('auth_obj')
-        return redirect(get_safe_post_login_redirect())
+        return redirect(pga_utils.get_safe_post_login_redirect())
 
     elif isinstance(msg, Response):
         return msg
diff --git a/web/pgadmin/authenticate/kerberos.py b/web/pgadmin/authenticate/kerberos.py
index a41a368ea0b..d8ebf6e663e 100644
--- a/web/pgadmin/authenticate/kerberos.py
+++ b/web/pgadmin/authenticate/kerberos.py
@@ -18,7 +18,7 @@
     current_app, render_template, flash, url_for
 from flask_security.views import _security
 from flask_security.utils import logout_user
-from flask_security import login_required
+from pgadmin.user_login_check import pga_login_required
 
 import config
 from pgadmin.model import User
@@ -97,7 +97,7 @@ def kerberos_logout():
     @blueprint.route("/update_ticket",
                      endpoint="update_ticket", methods=["GET"])
     @pgCSRFProtect.exempt
-    @login_required
+    @pga_login_required
     def kerberos_update_ticket():
         """
         Update the kerberos ticket.
@@ -127,7 +127,7 @@ def kerberos_update_ticket():
     @blueprint.route("/validate_ticket",
                      endpoint="validate_ticket", methods=["GET"])
     @pgCSRFProtect.exempt
-    @login_required
+    @pga_login_required
     def kerberos_validate_ticket():
         """
         Return the kerberos ticket lifetime left after getting the
diff --git a/web/pgadmin/authenticate/mfa/utils.py b/web/pgadmin/authenticate/mfa/utils.py
index 64cbd9e244c..460a24486f8 100644
--- a/web/pgadmin/authenticate/mfa/utils.py
+++ b/web/pgadmin/authenticate/mfa/utils.py
@@ -13,7 +13,7 @@
 
 from flask import url_for, session, request, redirect
 from flask_login.utils import login_url
-from flask_security import current_user
+from flask_security import current_user, login_required
 
 import config
 from pgadmin.model import UserMFA, db
@@ -279,7 +279,7 @@ def get_next_url():
         registration_url = url_for('mfa.register')
 
         if next_url.startswith(registration_url):
-            return url('browser.index')
+            return url_for('browser.index')
 
         return next_url
 
@@ -290,8 +290,8 @@ def redirect_to_mfa_registration():
         return redirect(login_url("mfa.register", next_url=get_next_url()))
 
     @wraps(wrapped)
+    @login_required
     def inner(*args, **kwargs):
-
         def execute_func():
             session['mfa_authenticated'] = True
             return wrapped(*args, **kwargs)
diff --git a/web/pgadmin/browser/__init__.py b/web/pgadmin/browser/__init__.py
index 017a791b87c..a2feedb53e8 100644
--- a/web/pgadmin/browser/__init__.py
+++ b/web/pgadmin/browser/__init__.py
@@ -28,7 +28,7 @@
     flash, Response, request, after_this_request, redirect, session
 from flask_babel import gettext
 from flask_gravatar import Gravatar
-from flask_login import current_user, login_required
+from flask_login import current_user
 from flask_login.utils import login_url
 from flask_security.changeable import send_password_changed_notice
 from flask_security.decorators import anonymous_user_required
@@ -64,6 +64,8 @@
 from pgadmin.authenticate import AuthSourceManager
 from pgadmin.utils.exception import CryptKeyMissing
 
+from pgadmin.user_login_check import pga_login_required
+
 try:
     from flask_security.views import default_render_json
 except ImportError as e:
@@ -377,8 +379,7 @@ def gravatar(username):
 
 @blueprint.route("/")
 @pgCSRFProtect.exempt
-@login_required
-@mfa_required
+@pga_login_required
 def index():
     """Render and process the main browser window."""
     # Register Gravatar module with the app only if required
@@ -471,7 +472,7 @@ def get_shared_storage_list():
 
 @blueprint.route("/js/utils.js")
 @pgCSRFProtect.exempt
-@login_required
+@pga_login_required
 def utils():
     layout = get_setting('Browser/Layout', default='')
     snippets = []
@@ -592,7 +593,7 @@ def exposed_urls():
 
 @blueprint.route("/js/error.js")
 @pgCSRFProtect.exempt
-@login_required
+@pga_login_required
 def error_js():
     return make_response(
         render_template('browser/js/error.js', _=gettext),
@@ -609,7 +610,7 @@ def messages_js():
 
 @blueprint.route("/browser.css")
 @pgCSRFProtect.exempt
-@login_required
+@pga_login_required
 def browser_css():
     """Render and return CSS snippets from the nodes and modules."""
     snippets = []
@@ -625,7 +625,7 @@ def browser_css():
 
 
 @blueprint.route("/nodes/", endpoint="nodes")
-@login_required
+@pga_login_required
 def get_nodes():
     """Build a list of treeview nodes from the child nodes."""
     nodes = []
@@ -931,7 +932,7 @@ def set_master_password():
     @blueprint.route("/change_password", endpoint="change_password",
                      methods=['GET', 'POST'])
     @pgCSRFProtect.exempt
-    @login_required
+    @pga_login_required
     def change_password():
         """View function which handles a change password request."""
 
diff --git a/web/pgadmin/browser/server_groups/__init__.py b/web/pgadmin/browser/server_groups/__init__.py
index 0a26f18cf3c..71799bab791 100644
--- a/web/pgadmin/browser/server_groups/__init__.py
+++ b/web/pgadmin/browser/server_groups/__init__.py
@@ -14,7 +14,8 @@
 
 from flask import request, jsonify, render_template
 from flask_babel import gettext
-from flask_security import current_user, login_required
+from flask_security import current_user
+from pgadmin.user_login_check import pga_login_required
 from pgadmin.browser import BrowserPluginModule
 from pgadmin.browser.utils import NodeView
 from pgadmin.utils.ajax import make_json_response, gone, \
@@ -162,7 +163,7 @@ class ServerGroupView(NodeView):
     parent_ids = []
     ids = [{'type': 'int', 'id': 'gid'}]
 
-    @login_required
+    @pga_login_required
     def list(self):
         res = []
 
@@ -176,7 +177,7 @@ def list(self):
 
         return ajax_response(response=res, status=200)
 
-    @login_required
+    @pga_login_required
     def delete(self, gid):
         """Delete a server group node in the settings database"""
 
@@ -232,7 +233,7 @@ def delete(self, gid):
 
         return make_json_response(result=request.form)
 
-    @login_required
+    @pga_login_required
     def update(self, gid):
         """Update the server-group properties"""
 
@@ -281,7 +282,7 @@ def update(self, gid):
             )
         )
 
-    @login_required
+    @pga_login_required
     def properties(self, gid):
         """Update the server-group properties"""
 
@@ -299,7 +300,7 @@ def properties(self, gid):
                 status=200
             )
 
-    @login_required
+    @pga_login_required
     def create(self):
         """Creates new server-group """
         data = request.form if request.form else json.loads(
@@ -349,23 +350,23 @@ def create(self):
                 success=0,
                 errormsg=gettext('No server group name was specified'))
 
-    @login_required
+    @pga_login_required
     def sql(self, gid):
         return make_json_response(status=422)
 
-    @login_required
+    @pga_login_required
     def modified_sql(self, gid):
         return make_json_response(status=422)
 
-    @login_required
+    @pga_login_required
     def statistics(self, gid):
         return make_json_response(status=422)
 
-    @login_required
+    @pga_login_required
     def dependencies(self, gid):
         return make_json_response(status=422)
 
-    @login_required
+    @pga_login_required
     def dependents(self, gid):
         return make_json_response(status=422)
 
@@ -394,7 +395,7 @@ def get_all_server_groups():
                 groups.append(group)
         return groups
 
-    @login_required
+    @pga_login_required
     def nodes(self, gid=None):
         """Return a JSON document listing the server groups for the user"""
         nodes = []
diff --git a/web/pgadmin/browser/server_groups/servers/__init__.py b/web/pgadmin/browser/server_groups/servers/__init__.py
index 05c93a89dc0..9e65e244866 100644
--- a/web/pgadmin/browser/server_groups/servers/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/__init__.py
@@ -13,7 +13,8 @@
 from flask import render_template, request, make_response, jsonify, \
     current_app, url_for, session
 from flask_babel import gettext
-from flask_security import current_user, login_required
+from flask_security import current_user
+from pgadmin.user_login_check import pga_login_required
 from psycopg.conninfo import make_conninfo, conninfo_to_dict
 
 from pgadmin.browser.server_groups.servers.types import ServerType
@@ -218,7 +219,7 @@ def get_servers(self, all_servers, hide_shared_server, gid):
 
         return servers
 
-    @login_required
+    @pga_login_required
     def get_nodes(self, gid):
         """Return a JSON document listing the server groups for the user"""
 
@@ -564,7 +565,7 @@ def update_connection_parameter(self, data, server):
 
             data['connection_params'] = existing_conn_params
 
-    @login_required
+    @pga_login_required
     def nodes(self, gid):
         res = []
         """
@@ -650,7 +651,7 @@ def nodes(self, gid):
 
         return make_json_response(result=res)
 
-    @login_required
+    @pga_login_required
     def node(self, gid, sid):
         """Return a JSON document listing the server groups for the user"""
         server = Server.query.filter_by(id=sid).first()
@@ -733,7 +734,7 @@ def delete_shared_server(self, server_name, gid, osid):
                 success=0,
                 errormsg=e.message)
 
-    @login_required
+    @pga_login_required
     def delete(self, gid, sid):
         """Delete a server node in the settings database."""
         servers = Server.query.filter_by(user_id=current_user.id, id=sid)
@@ -783,7 +784,7 @@ def delete(self, gid, sid):
         return make_json_response(success=1,
                                   info=gettext("Server deleted"))
 
-    @login_required
+    @pga_login_required
     def update(self, gid, sid):
         """Update the server settings"""
         server = Server.query.filter_by(id=sid).first()
@@ -988,7 +989,7 @@ def _server_modify_disallowed_when_connected(
                         ).format(disp_lbl[arg])
                     )
 
-    @login_required
+    @pga_login_required
     def list(self, gid):
         """
         Return list of attributes of all servers.
@@ -1035,7 +1036,7 @@ def list(self, gid):
             response=res
         )
 
-    @login_required
+    @pga_login_required
     def properties(self, gid, sid):
         """Return list of attributes of a server"""
 
@@ -1154,7 +1155,7 @@ def update_connection_string(manager, server):
         display_conn_string = make_conninfo(**con_info_ord)
         return display_conn_string
 
-    @login_required
+    @pga_login_required
     def create(self, gid):
         """Add a server node to the settings database"""
         required_args = ['name', 'db']
@@ -1376,15 +1377,15 @@ def create(self, gid):
                 errormsg=str(e)
             )
 
-    @login_required
+    @pga_login_required
     def sql(self, gid, sid):
         return make_json_response(data='')
 
-    @login_required
+    @pga_login_required
     def modified_sql(self, gid, sid):
         return make_json_response(data='')
 
-    @login_required
+    @pga_login_required
     def statistics(self, gid, sid):
         manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
         conn = manager.connection()
@@ -1408,11 +1409,11 @@ def statistics(self, gid, sid):
             )
         )
 
-    @login_required
+    @pga_login_required
     def dependencies(self, gid, sid):
         return make_json_response(data='')
 
-    @login_required
+    @pga_login_required
     def dependents(self, gid, sid):
         return make_json_response(data='')
 
diff --git a/web/pgadmin/dashboard/__init__.py b/web/pgadmin/dashboard/__init__.py
index 2cf92ae72bf..c5e3fdf7fa0 100644
--- a/web/pgadmin/dashboard/__init__.py
+++ b/web/pgadmin/dashboard/__init__.py
@@ -12,7 +12,7 @@
 from functools import wraps
 from flask import render_template, url_for, Response, g, request
 from flask_babel import gettext
-from flask_security import login_required
+from pgadmin.user_login_check import pga_login_required
 import json
 from pgadmin.utils import PgAdminModule
 from pgadmin.utils.ajax import make_response as ajax_response,\
@@ -314,7 +314,7 @@ def get_error(i_node_type):
 
 
 @blueprint.route("/dashboard.js")
-@login_required
+@pga_login_required
 def script():
     """render the required javascript"""
     return Response(
@@ -330,7 +330,7 @@ def script():
 @blueprint.route('/', endpoint='index')
 @blueprint.route('/<int:sid>', endpoint='get_by_sever_id')
 @blueprint.route('/<int:sid>/<int:did>', endpoint='get_by_database_id')
-@login_required
+@pga_login_required
 def index(sid=None, did=None):
     """
     Renders the welcome, server or database dashboard
@@ -446,7 +446,7 @@ def get_long_running_query_status(activities):
                  endpoint='dashboard_stats_sid')
 @blueprint.route('/dashboard_stats/<int:sid>/<int:did>',
                  endpoint='dashboard_stats_did')
-@login_required
+@pga_login_required
 @check_precondition
 def dashboard_stats(sid=None, did=None):
     resp_data = {}
@@ -478,7 +478,7 @@ def dashboard_stats(sid=None, did=None):
 @blueprint.route(
     '/activity/<int:sid>/<int:did>', endpoint='get_activity_by_database_id'
 )
-@login_required
+@pga_login_required
 @check_precondition
 def activity(sid=None, did=None):
     """
@@ -494,7 +494,7 @@ def activity(sid=None, did=None):
 @blueprint.route(
     '/locks/<int:sid>/<int:did>', endpoint='get_locks_by_database_id'
 )
-@login_required
+@pga_login_required
 @check_precondition
 def locks(sid=None, did=None):
     """
@@ -510,7 +510,7 @@ def locks(sid=None, did=None):
 @blueprint.route(
     '/prepared/<int:sid>/<int:did>', endpoint='get_prepared_by_database_id'
 )
-@login_required
+@pga_login_required
 @check_precondition
 def prepared(sid=None, did=None):
     """
@@ -523,7 +523,7 @@ def prepared(sid=None, did=None):
 
 @blueprint.route('/config/', endpoint='config')
 @blueprint.route('/config/<int:sid>', endpoint='get_config_by_server_id')
-@login_required
+@pga_login_required
 @check_precondition
 def config(sid=None):
     """
@@ -540,7 +540,7 @@ def config(sid=None):
 @blueprint.route(
     '/cancel_query/<int:sid>/<int:did>/<int:pid>', methods=['DELETE']
 )
-@login_required
+@pga_login_required
 @check_precondition
 def cancel_query(sid=None, did=None, pid=None):
     """
@@ -567,7 +567,7 @@ def cancel_query(sid=None, did=None, pid=None):
 @blueprint.route(
     '/terminate_session/<int:sid>/<int:did>/<int:pid>', methods=['DELETE']
 )
-@login_required
+@pga_login_required
 @check_precondition
 def terminate_session(sid=None, did=None, pid=None):
     """
@@ -595,7 +595,7 @@ def terminate_session(sid=None, did=None, pid=None):
                  endpoint='check_system_statistics_sid', methods=['GET'])
 @blueprint.route('check_extension/system_statistics/<int:sid>/<int:did>',
                  endpoint='check_system_statistics_did', methods=['GET'])
-@login_required
+@pga_login_required
 @check_precondition
 def check_system_statistics(sid=None, did=None):
     sql = "SELECT * FROM pg_extension WHERE extname = 'system_stats';"
@@ -620,7 +620,7 @@ def check_system_statistics(sid=None, did=None):
                  endpoint='system_statistics_sid', methods=['GET'])
 @blueprint.route('/system_statistics/<int:sid>/<int:did>',
                  endpoint='system_statistics_did', methods=['GET'])
-@login_required
+@pga_login_required
 @check_precondition
 def system_statistics(sid=None, did=None):
     resp_data = {}
@@ -652,7 +652,7 @@ def system_statistics(sid=None, did=None):
 
 @blueprint.route('/replication_stats/<int:sid>',
                  endpoint='replication_stats', methods=['GET'])
-@login_required
+@pga_login_required
 @check_precondition
 def replication_stats(sid=None):
     """
@@ -676,7 +676,7 @@ def replication_stats(sid=None):
 
 @blueprint.route('/replication_slots/<int:sid>',
                  endpoint='replication_slots', methods=['GET'])
-@login_required
+@pga_login_required
 @check_precondition
 def replication_slots(sid=None):
     """
diff --git a/web/pgadmin/misc/__init__.py b/web/pgadmin/misc/__init__.py
index 8718b3e9267..b8c01a64578 100644
--- a/web/pgadmin/misc/__init__.py
+++ b/web/pgadmin/misc/__init__.py
@@ -13,7 +13,7 @@
 from flask import render_template, Response, request, current_app
 from flask.helpers import url_for
 from flask_babel import gettext
-from flask_security import login_required
+from pgadmin.user_login_check import pga_login_required
 from pathlib import Path
 from pgadmin.utils import PgAdminModule, replace_binary_path, \
     get_binary_path_versions
@@ -221,7 +221,7 @@ def shutdown():
 @blueprint.route("/validate_binary_path",
                  endpoint="validate_binary_path",
                  methods=["POST"])
-@login_required
+@pga_login_required
 def validate_binary_path():
     """
     This function is used to validate the specified utilities path by
@@ -255,7 +255,7 @@ def validate_binary_path():
 
 @blueprint.route("/upgrade_check", endpoint="upgrade_check",
                  methods=['GET'])
-@login_required
+@pga_login_required
 def upgrade_check():
     # Get the current version info from the website, and flash a message if
     # the user is out of date, and the check is enabled.
diff --git a/web/pgadmin/misc/bgprocess/__init__.py b/web/pgadmin/misc/bgprocess/__init__.py
index adc3b766129..b30114c5b5a 100644
--- a/web/pgadmin/misc/bgprocess/__init__.py
+++ b/web/pgadmin/misc/bgprocess/__init__.py
@@ -12,7 +12,7 @@
 the long running background-processes.
 """
 from flask import url_for
-from flask_security import login_required
+from pgadmin.user_login_check import pga_login_required
 from pgadmin.utils import PgAdminModule
 from pgadmin.utils.ajax import make_response, gone, success_return,\
     make_json_response
@@ -43,7 +43,7 @@ def get_exposed_url_endpoints(self):
 
 
 @blueprint.route('/', methods=['GET'], endpoint='list')
-@login_required
+@pga_login_required
 def index():
     return make_response(response=BatchProcess.list())
 
@@ -52,7 +52,7 @@ def index():
 @blueprint.route(
     '/<pid>/<int:out>/<int:err>/', methods=['GET'], endpoint='detailed_status'
 )
-@login_required
+@pga_login_required
 def status(pid, out=-1, err=-1):
     """
     Check the status of the process running in background.
@@ -76,7 +76,7 @@ def status(pid, out=-1, err=-1):
 
 
 @blueprint.route('/<pid>', methods=['PUT'], endpoint='acknowledge')
-@login_required
+@pga_login_required
 def acknowledge(pid):
     """
     User has acknowledge the process
@@ -96,7 +96,7 @@ def acknowledge(pid):
 
 @blueprint.route('/update_cloud_details/<pid>', methods=['PUT'],
                  endpoint='update_cloud_details')
-@login_required
+@pga_login_required
 def update_cloud_details(pid):
     """
     Update the cloud details and get instance details
@@ -133,7 +133,7 @@ def update_cloud_details(pid):
 
 
 @blueprint.route('/stop/<pid>', methods=['PUT'], endpoint='stop_process')
-@login_required
+@pga_login_required
 def stop_process(pid):
     """
     User has stopped the process
diff --git a/web/pgadmin/misc/cloud/__init__.py b/web/pgadmin/misc/cloud/__init__.py
index bc5a93fb4ab..bbbaaf24d73 100644
--- a/web/pgadmin/misc/cloud/__init__.py
+++ b/web/pgadmin/misc/cloud/__init__.py
@@ -13,7 +13,8 @@
 from flask import Response, url_for
 from flask import render_template, request
 from flask_babel import gettext
-from flask_security import login_required, current_user
+from flask_security import current_user
+from pgadmin.user_login_check import pga_login_required
 
 from pgadmin.utils import PgAdminModule, html
 from pgadmin.utils.ajax import make_json_response,\
@@ -81,7 +82,7 @@ def register(self, app, options):
 
 
 @blueprint.route("/")
-@login_required
+@pga_login_required
 def index():
     return bad_request(
         errormsg=gettext("This URL cannot be called directly.")
@@ -89,7 +90,7 @@ def index():
 
 
 @blueprint.route("/cloud.js")
-@login_required
+@pga_login_required
 def script():
     """render own javascript"""
     res = Response(response=render_template(
@@ -101,7 +102,7 @@ def script():
 
 @blueprint.route('/clear_cloud_session/',
                  methods=['POST'], endpoint='clear_cloud_session')
-@login_required
+@pga_login_required
 def clear_session():
     """Get host IP Address"""
     clear_cloud_session()
@@ -110,7 +111,7 @@ def clear_session():
 
 @blueprint.route('/get_host_ip/',
                  methods=['GET'], endpoint='get_host_ip')
-@login_required
+@pga_login_required
 def get_host_ip():
     """Get host IP Address"""
     ip = get_my_ip()
@@ -120,7 +121,7 @@ def get_host_ip():
 @blueprint.route(
     '/deploy', methods=['POST'], endpoint='deploy_on_cloud'
 )
-@login_required
+@pga_login_required
 def deploy_on_cloud():
     """Deploy on Cloud."""
 
@@ -219,7 +220,7 @@ def clear_cloud_session(pid=None):
     '/update_cloud_process/<sid>', methods=['GET'],
     endpoint='update_cloud_process'
 )
-@login_required
+@pga_login_required
 def update_cloud_process(sid):
     """Update Cloud Server Process"""
     _process = Process.query.filter_by(user_id=current_user.id,
@@ -233,7 +234,7 @@ def update_cloud_process(sid):
     '/update_cloud_server', methods=['POST'],
     endpoint='update_cloud_server'
 )
-@login_required
+@pga_login_required
 def update_cloud_server():
     """Update Cloud Server."""
     server_data = json.loads(request.data)
diff --git a/web/pgadmin/misc/cloud/azure/__init__.py b/web/pgadmin/misc/cloud/azure/__init__.py
index de4a39b36c2..d24607e4cad 100644
--- a/web/pgadmin/misc/cloud/azure/__init__.py
+++ b/web/pgadmin/misc/cloud/azure/__init__.py
@@ -14,7 +14,7 @@
 from pgadmin.misc.bgprocess.processes import BatchProcess
 from pgadmin import make_json_response
 from pgadmin.utils import PgAdminModule
-from flask_security import login_required
+from pgadmin.user_login_check import pga_login_required
 import json
 from flask import session, current_app, request
 from flask_login import current_user
@@ -59,7 +59,7 @@ def get_exposed_url_endpoints(self):
 
 @blueprint.route('/verify_credentials/',
                  methods=['POST'], endpoint='verify_credentials')
-@login_required
+@pga_login_required
 def verify_credentials():
     """Verify Credentials."""
     data = json.loads(request.data)
@@ -96,7 +96,7 @@ def verify_credentials():
 
 @blueprint.route('/get_azure_verification_codes/',
                  methods=['GET'], endpoint='get_azure_verification_codes')
-@login_required
+@pga_login_required
 def get_azure_verification_codes():
     """Get azure code for authentication."""
     azure_auth_code = None
@@ -110,7 +110,7 @@ def get_azure_verification_codes():
 
 @blueprint.route('/check_cluster_name_availability/',
                  methods=['GET'], endpoint='check_cluster_name_availability')
-@login_required
+@pga_login_required
 def check_cluster_name_availability():
     """Check Server Name availability."""
     data = request.args
@@ -129,7 +129,7 @@ def check_cluster_name_availability():
 
 @blueprint.route('/subscriptions/',
                  methods=['GET'], endpoint='subscriptions')
-@login_required
+@pga_login_required
 def get_azure_subscriptions():
     """
     List subscriptions.
@@ -142,7 +142,7 @@ def get_azure_subscriptions():
 
 @blueprint.route('/resource_groups/<subscription_id>',
                  methods=['GET'], endpoint='resource_groups')
-@login_required
+@pga_login_required
 def get_azure_resource_groups(subscription_id):
     """
     Fetch resource groups based on subscription.
@@ -156,7 +156,7 @@ def get_azure_resource_groups(subscription_id):
 
 @blueprint.route('/regions/<subscription_id>',
                  methods=['GET'], endpoint='regions')
-@login_required
+@pga_login_required
 def get_azure_regions(subscription_id):
     """List Regions for Azure."""
     if not subscription_id:
@@ -169,7 +169,7 @@ def get_azure_regions(subscription_id):
 
 @blueprint.route('/zone_redundant_ha_supported/<region_name>',
                  methods=['GET'], endpoint='zone_redundant_ha_supported')
-@login_required
+@pga_login_required
 def is_ha_supported(region_name):
     """Check high availability support in given region."""
     azure = session['azure']['azure_obj']
@@ -181,7 +181,7 @@ def is_ha_supported(region_name):
 
 @blueprint.route('/availability_zones/<region_name>',
                  methods=['GET'], endpoint='availability_zones')
-@login_required
+@pga_login_required
 def get_azure_availability_zones(region_name):
     """List availability zones in given region."""
     if not region_name:
@@ -194,7 +194,7 @@ def get_azure_availability_zones(region_name):
 
 @blueprint.route('/db_versions/<availability_zone>',
                  methods=['GET'], endpoint='db_versions')
-@login_required
+@pga_login_required
 def get_azure_postgresql_server_versions(availability_zone):
     """Get azure postgres database versions."""
     if not availability_zone:
@@ -208,7 +208,7 @@ def get_azure_postgresql_server_versions(availability_zone):
 
 @blueprint.route('/instance_types/<availability_zone>/<db_version>',
                  methods=['GET'], endpoint='instance_types')
-@login_required
+@pga_login_required
 def get_azure_instance_types(availability_zone, db_version):
     """Get instance types for Azure."""
     if not db_version:
@@ -220,7 +220,7 @@ def get_azure_instance_types(availability_zone, db_version):
 
 @blueprint.route('/storage_types/<availability_zone>/<db_version>',
                  methods=['GET'], endpoint='storage_types')
-@login_required
+@pga_login_required
 def list_azure_storage_types(availability_zone, db_version):
     """Get the storage types supported."""
     if not db_version:
@@ -232,7 +232,7 @@ def list_azure_storage_types(availability_zone, db_version):
 
 @blueprint.route('/clear_session',
                  methods=['GET'], endpoint='clear_session')
-@login_required
+@pga_login_required
 def clear_session():
     clear_azure_session()
     return make_json_response(success=1)
diff --git a/web/pgadmin/misc/cloud/biganimal/__init__.py b/web/pgadmin/misc/cloud/biganimal/__init__.py
index a99ed59d6db..325cc492281 100644
--- a/web/pgadmin/misc/cloud/biganimal/__init__.py
+++ b/web/pgadmin/misc/cloud/biganimal/__init__.py
@@ -14,7 +14,7 @@
 import pickle
 from flask_babel import gettext
 from flask import session, current_app
-from flask_security import login_required
+from pgadmin.user_login_check import pga_login_required
 from werkzeug.datastructures import Headers
 from pgadmin.utils import PgAdminModule
 from pgadmin.misc.cloud.utils import _create_server, CloudProcessDesc
@@ -52,7 +52,7 @@ def get_exposed_url_endpoints(self):
 
 @blueprint.route('/verification_ack/',
                  methods=['GET'], endpoint='verification_ack')
-@login_required
+@pga_login_required
 def biganimal_verification_ack():
     """Check the Verification is done or not."""
     biganimal_obj = pickle.loads(session['biganimal']['provider_obj'])
@@ -65,7 +65,7 @@ def biganimal_verification_ack():
 
 @blueprint.route('/verification/',
                  methods=['GET'], endpoint='verification')
-@login_required
+@pga_login_required
 def verification():
     """Verify Credentials."""
     biganimal = BigAnimalProvider()
@@ -78,7 +78,7 @@ def verification():
 
 @blueprint.route('/projects/',
                  methods=['GET'], endpoint='projects')
-@login_required
+@pga_login_required
 def biganimal_projects():
     """Get Providers."""
     biganimal_obj = pickle.loads(session['biganimal']['provider_obj'])
@@ -88,7 +88,7 @@ def biganimal_projects():
 
 @blueprint.route('/providers/<project_id>',
                  methods=['GET'], endpoint='providers')
-@login_required
+@pga_login_required
 def biganimal_providers(project_id):
     """Get Providers."""
     biganimal_obj = pickle.loads(session['biganimal']['provider_obj'])
@@ -99,7 +99,7 @@ def biganimal_providers(project_id):
 
 @blueprint.route('/regions/',
                  methods=['GET'], endpoint='regions')
-@login_required
+@pga_login_required
 def biganimal_regions():
     """Get Regions."""
     biganimal_obj = pickle.loads(session['biganimal']['provider_obj'])
@@ -110,7 +110,7 @@ def biganimal_regions():
 
 @blueprint.route('/db_types/',
                  methods=['GET'], endpoint='db_types')
-@login_required
+@pga_login_required
 def biganimal_db_types():
     """Get Database Types."""
     biganimal_obj = pickle.loads(session['biganimal']['provider_obj'])
@@ -120,7 +120,7 @@ def biganimal_db_types():
 
 @blueprint.route('/db_versions/<cluster_type>/<pg_type>',
                  methods=['GET'], endpoint='db_versions')
-@login_required
+@pga_login_required
 def biganimal_db_versions(cluster_type, pg_type):
     """Get Database Version."""
     biganimal_obj = pickle.loads(session['biganimal']['provider_obj'])
@@ -130,7 +130,7 @@ def biganimal_db_versions(cluster_type, pg_type):
 
 @blueprint.route('/instance_types/<region_id>/<provider_id>',
                  methods=['GET'], endpoint='instance_types')
-@login_required
+@pga_login_required
 def biganimal_instance_types(region_id, provider_id):
     """Get Instance Types."""
     if not region_id or not provider_id:
@@ -143,7 +143,7 @@ def biganimal_instance_types(region_id, provider_id):
 
 @blueprint.route('/volume_types/<region_id>/<provider_id>',
                  methods=['GET'], endpoint='volume_types')
-@login_required
+@pga_login_required
 def biganimal_volume_types(region_id, provider_id):
     """Get Volume Types."""
     if not region_id or not provider_id:
@@ -155,7 +155,7 @@ def biganimal_volume_types(region_id, provider_id):
 
 @blueprint.route('/volume_properties/<region_id>/<provider_id>/<volume_type>',
                  methods=['GET'], endpoint='volume_properties')
-@login_required
+@pga_login_required
 def biganimal_volume_properties(region_id, provider_id, volume_type):
     """Get Volume Properties."""
     if not region_id or not provider_id:
diff --git a/web/pgadmin/misc/cloud/google/__init__.py b/web/pgadmin/misc/cloud/google/__init__.py
index 2ddb25a99e2..1b7a40d6c9b 100644
--- a/web/pgadmin/misc/cloud/google/__init__.py
+++ b/web/pgadmin/misc/cloud/google/__init__.py
@@ -20,7 +20,7 @@
 from pgadmin.misc.bgprocess import BatchProcess
 from pgadmin.misc.cloud.utils import _create_server, CloudProcessDesc
 from pgadmin.utils import PgAdminModule, filename_with_file_manager_path
-from flask_security import login_required
+from pgadmin.user_login_check import pga_login_required
 from flask import session, current_app, request
 from flask_babel import gettext as _
 
@@ -53,14 +53,14 @@ def get_exposed_url_endpoints(self):
 
 
 @blueprint.route("/")
-@login_required
+@pga_login_required
 def index():
     return bad_request(errormsg=_("This URL cannot be called directly."))
 
 
 @blueprint.route('/verify_credentials/',
                  methods=['POST'], endpoint='verify_credentials')
-@login_required
+@pga_login_required
 def verify_credentials():
     """
     Initiate process of authorisation for google oauth2
@@ -118,7 +118,7 @@ def verify_credentials():
 @blueprint.route('/callback',
                  methods=['GET'], endpoint='callback')
 @pgCSRFProtect.exempt
-@login_required
+@pga_login_required
 def callback():
     """
     Call back function on google authentication response.
@@ -132,7 +132,7 @@ def callback():
 
 @blueprint.route('/verification_ack',
                  methods=['GET'], endpoint='verification_ack')
-@login_required
+@pga_login_required
 def verification_ack():
     """
     Checks for google oauth2 authorisation confirmation
@@ -151,7 +151,7 @@ def verification_ack():
 
 @blueprint.route('/projects/',
                  methods=['GET'], endpoint='projects')
-@login_required
+@pga_login_required
 def get_projects():
     """
     Lists the projects for authorized user
@@ -165,7 +165,7 @@ def get_projects():
 
 @blueprint.route('/regions/<project_id>',
                  methods=['GET'], endpoint='regions')
-@login_required
+@pga_login_required
 def get_regions(project_id):
     """
     Lists regions based on project for authorized user
@@ -184,7 +184,7 @@ def get_regions(project_id):
 
 @blueprint.route('/availability_zones/<region>',
                  methods=['GET'], endpoint='availability_zones')
-@login_required
+@pga_login_required
 def get_availability_zones(region):
     """
     List availability zones for specified region
@@ -201,7 +201,7 @@ def get_availability_zones(region):
 
 @blueprint.route('/instance_types/<project_id>/<region>/<instance_class>',
                  methods=['GET'], endpoint='instance_types')
-@login_required
+@pga_login_required
 def get_instance_types(project_id, region, instance_class):
     """
     List the instances types for specified google project, region &
@@ -224,7 +224,7 @@ def get_instance_types(project_id, region, instance_class):
 
 @blueprint.route('/database_versions/',
                  methods=['GET'], endpoint='database_versions')
-@login_required
+@pga_login_required
 def get_database_versions():
     """
     Lists the postgresql database versions.
diff --git a/web/pgadmin/misc/cloud/rds/__init__.py b/web/pgadmin/misc/cloud/rds/__init__.py
index cdad06e71ba..2253b13e5bf 100644
--- a/web/pgadmin/misc/cloud/rds/__init__.py
+++ b/web/pgadmin/misc/cloud/rds/__init__.py
@@ -16,7 +16,7 @@
 from boto3.session import Session
 from flask_babel import gettext
 from flask import session, current_app, request
-from flask_security import login_required
+from pgadmin.user_login_check import pga_login_required
 from werkzeug.datastructures import Headers
 from pgadmin.utils import PgAdminModule
 from pgadmin.misc.cloud.utils import _create_server, CloudProcessDesc
@@ -48,7 +48,7 @@ def get_exposed_url_endpoints(self):
 
 @blueprint.route('/verify_credentials/',
                  methods=['POST'], endpoint='verify_credentials')
-@login_required
+@pga_login_required
 def verify_credentials():
     """Verify Credentials."""
     msg = ''
@@ -80,7 +80,7 @@ def verify_credentials():
 
 @blueprint.route('/db_instances/',
                  methods=['GET'], endpoint='db_instances')
-@login_required
+@pga_login_required
 def get_db_instances():
     """
     Fetch AWS DB Instances based on engine version.
@@ -116,7 +116,7 @@ def get_db_instances():
 
 @blueprint.route('/db_versions/',
                  methods=['GET'], endpoint='db_versions')
-@login_required
+@pga_login_required
 def get_db_versions():
     """GET AWS Database Versions for AWS."""
     if 'aws' not in session:
@@ -142,7 +142,7 @@ def get_db_versions():
 
 @blueprint.route('/regions/',
                  methods=['GET'], endpoint='regions')
-@login_required
+@pga_login_required
 def get_regions():
     """GET Regions for AWS."""
     try:
diff --git a/web/pgadmin/misc/file_manager/__init__.py b/web/pgadmin/misc/file_manager/__init__.py
index 45b6abcd6b2..39b5d25d436 100644
--- a/web/pgadmin/misc/file_manager/__init__.py
+++ b/web/pgadmin/misc/file_manager/__init__.py
@@ -26,7 +26,7 @@
 from flask import render_template, Response, session, request as req, \
     url_for, current_app, send_from_directory
 from flask_babel import gettext
-from flask_security import login_required
+from pgadmin.user_login_check import pga_login_required
 from pgadmin.utils import PgAdminModule
 from pgadmin.utils import get_storage_directory
 from pgadmin.utils.ajax import make_json_response, unauthorized, \
@@ -184,7 +184,7 @@ def register_preferences(self):
 
 
 @blueprint.route("/", endpoint='index')
-@login_required
+@pga_login_required
 def index():
     return bad_request(
         errormsg=gettext("This URL cannot be called directly.")
@@ -192,7 +192,7 @@ def index():
 
 
 @blueprint.route("/utility.js")
-@login_required
+@pga_login_required
 def utility():
     """render the required javascript"""
     return Response(response=render_template(
@@ -204,7 +204,7 @@ def utility():
 @blueprint.route(
     "/init", methods=["POST"], endpoint='init'
 )
-@login_required
+@pga_login_required
 def init_filemanager():
     if len(req.data) != 0:
         configs = json.loads(req.data)
@@ -259,7 +259,7 @@ def init_filemanager():
     "/delete_trans_id/<int:trans_id>",
     methods=["DELETE"], endpoint='delete_trans_id'
 )
-@login_required
+@pga_login_required
 def delete_trans_id(trans_id):
     Filemanager.release_transaction(trans_id)
     return make_json_response(
@@ -270,7 +270,7 @@ def delete_trans_id(trans_id):
 @blueprint.route(
     "/save_last_dir/<int:trans_id>", methods=["POST"], endpoint='save_last_dir'
 )
-@login_required
+@pga_login_required
 def save_last_directory_visited(trans_id):
     blueprint.last_directory_visited.set(req.json['path'])
     blueprint.last_storage.set(req.json['storage_folder'])
@@ -281,7 +281,7 @@ def save_last_directory_visited(trans_id):
     "/save_file_dialog_view/<int:trans_id>", methods=["POST"],
     endpoint='save_file_dialog_view'
 )
-@login_required
+@pga_login_required
 def save_file_dialog_view(trans_id):
     blueprint.file_dialog_view.set(req.json['view'])
     return make_json_response(status=200)
@@ -291,7 +291,7 @@ def save_file_dialog_view(trans_id):
     "/save_show_hidden_file_option/<int:trans_id>", methods=["PUT"],
     endpoint='save_show_hidden_file_option'
 )
-@login_required
+@pga_login_required
 def save_show_hidden_file_option(trans_id):
     blueprint.show_hidden_files.set(req.json['show_hidden'])
     return make_json_response(status=200)
@@ -1108,7 +1108,7 @@ def permission(self, path=None):
     "/filemanager/<int:trans_id>/",
     methods=["POST"], endpoint='filemanager'
 )
-@login_required
+@pga_login_required
 def file_manager(trans_id):
     """
     It is the common function for every call which is made
diff --git a/web/pgadmin/preferences/__init__.py b/web/pgadmin/preferences/__init__.py
index c5035a465c4..8ec7c259cdd 100644
--- a/web/pgadmin/preferences/__init__.py
+++ b/web/pgadmin/preferences/__init__.py
@@ -16,7 +16,7 @@
 import json
 from flask import render_template, url_for, Response, request, session
 from flask_babel import gettext
-from flask_security import login_required
+from pgadmin.user_login_check import pga_login_required
 from pgadmin.utils import PgAdminModule
 from pgadmin.utils.ajax import success_return, \
     make_response as ajax_response, internal_server_error
@@ -57,7 +57,7 @@ def get_exposed_url_endpoints(self):
 
 
 @blueprint.route("/preferences.js")
-@login_required
+@pga_login_required
 def script():
     """render the required javascript"""
     return Response(
@@ -69,7 +69,7 @@ def script():
 
 @blueprint.route("/", methods=["GET"], endpoint='index')
 @blueprint.route("/<module>/<preference>", endpoint='get_by_name')
-@login_required
+@pga_login_required
 def preferences(module=None, preference=None):
     """Fetch all/or requested preferences of pgAdmin IV."""
 
@@ -162,7 +162,7 @@ def _iterate_categories(pref_d, label, res):
 
 
 @blueprint.route("/get_all", methods=["GET"], endpoint='get_all')
-@login_required
+@pga_login_required
 def preferences_s():
     """Fetch all preferences for caching."""
     # Load Preferences
@@ -220,7 +220,7 @@ def get_data():
 
 
 @blueprint.route("/", methods=["PUT"], endpoint="update")
-@login_required
+@pga_login_required
 def save():
     """
     Save a specific preference.
@@ -296,7 +296,7 @@ def save_pref(data):
 
 
 @blueprint.route("/update", methods=["PUT"], endpoint="update_pref")
-@login_required
+@pga_login_required
 def update():
     """
     Update a specific preference.
diff --git a/web/pgadmin/redirects/__init__.py b/web/pgadmin/redirects/__init__.py
index 019a5be9320..4eb61d2840f 100644
--- a/web/pgadmin/redirects/__init__.py
+++ b/web/pgadmin/redirects/__init__.py
@@ -8,7 +8,7 @@
 ##########################################################################
 
 from flask import redirect, url_for
-from flask_security import login_required
+from pgadmin.user_login_check import pga_login_required
 
 from pgadmin import PgAdminModule
 
@@ -20,7 +20,7 @@
 
 
 @blueprint.route('/')
-@login_required
+@pga_login_required
 def index():
     """Redirect users hitting the root to the browser"""
     return redirect(url_for('browser.index'))
diff --git a/web/pgadmin/settings/__init__.py b/web/pgadmin/settings/__init__.py
index 6593252c0b4..f651bac2fad 100644
--- a/web/pgadmin/settings/__init__.py
+++ b/web/pgadmin/settings/__init__.py
@@ -15,7 +15,7 @@
 from flask import Response, request, render_template, url_for, current_app
 from flask_babel import gettext
 from flask_login import current_user
-from flask_security import login_required
+from pgadmin.user_login_check import pga_login_required
 from pgadmin.utils import PgAdminModule
 from pgadmin.utils.ajax import make_json_response, bad_request,\
     success_return, internal_server_error
@@ -80,13 +80,13 @@ def get_setting(setting, default=''):
 
 
 @blueprint.route("/")
-@login_required
+@pga_login_required
 def index():
     return bad_request(errormsg=gettext("This URL cannot be called directly."))
 
 
 @blueprint.route("/settings.js")
-@login_required
+@pga_login_required
 def script():
     """Render the required Javascript"""
     return Response(response=render_template("settings/settings.js"),
@@ -96,7 +96,7 @@ def script():
 
 @blueprint.route("/store", methods=['POST'], endpoint='store_bulk')
 @blueprint.route("/store/<setting>/<value>", methods=['PUT'], endpoint='store')
-@login_required
+@pga_login_required
 def store(setting=None, value=None):
     """Store a configuration setting, or if this is a POST request and a
     count value is present, store multiple settings at once."""
@@ -131,7 +131,7 @@ def store(setting=None, value=None):
 
 
 @blueprint.route("/layout", methods=['DELETE'], endpoint='reset_layout')
-@login_required
+@pga_login_required
 def reset_layout():
     """Reset configuration setting"""
 
@@ -162,7 +162,7 @@ def reset_layout():
 
 @blueprint.route("/reset_tree_state", methods=['DELETE'],
                  endpoint='reset_tree_state')
-@login_required
+@pga_login_required
 def reset_tree_state():
     """Reset the saved tree state."""
 
@@ -182,7 +182,7 @@ def reset_tree_state():
 
 @blueprint.route("/save_tree_state/", endpoint="save_tree_state",
                  methods=['POST'])
-@login_required
+@pga_login_required
 def save_browser_tree_state():
     """Save the browser tree state."""
     data = request.form if request.form else request.data.decode('utf-8')
@@ -210,7 +210,7 @@ def save_browser_tree_state():
 
 @blueprint.route("/get_tree_state/", endpoint="get_tree_state",
                  methods=['GET'])
-@login_required
+@pga_login_required
 def get_browser_tree_state():
     """Get the browser tree state."""
 
@@ -228,7 +228,7 @@ def get_browser_tree_state():
 @blueprint.route("/save_file_format_setting/",
                  endpoint="save_file_format_setting",
                  methods=['POST'])
-@login_required
+@pga_login_required
 def save_file_format_setting():
     """
     This function save the selected file format.save_file_format_setting
@@ -247,7 +247,7 @@ def save_file_format_setting():
 @blueprint.route("/get_file_format_setting/",
                  endpoint="get_file_format_setting",
                  methods=['GET'])
-@login_required
+@pga_login_required
 def get_file_format_setting():
     """
     This function return the last selected file format
diff --git a/web/pgadmin/tools/backup/__init__.py b/web/pgadmin/tools/backup/__init__.py
index 2020cb16d3c..60467b8c848 100644
--- a/web/pgadmin/tools/backup/__init__.py
+++ b/web/pgadmin/tools/backup/__init__.py
@@ -16,7 +16,8 @@
 from flask import render_template, request, current_app, \
     url_for, Response
 from flask_babel import gettext
-from flask_security import login_required, current_user
+from flask_security import current_user
+from pgadmin.user_login_check import pga_login_required
 from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
 from pgadmin.utils import PgAdminModule, get_storage_directory, html, \
     fs_short_path, document_dir, does_utility_exist, get_server, \
@@ -177,13 +178,13 @@ def details(self, cmd, args):
 
 
 @blueprint.route("/")
-@login_required
+@pga_login_required
 def index():
     return bad_request(errormsg=gettext("This URL cannot be called directly."))
 
 
 @blueprint.route("/backup.js")
-@login_required
+@pga_login_required
 def script():
     """render own javascript"""
     return Response(
@@ -391,7 +392,7 @@ def set_value(key, param, default_value=None, assertion=True):
 @blueprint.route(
     '/job/<int:sid>/object', methods=['POST'], endpoint='create_object_job'
 )
-@login_required
+@pga_login_required
 def create_backup_objects_job(sid):
     """
     Args:
@@ -498,7 +499,7 @@ def create_backup_objects_job(sid):
 @blueprint.route(
     '/utility_exists/<int:sid>/<backup_obj_type>', endpoint='utility_exists'
 )
-@login_required
+@pga_login_required
 def check_utility_exists(sid, backup_obj_type):
     """
     This function checks the utility file exist on the given path.
@@ -540,7 +541,7 @@ def check_utility_exists(sid, backup_obj_type):
 @blueprint.route(
     '/objects/<int:sid>/<int:did>/<int:scid>', endpoint='schema_objects'
 )
-@login_required
+@pga_login_required
 def objects(sid, did, scid=None):
     """
     This function returns backup objects
diff --git a/web/pgadmin/tools/debugger/__init__.py b/web/pgadmin/tools/debugger/__init__.py
index a356592985f..d54c4c69785 100644
--- a/web/pgadmin/tools/debugger/__init__.py
+++ b/web/pgadmin/tools/debugger/__init__.py
@@ -16,7 +16,7 @@
 
 from flask import render_template, request, current_app
 from flask_babel import gettext
-from flask_security import login_required
+from pgadmin.user_login_check import pga_login_required
 from werkzeug.user_agent import UserAgent
 
 from pgadmin.utils import PgAdminModule, \
@@ -237,7 +237,7 @@ def on_logout(self):
 
 
 @blueprint.route("/", endpoint='index')
-@login_required
+@pga_login_required
 def index():
     return bad_request(
         errormsg=gettext("This URL cannot be called directly.")
@@ -350,7 +350,7 @@ def check_node_type(node_type, fid, trid, conn, ppas_server,
     '/init/<node_type>/<int:sid>/<int:did>/<int:scid>/<int:fid>/<int:trid>',
     methods=['GET'], endpoint='init_for_trigger'
 )
-@login_required
+@pga_login_required
 def init_function(node_type, sid, did, scid, fid, trid=None):
     """
     init_function(node_type, sid, did, scid, fid, trid)
@@ -557,7 +557,7 @@ def check_user_ip_req(r_set, data):
 
 
 @blueprint.route('/direct/<int:trans_id>', methods=['GET'], endpoint='direct')
-@login_required
+@pga_login_required
 def direct_new(trans_id):
     de_inst = DebuggerInstance(trans_id)
 
@@ -769,7 +769,7 @@ def get_search_path(conn):
     methods=['POST'],
     endpoint='initialize_target_for_trigger'
 )
-@login_required
+@pga_login_required
 def initialize_target(debug_type, trans_id, sid, did,
                       scid, func_id, tri_id=None):
     """
@@ -894,7 +894,7 @@ def close(trans_id):
 @blueprint.route(
     '/restart/<int:trans_id>', methods=['GET'], endpoint='restart'
 )
-@login_required
+@pga_login_required
 def restart_debugging(trans_id):
     """
     restart_debugging(trans_id)
@@ -959,7 +959,7 @@ def restart_debugging(trans_id):
     '/start_listener/<int:trans_id>', methods=['POST'],
     endpoint='start_listener'
 )
-@login_required
+@pga_login_required
 def start_debugger_listener(trans_id):
     """
     start_debugger_listener(trans_id)
@@ -1203,7 +1203,7 @@ def get_debugger_arg_val(val_list):
     '/execute_query/<int:trans_id>/<query_type>', methods=['GET'],
     endpoint='execute_query'
 )
-@login_required
+@pga_login_required
 def execute_debugger_query(trans_id, query_type):
     """
     execute_debugger_query(trans_id, query_type)
@@ -1290,7 +1290,7 @@ def execute_debugger_query(trans_id, query_type):
 @blueprint.route(
     '/messages/<int:trans_id>/', methods=["GET"], endpoint='messages'
 )
-@login_required
+@pga_login_required
 def messages(trans_id):
     """
     messages(trans_id)
@@ -1348,7 +1348,7 @@ def messages(trans_id):
     '/start_execution/<int:trans_id>/<int:port_num>', methods=['GET'],
     endpoint='start_execution'
 )
-@login_required
+@pga_login_required
 def start_execution(trans_id, port_num):
     """
     start_execution(trans_id, port_num)
@@ -1424,7 +1424,7 @@ def start_execution(trans_id, port_num):
     '/set_breakpoint/<int:trans_id>/<int:line_no>/<int:set_type>',
     methods=['GET'], endpoint='set_breakpoint'
 )
-@login_required
+@pga_login_required
 def set_clear_breakpoint(trans_id, line_no, set_type):
     """
     set_clear_breakpoint(trans_id, line_no, set_type)
@@ -1525,7 +1525,7 @@ def get_debugger_template_path(de_inst):
     '/clear_all_breakpoint/<int:trans_id>', methods=['POST'],
     endpoint='clear_all_breakpoint'
 )
-@login_required
+@pga_login_required
 def clear_all_breakpoint(trans_id):
     """
     clear_all_breakpoint(trans_id)
@@ -1597,7 +1597,7 @@ def clear_all_breakpoint(trans_id):
     '/deposit_value/<int:trans_id>', methods=['POST'],
     endpoint='deposit_value'
 )
-@login_required
+@pga_login_required
 def deposit_parameter_value(trans_id):
     """
     deposit_parameter_value(trans_id)
@@ -1671,7 +1671,7 @@ def deposit_parameter_value(trans_id):
     '/select_frame/<int:trans_id>/<int:frame_id>', methods=['GET'],
     endpoint='select_frame'
 )
-@login_required
+@pga_login_required
 def select_frame(trans_id, frame_id):
     """
     select_frame(trans_id, frame_id)
@@ -1733,7 +1733,7 @@ def select_frame(trans_id, frame_id):
     '/get_arguments/<int:sid>/<int:did>/<int:scid>/<int:func_id>',
     methods=['GET'], endpoint='get_arguments'
 )
-@login_required
+@pga_login_required
 def get_arguments_sqlite(sid, did, scid, func_id):
     """
     get_arguments_sqlite(sid, did, scid, func_id)
@@ -1818,7 +1818,7 @@ def get_array_string(data, i):
     '/set_arguments/<int:sid>/<int:did>/<int:scid>/<int:func_id>',
     methods=['POST'], endpoint='set_arguments'
 )
-@login_required
+@pga_login_required
 def set_arguments_sqlite(sid, did, scid, func_id):
     """
     set_arguments_sqlite(sid, did, scid, func_id)
@@ -1907,7 +1907,7 @@ def set_arguments_sqlite(sid, did, scid, func_id):
     '/clear_arguments/<int:sid>/<int:did>/<int:scid>/<int:func_id>',
     methods=['POST'], endpoint='clear_arguments'
 )
-@login_required
+@pga_login_required
 def clear_arguments_sqlite(sid, did, scid, func_id):
     """
     clear_arguments_sqlite(sid, did, scid, func_id)
@@ -2052,7 +2052,7 @@ def check_result(result, conn, statusmsg):
     '/poll_end_execution_result/<int:trans_id>/',
     methods=["GET"], endpoint='poll_end_execution_result'
 )
-@login_required
+@pga_login_required
 def poll_end_execution_result(trans_id):
     """
     poll_end_execution_result(trans_id)
@@ -2128,7 +2128,7 @@ def poll_end_execution_result(trans_id):
 @blueprint.route(
     '/poll_result/<int:trans_id>/', methods=["GET"], endpoint='poll_result'
 )
-@login_required
+@pga_login_required
 def poll_result(trans_id):
     """
     poll_result(trans_id)
diff --git a/web/pgadmin/tools/erd/__init__.py b/web/pgadmin/tools/erd/__init__.py
index 3cd8d6f5db0..33ee7dc7436 100644
--- a/web/pgadmin/tools/erd/__init__.py
+++ b/web/pgadmin/tools/erd/__init__.py
@@ -12,7 +12,7 @@
 
 from flask import url_for, request, Response
 from flask import render_template, current_app as app
-from flask_security import login_required
+from pgadmin.user_login_check import pga_login_required
 from flask_babel import gettext
 from werkzeug.user_agent import UserAgent
 from pgadmin.utils import PgAdminModule, \
@@ -431,7 +431,7 @@ def register_preferences(self):
     methods=["POST"],
     endpoint='panel'
 )
-@login_required
+@pga_login_required
 def panel(trans_id):
     """
     This method calls index.html to render the erd tool.
@@ -496,7 +496,7 @@ def panel(trans_id):
     '/initialize/<int:trans_id>/<int:sgid>/<int:sid>/<int:did>',
     methods=["POST"], endpoint='initialize'
 )
-@login_required
+@pga_login_required
 def initialize_erd(trans_id, sgid, sid, did):
     """
     This method is responsible for instantiating and initializing
@@ -551,7 +551,7 @@ def _get_connection(sid, did, trans_id):
 @blueprint.route('/prequisite/<int:trans_id>/<int:sgid>/<int:sid>/<int:did>',
                  methods=["GET"],
                  endpoint='prequisite')
-@login_required
+@pga_login_required
 def prequisite(trans_id, sgid, sid, did):
     conn = _get_connection(sid, did, trans_id)
     helper = ERDHelper(trans_id, sid, did)
@@ -608,7 +608,7 @@ def translate_foreign_keys(tab_fks, tab_data, all_nodes):
 @blueprint.route('/sql/<int:trans_id>/<int:sgid>/<int:sid>/<int:did>',
                  methods=["POST"],
                  endpoint='sql')
-@login_required
+@pga_login_required
 def sql(trans_id, sgid, sid, did):
     data = json.loads(request.data)
     with_drop = False
@@ -687,7 +687,7 @@ def tables(params):
 @blueprint.route('/close/<int:trans_id>/<int:sgid>/<int:sid>/<int:did>',
                  methods=["DELETE"],
                  endpoint='close')
-@login_required
+@pga_login_required
 def close(trans_id, sgid, sid, did):
     manager = get_driver(
         PG_DEFAULT_DRIVER).connection_manager(sid)
diff --git a/web/pgadmin/tools/grant_wizard/__init__.py b/web/pgadmin/tools/grant_wizard/__init__.py
index 7dd210d1fcc..8ddcb6c56dc 100644
--- a/web/pgadmin/tools/grant_wizard/__init__.py
+++ b/web/pgadmin/tools/grant_wizard/__init__.py
@@ -13,7 +13,7 @@
 from flask import Response, url_for
 from flask import render_template, request, current_app
 from flask_babel import gettext
-from flask_security import login_required
+from pgadmin.user_login_check import pga_login_required
 from urllib.parse import unquote
 
 from pgadmin.browser.server_groups.servers.utils import parse_priv_to_db
@@ -115,7 +115,7 @@ def wrap(*args, **kwargs):
 
 
 @blueprint.route("/")
-@login_required
+@pga_login_required
 def index():
     return bad_request(
         errormsg=gettext("This URL cannot be called directly.")
@@ -123,7 +123,7 @@ def index():
 
 
 @blueprint.route("/grant_wizard.js")
-@login_required
+@pga_login_required
 def script():
     """render own javascript"""
     return Response(response=render_template(
@@ -135,7 +135,7 @@ def script():
 @blueprint.route(
     '/acl/<int:sid>/<int:did>/', methods=['GET'], endpoint='acl'
 )
-@login_required
+@pga_login_required
 @check_precondition
 def acl_list(sid, did):
     """render list of acls"""
@@ -255,7 +255,7 @@ def get_node_sql_with_type(node_id, node_type, server_prop,
     '/<int:sid>/<int:did>/<int:node_id>/<node_type>/',
     methods=['GET'], endpoint='objects'
 )
-@login_required
+@pga_login_required
 @check_precondition
 def properties(sid, did, node_id, node_type):
     """It fetches the properties of object types
@@ -411,7 +411,7 @@ def set_priv_for_package(server_prop, data, acls):
     '/sql/<int:sid>/<int:did>/',
     methods=['POST'], endpoint='modified_sql'
 )
-@login_required
+@pga_login_required
 @check_precondition
 def msql(sid, did):
     """
@@ -545,7 +545,7 @@ def parse_priv(data, acls, server_prop):
 @blueprint.route(
     '/<int:sid>/<int:did>/', methods=['POST'], endpoint='apply'
 )
-@login_required
+@pga_login_required
 @check_precondition
 def save(sid, did):
     """
diff --git a/web/pgadmin/tools/import_export/__init__.py b/web/pgadmin/tools/import_export/__init__.py
index 24d6aa76221..d4e822699a5 100644
--- a/web/pgadmin/tools/import_export/__init__.py
+++ b/web/pgadmin/tools/import_export/__init__.py
@@ -14,7 +14,8 @@
 
 from flask import Response, render_template, request, current_app
 from flask_babel import gettext as _
-from flask_security import login_required, current_user
+from flask_security import current_user
+from pgadmin.user_login_check import pga_login_required
 from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
 from pgadmin.utils import PgAdminModule, get_storage_directory, IS_WIN, \
     does_utility_exist, get_server, filename_with_file_manager_path
@@ -135,13 +136,13 @@ def details(self, cmd, args):
 
 
 @blueprint.route("/")
-@login_required
+@pga_login_required
 def index():
     return bad_request(errormsg=_("This URL cannot be called directly."))
 
 
 @blueprint.route("/js/import_export.js")
-@login_required
+@pga_login_required
 def script():
     """render the import/export javascript file"""
     return Response(
@@ -226,7 +227,7 @@ def _save_import_export_settings(settings):
 
 
 @blueprint.route('/job/<int:sid>', methods=['POST'], endpoint="create_job")
-@login_required
+@pga_login_required
 def create_import_export_job(sid):
     """
     Args:
@@ -358,7 +359,7 @@ def create_import_export_job(sid):
 
 
 @blueprint.route('/get_settings/', methods=['GET'], endpoint='get_settings')
-@login_required
+@pga_login_required
 def get_import_export_settings():
     settings = get_setting('import_export_setting', None)
     if settings is None:
@@ -371,7 +372,7 @@ def get_import_export_settings():
 @blueprint.route(
     '/utility_exists/<int:sid>', endpoint='utility_exists'
 )
-@login_required
+@pga_login_required
 def check_utility_exists(sid):
     """
     This function checks the utility file exist on the given path.
diff --git a/web/pgadmin/tools/import_export_servers/__init__.py b/web/pgadmin/tools/import_export_servers/__init__.py
index cf15a38042b..1250a0b22af 100644
--- a/web/pgadmin/tools/import_export_servers/__init__.py
+++ b/web/pgadmin/tools/import_export_servers/__init__.py
@@ -16,7 +16,8 @@
 
 from flask import Response, render_template, request
 from flask_babel import gettext as _
-from flask_security import login_required, current_user
+from flask_security import current_user
+from pgadmin.user_login_check import pga_login_required
 from pgadmin.utils import PgAdminModule
 from pgadmin.utils.ajax import bad_request
 from pgadmin.utils.constants import MIMETYPE_APP_JS
@@ -54,13 +55,13 @@ def get_exposed_url_endpoints(self):
 
 
 @blueprint.route("/")
-@login_required
+@pga_login_required
 def index():
     return bad_request(errormsg=_("This URL cannot be called directly."))
 
 
 @blueprint.route("/js/import_export_servers.js")
-@login_required
+@pga_login_required
 def script():
     """render the import/export javascript file"""
     return Response(
@@ -72,7 +73,7 @@ def script():
 
 
 @blueprint.route('/get_servers', methods=['GET'], endpoint='get_servers')
-@login_required
+@pga_login_required
 def get_servers():
     """
     This function is used to get the servers with server groups
@@ -102,7 +103,7 @@ def get_servers():
 
 
 @blueprint.route('/load_servers', methods=['POST'], endpoint='load_servers')
-@login_required
+@pga_login_required
 def load_servers():
     """
     This function is used to load the servers from the json file.
@@ -167,7 +168,7 @@ def load_servers():
 
 
 @blueprint.route('/save', methods=['POST'], endpoint='save')
-@login_required
+@pga_login_required
 def save():
     """
     This function is used to import or export based on the data
diff --git a/web/pgadmin/tools/maintenance/__init__.py b/web/pgadmin/tools/maintenance/__init__.py
index d08e0b7d3a3..35b02ad1aac 100644
--- a/web/pgadmin/tools/maintenance/__init__.py
+++ b/web/pgadmin/tools/maintenance/__init__.py
@@ -13,7 +13,8 @@
 
 from flask import url_for, Response, render_template, request, current_app
 from flask_babel import gettext as _
-from flask_security import login_required, current_user
+from flask_security import current_user
+from pgadmin.user_login_check import pga_login_required
 from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
 from pgadmin.utils import PgAdminModule, html, does_utility_exist, get_server
 from pgadmin.utils.ajax import bad_request, make_json_response
@@ -122,7 +123,7 @@ def details(self, cmd, args):
 
 
 @blueprint.route("/")
-@login_required
+@pga_login_required
 def index():
     return bad_request(
         errormsg=_("This URL cannot be called directly.")
@@ -130,7 +131,7 @@ def index():
 
 
 @blueprint.route("/js/maintenance.js")
-@login_required
+@pga_login_required
 def script():
     """render the maintenance tool of vacuum javascript file"""
     return Response(
@@ -160,7 +161,7 @@ def get_index_name(data):
 @blueprint.route(
     '/job/<int:sid>/<int:did>', methods=['POST'], endpoint='create_job'
 )
-@login_required
+@pga_login_required
 def create_maintenance_job(sid, did):
     """
     Args:
@@ -252,7 +253,7 @@ def create_maintenance_job(sid, did):
 @blueprint.route(
     '/utility_exists/<int:sid>', endpoint='utility_exists'
 )
-@login_required
+@pga_login_required
 def check_utility_exists(sid):
     """
     This function checks the utility file exist on the given path.
diff --git a/web/pgadmin/tools/psql/__init__.py b/web/pgadmin/tools/psql/__init__.py
index a6ddfb47873..772363b723b 100644
--- a/web/pgadmin/tools/psql/__init__.py
+++ b/web/pgadmin/tools/psql/__init__.py
@@ -19,7 +19,8 @@
 from flask import render_template, copy_current_request_context, \
     current_app as app
 from flask_babel import gettext
-from flask_security import login_required, current_user
+from flask_security import current_user
+from pgadmin.user_login_check import pga_login_required
 from pgadmin.browser.utils import underscore_unescape, underscore_escape
 from pgadmin.utils import PgAdminModule
 from pgadmin.utils.constants import MIMETYPE_APP_JS
@@ -71,7 +72,7 @@ def get_exposed_url_endpoints(self):
 
 
 @blueprint.route("/psql.js")
-@login_required
+@pga_login_required
 def script():
     """render the required javascript"""
     return Response(
@@ -84,7 +85,7 @@ def script():
 @blueprint.route('/panel/<int:trans_id>',
                  methods=["POST"],
                  endpoint="panel")
-@login_required
+@pga_login_required
 def panel(trans_id):
     """
     Return panel template for PSQL tools.
diff --git a/web/pgadmin/tools/restore/__init__.py b/web/pgadmin/tools/restore/__init__.py
index c2e247c7deb..7d289b9316c 100644
--- a/web/pgadmin/tools/restore/__init__.py
+++ b/web/pgadmin/tools/restore/__init__.py
@@ -13,7 +13,8 @@
 
 from flask import render_template, request, current_app, Response
 from flask_babel import gettext as _
-from flask_security import login_required, current_user
+from flask_security import current_user
+from pgadmin.user_login_check import pga_login_required
 from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
 from pgadmin.utils import PgAdminModule, fs_short_path, does_utility_exist, \
     get_server, filename_with_file_manager_path
@@ -109,13 +110,13 @@ def details(self, cmd, args):
 
 
 @blueprint.route("/")
-@login_required
+@pga_login_required
 def index():
     return bad_request(errormsg=_("This URL cannot be called directly."))
 
 
 @blueprint.route("/restore.js")
-@login_required
+@pga_login_required
 def script():
     """render own javascript"""
     return Response(
@@ -350,7 +351,7 @@ def _set_args_param_values(data, manager, server, driver, conn, _file):
 
 
 @blueprint.route('/job/<int:sid>', methods=['POST'], endpoint='create_job')
-@login_required
+@pga_login_required
 def create_restore_job(sid):
     """
     Args:
@@ -410,7 +411,7 @@ def create_restore_job(sid):
 @blueprint.route(
     '/utility_exists/<int:sid>', endpoint='utility_exists'
 )
-@login_required
+@pga_login_required
 def check_utility_exists(sid):
     """
     This function checks the utility file exist on the given path.
diff --git a/web/pgadmin/tools/schema_diff/__init__.py b/web/pgadmin/tools/schema_diff/__init__.py
index cb4500d4f27..ceaaa6e7ee3 100644
--- a/web/pgadmin/tools/schema_diff/__init__.py
+++ b/web/pgadmin/tools/schema_diff/__init__.py
@@ -15,7 +15,8 @@
 
 from flask import Response, session, url_for, request
 from flask import render_template, current_app as app
-from flask_security import current_user, login_required
+from flask_security import current_user
+from pgadmin.user_login_check import pga_login_required
 from flask_babel import gettext
 from pgadmin.utils import PgAdminModule
 from pgadmin.utils.ajax import make_json_response, bad_request, \
@@ -109,7 +110,7 @@ def register_preferences(self):
 
 
 @blueprint.route("/")
-@login_required
+@pga_login_required
 def index():
     return bad_request(
         errormsg=gettext('This URL cannot be requested directly.')
@@ -193,7 +194,7 @@ def update_session_diff_transaction(trans_id, session_obj, diff_model_obj):
     methods=["GET"],
     endpoint="initialize"
 )
-@login_required
+@pga_login_required
 def initialize():
     """
     This function will initialize the schema diff and return the list
@@ -261,7 +262,7 @@ def close(trans_id):
     methods=["GET"],
     endpoint="servers"
 )
-@login_required
+@pga_login_required
 def servers():
     """
     This function will return the list of servers for the specified
@@ -317,7 +318,7 @@ def servers():
     methods=["GET"],
     endpoint="get_server"
 )
-@login_required
+@pga_login_required
 def get_server(sid, did):
     """
     This function will return the server details for the specified
@@ -354,7 +355,7 @@ def get_server(sid, did):
     methods=["POST"],
     endpoint="connect_server"
 )
-@login_required
+@pga_login_required
 def connect_server(sid):
     # Check if server is already connected then no need to reconnect again.
     driver = get_driver(PG_DEFAULT_DRIVER)
@@ -377,7 +378,7 @@ def connect_server(sid):
     methods=["POST"],
     endpoint="connect_database"
 )
-@login_required
+@pga_login_required
 def connect_database(sid, did):
     server = Server.query.filter_by(id=sid).first()
     view = SchemaDiffRegistry.get_node_view('database')
@@ -389,7 +390,7 @@ def connect_database(sid, did):
     methods=["GET"],
     endpoint="databases"
 )
-@login_required
+@pga_login_required
 def databases(sid):
     """
     This function will return the list of databases for the specified
@@ -426,7 +427,7 @@ def databases(sid):
     methods=["GET"],
     endpoint="schemas"
 )
-@login_required
+@pga_login_required
 def schemas(sid, did):
     """
     This function will return the list of schemas for the specified
@@ -668,7 +669,7 @@ def compare_schema(params):
     methods=["GET"],
     endpoint="ddl_compare"
 )
-@login_required
+@pga_login_required
 def ddl_compare(trans_id, source_sid, source_did, source_scid,
                 target_sid, target_did, target_scid, source_oid,
                 target_oid, node_type, comp_status):
diff --git a/web/pgadmin/tools/search_objects/__init__.py b/web/pgadmin/tools/search_objects/__init__.py
index 9029e850ed4..fd27d3e1b97 100644
--- a/web/pgadmin/tools/search_objects/__init__.py
+++ b/web/pgadmin/tools/search_objects/__init__.py
@@ -11,7 +11,7 @@
 
 from flask import request
 from flask_babel import gettext
-from flask_security import login_required
+from pgadmin.user_login_check import pga_login_required
 
 from pgadmin.utils import PgAdminModule
 from pgadmin.utils.ajax import make_json_response, bad_request,\
@@ -54,20 +54,20 @@ def register_preferences(self):
 
 
 @blueprint.route("/", endpoint='index')
-@login_required
+@pga_login_required
 def index():
     return bad_request(errormsg=gettext("This URL cannot be called directly."))
 
 
 @blueprint.route("types/<int:sid>/<int:did>", endpoint='types')
-@login_required
+@pga_login_required
 def types(sid, did):
     so_obj = SearchObjectsHelper(sid, did, blueprint.show_system_objects())
     return make_json_response(data=so_obj.get_supported_types())
 
 
 @blueprint.route("search/<int:sid>/<int:did>", endpoint='search')
-@login_required
+@pga_login_required
 def search(sid, did):
     """
     URL args:
diff --git a/web/pgadmin/tools/sqleditor/__init__.py b/web/pgadmin/tools/sqleditor/__init__.py
index e8cd9f542a4..d94868ffe05 100644
--- a/web/pgadmin/tools/sqleditor/__init__.py
+++ b/web/pgadmin/tools/sqleditor/__init__.py
@@ -22,7 +22,8 @@
 from flask import Response, url_for, render_template, session, current_app
 from flask import request
 from flask_babel import gettext
-from flask_security import login_required, current_user
+from pgadmin.user_login_check import pga_login_required
+from flask_security import current_user
 from pgadmin.misc.file_manager import Filemanager
 from pgadmin.tools.sqleditor.command import QueryToolCommand, ObjectRegistry, \
     SQLFilter
@@ -161,7 +162,7 @@ def register_preferences(self):
 
 
 @blueprint.route('/')
-@login_required
+@pga_login_required
 def index():
     return bad_request(
         errormsg=gettext('This URL cannot be requested directly.')
@@ -169,7 +170,7 @@ def index():
 
 
 @blueprint.route("/filter", endpoint='filter')
-@login_required
+@pga_login_required
 def show_filter():
     return render_template(MODULE_NAME + '/filter.html')
 
@@ -180,7 +181,7 @@ def show_filter():
     methods=["PUT", "POST"],
     endpoint="initialize_viewdata"
 )
-@login_required
+@pga_login_required
 def initialize_viewdata(trans_id, cmd_type, obj_type, sgid, sid, did, obj_id):
     """
     This method is responsible for creating an asynchronous connection.
@@ -346,7 +347,7 @@ def panel(trans_id):
     '/initialize/sqleditor/<int:trans_id>/<int:sgid>/<int:sid>',
     methods=["POST"], endpoint='initialize_sqleditor'
 )
-@login_required
+@pga_login_required
 def initialize_sqleditor(trans_id, sgid, sid, did=None):
     """
     This method is responsible for instantiating and initializing
@@ -632,7 +633,7 @@ def close(trans_id):
     '/filter/validate/<int:sid>/<int:did>/<int:obj_id>',
     methods=["PUT", "POST"], endpoint='filter_validate'
 )
-@login_required
+@pga_login_required
 def validate_filter(sid, did, obj_id):
     """
     This method is used to validate the sql filter.
@@ -765,7 +766,7 @@ def check_transaction_status(trans_id, auto_comp=False):
     '/view_data/start/<int:trans_id>',
     methods=["GET"], endpoint='view_data_start'
 )
-@login_required
+@pga_login_required
 def start_view_data(trans_id):
     """
     This method is used to execute query using asynchronous connection.
@@ -864,7 +865,7 @@ def start_view_data(trans_id):
     '/query_tool/start/<int:trans_id>',
     methods=["PUT", "POST"], endpoint='query_tool_start'
 )
-@login_required
+@pga_login_required
 def start_query_tool(trans_id):
     """
     This method is used to execute query using asynchronous connection.
@@ -902,7 +903,7 @@ def extract_sql_from_network_parameters(request_data, request_arguments,
 
 
 @blueprint.route('/poll/<int:trans_id>', methods=["GET"], endpoint='poll')
-@login_required
+@pga_login_required
 def poll(trans_id):
     """
     This method polls the result of the asynchronous query and returns
@@ -1144,7 +1145,7 @@ def poll(trans_id):
     '/fetch/<int:trans_id>/<int:fetch_all>', methods=["GET"],
     endpoint='fetch_all'
 )
-@login_required
+@pga_login_required
 def fetch(trans_id, fetch_all=None):
     result = None
     has_more_rows = False
@@ -1199,7 +1200,7 @@ def fetch(trans_id, fetch_all=None):
     '/fetch_all_from_start/<int:trans_id>/<int:limit>', methods=["GET"],
     endpoint='fetch_all_from_start'
 )
-@login_required
+@pga_login_required
 def fetch_all_from_start(trans_id, limit=-1):
     """
     This function is used to fetch all the records from start and reset
@@ -1330,7 +1331,7 @@ def _check_and_connect(trans_obj):
 @blueprint.route(
     '/save/<int:trans_id>', methods=["PUT", "POST"], endpoint='save'
 )
-@login_required
+@pga_login_required
 def save(trans_id):
     """
     This method is used to save the data changes to the server
@@ -1401,7 +1402,7 @@ def save(trans_id):
     '/filter/inclusive/<int:trans_id>',
     methods=["PUT", "POST"], endpoint='inclusive_filter'
 )
-@login_required
+@pga_login_required
 def append_filter_inclusive(trans_id):
     """
     This method is used to append and apply the filter.
@@ -1456,7 +1457,7 @@ def append_filter_inclusive(trans_id):
     '/filter/exclusive/<int:trans_id>',
     methods=["PUT", "POST"], endpoint='exclusive_filter'
 )
-@login_required
+@pga_login_required
 def append_filter_exclusive(trans_id):
     """
     This method is used to append and apply the filter.
@@ -1512,7 +1513,7 @@ def append_filter_exclusive(trans_id):
     '/filter/remove/<int:trans_id>',
     methods=["PUT", "POST"], endpoint='remove_filter'
 )
-@login_required
+@pga_login_required
 def remove_filter(trans_id):
     """
     This method is used to remove the filter.
@@ -1552,7 +1553,7 @@ def remove_filter(trans_id):
 @blueprint.route(
     '/limit/<int:trans_id>', methods=["PUT", "POST"], endpoint='set_limit'
 )
-@login_required
+@pga_login_required
 def set_limit(trans_id):
     """
     This method is used to set the limit for the SQL.
@@ -1640,7 +1641,7 @@ def _check_and_cancel_transaction(trans_obj, delete_connection, conn, manager):
     '/cancel/<int:trans_id>',
     methods=["PUT", "POST"], endpoint='cancel_transaction'
 )
-@login_required
+@pga_login_required
 def cancel_transaction(trans_id):
     """
     This method is used to cancel the running transaction
@@ -1701,7 +1702,7 @@ def cancel_transaction(trans_id):
     '/object/get/<int:trans_id>',
     methods=["GET"], endpoint='get_object_name'
 )
-@login_required
+@pga_login_required
 def get_object_name(trans_id):
     """
     This method is used to get the object name
@@ -1757,7 +1758,7 @@ def check_and_upgrade_to_qt(trans_id, connect):
     '/auto_commit/<int:trans_id>',
     methods=["PUT", "POST"], endpoint='auto_commit'
 )
-@login_required
+@pga_login_required
 def set_auto_commit(trans_id):
     """
     This method is used to set the value for auto commit .
@@ -1810,7 +1811,7 @@ def set_auto_commit(trans_id):
     '/auto_rollback/<int:trans_id>',
     methods=["PUT", "POST"], endpoint='auto_rollback'
 )
-@login_required
+@pga_login_required
 def set_auto_rollback(trans_id):
     """
     This method is used to set the value for auto commit .
@@ -1863,7 +1864,7 @@ def set_auto_rollback(trans_id):
     '/autocomplete/<int:trans_id>',
     methods=["PUT", "POST"], endpoint='autocomplete'
 )
-@login_required
+@pga_login_required
 def auto_complete(trans_id):
     """
     This method implements the autocomplete feature.
@@ -1923,7 +1924,7 @@ def auto_complete(trans_id):
 
 
 @blueprint.route("/sqleditor.js")
-@login_required
+@pga_login_required
 def script():
     """render the required javascript"""
     return Response(
@@ -1939,7 +1940,7 @@ def script():
 
 
 @blueprint.route('/load_file/', methods=["PUT", "POST"], endpoint='load_file')
-@login_required
+@pga_login_required
 def load_file():
     """
     This function gets name of file from request data
@@ -1993,7 +1994,7 @@ def load_file():
 
 
 @blueprint.route('/save_file/', methods=["PUT", "POST"], endpoint='save_file')
-@login_required
+@pga_login_required
 def save_file():
     """
     This function retrieves file_name and data from request.
@@ -2072,7 +2073,7 @@ def get_file_encoding_of_loaded_file(file_name):
     methods=["POST"],
     endpoint='query_tool_download'
 )
-@login_required
+@pga_login_required
 def start_query_download_tool(trans_id):
     (status, error_msg, sync_conn, trans_obj,
      session_obj) = check_transaction_status(trans_id)
@@ -2151,7 +2152,7 @@ def start_query_download_tool(trans_id):
     methods=["GET"],
     endpoint='connection_status'
 )
-@login_required
+@pga_login_required
 def query_tool_status(trans_id):
     """
     The task of this function to return the status of the current connection
@@ -2208,7 +2209,7 @@ def query_tool_status(trans_id):
     '/filter_dialog/<int:trans_id>',
     methods=["GET"], endpoint='get_filter_data'
 )
-@login_required
+@pga_login_required
 def get_filter_data(trans_id):
     """
     This method is used to get all the columns for data sorting dialog.
@@ -2227,7 +2228,7 @@ def get_filter_data(trans_id):
     '/get_server_connection/<int:sgid>/<int:sid>',
     methods=["GET"], endpoint='_check_server_connection_status'
 )
-@login_required
+@pga_login_required
 def _check_server_connection_status(sgid, sid=None):
     """
     This function returns the server connection details
@@ -2275,7 +2276,7 @@ def _check_server_connection_status(sgid, sid=None):
     '/new_connection_dialog',
     methods=["GET"], endpoint='get_new_connection_servers'
 )
-@login_required
+@pga_login_required
 def get_new_connection_data(sgid=None, sid=None):
     """
     This method is used to get required data for get new connection.
@@ -2331,7 +2332,7 @@ def get_new_connection_data(sgid=None, sid=None):
     '/new_connection_database/<int:sgid>/<int:sid>',
     methods=["GET"], endpoint='get_new_connection_database'
 )
-@login_required
+@pga_login_required
 def get_new_connection_database(sgid, sid=None):
     """
     This method is used to get required data for get new connection.
@@ -2412,7 +2413,7 @@ def get_new_connection_database(sgid, sid=None):
     '/new_connection_user/<int:sgid>/<int:sid>',
     methods=["GET"], endpoint='get_new_connection_user'
 )
-@login_required
+@pga_login_required
 def get_new_connection_user(sgid, sid=None):
     """
     This method is used to get required data for get new connection.
@@ -2478,7 +2479,7 @@ def get_new_connection_user(sgid, sid=None):
     '/new_connection_role/<int:sgid>/<int:sid>',
     methods=["GET"], endpoint='get_new_connection_role'
 )
-@login_required
+@pga_login_required
 def get_new_connection_role(sgid, sid=None):
     """
     This method is used to get required data for get new connection.
@@ -2543,7 +2544,7 @@ def get_new_connection_role(sgid, sid=None):
     methods=["POST"],
     endpoint="connect_server"
 )
-@login_required
+@pga_login_required
 def connect_server(sid):
     # Check if server is already connected then no need to reconnect again.
     server = Server.query.filter_by(id=sid).first()
@@ -2568,7 +2569,7 @@ def connect_server(sid):
     '/filter_dialog/<int:trans_id>',
     methods=["PUT"], endpoint='set_filter_data'
 )
-@login_required
+@pga_login_required
 def set_filter_data(trans_id):
     """
     This method is used to update the columns for data sorting dialog.
@@ -2591,7 +2592,7 @@ def set_filter_data(trans_id):
     '/query_history/<int:trans_id>',
     methods=["POST"], endpoint='add_query_history'
 )
-@login_required
+@pga_login_required
 def add_query_history(trans_id):
     """
     This method adds to query history for user/server/database
@@ -2617,7 +2618,7 @@ def add_query_history(trans_id):
     '/query_history/<int:trans_id>',
     methods=["DELETE"], endpoint='clear_query_history'
 )
-@login_required
+@pga_login_required
 def clear_query_history(trans_id):
     """
     This method returns clears history for user/server/database
@@ -2637,7 +2638,7 @@ def clear_query_history(trans_id):
     '/query_history/<int:trans_id>',
     methods=["GET"], endpoint='get_query_history'
 )
-@login_required
+@pga_login_required
 def get_query_history(trans_id):
     """
     This method returns query history for user/server/database
@@ -2660,7 +2661,7 @@ def get_query_history(trans_id):
     '/get_macros/<int:macro_id>/<int:trans_id>',
     methods=["GET"], endpoint='get_macro'
 )
-@login_required
+@pga_login_required
 def macros(trans_id, macro_id=None, json_resp=True):
     """
     This method is used to get all the columns for data sorting dialog.
@@ -2679,7 +2680,7 @@ def macros(trans_id, macro_id=None, json_resp=True):
     '/set_macros/<int:trans_id>',
     methods=["PUT"], endpoint='set_macros'
 )
-@login_required
+@pga_login_required
 def update_macros(trans_id):
     """
     This method is used to get all the columns for data sorting dialog.
diff --git a/web/pgadmin/tools/sqleditor/utils/macros.py b/web/pgadmin/tools/sqleditor/utils/macros.py
index c4652fab39e..cf1d89abae0 100644
--- a/web/pgadmin/tools/sqleditor/utils/macros.py
+++ b/web/pgadmin/tools/sqleditor/utils/macros.py
@@ -12,7 +12,8 @@
 import json
 from flask_babel import gettext
 from flask import current_app, request
-from flask_security import login_required, current_user
+from pgadmin.user_login_check import pga_login_required
+from flask_security import current_user
 from pgadmin.utils.ajax import make_response as ajax_response,\
     make_json_response
 from pgadmin.model import db, Macros, UserMacros
diff --git a/web/pgadmin/tools/user_management/__init__.py b/web/pgadmin/tools/user_management/__init__.py
index fb3c6544687..0d6c93ac01b 100644
--- a/web/pgadmin/tools/user_management/__init__.py
+++ b/web/pgadmin/tools/user_management/__init__.py
@@ -13,7 +13,8 @@
 from flask import render_template, request, \
     Response, abort, current_app, session
 from flask_babel import gettext as _
-from flask_security import login_required, roles_required, current_user
+from flask_security import roles_required, current_user
+from pgadmin.user_login_check import pga_login_required
 from flask_security.utils import hash_password
 from werkzeug.exceptions import InternalServerError
 
@@ -73,13 +74,13 @@ def get_exposed_url_endpoints(self):
 
 
 @blueprint.route("/")
-@login_required
+@pga_login_required
 def index():
     return bad_request(errormsg=_("This URL cannot be called directly."))
 
 
 @blueprint.route("/user_management.js")
-@login_required
+@pga_login_required
 def script():
     """render own javascript"""
     return Response(
@@ -95,7 +96,7 @@ def script():
 
 @blueprint.route("/current_user.js")
 @pgCSRFProtect.exempt
-@login_required
+@pga_login_required
 def current_user_info():
     return Response(
         response=render_template(
diff --git a/web/pgadmin/user_login_check.py b/web/pgadmin/user_login_check.py
new file mode 100644
index 00000000000..84722ba88f6
--- /dev/null
+++ b/web/pgadmin/user_login_check.py
@@ -0,0 +1,24 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2024, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+"""Implements pgAdmin4 User validity."""
+
+from functools import wraps
+from flask_security import login_required
+
+
+def pga_login_required(func):
+    import pgadmin.authenticate.mfa.utils as mfa_utils
+
+    @wraps(func)
+    @mfa_utils.mfa_required
+    def wrapper(*args, **kwargs):
+        return func(*args, **kwargs)
+
+    return wrapper
openSUSE Build Service is sponsored by