mirror of
https://github.com/GAM-team/GAM.git
synced 2026-07-04 04:41:35 +00:00
Compare commits
21 Commits
v7.10.02
...
20250626.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a0c52d8eb | ||
|
|
f3e7c46561 | ||
|
|
b42c916516 | ||
|
|
4fd7172f7a | ||
|
|
e670cf3e6a | ||
|
|
e305cc0789 | ||
|
|
d7b9d43c63 | ||
|
|
75e3ae8144 | ||
|
|
130a483e4d | ||
|
|
cbd04bcec4 | ||
|
|
a51b245015 | ||
|
|
64356a9736 | ||
|
|
c18375abb7 | ||
|
|
c9c0cac57e | ||
|
|
8ca3717f97 | ||
|
|
cd0d82e994 | ||
|
|
f29f27577c | ||
|
|
cb5e5d1943 | ||
|
|
88bdfd2883 | ||
|
|
e875acf428 | ||
|
|
5d213e9951 |
8
.github/workflows/build.yml
vendored
8
.github/workflows/build.yml
vendored
@@ -457,10 +457,6 @@ jobs:
|
|||||||
- name: Custom wheels for Win arm64
|
- name: Custom wheels for Win arm64
|
||||||
if: runner.os == 'Windows' && runner.arch == 'ARM64'
|
if: runner.os == 'Windows' && runner.arch == 'ARM64'
|
||||||
run: |
|
run: |
|
||||||
latest_lxml_whl=$(curl https://api.github.com/repos/GAM-team/lxml-wheel/releases/latest -s | jq -r .assets.[0].browser_download_url)
|
|
||||||
echo "Downloading ${latest_lxml_whl}..."
|
|
||||||
curl -O -L "$latest_lxml_whl"
|
|
||||||
"$PYTHON" -m pip install lxml*.whl
|
|
||||||
latest_crypt_whl=$(curl https://api.github.com/repos/jay0lee/cryptography/releases/latest -s | jq -r .assets.[0].browser_download_url)
|
latest_crypt_whl=$(curl https://api.github.com/repos/jay0lee/cryptography/releases/latest -s | jq -r .assets.[0].browser_download_url)
|
||||||
echo "Downloading ${latest_crypt_whl}..."
|
echo "Downloading ${latest_crypt_whl}..."
|
||||||
curl -O -L "$latest_crypt_whl"
|
curl -O -L "$latest_crypt_whl"
|
||||||
@@ -810,7 +806,7 @@ jobs:
|
|||||||
echo "Created shared drive ${driveid}"
|
echo "Created shared drive ${driveid}"
|
||||||
$gam create user $newuser firstname GHA lastname $JID displayname "Github Actions ${JID}" password random recoveryphone 12125121110 recoveryemail jay0lee@gmail.com gha.jid $JID languages en+,en-GB- ou "${newou}"
|
$gam create user $newuser firstname GHA lastname $JID displayname "Github Actions ${JID}" password random recoveryphone 12125121110 recoveryemail jay0lee@gmail.com gha.jid $JID languages en+,en-GB- ou "${newou}"
|
||||||
$gam user $newuser add license workspaceenterpriseplus
|
$gam user $newuser add license workspaceenterpriseplus
|
||||||
$gam user $newuser update photo https://dummyimage.com/400x600/000/fff
|
$gam user $newuser update photo https://dummyimage.com/98x98/000/fff.jpg
|
||||||
$gam user $newuser get photo
|
$gam user $newuser get photo
|
||||||
$gam user $newuser delete photo
|
$gam user $newuser delete photo
|
||||||
$gam create alias $newalias user $newuser
|
$gam create alias $newalias user $newuser
|
||||||
@@ -920,7 +916,7 @@ jobs:
|
|||||||
$gam config enable_dasa true save
|
$gam config enable_dasa true save
|
||||||
$gam print users query "gha.jid=$JID" | $gam csv - gam delete user ~primaryEmail || if [ $? != 50 ]; then exit $?; fi # expect a 50 return code (vault hold on user)
|
$gam print users query "gha.jid=$JID" | $gam csv - gam delete user ~primaryEmail || if [ $? != 50 ]; then exit $?; fi # expect a 50 return code (vault hold on user)
|
||||||
$gam print mobile
|
$gam print mobile
|
||||||
$gam print devices
|
$gam print devices clientstates
|
||||||
$gam print browsers
|
$gam print browsers
|
||||||
$gam print cros allfields orderby serialnumber
|
$gam print cros allfields orderby serialnumber
|
||||||
$gam show crostelemetry storagepercentonly
|
$gam show crostelemetry storagepercentonly
|
||||||
|
|||||||
@@ -279,6 +279,7 @@ If an item contains spaces, it should be surrounded by ".
|
|||||||
geminiedu | 1010470004 | Gemini Education |
|
geminiedu | 1010470004 | Gemini Education |
|
||||||
geminiedupremium| 1010470005 | Gemini Education Premium |
|
geminiedupremium| 1010470005 | Gemini Education Premium |
|
||||||
geminient| duetai | 1010470001 | Gemini Enterprise |
|
geminient| duetai | 1010470001 | Gemini Enterprise |
|
||||||
|
geminiultra | 1010470008 | Google AI Ultra for Business |
|
||||||
gsuitebasic | gafb | gafw | basic | Google-Apps-For-Business |
|
gsuitebasic | gafb | gafw | basic | Google-Apps-For-Business |
|
||||||
gsuitebusiness | gau | gsb | unlimited | Google-Apps-Unlimited |
|
gsuitebusiness | gau | gsb | unlimited | Google-Apps-Unlimited |
|
||||||
gsuitebusinessarchived | gsbau | businessarchived | 1010340002 | Google Workspace Business - Archived User |
|
gsuitebusinessarchived | gsbau | businessarchived | 1010340002 | Google Workspace Business - Archived User |
|
||||||
@@ -4124,6 +4125,7 @@ gam print devices [todrive <ToDriveAttribute>*]
|
|||||||
[orderby <DeviceOrderByFieldName> [ascending|descending]]
|
[orderby <DeviceOrderByFieldName> [ascending|descending]]
|
||||||
[all|company|personal|nocompanydevices|nopersonaldevices]
|
[all|company|personal|nocompanydevices|nopersonaldevices]
|
||||||
[nodeviceusers|oneuserperrow]
|
[nodeviceusers|oneuserperrow]
|
||||||
|
[clientstates]
|
||||||
[formatjson [quotechar <Character>]]
|
[formatjson [quotechar <Character>]]
|
||||||
[showitemcountonly]
|
[showitemcountonly]
|
||||||
|
|
||||||
@@ -4435,20 +4437,18 @@ gam report usage customer [todrive <ToDriveAttribute>*]
|
|||||||
[convertmbtogb]
|
[convertmbtogb]
|
||||||
|
|
||||||
<ActivityApplicationName> ::=
|
<ActivityApplicationName> ::=
|
||||||
access|accesstransparency|
|
accesstransparency|access|
|
||||||
admin|
|
admin|
|
||||||
calendar|calendars|
|
calendar|calendars|
|
||||||
chat|
|
chat|
|
||||||
chrome|
|
chrome|
|
||||||
classroom|
|
classroom|
|
||||||
contextawareaccess|
|
contextawareaccess|
|
||||||
currents|gplus|google+|
|
gplus|currents|google+|
|
||||||
datastudio|
|
datastudio|
|
||||||
devices|mobile|
|
|
||||||
domain|
|
|
||||||
drive|doc|docs|
|
drive|doc|docs|
|
||||||
gcp|cloud|
|
gcp|cloud|
|
||||||
gemini|geminiforworkspace|
|
geminiinworkspaceapps|gemini|geminiforworkspace|
|
||||||
groups|group|
|
groups|group|
|
||||||
groupsenterprise|enterprisegroups|
|
groupsenterprise|enterprisegroups|
|
||||||
jamboard|
|
jamboard|
|
||||||
@@ -4466,7 +4466,7 @@ gam report <ActivityApplicationName> [todrive <ToDriveAttribute>*]
|
|||||||
[(user all|<UserItem>)|(orgunit|org|ou <OrgUnitPath> [showorgunit])|(select <UserTypeEntity>)]
|
[(user all|<UserItem>)|(orgunit|org|ou <OrgUnitPath> [showorgunit])|(select <UserTypeEntity>)]
|
||||||
[([start <Time>] [end <Time>])|(range <Time> <Time>)|
|
[([start <Time>] [end <Time>])|(range <Time> <Time>)|
|
||||||
yesterday|today|thismonth|(previousmonths <Integer>)]
|
yesterday|today|thismonth|(previousmonths <Integer>)]
|
||||||
[filtertime.String> <Time>] [filter|filters <String>]
|
[filtertime.<String> <Time>] [filter|filters <String>]
|
||||||
[event|events <EventNameList>] [ip <String>]
|
[event|events <EventNameList>] [ip <String>]
|
||||||
[groupidfilter <String>]
|
[groupidfilter <String>]
|
||||||
[maxactivities <Number>] [maxevents <Number>] [maxresults <Number>]
|
[maxactivities <Number>] [maxevents <Number>] [maxresults <Number>]
|
||||||
|
|||||||
@@ -1,3 +1,34 @@
|
|||||||
|
7.10.07
|
||||||
|
|
||||||
|
Updated `gam <UserTypeEntity> copy|move drivefile` to hanndle additional instances of
|
||||||
|
the `cannotModifyInheritedPermission` error.
|
||||||
|
|
||||||
|
Added license SKU `Google AI Ultra for Business`
|
||||||
|
* ProductID - 101047
|
||||||
|
* SKUID - 1010470008 | geminiultra
|
||||||
|
|
||||||
|
7.10.06
|
||||||
|
|
||||||
|
Added option `clientstates` to `gam print devices` to include client states in device output.
|
||||||
|
|
||||||
|
7.10.05
|
||||||
|
|
||||||
|
Google renamed an error: `cannotModifyInheritedTeamDrivePermission` became `cannotModifyInheritedPermission`.
|
||||||
|
GAM will now handle the new error.
|
||||||
|
|
||||||
|
7.10.04
|
||||||
|
|
||||||
|
Updated `gam report <ActivityApplicationName>` to accept accept application names as defined
|
||||||
|
in the Reports API discovery document; this means that GAM does not have to be updated when
|
||||||
|
Google defines a new application name.
|
||||||
|
|
||||||
|
`gemini_in_workspace_apps` is now available in `gam report`.
|
||||||
|
|
||||||
|
7.10.03
|
||||||
|
|
||||||
|
Fixed bug in commands that modify messages where the `labelids <LabelIdList>` option
|
||||||
|
was not being applied.
|
||||||
|
|
||||||
7.10.02
|
7.10.02
|
||||||
|
|
||||||
Added option `labelids <LabelIdList>` to all commands that process messages;
|
Added option `labelids <LabelIdList>` to all commands that process messages;
|
||||||
|
|||||||
@@ -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.10.02'
|
__version__ = '7.10.07'
|
||||||
__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
|
||||||
@@ -8864,6 +8864,7 @@ class CSVPrintFile():
|
|||||||
GAPI.fileOrganizerNotYetEnabledForThisTeamDrive,
|
GAPI.fileOrganizerNotYetEnabledForThisTeamDrive,
|
||||||
GAPI.fileOrganizerOnFoldersInSharedDriveOnly,
|
GAPI.fileOrganizerOnFoldersInSharedDriveOnly,
|
||||||
GAPI.fileOrganizerOnNonTeamDriveNotSupported,
|
GAPI.fileOrganizerOnNonTeamDriveNotSupported,
|
||||||
|
GAPI.cannotModifyInheritedPermission,
|
||||||
GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility,
|
GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility,
|
||||||
GAPI.invalidSharingRequest, GAPI.fileNeverWritable, GAPI.abusiveContentRestriction) as e:
|
GAPI.invalidSharingRequest, GAPI.fileNeverWritable, GAPI.abusiveContentRestriction) as e:
|
||||||
entityActionFailedWarning([Ent.USER, user, Ent.SPREADSHEET, title,
|
entityActionFailedWarning([Ent.USER, user, Ent.SPREADSHEET, title,
|
||||||
@@ -13548,52 +13549,55 @@ def doReportUsage():
|
|||||||
NL_SPACES_PATTERN = re.compile(r'\n +')
|
NL_SPACES_PATTERN = re.compile(r'\n +')
|
||||||
DISABLED_REASON_TIME_PATTERN = re.compile(r'.*(\d{4}/\d{2}/\d{2}-\d{2}:\d{2}:\d{2})')
|
DISABLED_REASON_TIME_PATTERN = re.compile(r'.*(\d{4}/\d{2}/\d{2}-\d{2}:\d{2}:\d{2})')
|
||||||
|
|
||||||
REPORT_CHOICE_MAP = {
|
REPORT_ALIASES_CHOICE_MAP = {
|
||||||
'access': 'access_transparency',
|
'access': 'accesstransparency',
|
||||||
'accesstransparency': 'access_transparency',
|
|
||||||
'admin': 'admin',
|
|
||||||
'calendar': 'calendar',
|
|
||||||
'calendars': 'calendar',
|
'calendars': 'calendar',
|
||||||
'chat': 'chat',
|
|
||||||
'chrome': 'chrome',
|
|
||||||
'classroom': 'classroom',
|
|
||||||
'cloud': 'gcp',
|
'cloud': 'gcp',
|
||||||
'contextawareaccess': 'context_aware_access',
|
|
||||||
'currents': 'gplus',
|
'currents': 'gplus',
|
||||||
'customer': 'customer',
|
|
||||||
'customers': 'customer',
|
'customers': 'customer',
|
||||||
'datastudio': 'data_studio',
|
'domain': 'customer',
|
||||||
'devices': 'mobile',
|
'devices': 'mobile',
|
||||||
'doc': 'drive',
|
'doc': 'drive',
|
||||||
'docs': 'drive',
|
'docs': 'drive',
|
||||||
'domain': 'customer',
|
'enterprisegroups': 'groupsenterprise',
|
||||||
'drive': 'drive',
|
'gemini': 'geminiinworkspaceapps',
|
||||||
'enterprisegroups': 'groups_enterprise',
|
'geminiforworkspace': 'geminiinworkspaceapps',
|
||||||
'gcp': 'gcp',
|
|
||||||
'gemini': 'gemini_for_workspace',
|
|
||||||
'geminiforworkspace': 'gemini_for_workspace',
|
|
||||||
'gplus': 'gplus',
|
|
||||||
'google+': 'gplus',
|
|
||||||
'group': 'groups',
|
'group': 'groups',
|
||||||
|
'google+': 'gplus',
|
||||||
|
'hangoutsmeet': 'meet',
|
||||||
|
'logins': 'login',
|
||||||
|
'lookerstudio': 'datastudio',
|
||||||
|
'oauthtoken': 'token',
|
||||||
|
'tokens': 'token',
|
||||||
|
'users': 'user',
|
||||||
|
}
|
||||||
|
|
||||||
|
REPORT_CHOICE_MAP = {
|
||||||
|
'accesstransparency': 'access_transparency',
|
||||||
|
'admin': 'admin',
|
||||||
|
'calendar': 'calendar',
|
||||||
|
'chat': 'chat',
|
||||||
|
'chrome': 'chrome',
|
||||||
|
'contextawareaccess': 'context_aware_access',
|
||||||
|
'customer': 'customer',
|
||||||
|
'datastudio': 'data_studio',
|
||||||
|
'drive': 'drive',
|
||||||
|
'gcp': 'gcp',
|
||||||
|
'geminiinworkspaceapps': 'gemini_in_workspace_apps',
|
||||||
|
'gplus': 'gplus',
|
||||||
'groups': 'groups',
|
'groups': 'groups',
|
||||||
'groupsenterprise': 'groups_enterprise',
|
'groupsenterprise': 'groups_enterprise',
|
||||||
'hangoutsmeet': 'meet',
|
|
||||||
'jamboard': 'jamboard',
|
'jamboard': 'jamboard',
|
||||||
'keep': 'keep',
|
'keep': 'keep',
|
||||||
'login': 'login',
|
'login': 'login',
|
||||||
'logins': 'login',
|
|
||||||
'lookerstudio': 'data_studio',
|
|
||||||
'meet': 'meet',
|
'meet': 'meet',
|
||||||
'mobile': 'mobile',
|
'mobile': 'mobile',
|
||||||
'oauthtoken': 'token',
|
|
||||||
'rules': 'rules',
|
'rules': 'rules',
|
||||||
'saml': 'saml',
|
'saml': 'saml',
|
||||||
'token': 'token',
|
'token': 'token',
|
||||||
'tokens': 'token',
|
|
||||||
'usage': 'usage',
|
'usage': 'usage',
|
||||||
'usageparameters': 'usageparameters',
|
'usageparameters': 'usageparameters',
|
||||||
'user': 'user',
|
'user': 'user',
|
||||||
'users': 'user',
|
|
||||||
'useraccounts': 'user_accounts',
|
'useraccounts': 'user_accounts',
|
||||||
'vault': 'vault',
|
'vault': 'vault',
|
||||||
}
|
}
|
||||||
@@ -13883,7 +13887,7 @@ def doReport():
|
|||||||
if dyn_choice.replace('_', '') not in REPORT_CHOICE_MAP and \
|
if dyn_choice.replace('_', '') not in REPORT_CHOICE_MAP and \
|
||||||
dyn_choice not in REPORT_CHOICE_MAP.values():
|
dyn_choice not in REPORT_CHOICE_MAP.values():
|
||||||
REPORT_CHOICE_MAP[dyn_choice.replace('_', '')] = dyn_choice
|
REPORT_CHOICE_MAP[dyn_choice.replace('_', '')] = dyn_choice
|
||||||
report = getChoice(REPORT_CHOICE_MAP, mapChoice=True)
|
report = getChoice(REPORT_CHOICE_MAP, choiceAliases=REPORT_ALIASES_CHOICE_MAP, mapChoice=True)
|
||||||
if report == 'usage':
|
if report == 'usage':
|
||||||
doReportUsage()
|
doReportUsage()
|
||||||
return
|
return
|
||||||
@@ -29505,6 +29509,7 @@ def getCIDeviceEntity():
|
|||||||
return ([], ci, customer, False)
|
return ([], ci, customer, False)
|
||||||
|
|
||||||
DEVICE_USERNAME_PATTERN = re.compile(r'^(devices/.+)/(deviceUsers/.+)$')
|
DEVICE_USERNAME_PATTERN = re.compile(r'^(devices/.+)/(deviceUsers/.+)$')
|
||||||
|
DEVICE_USERNAME_CLIENT_STATE_PATTERN = re.compile(r'^(devices/.+/deviceUsers/.+)/clientStates/(.+)$')
|
||||||
DEVICE_USERNAME_FORMAT_REQUIRED = 'devices/<String>/deviceUsers/<String>'
|
DEVICE_USERNAME_FORMAT_REQUIRED = 'devices/<String>/deviceUsers/<String>'
|
||||||
def getCIDeviceUserEntity():
|
def getCIDeviceUserEntity():
|
||||||
ci = buildGAPICIDeviceServiceObject()
|
ci = buildGAPICIDeviceServiceObject()
|
||||||
@@ -29953,6 +29958,7 @@ DEVICE_ORDERBY_CHOICE_MAP = {
|
|||||||
# [orderby <DeviceOrderByFieldName> [ascending|descending]]
|
# [orderby <DeviceOrderByFieldName> [ascending|descending]]
|
||||||
# [all|company|personal|nocompanydevices|nopersonaldevices]
|
# [all|company|personal|nocompanydevices|nopersonaldevices]
|
||||||
# [nodeviceusers|oneuserperrow]
|
# [nodeviceusers|oneuserperrow]
|
||||||
|
# [clientstates]
|
||||||
# [formatjson [quotechar <Character>]]
|
# [formatjson [quotechar <Character>]]
|
||||||
# [showitemcountonly]
|
# [showitemcountonly]
|
||||||
def doPrintCIDevices():
|
def doPrintCIDevices():
|
||||||
@@ -29968,6 +29974,7 @@ def doPrintCIDevices():
|
|||||||
queries = [None]
|
queries = [None]
|
||||||
view, entityType = DEVICE_VIEW_CHOICE_MAP['all']
|
view, entityType = DEVICE_VIEW_CHOICE_MAP['all']
|
||||||
getDeviceUsers = True
|
getDeviceUsers = True
|
||||||
|
getClientStates = False
|
||||||
oneUserPerRow = showItemCountOnly = False
|
oneUserPerRow = showItemCountOnly = False
|
||||||
while Cmd.ArgumentsRemaining():
|
while Cmd.ArgumentsRemaining():
|
||||||
myarg = getArgument()
|
myarg = getArgument()
|
||||||
@@ -29983,6 +29990,8 @@ def doPrintCIDevices():
|
|||||||
view, entityType = DEVICE_VIEW_CHOICE_MAP[myarg]
|
view, entityType = DEVICE_VIEW_CHOICE_MAP[myarg]
|
||||||
elif myarg == 'nodeviceusers':
|
elif myarg == 'nodeviceusers':
|
||||||
getDeviceUsers = False
|
getDeviceUsers = False
|
||||||
|
elif myarg == 'clientstates':
|
||||||
|
getClientStates = True
|
||||||
elif myarg in {'oneuserperrow', 'oneitemperrow'}:
|
elif myarg in {'oneuserperrow', 'oneitemperrow'}:
|
||||||
getDeviceUsers = oneUserPerRow = True
|
getDeviceUsers = oneUserPerRow = True
|
||||||
elif getFieldsList(myarg, DEVICE_FIELDS_CHOICE_MAP, fieldsList, initialField='name'):
|
elif getFieldsList(myarg, DEVICE_FIELDS_CHOICE_MAP, fieldsList, initialField='name'):
|
||||||
@@ -30001,14 +30010,16 @@ def doPrintCIDevices():
|
|||||||
if FJQC.formatJSON and oneUserPerRow:
|
if FJQC.formatJSON and oneUserPerRow:
|
||||||
csvPF.SetJSONTitles(['name', 'user.name', 'JSON'])
|
csvPF.SetJSONTitles(['name', 'user.name', 'JSON'])
|
||||||
itemCount = 0
|
itemCount = 0
|
||||||
|
throwReasons = [GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED]
|
||||||
|
retryReasons = GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS
|
||||||
for query in queries:
|
for query in queries:
|
||||||
printGettingAllAccountEntities(entityType, query)
|
printGettingAllAccountEntities(entityType, query)
|
||||||
pageMessage = getPageMessage()
|
pageMessage = getPageMessage()
|
||||||
try:
|
try:
|
||||||
devices = callGAPIpages(ci.devices(), 'list', 'devices',
|
devices = callGAPIpages(ci.devices(), 'list', 'devices',
|
||||||
pageMessage=pageMessage,
|
pageMessage=pageMessage,
|
||||||
throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
|
throwReasons=throwReasons,
|
||||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
retryReasons=retryReasons,
|
||||||
customer=customer, filter=query,
|
customer=customer, filter=query,
|
||||||
orderBy=OBY.orderBy, view=view, fields=fields, pageSize=100)
|
orderBy=OBY.orderBy, view=view, fields=fields, pageSize=100)
|
||||||
if showItemCountOnly:
|
if showItemCountOnly:
|
||||||
@@ -30027,10 +30038,27 @@ def doPrintCIDevices():
|
|||||||
try:
|
try:
|
||||||
deviceUsers = callGAPIpages(ci.devices().deviceUsers(), 'list', 'deviceUsers',
|
deviceUsers = callGAPIpages(ci.devices().deviceUsers(), 'list', 'deviceUsers',
|
||||||
pageMessage=pageMessage,
|
pageMessage=pageMessage,
|
||||||
throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
|
throwReasons=throwReasons,
|
||||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
retryReasons=retryReasons,
|
||||||
customer=customer, filter=query, parent=parent,
|
customer=customer, filter=query, parent=parent,
|
||||||
orderBy=OBY.orderBy, fields=userFields, pageSize=20)
|
orderBy=OBY.orderBy, fields=userFields, pageSize=20)
|
||||||
|
if getClientStates:
|
||||||
|
printGettingAllAccountEntities(Ent.DEVICE_USER_CLIENT_STATE, None)
|
||||||
|
states = callGAPIpages(ci.devices().deviceUsers().clientStates(), 'list', 'clientStates',
|
||||||
|
pageMessage=pageMessage,
|
||||||
|
throwReasons=throwReasons,
|
||||||
|
retryReasons=retryReasons,
|
||||||
|
customer=customer, filter=query, parent='devices/-/deviceUsers/-')
|
||||||
|
for state in states:
|
||||||
|
mg = DEVICE_USERNAME_CLIENT_STATE_PATTERN.match(state['name'])
|
||||||
|
if mg:
|
||||||
|
du = mg.group(1)
|
||||||
|
state_name = mg.group(2)
|
||||||
|
for i in range(len(deviceUsers)):
|
||||||
|
if deviceUsers[i]['name'] == du:
|
||||||
|
deviceUsers[i].setdefault('clientstates', {})
|
||||||
|
deviceUsers[i]['clientstates'][state_name] = state
|
||||||
|
break
|
||||||
for deviceUser in deviceUsers:
|
for deviceUser in deviceUsers:
|
||||||
mg = DEVICE_USERNAME_PATTERN.match(deviceUser['name'])
|
mg = DEVICE_USERNAME_PATTERN.match(deviceUser['name'])
|
||||||
if mg:
|
if mg:
|
||||||
@@ -59495,6 +59523,7 @@ def _copyPermissions(drive, user, i, count, j, jcount,
|
|||||||
GAPI.fileOrganizerNotYetEnabledForThisTeamDrive,
|
GAPI.fileOrganizerNotYetEnabledForThisTeamDrive,
|
||||||
GAPI.fileOrganizerOnFoldersInSharedDriveOnly,
|
GAPI.fileOrganizerOnFoldersInSharedDriveOnly,
|
||||||
GAPI.fileOrganizerOnNonTeamDriveNotSupported,
|
GAPI.fileOrganizerOnNonTeamDriveNotSupported,
|
||||||
|
GAPI.cannotModifyInheritedPermission,
|
||||||
GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility, GAPI.abusiveContentRestriction) as e:
|
GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility, GAPI.abusiveContentRestriction) as e:
|
||||||
entityActionFailedWarning(kvList, str(e), k, kcount)
|
entityActionFailedWarning(kvList, str(e), k, kcount)
|
||||||
break
|
break
|
||||||
@@ -59524,7 +59553,8 @@ def _copyPermissions(drive, user, i, count, j, jcount,
|
|||||||
entityActionPerformed(kvList, k, kcount)
|
entityActionPerformed(kvList, k, kcount)
|
||||||
except (GAPI.notFound, GAPI.permissionNotFound,
|
except (GAPI.notFound, GAPI.permissionNotFound,
|
||||||
GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||||
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission,
|
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner,
|
||||||
|
GAPI.cannotModifyInheritedTeamDrivePermission, GAPI.cannotModifyInheritedPermission,
|
||||||
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e:
|
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e:
|
||||||
entityActionFailedWarning(kvList, str(e), k, kcount)
|
entityActionFailedWarning(kvList, str(e), k, kcount)
|
||||||
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||||
@@ -59551,7 +59581,8 @@ def _copyPermissions(drive, user, i, count, j, jcount,
|
|||||||
entityActionPerformed(kvList, k, kcount)
|
entityActionPerformed(kvList, k, kcount)
|
||||||
except (GAPI.notFound, GAPI.permissionNotFound,
|
except (GAPI.notFound, GAPI.permissionNotFound,
|
||||||
GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||||
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission,
|
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner,
|
||||||
|
GAPI.cannotModifyInheritedTeamDrivePermission, GAPI.cannotModifyInheritedPermission,
|
||||||
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded) as e:
|
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded) as e:
|
||||||
entityActionFailedWarning(kvList, str(e), k, kcount)
|
entityActionFailedWarning(kvList, str(e), k, kcount)
|
||||||
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||||
@@ -60558,7 +60589,8 @@ def _updateMoveFilePermissions(drive, user, i, count,
|
|||||||
entityActionPerformed(kvList, k, kcount)
|
entityActionPerformed(kvList, k, kcount)
|
||||||
except (GAPI.notFound, GAPI.permissionNotFound,
|
except (GAPI.notFound, GAPI.permissionNotFound,
|
||||||
GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||||
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission,
|
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner,
|
||||||
|
GAPI.cannotModifyInheritedTeamDrivePermission, GAPI.cannotModifyInheritedPermission,
|
||||||
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e:
|
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e:
|
||||||
entityActionFailedWarning(kvList, str(e), k, kcount)
|
entityActionFailedWarning(kvList, str(e), k, kcount)
|
||||||
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||||
@@ -60599,6 +60631,7 @@ def _updateMoveFilePermissions(drive, user, i, count,
|
|||||||
GAPI.fileOrganizerNotYetEnabledForThisTeamDrive,
|
GAPI.fileOrganizerNotYetEnabledForThisTeamDrive,
|
||||||
GAPI.fileOrganizerOnFoldersInSharedDriveOnly,
|
GAPI.fileOrganizerOnFoldersInSharedDriveOnly,
|
||||||
GAPI.fileOrganizerOnNonTeamDriveNotSupported,
|
GAPI.fileOrganizerOnNonTeamDriveNotSupported,
|
||||||
|
GAPI.cannotModifyInheritedPermission,
|
||||||
GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility, GAPI.abusiveContentRestriction) as e:
|
GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility, GAPI.abusiveContentRestriction) as e:
|
||||||
entityActionFailedWarning(kvList, str(e), k, kcount)
|
entityActionFailedWarning(kvList, str(e), k, kcount)
|
||||||
break
|
break
|
||||||
@@ -63853,6 +63886,7 @@ def createDriveFileACL(users, useDomainAdminAccess=False):
|
|||||||
GAPI.fileOrganizerNotYetEnabledForThisTeamDrive,
|
GAPI.fileOrganizerNotYetEnabledForThisTeamDrive,
|
||||||
GAPI.fileOrganizerOnFoldersInSharedDriveOnly,
|
GAPI.fileOrganizerOnFoldersInSharedDriveOnly,
|
||||||
GAPI.fileOrganizerOnNonTeamDriveNotSupported,
|
GAPI.fileOrganizerOnNonTeamDriveNotSupported,
|
||||||
|
GAPI.cannotModifyInheritedPermission,
|
||||||
GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility,
|
GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility,
|
||||||
GAPI.invalidSharingRequest, GAPI.fileNeverWritable, GAPI.abusiveContentRestriction) as e:
|
GAPI.invalidSharingRequest, GAPI.fileNeverWritable, GAPI.abusiveContentRestriction) as e:
|
||||||
entityActionFailedWarning([Ent.USER, user, entityType, fileName, Ent.PERMISSION_ID, permissionId], str(e), j, jcount)
|
entityActionFailedWarning([Ent.USER, user, entityType, fileName, Ent.PERMISSION_ID, permissionId], str(e), j, jcount)
|
||||||
@@ -63981,7 +64015,8 @@ def updateDriveFileACLs(users, useDomainAdminAccess=False):
|
|||||||
GAPI.targetUserRoleLimitedByLicenseRestriction, GAPI.insufficientAdministratorPrivileges,
|
GAPI.targetUserRoleLimitedByLicenseRestriction, GAPI.insufficientAdministratorPrivileges,
|
||||||
GAPI.publishOutNotPermitted, GAPI.shareInNotPermitted, GAPI.shareOutNotPermitted, GAPI.shareOutNotPermittedToUser,
|
GAPI.publishOutNotPermitted, GAPI.shareInNotPermitted, GAPI.shareOutNotPermitted, GAPI.shareOutNotPermittedToUser,
|
||||||
GAPI.organizerOnNonTeamDriveItemNotSupported, GAPI.fileOrganizerOnNonTeamDriveNotSupported,
|
GAPI.organizerOnNonTeamDriveItemNotSupported, GAPI.fileOrganizerOnNonTeamDriveNotSupported,
|
||||||
GAPI.cannotUpdatePermission, GAPI.cannotModifyInheritedTeamDrivePermission, GAPI.fieldNotWritable) as e:
|
GAPI.cannotUpdatePermission, GAPI.cannotModifyInheritedTeamDrivePermission, GAPI.cannotModifyInheritedPermission,
|
||||||
|
GAPI.fieldNotWritable) as e:
|
||||||
entityActionFailedWarning([Ent.USER, user, entityType, fileName], str(e), j, jcount)
|
entityActionFailedWarning([Ent.USER, user, entityType, fileName], str(e), j, jcount)
|
||||||
except (GAPI.notFound, GAPI.teamDriveDomainUsersOnlyRestriction, GAPI.teamDriveTeamMembersOnlyRestriction,
|
except (GAPI.notFound, GAPI.teamDriveDomainUsersOnlyRestriction, GAPI.teamDriveTeamMembersOnlyRestriction,
|
||||||
GAPI.cannotShareTeamDriveTopFolderWithAnyoneOrDomains, GAPI.ownerOnTeamDriveItemNotSupported,
|
GAPI.cannotShareTeamDriveTopFolderWithAnyoneOrDomains, GAPI.ownerOnTeamDriveItemNotSupported,
|
||||||
@@ -64087,6 +64122,7 @@ def createDriveFilePermissions(users, useDomainAdminAccess=False):
|
|||||||
GAPI.fileOrganizerNotYetEnabledForThisTeamDrive,
|
GAPI.fileOrganizerNotYetEnabledForThisTeamDrive,
|
||||||
GAPI.fileOrganizerOnFoldersInSharedDriveOnly,
|
GAPI.fileOrganizerOnFoldersInSharedDriveOnly,
|
||||||
GAPI.fileOrganizerOnNonTeamDriveNotSupported,
|
GAPI.fileOrganizerOnNonTeamDriveNotSupported,
|
||||||
|
GAPI.cannotModifyInheritedPermission,
|
||||||
GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility,
|
GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility,
|
||||||
GAPI.invalidSharingRequest, GAPI.fileNeverWritable, GAPI.abusiveContentRestriction,
|
GAPI.invalidSharingRequest, GAPI.fileNeverWritable, GAPI.abusiveContentRestriction,
|
||||||
GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||||
@@ -64254,7 +64290,8 @@ def deleteDriveFileACLs(users, useDomainAdminAccess=False):
|
|||||||
if updateSheetProtectedRanges and mimeType == MIMETYPE_GA_SPREADSHEET:
|
if updateSheetProtectedRanges and mimeType == MIMETYPE_GA_SPREADSHEET:
|
||||||
_updateSheetProtectedRangesACLchange(sheet, user, i, count, j, jcount, fileId, fileName, False, permission)
|
_updateSheetProtectedRangesACLchange(sheet, user, i, count, j, jcount, fileId, fileName, False, permission)
|
||||||
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||||
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission,
|
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner,
|
||||||
|
GAPI.cannotModifyInheritedTeamDrivePermission, GAPI.cannotModifyInheritedPermission,
|
||||||
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e:
|
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e:
|
||||||
entityActionFailedWarning([Ent.USER, user, entityType, fileName], str(e), j, jcount)
|
entityActionFailedWarning([Ent.USER, user, entityType, fileName], str(e), j, jcount)
|
||||||
except GAPI.notFound as e:
|
except GAPI.notFound as e:
|
||||||
@@ -64310,7 +64347,8 @@ def deletePermissions(users, useDomainAdminAccess=False):
|
|||||||
fileId=ri[RI_ENTITY], permissionId=ri[RI_ITEM], supportsAllDrives=True)
|
fileId=ri[RI_ENTITY], permissionId=ri[RI_ITEM], supportsAllDrives=True)
|
||||||
entityActionPerformed([Ent.DRIVE_FILE_OR_FOLDER_ID, ri[RI_ENTITY], Ent.PERMISSION_ID, ri[RI_ITEM]], int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
entityActionPerformed([Ent.DRIVE_FILE_OR_FOLDER_ID, ri[RI_ENTITY], Ent.PERMISSION_ID, ri[RI_ITEM]], int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
||||||
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||||
GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission,
|
GAPI.badRequest, GAPI.cannotRemoveOwner,
|
||||||
|
GAPI.cannotModifyInheritedTeamDrivePermission, GAPI.cannotModifyInheritedPermission,
|
||||||
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.permissionNotFound, GAPI.cannotDeletePermission,
|
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.permissionNotFound, GAPI.cannotDeletePermission,
|
||||||
GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||||
entityActionFailedWarning([Ent.DRIVE_FILE_OR_FOLDER_ID, ri[RI_ENTITY], Ent.PERMISSION_ID, ri[RI_ITEM]], str(e), int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
entityActionFailedWarning([Ent.DRIVE_FILE_OR_FOLDER_ID, ri[RI_ENTITY], Ent.PERMISSION_ID, ri[RI_ITEM]], str(e), int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
||||||
@@ -70267,7 +70305,8 @@ def archiveMessages(users):
|
|||||||
listResult = callGAPIpages(service, 'list', parameters['listType'],
|
listResult = callGAPIpages(service, 'list', parameters['listType'],
|
||||||
pageMessage=getPageMessageForWhom(), maxItems=parameters['maxItems'],
|
pageMessage=getPageMessageForWhom(), maxItems=parameters['maxItems'],
|
||||||
throwReasons=GAPI.GMAIL_THROW_REASONS+GAPI.GMAIL_LIST_THROW_REASONS,
|
throwReasons=GAPI.GMAIL_THROW_REASONS+GAPI.GMAIL_LIST_THROW_REASONS,
|
||||||
userId='me', q=parameters['query'], fields=parameters['fields'],
|
userId='me', q=parameters['query'], labelIds=parameters['labelIds'],
|
||||||
|
fields=parameters['fields'],
|
||||||
maxResults=GC.Values[GC.MESSAGE_MAX_RESULTS])
|
maxResults=GC.Values[GC.MESSAGE_MAX_RESULTS])
|
||||||
messageIds = [message['id'] for message in listResult]
|
messageIds = [message['id'] for message in listResult]
|
||||||
except (GAPI.failedPrecondition, GAPI.permissionDenied, GAPI.invalid, GAPI.invalidArgument) as e:
|
except (GAPI.failedPrecondition, GAPI.permissionDenied, GAPI.invalid, GAPI.invalidArgument) as e:
|
||||||
@@ -70456,7 +70495,8 @@ def _processMessagesThreads(users, entityType):
|
|||||||
listResult = callGAPIpages(service, 'list', parameters['listType'],
|
listResult = callGAPIpages(service, 'list', parameters['listType'],
|
||||||
pageMessage=getPageMessageForWhom(), maxItems=parameters['maxItems'],
|
pageMessage=getPageMessageForWhom(), maxItems=parameters['maxItems'],
|
||||||
throwReasons=GAPI.GMAIL_THROW_REASONS+GAPI.GMAIL_LIST_THROW_REASONS,
|
throwReasons=GAPI.GMAIL_THROW_REASONS+GAPI.GMAIL_LIST_THROW_REASONS,
|
||||||
userId='me', q=parameters['query'], fields=parameters['fields'], includeSpamTrash=includeSpamTrash,
|
userId='me', q=parameters['query'], labelIds=parameters['labelIds'],
|
||||||
|
fields=parameters['fields'], includeSpamTrash=includeSpamTrash,
|
||||||
maxResults=GC.Values[GC.MESSAGE_MAX_RESULTS])
|
maxResults=GC.Values[GC.MESSAGE_MAX_RESULTS])
|
||||||
messageIds = [message['id'] for message in listResult]
|
messageIds = [message['id'] for message in listResult]
|
||||||
else:
|
else:
|
||||||
@@ -70572,7 +70612,8 @@ def exportMessagesThreads(users, entityType):
|
|||||||
listResult = callGAPIpages(service, 'list', parameters['listType'],
|
listResult = callGAPIpages(service, 'list', parameters['listType'],
|
||||||
pageMessage=getPageMessageForWhom(), maxItems=parameters['maxItems'],
|
pageMessage=getPageMessageForWhom(), maxItems=parameters['maxItems'],
|
||||||
throwReasons=GAPI.GMAIL_THROW_REASONS+GAPI.GMAIL_LIST_THROW_REASONS,
|
throwReasons=GAPI.GMAIL_THROW_REASONS+GAPI.GMAIL_LIST_THROW_REASONS,
|
||||||
userId='me', q=parameters['query'], fields=parameters['fields'], includeSpamTrash=includeSpamTrash,
|
userId='me', q=parameters['query'], labelIds=parameters['labelIds'],
|
||||||
|
fields=parameters['fields'], includeSpamTrash=includeSpamTrash,
|
||||||
maxResults=GC.Values[GC.MESSAGE_MAX_RESULTS])
|
maxResults=GC.Values[GC.MESSAGE_MAX_RESULTS])
|
||||||
entityIds = [entity['id'] for entity in listResult]
|
entityIds = [entity['id'] for entity in listResult]
|
||||||
except (GAPI.failedPrecondition, GAPI.permissionDenied, GAPI.invalid, GAPI.invalidArgument) as e:
|
except (GAPI.failedPrecondition, GAPI.permissionDenied, GAPI.invalid, GAPI.invalidArgument) as e:
|
||||||
@@ -70707,7 +70748,8 @@ def forwardMessagesThreads(users, entityType):
|
|||||||
listResult = callGAPIpages(service, 'list', parameters['listType'],
|
listResult = callGAPIpages(service, 'list', parameters['listType'],
|
||||||
pageMessage=getPageMessageForWhom(), maxItems=parameters['maxItems'],
|
pageMessage=getPageMessageForWhom(), maxItems=parameters['maxItems'],
|
||||||
throwReasons=GAPI.GMAIL_THROW_REASONS+GAPI.GMAIL_LIST_THROW_REASONS,
|
throwReasons=GAPI.GMAIL_THROW_REASONS+GAPI.GMAIL_LIST_THROW_REASONS,
|
||||||
userId='me', q=parameters['query'], fields=parameters['fields'], includeSpamTrash=includeSpamTrash,
|
userId='me', q=parameters['query'], labelIds=parameters['labelIds'],
|
||||||
|
fields=parameters['fields'], includeSpamTrash=includeSpamTrash,
|
||||||
maxResults=GC.Values[GC.MESSAGE_MAX_RESULTS])
|
maxResults=GC.Values[GC.MESSAGE_MAX_RESULTS])
|
||||||
entityIds = [entity['id'] for entity in listResult]
|
entityIds = [entity['id'] for entity in listResult]
|
||||||
except (GAPI.failedPrecondition, GAPI.permissionDenied, GAPI.invalid, GAPI.invalidArgument) as e:
|
except (GAPI.failedPrecondition, GAPI.permissionDenied, GAPI.invalid, GAPI.invalidArgument) as e:
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ CANNOT_DELETE_PERMISSION = 'cannotDeletePermission'
|
|||||||
CANNOT_DELETE_PRIMARY_CALENDAR = 'cannotDeletePrimaryCalendar'
|
CANNOT_DELETE_PRIMARY_CALENDAR = 'cannotDeletePrimaryCalendar'
|
||||||
CANNOT_DELETE_PRIMARY_SENDAS = 'cannotDeletePrimarySendAs'
|
CANNOT_DELETE_PRIMARY_SENDAS = 'cannotDeletePrimarySendAs'
|
||||||
CANNOT_DELETE_RESOURCE_WITH_CHILDREN = 'cannotDeleteResourceWithChildren'
|
CANNOT_DELETE_RESOURCE_WITH_CHILDREN = 'cannotDeleteResourceWithChildren'
|
||||||
|
CANNOT_MODIFY_INHERITED_PERMISSION = 'cannotModifyInheritedPermission'
|
||||||
CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION = 'cannotModifyInheritedTeamDrivePermission'
|
CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION = 'cannotModifyInheritedTeamDrivePermission'
|
||||||
CANNOT_MODIFY_RESTRICTED_LABEL = 'cannotModifyRestrictedLabel'
|
CANNOT_MODIFY_RESTRICTED_LABEL = 'cannotModifyRestrictedLabel'
|
||||||
CANNOT_MODIFY_VIEWERS_CAN_COPY_CONTENT = 'cannotModifyViewersCanCopyContent'
|
CANNOT_MODIFY_VIEWERS_CAN_COPY_CONTENT = 'cannotModifyViewersCanCopyContent'
|
||||||
@@ -228,6 +229,7 @@ DRIVE3_CREATE_ACL_THROW_REASONS = [BAD_REQUEST, INVALID, INVALID_SHARING_REQUEST
|
|||||||
FILE_ORGANIZER_NOT_YET_ENABLED_FOR_THIS_TEAMDRIVE,
|
FILE_ORGANIZER_NOT_YET_ENABLED_FOR_THIS_TEAMDRIVE,
|
||||||
FILE_ORGANIZER_ON_FOLDERS_IN_SHARED_DRIVE_ONLY,
|
FILE_ORGANIZER_ON_FOLDERS_IN_SHARED_DRIVE_ONLY,
|
||||||
FILE_ORGANIZER_ON_NON_TEAMDRIVE_NOT_SUPPORTED,
|
FILE_ORGANIZER_ON_NON_TEAMDRIVE_NOT_SUPPORTED,
|
||||||
|
CANNOT_MODIFY_INHERITED_PERMISSION,
|
||||||
TEAMDRIVES_FOLDER_SHARING_NOT_SUPPORTED, INVALID_LINK_VISIBILITY, ABUSIVE_CONTENT_RESTRICTION]
|
TEAMDRIVES_FOLDER_SHARING_NOT_SUPPORTED, INVALID_LINK_VISIBILITY, ABUSIVE_CONTENT_RESTRICTION]
|
||||||
DRIVE3_GET_ACL_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, FORBIDDEN, INTERNAL_ERROR,
|
DRIVE3_GET_ACL_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, FORBIDDEN, INTERNAL_ERROR,
|
||||||
INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, INSUFFICIENT_FILE_PERMISSIONS,
|
INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, INSUFFICIENT_FILE_PERMISSIONS,
|
||||||
@@ -248,10 +250,10 @@ DRIVE3_UPDATE_ACL_THROW_REASONS = [BAD_REQUEST, INVALID_OWNERSHIP_TRANSFER, CANN
|
|||||||
FILE_ORGANIZER_ON_FOLDERS_IN_SHARED_DRIVE_ONLY,
|
FILE_ORGANIZER_ON_FOLDERS_IN_SHARED_DRIVE_ONLY,
|
||||||
FILE_ORGANIZER_ON_NON_TEAMDRIVE_NOT_SUPPORTED,
|
FILE_ORGANIZER_ON_NON_TEAMDRIVE_NOT_SUPPORTED,
|
||||||
CANNOT_UPDATE_PERMISSION,
|
CANNOT_UPDATE_PERMISSION,
|
||||||
CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION,
|
CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION, CANNOT_MODIFY_INHERITED_PERMISSION,
|
||||||
FIELD_NOT_WRITABLE, PERMISSION_NOT_FOUND]
|
FIELD_NOT_WRITABLE, PERMISSION_NOT_FOUND]
|
||||||
DRIVE3_DELETE_ACL_THROW_REASONS = [BAD_REQUEST, CANNOT_REMOVE_OWNER,
|
DRIVE3_DELETE_ACL_THROW_REASONS = [BAD_REQUEST, CANNOT_REMOVE_OWNER,
|
||||||
CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION,
|
CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION, CANNOT_MODIFY_INHERITED_PERMISSION,
|
||||||
INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, SHARING_RATE_LIMIT_EXCEEDED,
|
INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, SHARING_RATE_LIMIT_EXCEEDED,
|
||||||
NOT_FOUND, PERMISSION_NOT_FOUND, CANNOT_DELETE_PERMISSION]
|
NOT_FOUND, PERMISSION_NOT_FOUND, CANNOT_DELETE_PERMISSION]
|
||||||
DRIVE3_MODIFY_LABEL_THROW_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, NOT_FOUND, FORBIDDEN, INTERNAL_ERROR,
|
DRIVE3_MODIFY_LABEL_THROW_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, NOT_FOUND, FORBIDDEN, INTERNAL_ERROR,
|
||||||
@@ -398,6 +400,8 @@ class cannotDeletePrimarySendAs(Exception):
|
|||||||
pass
|
pass
|
||||||
class cannotDeleteResourceWithChildren(Exception):
|
class cannotDeleteResourceWithChildren(Exception):
|
||||||
pass
|
pass
|
||||||
|
class cannotModifyInheritedPermission(Exception):
|
||||||
|
pass
|
||||||
class cannotModifyInheritedTeamDrivePermission(Exception):
|
class cannotModifyInheritedTeamDrivePermission(Exception):
|
||||||
pass
|
pass
|
||||||
class cannotModifyRestrictedLabel(Exception):
|
class cannotModifyRestrictedLabel(Exception):
|
||||||
@@ -698,6 +702,7 @@ REASON_EXCEPTION_MAP = {
|
|||||||
CANNOT_DELETE_PRIMARY_CALENDAR: cannotDeletePrimaryCalendar,
|
CANNOT_DELETE_PRIMARY_CALENDAR: cannotDeletePrimaryCalendar,
|
||||||
CANNOT_DELETE_PRIMARY_SENDAS: cannotDeletePrimarySendAs,
|
CANNOT_DELETE_PRIMARY_SENDAS: cannotDeletePrimarySendAs,
|
||||||
CANNOT_DELETE_RESOURCE_WITH_CHILDREN: cannotDeleteResourceWithChildren,
|
CANNOT_DELETE_RESOURCE_WITH_CHILDREN: cannotDeleteResourceWithChildren,
|
||||||
|
CANNOT_MODIFY_INHERITED_PERMISSION: cannotModifyInheritedPermission,
|
||||||
CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION: cannotModifyInheritedTeamDrivePermission,
|
CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION: cannotModifyInheritedTeamDrivePermission,
|
||||||
CANNOT_MODIFY_RESTRICTED_LABEL: cannotModifyRestrictedLabel,
|
CANNOT_MODIFY_RESTRICTED_LABEL: cannotModifyRestrictedLabel,
|
||||||
CANNOT_MODIFY_VIEWERS_CAN_COPY_CONTENT: cannotModifyViewersCanCopyContent,
|
CANNOT_MODIFY_VIEWERS_CAN_COPY_CONTENT: cannotModifyViewersCanCopyContent,
|
||||||
|
|||||||
@@ -107,6 +107,8 @@ _SKUS = {
|
|||||||
'product': '101047', 'aliases': ['aisecurity'], 'displayName': 'AI Security'},
|
'product': '101047', 'aliases': ['aisecurity'], 'displayName': 'AI Security'},
|
||||||
'1010470007': {
|
'1010470007': {
|
||||||
'product': '101047', 'aliases': ['aimeetingsandmessaging'], 'displayName': 'AI Meetings and Messaging'},
|
'product': '101047', 'aliases': ['aimeetingsandmessaging'], 'displayName': 'AI Meetings and Messaging'},
|
||||||
|
'1010470008': {
|
||||||
|
'product': '101047', 'aliases': ['geminiultra'], 'displayName': 'Google AI Ultra for Business'},
|
||||||
'1010490001': {
|
'1010490001': {
|
||||||
'product': '101049', 'aliases': ['eeu'], 'displayName': 'Endpoint Education Upgrade'},
|
'product': '101049', 'aliases': ['eeu'], 'displayName': 'Endpoint Education Upgrade'},
|
||||||
'1010500001': {
|
'1010500001': {
|
||||||
|
|||||||
@@ -211,6 +211,7 @@ gam print devices [todrive <ToDriveAttribute>*]
|
|||||||
[orderby <DeviceOrderByFieldName> [ascending|descending]]
|
[orderby <DeviceOrderByFieldName> [ascending|descending]]
|
||||||
[all|company|personal|nocompanydevices|nopersonaldevices]
|
[all|company|personal|nocompanydevices|nopersonaldevices]
|
||||||
[nodeviceusers|oneuserperrow]
|
[nodeviceusers|oneuserperrow]
|
||||||
|
[clientstates]
|
||||||
[formatjson [quotechar <Character>]]
|
[formatjson [quotechar <Character>]]
|
||||||
```
|
```
|
||||||
By default, all devices are displayed; use the query options to limit the display.
|
By default, all devices are displayed; use the query options to limit the display.
|
||||||
|
|||||||
@@ -10,8 +10,33 @@ 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.10.06
|
||||||
|
|
||||||
|
Added option `clientstates` to `gam print devices` to include client states in device output.
|
||||||
|
|
||||||
|
### 7.10.05
|
||||||
|
|
||||||
|
Google renamed an error: cannotModifyInheritedTeamDrivePermission became cannotModifyInheritedPermission.
|
||||||
|
GAM will now handle the new error.
|
||||||
|
|
||||||
|
### 7.10.04
|
||||||
|
|
||||||
|
Updated `gam report <ActivityApplicationName>` to accept accept application names as defined
|
||||||
|
in the Reports API discovery document; this means that GAM does not have to be updated when
|
||||||
|
Google defines a new application name.
|
||||||
|
|
||||||
|
`gemini_in_workspace_apps` is now available in `gam report`.
|
||||||
|
|
||||||
|
### 7.10.03
|
||||||
|
|
||||||
|
Fixed bug in commands that modify messages where the `labelids <LabelIdList>` option
|
||||||
|
was not being applied.
|
||||||
|
|
||||||
### 7.10.02
|
### 7.10.02
|
||||||
|
|
||||||
|
Added option `labelids <LabelIdList>` to all commands that process messages;
|
||||||
|
this option causes GAM to only return messages with labels that match all of the specified label IDs.
|
||||||
|
|
||||||
Updated `gam <UserTypeEntity> print|show forms` to always display `isPublished` and
|
Updated `gam <UserTypeEntity> print|show forms` to always display `isPublished` and
|
||||||
`isAcceptingResponses` in `publishSettings/publishState` regardless of their value;
|
`isAcceptingResponses` in `publishSettings/publishState` regardless of their value;
|
||||||
the API doesn't return these values when they are False.
|
the API doesn't return these values when they are False.
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ 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.10.02 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.10.06 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.13.5 64-bit final
|
Python 3.13.5 64-bit final
|
||||||
MacOS Sequoia 15.5 x86_64
|
MacOS Sequoia 15.5 x86_64
|
||||||
@@ -989,7 +989,7 @@ 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.10.02 - https://github.com/GAM-team/GAM - pythonsource
|
GAM 7.10.06 - https://github.com/GAM-team/GAM - pythonsource
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.13.5 64-bit final
|
Python 3.13.5 64-bit final
|
||||||
Windows-10-10.0.17134 AMD64
|
Windows-10-10.0.17134 AMD64
|
||||||
|
|||||||
@@ -39,20 +39,18 @@ config csv_output_row_filter "'\"accounts:used_quota_in_mb\":count>15000'"
|
|||||||
## Activity reports
|
## Activity reports
|
||||||
```
|
```
|
||||||
<ActivityApplicationName> ::=
|
<ActivityApplicationName> ::=
|
||||||
access|accesstransparency|
|
accesstransparency|access|
|
||||||
admin|
|
admin|
|
||||||
calendar|calendars|
|
calendar|calendars|
|
||||||
chat|
|
chat|
|
||||||
chrome|
|
chrome|
|
||||||
classroom|
|
classroom|
|
||||||
contextawareaccess|
|
contextawareaccess|
|
||||||
currents|gplus|google+|
|
gplus|currents|google+|
|
||||||
datastudio|
|
datastudio|
|
||||||
devices|mobile|
|
|
||||||
domain|
|
|
||||||
drive|doc|docs|
|
drive|doc|docs|
|
||||||
gcp|cloud|
|
gcp|cloud|
|
||||||
gemini|geminiforworkspace|
|
geminiinworkspaceapps|gemini|geminiforworkspace|
|
||||||
groups|group|
|
groups|group|
|
||||||
groupsenterprise|enterprisegroups|
|
groupsenterprise|enterprisegroups|
|
||||||
jamboard|
|
jamboard|
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ This table and other suggestions came from:
|
|||||||
<EmailAddress> ::= <String>@<DomainName>
|
<EmailAddress> ::= <String>@<DomainName>
|
||||||
<UniqueID> ::= id:<String>
|
<UniqueID> ::= id:<String>
|
||||||
<GroupItem> ::= <EmailAddress>|<UniqueID>|<String>
|
<GroupItem> ::= <EmailAddress>|<UniqueID>|<String>
|
||||||
|
<LabelID> ::= <String>
|
||||||
|
<LabelIDList> ::= "<LabelID>(,<LabelID)*"
|
||||||
<LabelName> ::= <String>
|
<LabelName> ::= <String>
|
||||||
<QueryGmail> ::= <String> See: https://support.google.com/mail/answer/7190
|
<QueryGmail> ::= <String> See: https://support.google.com/mail/answer/7190
|
||||||
<Time> ::=
|
<Time> ::=
|
||||||
@@ -389,6 +391,7 @@ Your command line will have: `embedimage file1.jpg image1` embedimage file2.jpg
|
|||||||
```
|
```
|
||||||
gam <UserTypeEntity> archive messages <GroupItem>
|
gam <UserTypeEntity> archive messages <GroupItem>
|
||||||
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
||||||
|
[labelids <LabelIDList>]
|
||||||
[quick|notquick] [doit] [max_to_archive <Number>])|(ids <MessageIDEntity>)
|
[quick|notquick] [doit] [max_to_archive <Number>])|(ids <MessageIDEntity>)
|
||||||
[csv [todrive <ToDriveAttribute>*]]
|
[csv [todrive <ToDriveAttribute>*]]
|
||||||
```
|
```
|
||||||
@@ -400,6 +403,7 @@ Messages are archived to the group specified by `<GroupItem>`.
|
|||||||
|
|
||||||
### Archive a selected set of messages
|
### Archive a selected set of messages
|
||||||
* `((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+` - Criteria to select messages
|
* `((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+` - Criteria to select messages
|
||||||
|
* `labelids <LabelIDList>` - Select messages with labels that match all of the specified label IDs.
|
||||||
* `max_to_archive` - Limit the number of messages that will be archived; use a value of 0 for no limit
|
* `max_to_archive` - Limit the number of messages that will be archived; use a value of 0 for no limit
|
||||||
* `doit` - No messages are archived unless you specify `doit`. By not specifying `doit`, you can preview the messages selected to verify that the results match your expectations.
|
* `doit` - No messages are archived unless you specify `doit`. By not specifying `doit`, you can preview the messages selected to verify that the results match your expectations.
|
||||||
|
|
||||||
@@ -432,10 +436,14 @@ See below for message selection.
|
|||||||
Export messages in EML format.
|
Export messages in EML format.
|
||||||
```
|
```
|
||||||
gam <UserTypeEntity> export message|messages
|
gam <UserTypeEntity> export message|messages
|
||||||
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [max_to_export <Number>])|(ids <MessageIDEntity>)
|
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
||||||
|
[labelids <LabelIDList>]
|
||||||
|
[quick|notquick] [max_to_export <Number>])|(ids <MessageIDEntity>)
|
||||||
[targetfolder <FilePath>] [targetname <FileName>] [overwrite [<Boolean>]]
|
[targetfolder <FilePath>] [targetname <FileName>] [overwrite [<Boolean>]]
|
||||||
gam <UserTypeEntity> export thread|threads
|
gam <UserTypeEntity> export thread|threads
|
||||||
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [max_to_export <Number>])|(ids <ThreadIDEntity>)
|
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
||||||
|
[labelids <LabelIDList>]
|
||||||
|
[quick|notquick] [max_to_export <Number>])|(ids <MessageIDEntity>)
|
||||||
[targetfolder <FilePath>] [targetname <FileName>] [overwrite [<Boolean>]]
|
[targetfolder <FilePath>] [targetname <FileName>] [overwrite [<Boolean>]]
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -459,10 +467,12 @@ See below for message selection.
|
|||||||
```
|
```
|
||||||
gam <UserTypeEntity> forward message|messages recipient|to <RecipientEntity>
|
gam <UserTypeEntity> forward message|messages recipient|to <RecipientEntity>
|
||||||
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
||||||
|
[labelids <LabelIDList>]
|
||||||
[quick|notquick] [doit] [max_to_forward <Number>])|(ids <MessageIDEntity>)
|
[quick|notquick] [doit] [max_to_forward <Number>])|(ids <MessageIDEntity>)
|
||||||
[subject <String>] [addorigfieldstosubject]
|
[subject <String>] [addorigfieldstosubject]
|
||||||
gam <UserTypeEntity> forward thread|threads recipient|to <RecipientEntity>
|
gam <UserTypeEntity> forward thread|threads recipient|to <RecipientEntity>
|
||||||
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
||||||
|
[labelids <LabelIDList>]
|
||||||
[quick|notquick] [doit] [max_to_forward <Number>])|(ids <ThreadIDEntity>)
|
[quick|notquick] [doit] [max_to_forward <Number>])|(ids <ThreadIDEntity>)
|
||||||
[subject <String>] [addorigfieldstosubject]
|
[subject <String>] [addorigfieldstosubject]
|
||||||
```
|
```
|
||||||
@@ -482,23 +492,28 @@ See below for message selection.
|
|||||||
```
|
```
|
||||||
gam <UserTypeEntity> delete messages|threads
|
gam <UserTypeEntity> delete messages|threads
|
||||||
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
||||||
|
[labelids <LabelIDList>]
|
||||||
[quick|notquick] [doit] [max_to_delete <Number>])|(ids <MessageIDEntity>)
|
[quick|notquick] [doit] [max_to_delete <Number>])|(ids <MessageIDEntity>)
|
||||||
[csv [todrive <ToDriveAttribute>*]]
|
[csv [todrive <ToDriveAttribute>*]]
|
||||||
gam <UserTypeEntity> modify messages|threads
|
gam <UserTypeEntity> modify messages|threads
|
||||||
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
||||||
|
[labelids <LabelIDList>]
|
||||||
[quick|notquick] [doit] [max_to_modify <Number>])|(ids <MessageIDEntity>)
|
[quick|notquick] [doit] [max_to_modify <Number>])|(ids <MessageIDEntity>)
|
||||||
((addlabel <LabelName>)|(removelabel <LabelName>))+
|
((addlabel <LabelName>)|(removelabel <LabelName>))+
|
||||||
[csv [todrive <ToDriveAttribute>*]]
|
[csv [todrive <ToDriveAttribute>*]]
|
||||||
gam <UserTypeEntity> spam messages|threads
|
gam <UserTypeEntity> spam messages|threads
|
||||||
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
||||||
|
[labelids <LabelIDList>]
|
||||||
[quick|notquick] [doit] [max_to_spam <Number>])|(ids <MessageIDEntity>)
|
[quick|notquick] [doit] [max_to_spam <Number>])|(ids <MessageIDEntity>)
|
||||||
[csv [todrive <ToDriveAttribute>*]]
|
[csv [todrive <ToDriveAttribute>*]]
|
||||||
gam <UserTypeEntity> trash messages|threads
|
gam <UserTypeEntity> trash messages|threads
|
||||||
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
||||||
|
[labelids <LabelIDList>]
|
||||||
[quick|notquick] [doit] [max_to_trash <Number>])|(ids <MessageIDEntity>)
|
[quick|notquick] [doit] [max_to_trash <Number>])|(ids <MessageIDEntity>)
|
||||||
[csv [todrive <ToDriveAttribute>*]]
|
[csv [todrive <ToDriveAttribute>*]]
|
||||||
gam <UserTypeEntity> untrash messages|threads
|
gam <UserTypeEntity> untrash messages|threads
|
||||||
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
|
||||||
|
[labelids <LabelIDList>]
|
||||||
[quick|notquick] [doit] [max_to_untrash <Number>])|(ids <MessageIDEntity>)
|
[quick|notquick] [doit] [max_to_untrash <Number>])|(ids <MessageIDEntity>)
|
||||||
[csv [todrive <ToDriveAttribute>*]]
|
[csv [todrive <ToDriveAttribute>*]]
|
||||||
```
|
```
|
||||||
@@ -522,6 +537,7 @@ user@domain.com,18e9fc58c5491f4c,Deleted,
|
|||||||
|
|
||||||
### Manage a selected set of messages
|
### Manage a selected set of messages
|
||||||
* `((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+` - Criteria to select messages
|
* `((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+` - Criteria to select messages
|
||||||
|
* `labelids <LabelIDList>` - Select messages with labels that match all of the specified label IDs.
|
||||||
* `max_to_xxx` - Limit the number of messages that will be processed; use a value of 0 for no limit
|
* `max_to_xxx` - Limit the number of messages that will be processed; use a value of 0 for no limit
|
||||||
* `doit` - No messages are processed unless you specify `doit`. By not specifying `doit`, you can preview the messages selected to verify that the results match your expectations.
|
* `doit` - No messages are processed unless you specify `doit`. By not specifying `doit`, you can preview the messages selected to verify that the results match your expectations.
|
||||||
|
|
||||||
@@ -570,6 +586,7 @@ gam config auto_batch_min 1 groups_inde EastOffice delete message query "rfc822m
|
|||||||
```
|
```
|
||||||
gam <UserTypeEntity> show messages|threads
|
gam <UserTypeEntity> show messages|threads
|
||||||
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])*
|
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])*
|
||||||
|
[labelids <LabelIDList>]
|
||||||
[quick|notquick] [max_to_show <Number>] [includespamtrash])|(ids <MessageIDEntity>)
|
[quick|notquick] [max_to_show <Number>] [includespamtrash])|(ids <MessageIDEntity>)
|
||||||
[labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>]
|
[labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>]
|
||||||
[countsonly|positivecountsonly] [useronly]
|
[countsonly|positivecountsonly] [useronly]
|
||||||
@@ -581,6 +598,7 @@ gam <UserTypeEntity> show messages|threads
|
|||||||
[targetfolder <FilePath>] [overwrite [<Boolean>]]
|
[targetfolder <FilePath>] [overwrite [<Boolean>]]
|
||||||
gam <UserTypeEntity> print messages|threads [todrive <ToDriveAttribute>*]
|
gam <UserTypeEntity> print messages|threads [todrive <ToDriveAttribute>*]
|
||||||
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])*
|
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])*
|
||||||
|
[labelids <LabelIDList>]
|
||||||
[quick|notquick] [max_to_print <Number>] [includespamtrash])|(ids <MessageIDEntity>)
|
[quick|notquick] [max_to_print <Number>] [includespamtrash])|(ids <MessageIDEntity>)
|
||||||
[labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>]
|
[labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>]
|
||||||
[countsonly|positivecountsonly] [useronly]
|
[countsonly|positivecountsonly] [useronly]
|
||||||
@@ -607,6 +625,7 @@ gam user user@domain.com print|show threads maxmessagesperthread 1
|
|||||||
|
|
||||||
## Display a selected set of messages
|
## Display a selected set of messages
|
||||||
* `((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+` - Criteria to select messages
|
* `((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+` - Criteria to select messages
|
||||||
|
* `labelids <LabelIDList>` - Select messages with labels that match all of the specified label IDs.
|
||||||
* `max_to_xxx` - Limit the number of messages that will be displayed
|
* `max_to_xxx` - Limit the number of messages that will be displayed
|
||||||
* `includespamtrash` - Include messages in the Spam and Trash folders
|
* `includespamtrash` - Include messages in the Spam and Trash folders
|
||||||
* `labelmatchpattern <REMatchPattern>` - Only display messages with some label that matches `<REMatchPattern>`
|
* `labelmatchpattern <REMatchPattern>` - Only display messages with some label that matches `<REMatchPattern>`
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ Paul shall send emails from the marketing email address with the name Paul from
|
|||||||
``` gam user paul add sendas marketing@example.com "Paul from Example" replyto paul```
|
``` gam user paul add sendas marketing@example.com "Paul from Example" replyto paul```
|
||||||
|
|
||||||
## Display sendas
|
## Display sendas
|
||||||
### Display the information as an indented list of keys and values.
|
### Display the sendas information as an indented list of keys and values.
|
||||||
```
|
```
|
||||||
gam <UserTypeEntity> info sendas <EmailAddressEntity> [compact|format|html]
|
gam <UserTypeEntity> info sendas <EmailAddressEntity> [compact|format|html]
|
||||||
gam <UserTypeEntity> show sendas [compact|format|html]
|
gam <UserTypeEntity> show sendas [compact|format|html]
|
||||||
@@ -126,7 +126,19 @@ By default, all sendas addresses are shown, use these options to limit the displ
|
|||||||
|
|
||||||
Use the `verifyonly` option to display `True` or `False` in the signature field based on whether the signature is non-blank.
|
Use the `verifyonly` option to display `True` or `False` in the signature field based on whether the signature is non-blank.
|
||||||
|
|
||||||
### Display the information in CSV form.
|
To capture a signature for use as input to GAM, do the following.
|
||||||
|
```
|
||||||
|
gam redirect stdout ./signature.html user user@domain.com show sendas compact
|
||||||
|
```
|
||||||
|
Edit signature.html and remove the following data leaving just the HTML.
|
||||||
|
```
|
||||||
|
SendAs Address: <user@domain.com>
|
||||||
|
IsPrimary: True
|
||||||
|
Default: True
|
||||||
|
Signature:
|
||||||
|
```
|
||||||
|
|
||||||
|
### Display the sendas information in CSV form.
|
||||||
```
|
```
|
||||||
gam <UserTypeEntity> print sendas [compact]
|
gam <UserTypeEntity> print sendas [compact]
|
||||||
[primary|default] [verifyonly] [todrive <ToDriveAttribute>*]
|
[primary|default] [verifyonly] [todrive <ToDriveAttribute>*]
|
||||||
@@ -170,7 +182,7 @@ email address signature rather than the alias signature to be set.
|
|||||||
If you have a current default signature, the API will update that, but if you delete it, it seems that the API will not over-write any of the other signatures, but instead add a new signature called `My signature`. If you rename that signature, the API will keep on updating that same signature, and not touch the other signatures.
|
If you have a current default signature, the API will update that, but if you delete it, it seems that the API will not over-write any of the other signatures, but instead add a new signature called `My signature`. If you rename that signature, the API will keep on updating that same signature, and not touch the other signatures.
|
||||||
|
|
||||||
## Display signature
|
## Display signature
|
||||||
### Display the information as an indented list of keys and values.
|
### Display the signature as an indented list of keys and values.
|
||||||
```
|
```
|
||||||
gam <UserTypeEntity> show signature|sig [compact|format|html]
|
gam <UserTypeEntity> show signature|sig [compact|format|html]
|
||||||
[primary|default] [verifyonly]
|
[primary|default] [verifyonly]
|
||||||
@@ -187,7 +199,19 @@ By default, the signature for `<UserTypeEntity>` is displayed, use these options
|
|||||||
|
|
||||||
Use the `verifyonly` option to display `True` or `False` in the signature field based on whether the signature is non-blank.
|
Use the `verifyonly` option to display `True` or `False` in the signature field based on whether the signature is non-blank.
|
||||||
|
|
||||||
### Display the information in CSV form.
|
To capture a signature for use as input to GAM, do the following.
|
||||||
|
```
|
||||||
|
gam redirect stdout ./signature.html user user@domain.com show signature compact
|
||||||
|
```
|
||||||
|
Edit signature.html and remove the following data leaving just the HTML.
|
||||||
|
```
|
||||||
|
SendAs Address: <user@domain.com>
|
||||||
|
IsPrimary: True
|
||||||
|
Default: True
|
||||||
|
Signature:
|
||||||
|
```
|
||||||
|
|
||||||
|
### Display the signature in CSV form.
|
||||||
```
|
```
|
||||||
gam <UserTypeEntity> print signature [compact]
|
gam <UserTypeEntity> print signature [compact]
|
||||||
[primary|default] [verifyonly] [todrive <ToDriveAttribute>*]
|
[primary|default] [verifyonly] [todrive <ToDriveAttribute>*]
|
||||||
|
|||||||
@@ -1,19 +1,12 @@
|
|||||||
# Using GAM7 with a delegated admin service account
|
# Using GAM7 with a delegated admin service account
|
||||||
- [Thanks](#thanks)
|
|
||||||
- [Introduction](#introduction)
|
- [Introduction](#introduction)
|
||||||
- [Advantages](#advantages)
|
- [Advantages](#advantages)
|
||||||
- [Disadvantages](#disadvantages)
|
- [Disadvantages](#disadvantages)
|
||||||
- [Setup Steps](#setup-steps)
|
- [Setup Steps](#setup-steps)
|
||||||
|
|
||||||
## Thanks
|
|
||||||
|
|
||||||
Thanks to Jay Lee for the original version of this document.
|
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
Delegated admin service accounts (DASA) are regular [GCP service accounts](https://cloud.google.com/iam/docs/service-accounts#what_are_service_accounts) that are granted a Workspace [delegated admin role](https://support.google.com/a/answer/33325). Service accounts have an email address like `gam-project-xuw-sp1-c4b@gam-project-xuw-sp1-c4b.iam.gserviceaccount.com` and are not part of a Workspace or Cloud Identity domain even if they are owned by a project in the domain’s organization. Service accounts cannot login to Google web services interactively, they are only able to call Google APIs.
|
Delegated admin service accounts (DASA) are regular [GCP service accounts](https://cloud.google.com/iam/docs/service-accounts#what_are_service_accounts) that are granted a Workspace [delegated admin role](https://support.google.com/a/answer/33325). Service accounts have an email address like `gam-project-xuw-sp1-c4b@gam-project-xuw-sp1-c4b.iam.gserviceaccount.com` and are not part of a Workspace or Cloud Identity domain even if they are owned by a project in the domain’s organization. Service accounts cannot login to Google web services interactively, they are only able to call Google APIs.
|
||||||
|
|
||||||
GAM7 version 6.50.00 or higher is required.
|
|
||||||
|
|
||||||
## Advantages
|
## Advantages
|
||||||
* DASA accounts don’t require a Workspace or Cloud Identity license.
|
* DASA accounts don’t require a Workspace or Cloud Identity license.
|
||||||
* DASA accounts don’t have a password login that can be phished or captured, they use [RSA private keys](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) to sign authentication requests which makes them very secure. You should however [rotate the key](https://jaylee.us/qwm) on a regular basis and keep it safe and secured!
|
* DASA accounts don’t have a password login that can be phished or captured, they use [RSA private keys](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) to sign authentication requests which makes them very secure. You should however [rotate the key](https://jaylee.us/qwm) on a regular basis and keep it safe and secured!
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
Print the current version of Gam with details
|
Print the current version of Gam with details
|
||||||
```
|
```
|
||||||
gam version
|
gam version
|
||||||
GAM 7.10.02 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.10.06 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.13.5 64-bit final
|
Python 3.13.5 64-bit final
|
||||||
MacOS Sequoia 15.5 x86_64
|
MacOS Sequoia 15.5 x86_64
|
||||||
@@ -15,7 +15,7 @@ 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.10.02 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.10.06 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.13.5 64-bit final
|
Python 3.13.5 64-bit final
|
||||||
MacOS Sequoia 15.5 x86_64
|
MacOS Sequoia 15.5 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
|
Print the current version of Gam with extended details and SSL information
|
||||||
```
|
```
|
||||||
gam version extended
|
gam version extended
|
||||||
GAM 7.10.02 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.10.06 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.13.5 64-bit final
|
Python 3.13.5 64-bit final
|
||||||
MacOS Sequoia 15.5 x86_64
|
MacOS Sequoia 15.5 x86_64
|
||||||
@@ -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.10.02
|
Latest: 7.10.06
|
||||||
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.10.02
|
7.10.06
|
||||||
```
|
```
|
||||||
In Linux/MacOS you can do:
|
In Linux/MacOS you can do:
|
||||||
```
|
```
|
||||||
@@ -82,7 +82,7 @@ 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.10.02 - https://github.com/GAM-team/GAM
|
GAM 7.10.06 - https://github.com/GAM-team/GAM
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.13.5 64-bit final
|
Python 3.13.5 64-bit final
|
||||||
MacOS Sequoia 15.5 x86_64
|
MacOS Sequoia 15.5 x86_64
|
||||||
|
|||||||
Reference in New Issue
Block a user