Compare commits

...

20 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
Ross Scroggs
fe1f0285f8 Updated gam <UserTypeEntity> create focustime|outofoffice ... timerange <Time> <Time> 2025-06-10 09:12:17 -07:00
Ross Scroggs
da83121d0d gam.cfg enforce_expansive_access new defaults to true 2025-06-10 09:02:20 -07:00
Ross Scroggs
f58a69e374 gam.cfg enforce_expansive_access new defaults to true 2025-06-10 09:02:03 -07:00
Jay Lee
2f40a164c5 Change default of expansive access. Fixes #1776
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
Push wiki / pushwiki (push) Has been cancelled
2025-06-09 15:51:27 +00:00
Ross Scroggs
58a3fa7313 Update Groups-Membership.md 2025-06-09 08:37:55 -07:00
Ross Scroggs
39ce5b7349 Improved output of gam info|show chromeschemas
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
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-06-06 18:39:25 -07:00
Ross Scroggs
860d44d819 Improved output of gam info|show chromeschemas 2025-06-06 18:38:43 -07:00
Ross Scroggs
5e90ff143e Update Chrome-Policies.md
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
2025-06-06 17:24:08 -07:00
Ross Scroggs
28e05bf09a Fixed bug in gam update chromepolicy
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
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
2025-06-05 22:53:23 -07:00
Ross Scroggs
0781e27993 Fixed bug in gam update chromepolicy 2025-06-05 22:53:05 -07:00
Ross Scroggs
a441dddc06 Update Chrome-Policies.md 2025-06-05 22:47:12 -07:00
15 changed files with 3473 additions and 474 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

