Compare commits

...

9 Commits

Author SHA1 Message Date
Ross Scroggs
260f2d3f5c Update chromeschema/chromepolicy commands 2025-06-12 12:54:23 -07:00
Ross Scroggs
475275add7 Update Chrome-Policies.md 2025-06-12 10:26:08 -07:00
Ross Scroggs
d71832096a Bug fixes: whatis, print shareddriveorganizers 2025-06-11 22:19:33 -07:00
Ross Scroggs
f12d3abfc1 Bug fixes: whatis, print shareddriveorganizers 2025-06-11 17:39:52 -07:00
Ross Scroggs
474aa069b7 Bug fixes: whatis, print shareddriveorganizers 2025-06-11 17:35:50 -07:00
Jay Lee
c49708cbae actions: rebuild for Python 3.13.5
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
2025-06-11 19:24:51 -04:00
Ross Scroggs
43ecba07bb Fixed bug in gam whatis <EmailItem> where the check for an invitable user always failed. 2025-06-11 13:06:13 -07:00
Ross Scroggs
51f8ebe8e2 Update Chrome-Policies.md
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-06-11 11:42:03 -07:00
Ross Scroggs
28edce3aca gam.cfg enforce_expansive_access now defaults to true
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2025-06-10 09:44:30 -07:00
8 changed files with 3222 additions and 409 deletions

View File

@@ -126,7 +126,7 @@ jobs:
with: with:
path: | path: |
cache.tar.xz cache.tar.xz
key: gam-${{ matrix.jid }}-20250603 key: gam-${{ matrix.jid }}-20250611
- name: Untar Cache archive - name: Untar Cache archive
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit == 'true' if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit == 'true'

View File

@@ -1,3 +1,17 @@
7.09.05
Improved output of `gam info|show chromeschemas [std]` to more accurately display the schemas.
Fixed bugs in `gam update chromepolicy` that caused invalid error messaages.
7.09.04
Fixed bug in `gam whatis <EmailItem>` where the check for an invitable user always failed.
Fixed bug in `gam print shareddriveorganizers` where no organizers were displayed when `domain` in `gam.cfg` was blank.
Updated to Python 3.13.5
7.09.03 7.09.03
Updated `gam <UserTypeEntity> create focustime|outofoffice ... timerange <Time> <Time>` to check Updated `gam <UserTypeEntity> create focustime|outofoffice ... timerange <Time> <Time>` to check

View File

