mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-28 09:51:36 +00:00
Compare commits
14 Commits
v7.33.00
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b23efd83f | ||
|
|
b7c96a8172 | ||
|
|
fed1662eb4 | ||
|
|
077747be99 | ||
|
|
9eee475b4a | ||
|
|
2636dd9827 | ||
|
|
e18a70e55b | ||
|
|
e11123fccd | ||
|
|
536ea84321 | ||
|
|
4d953ac09b | ||
|
|
d9ce0acd83 | ||
|
|
f735e5e268 | ||
|
|
97358d15ef | ||
|
|
ea0886229e |
@@ -12,7 +12,7 @@ authors = [
|
||||
dependencies = [
|
||||
"arrow>=1.3.0",
|
||||
"chardet>=5.2.0",
|
||||
"cryptography==46.0.3",
|
||||
"cryptography==46.0.5",
|
||||
"distro; sys_platform=='linux'",
|
||||
"filelock>=3.18.0",
|
||||
"google-api-python-client>=2.167.0",
|
||||
|
||||
@@ -2789,21 +2789,23 @@ gam create chromepolicyimage <ChromePolicyImageSchemaName> <FileName>
|
||||
|
||||
gam update chromepolicy [convertcrnl]
|
||||
(<SchemaName> ((<Field> <Value>)+ | <JSONData>))+
|
||||
((ou|orgunit <OrgUnitItem>)|(cigroup <GroupItem>))
|
||||
((ou|orgunit <OrgUnitItem>)|(group <GroupItem>))
|
||||
[(printerid <PrinterID>)|(appid <AppID>)]
|
||||
gam delete chromepolicy
|
||||
(<SchemaName> [<JSONData>])+
|
||||
((ou|orgunit <OrgUnitItem>)|(cigroup <GroupItem>))
|
||||
((ou|orgunit <OrgUnitItem>)|(group <GroupItem>))
|
||||
[(printerid <PrinterID>)|(appid <AppID>)]
|
||||
gam show chromepolicies
|
||||
((ou|orgunit <OrgUnitItem> [show all|direct|inherited])|(cigroup <GroupItem>))
|
||||
((ou|orgunit <OrgUnitItem> [show all|direct|inherited])|(group <GroupItem>))
|
||||
[(printerid <PrinterID>)|(appid <AppID>)]
|
||||
(filter <StringList>)* (namespace <NamespaceList>)*
|
||||
[show all|direct|inherited]
|
||||
[formatjson]
|
||||
gam print chromepolicies [todrive <ToDriveAttribute>*]
|
||||
((ou|orgunit <OrgUnitItem> [show all|direct|inherited])|(cigroup <GroupItem>))
|
||||
((ou|orgunit <OrgUnitItem> [show all|direct|inherited])|(group <GroupItem>))
|
||||
[(printerid <PrinterID>)|(appid <AppID>)]
|
||||
(filter <StringList>)* (namespace <NamespaceList>)*
|
||||
[show all|direct|inherited] [shownopolicy]
|
||||
[[formatjson [quotechar <Character>]]
|
||||
|
||||
<ChromePolicySchemaFieldName> ::=
|
||||
@@ -6166,6 +6168,7 @@ Display a users calendar settings
|
||||
defaulteventlength|
|
||||
format24hourtime|
|
||||
hideinvitations|
|
||||
hideinvitationssetting|
|
||||
hideweekends|
|
||||
locale|
|
||||
remindonrespondedeventsonly|
|
||||
|
||||
@@ -1,3 +1,25 @@
|
||||
7.33.03
|
||||
|
||||
Fixed bug in `gam [<UserTypeEntity>] sendemail ... from <EmailAddress> replyto <EmailAddress>`
|
||||
where an `<EmailAddress>` of the form `Text <user@domain.com>` had the `Text` removed.
|
||||
|
||||
7.33.02
|
||||
|
||||
Added `hideinvitationssetting` to `<UserCalendarSettingsField>` used by
|
||||
`gam <UserTypeEntity> print|show calsettings`.
|
||||
|
||||
7.33.01
|
||||
|
||||
Added option `shownopolicy` to `gam print chromepolicies` that will display output like the following
|
||||
if no policies apply to the selected OU or group.
|
||||
```
|
||||
gam print chromepolicies ou /Test appid chrome:emidddocikgklceeeifefomdnbkldhng namespace chrome.users.apps shownopolicy
|
||||
Getting all Chrome Policies that match query (chrome.users.apps.*) for /Test
|
||||
Got 0 Chrome Policies that matched query (chrome.users.apps.*) for /Test...
|
||||
name,orgUnitPath,parentOrgUnitPath,direct,appId
|
||||
noPolicy,/Test,/,False,chrome:emidddocikgklceeeifefomdnbkldhng
|
||||
```
|
||||
|
||||
7.33.00
|
||||
|
||||
Added variable `developer_preview_apis` to `gam.cfg` that is a comma separated list of APIs requiring a Developer Preview key.
|
||||
|
||||
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
|
||||
"""
|
||||
|
||||
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
||||
__version__ = '7.33.00'
|
||||
__version__ = '7.33.03'
|
||||
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
||||
|
||||
# pylint: disable=wrong-import-position
|
||||
@@ -1331,6 +1331,8 @@ def validateEmailAddressOrUID(emailAddressOrUID, checkPeople=True, ciGroupsAPI=F
|
||||
return emailAddressOrUID
|
||||
return emailAddressOrUID.find('@') != 0 and emailAddressOrUID.count('@') <= 1
|
||||
|
||||
NAME_EMAIL_ADDRESS_PATTERN = re.compile(r'^(.*)<(.+)>$')
|
||||
|
||||
# Normalize user/group email address/uid
|
||||
# uid:12345abc -> 12345abc
|
||||
# foo -> foo@domain
|
||||
@@ -1349,6 +1351,10 @@ def normalizeEmailAddressOrUID(emailAddressOrUID, noUid=False, checkForCustomerI
|
||||
return cg.group(1)
|
||||
if ciGroupsAPI and emailAddressOrUID.startswith('groups/'):
|
||||
return emailAddressOrUID
|
||||
if emailAddressOrUID.find('<') >= 0:
|
||||
match = NAME_EMAIL_ADDRESS_PATTERN.match(emailAddressOrUID)
|
||||
if match:
|
||||
emailAddressOrUID = match.group(2)
|
||||
atLoc = emailAddressOrUID.find('@')
|
||||
if atLoc == 0:
|
||||
return emailAddressOrUID[1:].lower() if not noLower else emailAddressOrUID[1:]
|
||||
@@ -4147,7 +4153,7 @@ def SetGlobalVariables():
|
||||
GC.Values[itemName] = _getCfgPassword(sectionName, itemName)
|
||||
elif varType == GC.TYPE_STRING:
|
||||
GC.Values[itemName] = _getCfgString(sectionName, itemName)
|
||||
elif varType in {GC.TYPE_STRINGLIST, GC.TYPE_HEADERFORCE, GC.TYPE_HEADERORDER}:
|
||||
elif varType in {GC.TYPE_STRINGLIST, GC.TYPE_HEADERFORCEREQUIRED, GC.TYPE_HEADERORDER}:
|
||||
GC.Values[itemName] = _getCfgStringList(sectionName, itemName)
|
||||
elif varType == GC.TYPE_FILE:
|
||||
GC.Values[itemName] = _getCfgFile(sectionName, itemName)
|
||||
@@ -4290,7 +4296,7 @@ def SetGlobalVariables():
|
||||
if GM.Globals[GM.PID] == 0:
|
||||
for itemName, itemEntry in sorted(GC.VAR_INFO.items()):
|
||||
varType = itemEntry[GC.VAR_TYPE]
|
||||
if varType in {GC.TYPE_HEADERFILTER, GC.TYPE_HEADERFORCE, GC.TYPE_HEADERORDER, GC.TYPE_ROWFILTER}:
|
||||
if varType in {GC.TYPE_HEADERFILTER, GC.TYPE_HEADERFORCEREQUIRED, GC.TYPE_HEADERORDER, GC.TYPE_ROWFILTER}:
|
||||
GM.Globals[GM.PARSER].set(sectionName, itemName, '')
|
||||
elif (varType == GC.TYPE_INTEGER) and itemName in {GC.CSV_INPUT_ROW_LIMIT, GC.CSV_OUTPUT_ROW_LIMIT}:
|
||||
GM.Globals[GM.PARSER].set(sectionName, itemName, '0')
|
||||
@@ -7328,8 +7334,6 @@ def _addEmbeddedImagesToMessage(message, embeddedImages):
|
||||
except (IOError, UnicodeDecodeError) as e:
|
||||
usageErrorExit(f'{imageFilename}: {str(e)}')
|
||||
|
||||
NAME_EMAIL_ADDRESS_PATTERN = re.compile(r'^.*<(.+)>$')
|
||||
|
||||
# Send an email
|
||||
def send_email(msgSubject, msgBody, msgTo, i=0, count=0, clientAccess=False, msgFrom=None, msgReplyTo=None,
|
||||
html=False, charset=UTF8, attachments=None, embeddedImages=None,
|
||||
@@ -7351,8 +7355,11 @@ def send_email(msgSubject, msgBody, msgTo, i=0, count=0, clientAccess=False, msg
|
||||
def cleanAddr(emailAddr):
|
||||
match = NAME_EMAIL_ADDRESS_PATTERN.match(emailAddr)
|
||||
if match:
|
||||
return match.group(1)
|
||||
return emailAddr
|
||||
emailName = match.group(1)
|
||||
emailAddr = normalizeEmailAddressOrUID(match.group(2), noUid=True, noLower=True)
|
||||
return (f'{emailName} <{emailAddr}>', emailAddr)
|
||||
emailAddr = normalizeEmailAddressOrUID(emailAddr, noUid=True, noLower=True)
|
||||
return (emailAddr, emailAddr)
|
||||
|
||||
if msgFrom is None:
|
||||
msgFrom = _getAdminEmail()
|
||||
@@ -7372,9 +7379,9 @@ def send_email(msgSubject, msgBody, msgTo, i=0, count=0, clientAccess=False, msg
|
||||
if embeddedImages:
|
||||
_addEmbeddedImagesToMessage(message, embeddedImages)
|
||||
message['Subject'] = msgSubject
|
||||
message['From'] = normalizeEmailAddressOrUID(cleanAddr(msgFrom), noUid=True, noLower=True)
|
||||
message['From'], msgFromAddr = cleanAddr(msgFrom)
|
||||
if msgReplyTo is not None:
|
||||
message['Reply-To'] = normalizeEmailAddressOrUID(cleanAddr(msgReplyTo), noUid=True, noLower=True)
|
||||
message['Reply-To'], _ = cleanAddr(msgReplyTo)
|
||||
if ccRecipients:
|
||||
message['Cc'] = ccRecipients.lower()
|
||||
if bccRecipients:
|
||||
@@ -7384,8 +7391,8 @@ def send_email(msgSubject, msgBody, msgTo, i=0, count=0, clientAccess=False, msg
|
||||
if header not in {'Subject', 'From', 'To', 'Reply-To', 'Cc', 'Bcc'}:
|
||||
message[header] = value
|
||||
if mailBox is None:
|
||||
mailBox = msgFrom
|
||||
mailBoxAddr = normalizeEmailAddressOrUID(cleanAddr(mailBox), noUid=True, noLower=True)
|
||||
mailBox = msgFromAddr
|
||||
_, mailBoxAddr = cleanAddr(mailBox)
|
||||
action = Act.Get()
|
||||
Act.Set(Act.SENDEMAIL)
|
||||
if not GC.Values[GC.SMTP_HOST]:
|
||||
@@ -30089,7 +30096,7 @@ CHROME_POLICY_SHOW_CHOICE_MAP = {
|
||||
# ((ou|orgunit <OrgUnitItem>)|(group <GroupItem>))
|
||||
# [(printerid <PrinterID>)|(appid <AppID>)]
|
||||
# (filter <StringList>)* (namespace <NamespaceList>)*
|
||||
# [show all|direct|inherited]
|
||||
# [show all|direct|inherited] [shownopolicy]
|
||||
# [[formatjson [quotechar <Character>]]
|
||||
def doPrintShowChromePolicies():
|
||||
def normalizedPolicy(policy):
|
||||
@@ -30160,25 +30167,54 @@ def doPrintShowChromePolicies():
|
||||
showJSON(None, policy, sortDictKeys=False)
|
||||
Ind.Decrement()
|
||||
|
||||
def _printPolicyRow(policy):
|
||||
row = flattenJSON(policy)
|
||||
if not FJQC.formatJSON:
|
||||
csvPF.WriteRowTitles(row)
|
||||
elif (not csvPF.rowFilter and not csvPF.rowDropFilter) or csvPF.CheckRowTitles(row):
|
||||
if entityType == Ent.ORGANIZATIONAL_UNIT:
|
||||
csvPF.WriteRowNoFilter({'name': policy['name'],
|
||||
'orgUnitPath': policy['orgUnitPath'],
|
||||
'parentOrgUnitPath': policy['parentOrgUnitPath'],
|
||||
'direct': policy['direct'],
|
||||
'JSON': json.dumps(cleanJSON(policy),
|
||||
ensure_ascii=False, sort_keys=True)})
|
||||
else:
|
||||
csvPF.WriteRowNoFilter({'name': policy['name'],
|
||||
'group': policy['group'],
|
||||
'JSON': json.dumps(cleanJSON(policy),
|
||||
ensure_ascii=False, sort_keys=True)})
|
||||
|
||||
|
||||
def _printPolicy(policy):
|
||||
nonlocal policiesShown
|
||||
policy = normalizedPolicy(policy)
|
||||
if (entityType == Ent.GROUP) or showPolicies in (CHROME_POLICY_SHOW_ALL, policy['direct']):
|
||||
row = flattenJSON(policy)
|
||||
if not FJQC.formatJSON:
|
||||
csvPF.WriteRowTitles(row)
|
||||
elif (not csvPF.rowFilter and not csvPF.rowDropFilter) or csvPF.CheckRowTitles(row):
|
||||
if entityType == Ent.ORGANIZATIONAL_UNIT:
|
||||
csvPF.WriteRowNoFilter({'name': policy['name'],
|
||||
'orgUnitPath': policy['orgUnitPath'],
|
||||
'parentOrgUnitPath': policy['parentOrgUnitPath'],
|
||||
'direct': policy['direct'],
|
||||
'JSON': json.dumps(cleanJSON(policy),
|
||||
ensure_ascii=False, sort_keys=True)})
|
||||
else:
|
||||
csvPF.WriteRowNoFilter({'name': policy['name'],
|
||||
'group': policy['group'],
|
||||
'JSON': json.dumps(cleanJSON(policy),
|
||||
ensure_ascii=False, sort_keys=True)})
|
||||
policiesShown += 1
|
||||
_printPolicyRow(policy)
|
||||
|
||||
def _printNoPolicy():
|
||||
nonlocal targetName
|
||||
policy = {'name': 'noPolicy'}
|
||||
if app_id:
|
||||
policy['appId'] = app_id
|
||||
elif printer_id:
|
||||
policy['printerId'] = printer_id
|
||||
if entityType == Ent.ORGANIZATIONAL_UNIT:
|
||||
policy['orgUnitPath'] = targetName
|
||||
if targetName == '/':
|
||||
policy['parentOrgUnitPath'] = '/'
|
||||
else:
|
||||
targetName = makeOrgUnitPathRelative(targetName)
|
||||
policy['parentOrgUnitPath'] = callGAPI(cd.orgunits(), 'get',
|
||||
throwReasons=GAPI.ORGUNIT_GET_THROW_REASONS,
|
||||
customerId=GC.Values[GC.CUSTOMER_ID],
|
||||
orgUnitPath=encodeOrgUnitPath(targetName),
|
||||
fields='parentOrgUnitPath')['parentOrgUnitPath']
|
||||
policy['direct'] = False
|
||||
else:
|
||||
policy['group'] = targetName
|
||||
_printPolicyRow(policy)
|
||||
|
||||
cp = buildGAPIObject(API.CHROMEPOLICY)
|
||||
cd = buildGAPIObject(API.DIRECTORY)
|
||||
@@ -30190,6 +30226,8 @@ def doPrintShowChromePolicies():
|
||||
app_id = groupEmail = orgUnit = printer_id = targetResource = None
|
||||
showPolicies = CHROME_POLICY_SHOW_ALL
|
||||
psFilters = []
|
||||
showNoPolicy = False
|
||||
policiesShown = 0
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if csvPF and myarg == 'todrive':
|
||||
@@ -30213,6 +30251,8 @@ def doPrintShowChromePolicies():
|
||||
psFilters.append(f'{psFilter}.*')
|
||||
elif myarg == 'show':
|
||||
showPolicies = getChoice(CHROME_POLICY_SHOW_CHOICE_MAP, mapChoice=True)
|
||||
elif csvPF and myarg == 'shownopolicy':
|
||||
showNoPolicy = True
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, False)
|
||||
checkPolicyArgs(targetResource, printer_id, app_id)
|
||||
@@ -30302,7 +30342,8 @@ def doPrintShowChromePolicies():
|
||||
else:
|
||||
for policy in policies:
|
||||
_printPolicy(policy)
|
||||
if csvPF:
|
||||
if showNoPolicy and policiesShown == 0:
|
||||
_printNoPolicy()
|
||||
csvPF.writeCSVfile(f'Chrome Policies - {targetName}')
|
||||
|
||||
CHROME_IMAGE_SCHEMAS_MAP = {
|
||||
@@ -54147,6 +54188,7 @@ USER_CALENDAR_SETTINGS_FIELDS_CHOICE_MAP = {
|
||||
'defaulteventlength': 'defaultEventLength',
|
||||
'format24hourtime': 'format24HourTime',
|
||||
'hideinvitations': 'hideInvitations',
|
||||
'hideinvitationssetting': 'hideInvitationsSetting',
|
||||
'hideweekends': 'hideWeekends',
|
||||
'locale': 'locale',
|
||||
'remindonrespondedeventsonly': 'remindOnRespondedEventsOnly',
|
||||
|
||||
@@ -123,6 +123,8 @@ CSV_OUTPUT_HEADER_DROP_FILTER = 'csv_output_header_drop_filter'
|
||||
CSV_OUTPUT_HEADER_FORCE = 'csv_output_header_force'
|
||||
# Orde output column headers
|
||||
CSV_OUTPUT_HEADER_ORDER = 'csv_output_header_order'
|
||||
# Required output column headers
|
||||
CSV_OUTPUT_HEADER_REQUIRED = 'csv_output_header_required'
|
||||
# Line terminator in CSV output file
|
||||
CSV_OUTPUT_LINE_TERMINATOR = 'csv_output_line_terminator'
|
||||
# Quote character in CSV output file
|
||||
@@ -329,6 +331,7 @@ CSV_INPUT_ROW_FILTER_ITEMS = {CSV_INPUT_ROW_FILTER, CSV_INPUT_ROW_FILTER_MODE,
|
||||
|
||||
CSV_OUTPUT_ROW_FILTER_ITEMS = {CSV_OUTPUT_HEADER_FILTER, CSV_OUTPUT_HEADER_DROP_FILTER,
|
||||
CSV_OUTPUT_HEADER_FORCE, CSV_OUTPUT_HEADER_ORDER,
|
||||
# CSV_OUTPUT_HEADER_REQUIRED,
|
||||
CSV_OUTPUT_ROW_FILTER, CSV_OUTPUT_ROW_FILTER_MODE,
|
||||
CSV_OUTPUT_ROW_DROP_FILTER, CSV_OUTPUT_ROW_DROP_FILTER_MODE,
|
||||
CSV_OUTPUT_ROW_LIMIT}
|
||||
@@ -373,6 +376,7 @@ Defaults = {
|
||||
CSV_OUTPUT_HEADER_DROP_FILTER: '',
|
||||
CSV_OUTPUT_HEADER_FORCE: '',
|
||||
CSV_OUTPUT_HEADER_ORDER: '',
|
||||
# CSV_OUTPUT_HEADER_REQUIRED: '',
|
||||
CSV_OUTPUT_LINE_TERMINATOR: 'lf',
|
||||
CSV_OUTPUT_QUOTE_CHAR: '\'"\'',
|
||||
CSV_OUTPUT_ROW_FILTER: '',
|
||||
@@ -487,7 +491,7 @@ TYPE_EMAIL_OPTIONAL = 'emao'
|
||||
TYPE_FILE = 'file'
|
||||
TYPE_FLOAT = 'floa'
|
||||
TYPE_HEADERFILTER = 'heaf'
|
||||
TYPE_HEADERFORCE = 'hefo'
|
||||
TYPE_HEADERFORCEREQUIRED = 'hefr'
|
||||
TYPE_HEADERORDER = 'heor'
|
||||
TYPE_INTEGER = 'inte'
|
||||
TYPE_LANGUAGE = 'lang'
|
||||
@@ -544,8 +548,9 @@ VAR_INFO = {
|
||||
CSV_OUTPUT_FIELD_DELIMITER: {VAR_TYPE: TYPE_CHARACTER},
|
||||
CSV_OUTPUT_HEADER_FILTER: {VAR_TYPE: TYPE_HEADERFILTER},
|
||||
CSV_OUTPUT_HEADER_DROP_FILTER: {VAR_TYPE: TYPE_HEADERFILTER},
|
||||
CSV_OUTPUT_HEADER_FORCE: {VAR_TYPE: TYPE_HEADERFORCE},
|
||||
CSV_OUTPUT_HEADER_FORCE: {VAR_TYPE: TYPE_HEADERFORCEREQUIRED},
|
||||
CSV_OUTPUT_HEADER_ORDER: {VAR_TYPE: TYPE_HEADERORDER},
|
||||
# CSV_OUTPUT_HEADER_REQUIRED: {VAR_TYPE: TYPE_HEADERFORCEREQUIRED},
|
||||
CSV_OUTPUT_LINE_TERMINATOR: {VAR_TYPE: TYPE_CHOICE, VAR_CHOICES: {'cr': '\r', 'lf': '\n', 'crlf': '\r\n'}},
|
||||
CSV_OUTPUT_QUOTE_CHAR: {VAR_TYPE: TYPE_CHARACTER},
|
||||
CSV_OUTPUT_ROW_FILTER: {VAR_TYPE: TYPE_ROWFILTER},
|
||||
|
||||
@@ -69,6 +69,8 @@ CSV_OUTPUT_HEADER_FILTER = 'cohf'
|
||||
CSV_OUTPUT_HEADER_FORCE = 'cofh'
|
||||
# Order output column headers
|
||||
CSV_OUTPUT_HEADER_ORDER = 'coho'
|
||||
# Required output column headers
|
||||
CSV_OUTPUT_HEADER_REQUIRED = 'corh'
|
||||
# No escape character in CSV output file
|
||||
CSV_OUTPUT_NO_ESCAPE_CHAR = 'cone'
|
||||
# Quote character in CSV output file
|
||||
@@ -248,6 +250,7 @@ Globals = {
|
||||
CSV_OUTPUT_HEADER_FILTER: [],
|
||||
CSV_OUTPUT_HEADER_FORCE: [],
|
||||
CSV_OUTPUT_HEADER_ORDER: [],
|
||||
# CSV_OUTPUT_HEADER_REQUIRED: [],
|
||||
CSV_OUTPUT_NO_ESCAPE_CHAR: None,
|
||||
CSV_OUTPUT_QUOTE_CHAR: None,
|
||||
CSV_OUTPUT_ROW_DROP_FILTER: [],
|
||||
|
||||
@@ -282,10 +282,11 @@ gam show chromepolicies
|
||||
((ou|orgunit <OrgUnitItem> [show all|direct|inherited])|(group <GroupItem>))
|
||||
[(printerid <PrinterID>)|(appid <AppID>)]
|
||||
[filter <StringList>] [namespace <NamespaceList>]
|
||||
[show all|direct|inherited]
|
||||
[formatjson]
|
||||
```
|
||||
By default, all Chrome policies for the OU or group are displayed.
|
||||
* `filter <String>` - Display policies based on fields like its resource name, description and additionalTargetKeyNames.
|
||||
* `filter <StringList>` - Display policies based on fields like its resource name, description and additionalTargetKeyNames.
|
||||
* `show all` - For OUs, display policies regardless of where set; this is the default
|
||||
* `show direct` - For OUs, display policies set directly in the OU
|
||||
* `show inherited` - For OUs, display policies set in a parent OU
|
||||
@@ -329,15 +330,25 @@ By default, Gam displays the information as an indented list of keys and values.
|
||||
gam print chromepolicies [todrive <ToDriveAttribute>*]
|
||||
((ou|orgunit <OrgUnitItem> [show all|direct|inherited])|(group <GroupItem>))
|
||||
[(printerid <PrinterID>)|(appid <AppID>)]
|
||||
[filter <String>] [namespace <NamespaceList>]
|
||||
[filter <StringList>] [namespace <NamespaceList>]
|
||||
[show all|direct|inherited] [shownopolicy]
|
||||
[[formatjson [quotechar <Character>]]
|
||||
```
|
||||
By default, all Chrome policies for the OU or group are displayed.
|
||||
* `filter <String>` - Display policies based on fields like its resource name, description and additionalTargetKeyNames.
|
||||
* `filter <StringList>` - Display policies based on fields like its resource name, description and additionalTargetKeyNames.
|
||||
* `show all` - For OUs, display policies regardless of where set; this is the default
|
||||
* `show direct` - For OUs, display policies set directly in the OU
|
||||
* `show inherited` - For OUs, display policies set in a parent OU
|
||||
|
||||
Use option `shownopolicy` to display output like the following if no policies apply to the OU or group.
|
||||
```
|
||||
gam print chromepolicies ou /Test appid chrome:emidddocikgklceeeifefomdnbkldhng namespace chrome.users.apps shownopolicy
|
||||
Getting all Chrome Policies that match query (chrome.users.apps.*) for /Test
|
||||
Got 0 Chrome Policies that matched query (chrome.users.apps.*) for /Test...
|
||||
name,orgUnitPath,parentOrgUnitPath,direct,appId
|
||||
noPolicy,/Test,/,False,chrome:emidddocikgklceeeifefomdnbkldhng
|
||||
```
|
||||
|
||||
These are the default namespaces; use `namespace <NamespaceList>` to override.
|
||||
* `default`
|
||||
* chrome.users
|
||||
|
||||
@@ -10,6 +10,28 @@ 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
|
||||
|
||||
### 7.33.03
|
||||
|
||||
Fixed bug in `gam [<UserTypeEntity>] sendemail ... from <EmailAddress> replyto <EmailAddress>`
|
||||
where an `<EmailAddress>` of the form `Text <user@domain.com>` had the `Text` removed.
|
||||
|
||||
### 7.33.02
|
||||
|
||||
Added `hideinvitationssetting` to `<UserCalendarSettingsField>` used by
|
||||
`gam <UserTypeEntity> print|show calsettings`.
|
||||
|
||||
### 7.33.01
|
||||
|
||||
Added option `shownopolicy` to `gam print chromepolicies` that will display output like the following
|
||||
if no policies apply to the selected OU or group.
|
||||
```
|
||||
gam print chromepolicies ou /Test appid chrome:emidddocikgklceeeifefomdnbkldhng namespace chrome.users.apps shownopolicy
|
||||
Getting all Chrome Policies that match query (chrome.users.apps.*) for /Test
|
||||
Got 0 Chrome Policies that matched query (chrome.users.apps.*) for /Test...
|
||||
name,orgUnitPath,parentOrgUnitPath,direct,appId
|
||||
noPolicy,/Test,/,False,chrome:emidddocikgklceeeifefomdnbkldhng
|
||||
```
|
||||
|
||||
### 7.33.00
|
||||
|
||||
Added variable `developer_preview_apis` to `gam.cfg` that is a comma separated list of APIs requiring a Developer Preview key.
|
||||
|
||||
@@ -252,7 +252,7 @@ writes the credentials into the file oauth2.txt.
|
||||
admin@server:/Users/admin$ rm -f /Users/admin/GAMConfig/oauth2.txt
|
||||
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
|
||||
GAM 7.33.00 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM 7.33.03 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.14.2 64-bit final
|
||||
macOS Tahoe 26.2 x86_64
|
||||
@@ -1034,7 +1034,7 @@ writes the credentials into the file oauth2.txt.
|
||||
C:\>del C:\GAMConfig\oauth2.txt
|
||||
C:\>gam version
|
||||
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
|
||||
GAM 7.33.00 - https://github.com/GAM-team/GAM - pythonsource
|
||||
GAM 7.33.03 - https://github.com/GAM-team/GAM - pythonsource
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.14.2 64-bit final
|
||||
Windows 11 10.0.26200 AMD64
|
||||
|
||||
34
wiki/No-Owner-Secondary-Calendars.md
Normal file
34
wiki/No-Owner-Secondary-Calendars.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Secondary Calendars with no Owner
|
||||
|
||||
Here's a start on how to get information for non-owned secondary calendars
|
||||
|
||||
Save the CSV file that Google sent you as NoOwnerSecCals.csv
|
||||
|
||||
Get calendar description and summary for non-owned secondary calendars.
|
||||
* There will be one row per calendar.
|
||||
```
|
||||
gam config num_threads 10 csv_output_header_force "calendarId,description,summary" redirect csv ./NOSC_Details.csv multiprocess redirect stderr - multiprocess csv NoOwnerSecCals.csv gam calendar "~Secondary calendar email" print settings fields description,summary
|
||||
```
|
||||
|
||||
Get event counts for non-owned secondary calendars.
|
||||
* There will be one row per calendar.
|
||||
```
|
||||
gam config num_threads 10 redirect csv ./NOSC_EventCounts.csv multiprocess redirect stderr - multiprocess csv NOSC_Details.csv gam calendar "~calendarId" print events countsonly addcsvdata description "~description" addcsvdata summary "~summary"
|
||||
```
|
||||
|
||||
Get summary for non-owned secondary calendars - Contains details, counts, ACLs
|
||||
* There will be one row per calendar/ACL combination
|
||||
```
|
||||
gam config num_threads 10 redirect csv ./NOSC_Summary.csv multiprocess redirect stderr - multiprocess csv NOSC_EventCounts.csv gam calendar "~calendarId" print acls noselfowner addcsvdata description "~description" addcsvdata summary "~summary" addcsvdata events "~events"
|
||||
```
|
||||
|
||||
You can add an owner.
|
||||
* Replace `admin@domain.com` with a super admin other than the one from: `gam oauth info`
|
||||
```
|
||||
gam config num_threads 10 redirect stdout ./Add_NOSC_Owner.txt multiprocess redirect stderr stdout csv NoOwnerSecCals.csv gam calendar "~Secondary calendar email" add acls owner admin@domain.com sendnotifications false
|
||||
```
|
||||
After inspecting NOSC_Summary.csv, you can delete the calendars if desired.
|
||||
* Replace `admin@domain.com` with the super admin specified in the previous step
|
||||
```
|
||||
gam config num_threads 10 redirect stdout ./Delete_NOSC.txt multiprocess redirect stderr stdout csv NoOwnerSecCals.csv gam user admin@domain.com remove calendar "~Secondary calendar email"
|
||||
``
|
||||
@@ -101,6 +101,7 @@
|
||||
defaulteventlength|
|
||||
format24hourtime|
|
||||
hideinvitations|
|
||||
hideinvitationssetting|
|
||||
hideweekends|
|
||||
locale|
|
||||
remindonrespondedeventsonly|
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
- [API documentation](#api-documentation)
|
||||
- [Definitions](#definitions)
|
||||
- [Aliases](#aliases)
|
||||
- [Delegation Notification](#delegation-notification)
|
||||
- [Delegator Banner](#delegator-banner)
|
||||
- [Delegate Notification](#delegate-notification)
|
||||
- [Create Gmail delegates](#create-gmail-delegates)
|
||||
- [Delete Gmail delegates](#delete-gmail-delegates)
|
||||
- [Update Gmail delegates](#update-gmail-delegates)
|
||||
@@ -57,7 +58,13 @@ The `convertalias` option causes GAM to make an extra API call per user in `<Use
|
||||
to convert aliases to primary email addresses. If you know that all of the email addresses
|
||||
in `<UserEntity>` are primary, you can omit `convertalias` and avoid the extra API calls.
|
||||
|
||||
## Delegation Notification
|
||||
## Delegator Banner
|
||||
When creating a delegate, the following banner is displayed in the delegator's Gmail inbox, it can not be suppressed.
|
||||
```
|
||||
<Delegate> now has delegated access to your account. This notice will end in 7 days.
|
||||
```
|
||||
|
||||
## Delegate Notification
|
||||
When creating a delegate, you can send a message to the delegate.
|
||||
```
|
||||
[notify [<Boolean>]
|
||||
|
||||
@@ -586,6 +586,9 @@ Getting all Groups for testuser1@domain.com (1/2)
|
||||
Getting all Groups for testuser2@domain.com (2/2)
|
||||
User,Groups,GroupsList
|
||||
testuser2@domain.com,0,
|
||||
|
||||
# Get group membership for all users
|
||||
$ gam config auto_batch_min 1 num_threads 10 redirect csv ./UsersGroups.csv multiprocess sortheaders User,Group redirect stderr - multiprocess all users print groups
|
||||
```
|
||||
### Display groups and their parents
|
||||
Display a user's groups and their parents as an indented list.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Print the current version of Gam with details
|
||||
```
|
||||
gam version
|
||||
GAM 7.33.00 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM 7.33.03 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.14.2 64-bit final
|
||||
macOS Tahoe 26.2 x86_64
|
||||
@@ -15,7 +15,7 @@ Time: 2025-12-23T13:57:00-08:00
|
||||
Print the current version of Gam with details and time offset information
|
||||
```
|
||||
gam version timeoffset
|
||||
GAM 7.33.00 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM 7.33.03 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.14.2 64-bit final
|
||||
macOS Tahoe 26.2 x86_64
|
||||
@@ -27,7 +27,7 @@ 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
|
||||
```
|
||||
gam version extended
|
||||
GAM 7.33.00 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM 7.33.03 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.14.2 64-bit final
|
||||
macOS Tahoe 26.2 x86_64
|
||||
@@ -68,7 +68,7 @@ MacOS High Sierra 10.13.6 x86_64
|
||||
Path: /Users/Admin/bin/gam7
|
||||
Version Check:
|
||||
Current: 5.35.08
|
||||
Latest: 7.33.00
|
||||
Latest: 7.33.03
|
||||
echo $?
|
||||
1
|
||||
```
|
||||
@@ -76,7 +76,7 @@ echo $?
|
||||
Print the current version number without details
|
||||
```
|
||||
gam version simple
|
||||
7.33.00
|
||||
7.33.03
|
||||
```
|
||||
In Linux/MacOS you can do:
|
||||
```
|
||||
@@ -86,7 +86,7 @@ echo $VER
|
||||
Print the current version of Gam and address of this Wiki
|
||||
```
|
||||
gam help
|
||||
GAM 7.33.00 - https://github.com/GAM-team/GAM
|
||||
GAM 7.33.03 - https://github.com/GAM-team/GAM
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.14.2 64-bit final
|
||||
macOS Tahoe 26.2 x86_64
|
||||
|
||||
@@ -74,6 +74,7 @@ Client Access
|
||||
* [Calendars](Calendars)
|
||||
* [Calendars - Access](Calendars-Access)
|
||||
* [Calendars - Events](Calendars-Events)
|
||||
* [Calendars - Secondary Calendars with no Owner](No-Owner-Secondary-Calendars)
|
||||
* [Chrome Auto Update Expiration Counts](Chrome-AUE-Counts)
|
||||
* [Chrome Browser Cloud Management](Chrome-Browser-Cloud-Management)
|
||||
* [Chrome Device Counts](Chrome-Device-Counts)
|
||||
|
||||
@@ -311,12 +311,14 @@ developer_preview_apis
|
||||
A comma separated list of APIs requiring a Developer Preview key.
|
||||
Default: Blank
|
||||
Valid values:
|
||||
accesscontextmanager,admin,alertcenter,analyticsadmin,calendar-json,cbcm,chat,chromemanagement,chromepolicy,
|
||||
classroom,cloudchannel,cloudidentity,cloudresourcemanager,contactdelegation,contacts,datastudio,docs,drive,
|
||||
driveactivity,drivelabels,email-audit,forms,gmail,groupsmigration,groupssettings,iam,iamcredentials,keep,
|
||||
licensing,meet,mybusinessaccountmanagement,oauth2,orgpolicy,people,pubsub,reseller,searchconsole,
|
||||
serviceaccountlookup,servicemanagement,serviceusage,sheets,siteVerification,storage,tagmanager,tasks,vault,
|
||||
versionhistory,youtube
|
||||
accesscontextmanager,admin,alertcenter,analyticsadmin,calendar-json,cbcm,chat,
|
||||
chromemanagement,chromepolicy,classroom,cloudchannel,cloudidentity,
|
||||
cloudresourcemanager,contactdelegation,contacts,datastudio,docs,drive,
|
||||
driveactivity,drivelabels,email-audit,forms,gmail,groupsmigration,groupssettings,
|
||||
iam,iamcredentials,keep,licensing,meet,mybusinessaccountmanagement,oauth2,
|
||||
orgpolicy,people,pubsub,reseller,searchconsole,serviceaccountlookup,
|
||||
servicemanagement,serviceusage,sheets,siteVerification,storage,tagmanager,tasks,
|
||||
vault,versionhistory,youtube
|
||||
developer_preview_api_key
|
||||
A Developer Preview API key that is passed to all API calls for APIs in developer_preview_apis
|
||||
Default: Blank
|
||||
|
||||
Reference in New Issue
Block a user