def addACL(function): calendarId, cal = buildCalendarDataGAPIObject(sys.argv[2]) if not cal: return myarg = sys.argv[4].lower().replace('_', '') if myarg not in CALENDAR_ACL_ROLES_MAP: controlflow.expected_argument_exit('Role', ', '.join(CALENDAR_ACL_ROLES_MAP), myarg) body = {'role': CALENDAR_ACL_ROLES_MAP[myarg]} i = _getCalendarACLScope(5, body) sendNotifications = True while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'sendnotifications': sendNotifications = gam.getBoolean(sys.argv[i + 1], myarg) i += 2 else: controlflow.invalid_argument_exit( sys.argv[i], f'gam calendar <email> {function.lower()}') print(f'Calendar: {calendarId}, {function} ACL: {formatACLRule(body)}') gapi.call(cal.acl(), 'insert', calendarId=calendarId, body=body, sendNotifications=sendNotifications)
def transferSecCals(users): target_user = sys.argv[5] remove_source_user = sendNotifications = True i = 6 while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'keepuser': remove_source_user = False i += 1 elif myarg == 'sendnotifications': sendNotifications = gam.getBoolean(sys.argv[i + 1], myarg) i += 2 else: controlflow.invalid_argument_exit(sys.argv[i], 'gam <users> transfer seccals') if remove_source_user: target_user, target_cal = buildCalendarGAPIObject(target_user) if not target_cal: return for user in users: user, source_cal = buildCalendarGAPIObject(user) if not source_cal: continue calendars = gapi.get_all_pages(source_cal.calendarList(), 'list', 'items', soft_errors=True, minAccessRole='owner', showHidden=True, fields='items(id),nextPageToken') for calendar in calendars: calendarId = calendar['id'] if calendarId.find('@group.calendar.google.com') != -1: body = { 'role': 'owner', 'scope': { 'type': 'user', 'value': target_user } } gapi.call(source_cal.acl(), 'insert', calendarId=calendarId, body=body, sendNotifications=sendNotifications) if remove_source_user: body = { 'role': 'none', 'scope': { 'type': 'user', 'value': user } } gapi.call(target_cal.acl(), 'insert', calendarId=calendarId, body=body, sendNotifications=sendNotifications)
def getSendUpdates(myarg, i, cal): if myarg == 'notifyattendees': sendUpdates = 'all' i += 1 elif myarg == 'sendnotifications': sendUpdates = 'all' if gam.getBoolean(sys.argv[i + 1], myarg) else 'none' i += 2 else: # 'sendupdates': sendUpdatesMap = {} for val in cal._rootDesc['resources']['events']['methods']['delete'][ 'parameters']['sendUpdates']['enum']: sendUpdatesMap[val.lower()] = val sendUpdates = sendUpdatesMap.get(sys.argv[i + 1].lower(), False) if not sendUpdates: controlflow.expected_argument_exit('sendupdates', ', '.join(sendUpdatesMap), sys.argv[i + 1]) i += 2 return (sendUpdates, i)
def getCalendarAttributes(i, body, function): colorRgbFormat = False while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'selected': body['selected'] = gam.getBoolean(sys.argv[i + 1], myarg) i += 2 elif myarg == 'hidden': body['hidden'] = gam.getBoolean(sys.argv[i + 1], myarg) i += 2 elif myarg == 'summary': body['summaryOverride'] = sys.argv[i + 1] i += 2 elif myarg == 'colorindex': body['colorId'] = gam.getInteger(sys.argv[i + 1], myarg, minVal=CALENDAR_MIN_COLOR_INDEX, maxVal=CALENDAR_MAX_COLOR_INDEX) i += 2 elif myarg == 'backgroundcolor': body['backgroundColor'] = gam.getColor(sys.argv[i + 1]) colorRgbFormat = True i += 2 elif myarg == 'foregroundcolor': body['foregroundColor'] = gam.getColor(sys.argv[i + 1]) colorRgbFormat = True i += 2 elif myarg == 'reminder': body.setdefault('defaultReminders', []) method = sys.argv[i + 1].lower() if method not in CLEAR_NONE_ARGUMENT: if method not in CALENDAR_REMINDER_METHODS: controlflow.expected_argument_exit( 'Method', ', '.join(CALENDAR_REMINDER_METHODS + CLEAR_NONE_ARGUMENT), method) minutes = gam.getInteger(sys.argv[i + 2], myarg, minVal=0, maxVal=CALENDAR_REMINDER_MAX_MINUTES) body['defaultReminders'].append({ 'method': method, 'minutes': minutes }) i += 3 else: i += 2 elif myarg == 'notification': body.setdefault('notificationSettings', {'notifications': []}) method = sys.argv[i + 1].lower() if method not in CLEAR_NONE_ARGUMENT: if method not in CALENDAR_NOTIFICATION_METHODS: controlflow.expected_argument_exit( 'Method', ', '.join(CALENDAR_NOTIFICATION_METHODS + CLEAR_NONE_ARGUMENT), method) eventType = sys.argv[i + 2].lower() if eventType not in CALENDAR_NOTIFICATION_TYPES_MAP: controlflow.expected_argument_exit( 'Event', ', '.join(CALENDAR_NOTIFICATION_TYPES_MAP), eventType) notice = { 'method': method, 'type': CALENDAR_NOTIFICATION_TYPES_MAP[eventType] } body['notificationSettings']['notifications'].append(notice) i += 3 else: i += 2 else: controlflow.invalid_argument_exit(sys.argv[i], f'gam {function} calendar') return colorRgbFormat
def getEventAttributes(i, calendarId, cal, body, action): # Default to external only so non-Google # calendars are notified of changes sendUpdates = 'externalOnly' action = 'update' if body else 'add' timeZone = None while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg in ['notifyattendees', 'sendnotifications', 'sendupdates']: sendUpdates, i = getSendUpdates(myarg, i, cal) elif myarg == 'attendee': body.setdefault('attendees', []) body['attendees'].append({'email': sys.argv[i + 1]}) i += 2 elif myarg == 'removeattendee' and action == 'update': remove_email = sys.argv[i + 1].lower() if 'attendees' in body: body['attendees'] = _remove_attendee(body['attendees'], remove_email) i += 2 elif myarg == 'optionalattendee': body.setdefault('attendees', []) body['attendees'].append({ 'email': sys.argv[i + 1], 'optional': True }) i += 2 elif myarg == 'anyonecanaddself': body['anyoneCanAddSelf'] = True i += 1 elif myarg == 'description': body['description'] = sys.argv[i + 1].replace('\\n', '\n') i += 2 elif myarg == 'replacedescription' and action == 'update': search = sys.argv[i + 1] replace = sys.argv[i + 2] if 'description' in body: body['description'] = re.sub(search, replace, body['description']) i += 3 elif myarg == 'start': if sys.argv[i + 1].lower() == 'allday': body['start'] = {'date': utils.get_yyyymmdd(sys.argv[i + 2])} i += 3 else: start_time = utils.get_time_or_delta_from_now(sys.argv[i + 1]) body['start'] = {'dateTime': start_time} i += 2 elif myarg == 'end': if sys.argv[i + 1].lower() == 'allday': body['end'] = {'date': utils.get_yyyymmdd(sys.argv[i + 2])} i += 3 else: end_time = utils.get_time_or_delta_from_now(sys.argv[i + 1]) body['end'] = {'dateTime': end_time} i += 2 elif myarg == 'guestscantinviteothers': body['guestsCanInviteOthers'] = False i += 1 elif myarg == 'guestscaninviteothers': body['guestsCanInviteTohters'] = gam.getBoolean( sys.argv[i + 1], 'guestscaninviteothers') i += 2 elif myarg == 'guestscantseeothers': body['guestsCanSeeOtherGuests'] = False i += 1 elif myarg == 'guestscanseeothers': body['guestsCanSeeOtherGuests'] = gam.getBoolean( sys.argv[i + 1], 'guestscanseeothers') i += 2 elif myarg == 'guestscanmodify': body['guestsCanModify'] = gam.getBoolean(sys.argv[i + 1], 'guestscanmodify') i += 2 elif myarg == 'id': if action == 'update': controlflow.invalid_argument_exit( 'id', 'gam calendar <calendar> updateevent') body['id'] = sys.argv[i + 1] i += 2 elif myarg == 'summary': body['summary'] = sys.argv[i + 1] i += 2 elif myarg == 'location': body['location'] = sys.argv[i + 1] i += 2 elif myarg == 'available': body['transparency'] = 'transparent' i += 1 elif myarg == 'transparency': validTransparency = ['opaque', 'transparent'] if sys.argv[i + 1].lower() in validTransparency: body['transparency'] = sys.argv[i + 1].lower() else: controlflow.expected_argument_exit( 'transparency', ', '.join(validTransparency), sys.argv[i + 1]) i += 2 elif myarg == 'visibility': validVisibility = ['default', 'public', 'private'] if sys.argv[i + 1].lower() in validVisibility: body['visibility'] = sys.argv[i + 1].lower() else: controlflow.expected_argument_exit('visibility', ', '.join(validVisibility), sys.argv[i + 1]) i += 2 elif myarg == 'tentative': body['status'] = 'tentative' i += 1 elif myarg == 'status': validStatus = ['confirmed', 'tentative', 'cancelled'] if sys.argv[i + 1].lower() in validStatus: body['status'] = sys.argv[i + 1].lower() else: controlflow.expected_argument_exit('visibility', ', '.join(validStatus), sys.argv[i + 1]) i += 2 elif myarg == 'source': body['source'] = {'title': sys.argv[i + 1], 'url': sys.argv[i + 2]} i += 3 elif myarg == 'noreminders': body['reminders'] = {'useDefault': False} i += 1 elif myarg == 'reminder': minutes = \ gam.getInteger(sys.argv[i+1], myarg, minVal=0, maxVal=CALENDAR_REMINDER_MAX_MINUTES) reminder = {'minutes': minutes, 'method': sys.argv[i + 2]} body.setdefault('reminders', { 'overrides': [], 'useDefault': False }) body['reminders']['overrides'].append(reminder) i += 3 elif myarg == 'recurrence': body.setdefault('recurrence', []) body['recurrence'].append(sys.argv[i + 1]) i += 2 elif myarg == 'timezone': timeZone = sys.argv[i + 1] i += 2 elif myarg == 'privateproperty': if 'extendedProperties' not in body: body['extendedProperties'] = {'private': {}, 'shared': {}} body['extendedProperties']['private'][sys.argv[i + 1]] = sys.argv[i + 2] i += 3 elif myarg == 'sharedproperty': if 'extendedProperties' not in body: body['extendedProperties'] = {'private': {}, 'shared': {}} body['extendedProperties']['shared'][sys.argv[i + 1]] = sys.argv[i + 2] i += 3 elif myarg == 'colorindex': body['colorId'] = gam.getInteger(sys.argv[i + 1], myarg, CALENDAR_EVENT_MIN_COLOR_INDEX, CALENDAR_EVENT_MAX_COLOR_INDEX) i += 2 elif myarg == 'hangoutsmeet': body['conferenceData'] = { 'createRequest': { 'requestId': f'{str(uuid.uuid4())}' } } i += 1 else: controlflow.invalid_argument_exit( sys.argv[i], f'gam calendar <email> {action}event') if ('recurrence' in body) and (('start' in body) or ('end' in body)): if not timeZone: timeZone = gapi.call(cal.calendars(), 'get', calendarId=calendarId, fields='timeZone')['timeZone'] if 'start' in body: body['start']['timeZone'] = timeZone if 'end' in body: body['end']['timeZone'] = timeZone return (sendUpdates, body)
def update_policy(): svc = build() customer = _get_customerid() schemas = build_schemas(svc) orgunit = None printer_id = None app_id = None i = 3 body = {'requests': []} while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg in ['ou', 'org', 'orgunit']: orgunit = _get_orgunit(sys.argv[i + 1]) i += 2 elif myarg == 'printerid': printer_id = sys.argv[i + 1] i += 2 elif myarg == 'appid': app_id = sys.argv[i + 1] i += 2 elif myarg in schemas: body['requests'].append({ 'policyValue': { 'policySchema': schemas[myarg]['name'], 'value': {} }, 'updateMask': '' }) i += 1 while i < len(sys.argv): field = sys.argv[i].lower() if field in ['ou', 'org', 'orgunit', 'printerid', 'appid' ] or '.' in field: break # field is actually a new policy, orgunit or app/printer id expected_fields = ', '.join(schemas[myarg]['settings']) if field not in expected_fields: msg = f'Expected {myarg} field of {expected_fields}. Got {field}.' controlflow.system_error_exit(4, msg) cased_field = schemas[myarg]['settings'][field]['name'] value = sys.argv[i + 1] vtype = schemas[myarg]['settings'][field]['type'] if vtype in ['TYPE_INT64', 'TYPE_INT32', 'TYPE_UINT64']: if not value.isnumeric(): msg = f'Value for {myarg} {field} must be a number, got {value}' controlflow.system_error_exit(7, msg) value = int(value) elif vtype in ['TYPE_BOOL']: value = gam.getBoolean(value, field) elif vtype in ['TYPE_ENUM']: value = value.upper() enum_values = schemas[myarg]['settings'][field]['enums'] if value not in enum_values: expected_enums = ', '.join(enum_values) msg = f'Expected {myarg} {field} value to be one of ' \ f'{expected_enums}, got {value}' controlflow.system_error_exit(8, msg) prefix = schemas[myarg]['settings'][field]['enum_prefix'] value = f'{prefix}{value}' elif vtype in ['TYPE_LIST']: value = value.split(',') body['requests'][-1]['policyValue']['value'][ cased_field] = value body['requests'][-1]['updateMask'] += f'{cased_field},' i += 2 else: msg = f'{myarg} is not a valid argument to "gam update chromepolicy"' controlflow.system_error_exit(4, msg) if not orgunit: controlflow.system_error_exit(3, 'You must specify an orgunit') for request in body['requests']: request['policyTargetKey'] = {'targetResource': orgunit} if printer_id: request['policyTargetKey']['additionalTargetKeys'] = { 'printer_id': printer_id } elif app_id: request['policyTargetKey']['additionalTargetKeys'] = { 'app_id': app_id } gapi.call(svc.customers().policies().orgunits(), 'batchModify', customer=customer, body=body)
def update_state(): ci = gapi_cloudidentity.build_dwd() gapi_directory_customer.setTrueCustomerId() customer = _get_device_customerid() customer_id = customer[10:] client_id = f'{customer_id}-gam' body = {} i, deviceuser = _get_deviceuser_name() while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'clientid': client_id = f'{customer_id}-{sys.argv[i+1]}' i += 2 elif myarg in ['assettag', 'assettags']: body['assetTags'] = gam.shlexSplitList(sys.argv[i + 1]) if body['assetTags'] == ['clear']: # TODO: this doesn't work to clear # existing values. Figure out why. body['assetTags'] = [None] i += 2 elif myarg in ['compliantstate', 'compliancestate']: comp_states = gapi.get_enum_values_minus_unspecified( ci._rootDesc['schemas'] ['GoogleAppsCloudidentityDevicesV1ClientState']['properties'] ['complianceState']['enum']) body['complianceState'] = sys.argv[i + 1].upper() if body['complianceState'] not in comp_states: controlflow.expected_argument_exit('compliant_state', ', '.join(comp_states), sys.argv[i + 1]) i += 2 elif myarg == 'customid': body['customId'] = sys.argv[i + 1] i += 2 elif myarg == 'healthscore': health_scores = gapi.get_enum_values_minus_unspecified( ci._rootDesc['schemas'] ['GoogleAppsCloudidentityDevicesV1ClientState']['properties'] ['healthScore']['enum']) body['healthScore'] = sys.argv[i + 1].upper() if body['healthScore'] == 'CLEAR': body['healthScore'] = None if body['healthScore'] and body['healthScore'] not in health_scores: controlflow.expected_argument_exit('health_score', ', '.join(health_scores), sys.argv[i + 1]) i += 2 elif myarg == 'customvalue': allowed_types = ['bool', 'number', 'string'] value_type = sys.argv[i + 1].lower() if value_type not in allowed_types: controlflow.expected_argument_exit('custom_value', ', '.join(allowed_types), sys.argv[i + 1]) key = sys.argv[i + 2] value = sys.argv[i + 3] if value_type == 'bool': value = gam.getBoolean(value, key) elif value_type == 'number': value = int(value) body.setdefault('keyValuePairs', {}) body['keyValuePairs'][key] = {f'{value_type}Value': value} i += 4 elif myarg in ['managedstate']: managed_states = gapi.get_enum_values_minus_unspecified( ci._rootDesc['schemas'] ['GoogleAppsCloudidentityDevicesV1ClientState']['properties'] ['managed']['enum']) body['managed'] = sys.argv[i + 1].upper() if body['managed'] == 'CLEAR': body['managed'] = None if body['managed'] and body['managed'] not in managed_states: controlflow.expected_argument_exit('managed_state', ', '.join(managed_states), sys.argv[i + 1]) i += 2 elif myarg in ['scorereason']: body['scoreReason'] = sys.argv[i + 1] if body['scoreReason'] == 'clear': body['scoreReason'] = None i += 2 else: controlflow.invalid_argument_exit(sys.argv[i], 'gam update deviceuserstate') name = f'{deviceuser}/clientStates/{client_id}' updateMask = ','.join(body.keys()) result = gapi.call(ci.devices().deviceUsers().clientStates(), 'patch', name=name, customer=customer, updateMask=updateMask, body=body) display.print_json(result)
def _build_query(query, myarg, i, query_discovery): if not query: query = {'dataScope': 'ALL_DATA'} if myarg == 'corpus': query['corpus'] = sys.argv[i + 1].upper() allowed_corpuses = gapi.get_enum_values_minus_unspecified( query_discovery['properties']['corpus']['enum']) if query['corpus'] not in allowed_corpuses: controlflow.expected_argument_exit('corpus', ', '.join(allowed_corpuses), sys.argv[i + 1]) i += 2 elif myarg in VAULT_SEARCH_METHODS_MAP: if query.get('searchMethod'): message = f'Multiple search methods ' \ f'({", ".join(VAULT_SEARCH_METHODS_LIST)})' \ f'specified, only one is allowed' controlflow.system_error_exit(3, message) searchMethod = VAULT_SEARCH_METHODS_MAP[myarg] query['searchMethod'] = searchMethod if searchMethod == 'ACCOUNT': query['accountInfo'] = {'emails': sys.argv[i + 1].split(',')} i += 2 elif searchMethod == 'ORG_UNIT': query['orgUnitInfo'] = { 'orgUnitId': gapi_directory_orgunits.getOrgUnitId(sys.argv[i + 1])[1] } i += 2 elif searchMethod == 'SHARED_DRIVE': query['sharedDriveInfo'] = { 'sharedDriveIds': sys.argv[i + 1].split(',') } i += 2 elif searchMethod == 'ROOM': query['hangoutsChatInfo'] = {'roomId': sys.argv[i + 1].split(',')} i += 2 else: i += 1 elif myarg == 'scope': query['dataScope'] = sys.argv[i + 1].upper() allowed_scopes = gapi.get_enum_values_minus_unspecified( query_discovery['properties']['dataScope']['enum']) if query['dataScope'] not in allowed_scopes: controlflow.expected_argument_exit('scope', ', '.join(allowed_scopes), sys.argv[i + 1]) i += 2 elif myarg in ['terms']: query['terms'] = sys.argv[i + 1] i += 2 elif myarg in ['start', 'starttime']: query['startTime'] = utils.get_date_zero_time_or_full_time(sys.argv[i + 1]) i += 2 elif myarg in ['end', 'endtime']: query['endTime'] = utils.get_date_zero_time_or_full_time(sys.argv[i + 1]) i += 2 elif myarg in ['timezone']: query['timeZone'] = sys.argv[i + 1] i += 2 elif myarg in ['excludedrafts']: query['mailOptions'] = { 'excludeDrafts': gam.getBoolean(sys.argv[i + 1], myarg) } i += 2 elif myarg in ['driveversiondate']: query.setdefault('driveOptions', {})['versionDate'] = \ utils.get_date_zero_time_or_full_time(sys.argv[i+1]) i += 2 elif myarg in ['includeshareddrives', 'includeteamdrives']: query.setdefault('driveOptions', {})['includeSharedDrives'] = gam.getBoolean( sys.argv[i + 1], myarg) i += 2 elif myarg in ['includerooms']: query['hangoutsChatOptions'] = { 'includeRooms': gam.getBoolean(sys.argv[i + 1], myarg) } i += 2 return (query, i)
def createExport(): v = buildGAPIObject() query_discovery = v._rootDesc['schemas']['Query'] allowed_formats = gapi.get_enum_values_minus_unspecified( v._rootDesc['schemas']['MailExportOptions']['properties'] ['exportFormat']['enum']) export_format = 'MBOX' showConfidentialModeContent = None # default to not even set matterId = None query = None body = {'exportOptions': {}} i = 3 while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'matter': matterId = getMatterItem(v, sys.argv[i + 1]) body['matterId'] = matterId i += 2 elif myarg == 'name': body['name'] = sys.argv[i + 1] i += 2 elif myarg in QUERY_ARGS: query, i = _build_query(query, myarg, i, query_discovery) elif myarg in ['format']: export_format = sys.argv[i + 1].upper() if export_format not in allowed_formats: controlflow.expected_argument_exit('export format', ', '.join(allowed_formats), export_format) i += 2 elif myarg in ['showconfidentialmodecontent']: showConfidentialModeContent = gam.getBoolean( sys.argv[i + 1], myarg) i += 2 elif myarg in ['region']: allowed_regions = gapi.get_enum_values_minus_unspecified( v._rootDesc['schemas']['ExportOptions']['properties']['region'] ['enum']) body['exportOptions']['region'] = sys.argv[i + 1].upper() if body['exportOptions']['region'] not in allowed_regions: controlflow.expected_argument_exit( 'region', ', '.join(allowed_regions), body['exportOptions']['region']) i += 2 elif myarg in ['includeaccessinfo']: body['exportOptions'].setdefault( 'driveOptions', {})['includeAccessInfo'] = gam.getBoolean( sys.argv[i + 1], myarg) i += 2 else: controlflow.invalid_argument_exit(sys.argv[i], 'gam create export') if not matterId: controlflow.system_error_exit( 3, 'you must specify a matter for the new export.') _validate_query(query, query_discovery) body['query'] = query if 'name' not in body: corpus_name = body['query']['corpus'] corpus_date = datetime.datetime.now() body['name'] = f'GAM {corpus_name} export - {corpus_date}' options_field = None if body['query']['corpus'] == 'MAIL': options_field = 'mailOptions' elif body['query']['corpus'] == 'GROUPS': options_field = 'groupsOptions' elif body['query']['corpus'] == 'HANGOUTS_CHAT': options_field = 'hangoutsChatOptions' if options_field: body['exportOptions'].pop('driveOptions', None) body['exportOptions'][options_field] = {'exportFormat': export_format} if showConfidentialModeContent is not None: body['exportOptions'][options_field][ 'showConfidentialModeContent'] = showConfidentialModeContent results = gapi.call(v.matters().exports(), 'create', matterId=matterId, body=body) print(f'Created export {results["id"]}') display.print_json(results)
def createExport(): v = buildGAPIObject() allowed_corpuses = gapi.get_enum_values_minus_unspecified( v._rootDesc['schemas']['Query']['properties']['corpus']['enum']) allowed_scopes = gapi.get_enum_values_minus_unspecified( v._rootDesc['schemas']['Query']['properties']['dataScope']['enum']) allowed_formats = gapi.get_enum_values_minus_unspecified( v._rootDesc['schemas']['MailExportOptions']['properties'] ['exportFormat']['enum']) export_format = 'MBOX' showConfidentialModeContent = None # default to not even set matterId = None body = {'query': {'dataScope': 'ALL_DATA'}, 'exportOptions': {}} i = 3 while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'matter': matterId = getMatterItem(v, sys.argv[i + 1]) body['matterId'] = matterId i += 2 elif myarg == 'name': body['name'] = sys.argv[i + 1] i += 2 elif myarg == 'corpus': body['query']['corpus'] = sys.argv[i + 1].upper() if body['query']['corpus'] not in allowed_corpuses: controlflow.expected_argument_exit('corpus', ', '.join(allowed_corpuses), sys.argv[i + 1]) i += 2 elif myarg in VAULT_SEARCH_METHODS_MAP: if body['query'].get('searchMethod'): message = f'Multiple search methods ' \ f'({", ".join(VAULT_SEARCH_METHODS_LIST)})' \ f'specified, only one is allowed' controlflow.system_error_exit(3, message) searchMethod = VAULT_SEARCH_METHODS_MAP[myarg] body['query']['searchMethod'] = searchMethod if searchMethod == 'ACCOUNT': body['query']['accountInfo'] = { 'emails': sys.argv[i + 1].split(',') } i += 2 elif searchMethod == 'ORG_UNIT': body['query']['orgUnitInfo'] = { 'orgUnitId': gam.getOrgUnitId(sys.argv[i + 1])[1] } i += 2 elif searchMethod == 'SHARED_DRIVE': body['query']['sharedDriveInfo'] = { 'sharedDriveIds': sys.argv[i + 1].split(',') } i += 2 elif searchMethod == 'ROOM': body['query']['hangoutsChatInfo'] = { 'roomId': sys.argv[i + 1].split(',') } i += 2 else: i += 1 elif myarg == 'scope': body['query']['dataScope'] = sys.argv[i + 1].upper() if body['query']['dataScope'] not in allowed_scopes: controlflow.expected_argument_exit('scope', ', '.join(allowed_scopes), sys.argv[i + 1]) i += 2 elif myarg in ['terms']: body['query']['terms'] = sys.argv[i + 1] i += 2 elif myarg in ['start', 'starttime']: body['query']['startTime'] = utils.get_date_zero_time_or_full_time( sys.argv[i + 1]) i += 2 elif myarg in ['end', 'endtime']: body['query']['endTime'] = utils.get_date_zero_time_or_full_time( sys.argv[i + 1]) i += 2 elif myarg in ['timezone']: body['query']['timeZone'] = sys.argv[i + 1] i += 2 elif myarg in ['excludedrafts']: body['query']['mailOptions'] = { 'excludeDrafts': gam.getBoolean(sys.argv[i + 1], myarg) } i += 2 elif myarg in ['driveversiondate']: body['query'].setdefault('driveOptions', {})['versionDate'] = \ utils.get_date_zero_time_or_full_time(sys.argv[i+1]) i += 2 elif myarg in ['includeshareddrives', 'includeteamdrives']: body['query'].setdefault( 'driveOptions', {})['includeSharedDrives'] = gam.getBoolean( sys.argv[i + 1], myarg) i += 2 elif myarg in ['includerooms']: body['query']['hangoutsChatOptions'] = { 'includeRooms': gam.getBoolean(sys.argv[i + 1], myarg) } i += 2 elif myarg in ['format']: export_format = sys.argv[i + 1].upper() if export_format not in allowed_formats: controlflow.expected_argument_exit('export format', ', '.join(allowed_formats), export_format) i += 2 elif myarg in ['showconfidentialmodecontent']: showConfidentialModeContent = gam.getBoolean( sys.argv[i + 1], myarg) i += 2 elif myarg in ['region']: allowed_regions = gapi.get_enum_values_minus_unspecified( v._rootDesc['schemas']['ExportOptions']['properties']['region'] ['enum']) body['exportOptions']['region'] = sys.argv[i + 1].upper() if body['exportOptions']['region'] not in allowed_regions: controlflow.expected_argument_exit( 'region', ', '.join(allowed_regions), body['exportOptions']['region']) i += 2 elif myarg in ['includeaccessinfo']: body['exportOptions'].setdefault( 'driveOptions', {})['includeAccessInfo'] = gam.getBoolean( sys.argv[i + 1], myarg) i += 2 else: controlflow.invalid_argument_exit(sys.argv[i], 'gam create export') if not matterId: controlflow.system_error_exit( 3, 'you must specify a matter for the new export.') if 'corpus' not in body['query']: controlflow.system_error_exit(3, f'you must specify a corpus for the ' \ f'new export. Choose one of {", ".join(allowed_corpuses)}') if 'searchMethod' not in body['query']: controlflow.system_error_exit(3, f'you must specify a search method ' \ 'for the new export. Choose one of ' \ f'{", ".join(VAULT_SEARCH_METHODS_LIST)}') if 'name' not in body: corpus_name = body['query']['corpus'] corpus_date = datetime.datetime.now() body['name'] = f'GAM {corpus_name} export - {corpus_date}' options_field = None if body['query']['corpus'] == 'MAIL': options_field = 'mailOptions' elif body['query']['corpus'] == 'GROUPS': options_field = 'groupsOptions' elif body['query']['corpus'] == 'HANGOUTS_CHAT': options_field = 'hangoutsChatOptions' if options_field: body['exportOptions'].pop('driveOptions', None) body['exportOptions'][options_field] = {'exportFormat': export_format} if showConfidentialModeContent is not None: body['exportOptions'][options_field][ 'showConfidentialModeContent'] = showConfidentialModeContent results = gapi.call(v.matters().exports(), 'create', matterId=matterId, body=body) print(f'Created export {results["id"]}') display.print_json(results)
def update_policy(): svc = build() customer = _get_customerid() schemas = build_schemas(svc) orgunit = None printer_id = None app_id = None i = 3 body = {'requests': []} while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg in ['ou', 'org', 'orgunit']: orgunit = _get_orgunit(sys.argv[i+1]) i += 2 elif myarg == 'printerid': printer_id = sys.argv[i+1] i += 2 elif myarg == 'appid': app_id = sys.argv[i+1] i += 2 elif myarg in schemas: schemaName = schemas[myarg]['name'] body['requests'].append({'policyValue': {'policySchema': schemaName, 'value': {}}, 'updateMask': ''}) i += 1 while i < len(sys.argv): field = sys.argv[i].lower() if field in ['ou', 'org', 'orgunit', 'printerid', 'appid'] or '.' in field: break # field is actually a new policy, orgunit or app/printer id # Handle TYPE_MESSAGE fields with durations, values, counts and timeOfDay as special cases schema = CHROME_SCHEMA_TYPE_MESSAGE.get(schemaName, {}).get(field) if schema: i += 1 casedField = schema['casedField'] vtype = schema['type'] if vtype != 'timeOfDay': if 'default' not in schema: value = gam.getInteger(sys.argv[i], casedField, minVal=schema['minVal'], maxVal=schema['maxVal'])*schema['scale'] i += 1 elif i < len(sys.argv) and sys.argv[i].isdigit(): value = gam.getInteger(sys.argv[i], casedField, minVal=schema['minVal'], maxVal=schema['maxVal'])*schema['scale'] i += 1 else: # Handle empty value for fields with default value = schema['default']*schema['scale'] if i < len(sys.argv) and not sys.argv[i]: i += 1 else: value = utils.get_hhmm(sys.argv[i]) i += 1 if vtype == 'duration': body['requests'][-1]['policyValue']['value'][casedField] = {vtype: f'{value}s'} elif vtype == 'value': body['requests'][-1]['policyValue']['value'][casedField] = {vtype: value} elif vtype == 'count': body['requests'][-1]['policyValue']['value'][casedField] = value else: ##timeOfDay hours, minutes = value.split(':') body['requests'][-1]['policyValue']['value'][casedField] = {vtype: {'hours': hours, 'minutes': minutes}} body['requests'][-1]['updateMask'] += f'{casedField},' continue expected_fields = ', '.join(schemas[myarg]['settings']) if field not in expected_fields: msg = f'Expected {myarg} field of {expected_fields}. Got {field}.' controlflow.system_error_exit(4, msg) cased_field = schemas[myarg]['settings'][field]['name'] value = sys.argv[i+1] vtype = schemas[myarg]['settings'][field]['type'] if vtype in ['TYPE_INT64', 'TYPE_INT32', 'TYPE_UINT64']: if not value.isnumeric(): msg = f'Value for {myarg} {field} must be a number, got {value}' controlflow.system_error_exit(7, msg) value = int(value) elif vtype in ['TYPE_BOOL']: value = gam.getBoolean(value, field) elif vtype in ['TYPE_ENUM']: value = value.upper() prefix = schemas[myarg]['settings'][field]['enum_prefix'] enum_values = schemas[myarg]['settings'][field]['enums'] if value in enum_values: value = f'{prefix}{value}' elif value.replace(prefix, '') in enum_values: pass else: expected_enums = ', '.join(enum_values) msg = f'Expected {myarg} {field} value to be one of ' \ f'{expected_enums}, got {value}' controlflow.system_error_exit(8, msg) elif vtype in ['TYPE_LIST']: value = value.split(',') if myarg == 'chrome.users.chromebrowserupdates' and \ cased_field == 'targetVersionPrefixSetting': mg = re.compile(r'^([a-z]+)-(\d+)$').match(value) if mg: channel = mg.group(1).lower().replace('_', '') minus = mg.group(2) channel_map = gapi_chromehistory.get_channel_map(None) if channel not in channel_map: expected_channels = ', '.join(channel_map) msg = f'Expected {myarg} {cased_field} channel to be one of ' \ f'{expected_channels}, got {channel}' controlflow.system_error_exit(8, msg) milestone = gapi_chromehistory.get_relative_milestone( channel_map[channel], int(minus)) if not milestone: msg = f'{myarg} {cased_field} channel {channel} offset {minus} does not exist' controlflow.system_error_exit(8, msg) value = f'{milestone}.' body['requests'][-1]['policyValue']['value'][cased_field] = value body['requests'][-1]['updateMask'] += f'{cased_field},' i += 2 else: msg = f'{myarg} is not a valid argument to "gam update chromepolicy"' controlflow.system_error_exit(4, msg) if not orgunit: controlflow.system_error_exit(3, 'You must specify an orgunit') for request in body['requests']: request['policyTargetKey'] = {'targetResource': orgunit} if printer_id: request['policyTargetKey']['additionalTargetKeys'] = {'printer_id': printer_id} elif app_id: request['policyTargetKey']['additionalTargetKeys'] = {'app_id': app_id} gapi.call(svc.customers().policies().orgunits(), 'batchModify', customer=customer, body=body)