@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
""" """
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>' __author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
__version__ = '7.09.03' __version__ = '7.09.05'
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)' __license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
#pylint: disable=wrong-import-position #pylint: disable=wrong-import-position
@@ -12353,7 +12353,8 @@ def checkServiceAccount(users):
Ind.Increment() Ind.Increment()
try: try:
key = callGAPI(iam.projects().serviceAccounts().keys(), 'get', key = callGAPI(iam.projects().serviceAccounts().keys(), 'get',
throwReasons=[GAPI.BAD_REQUEST, GAPI.INVALID, GAPI.NOT_FOUND, GAPI.PERMISSION_DENIED], throwReasons=[GAPI.BAD_REQUEST, GAPI.INVALID, GAPI.NOT_FOUND,
GAPI.PERMISSION_DENIED, GAPI.SERVICE_NOT_AVAILABLE],
name=name, fields='validAfterTime') name=name, fields='validAfterTime')
key_created, _ = iso8601.parse_date(key['validAfterTime']) key_created, _ = iso8601.parse_date(key['validAfterTime'])
key_age = todaysTime()-key_created key_age = todaysTime()-key_created
@@ -12366,6 +12367,10 @@ def checkServiceAccount(users):
Ent.SVCACCT, GM.Globals[GM.OAUTH2SERVICE_JSON_DATA]['client_email']], Ent.SVCACCT, GM.Globals[GM.OAUTH2SERVICE_JSON_DATA]['client_email']],
str(e)) str(e))
printPassFail(Msg.SERVICE_ACCOUNT_PRIVATE_KEY_AGE.format('UNKNOWN'), testWarn) printPassFail(Msg.SERVICE_ACCOUNT_PRIVATE_KEY_AGE.format('UNKNOWN'), testWarn)
except GAPI.serviceNotAvailable as e:
entityActionFailedExit([Ent.PROJECT, GM.Globals[GM.OAUTH2SERVICE_JSON_DATA]['project_id'],
Ent.SVCACCT, GM.Globals[GM.OAUTH2SERVICE_JSON_DATA]['client_email']],
str(e))
else: else:
printPassFail(Msg.SERVICE_ACCOUNT_SKIPPING_KEY_AGE_CHECK.format(key_type), testPass) printPassFail(Msg.SERVICE_ACCOUNT_SKIPPING_KEY_AGE_CHECK.format(key_type), testPass)
Ind.Decrement() Ind.Decrement()
@@ -13138,7 +13143,7 @@ def doWhatIs():
entityUnknownWarning(Ent.EMAIL, email) entityUnknownWarning(Ent.EMAIL, email)
setSysExitRC(ENTITY_IS_UKNOWN_RC) setSysExitRC(ENTITY_IS_UKNOWN_RC)
return return
if not invitableCheck or not getSvcAcctCredentials(API.CLOUDIDENTITY_USERINVITATIONS, _getAdminEmail(), softErrors=True): if not invitableCheck:
isInvitableUser = False isInvitableUser = False
else: else:
isInvitableUser, ci = _getIsInvitableUser(None, email) isInvitableUser, ci = _getIsInvitableUser(None, email)
@@ -28111,27 +28116,21 @@ def commonprefix(m):
return s1[:i] return s1[:i]
return s1 return s1
def simplifyChromeSchema(schema): SCHEMA_TYPE_MESSAGE_MAP = {
'NullableDuration': {'type': 'TYPE_INT64', 'namedType': 'duration'},
'NullableLong': {'type': 'TYPE_INT64', 'namedType': 'value'},
'SystemTimezone': {'type': 'TYPE_STRING', 'namedType': 'value'}
}
def simplifyChromeSchemaUpdate(schema):
schema_name = schema['name'].split('/')[-1] schema_name = schema['name'].split('/')[-1]
schema_dict = {'name': schema_name, schema_dict = {'name': schema_name, 'settings': {}}
'description': schema.get('policyDescription', ''),
'settings': {}
}
fieldDescriptions = schema['fieldDescriptions']
savedSettingName = ''
savedTypeName = ''
for mtype in schema['definition']['messageType']: for mtype in schema['definition']['messageType']:
numSettings = len(mtype['field']) if mtype['name'] in SCHEMA_TYPE_MESSAGE_MAP:
continue
for setting in mtype['field']: for setting in mtype['field']:
setting_name = setting['name'] setting_name = setting['name']
setting_dict = {'name': setting_name, setting_dict = {'name': setting_name, 'type': setting['type'], 'namedType': ''}
'constraints': None,
'descriptions': [],
'type': setting['type'],
}
if mtype['name'] == savedTypeName and numSettings == 1:
setting_dict['name'] = savedSettingName
savedTypeName = ''
if setting_dict['type'] == 'TYPE_STRING' and setting.get('label') == 'LABEL_REPEATED': if setting_dict['type'] == 'TYPE_STRING' and setting.get('label') == 'LABEL_REPEATED':
setting_dict['type'] = 'TYPE_LIST' setting_dict['type'] = 'TYPE_LIST'
if setting_dict['type'] == 'TYPE_ENUM': if setting_dict['type'] == 'TYPE_ENUM':
@@ -28142,29 +28141,83 @@ def simplifyChromeSchema(schema):
setting_dict['enum_prefix'] = commonprefix(setting_dict['enums']) setting_dict['enum_prefix'] = commonprefix(setting_dict['enums'])
prefix_len = len(setting_dict['enum_prefix']) prefix_len = len(setting_dict['enum_prefix'])
setting_dict['enums'] = [enum[prefix_len:] for enum in setting_dict['enums'] if not enum.endswith('UNSPECIFIED')] setting_dict['enums'] = [enum[prefix_len:] for enum in setting_dict['enums'] if not enum.endswith('UNSPECIFIED')]
setting_dict['descriptions'] = ['']*len(setting_dict['enums']) elif setting_dict['type'] == 'TYPE_MESSAGE':
for i, an in enumerate(setting_dict['enums']): type_name = setting['typeName']
if type_name not in SCHEMA_TYPE_MESSAGE_MAP:
continue
setting_dict['type'] = SCHEMA_TYPE_MESSAGE_MAP[type_name]['type']
setting_dict['namedType'] = SCHEMA_TYPE_MESSAGE_MAP[type_name]['namedType']
schema_dict['settings'][setting_name.lower()] = setting_dict
return(schema_name, schema_dict)
def simplifyChromeSchemaDisplay(schema):
schema_name = schema['name'].split('/')[-1]
schema_dict = {'name': schema_name, 'description': schema.get('policyDescription', '')}
fieldDescriptions = schema['fieldDescriptions']
enumDict = {}
for enumType in schema['definition'].get('enumType', []):
enumEntry = {}
enumEntry['enums'] = [enum['name'] for enum in enumType['value']]
enumEntry['enum_prefix'] = commonprefix(enumEntry['enums'])
enumEntry['enum_prefix_len'] = prefix_len = len(enumEntry['enum_prefix'])
enumEntry['enums'] = [enum[prefix_len:] for enum in enumEntry['enums'] if not enum.endswith('UNSPECIFIED')]
enumDict[enumType['name']] = enumEntry.copy()
mesgDict = {}
mesgPops = set()
for mesgType in schema['definition']['messageType']:
mtypeEntry = {'field': {}, 'subfield': False}
for mfield in mesgType['field']:
mfield.pop('number')
mtypeEntry['field'][mfield.pop('name')] = mfield
mesgDict[mesgType['name']] = mtypeEntry.copy()
for _, mtypeEntry in mesgDict.items():
for mfieldName, mfield in mtypeEntry['field'].items():
mfield['descriptions'] = []
if mfield['type'] == 'TYPE_STRING' and mfield.get('label') == 'LABEL_REPEATED':
mfield['type'] = 'TYPE_LIST'
if mfield['type'] == 'TYPE_ENUM':
mfield['subtype'] = enumDict[mfield['typeName']]
for an_enum in schema['definition']['enumType']:
if an_enum['name'] == mfield['typeName']:
mfield['descriptions'] = ['']*len(mfield['subtype']['enums'])
for i, an in enumerate(mfield['subtype']['enums']):
for fdesc in fieldDescriptions: for fdesc in fieldDescriptions:
if fdesc.get('field') == setting_name: if fdesc.get('field') == mfieldName:
for d in fdesc.get('knownValueDescriptions', []): for d in fdesc.get('knownValueDescriptions', []):
if d['value'][prefix_len:] == an: if d['value'][mfield['subtype']['enum_prefix_len']:] == an:
setting_dict['descriptions'][i] = d.get('description', '') mfield['descriptions'][i] = d.get('description', '')
break break
break break
break break
elif setting_dict['type'] == 'TYPE_MESSAGE': elif mfield['type'] == 'TYPE_MESSAGE':
savedSettingName = setting_name subfield = mfield['typeName']
savedTypeName = setting['typeName'] if subfield not in SCHEMA_TYPE_MESSAGE_MAP:
mesgDict[subfield]['subfield'] = True
mfield['subtype'] = mesgDict[subfield]
else:
mfield['type'] = SCHEMA_TYPE_MESSAGE_MAP[subfield]['type']
mesgPops.add(subfield)
continue continue
else: else:
setting_dict['enums'] = None for fdesc in fieldDescriptions:
for fdesc in schema['fieldDescriptions']: if fdesc['field'] == mfieldName:
if fdesc['field'] == setting_name:
if 'knownValueDescriptions' in fdesc: if 'knownValueDescriptions' in fdesc:
setting_dict['descriptions'] = fdesc['knownValueDescriptions'] if isinstance(fdesc['knownValueDescriptions'], list):
for kvd in fdesc['knownValueDescriptions']:
if isinstance(kvd, dict):
if 'description' in kvd:
mfield['descriptions'].append(f"{kvd['value']}: {kvd['description']}")
else:
mfield['descriptions'].append(f"{kvd['value']}")
else:
mfield['descriptions'].extend(kvd)
else:
mfield['descriptions'].append(kvd)
elif 'description' in fdesc: elif 'description' in fdesc:
setting_dict['descriptions'] = [fdesc['description']] mfield['descriptions'].append(fdesc['description'])
schema_dict['settings'][setting_name.lower()] = setting_dict for pfield in mesgPops:
mesgDict.pop(pfield)
schema_dict['settings'] = mesgDict
return(schema_name, schema_dict) return(schema_name, schema_dict)
def _getPolicyOrgUnitTarget(cd, cp, myarg, groupEmail): def _getPolicyOrgUnitTarget(cd, cp, myarg, groupEmail):
@@ -28507,7 +28560,7 @@ def doUpdateChromePolicy():
elif myarg == 'convertcrnl': elif myarg == 'convertcrnl':
convertCRsNLs = True convertCRsNLs = True
else: else:
schemaName, schema = simplifyChromeSchema(_getChromePolicySchema(cp, Cmd.Previous(), '*')) schemaName, schema = simplifyChromeSchemaUpdate(_getChromePolicySchema(cp, Cmd.Previous(), '*'))
body['requests'].append({'policyValue': {'policySchema': schemaName, 'value': {}}, body['requests'].append({'policyValue': {'policySchema': schemaName, 'value': {}},
'updateMask': ''}) 'updateMask': ''})
schemaNameList.append(schemaName) schemaNameList.append(schemaName)
@@ -28593,8 +28646,9 @@ def doUpdateChromePolicy():
if field not in schema['settings']: if field not in schema['settings']:
Cmd.Backup() Cmd.Backup()
missingChoiceExit(schema['settings']) missingChoiceExit(schema['settings'])
casedField = schema['settings'][field]['name'] field_settings = schema['settings'][field]
vtype = schema['settings'][field]['type'] casedField = field_settings['name']
vtype = field_settings['type']
value = getString(Cmd.OB_STRING, minLen=0 if vtype in {'TYPE_STRING', 'TYPE_LIST'} else 1) value = getString(Cmd.OB_STRING, minLen=0 if vtype in {'TYPE_STRING', 'TYPE_LIST'} else 1)
if vtype in ['TYPE_INT64', 'TYPE_INT32', 'TYPE_UINT64']: if vtype in ['TYPE_INT64', 'TYPE_INT32', 'TYPE_UINT64']:
if not value.isnumeric(): if not value.isnumeric():
@@ -28611,8 +28665,8 @@ def doUpdateChromePolicy():
invalidChoiceExit(value, TRUE_FALSE, True) invalidChoiceExit(value, TRUE_FALSE, True)
elif vtype == 'TYPE_ENUM': elif vtype == 'TYPE_ENUM':
value = value.upper() value = value.upper()
prefix = schema['settings'][field]['enum_prefix'] prefix = field_settings['enum_prefix']
enum_values = schema['settings'][field]['enums'] enum_values = field_settings['enums']
if value in enum_values: if value in enum_values:
value = f'{prefix}{value}' value = f'{prefix}{value}'
elif value.replace(prefix, '') in enum_values: elif value.replace(prefix, '') in enum_values:
@@ -28639,7 +28693,10 @@ def doUpdateChromePolicy():
elif value and not CHROME_TARGET_VERSION_PATTERN.match(value): elif value and not CHROME_TARGET_VERSION_PATTERN.match(value):
Cmd.Backup() Cmd.Backup()
invalidArgumentExit(Msg.CHROME_TARGET_VERSION_FORMAT) invalidArgumentExit(Msg.CHROME_TARGET_VERSION_FORMAT)
body['requests'][-1]['policyValue']['value'][casedField] = value if field_settings['namedType']:
body['requests'][-1]['policyValue']['value'][casedField] = {field_settings['namedType']: value}
else:
body['requests'][-1]['policyValue']['value'][casedField] = value
body['requests'][-1]['updateMask'] += f'{casedField},' body['requests'][-1]['updateMask'] += f'{casedField},'
checkPolicyArgs(targetResource, printer_id, app_id) checkPolicyArgs(targetResource, printer_id, app_id)
count = len(body['requests']) count = len(body['requests'])
@@ -28940,7 +28997,9 @@ def _showChromePolicySchema(schema, FJQC, i=0, count=0):
return return
printEntity([Ent.CHROME_POLICY_SCHEMA, schema['name']], i, count) printEntity([Ent.CHROME_POLICY_SCHEMA, schema['name']], i, count)
Ind.Increment() Ind.Increment()
showJSON(None, schema, dictObjectsKey={'messageType': 'name', 'field': 'name', 'fieldDescriptions': 'field'}) showJSON(None, schema,
dictObjectsKey={'messageType': 'name', 'field': 'name',
'fieldDescriptions': 'field', 'knownValueDescriptions': 'value'})
Ind.Decrement() Ind.Decrement()
CHROME_POLICY_SCHEMA_FIELDS_CHOICE_MAP = { CHROME_POLICY_SCHEMA_FIELDS_CHOICE_MAP = {
@@ -29074,31 +29133,35 @@ def doPrintShowChromePolicySchemas():
csvPF.writeCSVfile('Chrome Policy Schemas') csvPF.writeCSVfile('Chrome Policy Schemas')
def _showChromePolicySchemaStd(schema): def _showChromePolicySchemaStd(schema):
printKeyValueList([f'{schema.get("name")}', f'{schema.get("description")}']) def _printEntry(mtypeName, mtypeEntry):
Ind.Increment() vtype = mtypeEntry['type']
for val in schema['settings'].values(): if vtype != 'TYPE_MESSAGE':
vtype = val.get('type') printKeyValueList([f'{mtypeName}', f'{vtype}'])
printKeyValueList([f'{val.get("name")}', f'{vtype}']) else:
printKeyValueList([f'{mtypeName}'])
Ind.Increment() Ind.Increment()
if vtype == 'TYPE_ENUM': if vtype == 'TYPE_ENUM':
enums = val.get('enums', []) enums = mtypeEntry['subtype']['enums']
descriptions = val.get('descriptions', []) descriptions = mtypeEntry['descriptions']
for i in range(len(val.get('enums', []))): for i in range(len(enums)):
printKeyValueList([f'{enums[i]}', f'{descriptions[i]}']) printKeyValueList([f'{enums[i]}', f'{descriptions[i]}'])
elif vtype == 'TYPE_BOOL': elif vtype == 'TYPE_MESSAGE':
pvs = val.get('descriptions') for mfieldName, mfield in mtypeEntry['subtype']['field'].items():
for pvi in pvs: # managedBookmarks is recursive
if isinstance(pvi, dict): if mtypeName != 'entries':
pvalue = pvi.get('value') _printEntry(mfieldName, mfield)
pdescription = pvi.get('description')
printKeyValueList([f'{pvalue}', f'{pdescription}'])
elif isinstance(pvi, list):
printKeyValueList([f'{pvi[0]}'])
else: else:
description = val.get('descriptions') for description in mtypeEntry.get('descriptions', []):
if len(description) > 0: printKeyValueList([description])
printKeyValueList([f'{description[0]}'])
Ind.Decrement() Ind.Decrement()
printKeyValueList([f'{schema.get("name")}', f'{schema.get("description")}'])
Ind.Increment()
for _, mtypeEntry in schema['settings'].items():
if mtypeEntry['subfield']:
continue
for mfieldName, mfield in mtypeEntry['field'].items():
_printEntry(mfieldName, mfield)
Ind.Decrement() Ind.Decrement()
# gam info chromeschema std <SchemaName> # gam info chromeschema std <SchemaName>
@@ -29109,7 +29172,7 @@ def doInfoChromePolicySchemasStd(cp):
schema = callGAPI(cp.customers().policySchemas(), 'get', schema = callGAPI(cp.customers().policySchemas(), 'get',
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN], throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN],
name=name) name=name)
_, schema_dict = simplifyChromeSchema(schema) _, schema_dict = simplifyChromeSchemaDisplay(schema)
_showChromePolicySchemaStd(schema_dict) _showChromePolicySchemaStd(schema_dict)
except GAPI.notFound: except GAPI.notFound:
entityUnknownWarning(Ent.CHROME_POLICY_SCHEMA, name) entityUnknownWarning(Ent.CHROME_POLICY_SCHEMA, name)
@@ -29131,7 +29194,7 @@ def doShowChromePolicySchemasStd(cp):
parent=parent, filter=sfilter) parent=parent, filter=sfilter)
schemas = {} schemas = {}
for schema in result: for schema in result:
schema_name, schema_dict = simplifyChromeSchema(schema) schema_name, schema_dict = simplifyChromeSchemaDisplay(schema)
schemas[schema_name.lower()] = schema_dict schemas[schema_name.lower()] = schema_dict
for _, schema in sorted(iter(schemas.items())): for _, schema in sorted(iter(schemas.items())):
_showChromePolicySchemaStd(schema) _showChromePolicySchemaStd(schema)
@@ -66178,7 +66241,7 @@ def printSharedDriveOrganizers(users, useDomainAdminAccess=False):
showNoOrganizerDrives = SHOW_NO_PERMISSIONS_DRIVES_CHOICE_MAP['false'] showNoOrganizerDrives = SHOW_NO_PERMISSIONS_DRIVES_CHOICE_MAP['false']
fieldsList = ['role', 'type', 'emailAddress'] fieldsList = ['role', 'type', 'emailAddress']
cd = entityList = orgUnitId = query = matchPattern = None cd = entityList = orgUnitId = query = matchPattern = None
domainList = [GC.Values[GC.DOMAIN]] domainList = set([(GC.Values[GC.DOMAIN] if GC.Values[GC.DOMAIN] else _getValueFromOAuth('hd'))])
oneOrganizer = True oneOrganizer = True
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()

