Updates/cleanup (#1614)

* Handle socks error when checking local time offset

* Keep pylint happy

* Avoid trap when authentication flow blows up

* Fix bug that causes trap on create project
This commit is contained in:
Ross Scroggs
2023-03-16 09:31:20 -07:00
committed by GitHub
parent a6582503f2
commit 42ed5509ee
3 changed files with 27 additions and 13 deletions

View File

@@ -636,8 +636,10 @@ TIME_OFFSET_UNITS = [('day', 86400), ('hour', 3600), ('minute', 60),
def getLocalGoogleTimeOffset(testLocation='admin.googleapis.com'): def getLocalGoogleTimeOffset(testLocation='admin.googleapis.com'):
# If local time is well off, it breaks https because the server certificate
# will be seen as too old or new and thus invalid; http doesn't have that issue.
# Try with http first, if time is close (<MAX_LOCAL_GOOGLE_TIME_OFFSET seconds), # Try with http first, if time is close (<MAX_LOCAL_GOOGLE_TIME_OFFSET seconds),
# retry with https # retry with https as it should be OK
badhttp = transport.create_http() badhttp = transport.create_http()
for prot in ['http', 'https']: for prot in ['http', 'https']:
localUTC = datetime.datetime.now(datetime.timezone.utc) localUTC = datetime.datetime.now(datetime.timezone.utc)
@@ -646,6 +648,12 @@ def getLocalGoogleTimeOffset(testLocation='admin.googleapis.com'):
badhttp.request(f'{prot}://' + testLocation, 'HEAD')[0]['date']) badhttp.request(f'{prot}://' + testLocation, 'HEAD')[0]['date'])
except (httplib2.ServerNotFoundError, RuntimeError, ValueError) as e: except (httplib2.ServerNotFoundError, RuntimeError, ValueError) as e:
controlflow.system_error_exit(4, str(e)) controlflow.system_error_exit(4, str(e))
except httplib2.socks.HTTPError as e:
# If user has specified an HTTPS proxy, the http request will probably fail as httplib2
# turns a GET into a CONNECT which is not valid for an http address
if prot == 'http':
continue
handleServerError(e)
offset = remainder = int(abs((localUTC - googleUTC).total_seconds())) offset = remainder = int(abs((localUTC - googleUTC).total_seconds()))
if offset < MAX_LOCAL_GOOGLE_TIME_OFFSET and prot == 'http': if offset < MAX_LOCAL_GOOGLE_TIME_OFFSET and prot == 'http':
continue continue
@@ -7957,6 +7965,7 @@ def doCreateOrRotateServiceAccountKeys(iam=None,
client_email=None, client_email=None,
client_id=None): client_id=None):
local_key_size = 2048 local_key_size = 2048
validity_hours = 0
mode = 'retainexisting' mode = 'retainexisting'
body = {} body = {}
if iam: if iam:
@@ -7976,7 +7985,6 @@ def doCreateOrRotateServiceAccountKeys(iam=None,
mode = 'retainnone' mode = 'retainnone'
i = 3 i = 3
iam = buildGAPIServiceObject('iam', None) iam = buildGAPIServiceObject('iam', None)
validity_hours = 0
while i < len(sys.argv): while i < len(sys.argv):
myarg = sys.argv[i].lower().replace('_', '') myarg = sys.argv[i].lower().replace('_', '')
if myarg == 'algorithm': if myarg == 'algorithm':

View File

@@ -5,7 +5,6 @@ import os
from google.auth.jwt import Credentials as JWTCredentials from google.auth.jwt import Credentials as JWTCredentials
import gam
from gam import utils from gam import utils
from gam.auth import oauth from gam.auth import oauth
@@ -29,7 +28,6 @@ def get_admin_credentials_filename():
# some custom name in it. Otherwise, just use the default name. # some custom name in it. Otherwise, just use the default name.
if GC_Values[GC_ENABLE_DASA]: if GC_Values[GC_ENABLE_DASA]:
return GC_Values[GC_OAUTH2SERVICE_JSON] if GC_Values[GC_OAUTH2SERVICE_JSON] else _FN_OAUTH2SERVICE_JSON return GC_Values[GC_OAUTH2SERVICE_JSON] if GC_Values[GC_OAUTH2SERVICE_JSON] else _FN_OAUTH2SERVICE_JSON
else:
return GC_Values[GC_OAUTH2_TXT] if GC_Values[GC_OAUTH2_TXT] else _FN_OAUTH2_TXT return GC_Values[GC_OAUTH2_TXT] if GC_Values[GC_OAUTH2_TXT] else _FN_OAUTH2_TXT
@@ -47,12 +45,12 @@ def get_admin_credentials(api=None):
if key_type == 'default': if key_type == 'default':
return JWTCredentials.from_service_account_info(creds_data, return JWTCredentials.from_service_account_info(creds_data,
audience=audience) audience=audience)
elif key_type == 'yubikey': if key_type == 'yubikey':
yksigner = yubikey.YubiKey(creds_data) yksigner = yubikey.YubiKey(creds_data)
return JWTCredentials._from_signer_and_info(yksigner, return JWTCredentials._from_signer_and_info(yksigner,
creds_data, creds_data,
audience=audience) audience=audience)
elif key_type == 'signjwt': if key_type == 'signjwt':
sjsigner = signjwt.SignJwt(creds_data) sjsigner = signjwt.SignJwt(creds_data)
return signjwt.JWTCredentials._from_signer_and_info(sjsigner, return signjwt.JWTCredentials._from_signer_and_info(sjsigner,
creds_data, creds_data,

View File

@@ -50,6 +50,7 @@ MESSAGE_LOCAL_SERVER_SUCCESS = ('The authentication flow has completed. You may'
' close this browser window and return to GAM.') ' close this browser window and return to GAM.')
MESSAGE_AUTHENTICATION_COMPLETE = ('\nThe authentication flow has completed.\n') MESSAGE_AUTHENTICATION_COMPLETE = ('\nThe authentication flow has completed.\n')
MESSAGE_AUTHENTICATION_FAILED = ('\nThe authentication flow failed, reissue command')
class CredentialsError(Exception): class CredentialsError(Exception):
@@ -629,15 +630,22 @@ class _ShortURLFlow(google_auth_oauthlib.flow.InstalledAppFlow):
print(MESSAGE_CONSOLE_AUTHORIZATION_PROMPT.format(url=d['auth_url'])) print(MESSAGE_CONSOLE_AUTHORIZATION_PROMPT.format(url=d['auth_url']))
user_input.start() user_input.start()
userInput = False userInput = False
while True: alive = 2
while alive > 0:
sleep(0.1) sleep(0.1)
if not http_client.is_alive(): if not http_client.is_alive():
if 'code' in d:
user_input.terminate() user_input.terminate()
break break
elif not user_input.is_alive(): alive -= 1
if not user_input.is_alive():
userInput = True userInput = True
if 'code' in d:
http_client.terminate() http_client.terminate()
break break
alive -= 1
if 'code' not in d:
controlflow.system_error_exit(8, MESSAGE_AUTHENTICATION_FAILED)
while True: while True:
code = d['code'] code = d['code']
if code.startswith('http'): if code.startswith('http'):