Commit e53f712e authored by Jérome Perrin's avatar Jérome Perrin

oauth_google_login: apply a 10 seconds timeout when connecting to google server

In case of network problems, the http requests made to google during
login may take too long and cause global unavailability of the ERP5
instance.

Today we saw in long request logs:

    2023-05-29 07:10:35,662 - Thread 140596157511424: Started on 1685336511.6; Running for 524.1 secs; Same.

oauth2client does not expose an API to set a timeout, but it allows
passing a custom http instance where we can set a timeout.
parent 062b9867
import json import json
import oauth2client.client import oauth2client.client
import oauth2client.transport
from Products.ERP5Security.ERP5ExternalOauth2ExtractionPlugin import getGoogleUserEntry from Products.ERP5Security.ERP5ExternalOauth2ExtractionPlugin import getGoogleUserEntry
from zExceptions import Unauthorized from zExceptions import Unauthorized
SCOPE_LIST = ['https://www.googleapis.com/auth/userinfo.profile', SCOPE_LIST = ['https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/userinfo.email'] 'https://www.googleapis.com/auth/userinfo.email']
# Default timeout (in seconds) for the HTTP request made to google servers to
# exchange the authorization code for a token.
DEFAULT_HTTP_TIMEOUT = 10
def _getGoogleClientIdAndSecretKey(portal, reference="default"): def _getGoogleClientIdAndSecretKey(portal, reference="default"):
...@@ -33,7 +37,7 @@ def redirectToGoogleLoginPage(self): ...@@ -33,7 +37,7 @@ def redirectToGoogleLoginPage(self):
include_granted_scopes="true") include_granted_scopes="true")
self.REQUEST.RESPONSE.redirect(flow.step1_get_authorize_url()) self.REQUEST.RESPONSE.redirect(flow.step1_get_authorize_url())
def getAccessTokenFromCode(self, code, redirect_uri): def getAccessTokenFromCode(self, code, redirect_uri, timeout=DEFAULT_HTTP_TIMEOUT):
client_id, secret_key = _getGoogleClientIdAndSecretKey(self.getPortalObject()) client_id, secret_key = _getGoogleClientIdAndSecretKey(self.getPortalObject())
flow = oauth2client.client.OAuth2WebServerFlow( flow = oauth2client.client.OAuth2WebServerFlow(
client_id=client_id, client_id=client_id,
...@@ -42,7 +46,9 @@ def getAccessTokenFromCode(self, code, redirect_uri): ...@@ -42,7 +46,9 @@ def getAccessTokenFromCode(self, code, redirect_uri):
redirect_uri=redirect_uri, redirect_uri=redirect_uri,
access_type="offline", access_type="offline",
include_granted_scopes="true") include_granted_scopes="true")
credential = flow.step2_exchange(code) credential = flow.step2_exchange(
code,
http=oauth2client.transport.get_http_object(timeout=timeout))
credential_data = json.loads(credential.to_json()) credential_data = json.loads(credential.to_json())
return credential_data return credential_data
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment