def test_get_items_passes_additional_kwargs_to_service(self): gapi.get_items( self.mock_service, self.mock_method_name, my_param_1=1, my_param_2=2) self.assertEqual(self.mock_method.call_count, 1) method_kwargs = self.mock_method.call_args[1] self.assertEqual(1, method_kwargs.get('my_param_1')) self.assertEqual(2, method_kwargs.get('my_param_2'))
def test_get_items_non_default_page_field_name(self): field_name = 'things' fake_response = {field_name: [{}, {}, {}]} self.mock_method.return_value.execute.return_value = fake_response page = gapi.get_items( self.mock_service, self.mock_method_name, items=field_name) self.assertEqual(page, fake_response[field_name])
def showReport(): rep = buildGAPIObject() throw_reasons = [gapi.errors.ErrorReason.INVALID] report = sys.argv[2].lower() report = REPORT_CHOICE_MAP.get(report.replace('_', ''), report) valid_apps = gapi.get_enum_values_minus_unspecified( rep._rootDesc['resources']['activities']['methods']['list'] ['parameters']['applicationName']['enum']) + ['customer', 'user'] if report not in valid_apps: controlflow.expected_argument_exit("report", ", ".join(sorted(valid_apps)), report) customerId = GC_Values[GC_CUSTOMER_ID] if customerId == MY_CUSTOMER: customerId = None filters = parameters = actorIpAddress = startTime = endTime = eventName = orgUnitId = None tryDate = datetime.date.today().strftime(YYYYMMDD_FORMAT) to_drive = False userKey = 'all' fullDataRequired = None i = 3 while i < len(sys.argv): myarg = sys.argv[i].lower() if myarg == 'date': tryDate = utils.get_yyyymmdd(sys.argv[i + 1]) i += 2 elif myarg in ['orgunit', 'org', 'ou']: _, orgUnitId = __main__.getOrgUnitId(sys.argv[i + 1]) i += 2 elif myarg == 'fulldatarequired': fullDataRequired = [] fdr = sys.argv[i + 1].lower() if fdr and fdr != 'all': fullDataRequired = fdr.replace(',', ' ').split() i += 2 elif myarg == 'start': startTime = utils.get_time_or_delta_from_now(sys.argv[i + 1]) i += 2 elif myarg == 'end': endTime = utils.get_time_or_delta_from_now(sys.argv[i + 1]) i += 2 elif myarg == 'event': eventName = sys.argv[i + 1] i += 2 elif myarg == 'user': userKey = __main__.normalizeEmailAddressOrUID(sys.argv[i + 1]) i += 2 elif myarg in ['filter', 'filters']: filters = sys.argv[i + 1] i += 2 elif myarg in ['fields', 'parameters']: parameters = sys.argv[i + 1] i += 2 elif myarg == 'ip': actorIpAddress = sys.argv[i + 1] i += 2 elif myarg == 'todrive': to_drive = True i += 1 else: controlflow.invalid_argument_exit(sys.argv[i], "gam report") if report == 'user': while True: try: if fullDataRequired is not None: warnings = gapi.get_items(rep.userUsageReport(), 'get', 'warnings', throw_reasons=throw_reasons, date=tryDate, userKey=userKey, customerId=customerId, orgUnitID=orgUnitId, fields='warnings') fullData, tryDate = _check_full_data_available( warnings, tryDate, fullDataRequired) if fullData < 0: print('No user report available.') sys.exit(1) if fullData == 0: continue page_message = gapi.got_total_items_msg('Users', '...\n') usage = gapi.get_all_pages(rep.userUsageReport(), 'get', 'usageReports', page_message=page_message, throw_reasons=throw_reasons, date=tryDate, userKey=userKey, customerId=customerId, orgUnitID=orgUnitId, filters=filters, parameters=parameters) break except gapi.errors.GapiInvalidError as e: tryDate = _adjust_date(str(e)) if not usage: print('No user report available.') sys.exit(1) titles = ['email', 'date'] csvRows = [] ptypes = ['intValue', 'boolValue', 'datetimeValue', 'stringValue'] for user_report in usage: if 'entity' not in user_report: continue row = { 'email': user_report['entity']['userEmail'], 'date': tryDate } for item in user_report.get('parameters', []): if 'name' not in item: continue name = item['name'] if not name in titles: titles.append(name) for ptype in ptypes: if ptype in item: row[name] = item[ptype] break else: row[name] = '' csvRows.append(row) display.write_csv_file(csvRows, titles, f'User Reports - {tryDate}', to_drive) elif report == 'customer': while True: try: if fullDataRequired is not None: warnings = gapi.get_items(rep.customerUsageReports(), 'get', 'warnings', throw_reasons=throw_reasons, customerId=customerId, date=tryDate, fields='warnings') fullData, tryDate = _check_full_data_available( warnings, tryDate, fullDataRequired) if fullData < 0: print('No customer report available.') sys.exit(1) if fullData == 0: continue usage = gapi.get_all_pages(rep.customerUsageReports(), 'get', 'usageReports', throw_reasons=throw_reasons, customerId=customerId, date=tryDate, parameters=parameters) break except gapi.errors.GapiInvalidError as e: tryDate = _adjust_date(str(e)) if not usage: print('No customer report available.') sys.exit(1) titles = ['name', 'value', 'client_id'] csvRows = [] auth_apps = list() for item in usage[0]['parameters']: if 'name' not in item: continue name = item['name'] if 'intValue' in item: value = item['intValue'] elif 'msgValue' in item: if name == 'accounts:authorized_apps': for subitem in item['msgValue']: app = {} for an_item in subitem: if an_item == 'client_name': app['name'] = 'App: ' + \ subitem[an_item].replace('\n', '\\n') elif an_item == 'num_users': app['value'] = f'{subitem[an_item]} users' elif an_item == 'client_id': app['client_id'] = subitem[an_item] auth_apps.append(app) continue values = [] for subitem in item['msgValue']: if 'count' in subitem: mycount = myvalue = None for key, value in list(subitem.items()): if key == 'count': mycount = value else: myvalue = value if mycount and myvalue: values.append(f'{myvalue}:{mycount}') value = ' '.join(values) elif 'version_number' in subitem \ and 'num_devices' in subitem: values.append(f'{subitem["version_number"]}:' f'{subitem["num_devices"]}') else: continue value = ' '.join(sorted(values, reverse=True)) csvRows.append({'name': name, 'value': value}) for app in auth_apps: # put apps at bottom csvRows.append(app) display.write_csv_file(csvRows, titles, f'Customer Report - {tryDate}', todrive=to_drive) else: page_message = gapi.got_total_items_msg('Activities', '...\n') activities = gapi.get_all_pages(rep.activities(), 'list', 'items', page_message=page_message, applicationName=report, userKey=userKey, customerId=customerId, actorIpAddress=actorIpAddress, startTime=startTime, endTime=endTime, eventName=eventName, filters=filters, orgUnitID=orgUnitId) if activities: titles = ['name'] csvRows = [] for activity in activities: events = activity['events'] del activity['events'] activity_row = utils.flatten_json(activity) purge_parameters = True for event in events: for item in event.get('parameters', []): if set(item) == set(['value', 'name']): event[item['name']] = item['value'] elif set(item) == set(['intValue', 'name']): if item['name'] in ['start_time', 'end_time']: val = item.get('intValue') if val is not None: val = int(val) if val >= 62135683200: event[item['name']] = \ datetime.datetime.fromtimestamp( val-62135683200).isoformat() else: event[item['name']] = item['intValue'] elif set(item) == set(['boolValue', 'name']): event[item['name']] = item['boolValue'] elif set(item) == set(['multiValue', 'name']): event[item['name']] = ' '.join(item['multiValue']) elif item['name'] == 'scope_data': parts = {} for message in item['multiMessageValue']: for mess in message['parameter']: value = mess.get( 'value', ' '.join(mess.get('multiValue', []))) parts[mess['name']] = parts.get( mess['name'], []) + [value] for part, v in parts.items(): if part == 'scope_name': part = 'scope' event[part] = ' '.join(v) else: purge_parameters = False if purge_parameters: event.pop('parameters', None) row = utils.flatten_json(event) row.update(activity_row) for item in row: if item not in titles: titles.append(item) csvRows.append(row) display.sort_csv_titles([ 'name', ], titles) display.write_csv_file(csvRows, titles, f'{report.capitalize()} Activity Report', to_drive)
def test_get_items_returns_empty_list_when_no_items_returned(self): non_items_response = {'noItemsInThisResponse': {}} self.mock_method.return_value.execute.return_value = non_items_response page = gapi.get_items(self.mock_service, self.mock_method_name) self.assertIsInstance(page, list) self.assertEqual(0, len(page))
def test_get_items_returns_one_page(self): fake_response = {'items': [{}, {}, {}]} self.mock_method.return_value.execute.return_value = fake_response page = gapi.get_items(self.mock_service, self.mock_method_name) self.assertEqual(page, fake_response['items'])
def test_get_items_calls_correct_service_function(self): gapi.get_items(self.mock_service, self.mock_method_name) self.assertTrue(self.mock_method.called)
def doGetCustomerInfo(): cd = gapi.directory.buildGAPIObject() customer_info = gapi.call(cd.customers(), 'get', customerKey=GC_Values[GC_CUSTOMER_ID]) print(f'Customer ID: {customer_info["id"]}') print(f'Primary Domain: {customer_info["customerDomain"]}') result = gapi.call(cd.domains(), 'get', customer=customer_info['id'], domainName=customer_info['customerDomain'], fields='verified') print(f'Primary Domain Verified: {result["verified"]}') # If customer has changed primary domain customerCreationTime is date # of current primary being added, not customer create date. # We should also get all domains and use oldest date customer_creation = customer_info['customerCreationTime'] date_format = '%Y-%m-%dT%H:%M:%S.%fZ' oldest = datetime.datetime.strptime(customer_creation, date_format) domains = gapi.get_items(cd.domains(), 'list', 'domains', customer=GC_Values[GC_CUSTOMER_ID], fields='domains(creationTime)') for domain in domains: creation_timestamp = int(domain['creationTime']) / 1000 domain_creation = datetime.datetime.fromtimestamp(creation_timestamp) if domain_creation < oldest: oldest = domain_creation print(f'Customer Creation Time: {oldest.strftime(date_format)}') customer_language = customer_info.get('language', 'Unset (defaults to en)') print(f'Default Language: {customer_language}') if 'postalAddress' in customer_info: print('Address:') for field in ADDRESS_FIELDS_PRINT_ORDER: if field in customer_info['postalAddress']: print(f' {field}: {customer_info["postalAddress"][field]}') if 'phoneNumber' in customer_info: print(f'Phone: {customer_info["phoneNumber"]}') print(f'Admin Secondary Email: {customer_info["alternateEmail"]}') user_counts_map = { 'accounts:num_users': 'Total Users', 'accounts:gsuite_basic_total_licenses': 'G Suite Basic Licenses', 'accounts:gsuite_basic_used_licenses': 'G Suite Basic Users', 'accounts:gsuite_enterprise_total_licenses': 'G Suite Enterprise ' \ 'Licenses', 'accounts:gsuite_enterprise_used_licenses': 'G Suite Enterprise ' \ 'Users', 'accounts:gsuite_unlimited_total_licenses': 'G Suite Business ' \ 'Licenses', 'accounts:gsuite_unlimited_used_licenses': 'G Suite Business Users' } parameters = ','.join(list(user_counts_map)) tryDate = datetime.date.today().strftime(YYYYMMDD_FORMAT) customerId = GC_Values[GC_CUSTOMER_ID] if customerId == MY_CUSTOMER: customerId = None rep = gapi.reports.buildGAPIObject() usage = None throw_reasons = [gapi.errors.ErrorReason.INVALID] while True: try: usage = gapi.get_all_pages(rep.customerUsageReports(), 'get', 'usageReports', throw_reasons=throw_reasons, customerId=customerId, date=tryDate, parameters=parameters) break except gapi.errors.GapiInvalidError as e: tryDate = gapi.reports._adjust_date(str(e)) if not usage: print('No user count data available.') return print(f'User counts as of {tryDate}:') for item in usage[0]['parameters']: api_name = user_counts_map.get(item['name']) api_value = int(item.get('intValue', 0)) if api_name and api_value: print(f' {api_name}: {api_value:,}')