@@ -2725,6 +2725,7 @@ gam print chromschemas [todrive <ToDriveAttribute>*]
<ChromePolicySchemaFieldName>* [fields <ChromePolicySchemaFieldNameList>] <ChromePolicySchemaFieldName>* [fields <ChromePolicySchemaFieldNameList>]
[[formatjson [quotechar <Character>]] [[formatjson [quotechar <Character>]]
gam info chromeschema std <SchemaName>
gam show chromeschemas std gam show chromeschemas std
[filter <String>] [filter <String>]

View File

@@ -1,3 +1,43 @@
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
Updated `gam <UserTypeEntity> create focustime|outofoffice ... timerange <Time> <Time>` to check
that the first `<Time>` is less than the second `Time`; previously the event was not created.
For new installs the `enforce_expansive_access` Boolean variable in `gam.cfg` now defaults to True.
For existing installations, if `enforce_expansive_access` has not been added to `gam.cfg`,
a default value of True will be used.
7.09.02
Added command `gam info chromeschema std <SchemaName>` to display a Chrome policy schema in the same format as Legacy GAM.
Improved output of `gam show chromeschemas [std]` and `gam info chromeschema [std]` to more accurately display the schemas.
7.09.01
Fixed bug in `gam <UserTypeEntity> print diskusage` where the `ownedByMe` column was
blank for the top folder.
Fixed bug in `gam update chromepolicy` where the following error was generated
when updating policies with simple numerical values.
```
ERROR: Missing argument: Expected <value>"
```
7.09.00 7.09.00
Removed the overly broad service account `IAM and Access Management API` scope `https://www.googleapis.com/auth/cloud-platform` Removed the overly broad service account `IAM and Access Management API` scope `https://www.googleapis.com/auth/cloud-platform`

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.00' __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)
@@ -25947,7 +25952,7 @@ def exitIfChatNotConfigured(chat, kvList, errMsg, i, count):
if (('No bot associated with this project.' in errMsg) or if (('No bot associated with this project.' in errMsg) or
('Invalid project number.' in errMsg) or ('Invalid project number.' in errMsg) or
('Google Chat app not found.' in errMsg)): ('Google Chat app not found.' in errMsg)):
systemErrorExit(API_ACCESS_DENIED_RC, Msg.TO_SET_UP_GOOGLE_CHAT.format(setupChatURL(chat))) systemErrorExit(API_ACCESS_DENIED_RC, Msg.TO_SET_UP_GOOGLE_CHAT.format(setupChatURL(chat), GM.Globals[GM.OAUTH2SERVICE_JSON_DATA]['project_id']))
entityActionFailedWarning(kvList, errMsg, i, count) entityActionFailedWarning(kvList, errMsg, i, count)
def _getChatAdminAccess(adminAPI, userAPI): def _getChatAdminAccess(adminAPI, userAPI):
@@ -28111,21 +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']
for mtype in schema['definition']['messageType']: for mtype in schema['definition']['messageType']:
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 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':
@@ -28136,27 +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':
subfield = mfield['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):
@@ -28252,14 +28313,11 @@ def doDeleteChromePolicy():
entityActionFailedWarning(kvList, str(e)) entityActionFailedWarning(kvList, str(e))
CHROME_SCHEMA_SPECIAL_CASES = { CHROME_SCHEMA_SPECIAL_CASES = {
# duration
'chrome.users.AutoUpdateCheckPeriodNewV2': 'chrome.users.AutoUpdateCheckPeriodNewV2':
{'autoupdatecheckperiodminutesnew': {'autoupdatecheckperiodminutesnew':
{'casedField': 'autoUpdateCheckPeriodMinutesNew', {'casedField': 'autoUpdateCheckPeriodMinutesNew',
'type': 'duration', 'minVal': 1, 'maxVal': 720}}, 'type': 'duration', 'minVal': 1, 'maxVal': 720}},
'chrome.users.Avatar':
{'useravatarimage':
{'casedField': 'userAvatarImage',
'type': 'downloadUri'}},
'chrome.users.BrowserSwitcherDelayDurationV2': 'chrome.users.BrowserSwitcherDelayDurationV2':
{'browserswitcherdelayduration': {'browserswitcherdelayduration':
{'casedField': 'browserSwitcherDelayDuration', {'casedField': 'browserSwitcherDelayDuration',
@@ -28301,10 +28359,6 @@ CHROME_SCHEMA_SPECIAL_CASES = {
{'maxinvalidationfetchdelay': {'maxinvalidationfetchdelay':
{'casedField': 'maxInvalidationFetchDelay', {'casedField': 'maxInvalidationFetchDelay',
'type': 'duration', 'minVal': 1, 'maxVal': 30, 'default': 10}}, 'type': 'duration', 'minVal': 1, 'maxVal': 30, 'default': 10}},
'chrome.users.PrintingMaxSheetsAllowed':
{'printingmaxsheetsallowednullable':
{'casedField': 'printingMaxSheetsAllowedNullable',
'type': 'value', 'minVal': 1, 'maxVal': None}},
'chrome.users.PrintJobHistoryExpirationPeriodNewV2': 'chrome.users.PrintJobHistoryExpirationPeriodNewV2':
{'printjobhistoryexpirationperioddaysnew': {'printjobhistoryexpirationperioddaysnew':
{'casedField': 'printJobHistoryExpirationPeriodDaysNew', {'casedField': 'printJobHistoryExpirationPeriodDaysNew',
@@ -28312,7 +28366,16 @@ CHROME_SCHEMA_SPECIAL_CASES = {
'chrome.users.RelaunchNotificationWithDurationV2': 'chrome.users.RelaunchNotificationWithDurationV2':
{'relaunchnotificationperiodduration': {'relaunchnotificationperiodduration':
{'casedField': 'relaunchNotificationPeriodDuration', {'casedField': 'relaunchNotificationPeriodDuration',
'type': 'duration', 'minVal': -1, 'maxVal': None}}, 'type': 'duration', 'minVal': 1, 'maxVal': 168},
'relaunchinitialquietperiodduration':
{'casedField': 'relaunchInitialQuietPeriodDuration',
'type': 'duration', 'minVal': 0, 'maxVal': None},
'relaunchwindowstarttime':
{'casedField': 'relaunchWindowStartTime',
'type': 'timeOfDay'},
'relaunchwindowdurationmin':
{'casedField': 'relaunchWindowDurationMin',
'type': 'duration', 'minVal': 1, 'maxVal': 1440}},
'chrome.users.SecurityTokenSessionSettingsV2': 'chrome.users.SecurityTokenSessionSettingsV2':
{'securitytokensessionnotificationseconds': {'securitytokensessionnotificationseconds':
{'casedField': 'securityTokenSessionNotificationSeconds', {'casedField': 'securityTokenSessionNotificationSeconds',
@@ -28328,10 +28391,6 @@ CHROME_SCHEMA_SPECIAL_CASES = {
'updatessuppressedstarttime': 'updatessuppressedstarttime':
{'casedField': 'updatesSuppressedStartTime', {'casedField': 'updatesSuppressedStartTime',
'type': 'timeOfDay'}}, 'type': 'timeOfDay'}},
'chrome.users.Wallpaper':
{'wallpaperimage':
{'casedField': 'wallpaperImage',
'type': 'downloadUri'}},
'chrome.devices.EnableReportUploadFrequencyV2': 'chrome.devices.EnableReportUploadFrequencyV2':
{'reportdeviceuploadfrequency': {'reportdeviceuploadfrequency':
{'casedField': 'reportDeviceUploadFrequency', {'casedField': 'reportDeviceUploadFrequency',
@@ -28340,10 +28399,6 @@ CHROME_SCHEMA_SPECIAL_CASES = {
{'uptimelimitduration': {'uptimelimitduration':
{'casedField': 'uptimeLimitDuration', {'casedField': 'uptimeLimitDuration',
'type': 'duration', 'minVal': 1, 'maxVal': 365}}, 'type': 'duration', 'minVal': 1, 'maxVal': 365}},
'chrome.devices.SignInWallpaperImage':
{'devicewallpaperimage':
{'casedField': 'deviceWallpaperImage',
'type': 'downloadUri'}},
'chrome.devices.kiosk.AcPowerSettingsV2': 'chrome.devices.kiosk.AcPowerSettingsV2':
{'acidletimeout': {'acidletimeout':
{'casedField': 'acIdleTimeout', {'casedField': 'acIdleTimeout',
@@ -28370,10 +28425,6 @@ CHROME_SCHEMA_SPECIAL_CASES = {
'batteryscreenofftimeout': 'batteryscreenofftimeout':
{'casedField': 'batteryScreenOffTimeout', {'casedField': 'batteryScreenOffTimeout',
'type': 'duration', 'minVal': 0, 'maxVal': 35000}}, 'type': 'duration', 'minVal': 0, 'maxVal': 35000}},
'chrome.devices.managedguest.Avatar':
{'useravatarimage':
{'casedField': 'userAvatarImage',
'type': 'downloadUri'}},
'chrome.devices.managedguest.BrowsingDataLifetimeV2': 'chrome.devices.managedguest.BrowsingDataLifetimeV2':
{'browsinghistoryttl': {'browsinghistoryttl':
{'casedField': 'browsingHistoryTtl', {'casedField': 'browsingHistoryTtl',
@@ -28415,6 +28466,56 @@ CHROME_SCHEMA_SPECIAL_CASES = {
{'sessiondurationlimit': {'sessiondurationlimit':
{'casedField': 'sessionDurationLimit', {'casedField': 'sessionDurationLimit',
'type': 'duration', 'minVal': 1, 'maxVal': 1440}}, 'type': 'duration', 'minVal': 1, 'maxVal': 1440}},
# value
'chrome.users.GaiaLockScreenOfflineSigninTimeLimitDays':
{'gaialockscreenofflinesignintimelimitdays':
{'casedField': 'gaiaLockScreenOfflineSigninTimeLimitDays',
'type': 'value', 'minVal': 0, 'maxVal': 365}},
'chrome.users.GaiaOfflineSigninTimeLimitDays':
{'gaiaofflinesignintimelimitdays':
{'casedField': 'gaiaOfflineSigninTimeLimitDays',
'type': 'value', 'minVal': 0, 'maxVal': 365}},
'chrome.users.PrintingMaxSheetsAllowed':
{'printingmaxsheetsallowednullable':
{'casedField': 'printingMaxSheetsAllowedNullable',
'type': 'value', 'minVal': 1, 'maxVal': None}},
'chrome.users.RemoteAccessHostClipboardSizeBytes':
{'remoteaccesshostclipboardsizebytes':
{'casedField': 'remoteAccessHostClipboardSizeBytes',
'type': 'value', 'minVal': 0, 'maxVal': 2147483647}},
'chrome.users.SamlLockScreenOfflineSigninTimeLimitDays':
{'samllockscreenofflinesignintimelimitdays':
{'casedField': 'samlLockScreenOfflineSigninTimeLimitDays',
'type': 'value', 'minVal': 0, 'maxVal': 365}},
'chrome.devices.ExtensionCacheSize':
{'extensioncachesize':
{'casedField': 'extensionCacheSize',
'type': 'value', 'minVal': 1048576, 'maxVal': None, 'default': 268435456}},
'chrome.devices.managedguest.PrintingMaxSheetsAllowed':
{'printingmaxsheetsallowednullable':
{'casedField': 'printingMaxSheetsAllowedNullable',
'type': 'value', 'minVal': 1, 'maxVal': None}},
'chrome.devices.managedguest.RemoteAccessHostClipboardSizeBytes':
{'remoteaccesshostclipboardsizebytes':
{'casedField': 'remoteAccessHostClipboardSizeBytes',
'type': 'value', 'minVal': 0, 'maxVal': 2147483647}},
# downloadUri
'chrome.users.Avatar':
{'useravatarimage':
{'casedField': 'userAvatarImage',
'type': 'downloadUri'}},
'chrome.users.Wallpaper':
{'wallpaperimage':
{'casedField': 'wallpaperImage',
'type': 'downloadUri'}},
'chrome.devices.SignInWallpaperImage':
{'devicewallpaperimage':
{'casedField': 'deviceWallpaperImage',
'type': 'downloadUri'}},
'chrome.devices.managedguest.Avatar':
{'useravatarimage':
{'casedField': 'userAvatarImage',
'type': 'downloadUri'}},
'chrome.devices.managedguest.Wallpaper': 'chrome.devices.managedguest.Wallpaper':
{'wallpaperimage': {'wallpaperimage':
{'casedField': 'wallpaperImage', {'casedField': 'wallpaperImage',
@@ -28436,7 +28537,7 @@ def doUpdateChromePolicy():
return value return value
#if vtype == timeOfDay: #if vtype == timeOfDay:
hours, minutes = value.split(':') hours, minutes = value.split(':')
return {vtype: {'hours': hours, 'minutes': minutes}} return {vtype: {'hours': int(hours), 'minutes': int(minutes)}}
cp = buildGAPIObject(API.CHROMEPOLICY) cp = buildGAPIObject(API.CHROMEPOLICY)
cd = buildGAPIObject(API.DIRECTORY) cd = buildGAPIObject(API.DIRECTORY)
@@ -28459,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)
@@ -28545,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():
@@ -28563,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:
@@ -28591,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'])
@@ -28892,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) 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 = {
@@ -28915,6 +29022,9 @@ CHROME_POLICY_SCHEMA_FIELDS_CHOICE_MAP = {
# [formatjson] # [formatjson]
def doInfoChromePolicySchemas(): def doInfoChromePolicySchemas():
cp = buildGAPIObject(API.CHROMEPOLICY) cp = buildGAPIObject(API.CHROMEPOLICY)
if checkArgumentPresent('std'):
doInfoChromePolicySchemasStd(cp)
return
FJQC = FormatJSONQuoteChar() FJQC = FormatJSONQuoteChar()
fieldsList = [] fieldsList = []
name = _getChromePolicySchemaName() name = _getChromePolicySchemaName()
@@ -28943,7 +29053,7 @@ def doInfoChromePolicySchemas():
# [filter <String>] # [filter <String>]
# <ChromePolicySchemaFieldName>* [fields <ChromePolicySchemaFieldNameList>] # <ChromePolicySchemaFieldName>* [fields <ChromePolicySchemaFieldNameList>]
# [[formatjson [quotechar <Character>]] # [[formatjson [quotechar <Character>]]
def doPrintShowChromeSchemas(): def doPrintShowChromePolicySchemas():
def _printChromePolicySchema(schema): def _printChromePolicySchema(schema):
row = flattenJSON(schema) row = flattenJSON(schema)
if not FJQC.formatJSON: if not FJQC.formatJSON:
@@ -28957,10 +29067,12 @@ def doPrintShowChromeSchemas():
row['JSON'] = json.dumps(cleanJSON(schema), ensure_ascii=False, sort_keys=True) row['JSON'] = json.dumps(cleanJSON(schema), ensure_ascii=False, sort_keys=True)
csvPF.WriteRowNoFilter(row) csvPF.WriteRowNoFilter(row)
if checkArgumentPresent('std'):
doShowChromeSchemasStd()
return
cp = buildGAPIObject(API.CHROMEPOLICY) cp = buildGAPIObject(API.CHROMEPOLICY)
if checkArgumentPresent('std'):
if not Act.csvFormat():
doShowChromePolicySchemasStd(cp)
return
unknownArgumentExit()
parent = _getCustomersCustomerIdWithC() parent = _getCustomersCustomerIdWithC()
csvPF = CSVPrintFile(['name', 'schemaName', 'policyDescription', csvPF = CSVPrintFile(['name', 'schemaName', 'policyDescription',
'policyApiLifecycle.policyApiLifecycleStage', 'policyApiLifecycle.policyApiLifecycleStage',
@@ -29020,9 +29132,55 @@ def doPrintShowChromeSchemas():
if csvPF: if csvPF:
csvPF.writeCSVfile('Chrome Policy Schemas') csvPF.writeCSVfile('Chrome Policy Schemas')
def _showChromePolicySchemaStd(schema):
def _printEntry(mtypeName, mtypeEntry):
vtype = mtypeEntry['type']
if vtype != 'TYPE_MESSAGE':
printKeyValueList([f'{mtypeName}', f'{vtype}'])
else:
printKeyValueList([f'{mtypeName}'])
Ind.Increment()
if vtype == 'TYPE_ENUM':
enums = mtypeEntry['subtype']['enums']
descriptions = mtypeEntry['descriptions']
for i in range(len(enums)):
printKeyValueList([f'{enums[i]}', f'{descriptions[i]}'])
elif vtype == 'TYPE_MESSAGE':
for mfieldName, mfield in mtypeEntry['subtype']['field'].items():
# managedBookmarks is recursive
if mtypeName != 'entries':
_printEntry(mfieldName, mfield)
else:
for description in mtypeEntry.get('descriptions', []):
printKeyValueList([description])
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()
# gam info chromeschema std <SchemaName>
def doInfoChromePolicySchemasStd(cp):
name = _getChromePolicySchemaName()
checkForExtraneousArguments()
try:
schema = callGAPI(cp.customers().policySchemas(), 'get',
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN],
name=name)
_, schema_dict = simplifyChromeSchemaDisplay(schema)
_showChromePolicySchemaStd(schema_dict)
except GAPI.notFound:
entityUnknownWarning(Ent.CHROME_POLICY_SCHEMA, name)
except (GAPI.badRequest, GAPI.forbidden):
accessErrorExit(None)
# gam show chromeschemas std [filter <String>] # gam show chromeschemas std [filter <String>]
def doShowChromeSchemasStd(): def doShowChromePolicySchemasStd(cp):
cp = buildGAPIObject(API.CHROMEPOLICY)
sfilter = None sfilter = None
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
@@ -29036,35 +29194,10 @@ def doShowChromeSchemasStd():
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 _, value in sorted(iter(schemas.items())): for _, schema in sorted(iter(schemas.items())):
printKeyValueList([f'{value.get("name")}', f'{value.get("description")}']) _showChromePolicySchemaStd(schema)
Ind.Increment()
for val in value['settings'].values():
vtype = val.get('type')
printKeyValueList([f'{val.get("name")}', f'{vtype}'])
Ind.Increment()
if vtype == 'TYPE_ENUM':
enums = val.get('enums', [])
descriptions = val.get('descriptions', [])
for i in range(len(val.get('enums', []))):
printKeyValueList([f'{enums[i]}', f'{descriptions[i]}'])
elif vtype == 'TYPE_BOOL':
pvs = val.get('descriptions')
for pvi in pvs:
if isinstance(pvi, dict):
pvalue = pvi.get('value')
pdescription = pvi.get('description')
printKeyValueList([f'{pvalue}', f'{pdescription}'])
elif isinstance(pvi, list):
printKeyValueList([f'{pvi[0]}'])
else:
description = val.get('descriptions')
if len(description) > 0:
printKeyValueList([f'{description[0]}'])
Ind.Decrement()
Ind.Decrement()
printBlankLine() printBlankLine()
# gam create chromenetwork # gam create chromenetwork
@@ -51525,6 +51658,9 @@ def getStatusEventDateTime(dateType, dateList):
if dateType == 'timerange': if dateType == 'timerange':
startTime = getTimeOrDeltaFromNow(returnDateTime=True)[0] startTime = getTimeOrDeltaFromNow(returnDateTime=True)[0]
endTime = getTimeOrDeltaFromNow(returnDateTime=True)[0] endTime = getTimeOrDeltaFromNow(returnDateTime=True)[0]
if startTime >= endTime:
Cmd.Backup()
usageErrorExit(Msg.INVALID_EVENT_TIMERANGE.format(dateType, startTime, endTime))
recurrence = [] recurrence = []
while checkArgumentPresent(['recurrence']): while checkArgumentPresent(['recurrence']):
recurrence.append(getString(Cmd.OB_RECURRENCE)) recurrence.append(getString(Cmd.OB_RECURRENCE))
@@ -57296,6 +57432,7 @@ def printDiskUsage(users):
topFolder['path'] = f'{SHARED_DRIVES}{pathDelimiter}{topFolder["name"]}' topFolder['path'] = f'{SHARED_DRIVES}{pathDelimiter}{topFolder["name"]}'
else: else:
topFolder['path'] = topFolder['name'] topFolder['path'] = topFolder['name']
topFolder.pop('ownedByMe', None)
elif topFolder['name'] == MY_DRIVE and not topFolder.get('parents'): elif topFolder['name'] == MY_DRIVE and not topFolder.get('parents'):
topFolder['path'] = MY_DRIVE topFolder['path'] = MY_DRIVE
else: else:
@@ -57306,7 +57443,6 @@ def printDiskUsage(users):
if owners: if owners:
topFolder['Owner'] = owners[0].get('emailAddress', 'Unknown') topFolder['Owner'] = owners[0].get('emailAddress', 'Unknown')
trashFolder['Owner'] = topFolder['Owner'] trashFolder['Owner'] = topFolder['Owner']
topFolder.pop('ownedByMe', None)
topFolder.pop('parents', None) topFolder.pop('parents', None)
topFolder.update(zeroFolderInfo) topFolder.update(zeroFolderInfo)
topFolder.pop(sizeField, None) topFolder.pop(sizeField, None)
@@ -66105,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()
@@ -76101,7 +76237,7 @@ MAIN_COMMANDS_WITH_OBJECTS = {
Cmd.ARG_CHROMENEEDSATTN: doPrintShowChromeNeedsAttn, Cmd.ARG_CHROMENEEDSATTN: doPrintShowChromeNeedsAttn,
Cmd.ARG_CHROMEPOLICY: doPrintShowChromePolicies, Cmd.ARG_CHROMEPOLICY: doPrintShowChromePolicies,
Cmd.ARG_CHROMEPROFILE: doPrintShowChromeProfiles, Cmd.ARG_CHROMEPROFILE: doPrintShowChromeProfiles,
Cmd.ARG_CHROMESCHEMA: doPrintShowChromeSchemas, Cmd.ARG_CHROMESCHEMA: doPrintShowChromePolicySchemas,
Cmd.ARG_CHROMESNVALIDITY: doPrintChromeSnValidity, Cmd.ARG_CHROMESNVALIDITY: doPrintChromeSnValidity,
Cmd.ARG_CHROMEVERSIONS: doPrintShowChromeVersions, Cmd.ARG_CHROMEVERSIONS: doPrintShowChromeVersions,
Cmd.ARG_CIGROUP: doPrintCIGroups, Cmd.ARG_CIGROUP: doPrintCIGroups,
@@ -76233,7 +76369,7 @@ MAIN_COMMANDS_WITH_OBJECTS = {
Cmd.ARG_CHROMENEEDSATTN: doPrintShowChromeNeedsAttn, Cmd.ARG_CHROMENEEDSATTN: doPrintShowChromeNeedsAttn,
Cmd.ARG_CHROMEPOLICY: doPrintShowChromePolicies, Cmd.ARG_CHROMEPOLICY: doPrintShowChromePolicies,
Cmd.ARG_CHROMEPROFILE: doPrintShowChromeProfiles, Cmd.ARG_CHROMEPROFILE: doPrintShowChromeProfiles,
Cmd.ARG_CHROMESCHEMA: doPrintShowChromeSchemas, Cmd.ARG_CHROMESCHEMA: doPrintShowChromePolicySchemas,
Cmd.ARG_CHROMEVERSIONS: doPrintShowChromeVersions, Cmd.ARG_CHROMEVERSIONS: doPrintShowChromeVersions,
Cmd.ARG_CIGROUPMEMBERS: doShowCIGroupMembers, Cmd.ARG_CIGROUPMEMBERS: doShowCIGroupMembers,
Cmd.ARG_CIPOLICY: doPrintShowCIPolicies, Cmd.ARG_CIPOLICY: doPrintShowCIPolicies,

View File

@@ -379,7 +379,7 @@ Defaults = {
DEVICE_MAX_RESULTS: '200', DEVICE_MAX_RESULTS: '200',
DOMAIN: '', DOMAIN: '',
DRIVE_DIR: '', DRIVE_DIR: '',
ENFORCE_EXPANSIVE_ACCESS: FALSE, ENFORCE_EXPANSIVE_ACCESS: TRUE,
DRIVE_MAX_RESULTS: '1000', DRIVE_MAX_RESULTS: '1000',
DRIVE_V3_BETA: FALSE, DRIVE_V3_BETA: FALSE,
DRIVE_V3_NATIVE_NAMES: TRUE, DRIVE_V3_NATIVE_NAMES: TRUE,

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2024 Ross Scroggs All Rights Reserved. # Copyright (C) 2025 Ross Scroggs All Rights Reserved.
# #
# All Rights Reserved. # All Rights Reserved.
# #

View File

@@ -310,6 +310,7 @@ INVALID_ATTENDEE_CHANGE = 'Invalid attendee change "{0}"'
INVALID_CHARSET = 'Invalid charset "{0}"' INVALID_CHARSET = 'Invalid charset "{0}"'
INVALID_DATE_TIME_RANGE = '{0} {1} must be greater than/equal to {2} {3}' INVALID_DATE_TIME_RANGE = '{0} {1} must be greater than/equal to {2} {3}'
INVALID_ENTITY = 'Invalid {0}, {1}' INVALID_ENTITY = 'Invalid {0}, {1}'
INVALID_EVENT_TIMERANGE = '{0} {1} must be less than {2}'
INVALID_FILE_SELECTION_WITH_ADMIN_ACCESS = 'Invalid file selection with adminaccess|asadmin' INVALID_FILE_SELECTION_WITH_ADMIN_ACCESS = 'Invalid file selection with adminaccess|asadmin'
INVALID_GROUP = 'Invalid Group' INVALID_GROUP = 'Invalid Group'
INVALID_HTTP_HEADER = 'Invalid http header data: {0}' INVALID_HTTP_HEADER = 'Invalid http header data: {0}'

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2023 Ross Scroggs All Rights Reserved. # Copyright (C) 2025 Ross Scroggs All Rights Reserved.
# #
# All Rights Reserved. # All Rights Reserved.
# #

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2023 Ross Scroggs All Rights Reserved. # Copyright (C) 2025 Ross Scroggs All Rights Reserved.
# #
# All Rights Reserved. # All Rights Reserved.
# #

File diff suppressed because it is too large Load Diff

View File

@@ -10,6 +10,40 @@ 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
Updated `gam <UserTypeEntity> create focustime|outofoffice ... timerange <Time> <Time>` to check
that the first `<Time>` is less than the second `Time`; previously the event was not created.
For new installs the `enforce_expansive_access` Boolean variable in `gam.cfg` now defaults to True.
For existing installations, if `enforce_expansive_access` has not been added to `gam.cfg`,
a default value of True will be used.
### 7.09.02
Added command `gam info chromeschema std <SchemaName>` to display a Chrome policy schema in the same format as Legacy GAM.
Improved output of `gam show chromeschemas [std]` and `gam info chromeschema [std]` to more accurately display the schemas.
### 7.09.01
Fixed bug in `gam <UserTypeEntity> print diskusage` where the `ownedByMe` column was
blank for the top folder.
Fixed bug in `gam update chromepolicy` where the following error was generated
when updating policies with simple numerical values.
```
ERROR: Missing argument: Expected <value>"
```
### 7.09.00 ### 7.09.00
Removed the overly broad service account `IAM and Access Management API` scope `https://www.googleapis.com/auth/cloud-platform` Removed the overly broad service account `IAM and Access Management API` scope `https://www.googleapis.com/auth/cloud-platform`

View File

@@ -152,7 +152,7 @@ gam update group|groups <GroupEntity> create|add [<GroupRole>]
[preview] [actioncsv] [preview] [actioncsv]
<UserItem>|<UserTypeEntity> <UserItem>|<UserTypeEntity>
``` ```
To add a group as a memmber of another group, just specify its email address. To add a group as a member of another group, just specify its email address.
``` ```
gam update group group1@domain.com add member group2@domain.com gam update group group1@domain.com add member group2@domain.com
``` ```
@@ -208,7 +208,7 @@ gam update group|groups <GroupEntity> delete|remove [<GroupRole>]
``` ```
`<GroupRole>` is ignored, deletions take place regardless of role. `<GroupRole>` is ignored, deletions take place regardless of role.
To remove a group as a memmber of another group, just specify its email address. To remove a group as a member of another group, just specify its email address.
``` ```
gam update group group1@domain.com remove group2@domain.com gam update group group1@domain.com remove group2@domain.com
``` ```

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.00 - 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.00 - 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.00 - 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.00 - 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.00 - 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.00 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.00 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.00 - 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