mirror of
https://github.com/GAM-team/GAM.git
synced 2025-07-09 14:13:35 +00:00
Correct gam update org <OrgUnit> add cros /all cros
This commit is contained in:
223
src/gam.py
223
src/gam.py
@ -154,27 +154,15 @@ gam.exe update group announcements add member jsmith
|
|||||||
|
|
||||||
def setGamDirs():
|
def setGamDirs():
|
||||||
global gamPath, gamSiteConfigDir, gamUserConfigDir, gamDriveDir, gamCacheDir
|
global gamPath, gamSiteConfigDir, gamUserConfigDir, gamDriveDir, gamCacheDir
|
||||||
|
gamPath = os.path.dirname(os.path.realpath(__file__))
|
||||||
gamPath = os.path.dirname(os.path.realpath(sys.argv[0]))
|
gamSiteConfigDir = os.environ.get(u'GAMSITECONFIGDIR', gamPath)
|
||||||
try:
|
gamUserConfigDir = os.environ.get(u'GAMUSERCONFIGDIR', gamPath)
|
||||||
gamSiteConfigDir = os.environ[u'GAMSITECONFIGDIR']
|
|
||||||
except KeyError:
|
|
||||||
gamSiteConfigDir = gamPath
|
|
||||||
try:
|
|
||||||
gamUserConfigDir = os.environ[u'GAMUSERCONFIGDIR']
|
|
||||||
except KeyError:
|
|
||||||
gamUserConfigDir = gamPath
|
|
||||||
try:
|
|
||||||
gamCacheDir = os.environ[u'GAMCACHEDIR']
|
|
||||||
except KeyError:
|
|
||||||
gamCacheDir = os.path.join(gamPath, u'gamcache')
|
|
||||||
try:
|
|
||||||
gamDriveDir = os.environ[u'GAMDRIVEDIR']
|
|
||||||
except KeyError:
|
|
||||||
gamDriveDir = gamPath
|
|
||||||
|
|
||||||
if os.path.isfile(os.path.join(gamUserConfigDir, u'nocache.txt')):
|
if os.path.isfile(os.path.join(gamUserConfigDir, u'nocache.txt')):
|
||||||
gamCacheDir = None
|
gamCacheDir = None
|
||||||
|
else:
|
||||||
|
gamCacheDir = os.environ.get(u'GAMCACHEDIR', os.path.join(gamPath, u'gamcache'))
|
||||||
|
gamDriveDir = os.environ.get(u'GAMDRIVEDIR', gamPath)
|
||||||
|
|
||||||
|
|
||||||
def doGAMVersion():
|
def doGAMVersion():
|
||||||
import struct
|
import struct
|
||||||
@ -241,111 +229,63 @@ def commonAppsObjInit(appsObj):
|
|||||||
return appsObj
|
return appsObj
|
||||||
|
|
||||||
def checkErrorCode(e, service):
|
def checkErrorCode(e, service):
|
||||||
try:
|
|
||||||
if e[0]['reason'] in [u'Token invalid - Invalid token: Stateless token expired', u'Token invalid - Invalid token: Token not found']:
|
# First check for errors that need special handling
|
||||||
keep_domain = service.domain
|
if e[0].get('reason', '') in [u'Token invalid - Invalid token: Stateless token expired', u'Token invalid - Invalid token: Token not found']:
|
||||||
tryOAuth(service)
|
keep_domain = service.domain
|
||||||
service.domain = keep_domain
|
tryOAuth(service)
|
||||||
return False
|
service.domain = keep_domain
|
||||||
except KeyError:
|
return False
|
||||||
pass
|
|
||||||
if e[0]['body'][:34] in [u'Required field must not be blank: ', u'These characters are not allowed: ']:
|
if e[0]['body'][:34] in [u'Required field must not be blank: ', u'These characters are not allowed: ']:
|
||||||
return e[0]['body']
|
return e[0]['body']
|
||||||
if e.error_code == 600 and e[0][u'body'] == u'Quota exceeded for the current request' or e[0][u'reason'] == u'Bad Gateway':
|
if e.error_code == 600 and e[0][u'body'] == u'Quota exceeded for the current request' or e[0][u'reason'] == u'Bad Gateway':
|
||||||
return False
|
return False
|
||||||
if e.error_code == 600 and e[0][u'reason'] == u'Token invalid - Invalid token: Token disabled, revoked, or expired.':
|
if e.error_code == 600 and e[0][u'reason'] == u'Token invalid - Invalid token: Token disabled, revoked, or expired.':
|
||||||
return u'403 - Token disabled, revoked, or expired. Please delete and re-create oauth.txt'
|
return u'403 - Token disabled, revoked, or expired. Please delete and re-create oauth.txt'
|
||||||
if e.error_code == 1000: # UnknownError
|
|
||||||
return False
|
# We got a "normal" error, define the mapping below
|
||||||
elif e.error_code == 1001: # ServerBusy
|
error_code_map = {
|
||||||
return False
|
1000: False,
|
||||||
elif e.error_code == 1002:
|
1001: False,
|
||||||
return u'1002 - Unauthorized and forbidden'
|
1002: u'Unauthorized and forbidden',
|
||||||
elif e.error_code == 1100:
|
1100: u'User deleted recently',
|
||||||
return u'1100 - User deleted recently'
|
1200: u'Domain user limit exceeded',
|
||||||
elif e.error_code == 1200:
|
1201: u'Domain alias limit exceeded',
|
||||||
return u'1200 - Domain user limit exceeded'
|
1202: u'Domain suspended',
|
||||||
elif e.error_code == 1201:
|
1203: u'Domain feature unavailable',
|
||||||
return u'1201 - Domain alias limit exceeded'
|
1300: u'Entity %s exists' % e.invalidInput or '<unknown>',
|
||||||
elif e.error_code == 1202:
|
1301: u'Entity %s Does Not Exist' % e.invalidInput or '<unknown>',
|
||||||
return u'1202 - Domain suspended'
|
1302: u'Entity Name Is Reserved',
|
||||||
elif e.error_code == 1203:
|
1303: u'Entity %s name not valid' % e.invalidInput or '<unknown>',
|
||||||
return u'1203 - Domain feature unavailable'
|
1306: u'%s has members. Cannot delete.' % e.invalidInput or '<unknown>',
|
||||||
elif e.error_code == 1300:
|
1400: u'Invalid Given Name',
|
||||||
if e.invalidInput != '':
|
1401: u'Invalid Family Name',
|
||||||
return u'1300 - Entity %s exists' % e.invalidInput
|
1402: u'Invalid Password',
|
||||||
else:
|
1403: u'Invalid Username',
|
||||||
return u'1300 - Entity exists'
|
1404: u'Invalid Hash Function Name',
|
||||||
elif e.error_code == 1301:
|
1405: u'Invalid Hash Digest Length',
|
||||||
if e.invalidInput != '':
|
1406: u'Invalid Email Address',
|
||||||
return u'1301 - Entity %s Does Not Exist' % e.invalidInput
|
1407: u'Invalid Query Parameter Value',
|
||||||
else:
|
1408: u'Invalid SSO Signing Key',
|
||||||
return u'1301 - Entity Does Not Exist'
|
1409: u'Invalid Encryption Public Key',
|
||||||
elif e.error_code == 1302:
|
1410: u'Feature Unavailable For User',
|
||||||
return u'1302 - Entity Name Is Reserved'
|
1500: u'Too Many Recipients On Email List',
|
||||||
elif e.error_code == 1303:
|
1501: u'Too Many Aliases For User',
|
||||||
if e.invalidInput != '':
|
1502: u'Too Many Delegates For User',
|
||||||
return u'1303 - Entity %s name not valid' % e.invalidInput
|
1601: u'Duplicate Destinations',
|
||||||
else:
|
1602: u'Too Many Destinations',
|
||||||
return u'1303 - Entity name not valid'
|
1603: u'Invalid Route Address',
|
||||||
elif e.error_code == 1306:
|
1700: u'Group Cannot Contain Cycle',
|
||||||
if e.invalidInput != '':
|
1800: u'Group Cannot Contain Cycle',
|
||||||
return u'1306 - %s has members. Cannot delete.' % e.invalidInput
|
1801: u'Invalid value %s' % e.invalidInput or ''
|
||||||
else:
|
}
|
||||||
return u'1306 - Entity has members. Cannot delete.'
|
|
||||||
elif e.error_code == 1400:
|
return u'%s - %s' % (e.error_code, error_code_map.get(e.error_code, u'Unknown Error: %s' % (e.error_code, str(e))))
|
||||||
return u'1400 - Invalid Given Name'
|
|
||||||
elif e.error_code == 1401:
|
|
||||||
return u'1401 - Invalid Family Name'
|
|
||||||
elif e.error_code == 1402:
|
|
||||||
return u'1402 - Invalid Password'
|
|
||||||
elif e.error_code == 1403:
|
|
||||||
return u'1403 - Invalid Username'
|
|
||||||
elif e.error_code == 1404:
|
|
||||||
return u'1404 - Invalid Hash Function Name'
|
|
||||||
elif e.error_code == 1405:
|
|
||||||
return u'1405 - Invalid Hash Digest Length'
|
|
||||||
elif e.error_code == 1406:
|
|
||||||
return u'1406 - Invalid Email Address'
|
|
||||||
elif e.error_code == 1407:
|
|
||||||
return u'1407 - Invalid Query Parameter Value'
|
|
||||||
elif e.error_code == 1408:
|
|
||||||
return u'1408 - Invalid SSO Signing Key'
|
|
||||||
elif e.error_code == 1409:
|
|
||||||
return u'1409 - Invalid Encryption Public Key'
|
|
||||||
elif e.error_code == 1410:
|
|
||||||
return u'1410 - Feature Unavailable For User'
|
|
||||||
elif e.error_code == 1500:
|
|
||||||
return u'1500 - Too Many Recipients On Email List'
|
|
||||||
elif e.error_code == 1501:
|
|
||||||
return u'1501 - Too Many Aliases For User'
|
|
||||||
elif e.error_code == 1502:
|
|
||||||
return u'1502 - Too Many Delegates For User'
|
|
||||||
elif e.error_code == 1601:
|
|
||||||
return u'1601 - Duplicate Destinations'
|
|
||||||
elif e.error_code == 1602:
|
|
||||||
return u'1602 - Too Many Destinations'
|
|
||||||
elif e.error_code == 1603:
|
|
||||||
return u'1603 - Invalid Route Address'
|
|
||||||
elif e.error_code == 1700:
|
|
||||||
return u'1700 - Group Cannot Contain Cycle'
|
|
||||||
elif e.error_code == 1800:
|
|
||||||
return u'1800 - Invalid Domain Edition'
|
|
||||||
elif e.error_code == 1801:
|
|
||||||
if e.invalidInput != '':
|
|
||||||
return u'1801 - Invalid value %s' % e.invalidInput
|
|
||||||
else:
|
|
||||||
return u'1801 - Invalid Value'
|
|
||||||
else:
|
|
||||||
return u'%s: Unknown Error: %s' % (e.error_code, str(e))
|
|
||||||
|
|
||||||
def tryOAuth(gdataObject):
|
def tryOAuth(gdataObject):
|
||||||
global domain
|
global domain
|
||||||
global customerId
|
global customerId
|
||||||
try:
|
oauth2file = os.path.join(gamUserConfigDir, os.environ.get(u'OAUTHFILE', 'oauth2.txt'))
|
||||||
oauth2file = os.path.join(gamUserConfigDir, os.environ[u'OAUTHFILE'])
|
|
||||||
except KeyError:
|
|
||||||
oauth2file = os.path.join(gamUserConfigDir, u'oauth2.txt')
|
|
||||||
storage = oauth2client.file.Storage(oauth2file)
|
storage = oauth2client.file.Storage(oauth2file)
|
||||||
credentials = storage.get()
|
credentials = storage.get()
|
||||||
if credentials is None or credentials.invalid:
|
if credentials is None or credentials.invalid:
|
||||||
@ -357,14 +297,8 @@ def tryOAuth(gdataObject):
|
|||||||
disable_ssl_certificate_validation = True
|
disable_ssl_certificate_validation = True
|
||||||
credentials.refresh(httplib2.Http(disable_ssl_certificate_validation=disable_ssl_certificate_validation))
|
credentials.refresh(httplib2.Http(disable_ssl_certificate_validation=disable_ssl_certificate_validation))
|
||||||
gdataObject.additional_headers = {u'Authorization': u'Bearer %s' % credentials.access_token}
|
gdataObject.additional_headers = {u'Authorization': u'Bearer %s' % credentials.access_token}
|
||||||
try:
|
domain = os.environ.get(u'GA_DOMAIN', credentials.id_token[u'hd']).lower()
|
||||||
domain = os.environ[u'GA_DOMAIN'].lower()
|
customerId = os.environ.get(u'CUSTOMER_ID', 'my_customer')
|
||||||
except KeyError:
|
|
||||||
domain = credentials.id_token[u'hd'].lower()
|
|
||||||
try:
|
|
||||||
customerId = os.environ[u'CUSTOMER_ID']
|
|
||||||
except KeyError:
|
|
||||||
customerId = u'my_customer'
|
|
||||||
gdataObject.domain = domain
|
gdataObject.domain = domain
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -556,10 +490,7 @@ def getAPIScope(api):
|
|||||||
|
|
||||||
def buildGAPIObject(api):
|
def buildGAPIObject(api):
|
||||||
global domain, customerId
|
global domain, customerId
|
||||||
try:
|
oauth2file = os.path.join(gamUserConfigDir, os.environ.get(u'OAUTHFILE', 'oauth2.txt'))
|
||||||
oauth2file = os.path.join(gamUserConfigDir, os.environ[u'OAUTHFILE'])
|
|
||||||
except KeyError:
|
|
||||||
oauth2file = os.path.join(gamUserConfigDir, u'oauth2.txt')
|
|
||||||
storage = oauth2client.file.Storage(oauth2file)
|
storage = oauth2client.file.Storage(oauth2file)
|
||||||
credentials = storage.get()
|
credentials = storage.get()
|
||||||
if credentials is None or credentials.invalid:
|
if credentials is None or credentials.invalid:
|
||||||
@ -622,10 +553,7 @@ def buildGAPIObject(api):
|
|||||||
return service
|
return service
|
||||||
|
|
||||||
def buildGAPIServiceObject(api, act_as=None, soft_errors=False):
|
def buildGAPIServiceObject(api, act_as=None, soft_errors=False):
|
||||||
try:
|
oauth2servicefile = os.path.join(gamUserConfigDir, os.environ.get(u'OAUTHSERVICEFILE', 'oauth2service'))
|
||||||
oauth2servicefile = os.path.join(gamUserConfigDir, os.environ[u'OAUTHSERVICEFILE'])
|
|
||||||
except KeyError:
|
|
||||||
oauth2servicefile = os.path.join(gamUserConfigDir, u'oauth2service')
|
|
||||||
oauth2servicefilejson = u'%s.json' % oauth2servicefile
|
oauth2servicefilejson = u'%s.json' % oauth2servicefile
|
||||||
oauth2servicefilep12 = u'%s.p12' % oauth2servicefile
|
oauth2servicefilep12 = u'%s.p12' % oauth2servicefile
|
||||||
try:
|
try:
|
||||||
@ -5877,7 +5805,7 @@ def doUpdateOrg():
|
|||||||
users = getUsersToModify(entity_type=sys.argv[5], entity=sys.argv[6])
|
users = getUsersToModify(entity_type=sys.argv[5], entity=sys.argv[6])
|
||||||
else:
|
else:
|
||||||
users = getUsersToModify(entity_type=u'user', entity=sys.argv[5])
|
users = getUsersToModify(entity_type=u'user', entity=sys.argv[5])
|
||||||
if sys.argv[5].lower() == u'cros':
|
if (sys.argv[5].lower() == u'cros') or ((sys.argv[5].lower() == u'all') and (sys.argv[6].lower == u'cros')):
|
||||||
cros_count = len(users)
|
cros_count = len(users)
|
||||||
current_cros = 1
|
current_cros = 1
|
||||||
for cros in users:
|
for cros in users:
|
||||||
@ -5960,10 +5888,7 @@ def doGetUserInfo(user_email=None):
|
|||||||
try:
|
try:
|
||||||
user_email = sys.argv[3]
|
user_email = sys.argv[3]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
try:
|
oauth2file = os.path.join(gamUserConfigDir, os.environ.get(u'OAUTHFILE'), 'oauth2.txt')
|
||||||
oauth2file = os.path.join(gamUserConfigDir, os.environ[u'OAUTHFILE'])
|
|
||||||
except KeyError:
|
|
||||||
oauth2file = os.path.join(gamUserConfigDir, u'oauth2.txt')
|
|
||||||
storage = oauth2client.file.Storage(oauth2file)
|
storage = oauth2client.file.Storage(oauth2file)
|
||||||
credentials = storage.get()
|
credentials = storage.get()
|
||||||
if credentials is None or credentials.invalid:
|
if credentials is None or credentials.invalid:
|
||||||
@ -8370,6 +8295,12 @@ def getUsersToModify(entity_type=None, entity=None, silent=False, return_uids=Fa
|
|||||||
users.append(member[u'deviceId'])
|
users.append(member[u'deviceId'])
|
||||||
if not silent:
|
if not silent:
|
||||||
sys.stderr.write(u"done getting %s CrOS devices.\r\n" % len(users))
|
sys.stderr.write(u"done getting %s CrOS devices.\r\n" % len(users))
|
||||||
|
else:
|
||||||
|
print 'ERROR: %s is not a valid argument for "gam all"' % entity
|
||||||
|
sys.exit(3)
|
||||||
|
elif entity_type == u'cros':
|
||||||
|
users = entity.replace(u',', u' ').split()
|
||||||
|
entity = u'cros'
|
||||||
else:
|
else:
|
||||||
print 'ERROR: %s is not a valid argument for "gam"' % entity_type
|
print 'ERROR: %s is not a valid argument for "gam"' % entity_type
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
@ -8396,10 +8327,7 @@ def OAuthInfo():
|
|||||||
try:
|
try:
|
||||||
access_token = sys.argv[3]
|
access_token = sys.argv[3]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
try:
|
oauth2file = os.path.join(gamUserConfigDir, os.environ.get(u'OAUTHFILE', 'oauth2.txt'))
|
||||||
oauth2file = os.path.join(gamUserConfigDir, os.environ[u'OAUTHFILE'])
|
|
||||||
except KeyError:
|
|
||||||
oauth2file = os.path.join(gamUserConfigDir, u'oauth2.txt')
|
|
||||||
storage = oauth2client.file.Storage(oauth2file)
|
storage = oauth2client.file.Storage(oauth2file)
|
||||||
credentials = storage.get()
|
credentials = storage.get()
|
||||||
if credentials is None or credentials.invalid:
|
if credentials is None or credentials.invalid:
|
||||||
@ -8434,10 +8362,7 @@ def OAuthInfo():
|
|||||||
print u'Google Apps Admin: Unknown'
|
print u'Google Apps Admin: Unknown'
|
||||||
|
|
||||||
def doDeleteOAuth():
|
def doDeleteOAuth():
|
||||||
try:
|
oauth2file = os.path.join(gamUserConfigDir, os.environ.get(u'OAUTHFILE', 'oauth2.txt'))
|
||||||
oauth2file = os.path.join(gamUserConfigDir, os.environ[u'OAUTHFILE'])
|
|
||||||
except KeyError:
|
|
||||||
oauth2file = os.path.join(gamUserConfigDir, u'oauth2.txt')
|
|
||||||
storage = oauth2client.file.Storage(oauth2file)
|
storage = oauth2client.file.Storage(oauth2file)
|
||||||
credentials = storage.get()
|
credentials = storage.get()
|
||||||
try:
|
try:
|
||||||
@ -8499,10 +8424,7 @@ possible_scopes = [u'https://www.googleapis.com/auth/admin.directory.group',
|
|||||||
u'https://www.googleapis.com/auth/admin.directory.domain'] # Domain API
|
u'https://www.googleapis.com/auth/admin.directory.domain'] # Domain API
|
||||||
|
|
||||||
def doRequestOAuth(incremental_auth=False):
|
def doRequestOAuth(incremental_auth=False):
|
||||||
try:
|
CLIENT_SECRETS = os.path.join(gamUserConfigDir, os.environ.get(u'CLIENTSECRETSFILE', 'client_secrets.json'))
|
||||||
CLIENT_SECRETS = os.path.join(gamUserConfigDir, os.environ[u'CLIENTSECRETSFILE'])
|
|
||||||
except KeyError:
|
|
||||||
CLIENT_SECRETS = os.path.join(gamUserConfigDir, u'client_secrets.json')
|
|
||||||
MISSING_CLIENT_SECRETS_MESSAGE = u"""
|
MISSING_CLIENT_SECRETS_MESSAGE = u"""
|
||||||
WARNING: Please configure OAuth 2.0
|
WARNING: Please configure OAuth 2.0
|
||||||
|
|
||||||
@ -8625,10 +8547,7 @@ access or an 'a' to grant action-only access.
|
|||||||
FLOW = oauth2client.client.flow_from_clientsecrets(CLIENT_SECRETS,
|
FLOW = oauth2client.client.flow_from_clientsecrets(CLIENT_SECRETS,
|
||||||
scope=scopes,
|
scope=scopes,
|
||||||
message=MISSING_CLIENT_SECRETS_MESSAGE)
|
message=MISSING_CLIENT_SECRETS_MESSAGE)
|
||||||
try:
|
oauth2file = os.path.join(gamUserConfigDir, os.environ.get(u'OAUTHFILE', 'oauth2.txt'))
|
||||||
oauth2file = os.path.join(gamUserConfigDir, os.environ[u'OAUTHFILE'])
|
|
||||||
except KeyError:
|
|
||||||
oauth2file = os.path.join(gamUserConfigDir, u'oauth2.txt')
|
|
||||||
storage = oauth2client.file.Storage(oauth2file)
|
storage = oauth2client.file.Storage(oauth2file)
|
||||||
credentials = storage.get()
|
credentials = storage.get()
|
||||||
flags = cmd_flags()
|
flags = cmd_flags()
|
||||||
@ -8661,7 +8580,7 @@ def run_batch(items):
|
|||||||
if not getattr(sys, 'frozen', False): # we're not frozen
|
if not getattr(sys, 'frozen', False): # we're not frozen
|
||||||
python_cmd.append(os.path.realpath(sys.argv[0]))
|
python_cmd.append(os.path.realpath(sys.argv[0]))
|
||||||
try:
|
try:
|
||||||
num_worker_threads = int(os.environ[u'GAM_THREADS'])
|
num_worker_threads = int(os.environ.get(u'GAM_THREADS', 5))
|
||||||
except (TypeError, KeyError):
|
except (TypeError, KeyError):
|
||||||
num_worker_threads = 5
|
num_worker_threads = 5
|
||||||
import Queue, threading
|
import Queue, threading
|
||||||
|
Reference in New Issue
Block a user