mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2026-08-17 16:34:44 -05:00
On packaged Linux installs the bundled venv is created with --system-site-packages (issue #7173) so it can reach system packages such as dbus-python. That also exposes the deprecated system oauth2client and whatever pyOpenSSL ships alongside it. googleapiclient imports oauth2client optionally, and on Ubuntu 24.04 that drags in a pyOpenSSL too old for our bundled cryptography, aborting startup at blueprint registration with "AttributeError: module 'lib' has no attribute 'GEN_EMAIL'". pgAdmin only ever authenticates to Google via google-auth and google-auth-oauthlib, so park a None sentinel under sys.modules['oauth2client'] before importing googleapiclient in both the web module and the standalone pgacloud provider. The optional import then fails cleanly and googleapiclient falls back to google-auth. Closes #10110
This commit is contained in:
@@ -8,12 +8,23 @@
|
|||||||
# ##########################################################################
|
# ##########################################################################
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from utils.io import debug, error, output
|
from utils.io import debug, error, output
|
||||||
from utils.misc import get_my_ip, get_random_id
|
from utils.misc import get_my_ip, get_random_id
|
||||||
from providers._abstract import AbsProvider
|
from providers._abstract import AbsProvider
|
||||||
|
|
||||||
|
# pgAdmin only authenticates to Google via google-auth, never the
|
||||||
|
# long-deprecated oauth2client. googleapiclient still tries to import
|
||||||
|
# oauth2client optionally, and on packaged installs the venv inherits the
|
||||||
|
# system site-packages (--system-site-packages, see issue #7173) where a
|
||||||
|
# stale oauth2client and an incompatible pyOpenSSL may be present. That
|
||||||
|
# optional import drags in the broken pyOpenSSL and crashes with "module
|
||||||
|
# 'lib' has no attribute 'GEN_EMAIL'". Blocking the module here makes
|
||||||
|
# googleapiclient fall back to google-auth cleanly. See issue #10110.
|
||||||
|
sys.modules.setdefault('oauth2client', None)
|
||||||
|
|
||||||
from googleapiclient import discovery
|
from googleapiclient import discovery
|
||||||
from googleapiclient.errors import HttpError
|
from googleapiclient.errors import HttpError
|
||||||
from google.auth.transport.requests import Request
|
from google.auth.transport.requests import Request
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
# Google Cloud Deployment Implementation
|
# Google Cloud Deployment Implementation
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
from urllib.parse import unquote
|
from urllib.parse import unquote
|
||||||
|
|
||||||
from config import root
|
from config import root
|
||||||
@@ -25,6 +26,18 @@ from flask import session, current_app, request
|
|||||||
from flask_babel import gettext as _
|
from flask_babel import gettext as _
|
||||||
|
|
||||||
from oauthlib.oauth2 import AccessDeniedError
|
from oauthlib.oauth2 import AccessDeniedError
|
||||||
|
|
||||||
|
# pgAdmin only authenticates to Google via google-auth and
|
||||||
|
# google-auth-oauthlib, never the long-deprecated oauth2client.
|
||||||
|
# googleapiclient still tries to import oauth2client optionally, and on
|
||||||
|
# packaged installs the venv inherits the system site-packages
|
||||||
|
# (--system-site-packages, see issue #7173) where a stale oauth2client and
|
||||||
|
# an incompatible pyOpenSSL may be present. That optional import drags in
|
||||||
|
# the broken pyOpenSSL and aborts startup with "module 'lib' has no
|
||||||
|
# attribute 'GEN_EMAIL'". Blocking the module here makes googleapiclient
|
||||||
|
# fall back to google-auth cleanly. See issue #10110.
|
||||||
|
sys.modules.setdefault('oauth2client', None)
|
||||||
|
|
||||||
from googleapiclient import discovery
|
from googleapiclient import discovery
|
||||||
from googleapiclient.errors import HttpError
|
from googleapiclient.errors import HttpError
|
||||||
from google_auth_oauthlib.flow import InstalledAppFlow
|
from google_auth_oauthlib.flow import InstalledAppFlow
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2026, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
"""
|
||||||
|
Regression test for issue #10110.
|
||||||
|
|
||||||
|
On packaged installs the venv inherits the system site-packages
|
||||||
|
(--system-site-packages, see issue #7173). When a stale ``oauth2client``
|
||||||
|
and an incompatible ``pyOpenSSL`` live there, googleapiclient's optional
|
||||||
|
``import oauth2client`` drags in the broken pyOpenSSL and aborts pgAdmin
|
||||||
|
startup with "module 'lib' has no attribute 'GEN_EMAIL'".
|
||||||
|
|
||||||
|
The cloud.google module guards against this by parking a ``None`` sentinel
|
||||||
|
under ``sys.modules['oauth2client']`` before importing googleapiclient, so
|
||||||
|
the optional import fails cleanly and google-auth is used instead.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
|
||||||
|
|
||||||
|
class _SkipServerSetUpMixin:
|
||||||
|
"""Skip BaseTestGenerator's Postgres connection — pure logic tests."""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
unittest.TestCase.setUp(self)
|
||||||
|
|
||||||
|
|
||||||
|
class TestOauth2ClientBlockedOnGoogleImport(
|
||||||
|
_SkipServerSetUpMixin, BaseTestGenerator):
|
||||||
|
"""Importing cloud.google must keep googleapiclient off oauth2client."""
|
||||||
|
|
||||||
|
scenarios = (('default', {}),)
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
# Importing the module installs the sentinel as a side effect.
|
||||||
|
import pgadmin.misc.cloud.google # noqa: F401
|
||||||
|
|
||||||
|
# The sentinel must be in place so googleapiclient never imports
|
||||||
|
# the deprecated oauth2client (and the pyOpenSSL it would pull in).
|
||||||
|
self.assertIsNone(
|
||||||
|
sys.modules.get('oauth2client', 'missing'),
|
||||||
|
"cloud.google must park a None sentinel under "
|
||||||
|
"sys.modules['oauth2client'] to block the optional import")
|
||||||
|
|
||||||
|
# googleapiclient must consequently report no oauth2client support.
|
||||||
|
import googleapiclient._auth as _auth
|
||||||
|
self.assertFalse(
|
||||||
|
_auth.HAS_OAUTH2CLIENT,
|
||||||
|
"googleapiclient must fall back to google-auth, not oauth2client")
|
||||||
Reference in New Issue
Block a user