New User Invitation API

This commit is contained in:
Jay Lee
2021-03-11 17:07:13 -05:00
parent 66651d0eed
commit ce4f74bc61
2 changed files with 171 additions and 0 deletions

View File

@ -55,6 +55,7 @@ from gam.gapi import cloudidentity as gapi_cloudidentity
from gam.gapi import cbcm as gapi_cbcm
from gam.gapi.cloudidentity import devices as gapi_cloudidentity_devices
from gam.gapi.cloudidentity import groups as gapi_cloudidentity_groups
from gam.gapi.cloudidentity import userinvitations as gapi_cloudidentity_userinvitations
from gam.gapi import contactdelegation as gapi_contactdelegation
from gam.gapi.directory import asps as gapi_directory_asps
from gam.gapi.directory import cros as gapi_directory_cros
@ -10262,6 +10263,11 @@ OAUTH2_SCOPES = [
'subscopes': ['readonly'],
'scopes': 'https://www.googleapis.com/auth/cloud-identity.groups'
},
{
'name': 'Cloud Identity - User Invitations',
'subscopes': ['readonly'],
'scopes': 'https://www.googleapis.com/auth/cloud-identity.userinvitations'
},
{
'name': 'Contact Delegation',
'subscopes': ['readonly'],
@ -11168,6 +11174,8 @@ def ProcessGAMCommand(args):
gapi_directory_roles.create()
elif argument in ['browsertoken', 'browsertokens']:
gapi_cbcm.createtoken()
elif argument in ['userinvitation', 'userinvitations']:
gapi_cloudidentity_userinvitations.send()
else:
controlflow.invalid_argument_exit(argument, 'gam create')
sys.exit(0)
@ -11288,6 +11296,8 @@ def ProcessGAMCommand(args):
gapi_cloudidentity_devices.info_state()
elif argument in ['browser', 'browsers']:
gapi_cbcm.info()
elif argument in ['userinvitation', 'userinvitations']:
gapi_cloudidentity_userinvitations.get()
else:
controlflow.invalid_argument_exit(argument, 'gam info')
sys.exit(0)
@ -11295,6 +11305,8 @@ def ProcessGAMCommand(args):
argument = sys.argv[2].lower()
if argument in ['guardianinvitation', 'guardianinvitations']:
doCancelGuardianInvitation()
elif argument in ['userinvitation', 'userinvitations']:
gapi_cloudidentity_userinvitations.cancel()
else:
controlflow.invalid_argument_exit(argument, 'gam cancel')
sys.exit(0)
@ -11453,6 +11465,8 @@ def ProcessGAMCommand(args):
gapi_cbcm.printshowtokens(True)
elif argument in ['vaultcount']:
gapi_vault.print_count()
elif argument in ['userinvitations']:
gapi_cloudidentity_userinvitations.print_()
else:
controlflow.invalid_argument_exit(argument, 'gam print')
sys.exit(0)
@ -11560,6 +11574,11 @@ def ProcessGAMCommand(args):
else:
controlflow.invalid_argument_exit(argument, 'gam rotate')
sys.exit(0)
elif command == 'check':
argument = sys.argv[2].lower()
if argument in ['userinvitation', 'userinvitations']:
gapi_cloudidentity_userinvitations.is_invitable_user()
sys.exit(0)
elif command in ['cancelwipe', 'wipe', 'approve', 'block', 'sync']:
target = sys.argv[2].lower().replace('_', '')
if target in ['device', 'devices']:
@ -11889,6 +11908,8 @@ def ProcessGAMCommand(args):
checkWhat = sys.argv[4].replace('_', '').lower()
if checkWhat == 'serviceaccount':
doCheckServiceAccount(users)
elif checkWhat == 'isinvitable':
gapi_cloudidentity_userinvitations.bulk_is_invitable(users)
else:
controlflow.invalid_argument_exit(checkWhat,
'gam <users> check')

View File

@ -0,0 +1,150 @@
"""Methods related to Cloud Identity User Invitation API"""
# pylint: disable=unused-wildcard-import wildcard-import
import sys
import googleapiclient
from gam.var import *
from gam import controlflow
from gam import display
from gam import gapi
from gam.gapi import errors as gapi_errors
from gam.gapi import cloudidentity as gapi_cloudidentity
def _get_customerid():
''' returns customer in format needed for this API'''
customer = GC_Values[GC_CUSTOMER_ID]
if customer.startswith('C'):
customer = customer[1:]
return f'customers/{customer}'
def _reduce_name(name):
''' converts long name into email address'''
return name.split('/')[-1]
def _generic_action(action):
'''generic function to call actionable APIs'''
svc = gapi_cloudidentity.build('cloudidentity_beta')
customer = _get_customerid()
email = sys.argv[3].lower()
name = f'{customer}/userinvitations/{email}'
action_map = {
'cancel': 'Cancelling',
'send': 'Sending'
}
print_action = action_map[action]
kwargs = {}
if action != 'get':
kwargs['body'] = {}
print(f'{print_action} user invite...')
result = gapi.call(svc.customers().userinvitations(), action,
name=name, **kwargs)
name = result.get('response', {}).get('name')
if name:
result['response']['name'] = _reduce_name(name)
display.print_json(result)
def _generic_get(get_type):
'''generic function to call read data APIs'''
svc = gapi_cloudidentity.build('cloudidentity_beta')
customer = _get_customerid()
email = sys.argv[3].lower()
name = f'{customer}/userinvitations/{email}'
result = gapi.call(svc.customers().userinvitations(), get_type,
name=name)
if 'name' in result:
result['name'] = _reduce_name(result['name'])
display.print_json(result)
# /batch is broken for Cloud Identity. Once fixed move this to using batch.
# Current serial implementation will be SLOW...
def bulk_is_invitable(emails):
'''gam <users> check isinvitable'''
def _invite_result(request_id, response, _):
if response.get('isInvitableUser'):
rows.append({'invitableUsers': request_id})
svc = gapi_cloudidentity.build('cloudidentity_beta')
customer = _get_customerid()
todrive = False
#batch_size = 1000
#ebatch = svc.new_batch_http_request(callback=_invite_result)
rows = []
throw_reasons = [gapi_errors.ErrorReason.FOUR_O_THREE]
for email in emails:
name = f'{customer}/userinvitations/{email}'
endpoint = svc.customers().userinvitations()
#if len(ebatch._order) == batch_size:
# ebatch.execute()
# ebatch = svc.new_batch_http_request(callback=_invite_result)
#req = endpoint.isInvitableUser(name=name)
#ebatch.add(req, request_id=email)
try:
result = gapi.call(endpoint,
'isInvitableUser',
throw_reasons=throw_reasons,
name=name)
except googleapiclient.errors.HttpError:
continue
if result.get('isInvitableUser'):
rows.append({'invitableUsers': email})
#ebatch.execute()
titles = ['invitableUsers']
display.write_csv_file(rows, titles, 'Invitable Users', todrive)
def cancel():
'''gam cancel userinvitation <email>'''
_generic_action('cancel')
def get():
'''gam info userinvitation <email>'''
_generic_get('get')
def is_invitable_user():
'''gam check userinvitation <email>'''
_generic_get('isInvitableUser')
def send():
'''gam create userinvitation <email>'''
_generic_action('send')
def print_():
'''gam print userinvitations'''
svc = gapi_cloudidentity.build('cloudidentity_beta')
customer = _get_customerid()
todrive = False
titles = []
rows = []
filter_ = None
i = 3
while i < len(sys.argv):
myarg = sys.argv[i].lower().replace('_', '')
if myarg == 'filter':
filter_ = sys.argv[i+1]
i += 2
elif myarg == 'todrive':
todrive = True
i += 1
else:
controlflow.invalid_argument_exit(sys.argv[i],
'gam print userinvitations')
invites = gapi.get_all_pages(svc.customers().userinvitations(),
'list',
'userInvitations',
parent=customer,
filter=filter_)
for invite in invites:
invite['name'] = _reduce_name(invite['name'])
row = {}
for key, val in invite.items():
if key not in titles:
titles.append(key)
row[key] = val
rows.append(row)
display.write_csv_file(rows, titles, 'User Invitations', todrive)