File diff suppressed because it is too large Load Diff

View File

@@ -10,6 +10,14 @@ Add the `-s` option to the end of the above commands to suppress creating the `g
See [Downloads-Installs-GAM7](https://github.com/GAM-team/GAM/wiki/Downloads-Installs) for Windows or other options, including manual installation See [Downloads-Installs-GAM7](https://github.com/GAM-team/GAM/wiki/Downloads-Installs) for Windows or other options, including manual installation
### 7.09.04
Fixed bug in `gam whatis <EmailItem>` where the check for an invitable user always failed.
Fixed bug in `gam print shareddriveorganizers` where no organizers were displayed when `domain` in `gam.cfg` was blank.
Updated to Python 3.13.5
### 7.09.03 ### 7.09.03
Updated `gam <UserTypeEntity> create focustime|outofoffice ... timerange <Time> <Time>` to check Updated `gam <UserTypeEntity> create focustime|outofoffice ... timerange <Time> <Time>` to check

View File

@@ -251,9 +251,9 @@ writes the credentials into the file oauth2.txt.
admin@server:/Users/admin$ rm -f /Users/admin/GAMConfig/oauth2.txt admin@server:/Users/admin$ rm -f /Users/admin/GAMConfig/oauth2.txt
admin@server:/Users/admin$ gam version admin@server:/Users/admin$ gam version
WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
GAM 7.09.03 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.09.04 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.4 64-bit final Python 3.13.5 64-bit final
MacOS Sequoia 15.5 x86_64 MacOS Sequoia 15.5 x86_64
Path: /Users/admin/bin/gam7 Path: /Users/admin/bin/gam7
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
@@ -989,9 +989,9 @@ writes the credentials into the file oauth2.txt.
C:\>del C:\GAMConfig\oauth2.txt C:\>del C:\GAMConfig\oauth2.txt
C:\>gam version C:\>gam version
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
GAM 7.09.03 - https://github.com/GAM-team/GAM - pythonsource GAM 7.09.04 - https://github.com/GAM-team/GAM - pythonsource
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.4 64-bit final Python 3.13.5 64-bit final
Windows-10-10.0.17134 AMD64 Windows-10-10.0.17134 AMD64
Path: C:\GAM7 Path: C:\GAM7
Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com

View File

@@ -3,9 +3,9 @@
Print the current version of Gam with details Print the current version of Gam with details
``` ```
gam version gam version
GAM 7.09.03 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.09.04 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.4 64-bit final Python 3.13.5 64-bit final
MacOS Sequoia 15.5 x86_64 MacOS Sequoia 15.5 x86_64
Path: /Users/Admin/bin/gam7 Path: /Users/Admin/bin/gam7
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
@@ -15,9 +15,9 @@ Time: 2023-06-02T21:10:00-07:00
Print the current version of Gam with details and time offset information Print the current version of Gam with details and time offset information
``` ```
gam version timeoffset gam version timeoffset
GAM 7.09.03 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.09.04 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.4 64-bit final Python 3.13.5 64-bit final
MacOS Sequoia 15.5 x86_64 MacOS Sequoia 15.5 x86_64
Path: /Users/Admin/bin/gam7 Path: /Users/Admin/bin/gam7
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
@@ -27,9 +27,9 @@ Your system time differs from www.googleapis.com by less than 1 second
Print the current version of Gam with extended details and SSL information Print the current version of Gam with extended details and SSL information
``` ```
gam version extended gam version extended
GAM 7.09.03 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.09.04 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.4 64-bit final Python 3.13.5 64-bit final
MacOS Sequoia 15.5 x86_64 MacOS Sequoia 15.5 x86_64
Path: /Users/Admin/bin/gam7 Path: /Users/Admin/bin/gam7
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
@@ -64,7 +64,7 @@ MacOS High Sierra 10.13.6 x86_64
Path: /Users/Admin/bin/gam7 Path: /Users/Admin/bin/gam7
Version Check: Version Check:
Current: 5.35.08 Current: 5.35.08
Latest: 7.09.03 Latest: 7.09.04
echo $? echo $?
1 1
``` ```
@@ -72,7 +72,7 @@ echo $?
Print the current version number without details Print the current version number without details
``` ```
gam version simple gam version simple
7.09.03 7.09.04
``` ```
In Linux/MacOS you can do: In Linux/MacOS you can do:
``` ```
@@ -82,9 +82,9 @@ echo $VER
Print the current version of Gam and address of this Wiki Print the current version of Gam and address of this Wiki
``` ```
gam help gam help
GAM 7.09.03 - https://github.com/GAM-team/GAM GAM 7.09.04 - https://github.com/GAM-team/GAM
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.4 64-bit final Python 3.13.5 64-bit final
MacOS Sequoia 15.5 x86_64 MacOS Sequoia 15.5 x86_64
Path: /Users/Admin/bin/gam7 Path: /Users/Admin/bin/gam7
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com

View File

@@ -337,7 +337,7 @@ enforce_expansive_access
gam <UserTypeEntity> move drivefile gam <UserTypeEntity> move drivefile
gam <UserTypeEntity> transfer ownership gam <UserTypeEntity> transfer ownership
gam <UserTypeEntity> claim ownership gam <UserTypeEntity> claim ownership
Default: False Default: True
event_max_results event_max_results
When retrieving lists of Calendar events from API, When retrieving lists of Calendar events from API,
how many should be retrieved in each API call how many should be retrieved in each API call