Compare commits

...

15 Commits

Author SHA1 Message Date
Ross Scroggs
d791a864fa Added error message to gam report commands to indicate forbidden access
Some checks failed
Build and test GAM / build (Win64, build, 10, VC-WIN64A, windows-2022) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 3, linux-aarch64, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 4, linux-aarch64, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 6, linux-aarch64, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 8, darwin64-arm64, macos-14) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 9, darwin64-arm64, macos-15) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 1, linux-x86_64, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 2, linux-x86_64, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 5, linux-x86_64, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 7, darwin64-x86_64, macos-13) (push) Has been cancelled
Build and test GAM / build (x86_64, test, 11, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (x86_64, test, 12, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (x86_64, test, 13, ubuntu-24.04, 3.12) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-03-05 10:49:23 -08:00
Ross Scroggs
b3867fba5b Fixed bug in gam calendars <CalendarEntity> info events and `gam <UserTypeEntity> info events
Some checks failed
Build and test GAM / build (Win64, build, 10, VC-WIN64A, windows-2022) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 3, linux-aarch64, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 4, linux-aarch64, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 6, linux-aarch64, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 8, darwin64-arm64, macos-14) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 9, darwin64-arm64, macos-15) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 1, linux-x86_64, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 2, linux-x86_64, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 5, linux-x86_64, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 7, darwin64-x86_64, macos-13) (push) Has been cancelled
Build and test GAM / build (x86_64, test, 11, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (x86_64, test, 12, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (x86_64, test, 13, ubuntu-24.04, 3.12) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-03-03 17:42:42 -08:00
GitHub Action
e53f440ed2 [ci skip] Updated cacerts.pem 2025-03-04 01:05:59 +00:00
Ross Scroggs
51793f443d mprove message displayed when a command is issued that requires Google Chat Bot setup
Some checks are pending
Build and test GAM / build (Win64, build, 10, VC-WIN64A, windows-2022) (push) Waiting to run
Build and test GAM / build (aarch64, build, 3, linux-aarch64, ubuntu-24.04-arm) (push) Waiting to run
Build and test GAM / build (aarch64, build, 4, linux-aarch64, ubuntu-22.04-arm) (push) Waiting to run
Build and test GAM / build (aarch64, build, 6, linux-aarch64, ubuntu-22.04-arm, yes) (push) Waiting to run
Build and test GAM / build (aarch64, build, 8, darwin64-arm64, macos-14) (push) Waiting to run
Build and test GAM / build (aarch64, build, 9, darwin64-arm64, macos-15) (push) Waiting to run
Build and test GAM / build (x86_64, build, 1, linux-x86_64, ubuntu-22.04) (push) Waiting to run
Build and test GAM / build (x86_64, build, 2, linux-x86_64, ubuntu-24.04) (push) Waiting to run
Build and test GAM / build (x86_64, build, 5, linux-x86_64, ubuntu-22.04, yes) (push) Waiting to run
Build and test GAM / build (x86_64, build, 7, darwin64-x86_64, macos-13) (push) Waiting to run
Build and test GAM / build (x86_64, test, 11, ubuntu-24.04, 3.10) (push) Waiting to run
Build and test GAM / build (x86_64, test, 12, ubuntu-24.04, 3.11) (push) Waiting to run
Build and test GAM / build (x86_64, test, 13, ubuntu-24.04, 3.12) (push) Waiting to run
Build and test GAM / merge (push) Blocked by required conditions
Build and test GAM / publish (push) Blocked by required conditions
CodeQL / Analyze (python) (push) Waiting to run
Check for Google Root CA Updates / check-apis (push) Waiting to run
2025-03-03 08:55:42 -08:00
Ross Scroggs
03daa83d3c Add password prompting to create|update user
Some checks failed
Build and test GAM / build (Win64, build, 10, VC-WIN64A, windows-2022) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 3, linux-aarch64, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 4, linux-aarch64, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 6, linux-aarch64, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 8, darwin64-arm64, macos-14) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 9, darwin64-arm64, macos-15) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 1, linux-x86_64, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 2, linux-x86_64, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 5, linux-x86_64, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 7, darwin64-x86_64, macos-13) (push) Has been cancelled
Build and test GAM / build (x86_64, test, 11, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (x86_64, test, 12, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (x86_64, test, 13, ubuntu-24.04, 3.12) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-02-27 21:53:03 -08:00
Ross Scroggs
f2ff6d8bf7 Add password prompting to create|update user 2025-02-27 21:40:07 -08:00
Ross Scroggs
3d196b15c8 Contacts have to be with enable_dasa false 2025-02-27 21:19:06 -08:00
Ross Scroggs
09e3f66563 Merge branch 'main' of https://github.com/GAM-team/GAM 2025-02-27 20:41:18 -08:00
Ross Scroggs
fb0687d3ff Add password prompting to create|update user 2025-02-27 20:41:15 -08:00
Jay Lee
f639de870b Merge branch 'main' of https://github.com/GAM-team/GAM
Some checks failed
Build and test GAM / build (Win64, build, 10, VC-WIN64A, windows-2022) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 3, linux-aarch64, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 4, linux-aarch64, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 6, linux-aarch64, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 8, darwin64-arm64, macos-14) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 9, darwin64-arm64, macos-15) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 1, linux-x86_64, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 2, linux-x86_64, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 5, linux-x86_64, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 7, darwin64-x86_64, macos-13) (push) Has been cancelled
Build and test GAM / build (x86_64, test, 11, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (x86_64, test, 12, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (x86_64, test, 13, ubuntu-24.04, 3.12) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-02-26 14:04:41 +00:00
Jay Lee
81a1855f01 centralize non-email group member prefix strings 2025-02-26 14:04:33 +00:00
Ross Scroggs
d9f8c644fe Handle ERROR 400: malformedWorkingLocationEvent error
Some checks are pending
Build and test GAM / build (Win64, build, 10, VC-WIN64A, windows-2022) (push) Waiting to run
Build and test GAM / build (aarch64, build, 3, linux-aarch64, ubuntu-24.04-arm) (push) Waiting to run
Build and test GAM / build (aarch64, build, 4, linux-aarch64, ubuntu-22.04-arm) (push) Waiting to run
Build and test GAM / build (aarch64, build, 6, linux-aarch64, ubuntu-22.04-arm, yes) (push) Waiting to run
Build and test GAM / build (aarch64, build, 8, darwin64-arm64, macos-14) (push) Waiting to run
Build and test GAM / build (aarch64, build, 9, darwin64-arm64, macos-15) (push) Waiting to run
Build and test GAM / build (x86_64, build, 1, linux-x86_64, ubuntu-22.04) (push) Waiting to run
Build and test GAM / build (x86_64, build, 2, linux-x86_64, ubuntu-24.04) (push) Waiting to run
Build and test GAM / build (x86_64, build, 5, linux-x86_64, ubuntu-22.04, yes) (push) Waiting to run
Build and test GAM / build (x86_64, build, 7, darwin64-x86_64, macos-13) (push) Waiting to run
Build and test GAM / build (x86_64, test, 11, ubuntu-24.04, 3.10) (push) Waiting to run
Build and test GAM / build (x86_64, test, 12, ubuntu-24.04, 3.11) (push) Waiting to run
Build and test GAM / build (x86_64, test, 13, ubuntu-24.04, 3.12) (push) Waiting to run
Build and test GAM / merge (push) Blocked by required conditions
Build and test GAM / publish (push) Blocked by required conditions
CodeQL / Analyze (python) (push) Waiting to run
Check for Google Root CA Updates / check-apis (push) Waiting to run
2025-02-25 08:32:54 -08:00
Ross Scroggs
0a755335da #1754 - Fixed bug in gam all users print users issuspended false allfields that caused a trap.
Some checks are pending
Build and test GAM / build (Win64, build, 10, VC-WIN64A, windows-2022) (push) Waiting to run
Build and test GAM / build (aarch64, build, 3, linux-aarch64, ubuntu-24.04-arm) (push) Waiting to run
Build and test GAM / build (aarch64, build, 4, linux-aarch64, ubuntu-22.04-arm) (push) Waiting to run
Build and test GAM / build (aarch64, build, 6, linux-aarch64, ubuntu-22.04-arm, yes) (push) Waiting to run
Build and test GAM / build (aarch64, build, 8, darwin64-arm64, macos-14) (push) Waiting to run
Build and test GAM / build (aarch64, build, 9, darwin64-arm64, macos-15) (push) Waiting to run
Build and test GAM / build (x86_64, build, 1, linux-x86_64, ubuntu-22.04) (push) Waiting to run
Build and test GAM / build (x86_64, build, 2, linux-x86_64, ubuntu-24.04) (push) Waiting to run
Build and test GAM / build (x86_64, build, 5, linux-x86_64, ubuntu-22.04, yes) (push) Waiting to run
Build and test GAM / build (x86_64, build, 7, darwin64-x86_64, macos-13) (push) Waiting to run
Build and test GAM / build (x86_64, test, 11, ubuntu-24.04, 3.10) (push) Waiting to run
Build and test GAM / build (x86_64, test, 12, ubuntu-24.04, 3.11) (push) Waiting to run
Build and test GAM / build (x86_64, test, 13, ubuntu-24.04, 3.12) (push) Waiting to run
Build and test GAM / merge (push) Blocked by required conditions
Build and test GAM / publish (push) Blocked by required conditions
CodeQL / Analyze (python) (push) Waiting to run
Check for Google Root CA Updates / check-apis (push) Waiting to run
2025-02-24 13:06:34 -08:00
Ross Scroggs
d4200b66dc Chat usage reports are now available.
Some checks failed
Build and test GAM / build (Win64, build, 10, VC-WIN64A, windows-2022) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 3, linux-aarch64, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 4, linux-aarch64, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 6, linux-aarch64, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 8, darwin64-arm64, macos-14) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 9, darwin64-arm64, macos-15) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 1, linux-x86_64, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 2, linux-x86_64, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 5, linux-x86_64, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 7, darwin64-x86_64, macos-13) (push) Has been cancelled
Build and test GAM / build (x86_64, test, 11, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (x86_64, test, 12, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (x86_64, test, 13, ubuntu-24.04, 3.12) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-02-22 07:53:15 -08:00
Ross Scroggs
2afc28e017 Updated from v1beta1 to v1 for Cloud Identity - Policy.
Some checks are pending
Build and test GAM / build (Win64, build, 10, VC-WIN64A, windows-2022) (push) Waiting to run
Build and test GAM / build (aarch64, build, 3, linux-aarch64, ubuntu-24.04-arm) (push) Waiting to run
Build and test GAM / build (aarch64, build, 4, linux-aarch64, ubuntu-22.04-arm) (push) Waiting to run
Build and test GAM / build (aarch64, build, 6, linux-aarch64, ubuntu-22.04-arm, yes) (push) Waiting to run
Build and test GAM / build (aarch64, build, 8, darwin64-arm64, macos-14) (push) Waiting to run
Build and test GAM / build (aarch64, build, 9, darwin64-arm64, macos-15) (push) Waiting to run
Build and test GAM / build (x86_64, build, 1, linux-x86_64, ubuntu-22.04) (push) Waiting to run
Build and test GAM / build (x86_64, build, 2, linux-x86_64, ubuntu-24.04) (push) Waiting to run
Build and test GAM / build (x86_64, build, 5, linux-x86_64, ubuntu-22.04, yes) (push) Waiting to run
Build and test GAM / build (x86_64, build, 7, darwin64-x86_64, macos-13) (push) Waiting to run
Build and test GAM / build (x86_64, test, 11, ubuntu-24.04, 3.10) (push) Waiting to run
Build and test GAM / build (x86_64, test, 12, ubuntu-24.04, 3.11) (push) Waiting to run
Build and test GAM / build (x86_64, test, 13, ubuntu-24.04, 3.12) (push) Waiting to run
Build and test GAM / merge (push) Blocked by required conditions
Build and test GAM / publish (push) Blocked by required conditions
CodeQL / Analyze (python) (push) Waiting to run
Check for Google Root CA Updates / check-apis (push) Waiting to run
2025-02-21 07:22:17 -08:00
8 changed files with 247 additions and 393 deletions

View File

@@ -824,6 +824,7 @@ jobs:
$gam config csv_output_row_filter "name:regex:gha_test_${JID}_" print vaultholds || if [ $? != 55 ]; then exit $?; fi | $gam csv - gam delete vaulthold "id:~~holdId~~" matter "id:~~matterId~~"
$gam config csv_output_row_filter "name:regex:gha_test_${HID}_" print vaultmatters matterstate OPEN | $gam csv - gam update vaultmatter "id:~~matterId~~" action close
$gam config csv_output_row_filter "name:regex:gha_test_${HID}_" print vaultmatters matterstate CLOSED | $gam csv - gam update vaultmatter "id:~~matterId~~" action delete
$gam config csv_output_row_filter "Emails.1.address:regex:^gha_test-${JID}_" print contacts | $gam csv - gam delete contact ~ContactID
$gam config enable_dasa true save
$gam config csv_output_row_filter "name:regex:gha_test_${JID}_" print features | $gam csv - gam delete feature ~name
$gam config csv_output_row_filter "name:regex:^gha_test_${JID}_" user $gam_user print shareddrives asadmin | $gam csv - gam user $gam_user delete shareddrive ~id nukefromorbit
@@ -832,7 +833,6 @@ jobs:
$gam config csv_output_row_filter "email:regex:^gha_test_${JID}_" print cigroups | $gam csv - gam delete cigroup ~email
$gam config csv_output_row_filter "resourceId:regex:^gha_test_${JID}_" print resources | $gam csv - gam delete resource ~resourceId
$gam config csv_output_row_filter "buildingId:regex:^gha_test_${JID}_" print buildings | $gam csv - gam delete building ~buildingId
$gam config csv_output_row_filter "Emails.1.address:regex:^gha_test-${JID}_" print contacts | $gam csv - gam delete contact ~ContactID
echo "Creating OrgUnit ${newou}"
$gam create ou "${newou}"
@@ -874,6 +874,8 @@ jobs:
$gam csv sample.csv gam update user ~~email~~ recoveryphone "" recoveryemail ""
$gam config enable_dasa false save
$gam csv sample.csv gam user ~email add license workspaceenterpriseplus
#$gam user $newuser add contactdelegate "${newbase}-bulkuser-1"
#$gam user $newuser print contactdelegates
$gam config enable_dasa true save
$gam csv sample.csv gam user $gam_user sendemail recipient ~~email~~@pdl.jaylee.us subject "test message $newbase" message "GHA test message"
$gam csv sample.csv gam update group $newgroup add member ~email
@@ -884,8 +886,6 @@ jobs:
$gam user $newuser imap on
$gam user $newuser show imap
$gam user $newuser show delegates
#$gam user $newuser add contactdelegate "${newbase}-bulkuser-1"
#$gam user $newuser print contactdelegates
export biohazard=$(echo -e '\xe2\x98\xa3')
$gam user $newuser label "$biohazard unicode biohazard $biohazard"
$gam user $newuser show labels
@@ -951,9 +951,9 @@ jobs:
$gam user $newuser show holds || if [ $? != 55 ]; then exit $?; fi # expect a 55 return code
export sn="$JID$JID$JID$JID-$(openssl rand -base64 32 | sed 's/[^a-zA-Z0-9]//g')"
$gam create device serialnumber $sn devicetype android
$gam delete contacts emailmatchpattern "^${newbase}@example.com$"
$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 delete contacts emailmatchpattern "^${newbase}@example.com$"
$gam print mobile
$gam print devices
$gam print browsers

View File

@@ -4073,6 +4073,7 @@ gam show cigroup-members
releaseversion|
securitypatchtime|
serialnumber|
unifieddeviceid|
wifimacaddresses
<DeviceFieldNameList> ::= "<DeviceFieldName>(,<DeviceFieldName>)*"
@@ -4474,6 +4475,7 @@ gam report <ActivityApplicationName> [todrive <ToDriveAttribute>*]
app_maker|
apps_scripts|
calendar|
chat|
classroom|
cros|
device_management|
@@ -4494,6 +4496,7 @@ gam report customers|customer|domain [todrive <ToDriveAttribute>*]
<UserServiceName> ::=
accounts|
chat|
classroom|
docs|
drive|
@@ -5463,7 +5466,10 @@ gam download storagefile <StorageBucketObjectName>
(file|htmlfile <FileName> [charset <Charset>])|
(gdoc|ghtml <UserGoogleDoc>)))|
(ou|org|orgunitpath <OrgUnitPath>|<OrgUnitID>)
(password (random [<Integer>])|(uniquerandom [<Integer>])|blocklogin|<Password>)|
(password (random [<Integer>])|(uniquerandom [<Integer>])|
blocklogin|
prompt|uniqueprompt|
<Password>)|
(recoveryemail <EmailAddress>)|
(recoveryphone <string>)|
(suspend|suspended <Boolean>)|
@@ -5546,7 +5552,7 @@ gam create|add user <EmailAddress> [ignorenullpassword] <UserAttribute>*
[replyto <EmailAaddress>]
[<NotifyMessageContent>]
(replace <Tag> <UserReplacement>)*]
[lograndompassword <FileName>]
[logpassword <FileName>]
[addnumericsuffixonduplicate <Number>]
gam <UserTypeEntity> waitformailbox [retries <Number>]
@@ -5571,7 +5577,7 @@ gam update user <UserItem> [ignorenullpassword] <UserAttribute>*
[<NotifyMessageContent>]
(replace <Tag> <UserReplacement>)*]
[notifyonupdate [<Boolean>]] [setchangepasswordoncreate [<Boolean>]]
[lograndompassword <FileName>]
[logpassword <FileName>]
gam delete user <UserItem> [noactionifalias]
gam undelete user <UserItem> [ou|org|orgunit <OrgUnitPath>]
gam suspend user <UserItem> [noactionifalias]
@@ -5605,7 +5611,7 @@ gam update users <UserTypeEntity> [ignorenullpassword] <UserAttribute>*
[<NotifyMessageContent>]
(replace <Tag> <UserReplacement>)*]
[notifyonupdate [<Boolean>]] [setchangepasswordoncreate [<Boolean>]]
[lograndompassword <FileName>]
[logpassword <FileName>]
[verifynotinvitable]
gam delete users <UserTypeEntity> [noactionifalias]
gam undelete users <UserEntity> [ou|org|orgunit <OrgUnitPath>]
@@ -5638,7 +5644,7 @@ gam <UserTypeEntity> update users [ignorenullpassword] <UserAttribute>*
[<NotifyMessageContent>]
(replace <Tag> <UserReplacement>)*]
[notifyonupdate [<Boolean>]] [setchangepasswordoncreate [<Boolean>]]
[lograndompassword <FileName>]
[logpassword <FileName>]
[verifynotinvitable]
gam <UserTypeEntity> delete users [noactionifalias]
gam <UserEntity> undelete users [ou|org|orgunit <OrgUnitPath>]

View File

@@ -1,3 +1,53 @@
7.05.08
Added error message to `gam report` commands to indicate forbidden access;
previously, no error message was displayed.
```
ERROR: Customer ID: C012abc34, Caller does not have access to the customers reporting data.
```
7.05.07
Fixed bug in `gam calendars <CalendarEntity> info events` and `gam <UserTypeEntity> info events`
where option `showdayofweek` was not recognized.
7.05.06
Improve message displayed when a command is issued that requires Google Chat Bot setup;
display a link to the Wiki `Set up a Chat Bot` instructions.
7.05.05
Added options `password prompt` and `password uniqueprompt` to `gam create user <EmailAddress>`
and `gam update users <UserTypeEntity>` that prompt you to enter a password from stdin.
See [User Passwords](https://github.com/GAM-team/GAM/wiki/Users#passwords)
7.05.04
Updated `gam calendars <CalendarEntity> update events` and `gam <UserTypeEntity> update events`
to handle the following error:
```
ERROR 400: malformedWorkingLocationEvent - A working location event must have a visibility setting of public.
```
7.05.03
Fixed bug in `gam all users print users issuspended false allfields` that caused a trap.
7.05.02
Chat usage reports are now available. Added `chat` to `<CustomerServiceName>` and `<UserServiceName>`
for use in `gam report customer|user`.
* https://workspaceupdates.googleblog.com/2025/02/chat-usage-analytics-updates.html
7.05.01
Updated from `v1beta1` to `v1` for `Cloud Identity - Policy`.
* See: https://workspaceupdates.googleblog.com/2025/02/policy-api-general-availability.html
7.05.00
Enabled support for Limited Access as described here:

View File

@@ -273,257 +273,6 @@ r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1
gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+
-----END CERTIFICATE-----
# Operating CA: Entrust Datacard
# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
# Label: "Entrust Root Certification Authority"
# Serial: 1164660820
# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4
# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9
# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c
-----BEGIN CERTIFICATE-----
MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC
VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw
NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw
NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy
ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV
BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo
Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4
4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9
KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI
rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi
94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB
sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi
gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo
kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE
vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t
O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua
AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP
9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/
eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m
0vdXcDazv/wor3ElhVsT/h5/WrQ8
-----END CERTIFICATE-----
# Operating CA: Entrust Datacard
# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only
# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only
# Label: "Entrust Root Certification Authority - EC1"
# Serial: 51543124481930649114116133369
# MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc
# SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47
# SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5
-----BEGIN CERTIFICATE-----
MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG
A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3
d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu
dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq
RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy
MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD
VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0
L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g
Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD
ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi
A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt
ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH
Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC
R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX
hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
-----END CERTIFICATE-----
# Operating CA: Entrust Datacard
# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only
# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only
# Label: "Entrust Root Certification Authority - G2"
# Serial: 1246989352
# MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2
# SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4
# SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39
-----BEGIN CERTIFICATE-----
MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC
VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50
cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs
IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz
dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy
NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu
dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt
dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0
aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T
RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN
cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW
wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1
U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0
jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP
BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN
BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/
jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v
1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R
nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH
VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g==
-----END CERTIFICATE-----
# Operating CA: Entrust Datacard
# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
# Label: "Entrust.net Premium 2048 Secure Server CA"
# Serial: 946069240
# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90
# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31
# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77
-----BEGIN CERTIFICATE-----
MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3
MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub
j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo
U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b
u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+
bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er
fF6adulZkMV8gzURZVE=
-----END CERTIFICATE-----
# Operating CA: Entrust Datacard
# Issuer: CN=AffirmTrust Commercial O=AffirmTrust
# Subject: CN=AffirmTrust Commercial O=AffirmTrust
# Label: "AffirmTrust Commercial"
# Serial: 8608355977964138876
# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7
# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7
# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7
-----BEGIN CERTIFICATE-----
MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE
BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL
MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP
Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr
ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL
MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1
yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr
VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/
nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG
XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj
vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt
Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g
N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC
nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
-----END CERTIFICATE-----
# Operating CA: Entrust Datacard
# Issuer: CN=AffirmTrust Networking O=AffirmTrust
# Subject: CN=AffirmTrust Networking O=AffirmTrust
# Label: "AffirmTrust Networking"
# Serial: 8957382827206547757
# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f
# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f
# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b
-----BEGIN CERTIFICATE-----
MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE
BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL
MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y
YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua
kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL
QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp
6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG
yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i
QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO
tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu
QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ
Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u
olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48
x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
-----END CERTIFICATE-----
# Operating CA: Entrust Datacard
# Issuer: CN=AffirmTrust Premium O=AffirmTrust
# Subject: CN=AffirmTrust Premium O=AffirmTrust
# Label: "AffirmTrust Premium"
# Serial: 7893706540734352110
# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57
# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27
# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a
-----BEGIN CERTIFICATE-----
MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE
BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz
dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG
A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U
cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf
qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ
JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ
+jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS
s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5
HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7
70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG
V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S
qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S
5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia
C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX
OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE
FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2
KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg
Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B
8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ
MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc
0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ
u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF
u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH
YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8
GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO
RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e
KeC2uAloGRwYQw==
-----END CERTIFICATE-----
# Operating CA: Entrust Datacard
# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust
# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust
# Label: "AffirmTrust Premium ECC"
# Serial: 8401224907861490260
# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d
# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb
# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23
-----BEGIN CERTIFICATE-----
MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC
VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ
cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ
BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt
VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D
0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9
ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G
A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G
A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs
aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I
flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ==
-----END CERTIFICATE-----
# Operating CA: GlobalSign
# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA
# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA

View File

@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
"""
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
__version__ = '7.05.00'
__version__ = '7.05.08'
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
#pylint: disable=wrong-import-position
@@ -5751,14 +5751,18 @@ def convertUIDtoEmailAddressWithType(emailAddressOrUID, cd=None, sal=None, email
return (uid, 'serviceaccount')
return (normalizedEmailAddressOrUID, 'unknown')
NON_EMAIL_MEMBER_PREFIXES = (
"cbcm-browser.",
"chrome-os-device.",
)
# Convert UID to email address
def convertUIDtoEmailAddress(emailAddressOrUID, cd=None, emailTypes=None,
checkForCustomerId=False, ciGroupsAPI=False, aliasAllowed=True):
if ciGroupsAPI:
if emailAddressOrUID.startswith('cbcm-browser.') or emailAddressOrUID.startswith('chrome-os-device.'):
if emailAddressOrUID.startswith(NON_EMAIL_MEMBER_PREFIXES):
return emailAddressOrUID
normalizedEmailAddressOrUID = normalizeEmailAddressOrUID(emailAddressOrUID, ciGroupsAPI=ciGroupsAPI)
if normalizedEmailAddressOrUID.startswith('cbcm-browser.') or normalizedEmailAddressOrUID.startswith('chrome-os-device.'):
if normalizedEmailAddressOrUID.startswith(NON_EMAIL_MEMBER_PREFIXES):
return normalizedEmailAddressOrUID
email, _ = convertUIDtoEmailAddressWithType(emailAddressOrUID, cd, emailTypes,
checkForCustomerId, ciGroupsAPI, aliasAllowed)
@@ -13109,6 +13113,7 @@ CUSTOMER_REPORT_SERVICES = {
'app_maker',
'apps_scripts',
'calendar',
'chat',
'classroom',
'cros',
'device_management',
@@ -13122,6 +13127,7 @@ CUSTOMER_REPORT_SERVICES = {
USER_REPORT_SERVICES = {
'accounts',
'chat',
'classroom',
'docs',
'drive',
@@ -13423,8 +13429,8 @@ def doReportUsage():
break
except GAPI.invalidInput as e:
systemErrorExit(GOOGLE_API_ERROR_RC, str(e))
except GAPI.forbidden:
accessErrorExit(None)
except GAPI.forbidden as e:
accessErrorExit(None, str(e))
if startUseDate:
reportName = f'{report.capitalize()} Usage Report - {startUseDate}:{endUseDate}'
else:
@@ -14021,8 +14027,8 @@ def doReport():
printErrorMessage(BAD_REQUEST_RC, Msg.BAD_REQUEST)
exitUserLoop = True
break
except GAPI.forbidden:
accessErrorExit(None)
except GAPI.forbidden as e:
accessErrorExit(None, str(e))
startDateTime += oneDay
if exitUserLoop:
break
@@ -14102,8 +14108,8 @@ def doReport():
continue
except GAPI.invalidInput as e:
systemErrorExit(GOOGLE_API_ERROR_RC, str(e))
except GAPI.forbidden:
accessErrorExit(None)
except GAPI.forbidden as e:
accessErrorExit(None, str(e))
startDateTime += oneDay
csvPF.writeCSVfile(f'Customer Report - {tryDate}')
else: # activityReports
@@ -18916,6 +18922,7 @@ CONTACT_USER_DEFINED_FIELDS = 'User Defined Fields'
CONTACT_WEBSITES = 'Websites'
#
class ContactsManager():
CONTACT_ARGUMENT_TO_PROPERTY_MAP = {
'json': CONTACT_JSON,
'name': CONTACT_NAME,
@@ -21296,7 +21303,7 @@ def queryPeopleContacts(people, contactQuery, fields, sortOrder, entityType, use
showMessage = pageMessage.replace(TOTAL_ITEMS_MARKER, str(totalItems))
writeGotMessage(showMessage.replace('{0}', str(Ent.Choose(Ent.PEOPLE_CONTACT, totalItems))))
return entityList
except GAPI.permissionDenied as e:
except (GAPI.permissionDenied, GAPI.failedPrecondition) as e:
ClientAPIAccessDeniedExit(str(e))
except (GAPI.serviceNotAvailable, GAPI.forbidden):
entityUnknownWarning(entityType, user, i, count)
@@ -21446,7 +21453,7 @@ def createUserPeopleContact(users):
csvPF.WriteRow(row)
except GAPI.invalidArgument as e:
entityActionFailedWarning([entityType, user, peopleEntityType, None], str(e), i, count)
except GAPI.permissionDenied as e:
except (GAPI.permissionDenied, GAPI.failedPrecondition) as e:
ClientAPIAccessDeniedExit(str(e))
except (GAPI.serviceNotAvailable, GAPI.forbidden):
ClientAPIAccessDeniedExit()
@@ -21611,7 +21618,7 @@ def _clearUpdatePeopleContacts(users, updateContacts):
entityActionFailedWarning([entityType, user, peopleEntityType, resourceName], str(e), j, jcount)
except (GAPI.notFound, GAPI.internalError):
entityActionFailedWarning([entityType, user, peopleEntityType, resourceName], Msg.DOES_NOT_EXIST, j, jcount)
except GAPI.permissionDenied as e:
except (GAPI.permissionDenied, GAPI.failedPrecondition) as e:
ClientAPIAccessDeniedExit(str(e))
except (GAPI.serviceNotAvailable, GAPI.forbidden):
ClientAPIAccessDeniedExit()
@@ -21761,7 +21768,7 @@ def dedupReplaceDomainUserPeopleContacts(users):
entityActionFailedWarning([entityType, user, peopleEntityType, resourceName], str(e), j, jcount)
except (GAPI.notFound, GAPI.internalError):
entityActionFailedWarning([entityType, user, peopleEntityType, resourceName], Msg.DOES_NOT_EXIST, j, jcount)
except GAPI.permissionDenied as e:
except (GAPI.permissionDenied, GAPI.failedPrecondition) as e:
ClientAPIAccessDeniedExit(str(e))
except (GAPI.serviceNotAvailable, GAPI.forbidden):
ClientAPIAccessDeniedExit()
@@ -21816,7 +21823,7 @@ def deleteUserPeopleContacts(users):
entityActionPerformed([entityType, user, peopleEntityType, resourceName], j, jcount)
except (GAPI.notFound, GAPI.internalError):
entityActionFailedWarning([entityType, user, peopleEntityType, resourceName], Msg.DOES_NOT_EXIST, j, jcount)
except GAPI.permissionDenied as e:
except (GAPI.permissionDenied, GAPI.failedPrecondition) as e:
ClientAPIAccessDeniedExit(str(e))
except (GAPI.serviceNotAvailable, GAPI.forbidden):
ClientAPIAccessDeniedExit()
@@ -22113,7 +22120,7 @@ def _infoPeople(users, entityType, source):
except GAPI.invalidArgument as e:
entityActionFailedWarning([entityType, user, peopleEntityType, resourceName], str(e), j, jcount)
continue
except GAPI.permissionDenied as e:
except (GAPI.permissionDenied, GAPI.failedPrecondition) as e:
ClientAPIAccessDeniedExit(str(e))
except (GAPI.serviceNotAvailable, GAPI.forbidden):
ClientAPIAccessDeniedExit()
@@ -22528,7 +22535,7 @@ def _printShowPeople(source):
pageSize=GC.Values[GC.PEOPLE_MAX_RESULTS],
sources=sources, mergeSources=mergeSources,
readMask=fields, fields='nextPageToken,people', **kwargs)
except GAPI.permissionDenied as e:
except (GAPI.permissionDenied, GAPI.failedPrecondition) as e:
ClientAPIAccessDeniedExit(str(e))
except (GAPI.serviceNotAvailable, GAPI.forbidden):
ClientAPIAccessDeniedExit()
@@ -22567,14 +22574,14 @@ def doInfoDomainPeopleContacts():
# [countsonly]
# [allfields|(fields <PeopleFieldNameList>)] [showmetadata]
# [formatjson]
# gam print peoplecontacts [todrive <ToDriveAttribute>*]
# gam print domaincontacts|peoplecontacts [todrive <ToDriveAttribute>*]
# [sources <PeopleSourceName>]
# [query <String>]
# [mergesources <PeopleMergeSourceName>]
# [countsonly]
# [allfields|(fields <PeopleFieldNameList>)] [showmetadata]
# [formatjson [quotechar <Character>]]
# gam show peoplecontacts
# gam show domaincontacts|peoplecontacts
# [sources <PeopleSourceName>]
# [query <String>]
# [mergesources <PeopleMergeSourceName>]
@@ -22650,7 +22657,7 @@ def printShowUserPeopleProfiles(users):
except GAPI.notFound:
entityUnknownWarning(Ent.PEOPLE_PROFILE, user, i, count)
continue
except GAPI.permissionDenied as e:
except (GAPI.permissionDenied, GAPI.failedPrecondition) as e:
ClientAPIAccessDeniedExit(str(e))
except (GAPI.serviceNotAvailable, GAPI.forbidden):
ClientAPIAccessDeniedExit()
@@ -22806,7 +22813,7 @@ def _processPeopleContactPhotos(users, function):
entityDoesNotHaveItemWarning([entityType, user, peopleEntityType, resourceName, Ent.PHOTO, filename], j, jcount)
except (GAPI.invalidArgument, OSError, IOError) as e:
entityActionFailedWarning([entityType, user, peopleEntityType, resourceName, Ent.PHOTO, filename], str(e), j, jcount)
except GAPI.permissionDenied as e:
except (GAPI.permissionDenied, GAPI.failedPrecondition) as e:
ClientAPIAccessDeniedExit(str(e))
except (GAPI.serviceNotAvailable, GAPI.forbidden):
ClientAPIAccessDeniedExit()
@@ -29251,6 +29258,7 @@ DEVICE_FIELDS_CHOICE_MAP = {
'releaseversion': 'releaseVersion',
'securitypatchtime': 'securityPatchTime',
'serialnumber': 'serialNumber',
'unifieddeviceid': 'unifiedDeviceId',
'wifimacaddresses': 'wifiMacAddresses'
}
@@ -34179,7 +34187,7 @@ def doPrintGroupMembers():
for name in info['names']:
if name['metadata']['source']['type'] == sourceType:
return name['displayName']
except (GAPI.notFound, GAPI.serviceNotAvailable, GAPI.forbidden, GAPI.permissionDenied):
except (GAPI.notFound, GAPI.serviceNotAvailable, GAPI.forbidden, GAPI.permissionDenied, GAPI.failedPrecondition):
pass
return unknownName
@@ -35726,10 +35734,16 @@ def _showPolicies(policies, FJQC, add_warnings, no_appnames,
_showPolicy(policy, FJQC, i, count)
Ind.Decrement()
def _checkPoliciesWithDASA():
if GC.Values[GC.ENABLE_DASA]:
systemErrorExit(USAGE_ERROR_RC,
Msg.COMMAND_NOT_COMPATIBLE_WITH_ENABLE_DASA.format(Act.ToPerform().lower(), Cmd.ARG_CIPOLICIES))
# gam info policies <CIPolicyNameEntity>
# [nowarnings] [noappnames]
# [formatjson]
def doInfoCIPolicies():
_checkPoliciesWithDASA()
groups_ci = buildGAPIObject(API.CLOUDIDENTITY_GROUPS)
ci = buildGAPIObject(API.CLOUDIDENTITY_POLICY)
cd = buildGAPIObject(API.DIRECTORY)
@@ -35788,6 +35802,7 @@ def doPrintShowCIPolicies():
ensure_ascii=False,
sort_keys=True)})
_checkPoliciesWithDASA()
groups_ci = buildGAPIObject(API.CLOUDIDENTITY_GROUPS)
ci = buildGAPIObject(API.CLOUDIDENTITY_POLICY)
cd = buildGAPIObject(API.DIRECTORY)
@@ -38923,6 +38938,22 @@ def _setEventRecurrenceTimeZone(cal, calId, body, parameters, i, count):
body['end']['timeZone'] = timeZone
return True
def _getEventDaysOfWeek(event):
for attr in ['start', 'end']:
if attr in event:
if 'date' in event[attr]:
try:
dateTime = datetime.datetime.strptime(event[attr]['date'], YYYYMMDD_FORMAT)
event[attr]['dayOfWeek'] = calendarlib.day_abbr[dateTime.weekday()]
except ValueError:
pass
elif 'dateTime' in event[attr]:
try:
dateTime, _ = iso8601.parse_date(event[attr]['dateTime'])
event[attr]['dayOfWeek'] = calendarlib.day_abbr[dateTime.weekday()]
except (iso8601.ParseError, OverflowError):
pass
def _createCalendarEvents(user, origCal, function, calIds, count, body, parameters):
if parameters['attendees']:
body['attendees'] = parameters.pop('attendees')
@@ -39051,7 +39082,8 @@ def _updateCalendarEvents(origUser, user, origCal, calIds, count, calendarEventE
event = callGAPI(cal.events(), 'patch',
throwReasons=GAPI.CALENDAR_THROW_REASONS+[GAPI.NOT_FOUND, GAPI.DELETED, GAPI.FORBIDDEN,
GAPI.INVALID, GAPI.REQUIRED, GAPI.TIME_RANGE_EMPTY, GAPI.EVENT_DURATION_EXCEEDS_LIMIT,
GAPI.REQUIRED_ACCESS_LEVEL, GAPI.CANNOT_CHANGE_ORGANIZER_OF_INSTANCE],
GAPI.REQUIRED_ACCESS_LEVEL, GAPI.CANNOT_CHANGE_ORGANIZER_OF_INSTANCE,
GAPI.MALFORMED_WORKING_LOCATION_EVENT],
calendarId=calId, eventId=eventId, conferenceDataVersion=1, sendUpdates=parameters['sendUpdates'], supportsAttachments=True,
body=body, fields=pfields)
if parameters['csvPF'] is None:
@@ -39066,7 +39098,7 @@ def _updateCalendarEvents(origUser, user, origCal, calIds, count, calendarEventE
break
entityActionFailedWarning([Ent.CALENDAR, calId, Ent.EVENT, eventId], str(e), j, jcount)
except (GAPI.forbidden, GAPI.invalid, GAPI.required, GAPI.timeRangeEmpty, GAPI.eventDurationExceedsLimit,
GAPI.requiredAccessLevel, GAPI.cannotChangeOrganizerOfInstance) as e:
GAPI.requiredAccessLevel, GAPI.cannotChangeOrganizerOfInstance, GAPI.malformedWorkingLocationEvent) as e:
entityActionFailedWarning([Ent.CALENDAR, calId, Ent.EVENT, eventId], str(e), j, jcount)
except GAPI.notACalendarUser:
userCalServiceNotEnabledWarning(calId, i, count)
@@ -39557,6 +39589,8 @@ def _getCalendarInfoEventOptions(calendarEventEntity):
myarg = getArgument()
if myarg == 'fields':
_getEventFields(fieldsList)
elif myarg == 'showdayofweek':
calendarEventEntity['showDayOfWeek'] = True
else:
FJQC.GetFormatJSON(myarg)
_addEventEntitySelectFields(calendarEventEntity, fieldsList)
@@ -39580,6 +39614,8 @@ def _infoCalendarEvents(origUser, user, origCal, calIds, count, calendarEventEnt
throwReasons=GAPI.CALENDAR_THROW_REASONS+[GAPI.NOT_FOUND, GAPI.DELETED, GAPI.FORBIDDEN],
calendarId=calId, eventId=eventId, fields=fields)
if calendarEventEntity['maxinstances'] == -1 or 'recurrence' not in event:
if calendarEventEntity['showDayOfWeek']:
_getEventDaysOfWeek(event)
_showCalendarEvent(user, calId, Ent.EVENT, event, j, jcount, FJQC)
else:
instances = callGAPIpages(cal.events(), 'instances', 'items',
@@ -39593,6 +39629,8 @@ def _infoCalendarEvents(origUser, user, origCal, calIds, count, calendarEventEnt
l = 0
for instance in instances:
l += 1
if calendarEventEntity['showDayOfWeek']:
_getEventDaysOfWeek(instance)
_showCalendarEvent(user, calId, Ent.INSTANCE, instance, l, lcount, FJQC)
Ind.Decrement()
except (GAPI.notFound, GAPI.deleted) as e:
@@ -39646,22 +39684,6 @@ def _getCalendarPrintShowEventOptions(calendarEventEntity, entityType):
_addEventEntitySelectFields(calendarEventEntity, fieldsList)
return (csvPF, FJQC, fieldsList)
def _getEventDaysOfWeek(event):
for attr in ['start', 'end']:
if attr in event:
if 'date' in event[attr]:
try:
dateTime = datetime.datetime.strptime(event[attr]['date'], YYYYMMDD_FORMAT)
event[attr]['dayOfWeek'] = calendarlib.day_abbr[dateTime.weekday()]
except ValueError:
pass
elif 'dateTime' in event[attr]:
try:
dateTime, _ = iso8601.parse_date(event[attr]['dateTime'])
event[attr]['dayOfWeek'] = calendarlib.day_abbr[dateTime.weekday()]
except (iso8601.ParseError, OverflowError):
pass
# gam calendars <CalendarEntity> print events <EventEntity> <EventDisplayProperties>*
# [fields <EventFieldNameList>] [showdayofweek]
# [countsonly] [formatjson [quotechar <Character>]] [todrive <ToDriveAttribute>*]
@@ -40375,20 +40397,20 @@ def convertExportNameToID(v, nameOrId, matterId, matterNameId):
if cg:
try:
export = callGAPI(v.matters().exports(), 'get',
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN],
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, exportId=cg.group(1))
return (export['id'], export['name'], formatVaultNameId(export['id'], export['name']))
except (GAPI.notFound, GAPI.badRequest):
entityDoesNotHaveItemExit([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_EXPORT, nameOrId])
except GAPI.forbidden:
ClientAPIAccessDeniedExit()
except (GAPI.forbidden, GAPI.invalidArgument) as e:
ClientAPIAccessDeniedExit(str(e))
nameOrIdlower = nameOrId.lower()
try:
exports = callGAPIpages(v.matters().exports(), 'list', 'exports',
throwReasons=[GAPI.FORBIDDEN],
throwReasons=[GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, fields='exports(id,name),nextPageToken')
except GAPI.forbidden:
ClientAPIAccessDeniedExit()
except (GAPI.forbidden, GAPI.invalidArgument) as e:
ClientAPIAccessDeniedExit(str(e))
for export in exports:
if export['name'].lower() == nameOrIdlower:
return (export['id'], export['name'], formatVaultNameId(export['id'], export['name']))
@@ -40399,20 +40421,20 @@ def convertHoldNameToID(v, nameOrId, matterId, matterNameId):
if cg:
try:
hold = callGAPI(v.matters().holds(), 'get',
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN],
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, holdId=cg.group(1))
return (hold['holdId'], hold['name'], formatVaultNameId(hold['holdId'], hold['name']))
except (GAPI.notFound, GAPI.badRequest):
entityDoesNotHaveItemExit([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_HOLD, nameOrId])
except GAPI.forbidden:
ClientAPIAccessDeniedExit()
except (GAPI.forbidden, GAPI.invalidArgument) as e:
ClientAPIAccessDeniedExit(str(e))
nameOrIdlower = nameOrId.lower()
try:
holds = callGAPIpages(v.matters().holds(), 'list', 'holds',
throwReasons=[GAPI.FORBIDDEN],
throwReasons=[GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, fields='holds(holdId,name),nextPageToken')
except GAPI.forbidden:
ClientAPIAccessDeniedExit()
except (GAPI.forbidden, GAPI.invalidArgument) as e:
ClientAPIAccessDeniedExit(str(e))
for hold in holds:
if hold['name'].lower() == nameOrIdlower:
return (hold['holdId'], hold['name'], formatVaultNameId(hold['holdId'], hold['name']))
@@ -40423,17 +40445,17 @@ def convertMatterNameToID(v, nameOrId, state=None):
if cg:
try:
matter = callGAPI(v.matters(), 'get',
throwReasons=[GAPI.NOT_FOUND, GAPI.FORBIDDEN],
throwReasons=[GAPI.NOT_FOUND, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=cg.group(1), view='BASIC', fields='matterId,name,state')
return (matter['matterId'], matter['name'], formatVaultNameId(matter['name'], matter['matterId']), matter['state'])
except (GAPI.notFound, GAPI.forbidden):
entityDoesNotExistExit(Ent.VAULT_MATTER, nameOrId)
try:
matters = callGAPIpages(v.matters(), 'list', 'matters',
throwReasons=[GAPI.FORBIDDEN],
throwReasons=[GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
view='BASIC', state=state, fields='matters(matterId,name,state),nextPageToken')
except GAPI.forbidden:
ClientAPIAccessDeniedExit()
except (GAPI.forbidden, GAPI.invalidArgument) as e:
ClientAPIAccessDeniedExit(str(e))
nameOrIdlower = nameOrId.lower()
ids = []
states = []
@@ -40454,20 +40476,20 @@ def convertQueryNameToID(v, nameOrId, matterId, matterNameId):
if cg:
try:
query = callGAPI(v.matters().savedQueries(), 'get',
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN],
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, savedQueryId=cg.group(1))
return (query['savedQueryId'], query['displayName'], formatVaultNameId(query['savedQueryId'], query['displayName']))
except (GAPI.notFound, GAPI.badRequest):
entityDoesNotHaveItemExit([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_QUERY, nameOrId])
except GAPI.forbidden:
ClientAPIAccessDeniedExit()
except (GAPI.forbidden, GAPI.invalidArgument) as e:
ClientAPIAccessDeniedExit(str(e))
nameOrIdlower = nameOrId.lower()
try:
queries = callGAPIpages(v.matters().savedQueries(), 'list', 'savedQueries',
throwReasons=[GAPI.FORBIDDEN],
throwReasons=[GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, fields='savedQueries(savedQueryId,displayName),nextPageToken')
except GAPI.forbidden:
ClientAPIAccessDeniedExit()
except (GAPI.forbidden, GAPI.invalidArgument) as e:
ClientAPIAccessDeniedExit(str(e))
for query in queries:
if query['displayName'].lower() == nameOrIdlower:
return (query['savedQueryId'], query['displayName'], formatVaultNameId(query['savedQueryId'], query['displayName']))
@@ -40481,9 +40503,9 @@ def warnMatterNotOpen(v, matter, matterNameId, j, jcount):
if v is not None:
try:
matter['state'] = callGAPI(v.matters(), 'get',
throwReasons=[GAPI.NOT_FOUND, GAPI.FORBIDDEN],
throwReasons=[GAPI.NOT_FOUND, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matter['matterId'], view='BASIC', fields='state')['state']
except (GAPI.notFound, GAPI.forbidden):
except (GAPI.notFound, GAPI.forbidden, GAPI.invalidArgument):
matter['state'] = 'Unknown'
else:
setSysExitRC(DATA_NOT_AVALIABLE_RC)
@@ -40799,10 +40821,10 @@ def doDeleteVaultExport():
unknownArgumentExit()
try:
callGAPI(v.matters().exports(), 'delete',
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN],
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, exportId=exportId)
entityActionPerformed([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_EXPORT, exportNameId])
except (GAPI.notFound, GAPI.badRequest, GAPI.forbidden) as e:
except (GAPI.notFound, GAPI.badRequest, GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_EXPORT, exportNameId], str(e))
VAULT_EXPORT_FIELDS_CHOICE_MAP = {
@@ -40853,10 +40875,10 @@ def doInfoVaultExport():
fields = getFieldsFromFieldsList(fieldsList)
try:
export = callGAPI(v.matters().exports(), 'get',
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN],
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, exportId=exportId, fields=fields)
_showVaultExport(matterNameId, export, cd, FJQC)
except (GAPI.notFound, GAPI.badRequest, GAPI.forbidden) as e:
except (GAPI.notFound, GAPI.badRequest, GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_EXPORT, exportNameId], str(e))
VAULT_EXPORT_STATUS_MAP = {'completed': 'COMPLETED', 'failed': 'FAILED', 'inprogress': 'IN_PROGRESS'}
@@ -40919,9 +40941,9 @@ def doPrintShowVaultExports():
try:
results = callGAPIpages(v.matters(), 'list', 'matters',
pageMessage=getPageMessage(),
throwReasons=[GAPI.FORBIDDEN],
throwReasons=[GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
view='BASIC', state='OPEN', fields='matters(matterId,name,state),nextPageToken')
except GAPI.forbidden as e:
except (GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_EXPORT, None], str(e))
return
else:
@@ -40949,12 +40971,12 @@ def doPrintShowVaultExports():
try:
exports = callGAPIpages(v.matters().exports(), 'list', 'exports',
pageMessage=pageMessage,
throwReasons=[GAPI.FAILED_PRECONDITION, GAPI.FORBIDDEN],
throwReasons=[GAPI.FAILED_PRECONDITION, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, fields=fields)
except GAPI.failedPrecondition:
warnMatterNotOpen(v, matter, matterNameId, j, jcount)
continue
except GAPI.forbidden as e:
except (GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_EXPORT, None], str(e))
break
else:
@@ -41049,9 +41071,9 @@ def doCopyVaultExport():
while True:
try:
export = callGAPI(v.matters().exports(), 'get',
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN],
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, exportId=exportId)
except (GAPI.notFound, GAPI.badRequest, GAPI.forbidden) as e:
except (GAPI.notFound, GAPI.badRequest, GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_EXPORT, exportNameId], str(e))
return
if export['status'] == 'COMPLETED':
@@ -41149,9 +41171,9 @@ def doDownloadVaultExport():
while True:
try:
export = callGAPI(v.matters().exports(), 'get',
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN],
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, exportId=exportId)
except (GAPI.notFound, GAPI.badRequest, GAPI.forbidden) as e:
except (GAPI.notFound, GAPI.badRequest, GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_EXPORT, exportNameId], str(e))
return
if export['status'] == 'COMPLETED':
@@ -41339,7 +41361,8 @@ def doCreateVaultHold():
body['accounts'].append({'accountId': convertEmailAddressToUID(account, cd, accountType, accountsLocation)})
try:
hold = callGAPI(v.matters().holds(), 'create',
throwReasons=[GAPI.ALREADY_EXISTS, GAPI.BAD_REQUEST, GAPI.BACKEND_ERROR, GAPI.FAILED_PRECONDITION, GAPI.FORBIDDEN],
throwReasons=[GAPI.ALREADY_EXISTS, GAPI.BAD_REQUEST, GAPI.BACKEND_ERROR, GAPI.FAILED_PRECONDITION,
GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, body=body)
if not returnIdOnly:
entityActionPerformed([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_HOLD, formatVaultNameId(hold['name'], hold['holdId'])])
@@ -41347,7 +41370,8 @@ def doCreateVaultHold():
_showVaultHold(None, hold, None, None)
else:
writeStdout(f'{hold["holdId"]}\n')
except (GAPI.alreadyExists, GAPI.badRequest, GAPI.backendError, GAPI.failedPrecondition, GAPI.forbidden) as e:
except (GAPI.alreadyExists, GAPI.badRequest, GAPI.backendError, GAPI.failedPrecondition,
GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_HOLD, body.get('name')], str(e))
# gam update vaulthold|hold <HoldItem> matter <MatterItem>
@@ -41392,9 +41416,9 @@ def doUpdateVaultHold():
missingArgumentExit('matter')
try:
old_body = callGAPI(v.matters().holds(), 'get',
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN],
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, holdId=holdId, fields='name,corpus,query,orgUnit')
except (GAPI.notFound, GAPI.badRequest, GAPI.forbidden) as e:
except (GAPI.notFound, GAPI.badRequest, GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_HOLD, holdNameId], str(e))
return
accountType = 'group' if old_body['corpus'] == 'GROUPS' else 'user'
@@ -41420,10 +41444,10 @@ def doUpdateVaultHold():
if body:
try:
hold = callGAPI(v.matters().holds(), 'update',
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN],
throwReas=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, holdId=holdId, body=body)
entityActionPerformed([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_HOLD, holdNameId])
except (GAPI.notFound, GAPI.badRequest, GAPI.forbidden) as e:
except (GAPI.notFound, GAPI.badRequest, GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_HOLD, holdNameId], str(e))
return
jcount = len(addAccountIds)
@@ -41436,12 +41460,12 @@ def doUpdateVaultHold():
j += 1
try:
callGAPI(v.matters().holds().accounts(), 'create',
throwReasons=[GAPI.ALREADY_EXISTS, GAPI.BACKEND_ERROR, GAPI.FORBIDDEN],
throwReasons=[GAPI.ALREADY_EXISTS, GAPI.BACKEND_ERROR, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, holdId=holdId, body={'accountId': account['id']})
entityActionPerformed([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_HOLD, holdNameId, Ent.ACCOUNT, account['email']], j, jcount)
except (GAPI.alreadyExists, GAPI.backendError) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_HOLD, holdNameId, Ent.ACCOUNT, account['email']], str(e), j, jcount)
except GAPI.forbidden as e:
except (GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_HOLD, None], str(e))
return
Ind.Decrement()
@@ -41457,12 +41481,12 @@ def doUpdateVaultHold():
j += 1
try:
callGAPI(v.matters().holds().accounts(), 'delete',
throwReasons=[GAPI.NOT_FOUND, GAPI.BACKEND_ERROR, GAPI.FORBIDDEN],
throwReasons=[GAPI.NOT_FOUND, GAPI.BACKEND_ERROR, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, holdId=holdId, accountId=account['id'])
entityActionPerformed([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_HOLD, holdNameId, Ent.ACCOUNT, account['email']], j, jcount)
except (GAPI.alreadyExists, GAPI.backendError) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_HOLD, holdNameId, Ent.ACCOUNT, account['email']], str(e), j, jcount)
except GAPI.forbidden as e:
except (GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_HOLD, None], str(e))
return
Ind.Decrement()
@@ -41487,10 +41511,10 @@ def doDeleteVaultHold():
unknownArgumentExit()
try:
callGAPI(v.matters().holds(), 'delete',
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN],
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, holdId=holdId)
entityActionPerformed([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_HOLD, holdNameId])
except (GAPI.notFound, GAPI.badRequest, GAPI.forbidden) as e:
except (GAPI.notFound, GAPI.badRequest, GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_HOLD, holdNameId], str(e))
VAULT_HOLD_FIELDS_CHOICE_MAP = {
@@ -41540,10 +41564,10 @@ def doInfoVaultHold():
fields = getFieldsFromFieldsList(fieldsList)
try:
hold = callGAPI(v.matters().holds(), 'get',
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN],
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, holdId=holdId, fields=fields)
_showVaultHold(matterNameId, hold, cd, FJQC)
except (GAPI.notFound, GAPI.badRequest, GAPI.forbidden) as e:
except (GAPI.notFound, GAPI.badRequest, GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_HOLD, holdNameId], str(e))
PRINT_VAULT_HOLDS_TITLES = ['matterId', 'matterName', 'holdId', 'name', 'updateTime']
@@ -41594,9 +41618,9 @@ def doPrintShowVaultHolds():
try:
results = callGAPIpages(v.matters(), 'list', 'matters',
pageMessage=getPageMessage(),
throwReasons=[GAPI.FORBIDDEN],
throwReasons=[GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
view='BASIC', state='OPEN', fields='matters(matterId,name,state),nextPageToken')
except GAPI.forbidden as e:
except (GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_HOLD, None], str(e))
return
else:
@@ -41623,12 +41647,12 @@ def doPrintShowVaultHolds():
try:
holds = callGAPIpages(v.matters().holds(), 'list', 'holds',
pageMessage=pageMessage,
throwReasons=[GAPI.FAILED_PRECONDITION, GAPI.FORBIDDEN],
throwReasons=[GAPI.FAILED_PRECONDITION, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, fields=fields)
except GAPI.failedPrecondition:
warnMatterNotOpen(v, matter, matterNameId, j, jcount)
continue
except GAPI.forbidden as e:
except (GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_HOLD, None], str(e))
break
else:
@@ -41674,9 +41698,9 @@ def printShowUserVaultHolds(entityList):
try:
matters = callGAPIpages(v.matters(), 'list', 'matters',
pageMessage=getPageMessage(),
throwReasons=[GAPI.FORBIDDEN],
throwReasons=[GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
view='BASIC', state='OPEN', fields='matters(matterId,name,state),nextPageToken')
except GAPI.forbidden as e:
except (GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_HOLD, None], str(e))
return
jcount = len(matters)
@@ -41690,11 +41714,11 @@ def printShowUserVaultHolds(entityList):
try:
matter['holds'] = callGAPIpages(v.matters().holds(), 'list', 'holds',
pageMessage=getPageMessageForWhom(),
throwReasons=[GAPI.FAILED_PRECONDITION, GAPI.FORBIDDEN],
throwReasons=[GAPI.FAILED_PRECONDITION, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, fields='holds(holdId,name,accounts(accountId,email),orgUnit(orgUnitId)),nextPageToken')
except GAPI.failedPrecondition:
warnMatterNotOpen(v, matter, matterNameId, j, jcount)
except GAPI.forbidden as e:
except (GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_HOLD, None], str(e), j, jcount)
totalHolds = 0
_, _, entityList = getEntityArgument(entityList)
@@ -41805,10 +41829,10 @@ def doInfoVaultQuery():
fields = getFieldsFromFieldsList(fieldsList)
try:
query = callGAPI(v.matters().savedQueries(), 'get',
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN],
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, savedQueryId=queryId, fields=fields)
_showVaultQuery(matterNameId, query, cd, FJQC)
except (GAPI.notFound, GAPI.badRequest, GAPI.forbidden) as e:
except (GAPI.notFound, GAPI.badRequest, GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId, Ent.VAULT_QUERY, queryNameId], str(e))
PRINT_VAULT_QUERIES_TITLES = ['matterId', 'matterName', 'savedQueryId', 'displayName']
@@ -41849,9 +41873,9 @@ def doPrintShowVaultQueries():
try:
results = callGAPIpages(v.matters(), 'list', 'matters',
pageMessage=getPageMessage(),
throwReasons=[GAPI.FORBIDDEN],
throwReasons=[GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
view='BASIC', state='OPEN', fields='matters(matterId,name,state),nextPageToken')
except GAPI.forbidden as e:
except (GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_QUERY, None], str(e))
return
else:
@@ -41878,12 +41902,12 @@ def doPrintShowVaultQueries():
try:
queries = callGAPIpages(v.matters().savedQueries(), 'list', 'savedQueries',
pageMessage=pageMessage,
throwReasons=[GAPI.FAILED_PRECONDITION, GAPI.FORBIDDEN],
throwReasons=[GAPI.FAILED_PRECONDITION, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, fields=fields)
except GAPI.failedPrecondition:
warnMatterNotOpen(v, matter, matterNameId, j, jcount)
continue
except GAPI.forbidden as e:
except (GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_QUERY, None], str(e))
break
else:
@@ -41970,7 +41994,7 @@ def doCreateVaultMatter():
body['name'] = f'GAM Matter - {ISOformatTimeStamp(todaysTime())}'
try:
matter = callGAPI(v.matters(), 'create',
throwReasons=[GAPI.ALREADY_EXISTS, GAPI.FORBIDDEN],
throwReasons=[GAPI.ALREADY_EXISTS, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
body=body)
matterId = matter['matterId']
matterNameId = formatVaultNameId(matter['name'], matterId)
@@ -41978,7 +42002,7 @@ def doCreateVaultMatter():
entityActionPerformed([Ent.VAULT_MATTER, matterNameId])
else:
writeStdout(f'{matterId}\n')
except (GAPI.alreadyExists, GAPI.forbidden) as e:
except (GAPI.alreadyExists, GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, body['name']], str(e))
return
jcount = len(collaborators)
@@ -41993,11 +42017,11 @@ def doCreateVaultMatter():
cbody['matterPermission']['accountId'] = collaborator['id']
try:
callGAPI(v.matters(), 'addPermissions',
throwReasons=[GAPI.FAILED_PRECONDITION, GAPI.FORBIDDEN],
throwReasons=[GAPI.FAILED_PRECONDITION, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, body=cbody)
if not returnIdOnly:
entityActionPerformed([Ent.VAULT_MATTER, matterNameId, Ent.COLLABORATOR, collaborator['email']], j, jcount)
except (GAPI.failedPrecondition, GAPI.forbidden) as e:
except (GAPI.failedPrecondition, GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId], str(e))
break
Ind.Decrement()
@@ -42021,10 +42045,10 @@ def doActionVaultMatter(action, matterId=None, matterNameId=None, v=None):
action_kwargs = {} if action == 'delete' else {'body': {}}
try:
callGAPI(v.matters(), action,
throwReasons=[GAPI.NOT_FOUND, GAPI.FAILED_PRECONDITION, GAPI.FORBIDDEN],
throwReasons=[GAPI.NOT_FOUND, GAPI.FAILED_PRECONDITION, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, **action_kwargs)
entityActionPerformed([Ent.VAULT_MATTER, matterNameId])
except (GAPI.notFound, GAPI.failedPrecondition, GAPI.forbidden) as e:
except (GAPI.notFound, GAPI.failedPrecondition, GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId], str(e))
# gam close vaultmatter|matter <MatterItem>
@@ -42077,7 +42101,7 @@ def doUpdateVaultMatter():
if 'name' not in body or 'description' not in body:
# bah, API requires name/description to be sent on update even when it's not changing
result = callGAPI(v.matters(), 'get',
throwReasons=[GAPI.NOT_FOUND, GAPI.FORBIDDEN],
throwReasons=[GAPI.NOT_FOUND, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, view='BASIC')
body.setdefault('name', result['name'])
body.setdefault('description', result.get('description'))
@@ -42085,7 +42109,7 @@ def doUpdateVaultMatter():
throwReasons=[GAPI.NOT_FOUND, GAPI.FAILED_PRECONDITION, GAPI.FORBIDDEN],
matterId=matterId, body=body)
entityActionPerformed([Ent.VAULT_MATTER, matterNameId])
except (GAPI.notFound, GAPI.failedPrecondition, GAPI.forbidden) as e:
except (GAPI.notFound, GAPI.failedPrecondition, GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId], str(e))
return
jcount = len(addCollaborators)
@@ -42098,10 +42122,10 @@ def doUpdateVaultMatter():
j += 1
try:
callGAPI(v.matters(), 'addPermissions',
throwReasons=[GAPI.FAILED_PRECONDITION, GAPI.FORBIDDEN],
throwReasons=[GAPI.FAILED_PRECONDITION, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, body={'matterPermission': {'role': 'COLLABORATOR', 'accountId': collaborator['id']}})
entityActionPerformed([Ent.VAULT_MATTER, matterNameId, Ent.COLLABORATOR, collaborator['email']], j, jcount)
except (GAPI.failedPrecondition, GAPI.forbidden) as e:
except (GAPI.failedPrecondition, GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId], str(e))
break
Ind.Decrement()
@@ -42115,10 +42139,10 @@ def doUpdateVaultMatter():
j += 1
try:
callGAPI(v.matters(), 'removePermissions',
throwReasons=[GAPI.FAILED_PRECONDITION, GAPI.FORBIDDEN],
throwReasons=[GAPI.FAILED_PRECONDITION, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, body={'accountId': collaborator['id']})
entityActionPerformed([Ent.VAULT_MATTER, matterNameId, Ent.COLLABORATOR, collaborator['email']], j, jcount)
except (GAPI.failedPrecondition, GAPI.forbidden) as e:
except (GAPI.failedPrecondition, GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId], str(e))
break
Ind.Decrement()
@@ -42151,11 +42175,11 @@ def doInfoVaultMatter():
fields = getFieldsFromFieldsList(fieldsList)
try:
matter = callGAPI(v.matters(), 'get',
throwReasons=[GAPI.NOT_FOUND, GAPI.FORBIDDEN],
throwReasons=[GAPI.NOT_FOUND, GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT],
matterId=matterId, view=view, fields=fields)
cd = buildGAPIObject(API.DIRECTORY) if 'matterPermissions' in matter else None
_showVaultMatter(matter, cd, FJQC)
except (GAPI.notFound, GAPI.forbidden) as e:
except (GAPI.notFound, GAPI.forbidden, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, matterNameId], str(e))
VAULT_MATTER_STATE_MAP = {'open': 'OPEN', 'closed': 'CLOSED', 'deleted': 'DELETED'}
@@ -42211,9 +42235,9 @@ def doPrintShowVaultMatters():
try:
matters = callGAPIpages(v.matters(), 'list', 'matters',
pageMessage=getPageMessage(),
throwReasons=[GAPI.FORBIDDEN],
throwReasons=[GAPI.FORBIDDEN, GAPI.INVALID_ARGUMENT, GAPI.INVALID_ARGUMENT],
view=view, state=stateParm, fields=fields)
except GAPI.forbidden as e:
except (GAPI.forbidden, GAPI.invalidArgument, GAPI.invalidArgument) as e:
entityActionFailedWarning([Ent.VAULT_MATTER, None], str(e))
return
jcount = len(matters)
@@ -42404,6 +42428,8 @@ class PasswordOptions():
self.makeCleanPassword = True
self.cleanPasswordLen = 25
self.randomPasswordChars = None
self.promptForPassword = False
self.promptForUniquePassword = False
self.notifyPasswordSet = False
self.updateCmd = updateCmd
self.filename = ''
@@ -42450,7 +42476,7 @@ class PasswordOptions():
self.makeCleanPassword = True
notFoundBody[up] = self.CreateRandomPassword()
self.notFoundPassword = notFoundBody[up]
elif myarg == 'lograndompassword':
elif myarg in {'lograndompassword', 'logpassword'}:
self.filename = getString(Cmd.OB_FILE_NAME)
else:
return False
@@ -42471,7 +42497,8 @@ class PasswordOptions():
password = self.GetPassword()
if password:
body[up] = password
self.makeRandomPassword = self.makeUniqueRandomPassword = False
self.makeRandomPassword = self.makeUniqueRandomPassword =\
self.promptForPassword = self.promptForUniquePassword = False
if password.lower() == 'blocklogin':
self.makeRandomPassword = True
self.makeCleanPassword = False
@@ -42484,6 +42511,13 @@ class PasswordOptions():
self.makeUniqueRandomPassword = self.makeCleanPassword = True
else:
self.makeRandomPassword = self.makeCleanPassword = True
elif password.lower() == 'prompt':
self.promptForPassword = True
elif password.lower() == 'uniqueprompt':
if self.updateCmd:
self.promptForUniquePassword = True
else:
self.promptForPassword = True
elif up == 'hashFunction':
body[up] = self.HASH_FUNCTION_MAP[myarg]
self.clearPassword = self.hashPassword = False
@@ -42506,11 +42540,17 @@ class PasswordOptions():
except Exception:
pass
def AssignPassword(self, body, notify, notFoundBody, createIfNotFound):
def AssignPassword(self, body, notify, notFoundBody, createIfNotFound, user=None):
up = 'password'
if self.makeRandomPassword or self.makeUniqueRandomPassword:
body[up] = self.CreateRandomPassword()
self.password = body[up]
elif user and (self.promptForPassword or self.promptForUniquePassword):
body[up] = readStdin(f'Enter password for {user}: ')
self.password = body[up]
elif self.promptForPassword:
body[up] = readStdin('Enter password: ')
self.password = body[up]
if up in body:
self.FinalizePassword(body, notify, up)
elif 'hashFunction' in body:
@@ -43144,7 +43184,12 @@ def getUserAttributes(cd, updateCmd, noUid=False):
body[up][schemaName][fieldName] = None
else:
unknownArgumentExit()
if not PwdOpts.makeUniqueRandomPassword:
if PwdOpts.promptForPassword or PwdOpts.promptForUniquePassword:
if not updateCmd:
PwdOpts.AssignPassword(body, notify, notFoundBody, parameters['createIfNotFound'], body['primaryEmail'])
elif not PwdOpts.promptForUniquePassword:
PwdOpts.AssignPassword(body, notify, notFoundBody, parameters['createIfNotFound'])
elif not PwdOpts.makeUniqueRandomPassword:
PwdOpts.AssignPassword(body, notify, notFoundBody, parameters['createIfNotFound'])
return (body, notify, tagReplacements, addGroups, addAliases, PwdOpts,
updatePrimaryEmail, notFoundBody, groupOrgUnitMap, parameters,
@@ -43178,7 +43223,7 @@ def createUserAddAliases(cd, user, aliasList, i, count):
# [replyto <EmailAaddress>]
# [<NotifyMessageContent>]
# (replace <Tag> <UserReplacement>)*]
# [lograndompassword <FileName>] [ignorenullpassword]
# [logpassword <FileName>] [ignorenullpassword]
# [verifynotinvitable]
# [addnumericsuffixonduplicate <Number>]
def doCreateUser():
@@ -43283,7 +43328,7 @@ def verifyUserPrimaryEmail(cd, user, createIfNotFound, i, count):
# [<NotifyMessageContent>]
# (replace <Tag> <UserReplacement>)*]
# [notifyonupdate [<Boolean>]]
# [lograndompassword <FileName>] [ignorenullpassword]
# [logpassword <FileName>] [ignorenullpassword]
def updateUsers(entityList):
def waitingForCreationToComplete(sleep_time):
writeStderr(Ind.Spaces()+Msg.WAITING_FOR_ITEM_CREATION_TO_COMPLETE_SLEEPING.format(Ent.Singular(Ent.USER), sleep_time))
@@ -43365,8 +43410,8 @@ def updateUsers(entityList):
if isInvitableUser:
entityActionNotPerformedWarning([Ent.USER, body['primaryEmail']], Msg.EMAIL_ADDRESS_IS_UNMANAGED_ACCOUNT, i, count)
continue
if PwdOpts.makeUniqueRandomPassword:
PwdOpts.AssignPassword(body, notify, notFoundBody, parameters['createIfNotFound'])
if PwdOpts.makeUniqueRandomPassword or PwdOpts.promptForUniquePassword:
PwdOpts.AssignPassword(body, notify, notFoundBody, parameters['createIfNotFound'], userKey)
retry = 0
while True:
try:
@@ -43543,14 +43588,16 @@ def undeleteUsers(entityList):
callGAPI(cd.users(), 'undelete',
throwReasons=[GAPI.DELETED_USER_NOT_FOUND, GAPI.INVALID_ORGUNIT,
GAPI.DOMAIN_NOT_FOUND, GAPI.DOMAIN_CANNOT_USE_APIS,
GAPI.FORBIDDEN, GAPI.BAD_REQUEST, GAPI.INVALID, GAPI.DUPLICATE],
GAPI.FORBIDDEN, GAPI.BAD_REQUEST, GAPI.INVALID, GAPI.DUPLICATE,
GAPI.LIMIT_EXCEEDED],
userKey=user_uid, body={'orgUnitPath': makeOrgUnitPathAbsolute(orgUnitPaths[0])})
entityActionPerformed([Ent.DELETED_USER, user], i, count)
except GAPI.deletedUserNotFound:
entityUnknownWarning(Ent.DELETED_USER, user, i, count)
except GAPI.invalidOrgunit:
entityActionFailedWarning([Ent.USER, user], Msg.INVALID_ORGUNIT, i, count)
except (GAPI.domainNotFound, GAPI.domainCannotUseApis, GAPI.forbidden, GAPI.badRequest, GAPI.invalid, GAPI.duplicate) as e:
except (GAPI.domainNotFound, GAPI.domainCannotUseApis, GAPI.forbidden, GAPI.badRequest,
GAPI.invalid, GAPI.duplicate, GAPI.limitExceeded) as e:
entityActionFailedWarning([Ent.USER, user], str(e), i, count)
# gam undelete users <UserEntity> [ou|org|orgunit <OrgUnitPath>]
@@ -44789,7 +44836,7 @@ def doPrintUsers(entityList=None):
return
sortRows = True
# If no individual fields were specified (allfields, basic, full) or individual fields other than primaryEmail were specified, look up each user
if isSuspended is not None:
if isSuspended is not None and fieldsList:
fieldsList.append('suspended')
if projectionSet or len(set(fieldsList)) > 1 or showValidColumn:
jcount = len(entityList)

View File

@@ -227,7 +227,7 @@ _INFO = {
CLOUDIDENTITY_INBOUND_SSO: {'name': 'Cloud Identity Inbound SSO API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
CLOUDIDENTITY_ORGUNITS: {'name': 'Cloud Identity OrgUnits API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
CLOUDIDENTITY_ORGUNITS_BETA: {'name': 'Cloud Identity OrgUnits API', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
CLOUDIDENTITY_POLICY: {'name': 'Cloud Identity Policy API', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
CLOUDIDENTITY_POLICY: {'name': 'Cloud Identity Policy API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
CLOUDIDENTITY_USERINVITATIONS: {'name': 'Cloud Identity User Invitations API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
CLOUDRESOURCEMANAGER: {'name': 'Cloud Resource Manager API v3', 'version': 'v3', 'v2discovery': True},
CONTACTS: {'name': 'Contacts API', 'version': 'v3', 'v2discovery': False},

View File

@@ -273,7 +273,7 @@ LOOKERSTUDIO_THROW_REASONS = [INVALID_ARGUMENT, SERVICE_NOT_AVAILABLE, BAD_REQUE
MEMBERS_THROW_REASONS = [GROUP_NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, INVALID, FORBIDDEN, SERVICE_NOT_AVAILABLE]
MEMBERS_RETRY_REASONS = [SYSTEM_ERROR, SERVICE_NOT_AVAILABLE]
ORGUNIT_GET_THROW_REASONS = [INVALID_ORGUNIT, ORGUNIT_NOT_FOUND, BACKEND_ERROR, BAD_REQUEST, INVALID_CUSTOMER_ID, LOGIN_REQUIRED]
PEOPLE_ACCESS_THROW_REASONS = [SERVICE_NOT_AVAILABLE, FORBIDDEN, PERMISSION_DENIED]
PEOPLE_ACCESS_THROW_REASONS = [SERVICE_NOT_AVAILABLE, FORBIDDEN, PERMISSION_DENIED, FAILED_PRECONDITION]
RESELLER_THROW_REASONS = [BAD_REQUEST, RESOURCE_NOT_FOUND, FORBIDDEN, INVALID]
SHEETS_ACCESS_THROW_REASONS = DRIVE_USER_THROW_REASONS+[NOT_FOUND, PERMISSION_DENIED, FORBIDDEN, INTERNAL_ERROR, INSUFFICIENT_FILE_PERMISSIONS,
BAD_REQUEST, INVALID, INVALID_ARGUMENT, FAILED_PRECONDITION]

View File

@@ -504,7 +504,9 @@ To set up Google Chat for your API project, please go to:
{0}
and complete all fields.
and follow the instructions at:
https://github.com/GAM-team/GAM/wiki/Chat-Bot#set-up-a-chat-bot
"""
TOTAL_ITEMS_IN_ENTITY = 'Total {0} in {1}'
TRIMMED_MESSAGE_FROM_LENGTH_TO_MAXIMUM = 'Trimmed message of length {0} to maximum length {1}'