mirror of
https://github.com/GAM-team/GAM.git
synced 2025-07-09 14:13:35 +00:00
Handle out of domain users better
This commit is contained in:
47
src/gam.py
47
src/gam.py
@ -92,8 +92,10 @@ GM_BATCH_QUEUE = u'batq'
|
|||||||
GM_EXTRA_ARGS_DICT = u'exad'
|
GM_EXTRA_ARGS_DICT = u'exad'
|
||||||
# Scopes retrieved from gamscopes.json
|
# Scopes retrieved from gamscopes.json
|
||||||
GM_GAMSCOPES_BY_API = u'scop'
|
GM_GAMSCOPES_BY_API = u'scop'
|
||||||
|
# Current API user
|
||||||
|
GM_CURRENT_API_USER = u'capu'
|
||||||
# Current API scope
|
# Current API scope
|
||||||
GM_CURRENT_API_SCOPES = u'scoc'
|
GM_CURRENT_API_SCOPES = u'caps'
|
||||||
# Values retrieved from oauth2service.json
|
# Values retrieved from oauth2service.json
|
||||||
GM_OAUTH2SERVICE_KEY = u'oauk'
|
GM_OAUTH2SERVICE_KEY = u'oauk'
|
||||||
GM_OAUTH2SERVICE_ACCOUNT_EMAIL = u'oaae'
|
GM_OAUTH2SERVICE_ACCOUNT_EMAIL = u'oaae'
|
||||||
@ -117,6 +119,7 @@ GM_Globals = {
|
|||||||
GM_BATCH_QUEUE: None,
|
GM_BATCH_QUEUE: None,
|
||||||
GM_EXTRA_ARGS_DICT: {u'prettyPrint': False},
|
GM_EXTRA_ARGS_DICT: {u'prettyPrint': False},
|
||||||
GM_GAMSCOPES_BY_API: {},
|
GM_GAMSCOPES_BY_API: {},
|
||||||
|
GM_CURRENT_API_USER: None,
|
||||||
GM_CURRENT_API_SCOPES: [],
|
GM_CURRENT_API_SCOPES: [],
|
||||||
GM_OAUTH2SERVICE_KEY: None,
|
GM_OAUTH2SERVICE_KEY: None,
|
||||||
GM_OAUTH2SERVICE_ACCOUNT_EMAIL: None,
|
GM_OAUTH2SERVICE_ACCOUNT_EMAIL: None,
|
||||||
@ -254,6 +257,7 @@ MESSAGE_PLEASE_AUTHORIZE_SERVICE_ACCOUNT = u'Please authorize your Service accou
|
|||||||
MESSAGE_REQUEST_COMPLETED_NO_FILES = u'Request completed but no results/files were returned, try requesting again'
|
MESSAGE_REQUEST_COMPLETED_NO_FILES = u'Request completed but no results/files were returned, try requesting again'
|
||||||
MESSAGE_REQUEST_NOT_COMPLETE = u'Request needs to be completed before downloading, current status is: {0}'
|
MESSAGE_REQUEST_NOT_COMPLETE = u'Request needs to be completed before downloading, current status is: {0}'
|
||||||
MESSAGE_RESULTS_TOO_LARGE_FOR_GOOGLE_SPREADSHEET = u'Results are too large for Google Spreadsheets. Uploading as a regular CSV file.'
|
MESSAGE_RESULTS_TOO_LARGE_FOR_GOOGLE_SPREADSHEET = u'Results are too large for Google Spreadsheets. Uploading as a regular CSV file.'
|
||||||
|
MESSAGE_SERVICE_NOT_APPLICABLE = 'Service not applicable for this address: {0}'
|
||||||
MESSAGE_WIKI_INSTRUCTIONS_OAUTH2SERVICE_JSON = u'Please follow the instructions at this site to setup a Service account.'
|
MESSAGE_WIKI_INSTRUCTIONS_OAUTH2SERVICE_JSON = u'Please follow the instructions at this site to setup a Service account.'
|
||||||
|
|
||||||
OAUTH_TOKEN_ERRORS = [u'access_denied', u'unauthorized_client: Unauthorized client or scope in request.', u'access_denied: Requested client not authorized.', u'invalid_grant: Not a valid email.', u'invalid_request: Invalid impersonation prn email address.']
|
OAUTH_TOKEN_ERRORS = [u'access_denied', u'unauthorized_client: Unauthorized client or scope in request.', u'access_denied: Requested client not authorized.', u'invalid_grant: Not a valid email.', u'invalid_request: Invalid impersonation prn email address.']
|
||||||
@ -609,17 +613,20 @@ def doGAMVersion():
|
|||||||
platform.platform(), platform.machine(),
|
platform.platform(), platform.machine(),
|
||||||
GM_Globals[GM_GAM_PATH])
|
GM_Globals[GM_GAM_PATH])
|
||||||
|
|
||||||
|
|
||||||
def handleOAuthTokenError(e, soft_errors):
|
def handleOAuthTokenError(e, soft_errors):
|
||||||
if e.message in OAUTH_TOKEN_ERRORS:
|
if e.message in OAUTH_TOKEN_ERRORS:
|
||||||
if soft_errors:
|
if not GM_Globals[GM_CURRENT_API_USER]:
|
||||||
return None
|
|
||||||
sys.stderr.write(u'{0}{1}\n'.format(ERROR_PREFIX, MESSAGE_API_ACCESS_DENIED.format(GM_Globals[GM_OAUTH2SERVICE_ACCOUNT_CLIENT_ID],
|
sys.stderr.write(u'{0}{1}\n'.format(ERROR_PREFIX, MESSAGE_API_ACCESS_DENIED.format(GM_Globals[GM_OAUTH2SERVICE_ACCOUNT_CLIENT_ID],
|
||||||
u','.join(GM_Globals[GM_CURRENT_API_SCOPES]), GC_Values[GC_ADMIN])))
|
u','.join(GM_Globals[GM_CURRENT_API_SCOPES]), GC_Values[GC_ADMIN])))
|
||||||
systemErrorExit(12, MESSAGE_API_ACCESS_CONFIG)
|
systemErrorExit(12, MESSAGE_API_ACCESS_CONFIG)
|
||||||
|
else:
|
||||||
|
systemErrorExit(19, MESSAGE_SERVICE_NOT_APPLICABLE.format(GM_Globals[GM_CURRENT_API_USER]))
|
||||||
|
if soft_errors:
|
||||||
|
sys.stderr.write(u'{0}Authentication Token Error - {1}\n'.format(ERROR_PREFIX, e))
|
||||||
|
return None
|
||||||
systemErrorExit(18, u'Authentication Token Error - {0}'.format(e))
|
systemErrorExit(18, u'Authentication Token Error - {0}'.format(e))
|
||||||
|
|
||||||
def tryOAuth(gdataObject, soft_errors=False):
|
def getGDataOAuthToken(gdataObject):
|
||||||
credentials = oauth2client.client.SignedJwtAssertionCredentials(GM_Globals[GM_OAUTH2SERVICE_ACCOUNT_EMAIL],
|
credentials = oauth2client.client.SignedJwtAssertionCredentials(GM_Globals[GM_OAUTH2SERVICE_ACCOUNT_EMAIL],
|
||||||
GM_Globals[GM_OAUTH2SERVICE_KEY],
|
GM_Globals[GM_OAUTH2SERVICE_KEY],
|
||||||
scope=GM_Globals[GM_CURRENT_API_SCOPES], user_agent=GAM_INFO, sub=GC_Values[GC_ADMIN])
|
scope=GM_Globals[GM_CURRENT_API_SCOPES], user_agent=GAM_INFO, sub=GC_Values[GC_ADMIN])
|
||||||
@ -630,17 +637,14 @@ def tryOAuth(gdataObject, soft_errors=False):
|
|||||||
except httplib2.ServerNotFoundError as e:
|
except httplib2.ServerNotFoundError as e:
|
||||||
systemErrorExit(4, e)
|
systemErrorExit(4, e)
|
||||||
except oauth2client.client.AccessTokenRefreshError, e:
|
except oauth2client.client.AccessTokenRefreshError, e:
|
||||||
return handleOAuthTokenError(e, soft_errors)
|
return handleOAuthTokenError(e, False)
|
||||||
gdataObject.additional_headers = {u'Authorization': u'Bearer %s' % credentials.access_token}
|
gdataObject.additional_headers = {u'Authorization': u'Bearer %s' % credentials.access_token}
|
||||||
gdataObject.domain = GC_Values[GC_DOMAIN]
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def checkGDataError(e, service):
|
def checkGDataError(e, service):
|
||||||
# First check for errors that need special handling
|
# First check for errors that need special handling
|
||||||
if e[0].get(u'reason', u'') in [u'Token invalid - Invalid token: Stateless token expired', u'Token invalid - Invalid token: Token not found']:
|
if e[0].get(u'reason', u'') in [u'Token invalid - Invalid token: Stateless token expired', u'Token invalid - Invalid token: Token not found']:
|
||||||
keep_domain = service.domain
|
getGDataOAuthToken(service)
|
||||||
tryOAuth(service)
|
|
||||||
service.domain = keep_domain
|
|
||||||
return False
|
return False
|
||||||
if e[0][u'body'].startswith(u'Required field must not be blank:') or e[0][u'body'].startswith(u'These characters are not allowed:'):
|
if e[0][u'body'].startswith(u'Required field must not be blank:') or e[0][u'body'].startswith(u'These characters are not allowed:'):
|
||||||
return e[0]['body']
|
return e[0]['body']
|
||||||
@ -763,7 +767,7 @@ def callGAPI(service, function, silent_errors=False, soft_errors=False, throw_re
|
|||||||
return None
|
return None
|
||||||
sys.exit(int(http_status))
|
sys.exit(int(http_status))
|
||||||
except oauth2client.client.AccessTokenRefreshError, e:
|
except oauth2client.client.AccessTokenRefreshError, e:
|
||||||
return handleOAuthTokenError(e, False)
|
return handleOAuthTokenError(e, soft_errors)
|
||||||
except httplib2.CertificateValidationUnsupported:
|
except httplib2.CertificateValidationUnsupported:
|
||||||
noPythonSSLExit()
|
noPythonSSLExit()
|
||||||
except TypeError, e:
|
except TypeError, e:
|
||||||
@ -881,6 +885,7 @@ def getAPIversionHttpService(api):
|
|||||||
def buildGAPIObject(api, act_as=None, soft_errors=False):
|
def buildGAPIObject(api, act_as=None, soft_errors=False):
|
||||||
svcsub = act_as if act_as else GC_Values[GC_ADMIN]
|
svcsub = act_as if act_as else GC_Values[GC_ADMIN]
|
||||||
api_version, http, service = getAPIversionHttpService(api)
|
api_version, http, service = getAPIversionHttpService(api)
|
||||||
|
GM_Globals[GM_CURRENT_API_USER] = act_as
|
||||||
GM_Globals[GM_CURRENT_API_SCOPES] = GM_Globals[GM_GAMSCOPES_BY_API].get(api_version, [])
|
GM_Globals[GM_CURRENT_API_SCOPES] = GM_Globals[GM_GAMSCOPES_BY_API].get(api_version, [])
|
||||||
if not GM_Globals[GM_CURRENT_API_SCOPES]:
|
if not GM_Globals[GM_CURRENT_API_SCOPES]:
|
||||||
systemErrorExit(15, MESSAGE_NO_SCOPES_FOR_API.format(service._rootDesc[u'title']))
|
systemErrorExit(15, MESSAGE_NO_SCOPES_FOR_API.format(service._rootDesc[u'title']))
|
||||||
@ -889,6 +894,8 @@ def buildGAPIObject(api, act_as=None, soft_errors=False):
|
|||||||
scope=GM_Globals[GM_CURRENT_API_SCOPES], user_agent=GAM_INFO, sub=svcsub)
|
scope=GM_Globals[GM_CURRENT_API_SCOPES], user_agent=GAM_INFO, sub=svcsub)
|
||||||
try:
|
try:
|
||||||
service._http = credentials.authorize(http)
|
service._http = credentials.authorize(http)
|
||||||
|
except httplib2.ServerNotFoundError as e:
|
||||||
|
systemErrorExit(4, e)
|
||||||
except oauth2client.client.AccessTokenRefreshError, e:
|
except oauth2client.client.AccessTokenRefreshError, e:
|
||||||
return handleOAuthTokenError(e, soft_errors)
|
return handleOAuthTokenError(e, soft_errors)
|
||||||
return service
|
return service
|
||||||
@ -899,31 +906,33 @@ GDATA_API_INFO = {
|
|||||||
u'email-settings': u'Email Settings API',
|
u'email-settings': u'Email Settings API',
|
||||||
}
|
}
|
||||||
|
|
||||||
def commonAppsObjInit(appsObj, api):
|
def initGDataObject(gdataObj, api):
|
||||||
getOAuth2ServiceDetails()
|
getOAuth2ServiceDetails()
|
||||||
api, _, api_version = getAPIVersion(api)
|
api, _, api_version = getAPIVersion(api)
|
||||||
|
GM_Globals[GM_CURRENT_API_USER] = None
|
||||||
GM_Globals[GM_CURRENT_API_SCOPES] = GM_Globals[GM_GAMSCOPES_BY_API].get(api_version, [])
|
GM_Globals[GM_CURRENT_API_SCOPES] = GM_Globals[GM_GAMSCOPES_BY_API].get(api_version, [])
|
||||||
if not GM_Globals[GM_CURRENT_API_SCOPES]:
|
if not GM_Globals[GM_CURRENT_API_SCOPES]:
|
||||||
systemErrorExit(15, MESSAGE_NO_SCOPES_FOR_API.format(GDATA_API_INFO[api]))
|
systemErrorExit(15, MESSAGE_NO_SCOPES_FOR_API.format(GDATA_API_INFO[api]))
|
||||||
tryOAuth(appsObj)
|
getGDataOAuthToken(gdataObj)
|
||||||
|
gdataObj.domain = GC_Values[GC_DOMAIN]
|
||||||
#Identify GAM to Google's Servers
|
#Identify GAM to Google's Servers
|
||||||
appsObj.source = GAM_INFO
|
gdataObj.source = GAM_INFO
|
||||||
#Show debugging output if debug.gam exists
|
#Show debugging output if debug.gam exists
|
||||||
if GC_Values[GC_DEBUG_LEVEL] > 0:
|
if GC_Values[GC_DEBUG_LEVEL] > 0:
|
||||||
appsObj.debug = True
|
gdataObj.debug = True
|
||||||
return appsObj
|
return gdataObj
|
||||||
|
|
||||||
def getAdminSettingsObject():
|
def getAdminSettingsObject():
|
||||||
import gdata.apps.adminsettings.service
|
import gdata.apps.adminsettings.service
|
||||||
return commonAppsObjInit(gdata.apps.adminsettings.service.AdminSettingsService(), u'admin-settings')
|
return initGDataObject(gdata.apps.adminsettings.service.AdminSettingsService(), u'admin-settings')
|
||||||
|
|
||||||
def getAuditObject():
|
def getAuditObject():
|
||||||
import gdata.apps.audit.service
|
import gdata.apps.audit.service
|
||||||
return commonAppsObjInit(gdata.apps.audit.service.AuditService(), u'email-audit')
|
return initGDataObject(gdata.apps.audit.service.AuditService(), u'email-audit')
|
||||||
|
|
||||||
def getEmailSettingsObject():
|
def getEmailSettingsObject():
|
||||||
import gdata.apps.emailsettings.service
|
import gdata.apps.emailsettings.service
|
||||||
return commonAppsObjInit(gdata.apps.emailsettings.service.EmailSettingsService(), u'email-settings')
|
return initGDataObject(gdata.apps.emailsettings.service.EmailSettingsService(), u'email-settings')
|
||||||
|
|
||||||
def geturl(url, dst):
|
def geturl(url, dst):
|
||||||
import urllib2
|
import urllib2
|
||||||
|
Reference in New Issue
Block a user