Compare commits

..

111 Commits

Author SHA1 Message Date
Ross Scroggs
0562639715 Added additional options to gam <UserTypeEntity> print|show youtubechannels. 2023-11-22 20:36:43 -08:00
Ross Scroggs
51de288f27 Added option sizefield quotabytesused|size to file display commands
Fixed bug in gam <UserTypeEntity> copy|move drivefile` that caused a trap.
2023-11-22 08:56:30 -08:00
Ross Scroggs
7cfb16c1f5 dditional updates on MacOS when a gam csv command is interrupted with a contol-C. 2023-11-18 14:22:38 -08:00
Ross Scroggs
f0cddbe7c2 Fixed bug in `gam print|show crostelemetry
Updated multiprocessing to handle the following error that occurs on MacOS when a `gam csv` command
is interrupted with a contol-C.

It's a pyinstaller issue, revert to 5.13.2 for Mac OS
2023-11-18 08:49:28 -08:00
Ross Scroggs
06840c2608 Two fixes
Updated multiprocessing to handle the following error that occurs on MacOS when a `gam csv` command
is interrupted with a contol-C.
```
multiprocessing/resource_tracker.py:224: UserWarning: resource_tracker: There appear to be N leaked semaphore objects to clean up at shutdown
```

Fixed bug in `gam print crostelemetry` that caused a trap: `KeyError: 'reportTime'`.
2023-11-17 11:12:29 -08:00
Ross Scroggs
87db64897d Ignore github/Google time offset errors 2023-11-16 08:01:31 -08:00
Ross Scroggs
683d47175b Added option noduplicate to gam <UserTypeEntity> create drivefile 2023-11-15 18:27:12 -08:00
Ross Scroggs
fac8c11798 Updated gam <UserTypeEntity> get drivefile <DriveFileEntity>
to handle the following error
that seems to occur when multiple tabs from a Google sheet are being downloaded in parallel.
```
Download Failed: HTTP Error: 429
```
2023-11-13 16:59:11 -08:00
Ross Scroggs
b5f5291e14 Added options to gam report <ActivityApplicationName>
`addcsvdata <FieldName> <String>`
`shownoactivities`
2023-11-11 17:11:18 -08:00
Ross Scroggs
194b93a7ee Updated gam delete building to handle the following error:
ERROR: 412: conditionNotMet - Cannot delete building because there are Calendar resources associated with it.
2023-11-07 19:17:00 -08:00
Ross Scroggs
55099e6835 Improved error message when trying to add external students/teachers to a course. 2023-11-03 14:40:56 -07:00
Ross Scroggs
4a199c7b6f Multiple updates 2023-11-03 08:52:05 -07:00
Ross Scroggs
3facd05a94 SKU fix and update 2023-10-25 13:11:17 -07:00
Ross Scroggs
bb443be367 Fixed bug in commands that display calendar events where event start and end times were not properly displayed 2023-10-24 21:21:21 -07:00
GitHub Action
1952aa2026 [ci skip] Updated cacerts.pem 2023-10-23 23:24:19 +00:00
Ross Scroggs
d206ac4518 Handle service not available when listing cros 2023-10-21 06:46:14 -07:00
Ross Scroggs
6b19ba1933 Updated gam print|show browsers to handle the following error:
ERROR: 503: serviceNotAvailable - The service is currently unavailable.
2023-10-20 19:32:36 -07:00
Ross Scroggs
bcf9c051f0 Try to fix build errors 2023-10-20 16:42:06 -07:00
Ross Scroggs
4934809b88 Add showmimetypesize to print filelist/filecounts 2023-10-20 14:35:45 -07:00
Ross Scroggs
55298f0134 Two updates
Fixed bug in `gam <UserTypeEntity> create contact <JSONData>` that caused a trap when
contacts were being copied from one user to another.

Updated the commands to allow specification of a task list by its title.
2023-10-19 08:14:03 -07:00
Ross Scroggs
7e9207ae3c Fixed bug in gam <UserTypeEntity> create task <TasklistIDEntity> 2023-10-17 20:25:24 -07:00
Ross Scroggs
7915f97bd5 Updated lookerstudioassets|lookerstudiopermissions commands to handle the following error:
ERROR: 500: internalError - Internal error encountered.
2023-10-13 11:36:44 -07:00
Ross Scroggs
1231627412 More info chromeapp cleanup 2023-10-12 12:33:14 -07:00
Ross Scroggs
40977cedc7 Cleaned up and renamed gam info appdetails to gam info chromeapp. 2023-10-12 12:14:14 -07:00
Ross Scroggs
d500196dee Added command to get customer app details. 2023-10-12 09:03:03 -07:00
Jay Lee
994d489226 actions: remove errant ) 2023-10-11 13:25:51 -04:00
Jay Lee
602c47a900 actions: pin win to python 3.11.6 2023-10-11 13:10:29 -04:00
Jay Lee
de4315b4b7 actions: revert pyinstaller on Win 2023-10-11 12:20:43 -04:00
Ross Scroggs
9bbdae6986 Added support for Google Workspace Labs license (for real) 2023-10-11 07:55:11 -07:00
Ross Scroggs
c7899ba401 Merge branch 'main' of https://github.com/GAM-team/GAM 2023-10-11 07:28:36 -07:00
Ross Scroggs
4b9a8cc235 Added support for Google Workspace Labs license. 2023-10-11 07:22:46 -07:00
Jay Lee
4ae5cdee83 actions: forward slashes 2023-10-11 09:40:49 -04:00
Jay Lee
1393ed3ca6 actions: attempt windows fix 2023-10-11 09:38:20 -04:00
Jay Lee
6ec24c87cd Create openssl.props 2023-10-11 08:43:00 -04:00
Jay Lee
a404311097 [no ci] actions: revert openssl.props copy 2023-10-11 08:41:38 -04:00
Jay Lee
a7d8260de5 [no ci] actions: test python 3.11 2023-10-10 16:41:19 -04:00
Jay Lee
63fe8b53f9 Delete src/tools/openssl.props 2023-10-10 16:28:18 -04:00
Jay Lee
4ad4711b84 [no ci] actions: pyinstaller 5.3.2 for staticx, no openssl.props needed 2023-10-10 16:06:33 -04:00
Ross Scroggs
f13625719b Merge branch 'main' of https://github.com/GAM-team/GAM 2023-10-10 11:26:24 -07:00
Ross Scroggs
5ae29742ce Fixed bug introduced in 6.64.09 that caused a trap when gam redirect csv <FileName> multiprocess was used. 2023-10-10 11:25:57 -07:00
Jay Lee
ec6f36cf82 actions: disable sso assignment for now 2023-10-10 13:58:54 -04:00
Ross Scroggs
c18cf75b4f Cleaned up print filelist when there are no rows to print 2023-10-10 07:21:38 -07:00
Ross Scroggs
7b6673b43b Fixed bug in redirect csv - todrive tdtitle "File Title" tdsheettitle "Sheet Title" where "Sheet Title" was not assigned to the new sheet. 2023-10-06 10:42:17 -07:00
Ross Scroggs
d1dea2593f Updated gam <UserTypeEntity> move drivefile to handle the following error:
ERROR: 403: targetUserRoleLimitedByLicenseRestriction - Cannot set the requested role for that user as they lack the necessary license
2023-10-04 09:36:28 -07:00
Ross Scroggs
aebec7fa94 Added fields devicelicensetype and osupdatestatus to <CrOSFieldName>. 2023-10-03 13:43:01 -07:00
Ross Scroggs
7f79bf0e87 Added matchfield organizerself <Boolean> to <EventMatchProperty> 2023-10-03 08:34:37 -07:00
Ross Scroggs
0e0d45322e Updated gam calendars <CalendarEntity> move events
to handle the following error:
```
ERROR: 400: badRequest - Bad Request
2023-10-01 11:47:41 -07:00
Ross Scroggs
b7f572149f Updated gam <UserTypeEntity> get drivefile to allow downloading Jamboard files 2023-09-28 13:00:57 -07:00
Ross Scroggs
b07bd82f60 Updated gam <UserTypeEntity> print|show youtubechannels to handle the following error:
ERROR: 403: unsupportedSupervisedAccount - Access Forbidden. The authenticated user cannot access this service.
2023-09-27 16:48:31 -07:00
Ross Scroggs
086c7469c5 Added support for displaying users YouTube channels.
Pyinstaller 6.0.0 causes errors. You can tweak build.yml to revert to 5.13.2
2023-09-26 21:10:52 -07:00
Ross Scroggs
37a968a142 Fix typo 2023-09-25 09:48:04 -07:00
Ross Scroggs
dab05fb5c5 Fixed bug in gam print vacation where endDate value was not converted to yyyy-mm-dd format. 2023-09-22 07:14:57 -07:00
Ross Scroggs
115dde8c2f Updated gam print|show ownership to show the correct file owner when the most recent event is change_owner. 2023-09-20 15:24:20 -07:00
Ross Scroggs
38c78228aa Multiple changes
Added support for Duet AI license.

Added `api_call_tries_limit` variable to `gam.cfg` that limits the number of tries
for Google API calls that return an error that indicates a retry should be performed. The default value is 10 and the range of allowable values is 3-10.

Code cleanup for retry loops

Initial (not announced, in preview mode) code for Chat API support of group members and role management

Allow spaces/xxx and space/xxx when specifying chat spaces
2023-09-20 11:26:16 -07:00
Ross Scroggs
9999abe462 Update OU inheritance options 2023-09-17 16:46:31 -07:00
Ross Scroggs
d16ce28ee5 Multiple updates 2023-09-15 19:44:26 -07:00
Ross Scroggs
effa972a40 Updated print aliases|groups|group-members|users
Added option `verifyorganizer [<Boolean>]` to `gam <UserTypeEntity> copy|move drivefile`
2023-09-13 13:45:10 -07:00
Jay Lee
e998bcfde6 Python 3.12 fix for six no longer needed 2023-09-12 10:11:25 -04:00
Ross Scroggs
c9023d4792 Show actual Shared Drive names for drives in other domains 2023-09-07 21:15:08 -07:00
Ross Scroggs
c30931545f Added option showdeleted [<Boolean>]' to gam <UserTypeEntity> print|show chatmessages`.
Updated commands that call the Reports API (including `gam info domain`) to handle a change
in the Reports API that generated the following warning:
```
WARNING: End date greater than LastReportedDate.
2023-09-07 09:03:00 -07:00
Ross Scroggs
ed62abe464 Added option ou_and_children <OrgUnitItem> to gam print|show crostelemetry 2023-09-04 20:04:41 -07:00
Ross Scroggs
34e42a1076 Added option addcsvdata <FieldName> <String> to commands that print calendar acsl 2023-09-03 19:16:56 -07:00
Jay Lee
451d945095 temp show body on sso assignment for debugging purposes 2023-09-01 14:35:10 +00:00
Ross Scroggs
cfb44548ab Added commands to show the number of CrOS devices or Users in an entity.
Updated `gam create project` to prompt user to mark `GAM Project Creation` as a trusted app.
2023-08-31 13:27:49 -07:00
Ross Scroggs
c6de3de370 Updated gam create teamdrive to handle the following error:
ERROR: 403: userCannotCreateTeamDrives - The authenticated user cannot create new shared drives.
2023-08-30 08:04:01 -07:00
Ross Scroggs
59b653f92a 6.63.08 updates 2023-08-29 16:20:21 -07:00
Ross Scroggs
b509e35cd1 Updated cigroup commands to handle the following error:
ERROR: 400: invalidArgument - Request contains an invalid argument.
2023-08-29 16:19:16 -07:00
Ross Scroggs
079553e8bb Update Users-Drive-Files-Manage.md 2023-08-28 19:17:33 -07:00
Ross Scroggs
220cbbac80 Fixed bug in gam <UserTypeEntity> append sheetrange that caused a trap 2023-08-26 07:56:59 -07:00
Ross Scroggs
6993137430 Fixed bug in gam <UserTypeEntity> append sheetrange that caused a trap
Upgraded to Python 3.11.5 where possible.
2023-08-25 21:18:15 -07:00
Jay Lee
d0a378413f actions: rebuild for Python 3.11.5 2023-08-25 13:28:58 -04:00
Ross Scroggs
c314637847 Updated cigroup commands to handle the following error:
ERROR: 503: serviceNotAvailable - The service is currently unavailable.
2023-08-24 09:55:19 -07:00
Ross Scroggs
219e9ee8da Updated inboundsso commands to handle the following error:
ERROR: 503: serviceNotAvailable - The service is currently unavailable.
2023-08-23 22:10:54 -07:00
Ross Scroggs
d47268f45c Revert "Made serviceNotAvailable retryable"
This reverts commit d5eef1faf5.
2023-08-23 21:39:23 -07:00
Ross Scroggs
d5eef1faf5 Made serviceNotAvailable retryable 2023-08-23 20:46:05 -07:00
Ross Scroggs
a7097a7310 Added option ignorerole to gam update groups|cigroups <GroupEntity> sync [<GroupRole>|ignorerole] ... <UserTypeEntity> 2023-08-23 15:43:43 -07:00
Ross Scroggs
0335ea7056 Documentation updates 2023-08-23 08:25:05 -07:00
Ross Scroggs
71777652cf Documentation updates 2023-08-22 09:55:20 -07:00
Ross Scroggs
7a91faab2b indentation cleanup 2023-08-21 16:38:40 -07:00
Ross Scroggs
ed073877a6 Merge branch 'main' of https://github.com/GAM-team/GAM 2023-08-21 16:10:25 -07:00
Ross Scroggs
8a46365f51 Allow external members in chat spaces 2023-08-21 16:10:21 -07:00
Jay Lee
04fded6d94 remove failing tests 2023-08-21 18:35:35 +00:00
Jay Lee
15670fc7c4 backout urllib3 shim changes until google-auth supports urllib3 2.0+ 2023-08-21 15:02:27 +00:00
Jay Lee
cf27d4d9cc Merge branch 'main' of https://github.com/GAM-team/GAM 2023-08-21 14:22:15 +00:00
Jay Lee
48c30dc266 switch to modern urllib3 via a shim 2023-08-21 14:21:59 +00:00
Ross Scroggs
d2430323b2 Fixed bug in gam <UserTypeEntity> collect orphans where shortcuts were being created unnecessarily 2023-08-20 13:57:18 -07:00
Ross Scroggs
2a38699595 Fix bug/typo 2023-08-19 08:26:32 -07:00
Ross Scroggs
e76b71e245 Added process_wait_limit variable to gam.cfg 2023-08-18 15:40:00 -07:00
Jay Lee
92174438f6 TLS 1.2 on IAM credentials api call also 2023-08-18 19:16:33 +00:00
Jay Lee
0c85abf074 actions: allow TLS 1.2 to see if it fixes Python 3.12 2023-08-18 15:00:41 -04:00
Jay Lee
e9ea536aaf debug stepping to figure out where we die... 2023-08-18 18:49:38 +00:00
Jay Lee
d2bbbb3b73 Merge branch 'main' of https://github.com/GAM-team/GAM 2023-08-18 18:44:05 +00:00
Jay Lee
6735c361a4 use TLS 1.2 with WIF and Github Actions 2023-08-18 18:43:48 +00:00
Ross Scroggs
1243ece157 Use writeStdout so redirect stdout catches data; update documentation 2023-08-18 11:37:55 -07:00
Ross Scroggs
7573013da4 Merge branch 'main' of https://github.com/GAM-team/GAM 2023-08-18 10:43:16 -07:00
Ross Scroggs
b79c48718e pylint cleanup; fix broken links 2023-08-18 10:43:13 -07:00
Jay Lee
8354c63a62 Merge branch 'main' of https://github.com/GAM-team/GAM 2023-08-18 17:38:04 +00:00
Jay Lee
c163d9ac46 output signjwt data for troubleshooting 2023-08-18 17:37:48 +00:00
Jay Lee
dcf63e203a actions: expect no tests to run (exit code 5) 2023-08-18 11:22:17 -04:00
Jay Lee
8fb01205ea gdata: cleanup some regex 2023-08-18 15:14:28 +00:00
Jay Lee
3e85b268a0 actions: get create contact command right (maybe) 2023-08-18 14:30:17 +00:00
Jay Lee
78d93428f2 actions: fix contacts filter 2023-08-18 14:20:25 +00:00
Jay Lee
4454e55b1e GData reduction, security recs for regex 2023-08-18 14:12:00 +00:00
Jay Lee
f1229fe8ce Set flag to honor admin console conflict account resolution setting by default 2023-08-17 12:24:40 +00:00
Ross Scroggs
09581ae654 Added support for calendar working location events. 2023-08-16 19:26:03 -07:00
Jay Lee
03fd8c296d actions: upgrade google-auth libraries to ToT for Python 3.12 2023-08-16 21:30:37 -04:00
Ross Scroggs
155c29cc55 Fix typo 2023-08-16 07:26:08 -07:00
Ross Scroggs
a017621a3d Added support for alternative output when creating contacts 2023-08-15 07:58:23 -07:00
Jay Lee
bea1c1c22d actions: reenable Python 3.12 2023-08-13 11:31:40 -04:00
Ross Scroggs
02c7628840 Wiki cleanup 2023-08-11 16:28:30 -07:00
Ross Scroggs
b5a9f302df Added output Item cap to gam <UserTypeEntity> print filecounts select select <SharedDriveEntity> 2023-08-11 13:26:50 -07:00
159 changed files with 5815 additions and 15907 deletions

View File

@@ -86,11 +86,11 @@ jobs:
python: "3.10"
jid: 11
arch: x86_64
#- os: ubuntu-22.04
# goal: test
# python: "3.12"
# jid: 12
# arch: x86_64
- os: ubuntu-22.04
goal: test
python: "3.11"
jid: 12
arch: x86_64
steps:
@@ -114,7 +114,7 @@ jobs:
path: |
bin.tar.xz
src/cpython
key: gam-${{ matrix.jid }}-20230801
key: gam-${{ matrix.jid }}-202311118
- name: Untar Cache archive
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit == 'true'
@@ -342,7 +342,12 @@ jobs:
cd "${GITHUB_WORKSPACE}/src"
git clone https://github.com/python/cpython.git
cd "${PYTHON_SOURCE_PATH}"
# Pin Windows to 3.11.6 for the moment
# if [[ "${RUNNER_OS}" == "Windows" ]]; then
# export LATEST_STABLE_TAG="v3.11.6"
# else
export LATEST_STABLE_TAG=$(git tag --list | grep -v a | grep -v rc | grep -v b | sort -Vr | head -n1)
# fi
git checkout "${LATEST_STABLE_TAG}"
export COMPILED_PYTHON_VERSION=${LATEST_STABLE_TAG:1} # Trim the "v" prefix
echo "COMPILED_PYTHON_VERSION=${COMPILED_PYTHON_VERSION}" >> $GITHUB_ENV
@@ -479,7 +484,16 @@ jobs:
git clone https://github.com/pyinstaller/pyinstaller.git
cd pyinstaller
export latest_release=$(git tag --list | grep -v dev | grep -v rc | sort -Vr | head -n1)
git checkout "${latest_release}"
#V6.0.0 causes errors on staticx
if [[ "${staticx}" == "yes" ]]; then
git checkout "v5.13.2"
elif [[ "${RUNNER_OS}" == "Windows" ]]; then
git checkout "v5.13.2"
elif [[ "${RUNNER_OS}" == "macOS" ]]; then
git checkout "v5.13.2"
else
git checkout "${latest_release}"
fi
# remove pre-compiled bootloaders so we fail if bootloader compile fails
rm -rvf PyInstaller/bootloader/*-*/*
cd bootloader
@@ -526,6 +540,7 @@ jobs:
export distpath="./dist/gam"
export gampath="${distpath}"
"${PYTHON}" -m PyInstaller --clean --noconfirm --distpath="${distpath}" gam.spec
cat build/gam/warn-gam.txt
- name: Copy extra package files
if: matrix.goal == 'build'
@@ -563,8 +578,8 @@ jobs:
- name: Basic Tests all jobs
id: basictests
run: |
$PYTHON -m unittest discover --start-directory ./ --pattern "*_test.py" --buffer
$gam version extended
$PYTHON -m unittest discover --start-directory ./ --pattern "*_test.py" --buffer || if [ $? != 5 ]; then exit $?; fi # exit 5 is no tests
$gam version extended nooffseterror
export GAMVERSION=$($gam version simple)
echo "GAM Version ${GAMVERSION}"
echo "GAMVERSION=${GAMVERSION}" >> $GITHUB_ENV
@@ -598,7 +613,7 @@ jobs:
- name: Basic Tests build jobs only
if: matrix.goal != 'test' && steps.cache-python-ssl.outputs.cache-hit != 'true'
run: |
export voutput=$($gam version extended)
export voutput=$($gam version extended nooffseterror)
export python_line=$(echo -e "${voutput}" | grep "Python ")
export python_arr=($python_line)
export this_python=${python_arr[1]}
@@ -660,7 +675,8 @@ 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}"
export GAM_THREADS=5
@@ -679,6 +695,8 @@ jobs:
$gam user $gam_user sendemail recipient $newuser subject "test message $newbase" message "GHA test message"
$gam user $gam_user sendemail recipient exchange@pdl.jaylee.us subject "test ${tstamp}" message "test message"
$gam config enable_dasa false save
$gam create contact firstname GHA lastname "$JID" email work "${newbase}@example.com" primary
$gam print contacts
$gam user $newuser add license workspaceenterpriseplus
$gam print privileges
$gam config enable_dasa true save
@@ -776,6 +794,7 @@ jobs:
$gam create device serialnumber $sn devicetype android
$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
@@ -803,8 +822,8 @@ jobs:
echo "printer model count:"
ssoprofile=$($gam create inboundssoprofile name "El Goog ${newbase}" loginurl https://www.google.com logouturl https://www.google.com changepasswordurl https://www.google.com entityid ElGoog return_name_only)
$gam create inboundssocredential profile "id:${ssoprofile}" generate_key
$gam create inboundssoassignment profile "id:${ssoprofile}" orgunit "${newou}" mode SAML_SSO
$gam delete inboundssoassignment "orgunit:${newou}"
#$gam create inboundssoassignment profile "id:${ssoprofile}" orgunit "${newou}" mode SAML_SSO
#$gam delete inboundssoassignment "orgunit:${newou}"
$gam delete inboundssoprofile "id:${ssoprofile}"
$gam print printermodels | wc -l
$gam print printers

View File

@@ -8,6 +8,7 @@
- [Create an administrator](#create-an-administrator)
- [Delete an administrator](#delete-an-administrator)
- [Display administrators](#display-administrators)
- [Copy roles from one administrator to another](#copy-roles-from-one-administrator-to-another)
## Administrator roles documentation
* https://support.google.com/a/answer/33325?ref_topic=4514341
@@ -856,6 +857,7 @@ gam show adminroles|roles [todrive <ToDriveAttribute>*] [privileges]
* `privileges` - Display privileges associated with each role
## Create an administrator
Add an administrator role to an administrator.
```
gam create admin <EmailAddress>|<UniqueID> <RoleItem> customer|(org_unit <OrgUnitItem>)
[condition securitygroup|nonsecuritygroup]
@@ -868,6 +870,7 @@ The option `condition` limits the conditions for delegate admin access. This cur
* `condition nonsecuritygroup` - limit the delegated admin to managing non-security groups
## Delete an administrator
Remove an administrator role from an administrator.
```
gam delete admin <RoleAssignmentId>
```
@@ -888,3 +891,15 @@ options to limit the display:
In versions prior to 6.07.01, specification of both `user <UserItem>`
and `role <RoleItem>` generated no output due to an undocumented API rule that disallows both.
## Copy roles from one administrator to another
Get roles for current admin.
```
gam redirect csv ./CurrentAdminRoles.csv print admins user currentadmin@domain.com
```
Add roles to new admin.
```
gam config csv_input_row_filter "scopeType:regex:CUSTOMER" redirect stdout ./UpdateNewAdminCustomerRoles.txt multiprocess redirect stderr stdout csv CurrentAdminRoles.csv gam create admin newadmin@domain.com "id:~~roleId~~" customer
gam config csv_input_row_filter "scopeType:regex:ORG_UNIT" redirect stdout ./UpdateNewAdminOrgUnitRoles.txt multiprocess redirect stderr stdout csv CurrentAdminRoles.csv gam create admin newadmin@domain.com "id:~~roleId~~" org_unit "id:~~orgUnitId~~"
```

View File

@@ -21,11 +21,16 @@
* https://developers.google.com/admin-sdk/directory/v1/guides/search-users
## Definitions
See [Collections of Items](Collections-of-Items)
```
<DomainName> ::= <String>(.<String>)+
<DomainNameList> ::= "<DomainName>(,<DomainName>)*"
<DomainNameEntity> ::=
<DomainNameList> | <FileSelector> | <CSVFileSelector>
<EmailAddress> ::= <String>@<DomainName>
<EmailAddressList> ::= "<EmailAddress>(,<EmailAddress>)*"
<EmailAddressEntity> ::= <EmailAddressList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<UniqueID> ::= id:<String>
```
## Create an alias for a target
@@ -83,7 +88,8 @@ gam info alias|aliases <EmailAddressEntity>
Display selected aliases.
```
gam print aliases [todrive <ToDriveAttribute>*]
[domain <DomainName>] [(query <QueryUser>)|(queries <QueryUserList>)]
([domain|domains <DomainNameEntity>] [(query <QueryUser>)|(queries <QueryUserList>)]
[limittoou <OrgUnitItem>])
[user|users <EmailAddressList>] [group|groups <EmailAddressList>]
[select <UserTypeEntity>]
[aliasmatchpattern <RegularExpression>]
@@ -93,8 +99,10 @@ gam print aliases [todrive <ToDriveAttribute>*]
(addcsvdata <FieldName> <String>)*
```
By default, group and user aliases in all domains in the account are selected; these options allow selection of subsets of aliases:
* `domain <DomainName>` - Limit aliases to those in `<DomainName>`
* `(query <QueryUser>)|(queries <QueryUserList>)` - Print aliases for selected users
* `domain|domains <DomainNameEntity>` - Limit aliases to those in the domains specified by `<DomainNameEntity>`
* You can predefine this list with the `print_agu_domains` variable in `gam.cfg`.
* `(query <QueryUser>)|(queries <QueryUserList>)` - Print aliases for users/groups that match a query; each query is run against each domain
* `limittoou <OrgUnitItem>` - Print aliases for users in the specified `<OrgUnitItem>`
* `user|users <EmailAddressList>` - Print aliases for users in `<EmailAddressList`
* `select <UserTypeEntity>` - Print aliases for users in `<UserTypeEntity>`
* `group|groups <EmailAddressList>` - Print aliases for groups in `<EmailAddressList`
@@ -116,6 +124,21 @@ By default, the aliases in a list are separated by the `csv_output_field_delimit
Specifying both `onerowpertarget` and `suppressnoaliasrows` causes GAM to not display any targets that have no aliases.
When multiple domains are specified and a query/queries are specified, an API call is made for each domain/query combination.
```
$ gam print aliases domains school.org,students.school.org queries "'email:admin*','email:test*'"
Getting all Users that match query (domain=school.org, query="email:admin*"), may take some time on a large Google Workspace Account...
Got 3 Users: admin@school.org - admindirector@school.org
Getting all Users that match query (domain=school.org, query="email:test*"), may take some time on a large Google Workspace Account...
Got 20 Users: testusera@school.org - testuserx@school.org
Getting all Users that match query (domain=students.school.org, query="email:admin*"), may take some time on a large Google Workspace Account...
Got 1 User: admin@students.school.org - admin@students.school.org
Getting all Users that match query (domain=students.school.org, query="email:test*"), may take some time on a large Google Workspace Account...
Got 1 User: testuser1@students.school.org - testuser1@students.school.org
Alias,Target,TargetType
...
```
## Bulk delete aliases
You can bulk delete aliases as follows; use `(query <QueryUser>)|(queries <QueryUserList>)` and
`aliasmatchpattern <RegularExpression>` as desired.

View File

@@ -161,6 +161,7 @@ gam oauth update
<ProjectIDEntity> ::=
current | gam | <ProjectID> | (filter <String>) |
(select <ProjectIDList> | <FileSelector> | <CSVFileSelector>)
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<ProjectName> ::= <String>
Must match this Python Regular Expression: [a-zA-Z0-9 '"!-]{4,30}
<ServiceAccountName> ::= <String>
@@ -230,6 +231,16 @@ gam create gcpfolder [admin <EmailAddress] folder <String>
Create a new project to create and download two files: `client_secrets.json` for the Client and `oauth2service.json` for the Service Account.
On-screen instructions lead you through the process.
An existing project, `GAM Project Creation`, is used to create your GAM project. The initial instructions tell you how to
enable this project as a trusted app as your workspace may not allow untrusted third-party apps.
This is recommended but not mandatory unless your workspace has "Google Cloud" service restricted:
* https://support.google.com/a/answer/7281227?hl=en#zippy=%2Crestrict-or-unrestrict-google-services
If it is restricted and you complete this step it may take an hour or so to take full affect and allow you to approve GAM project creation.
The final instructions tell you how to enable your new GAM project as a trusted app as your workspace may not allow untrusted third-party apps.
You can skip these steps if you know that untrusted third-party apps are allowed.
### Default values
* `<AppName>` - "GAM"
* `<ProjectID>` - "gam-project-abc-def-jki" where "abc-def-ghi" are randomly generated
@@ -920,7 +931,7 @@ This will prevent the limited user from having any client access.
Perform these steps:
Create a a new service account in your project that will be used for the limited user;
this will create `outh2service.json`.
this will create `oauth2service.json`.
```
gam add svcacct saname "gam-limited" sadisplayname "GAM Limited"
```

View File

@@ -16,44 +16,7 @@
<FalseValues>= false|off|no|disabled|0
<TrueValues> ::= true|on|yes|enabled|1
<Charset> ::= ascii|latin1|mbcs|utf-8|utf-8-sig|utf-16|<String>
<CalendarColorIndex> ::= <Number in range 1-24>
<CalendarColorName> ::=
amethyst|avocado|banana|basil|birch|blueberry|
cherryblossom|citron|cobalt|cocoa|eucalyptus|flamingo|
grape|graphite|lavender|mango|peacock|pistachio|
pumpkin|radicchio|sage|tangerine|tomato|wisteria|
<ColorHex> ::= "#<Hex><Hex><Hex><Hex><Hex><Hex>"
<ColorNameGoogle> ::=
asparagus|bluevelvet|bubblegum|cardinal|chocolateicecream|denim|desertsand|
earthworm|macaroni|marsorange|mountaingray|mountaingrey|mouse|oldbrickred|
pool|purpledino|purplerain|rainysky|seafoam|slimegreen|spearmint|
toyeggplant|vernfern|wildstrawberries|yellowcab
<ColorNameWeb> ::=
aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|
blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|
cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|
darkgrey|darkgreen|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|
darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|
darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|
firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|
gray|grey|green|greenyellow|honeydew|hotpink|indianred|indigo|ivory|khaki|
lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|
lightgoldenrodyellow|lightgray|lightgrey|lightgreen|lightpink|lightsalmon|
lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|
lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|
mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|
mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|
navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|
palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|
peru|pink|plum|powderblue|purple|red|rosybrown|royalblue|saddlebrown|salmon|
sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|
slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|
wheat|white|whitesmoke|yellow|yellowgreen
<ColorName> ::= <ColorNameGoogle>|<ColorNameWeb>
<ColorValue> ::= <ColorName>|<ColorHex>
<DayOfWeek> ::= mon|tue|wed|thu|fri|sat|sun
<DriveLabelLanguageCode> ::=
<BCP47LanguageCode> ::=
ar-sa| # Arabic Saudi Arabia
cs-cz| # Czech Czech Republic
da-dk| # Danish Denmark
@@ -91,6 +54,43 @@
zh-cn| # Chinese China
zh-hk| # Chinese Hong Kong
zh-tw # Chinese Taiwan
<Charset> ::= ascii|latin1|mbcs|utf-8|utf-8-sig|utf-16|<String>
<CalendarColorIndex> ::= <Number in range 1-24>
<CalendarColorName> ::=
amethyst|avocado|banana|basil|birch|blueberry|
cherryblossom|citron|cobalt|cocoa|eucalyptus|flamingo|
grape|graphite|lavender|mango|peacock|pistachio|
pumpkin|radicchio|sage|tangerine|tomato|wisteria|
<ColorHex> ::= "#<Hex><Hex><Hex><Hex><Hex><Hex>"
<ColorNameGoogle> ::=
asparagus|bluevelvet|bubblegum|cardinal|chocolateicecream|denim|desertsand|
earthworm|macaroni|marsorange|mountaingray|mountaingrey|mouse|oldbrickred|
pool|purpledino|purplerain|rainysky|seafoam|slimegreen|spearmint|
toyeggplant|vernfern|wildstrawberries|yellowcab
<ColorNameWeb> ::=
aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|
blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|
cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|
darkgrey|darkgreen|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|
darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|
darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|
firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|
gray|grey|green|greenyellow|honeydew|hotpink|indianred|indigo|ivory|khaki|
lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|
lightgoldenrodyellow|lightgray|lightgrey|lightgreen|lightpink|lightsalmon|
lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|
lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|
mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|
mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|
navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|
palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|
peru|pink|plum|powderblue|purple|red|rosybrown|royalblue|saddlebrown|salmon|
sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|
slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|
wheat|white|whitesmoke|yellow|yellowgreen
<ColorName> ::= <ColorNameGoogle>|<ColorNameWeb>
<ColorValue> ::= <ColorName>|<ColorHex>
<DayOfWeek> ::= mon|tue|wed|thu|fri|sat|sun
<EventColorIndex> ::= <Number in range 1-11>
<EventColorName> ::=
banana|basil|blueberry|flamingo|graphite|grape|
@@ -211,6 +211,7 @@
gfolder|gdirectory|
gform|
gfusion|
gjam|
gmap|
gpresentation|
gscript|
@@ -371,12 +372,6 @@
<CourseWorkState> ::= draft|published|deleted
<CrOSID> ::= <String>
<CustomerID> ::= <String>
<DataStudioAssetID> ::= <String>
<DataStudioPermission> ::=
user:<EmailAddress>|
group:<EmailAddress>|
domain:<DomainName>|
serviceAccount:<EmailAddress>
<DeliverySetting> ::=
allmail|
abridged|daily|
@@ -452,6 +447,12 @@
<LabelID> ::= Label_<String>
<LabelName> ::= <String>
<LabelReplacement> ::= <String>
<LookerStudioAssetID> ::= <String>
<LookerStudioPermission> ::=
user:<EmailAddress>|
group:<EmailAddress>|
domain:<DomainName>|
serviceAccount:<EmailAddress>
<Marker> ::= <String>
<MatterItem> ::= <UniqueID>|<String>
<MatterState> ::= open|closed|deleted
@@ -570,6 +571,7 @@
<TakeoutBucketName> ::= takeout-export-[a-f,0-9,-]*
<TaskID> ::= <String>
<TaskListID> ::= <String>
<TaskListTitle> ::= tltitle:<String>
<TasklistIDTaskID> ::= <TasklistID>/<TaskID>
<ThreadID> ::= <String>
<TimeZone> ::= <String>
@@ -611,4 +613,5 @@
(file|textfile|htmlfile <FileName> [charset <Charset>])|
(gdoc|ghtml <UserGoogleDoc>)|
(gcsdoc|gcshtml <StorageBucketObjectName>)
<YouTubeChannelID> ::= <String>
```

View File

@@ -171,32 +171,39 @@ primaryEmail,externalIds,externalIds.0.type,externalIds.0.value,externalIds.1.ty
You can include rows generated by gam print commands based on column values. You specify a list
of fields (headers) and the values they must have. `csv_output_row_filter` is used to specify the
fields and values. Each field name/expression can appear only once in the list.
You specify whether all or any value filters must match for the row to be included in the output.
* `csv_output_row_filter_mode allmatch` - All value filters must match for the row to be included in the output; this is the default
* `csv_output_row_filter_mode anymatch` - Any value filter must match for the row to be included in the output
```
gam config csv_output_row_filter <RowValueFilterList> ...
gam config csv_output_row_filter <RowValueFilterJSONList> ...
```
You optionally specify whether all or any value filters must match for the row to be included in the output.
* `csv_output_row_filter_mode allmatch` - All value filters must match for the row to be included in the output; this is the default
* `csv_output_row_filter_mode anymatch` - Any value filter must match for the row to be included in the output
```
gam config csv_output_row_filter_mode anymatch csv_output_row_filter <RowValueFilterList> ...
gam config csv_output_row_filter_mode anymatch csv_output_row_filter <RowValueFilterJSONList> ...
```
### Exclusive filters
You can exclude rows generated by gam print commands based on column values. You specify a list
of fields (headers) and the values they must not have. `csv_output_row_drop_filter` is used to specify the
fields and values. Each field name/expression can appear only once in the list.
You specify whether all or any value filters must match for the row to be excluded from the output.
* `csv_output_row_filter_drop_mode allmatch` - If all value filters match, the row is excluded from the output
* `csv_output_row_filter_drop_mode anymatch` - If any value filter matches, the row is excluded from the output; this is the default
```
gam config csv_output_row_drop_filter <RowValueFilterList> ...
gam config csv_output_row_drop_filter <RowValueFilterJSONList> ...
```
You optionally specify whether all or any value filters must match for the row to be excluded from the output.
* `csv_output_row_drop_filter_mode allmatch` - If all value filters match, the row is excluded from the output
* `csv_output_row_drop_filter_mode anymatch` - If any value filter matches, the row is excluded from the output; this is the default
```
gam config csv_output_row_drop_filter_mode allmatch csv_output_row_drop_filter <RowValueFilterList> ...
gam config csv_output_row_drop_filter_mode allmatch csv_output_row_drop_filter <RowValueFilterJSONList> ...
```
### Matches
A filter matches if the field has the desired value. lf you specify a regular expression for a field name that matches
several columns, the filter matches if any of the columns has a match. In the case of `notregex|notregexcs|notdata`,

View File

@@ -28,6 +28,7 @@ Calendar ACL roles (as seen in Calendar GUI):
<CalendarItem> ::= <EmailAddress>
<CalendarList> ::= "<CalendarItem>(,<CalendarItem>)*"
<CalendarEntity> ::= <CalendarList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<CalendarACLRole> ::= editor|freebusy|freebusyreader|owner|reader|writer
<CalendarACLScope> ::= <EmailAddress>|user:<EmailAdress>|group:<EmailAddress>|domain:<DomainName>|domain|default
@@ -56,11 +57,14 @@ By default, Gam displays the information as an indented list of keys and values.
* `formatjson` - Display the fields in JSON format.
```
gam calendars <CalendarEntity> print acls|calendaracls [todrive <ToDriveAttribute>*]
[noselfowner]
[noselfowner] (addcsvdata <FieldName> <String>)*
[formatjson [quotechar <Character>]]
```
Option `noselfowner` suppresses the display of ACLs that reference the calendar itself as its owner.
Add additional columns of data from the command line to the output
* `addcsvdata <FieldName> <String>`
By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain
the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled.
When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output.
@@ -74,7 +78,9 @@ gam calendar <CalendarEntity> add <CalendarACLRole> ([user] <EmailAddress>)|(gro
gam calendar <CalendarEntity> update <CalendarACLRole> ([user] <EmailAddress>)|(group <EmailAddress>)|(domain [<DomainName>])|default [sendnotifications <Boolean>]
gam calendar <CalendarEntity> delete [<CalendarACLRole>] ([user] <EmailAddress>)|(group <EmailAddress>)|(domain [<DomainName>])|default
gam calendar <CalendarEntity> showacl [formatjson]
gam calendar <CalendarEntity> printacl [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]]
gam calendar <CalendarEntity> printacl [todrive <ToDriveAttribute>*]
(addcsvdata <FieldName> <String>)*
[formatjson [quotechar <Character>]]
```
By default, when you add or update a calendar ACL, notification is sent to the members referenced in the `<CalendarACLScopeEntity>`.
Use `sendnotifications false` to suppress sending the notification.

View File

@@ -11,7 +11,7 @@
- [Add calendar attendees](#add-calendar-attendees)
- [Update calendar events](#update-calendar-events)
- [Update calendar attendees](#update-calendar-attendees)
- [Specify calendar attendees with JSON data](#specify-calendar-attendees-with-JSON-data)
- [Specify calendar attendees with JSON data](#specify-calendar-attendees-with-json-data)
- [Delete selected calendar events](#delete-selected-calendar-events)
- [Delete all calendar events](#delete-all-calendar-events)
- [Move calendar events to another calendar](#move-calendar-events-to-another-calendar)
@@ -63,10 +63,12 @@ Client access works when accessing Resource calendars.
<CalendarItem> ::= <EmailAddress>
<CalendarList> ::= "<CalendarItem>(,<CalendarItem>)*"
<CalendarEntity> ::= <CalendarList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<DomainName> ::= <String>(.<String>)+
<EmailAddress> ::= <String>@<DomainName>
<EmailAddressList> ::= "<EmailAddess>(,<EmailAddress>)*"
<EmailAddressEntity> ::= <EmailAddressList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<EventAttachmentsSubfieldName> ::=
attachments.fileid|
@@ -183,6 +185,7 @@ Client access works when accessing Resource calendars.
(matchfield location <RegularExpression>)|
(matchfield organizeremail <RegularExpression>)|
(matchfield organizername <RegularExpression>)|
(matchfield organizerself <Boolean>)|
(matchfield status <RegularExpression>)|
(matchfield summary <RegularExpression>)|
(matchfield transparency <RegularExpression>)|
@@ -192,6 +195,7 @@ Client access works when accessing Resource calendars.
(id|eventid <EventId>) |
(event|events <EventIdList> |
<FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVSubkeySelector> | <CSVDataSelector>)
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<EventSelectEntity> ::=
(<EventSelectProperty>+ <EventMatchProperty>*)
@@ -463,7 +467,7 @@ No events are deleted unless you specify the `doit` option; omit `doit` to verif
When events are deleted from a calendar, they are moved to the calendar's trash and are only permanently deleted (purged) after 30 days.
Following a suggestion here (https://stackoverflow.com/questions/41043053/how-to-empty-calendar-trash-via-google-services) you can permanently delete
calendar events. This is achieved by creating a temporary calendar, deleting the events, moving the deleted events to the temporary calendar
calendar events with `purge events`. This is achieved by creating a temporary calendar, deleting the events, moving the deleted events to the temporary calendar
and then deleting the temporary calendar.
## Delete all calendar events

View File

@@ -21,6 +21,7 @@ Client access works when accessing Resource calendars.
<CalendarItem> ::= <EmailAddress>
<CalendarList> ::= "<CalendarItem>(,<CalendarItem>)*"
<CalendarEntity> ::= <CalendarList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<TimeZone> ::= <String>
See: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

View File

@@ -3,7 +3,6 @@
- [Chrome Browser Cloud Management](#chrome-browser-cloud-management)
- [API documentation](#api-documentation)
- [Query documentation](#query-documentation)
- [Collections of ChromeOS Devices](Collections-of-ChromeOS-Devices)
- [Definitions](#definitions)
- [Manage Chrome browsers](#manage-chrome-browsers)
- [Update Chrome browsers](#update-chrome-browsers)
@@ -25,8 +24,9 @@
* https://support.google.com/chrome/a/answer/9681204#retrieve_all_chrome_devices_for_an_account
## Definitions
* [`<CrOSTypeEntity>`](Collections-of-ChromeOS-Devices)
```BNF
```
<BrowserTokenPermanentID> ::= <String>
<OrgUnitPath> ::= /|(/<String)+
<QueryBrowser> ::= <String> See: https://support.google.com/chrome/a/answer/9681204#retrieve_all_chrome_devices_for_an_account
@@ -41,6 +41,7 @@
(query:<QueryBrowser>)|(query:orgunitpath:<OrgUnitPath>)|(query <QueryBrowser>) |
(browserou <OrgUnitItem>) | (browserous <OrgUnitList>) |
<FileSelector> | <CSVFileSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<BrowserAttribute> ::=
(annotatedassetid|asset|assetid <String>)|
@@ -136,7 +137,7 @@ gam csv UpdateBrowsers.csv gam update browser ~deviceId updatenotes "~~notes~~\n
```
gam move browsers ou|org|orgunit <OrgUnitPath>
((ids <DeviceIDList>) |
(queries <QueryBrowserList> [querytime.* <Time>]) |
(queries <QueryBrowserList> [querytime<String> <Time>]) |
(browserou <OrgUnitItem>) | (browserous <OrgUnitList>) |
<FileSelector> | <CSVFileSelector>)
[batchsize <Integer>]
@@ -177,7 +178,7 @@ By default, Gam displays the information as an indented list of keys and values:
```
gam show browsers
([ou|org|orgunit|browserou <OrgUnitPath>] [(query <QueryBrowser>)|(queries <QueryBrowserList>))|(select <BrowserEntity>))
[querytime.* <Time>]
[querytime<String> <Time>]
[orderby <BrowserOrderByFieldName> [ascending|descending]]
[basic|full|allfields|annotated] <BrowserFieldName>* [fields <BrowserFieldNameList>]
[formatjson]
@@ -204,7 +205,7 @@ The characters following `querytime` can be any combination of lowercase letters
```
gam print browsers [todrive <ToDriveAttribute>*]
([ou|org|orgunit|browserou <OrgUnitPath>] [(query <QueryBrowser>)|(queries <QueryBrowserList>))|(select <BrowserEntity>))
[querytime.* <Time>]
[querytime<String> <Time>]
[orderby <BrowserOrderByFieldName> [ascending|descending]]
[basic|full|allfields|annotated] <BrowserFieldName>* [fields <BrowserFieldNameList>]
[sortheaders] [formatjson [quotechar <Character>]]
@@ -371,7 +372,7 @@ gam revoke browsertoken <BrowserTokenPermanentID>
```
gam show browsertokens
([ou|org|orgunit|browserou <OrgUnitPath>] [(query <QueryBrowserToken)|(queries <QueryBrowserTokenList>)))
[querytime.* <Time>]
[querytime<String> <Time>]
[orderby <BrowserTokenFieldName> [ascending|descending]]
[allfields] <BrowserTokenFieldName>* [fields <BrowserTokenFieldNameList>]
[formatjson]
@@ -394,7 +395,7 @@ By default, Gam displays the information as an indented list of keys and values:
```
gam print browsertokens [todrive <ToDriveAttribute>*]
([ou|org|orgunit|browserou <OrgUnitPath>] [(query <QueryBrowserToken)|(queries <QueryBrowserTokenList>)))
[querytime.* <Time>]
[querytime<String> <Time>]
[orderby <BrowserTokenFieldName> [ascending|descending]]
[allfields] <BrowserTokenFieldName>* [fields <BrowserTokenFieldNameList>]
[sortheaders] [formatjson [quotechar <Character>]]

View File

@@ -4,6 +4,7 @@
- [API documentation](#api-documentation)
- [Definitions](#definitions)
- [Quoting rules](#quoting-rules)
- [Display Chrome installed app details](#display-chrome-installed-app-details)
- [Display Chrome installed apps counts](#display-chrome-installed-apps-counts)
- [Display Chrome devices with a specific installed application](#display-chrome-devices-with-a-specific-installed-application)
@@ -19,6 +20,7 @@ the appropriate scope: `Chrome Management API - read only`.
gam update project
gam oauth create
```
To get installed app details you must authorize the scope: `Chrome Management API - AppDetails read only`.
## Definitions
```
@@ -47,6 +49,14 @@ Typically, you will enclose the entire list in double quotes and quote each item
- Items, separated by spaces, with spaces, commas or single quotes in the items themselves
* ```"'it em' 'it,em' \"it'em\""```
## Display Chrome installed app details
```
gam info chromeapp android|chrome|web <AppID>
[formatjson]
```
By default, Gam displays the information as an indented list of keys and values.
* `formatjson` - Display the fields in JSON format.
## Display Chrome installed apps counts
```
gam show chromeapps

View File

@@ -4,7 +4,6 @@
- [API documentation](#api-documentation)
- [Query documentation](#query-documentation)
- [Notes](#notes)
- [Collections of ChromeOS Devices](Collections-of-ChromeOS-Devices)
- [Definitions](#definitions)
- [CrOS Query Searchable Fields](#cros-query-searchable-fields)
- [ChromeOS device update OU error handling](#chromeos-device-update-ou-error-handling)
@@ -24,6 +23,7 @@
- [Print a header row and fields for selected CrOS devices](#print-a-header-row-and-fields-for-selected-cros-devices)
- [Print a header row and fields for specified CrOS devices](#print-a-header-row-and-fields-for-specified-cros-devices)
- [Display Examples](#display-examples)
- [Display CrOS device count](#display-cros-device-count)
- [Print ChromeOS device activity](#print-chromeos-device-activity)
- [Print a header row and activity for selected CrOS devices](#print-a-header-row-and-activity-for-selected-cros-devices)
- [Print a header row and activity for specified CrOS devices](#print-a-header-row-and-activity-for-specified-cros-devices)
@@ -74,8 +74,9 @@ The first form allows more powerful selection of devices with `<CrOSTypeEntity>`
The second form is backwards compatible with Standard GAM and selection with `<CrOSEntity>` is limited.
## Definitions
```BNF
* [`<CrOSTypeEntity>`](Collections-of-ChromeOS-Devices)
```
<OrgUnitPath> ::= /|(/<String)+
<QueryCrOS> ::= <String> See: https://support.google.com/chrome/a/answer/1698333
<CommandID> ::= <String>
@@ -85,6 +86,7 @@ The second form is backwards compatible with Standard GAM and selection with `<C
<SerialNumberList> ::= "<SerialNumber>(,<SerialNumber>)*"
<SerialNumberEntity> ::=
<SerialNumberList> | <FileSelector> | <CSVFileSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<CrOSEntity> ::=
<CrOSIDList> | (cros_sn <SerialNumberList>) |
@@ -108,6 +110,7 @@ The second form is backwards compatible with Standard GAM and selection with `<C
deprovisionreason|
devicefiles|
deviceid|
devicelicensetype|
diskvolumereports|
dockmacaddress|
ethernetmacaddress|
@@ -126,6 +129,7 @@ The second form is backwards compatible with Standard GAM and selection with `<C
ordernumber|
orgunitid|
orgunitpath|org|ou|
osupdatestatus|
osversion|
platformversion|
recentusers|
@@ -133,8 +137,8 @@ The second form is backwards compatible with Standard GAM and selection with `<C
serialnumber|
status|
supportenddate|
systemramtotal|
systemramfreereports|
systemramtotal|
tpmversioninfo|
willautorenew
<CrOSFieldNameList> ::= "<CrOSFieldName>(,<CrOSFieldName>)*"
@@ -244,7 +248,7 @@ Partial serial number searches are supported, as long as you enter at least thre
### Status
To view all provisioned or deprovisioned devices, select the status from the left drop-down, and all of the devices that fit this criterion will appear in the view. Alternatively, you can do the following searches from the All devices view:
`gam print cros query "status:[provisioned|disable|deprovisioned]"`
`gam print cros query "status:[provisioned|disabled|deprovisioned]"`
### User
Enter user: as the operator. For example, to match the name Joe, but not Joey, enter the following:
@@ -534,7 +538,7 @@ gam <CrOSTypeEntity> print cros
```
gam print cros [todrive <ToDriveAttribute>*]
[(query <QueryCrOS>)|(queries <QueryCrOSList>) [querytime.* <Time>]
[(query <QueryCrOS>)|(queries <QueryCrOSList>) [querytime<String> <Time>]
[(limittoou|cros_ou <OrgUnitItem>)|(cros_ou_and_children <OrgUnitItem>)|
(cros_ous <OrgUnitList>)|(cros_ous_and_children <OrgUnitList>)]]
[orderby <CrOSOrderByFieldName> [ascending|descending]]
@@ -554,9 +558,13 @@ is also specified, the query applies to devices within the OUs.
- `(query <QueryCrOS>)|(queries <QueryCrOSList>)` - Select CrOS devices that match a query
- `limittoou|cros_ou <OrgUnitItem>` - Select CrOS devices directly in the OU `<OrgUnitItem>`
- You can predefine this item with the `print_cros_ous` variable in `gam.cfg`.
- `cros_ou_and_children <OrgUnitItem>` - Select CrOS devices in the OU `<OrgUnitItem>` and its sub OUs
- You can predefine this item with the `print_cros_ous_and_children` variable in `gam.cfg`.
- `cros_ous <OrgUnitList>` - Select CrOS devices directly in the OUs `<OrgUnitList>`
- You can predefine this list with the `print_cros_ous` variable in `gam.cfg`.
- `cros_ous_and_children <OrgUnitList>` - Select CrOS devices in the OUs `<OrgUnitList>` and their sub OUs
- You can predefine this list with the `print_cros_ous_and_children` variable in `gam.cfg`.
Use the `querytime<String> <Time>` option to allow times, usually relative, to be substituted into the `query <QueryCrOS>` and `queries <QueryCrOSList>` options.
The `querytime<String> <Time>` value replaces the string `#querytime<String>#` in any queries.
@@ -671,13 +679,19 @@ Print information about CrOS devices synced between 45 days ago and 30 days ago:
gam print cros query "sync:#querytime1#..#querytime2#" querytime1 -45d querytime2 -30d
```
## Display CrOS device count
Display the number of CrOS devices in an entity.
```
gam <CrOSTypeEntity> show count
```
## Print ChromeOS device activity
### Print a header row and activity for selected CrOS devices
```
gam print crosactivity [todrive <ToDriveAttribute>*]
[(query <QueryCrOS>)|(queries <QueryCrOSList>) [querytime.* <Time>]
[(query <QueryCrOS>)|(queries <QueryCrOSList>) [querytime<String> <Time>]
[(limittoou|cros_ou <OrgUnitItem>)|(cros_ou_and_children <OrgUnitItem>)|
(cros_ous <OrgUnitList>)|(cros_ous_and_children <OrgUnitList>)]]
[orderby <CrOSOrderByFieldName> [ascending|descending]]
@@ -696,9 +710,13 @@ is also specified, the query applies to devices within the OUs.
- `(query <QueryCrOS>)|(queries <QueryCrOSList>)` - Select CrOS devices that match a query
- `limittoou|cros_ou <OrgUnitItem>` - Select CrOS devices directly in the OU `<OrgUnitItem>`
- You can predefine this item with the `print_cros_ous` variable in `gam.cfg`.
- `cros_ou_and_children <OrgUnitItem>` - Select CrOS devices in the OU `<OrgUnitItem>` and its sub OUs
- You can predefine this item with the `print_cros_ous_and_children` variable in `gam.cfg`.
- `cros_ous <OrgUnitList>` - Select CrOS devices directly in the OUs `<OrgUnitList>`
- You can predefine this list with the `print_cros_ous` variable in `gam.cfg`.
- `cros_ous_and_children <OrgUnitList>` - Select CrOS devices in the OUs `<OrgUnitList>` and their sub OUs
- You can predefine this list with the `print_cros_ous_and_children` variable in `gam.cfg`.
Use the `querytime<String> <Time>` option to allow times, usually relative, to be substituted into the `query <QueryCrOS>` and `queries <QueryCrOSList>` options.
The `querytime<String> <Time>` value replaces the string `#querytime<String>#` in any queries.
@@ -824,7 +842,7 @@ gam info crostelemetry <SerialNumber>
### Display data about all or selected devices.
```
gam show crostelemetry
[(ou|org|orgunit <OrgUnitItem>)|(cros_sn <SerialNumber>)|(filter <String>)]
[(ou|org|orgunit|ou_and_children <OrgUnitItem>)|(cros_sn <SerialNumber>)|(filter <String>)]
<CrOSTelemetryFieldName>* [fields <CrOSTelemetryFieldNameList>]
[start <Date>] [end <Date>] [listlimit <Number>]
[reverselists <CrOSTelemetryListFieldNameList>]
@@ -833,6 +851,7 @@ gam show crostelemetry
Use these options to select CrOS devices; if none are chosen, all CrOS devices in the account are selected.
- `ou|org|orgunit <OrgUnitItem>` - Select CrOS devices directly in the OU `<OrgUnitItem>`
- `ou_and_children <OrgUnitItem>` - Select CrOS devices in the OU `<OrgUnitItem>` and its sub OUs
- `cros_sn <SerialNumber>` - Select the CrOS device with serial number `<SerialNumber>`.
- `filter <String>` - Select the CrOS device with a filter.
- `listlimit <Number>` - Limits the number of repetitions to `<Number>`; if not specified or `<Number>` equals zero, there is no limit.
@@ -849,7 +868,7 @@ By default, Gam displays the information as an indented list of keys and values:
### Print data about all or selected devices.
```
gam print crostelemetry [todrive <ToDriveAttribute>*]
[(ou|org|orgunit <OrgUnitItem>)|(cros_sn <SerialNumber>)|(filter <String>)]
[(ou|org|orgunit|ou_and_children <OrgUnitItem>)|(cros_sn <SerialNumber>)|(filter <String>)]
<CrOSTelemetryFieldName>* [fields <CrOSTelemetryFieldNameList>]
[reverselists <CrOSTelemetryListFieldNameList>]
[start <Date>] [end <Date>] [listlimit <Number>]
@@ -858,6 +877,7 @@ gam print crostelemetry [todrive <ToDriveAttribute>*]
Use these options to select CrOS devices; if none are chosen, all CrOS devices in the account are selected.
- `ou|org|orgunit <OrgUnitItem>` - Select CrOS devices directly in the OU `<OrgUnitItem>`
- `ou_and_children <OrgUnitItem>` - Select CrOS devices in the OU `<OrgUnitItem>` and its sub OUs
- `cros_sn <SerialNumber>` - Select the CrOS device with serial number `<SerialNumber>`.
- `filter <String>` - Select the CrOS device with a filter.
- `listlimit <Number>` - Limits the number of repetitions to `<Number>`; if not specified or `<Number>` equals zero, there is no limit.

View File

@@ -47,40 +47,50 @@ gam user user@domain.com check|update serviceaccount
<CourseAliasList> ::= "<CourseAlias>(,<CourseAlias>)*"
<CourseAliasEntity> ::=
<CourseAliasList>|<FileSelector>|<CSVFileSelector>|<CSVkmdSelector>|<CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<CourseAnnouncementID> ::= <Number>
<CourseAnnouncementIDList> ::= "<CourseAnnouncementID>(,<CourseAnnouncementID>)*"
<CourseAnnouncementIDEntity> ::=
<CourseAnnouncementIDList>|<FileSelector>|<CSVFileSelector>|<CSVkmdSelector>|<CSVSubkeySelector>|<CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<CourseAnnouncementState> ::= draft|published|deleted
<CourseAnnouncementStateList> ::= all|"<CourseAnnouncementState>(,<CourseAnnouncementState>)*"
<CourseID> ::= <Number>|d:<CourseAlias>
<CourseIDList> ::= "<CourseID>(,<CourseID>)*"
<CourseEntity> ::=
<CourseIDList>|<FileSelector>|<CSVFileSelector>|<CSVkmdSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<CourseMaterialID> ::= <Number>
<CourseMaterialIDList> ::= "<CourseMaterialID>(,<CourseMaterialID>)*"
<CourseMaterialState> ::= draft|published|deleted
<CourseMaterialStateList> ::= all|"<CourseMaterialState>(,<CourseMaterialState>)*"
<CourseMaterialIDEntity> ::= <CourseMaterialIDList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVSubkeySelector> | <CSVDataSelector>
<CourseMaterialIDEntity> ::=
<CourseMaterialIDList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVSubkeySelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<CourseState> ::= active|archived|provisioned|declined|suspended
<CourseStateList> ::= all|"<CourseState>(,<CourseState>)*"
<CourseSubmissionID> ::= <Number>
<CourseSubmissionIDList> ::= "<CourseSubmissionID>(,<CourseSubmissionID>)*"
<CourseSubmissionIDEntity> ::=
<CourseSubmissionIDList>|<FileSelector>|<CSVFileSelector>|<CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<CourseSubmissionState> ::= new|created|turned_in|returned|reclaimed_by_student
<CourseSubmissionStateList> ::= all|"<CourseSubmissionState>(,<CourseSubmissionState>)*"
<CourseTopic> ::= <String>
<CourseTopicList> ::= "<CourseTopic>(,<CourseTopic>)*"
<CourseTopicEntity> ::= <CourseTopicList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<CourseTopicEntity> ::=
<CourseTopicList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<CourseTopicID> ::= <Number>
<CourseTopicIDList> ::= "<CourseTopicID>(,<CourseTopicID>)*"
<CourseTopicIDEntity> ::=
<CourseTopicIDList>|<FileSelector>|<CSVFileSelector>|<CSVkmdSelector>|<CSVSubkeySelector>|<CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<CourseWorkID> ::= <Number>
<CourseWorkIDList> ::= "<CourseWorkID>(,<CourseWorkID>)*"
<CourseWorkIDEntity> ::=
<CourseWorkIDList>|<FileSelector>|<CSVFileSelector>|<CSVkmdSelector>|<CSVSubkeySelector>|<CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<CourseWorkState> ::= draft|published|deleted
<CourseWorkStateList> ::= all|"<CourseWorkState>(,<CourseWorkState>)*"
@@ -268,7 +278,7 @@ gam create|add course [id|alias <CourseAlias>] <CourseAttribute>*
[markdraftaspublished [<Boolean>]]
[markpublishedasdraft [<Boolean>]]
[members none|all|students|teachers]]
[logdrivefileids [<Boolean>>]]
[logdrivefileids [<Boolean>]]
gam update course <CourseID> <CourseAttribute>+
[copyfrom <CourseID>
@@ -282,7 +292,7 @@ gam update course <CourseID> <CourseAttribute>+
[markdraftaspublished [<Boolean>]]
[markpublishedasdraft [<Boolean>]]
[members none|all|students|teachers]]
[logdrivefileids [<Boolean>>]]
[logdrivefileids [<Boolean>]]
gam update courses <CourseEntity> <CourseAttribute>+
[copyfrom <CourseID>
[announcementstates <CourseAnnouncementStateList>]
@@ -295,7 +305,7 @@ gam update courses <CourseEntity> <CourseAttribute>+
[markdraftaspublished [<Boolean>]]
[markpublishedasdraft [<Boolean>]]
[members none|all|students|teachers]]
[logdrivefileids [<Boolean>>]]
[logdrivefileids [<Boolean>]]
```
`copyfrom <CourseID>` allows copying of course announcements, work, topics and members from one course to another.
* Accouncements - By default, no course announcements are copied
@@ -325,7 +335,7 @@ gam update courses <CourseEntity> <CourseAttribute>+
* `members students` - Copy students
* `members teachers` - Copy teachers
When true, `logdrivefileids [<Boolean>>]` generates a CSV file with headers `courseId,ownerId,fileId' that
When true, `logdrivefileids [<Boolean>]` generates a CSV file with headers `courseId,ownerId,fileId' that
lists all drive files in the course.
The Classroom API does not support course materials of type `form`, they will not be copied.

View File

@@ -20,11 +20,15 @@
<UniqueID> ::= id:<String>
<GuardianItem> ::= <EmailAddress>|<UniqueID>|<String>
<GuardianItemList> ::= "<GuardianItem>(,<GuardianItem>)*"
<GuardianEntity> ::= <GuardianList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<GuardianEntity> ::=
<GuardianList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<StudentItem> ::= <EmailAddress>|<UniqueID>|<String>
<GuardianInvitationID> ::= <String>
<GuardianInvitationIDList> ::= "<GuardianInvitationId>(,<GuardianInvitationID>)*"
<GuardianInvitationIDEntity> ::= <GuardianInvitationIDList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<GuardianInvitationIDEntity> ::=
<GuardianInvitationIDList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<GuardianState> ::= complete|pending
<GuardianStateList> ::= "<GuardianState>(,<GuardianState>)*"
```

View File

@@ -33,11 +33,15 @@ The Classroom API does not support inviting users from outside your domain.
<UniqueID> ::= id:<String>
<ClassroomInvitationID> ::= <String>
<ClassroomInvitationIDList> ::= "<ClassroomInvitationID>(,<ClassroomInvitationID>)*"
<ClassroomInvitationIDEntity> ::= <ClassroomInvitationIDList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<ClassroomInvitationIDEntity> ::=
<ClassroomInvitationIDList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<CourseAlias> ::= <String>
<CourseID> ::= <Number>|d:<CourseAlias>
<CourseIDList> ::= "<CourseID>(,<CourseID>)*"
<CourseEntity> ::= <CourseIDList> | <FileSelector> | <CSVFileSelector | <CSVkmdSelector>
<CourseEntity> ::=
<CourseIDList> | <FileSelector> | <CSVFileSelector | <CSVkmdSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<CourseState> ::= active|archived|provisioned|declined|suspended
<CourseStateList> ::= all|"<CourseState>(,<CourseState>)*"
```

View File

@@ -22,7 +22,9 @@
<CourseAlias> ::= <String>
<CourseID> ::= <Number>|d:<CourseAlias>
<CourseIDList> ::= "<CourseID>(,<CourseID>)*"
<CourseEntity> ::= <CourseIDList> | <FileSelector> | <CSVFileSelector | <CSVkmdSelector>
<CourseEntity> ::=
<CourseIDList> | <FileSelector> | <CSVFileSelector | <CSVkmdSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<CourseState> ::= active|archived|provisioned|declined|suspended
<CourseStateList> ::= all|"<CourseState>(,<CourseState>)*"
```

View File

@@ -167,7 +167,7 @@ These two/three columns are used to match current company devices against the CS
If `preview` is specified, the operations that would be performed are previewed but are not performed; use this to test.
```
gam sync devices
[(query <QueryDevice>)|(queries <QueryDeviceList>) (querytime.* <Time>)*]
[(query <QueryDevice>)|(queries <QueryDeviceList>) (querytime<String> <Time>)*]
csvfile <FileName>
(devicetype_column <String>)|(static_devicetype <DeviceType>)
(serialnumber_column <String>)
@@ -190,7 +190,7 @@ By default, Gam displays the information as an indented list of keys and values.
## Print devices
```
gam print devices [todrive <ToDriveAttribute>*]
[(query <QueryDevice>)|(queries <QueryDeviceList>) (querytime.* <Time>)*]
[(query <QueryDevice>)|(queries <QueryDeviceList>) (querytime<String> <Time>)*]
<DeviceFieldName>* [fields <DeviceFieldNameList>] [userfields <DeviceUserFieldNameList>]
[orderby <DeviceOrderByFieldName> [ascending|descending]]
[all|company|personal|nocompanydevices|nopersonaldevices]
@@ -266,7 +266,7 @@ gam info deviceuser <DeviceUserEntity>
```
gam print deviceusers [todrive <ToDriveAttribute>*]
[select <DeviceID>]
[(query <QueryDevice>)|(queries <QueryDeviceList>) (querytime.* <Time>)*]
[(query <QueryDevice>)|(queries <QueryDeviceList>) (querytime<String> <Time>)*]
<DeviceUserFieldName>* [fields <DeviceUserFieldNameList>]
[orderby <DeviceOrderByFieldName> [ascending|descending]]
[formatjson [quotechar <Character>]]

View File

@@ -61,7 +61,9 @@ and Cloud Identity Premium accounts. Unfortunately, even if you have the require
<UniqueID> ::= id:<String>
<GroupItem> ::= <EmailAddress>|<UniqueID>|groups/<String>
<GroupList> ::= "<GroupItem>(,<GroupItem>)*"
<GroupEntity> ::= <GroupList>|<FileSelector>|<CSVkmdSelector>|<CSVDataSelector>
<GroupEntity> ::=
<GroupList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<GroupRole> ::= owner|manager|member
<GroupRoleList> ::= "<GroupRole>(,<GroupRole>)*"
<CIGroupType> ::= customer|group|other|serviceaccount|user
@@ -176,14 +178,18 @@ testgroup@domain.com,testuser4@domain.com,MEMBER,Remove Failed,Does not exist
## Synchronize members in a group
A synchronize operation gets the current membership for a group and does adds and deletes as necessary to make it match `<UserTypeEntity>`.
This is done by specific role except for a special case where role is ignored.
```
gam update cigroups <GroupEntity> sync [<GroupRole>]
gam update cigroups <GroupEntity> sync [<GroupRole>|ignorerole]
[usersonly|groupsonly] [addonly|removeonly]
[notsuspended|suspended] [notarchived|archived]
[expire|expires <Time>] [preview] [actioncsv]
<UserTypeEntity>
```
If `<GroupRole>` is not specified, `member` is assumed.
If `ignorerole` is specified, GAM removes members regardless of role and adds new members with role MEMBER.
This is a special purpose option, use with caution and ensure that `<UserTypeEntity>` specifies the full desired membership list of all roles.
If neither `<GroupRole>` nor `ignorerole` is specified, `member` is assumed.
When `<UserTypeEntity>` specifies a group or groups:
* `usersonly` - Only the user members from the specified groups are added/deleted

View File

@@ -57,7 +57,9 @@ and Cloud Identity Premium accounts. Unfortunately, even if you have the require
<UniqueID> ::= id:<String>
<GroupItem> ::= <EmailAddress>|<UniqueID>|<String>
<GroupList> ::= "<GroupItem>(,<GroupItem>)*"
<GroupEntity> ::= <GroupList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<GroupEntity> ::=
<GroupList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<GroupRole> ::= owner|manager|member
<GroupRoleList> ::= "<GroupRole>(,<GroupRole>)*"
<CIGroupType> ::= customer|group|other|serviceaccount|user
@@ -365,6 +367,11 @@ When using the `formatjson` option, double quotes are used extensively in the da
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
### Display dynamic groups
```
gam print cigroups query "'cloudidentity.googleapis.com/groups.dynamic' in labels"
```
### Display security groups
```
gam print cigroups query "'cloudidentity.googleapis.com/groups.security' in labels"

View File

@@ -165,10 +165,6 @@ Data fields identified in a `csvkmd` argument.
<CrOSEntity> ::=
<CrOSIDList> | (cros_sn <SerialNumberList>) |
(query:<QueryCrOS>) | (query:orgunitpath:<OrgUnitPath>) | (query <QueryCrOS>)
<DataStudioAssetIDEntity> ::=
<DataStudioAssetIDList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<DataStudioPermissionEntity> ::=
<DataStudioPermissionList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<DeviceIDEntity> ::=
<DeviceIDList> | (device_sn <SerialNumber>)
(query:<QueryDevice>) | (query <QueryDevice>)
@@ -282,6 +278,10 @@ Data fields identified in a `csvkmd` argument.
<LabelIDList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<LabelNameEntity> ::=
<LabelNameList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<LookerStudioAssetIDEntity> ::=
<LookerStudioAssetIDList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<LookerStudioPermissionEntity> ::=
<LookerStudioPermissionList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<MessageIDEntity> ::=
<MessageIDList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<MobileEntity> ::=
@@ -332,8 +332,8 @@ Data fields identified in a `csvkmd` argument.
<SiteACLScopeList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<SiteEntity> ::=
<SiteList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<TasklistIDEntity> ::=
<TasklistIDList> | <FileSelector> | <CSVFileSelector>
<TasklistEntity> ::=
<TasklistIDList> | <TaskListTitleList> | <FileSelector> | <CSVFileSelector>
<TasklistIDTaskIDEntity> ::=
<TasklistIDTaskIDList> | <FileSelector> | <CSVFileSelector>
<ThreadIDEntity> ::=

View File

@@ -3,6 +3,7 @@
- [Windows Command Prompt](#windows-command-prompt)
- [Windows PowerShell](#windows-powershell)
- [List quoting rules](#list-quoting-rules)
- [Queries example](#queries-example)
## Linux and MacOS
@@ -16,6 +17,10 @@ To embed a `'` in a string enclosed in `"`, enter `'`; `name "Test'Group"`.
To embed a `"` in a string enclosed in `'`, enter `"`; `name 'Test"Group'`.
To embed a `'` in a string enclosed in `'`, enter `'\''`; `name 'Test'\''Group'`.
To embed a `"` in a string enclosed in `"`, enter `\"`; `name "Test\"Group"`.
Linux and MacOS do not recognize smart or curly quotes, `“` and `”`, they can not be used to enclose arguments.
## Windows Command Prompt
@@ -56,3 +61,19 @@ Typically, you will enclose the entire list in double quotes and quote each item
* ```"'it em' 'it,em' \"it'em\""```
Typical places where these rules apply are lists of OUs and Contact Groups.
## Queries example
### Linux and MacOS
```
gam print users queries "\"orgUnitPath='/Students/Lower School/2027'\",\"orgUnitPath='/Students/Lower School/2028'\""
```
### Windows Command Prompt
```
gam print users queries "\"orgUnitPath='/Students/Lower School/2027'\",\"orgUnitPath='/Students/Lower School/2028'\""
```
### Windows Power Shell
```
gam print users queries "`"orgUnitPath=\'/Students/Lower\ School/2027\'`",`"orgUnitPath=\'/Students/Lower\ School/2028\'`""
```

View File

@@ -31,6 +31,7 @@ gam user user@domain.com check serviceaccount
<PeopleResourceNameList> ::= "<PeopleResourceName>(,<PeopleResourceName>)*"
<PeopleResourceNameEntity> ::=
<PeopleResourceNameNameList> | <FileSelector> | <CSVFileSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<PeopleSourceName> ::=
contact|contacts|

View File

@@ -54,7 +54,8 @@
<ContactID> ::= <String>
<ContactIDList> ::= "<ContactID>(,<ContactID>)*"
<ContactEntity> ::=
<ContactIDList>|<FileSelector>|<CSVkmdSelector>|<CSVDataSelector>
<ContactIDList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<ContactSelection> ::=
[query <QueryContact>]
[emailmatchpattern <RegularExpression> [emailmatchtype work|home|other|<String>]]
@@ -185,14 +186,29 @@
## Create domain shared contacts
```
gam create contact <ContactAttribute>+
[(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*))| returnidonly]
```
By default, the domain name and contact ID are displayed on stdout.
* `csv [todrive <ToDriveAttribute>*]` - Write domain name and contact ID values to a CSV file.
* `addcsvdata <FieldName> <String>` - Add additional columns of data from the command line to the output
* `returnidonly` - Display just the contact ID on stdout
To retrieve the contact ID with `returnidonly`:
```
Linux/MacOS
contactId=$(gam create contact ... returnidonly)
Windows PowerShell
$contactId = & gam create contact ... returnidonly
```
## Select domain shared contacts
You specify contacts by ID or by selection qualifiers.
```
<ContactID> ::= <String>
<ContactIDList> ::= "<ContactID>(,<ContactID>)*"
<ContactEntity> ::=
<ContactIDList>|<FileSelector>|<CSVkmdSelector>|<CSVDataSelector>
<ContactIDList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<ContactSelection> ::=
[query <QueryContact>]
[emailmatchpattern <RegularExpression> [emailmatchtype work|home|other|<String>]]

View File

@@ -75,6 +75,7 @@
others_3p_shortcuts |
others_items |
writable_files
<SharedDriveID> ::= <String>
<SharedDriveName> ::= <String>
<SharedDriveIDEntity> ::= (teamdriveid <DriveFileItem>) | (teamdriveid:<DriveFileItem>)
@@ -200,6 +201,7 @@ By default, all types of files and folders are displayed; you can specify a list
gfolder|gdirectory|
gform|
gfusion|
gjam|
gmap|
gpresentation|
gscript|
@@ -218,6 +220,7 @@ This is the mapping from `<MimeTypeShortcut>` to MIME type.
* `gfolder|gdirectory` - application/vnd.google-apps.folder
* `gform` - application/vnd.google-apps.form
* `gfusion|gfusiontable` - application/vnd.google-apps.fusiontable
* `gjam` - application/vnd.google-apps.jam
* `gmap` - application/vnd.google-apps.map
* `gpresentation` - application/vnd.google-apps.presentation
* `gscript` - application/vnd.google-apps.script
@@ -304,6 +307,7 @@ You can select a list of file IDs by referencing files that contain file IDs.
```
<DriveFileEntity> ::=
<FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVSubkeySelector>) | <CSVDataSelector>)
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
```
* [Collections of Items](Collections-of-Items)

View File

@@ -8,7 +8,499 @@ Automatic update to the latest version on Linux/Mac OS/Google Cloud Shell/Raspbe
By default, a folder, `gamadv-xtd3`, is created in the default or specified path and the files are downloaded into that folder.
Add the `-s` option to the end of the above commands to suppress creating the `gamadv-xtd3` folder; the files are downloaded directly into the default or specified path.
See [Downloads](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads) for Windows or other options, including manual installation.
See [Downloads](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads) for Windows or other options, including manual installation
### 6.65.15
Added additional options to `gam <UserTypeEntity> print|show youtubechannels`.
### 6.65.14
Fixed bug in gam <UserTypeEntity> copy|move drivefile` that caused a trap.
```
UnboundLocalError: cannot access local variable 'emailAddress' where it is not associated with a value
```
### 6.65.13
Added support for user language `en-CA`.
Added option `sizefield quotabytesused|size` to the following commands that specifies which
file size field to use when totaling file sizes; the default value is `quotabytesused`; previous versions used `size`.
```
gam <UserTypeEntity> print|show filecounts
gam <UserTypeEntity> print filelist
gam <UserTypeEntity> print|show filetree
gam <UserTypeEntity> print diskusage
```
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-Drive-Files-Display#file-size-fields
### 6.65.12
Additional updates on MacOS when a `gam csv` command is interrupted with a contol-C.
### 6.65.11
Updated multiprocessing to handle the following error that occurs on MacOS when a `gam csv` command
is interrupted with a contol-C.
```
multiprocessing/resource_tracker.py:224: UserWarning: resource_tracker: There appear to be N leaked semaphore objects to clean up at shutdown
```
Fixed bug in `gam print|show crostelemetry` where no CrOS device data was displayed if no selection
options were chosen; now, data is displayed for all CrOS devices as documented.
### 6.65.10
Fixed bug in `gam print crostelemetry` that caused a trap: `KeyError: 'reportTime'`.
### 6.65.09
Added option `noduplicate` to `gam <UserTypeEntity> create drivefile` that causes GAM
to issue a warning and not perform the create if a non-trashed item with the same name (regardless of MIME type)
exists in the parent folder.
Updated `gam <UserTypeEntity> get drivefile <DriveFileEntity>` to handle the following error
that seems to occur when multiple tabs from a Google sheet are being downloaded in parallel.
```
Download Failed: HTTP Error: 429
```
### 6.65.08
Added option `addcsvdata <FieldName> <String>` to `gam report <ActivityApplicationName>` that adds
additional columns of data to the CSV file output.
Added option `shownoactivities` to `gam report <ActivityApplicationName>` that causes GAM to display
a row with a key value of `NoActivities` when there are no activities to report.
For example, to find Shared Drives with no activity, see: https://github.com/taers232c/GAMADV-XTD3/wiki/Reports#find-shared-drives-with-no-activity
### 6.65.07
Updated `gam delete building` to handle the following error:
```
ERROR: 412: conditionNotMet - Cannot delete building because there are Calendar resources associated with it.
```
### 6.65.06
Improved error message when trying to add external students/teachers to a course.
```
gam courses 544906261666 add student user@gmail.com
Course: 544906261666, Add 1 Student
Course: 544906261666, Student: user@gmail.com, Add Failed: 403: permissionDenied - @CannotDirectAddUser Unable to directly add the user to the course. Please check that the user account exists and is within the course admin's domain. Add external user with: gam user user@gmail.com create classroominvitation courses 544906261666 role Student
```
### 6.65.05
Updated `gam info users <UserTypeEntity>` to make option `grouptree` effective when used
with option `formatjson`.
Added option `[formatjson [quotechar <Character>]]]`
to these commands so that event details are displayed in CSV format.
```
gam print|show grouptree <GroupEntity>
gam <UserTypeEntity> print|show grouptree
```
Added option `querytime<String> <Date>` to all commands that process messages.
For example, you can identify all messages within a particular time period, in this case, all messages unread
in the last 30 days.
```
gam user user@domain.com print messages querytime30d -30d query "after:#querytime30d# is:unread"
```
Updated `gam <UserTypeEntity> import|insert message` to allow `replace <Tag> <UserReplacement>` as documented.
Updated non-owner permission handling in `gam <UserTypeEntity> copy|move drivefile`.
### 6.65.04
Fixed bug where license SKU `1010020031` (Google Workspace Frontline Standard) was improperly entered making it unusable;
its alias `wsflwstan` was usable.
Added support for Google Workspace Additional Storage.
* ProductID - 101043
* SKUID - 1010430001 | gwas | plusstorage
### 6.65.03
Fixed bug in commands that display calendar events where event start and end times were not properly displayed
when `gam.cfg` had `timezone utc`. The API returns the start and end times expressed in the calendar timezone
but GAM replaced the timezone specifier with a `Z`; the date and time values were as expected. This became
a problem when event data was exported and used to create or update events.
### 6.65.02
Updated `gam print|show browsers` to handle the following error:
```
ERROR: 503: serviceNotAvailable - The service is currently unavailable.
```
### 6.65.01
Added option `showmimetypesize` to `gam <UserTypeEntity> print|show filecounts` and
`gam <UserTypeEntity> print filelist countsonly` that displays the total file size for each MIME type.
### 6.65.00
Fixed bug in `gam <UserTypeEntity> create contact <JSONData>` that caused a trap when
contacts were being copied from one user to another.
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-People-Contacts-Profiles#copy-user-contacts-to-another-user
Updated the following commands to allow specification of a task list by its title.
```
<TaskListTitle> ::= tltitle:<String>
<TasklistTitleList> ::= "'<TasklistTitle>'(,'<TasklistTitle>')*"
<TasklistEntity> ::=
<TasklistIDList> | <TaskListTitleList> | <FileSelector> | <CSVFileSelector>
gam <UserTypeEntity> create task <TasklistEntity>
gam <UserTypeEntity> show tasks [tasklists <TasklistEntity>]
gam <UserTypeEntity> print tasks [tasklists <TasklistEntity>]
gam <UserTypeEntity> update tasklist <TasklistEntity>
gam <UserTypeEntity> delete tasklist <TasklistEntity>
gam <UserTypeEntity> clear tasklist <TasklistEntity>
gam <UserTypeEntity> info tasklist <TasklistEntity>
```
Note the quoting in `<TasklistTitleList>`; the entire list should be enclosed in `"` and
each `tltitle:<String>` must be enclosed in `'` if `<String>` contains a space.
### 6.64.16
Fixed bug in `gam <UserTypeEntity> create task <TasklistIDEntity>` that caused a trap
when an invalid TaskListID was specified.
### 6.64.15
Updated `lookerstudioassets|lookerstudiopermissions` commands to handle the following error:
```
ERROR: 500: internalError - Internal error encountered.
```
### 6.64.14
Cleaned up and renamed `gam info appdetails` to `gam info chromeapp`.
### 6.64.13
Added command to get customer app details.
```
gam info appdetails android|chrome|web <AppID> [formatjson]
```
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Chrome-Installed-Apps
### 6.64.12
Upgraded to Python 3.12.0 where possible.
Upgraded to OpenSSL 3.1.3 where possible.
### 6.64.11
Added support for Google Workspace Labs license.
* ProductID - 101047
* SKUID - 1010470002 | gwlabs | workspacelabs
### 6.64.10
Fixed bug introduced in 6.64.09 that caused a trap when `gam redirect csv <FileName> multiprocess` was used.
### 6.64.09
Eliminated extraneous `permisssions.0.xxxx` headers in `gam <UserTypeEntity> print filelist ... oneitemperrow`
that appeared when some user in `<UserTypeEntity>` had no files to display.
### 6.64.08
Fixed bug in `redirect csv - todrive tdtitle "File Title" tdsheettitle "Sheet Title"` where
"Sheet Title" was not assigned to the new sheet.
### 6.64.07
Updated `gam <UserTypeEntity> move drivefile` to handle the following error:
```
ERROR: 403: targetUserRoleLimitedByLicenseRestriction - Cannot set the requested role for that user as they lack the necessary license
```
### 6.64.06
Added fields `devicelicensetype` and `osupdatestatus` to `<CrOSFieldName>`.
### 6.64.05
Added `matchfield organizerself <Boolean>` to `<EventMatchProperty>` to simplify selecting events
where the user in the following commands is/is not the organizer of the event.
```
gam <UserTypeEntity> update events <UserCalendarEntity> [<EventEntity>]
gam <UserTypeEntity> delete events <UserCalendarEntity> [<EventEntity>]
gam <UserTypeEntity> purge events <UserCalendarEntity> [<EventEntity>]
gam <UserTypeEntity> move events <UserCalendarEntity> [<EventEntity>]
gam <UserTypeEntity> info events <UserCalendarEntity> [<EventEntity>]
gam <UserTypeEntity> show events <UserCalendarEntity> [<EventEntity>]
gam <UserTypeEntity> print events <UserCalendarEntity> [<EventEntity>]
gam <UserTypeEntity> update calattendees <UserCalendarEntity> <EventEntity>
```
### 6.64.04
Updated `gam calendars <CalendarEntity> move events` and `gam <UserTypeEntity> move events <UserCalendarEntity>`
to handle the following error:
```
ERROR: 400: badRequest - Bad Request
```
### 6.64.03
Updated `gam <UserTypeEntity> get drivefile` to allow downloading Jamboard files; they must be downloaded with `format pdf`.
### 6.64.02
Updated `gam <UserTypeEntity> transfer drive` to handle the following error:
```
ERROR: 400: Bad Request. User message: "The action cannot be performed on an item of mime-type: application/vnd.google-apps.shortcut" - invalidSharingRequest
```
### 6.64.01
Updated `gam <UserTypeEntity> print|show youtubechannels` to handle the following error:
```
ERROR: 403: unsupportedSupervisedAccount - Access Forbidden. The authenticated user cannot access this service.
```
### 6.64.00
Added support for displaying users YouTube channels.
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-YouTube
### 6.63.19
Fixed bug in `gam print vacation` where `endDate` value was not converted to `yyyy-mm-dd` format.
### 6.63.18
Updated `gam print|show ownership` to show the correct file owner when the most recent event is `change_owner`.
### 6.63.17
Added support for Duet AI license.
* ProductID - 101047
* SKUID - 1010470001 | duetai
Added `api_call_tries_limit` variable to `gam.cfg` that limits the number of tries
for Google API calls that return an error that indicates a retry should be performed.
The default value is 10 and the range of allowable values is 3-10.
### 6.63.16
Arguments `noinherit`, `blockinheritance` and `blockinheritance true` have been removed from the following
commands due to an upcoming API change that no longer allows blocking OU setting inheritance.
Arguments `inherit` and `blockinheritance false` are still valid.
```
gam create org <OrgUnitPath>
gam update org <OrgUnitItem>
gam update orgs <OrgUnitEntity>
```
### 6.63.15
Added `print_cros_ous` and `print_cros_ous_and_children` variables to `gam.cfg` that provide a default list of OUs for these commands:
```
gam print cros
gam print crosactivity
```
Updated `group` commands that manage members to handle the following error:
```
ERROR: 503: serviceNotAvailable - The service is currently unavailable.
```
Updated Data Studio to Looker Studio; added the following command synonyms:
* `lookerstudioassets` for `datastudioassets`
* 'lookerstudiopermissions` for `datastudiopermissions`
Corrected error message in `gam add datastudiopermissions`:
* Old -`ERROR: Missing argument: Expected <DataStudioAssetMembersEntity>`
* New - `ERROR: Missing argument: Expected <LookerStudioPermissionEntity>
### 6.63.14
Added option `verifyorganizer [<Boolean>]` to `gam <UserTypeEntity> copy|move drivefile`. When a copy/move
operation involves a Shared Drive, GAM verifies that the user is an organizer. Unfortunatley, this fails
when the user is not a direct organizer but is a member of a group that is an organizer. Specifying
`verifyorganizer false` suppresses the verification.
Updated the following commands to be able to specify a list of domains rather than a single domain:
```
gam print aliases
gam print groups
gam print|show group-members
gam print users
```
Added `print_agu_domains` variable to `gam.cfg` that provides a default list of domains for these commands.
When multiple domains are specified and a query/queries are specified, an API call is made for each domain/query combination.
```
$ gam print users domains school.org,students.school.org queries "'email:admin*','email:test*'"
Getting all Users that match query (domain=school.org, query="email:admin*"), may take some time on a large Google Workspace Account...
Got 3 Users: admin@school.org - admindirector@school.org
Getting all Users that match query (domain=school.org, query="email:test*"), may take some time on a large Google Workspace Account...
Got 20 Users: testusera@school.org - testuserx@school.org
Getting all Users that match query (domain=students.school.org, query="email:admin*"), may take some time on a large Google Workspace Account...
Got 1 User: admin@students.school.org - admin@students.school.org
Getting all Users that match query (domain=students.school.org, query="email:test*"), may take some time on a large Google Workspace Account...
Got 1 User: testuser1@students.school.org - testuser1@students.school.org
primaryEmail
...
```
### 6.63.13
Updated `gam <UserTypeEntity> print filelist ... showdrivename` and `gam <UserTypeEntity> show fileinfo <DriveFileEntity> ... showdrivename`
to show the actual name of Shared Drives in other domains rather than `Drive`.
### 6.63.12
Updated commands that call the Reports API (including `gam info domain`) to handle a change
in the Reports API that generated the following warning:
```
WARNING: End date greater than LastReportedDate.
```
Added option `showdeleted [<Boolean>]' to `gam <UserTypeEntity> print|show chatmessages`.
### 6.63.11
Added option `ou_and_children <OrgUnitItem>` to `gam print|show crostelemetry` to simplify getting
telemetry data for all ChromeOS devices in an OU and its children.
### 6.63.10
Added option `addcsvdata <FieldName> <String>` to these commands. This adds additional columns of data to the CSV file output
when the `csv` option is used. If a CSV file of calendar information is being used to specify the calenders, fields, e.g., summary
can be added to the ACL output file.
```
gam <UserTypeEntity> print calendaracls <UserCalendarEntity>
gam resource <ResourceID> print calendaracls
gam resources <ResourceEntity> print calendaracls
gam calendar <CalendarEntity> printacl
gam calendars <CalendarEntity> print acls
```
Added commands to show the number of CrOS devices or Users in an entity.
```
gam <CrOSTypeEntity> show count
gam <UserTypeEntity> show count
```
Updated `gam create project` to prompt user to mark `GAM Project Creation` as a trusted app.
### 6.63.09
Updated `gam create teamdrive` to handle the following error:
```
ERROR: 403: userCannotCreateTeamDrives - The authenticated user cannot create new shared drives.
```
### 6.63.08
Updated `cigroup` commands to handle the following error:
```
ERROR: 400: invalidArgument - Request contains an invalid argument.
```
### 6.63.07
Fixed bug in `gam <UserTypeEntity> append sheetrange` that caused a trap when appending to an empty sheet.
Upgraded to Python 3.11.5 where possible.
### 6.63.06
Updated `cigroup` commands to handle the following error:
```
ERROR: 503: serviceNotAvailable - The service is currently unavailable.
```
### 6.63.05
Updated `inboundsso` commands to handle the following error:
```
ERROR: 503: serviceNotAvailable - The service is currently unavailable.
```
### 6.63.04
Added option `ignorerole` to `gam update groups|cigroups <GroupEntity> sync [<GroupRole>|ignorerole] ... <UserTypeEntity>` that causes GAM
to remove members regardless of role and add new members with role MEMBER. This is a special purpose option, use with caution
and ensure that `<UserTypeEntity>` specifies the full desired membership list of all roles.
### 6.63.03
Added option `externalusersallowed <Boolean>` to `gam <UserTypeEntity> create chatspace`
that allows creation of chat spaces that allow external users.
Updated commands that process chat members to allow external users.
### 6.63.02
Fixed bug in `gam <UserTypeEntity> collect orphans` where shortcuts were being created unnecessarily
when `useshortcuts` was false; either by default or when explicitly set.
### 6.63.01
Added `process_wait_limit` variable to `gam.cfg` that controls how long (in seconds) GAM should wait for all batch|csv processes to complete
after all have been started. If the limit is reached, GAM terminates any remaining processes. The default is 0 which specifies no limit.
Following Jay's lead, added option `alwaysevict` to `gam create|update user` that is used to specify GAM's
behavior when `verifynotinvitable` is not specified and there is a conflict with an unmanaged account.
By default, when creating a user that has a conflict with an unmanaged account, GAM will honor the setting on this page:
* https://admin.google.com/ac/accountsettings/conflictaccountmanagement
Specifying `alwaysevict` forces GAM to select this setting: `Replace conflicting unmanaged accounts with managed ones`
With `gam update user`, `alwaysevict` only applies if `createifnotfound` is specified and the user was not found to update and must be created.
### 6.63.00
Added support for calendar working location events.
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-Calendars-Events#working-location-events
### 6.62.08
Added option `addcsvdata <FieldName> <String>` to these commands. This adds additional columns of data to the CSV file output
when the `csv` option is used.
```
gam create contact
gam <UserTypeEntity> create contact
gam <UserTypeEntity> create contactgroup
```
### 6.62.07
Added option `csv [todrive <ToDriveAttribute>*]` to these commands that causes GAM to output
the contact creator and contact ID in CSV form. This will be useful when bulk contacts are created.
Added `returnidonly` to these commands that causes GAM to return just the
contact ID as output. This will be useful in scripts that create a contact and then
want to perform subsequent GAM commands on the contact.
```
gam create contact
gam <UserTypeEntity> create contact
gam <UserTypeEntity> create contactgroup
```
### 6.62.06
Added output `Item cap` to `gam <UserTypeEntity> print filecounts select select <SharedDriveEntity>` that
displays the total number of files/folders on the Shared Drive divided by 400000, the maximum number of file/folders on a Shared Drive.
### 6.62.05

View File

@@ -1,4 +1,4 @@
# Groups - Membership
Groups - Membership
- [API documentation](#api-documentation)
- [Python Regular Expressions](Python-Regular-Expressions) Match function
- [Definitions](#definitions)
@@ -19,6 +19,7 @@
* https://developers.google.com/admin-sdk/directory/v1/reference/members
## Definitions
See [Collections of Items](Collections-of-Items)
```
<DeliverySetting> ::=
allmail|
@@ -27,18 +28,24 @@
disabled|
none|nomail
<DomainName> ::= <String>(.<String>)+
<DomainNameList> ::= "<DomainName>(,<DomainName>)*"
<DomainNameEntity> ::=
<DomainNameList> | <FileSelector> | <CSVFileSelector>
<EmailAddress> ::= <String>@<DomainName>
<EmailItem> ::= <EmailAddress>|<UniqueID>|<String>
<UniqueID> ::= id:<String>
<GroupItem> ::= <EmailAddress>|<UniqueID>|<String>
<GroupList> ::= "<GroupItem>(,<GroupItem>)*"
<GroupEntity> ::= <GroupList>|<FileSelector>|<CSVkmdSelector>|<CSVDataSelector>
<GroupEntity> ::=
<GroupList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<GroupRole> ::= owner|manager|member
<GroupRoleList> ::= "<GroupRole>(,<GroupRole>)*"
<GroupType> ::= customer|group|user
<GroupTypeList> ::= "<GroupType>(,<GroupType>)*"
<QueryGroup> ::= <String>
See: https://developers.google.com/admin-sdk/directory/v1/guides/search-groups
<QueryGroupList> ::= "<QueryGroup>(,<QueryGroup>)*"
<MembersFieldName> ::=
delivery|deliverysettings|
@@ -106,7 +113,7 @@ users in a particular archived state. This option can be used with the following
(query <QueryUser>)|
(queries <QueryUserList>)
```
Prior to bersion `6.20.05`, the `notarchived|archived` option could only be used with the following `<UserTypeEntity>`:
Prior to version `6.20.05`, the `notarchived|archived` option could only be used with the following `<UserTypeEntity>`:
```
(group|group_ns|group_susp <GroupItem>)|
(groups|groups_ns|groups_susp <GroupList>)|
@@ -211,8 +218,9 @@ testgroup@domain.com,testuser4@domain.com,MEMBER,Remove Failed,Does not exist
## Synchronize members in a group
A synchronize operation gets the current membership for a group and does adds and deletes as necessary to make it match `<UserTypeEntity>`.
This is done by specific role except for a special case where role is ignored.
```
gam update group|groups <GroupEntity> sync [<GroupRole>]
gam update group|groups <GroupEntity> sync [<GroupRole>|ignorerole]
[usersonly|groupsonly] [addonly|removeonly]
[notsuspended|suspended] [notarchived|archived]
[remove_domain_nostatus_members]
@@ -221,7 +229,10 @@ gam update group|groups <GroupEntity> sync [<GroupRole>]
(additionalmembers [<GroupRole>] <EmailAddressEntity>)*
<UserItem>|<UserTypeEntity>
```
If `<GroupRole>` is not specified, `member` is assumed.
If `ignorerole` is specified, GAM removes members regardless of role and adds new members with role MEMBER.
This is a special purpose option, use with caution and ensure that `<UserTypeEntity>` specifies the full desired membership list of all roles.
If neither `<GroupRole>` nor `ignorerole` is specified, `member` is assumed.
When `<UserTypeEntity>` specifies a group or groups:
* `usersonly` - Only the user members from the specified groups are added/deleted
@@ -557,7 +568,7 @@ gam info member|group-members <UserItem>|<UserTypeEntity> <GroupEntity>
By default, delivery information is not displayed.
```
gam print group-members [todrive <ToDriveAttribute>*]
[([domain <DomainName>] ([member|showownedby <EmailItem>]|[query <QueryGroup>]))|
[([domain|domains <DomainNameEntity>] ([member|showownedby <EmailItem>]|[(query <QueryGroup>)|(queries <QueryGroupList>)]))|
(group|group_ns|group_susp <GroupItem>)|
(select <GroupEntity>)]
[emailmatchpattern [not] <RegularExpression>] [namematchpattern [not] <RegularExpression>]
@@ -575,10 +586,11 @@ gam print group-members [todrive <ToDriveAttribute>*]
[formatjson [quotechar <Character>]]
```
By default, the group membership of all groups in the account are displayed, these options allow selection of subsets of groups:
* `domain <DomainName>` - Limit display to groups in the domain `<DomainName>`
* `domain|domains <DomainNameEntity>` - Limit display to groups in the domains specified by `<DomainNameEntity>`
* You can predefine this list with the `print_agu_domains` variable in `gam.cfg`.
* `member <EmailItem>` - Limit display to groups that contain `<EmailItem>` as a member; mutually exclusive with `query <QueryGroup>`
* `showownedby <EmailItem>` - Limit display to groups that contain `<EmailItem>` as an owner; mutually exclusive with `query <QueryGroup>`
* `query <QueryGroup>` - Limit display to groups that match `<QueryGroup>`, matching is done at Google; mutually exclusive with `member <UserItem>`
* `(query <QueryGroup>)|(queries <QueryGroupList>)` - Limit groups to those that match a query; each query is run against each domain
* `group <GroupItem>` - Limit display to the single group `<GroupItem>`
* `group_ns <GroupItem>` - Limit display to the single group `<GroupItem>`, display non-suspended members
* `group_susp <GroupItem>` - Limit display to the single group `<GroupItem>`, display suspended members
@@ -673,7 +685,7 @@ The `quotechar <Character>` option allows you to choose an alternate quote chara
## Display group membership in hierarchical format
```
gam show group-members
[([domain <DomainName>] ([member|showownedby <EmailItem>]|[query <QueryGroup>]))|
[([domain|domains <DomainNameEntity>] ([member|showownedby <EmailItem>]|[(query <QueryGroup>)|(queries <QueryGroupList>)]))|
(group|group_ns|group_susp <GroupItem>)|
(select <GroupEntity>)]
[emailmatchpattern [not] <RegularExpression>] [namematchpattern [not] <RegularExpression>]
@@ -686,10 +698,11 @@ gam show group-members
[includederivedmembership]
```
By default, the group membership of all groups in the account are displayed, these options allow selection of subsets of groups:
* `domain <DomainName>` - Limit display to groups in the domain `<DomainName>`
* `domain|domains <DomainNameEntity>` - Limit display to groups in the domains specified by `<DomainNameEntity>`
* You can predefine this list with the `print_agu_domains` variable in `gam.cfg`.
* `member <EmailItem>` - Limit display to groups that contain `<EmailItem>` as a member; mutually exclusive with `query <QueryGroup>`
* `showownedby <EmailItem>` - Limit display to groups that contain `<EmailItem>` as an owner; mutually exclusive with `query <QueryGroup>`
* `query <QueryGroup>` - Limit display to groups that match `<QueryGroup>`, matching is done at Google; mutually exclusive with `member <UserItem>`
* `(query <QueryGroup>)|(queries <QueryGroupList>)` - Limit groups to those that match a query; each query is run against each domain
* `group <GroupItem>` - Limit display to the single group `<GroupItem>`
* `group_ns <GroupItem>` - Limit display to the single group `<GroupItem>`, display non-suspended members
* `group_susp <GroupItem>` - Limit display to the single group `<GroupItem>`, display suspended members

View File

@@ -11,7 +11,7 @@
- [GUI API Group settings mapping](#gui-api-group-settings-mapping)
- [GUI API Group access type settings mapping](#gui-api-group-access-type-settings-mapping)
- [Manage groups](#manage-groups)
- [Update a group's settings with JSON data](#update-a-groups-settings-with-JSON-data)
- [Update a group's settings with JSON data](#update-a-groups-settings-with-json-data)
- [Display information about specific groups](#display-information-about-specific-groups)
- [Display information about selected groups](#display-information-about-selected-groups)
- [Display a group and its parents](#Display-a-group-and-its-parents)
@@ -44,20 +44,27 @@
* https://support.google.com/a/answer/167430
## Definitions
See [Collections of Items](Collections-of-Items)
```
<DomainName> ::= <String>(.<String>)+
<DomainNameList> ::= "<DomainName>(,<DomainName>)*"
<DomainNameEntity> ::=
<DomainNameList> | <FileSelector> | <CSVFileSelector>
<EmailAddress> ::= <String>@<DomainName>
<UniqueID> ::= id:<String>
<EmailItem> ::= <EmailAddress>|<UniqueID>|<String>
<GroupItem> ::= <EmailAddress>|<UniqueID>|<String>
<GroupList> ::= "<GroupItem>(,<GroupItem>)*"
<GroupEntity> ::= <GroupList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<GroupEntity> ::=
<GroupList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<GroupRole> ::= owner|manager|member
<GroupRoleList> ::= "<GroupRole>(,<GroupRole>)*"
<GroupType> ::= customer|group|user
<GroupTypeList> ::= "<GroupType>(,<GroupType>)*"
<QueryGroup> ::= <String>
See: https://developers.google.com/admin-sdk/directory/v1/guides/search-groups
<QueryGroupList> ::= "<QueryGroup>(,<QueryGroup>)*"
<QueryDynamicGroup> ::= <String>
See: https://cloud.google.com/identity/docs/reference/rest/v1/groups#dynamicgroupquery
@@ -402,7 +409,7 @@ By default, Gam displays the information as an indented list of keys and values.
This command displays information in CSV format.
```
gam print groups [todrive <ToDriveAttribute>*]
[([domain <DomainName>] ([member|showownedby <EmailItem>]|[query <QueryGroup>]))|
[([domain|domains <DomainNameEntity>] ([member|showownedby <EmailItem>]|[(query <QueryGroup>)|(queries <QueryGroupList>)]))|
(select <GroupEntity>)]
[emailmatchpattern [not] <RegularExpression>] [namematchpattern [not] <RegularExpression>]
[descriptionmatchpattern [not] <RegularExpression>] (matchsetting [not] <GroupAttribute>)*
@@ -421,12 +428,12 @@ gam print groups [todrive <ToDriveAttribute>*]
[formatjson [quotechar <Character>]]
```
By default, all groups in the account are displayed, these options allow selection of subsets of groups:
* `domain <DomainName>` - Limit display to groups in the domain `<DomainName>`
* `domain|domains <DomainNameEntity>` - Limit display to groups in the domains specified by `<DomainNameEntity>`
* You can predefine this list with the `print_agu_domains` variable in `gam.cfg`.
* `member <EmailItem>` - Limit display to groups that contain `<EmailItem>` as a member; mutually exclusive with `query <QueryGroup>`
* `showownedby <EmailItem>` - Limit display to groups that contain `<EmailItem>` as an owner; mutually exclusive with `query <QueryGroup>`
* `query <QueryGroup>` - Limit display to groups that match <QueryGroup>, matching is done at Google; mutually exclusive with `member <UserItem>`
* `(query <QueryGroup>)|(queries <QueryGroupList>)` - Limit groups to those that match a query; each query is run against each domain
* `select <GroupEntity>` - Limit display to the groups specified in `<GroupEntity>`
* `showownedby <UserItem>` - Limit display to groups owned by `<UserItem>`
When using `query <QueryGroup>` with the `name:{PREFIX}*` query, `PREFIX` must contain at least three characters.

70
docs/Home.md Normal file
View File

@@ -0,0 +1,70 @@
- [Introduction](#introduction)
- [Requirements](#requirements)
- [Installation - First time GAM installation](#installation---first-time-gam-installation)
- [Installation - Upgrading from a GAM version other than a prior version of GAMADV-X or GAMADV-XTD or GAMADV-XTD3](#installation---upgrading-from-a-gam-version-other-than-a-prior-version-of-gamadv-x-or-gamadv-xtd-or-gamadv-xtd3)
- [Installation - Upgrading from a prior version of GAMADV-X or GAMADV-XTD or GAMADV-XTD3](#installation---upgrading-from-a-prior-version-of-gamadv-x-or-gamadv-xtd-or-gamadv-xtd3)
# Introduction
GAMADV-XTD3 is a free, open source command line tool for Google Workspace Administrators to manage domain and user settings quickly and easily.
GAMADV-XTD3 is built with Python 3; as Python 2 support ends on 2020-01-01, this is the version of Advanced GAM that new/existing users should install.
This page provides simple instructions for downloading, installing and starting to use GAMADV-XTD3.
GAMADV-XTD3 requires paid, or Education/Non-profit, editions of Google Workspace. G Suite Legacy Free Edition has limited API support and not all GAM commands work.
GAMADV-XTD3 is a rewrite/extension of Jay Lee's [GAM], without his efforts, this version wouldn't exist.
GAMADV-XTD3 is backwards compatible with [GAM], meaning that if your command works with regular GAM, it will also work with GAMADV-XTD3. There may be differences in output, but the syntax is compatible.
# Documentation
Basic GAM documentation is hosted in the [GitHub Wiki]. Documentation specifically for GAMADV-XTD3 is hosted in the [GitHub GAMADV-XTD3 Wiki] and in Gam*.txt files.
# Mailing List / Discussion group
The GAM mailing list / discussion group is hosted on [Google Groups]. You can join the list and interact via email, or just post from the web itself.
# Source Repository
The official GAMADV-XTD3 source repository is on [GitHub] in the master branch.
# Author
GAMADV-XTD3 is maintained by <a href="mailto:ross.scroggs@gmail.com">Ross Scroggs</a>.
# Requirements
To run all commands properly, GAMADV-XTD3 requires three things:
* An API project which identifies your install of GAMADV-XTD3 to Google and keeps track of API quotas.
* Authorization to act as your Google Workspace Administrator in order to perform management functions like add users, modify group settings and membership and pull domain reports.
* A special service account that is authorized to act on behalf of your users in order to modify user-specific settings and data such as Drive files, Calendars and Gmail messages and settings like signatures.
# Installation - First time GAM installation
Use these steps if you have never used any version of GAM in your domain. They will create a GAM project
and all necessary authentications.
* Download: [Downloads](Downloads)
* Configuration: [GAM Configuration](gam.cfg)
* Install: [How to Install Advanced GAM](How-to-Install-Advanced-GAM)
# Installation - Upgrading from a GAM version other than a prior version of GAMADV-X or GAMADV-XTD or GAMADV-XTD3
Use these steps if you have used any version of GAM in your domain. They will update your GAM project
and all necessary authentications.
* Download: [Downloads](Downloads)
* Configuration: [GAM Configuration](gam.cfg)
* Upgrade: [How to Upgrade from Standard GAM](How-to-Upgrade-from-Standard-GAM)
# Installation - Upgrading from a prior version of GAMADV-X or GAMADV-XTD or GAMADV-XTD3
Use these steps if you already use GAMADV-X or GAMADV-XTD or GAMADV-XTD3. The updates may tell you to update your GAM project
or authentications because new features have been included.
* Updates: [GAM Updates]
* Download: [Downloads](Downloads)
You can install multiple versions of GAM and GAMADV-XTD3 in different parallel directories.
[GAM]: https://github.com/GAM-team/GAM
[GitHub Releases]: https://github.com/taers232c/GAMADV-XTD3/releases
[GitHub]: https://github.com/taers232c/GAMADV-XTD3/tree/master
[GitHub Wiki]: https://github.com/GAM-team/GAM/wiki/
[GitHub GAMADV-XTD3 Wiki]: https://github.com/taers232c/GAMADV-XTD3/wiki/
[Google Groups]: https://groups.google.com/group/google-apps-manager
[GAM Updates]: https://github.com/taers232c/GAMADV-XTD3/wiki/GamUpdates

View File

@@ -269,55 +269,61 @@ Append an 'r' to grant read-only access or an 'a' to grant action-only access.
[*] 0) Calendar API (supports readonly)
[*] 1) Chrome Browser Cloud Management API (supports readonly)
[*] 2) Chrome Management API - Telemetry read only
[*] 3) Chrome Management API - read only
[*] 4) Chrome Policy API (supports readonly)
[*] 5) Chrome Printer Management API (supports readonly)
[*] 6) Chrome Version History API
[*] 7) Classroom API - Course Announcements (supports readonly)
[*] 8) Classroom API - Course Topics (supports readonly)
[*] 9) Classroom API - Course Work/Materials (supports readonly)
[*] 10) Classroom API - Course Work/Submissions (supports readonly)
[*] 11) Classroom API - Courses (supports readonly)
[*] 12) Classroom API - Profile Emails
[*] 13) Classroom API - Profile Photos
[*] 14) Classroom API - Rosters (supports readonly)
[*] 15) Classroom API - Student Guardians (supports readonly)
[*] 16) Cloud Identity Groups API (supports readonly)
[*] 17) Cloud Storage (Vault Export - read only)
[*] 18) Contact Delegation API (supports readonly)
[*] 19) Contacts API - Domain Shared and Users and GAL
[*] 20) Data Transfer API (supports readonly)
[*] 21) Directory API - Chrome OS Devices (supports readonly)
[*] 22) Directory API - Customers (supports readonly)
[*] 23) Directory API - Domains (supports readonly)
[*] 24) Directory API - Groups (supports readonly)
[*] 25) Directory API - Mobile Devices Directory (supports readonly and action)
[*] 26) Directory API - Organizational Units (supports readonly)
[*] 27) Directory API - Resource Calendars (supports readonly)
[*] 28) Directory API - Roles (supports readonly)
[*] 29) Directory API - User Schemas (supports readonly)
[*] 30) Directory API - User Security
[*] 31) Directory API - Users (supports readonly)
[*] 32) Email Audit API
[*] 33) Groups Migration API
[*] 34) Groups Settings API
[*] 35) License Manager API
[*] 36) People API (supports readonly)
[*] 37) People Directory API - read only
[ ] 38) Pub / Sub API
[*] 39) Reports API - Audit Reports
[*] 40) Reports API - Usage Reports
[ ] 41) Reseller API
[*] 42) Site Verification API
[*] 43) Sites API
[*] 44) Vault API (supports readonly)
[*] 2) Chrome Management API - AppDetails read only
[*] 3) Chrome Management API - Telemetry read only
[*] 4) Chrome Management API - read only
[*] 5) Chrome Policy API (supports readonly)
[*] 6) Chrome Printer Management API (supports readonly)
[ ] 7) Chrome Version History API
[*] 8) Classroom API - Course Announcements (supports readonly)
[*] 9) Classroom API - Course Topics (supports readonly)
[*] 10) Classroom API - Course Work/Materials (supports readonly)
[*] 11) Classroom API - Course Work/Submissions (supports readonly)
[*] 12) Classroom API - Courses (supports readonly)
[*] 13) Classroom API - Profile Emails
[*] 14) Classroom API - Profile Photos
[*] 15) Classroom API - Rosters (supports readonly)
[*] 16) Classroom API - Student Guardians (supports readonly)
[*] 17) Cloud Channel API (supports readonly)
[*] 18) Cloud Identity - Inbound SSO Settings (supports readonly)
[*] 19) Cloud Identity Groups API (supports readonly)
[*] 20) Cloud Identity OrgUnits API (supports readonly)
[*] 21) Cloud Identity User Invitations API (supports readonly)
[ ] 22) Cloud Storage API (Read Only, Vault/Takeout Download, Cloud Storage)
[ ] 23) Cloud Storage API (Read/Write, Vault/Takeout Copy/Download, Cloud Storage)
[*] 24) Contact Delegation API (supports readonly)
[*] 25) Contacts API - Domain Shared Contacts and GAL
[*] 26) Data Transfer API (supports readonly)
[*] 27) Directory API - Chrome OS Devices (supports readonly)
[*] 28) Directory API - Customers (supports readonly)
[*] 29) Directory API - Domains (supports readonly)
[*] 30) Directory API - Groups (supports readonly)
[*] 31) Directory API - Mobile Devices Directory (supports readonly and action)
[*] 32) Directory API - Organizational Units (supports readonly)
[*] 33) Directory API - Resource Calendars (supports readonly)
[*] 34) Directory API - Roles (supports readonly)
[*] 35) Directory API - User Schemas (supports readonly)
[*] 36) Directory API - User Security
[*] 37) Directory API - Users (supports readonly)
[ ] 38) Email Audit API
[*] 39) Groups Migration API
[*] 40) Groups Settings API
[*] 41) License Manager API
[*] 42) People API (supports readonly)
[*] 43) People Directory API - read only
[ ] 44) Pub / Sub API
[*] 45) Reports API - Audit Reports
[*] 46) Reports API - Usage Reports
[*] 47) Reseller API
[*] 48) Site Verification API
[ ] 49) Sites API
[*] 50) Vault API (supports readonly)
s) Select all scopes
u) Unselect all scopes
e) Exit without changes
c) Continue to authorization
Please enter 0-44[a|r] or s|u|e|c: c
Please enter 0-50[a|r] or s|u|e|c: c
Enter your Google Workspace admin email address? admin@domain.com
@@ -348,35 +354,41 @@ Service Account Private Key Authentication
Authentication PASS
Service Account Private Key age; Google recommends rotating keys on a routine basis
Service Account Private Key age: 0 days PASS
Domain-Wide Delegation authentication:, User: admin@domain.com, Scopes: 28
https://mail.google.com/ PASS (1/28)
https://sites.google.com/feeds PASS (2/28)
https://www.googleapis.com/auth/apps.alerts PASS (3/28)
https://www.googleapis.com/auth/calendar PASS (4/28)
https://www.googleapis.com/auth/classroom.announcements PASS (5/28)
https://www.googleapis.com/auth/classroom.coursework.students PASS (6/28)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (7/28)
https://www.googleapis.com/auth/classroom.profile.emails PASS (8/28)
https://www.googleapis.com/auth/classroom.rosters PASS (9/28)
https://www.googleapis.com/auth/classroom.topics PASS (10/28)
https://www.googleapis.com/auth/cloud-identity PASS (11/28)
https://www.googleapis.com/auth/cloud-platform PASS (12/28)
https://www.googleapis.com/auth/contacts PASS (13/28)
https://www.googleapis.com/auth/contacts.other.readonly PASS (14/28)
https://www.googleapis.com/auth/datastudio PASS (15/28)
https://www.googleapis.com/auth/directory.readonly PASS (16/28)
https://www.googleapis.com/auth/documents PASS (17/28)
https://www.googleapis.com/auth/drive PASS (18/28)
https://www.googleapis.com/auth/drive.activity PASS (19/28)
https://www.googleapis.com/auth/drive.admin.labels FAIL (20/28)
https://www.googleapis.com/auth/drive.labels FAIL (21/28)
https://www.googleapis.com/auth/gmail.modify PASS (22/28)
https://www.googleapis.com/auth/gmail.settings.basic PASS (23/28)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (24/28)
https://www.googleapis.com/auth/keep PASS (25/28)
https://www.googleapis.com/auth/spreadsheets PASS (26/28)
https://www.googleapis.com/auth/tasks PASS (27/28)
https://www.googleapis.com/auth/userinfo.profile PASS (28/28)
Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 34
https://mail.google.com/ PASS (1/34)
https://sites.google.com/feeds PASS (2/34)
https://www.googleapis.com/auth/analytics.readonly PASS (3/34)
https://www.googleapis.com/auth/apps.alerts PASS (4/34)
https://www.googleapis.com/auth/calendar PASS (5/34)
https://www.googleapis.com/auth/chat.delete PASS (6/34)
https://www.googleapis.com/auth/chat.memberships PASS (7/34)
https://www.googleapis.com/auth/chat.messages PASS (8/34)
https://www.googleapis.com/auth/chat.spaces PASS (9/34)
https://www.googleapis.com/auth/classroom.announcements PASS (10/34)
https://www.googleapis.com/auth/classroom.coursework.students PASS (11/34)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (12/34)
https://www.googleapis.com/auth/classroom.profile.emails PASS (13/34)
https://www.googleapis.com/auth/classroom.rosters PASS (14/34)
https://www.googleapis.com/auth/classroom.topics PASS (15/34)
https://www.googleapis.com/auth/cloud-identity PASS (16/34)
https://www.googleapis.com/auth/cloud-platform PASS (17/34)
https://www.googleapis.com/auth/contacts PASS (18/34)
https://www.googleapis.com/auth/contacts.other.readonly PASS (19/34)
https://www.googleapis.com/auth/datastudio PASS (20/34)
https://www.googleapis.com/auth/directory.readonly PASS (21/34)
https://www.googleapis.com/auth/documents PASS (22/34)
https://www.googleapis.com/auth/drive PASS (23/34)
https://www.googleapis.com/auth/drive.activity PASS (24/34)
https://www.googleapis.com/auth/drive.admin.labels FAIL (25/34)
https://www.googleapis.com/auth/drive.labels FAIL (26/34)
https://www.googleapis.com/auth/gmail.modify PASS (27/34)
https://www.googleapis.com/auth/gmail.settings.basic PASS (28/34)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (29/34)
https://www.googleapis.com/auth/keep PASS (30/34)
https://www.googleapis.com/auth/spreadsheets PASS (31/34)
https://www.googleapis.com/auth/tasks PASS (32/34)
https://www.googleapis.com/auth/userinfo.profile PASS (33/34)
https://www.googleapis.com/auth/youtube.readonly PASS (34/34)
Some scopes FAILED!
To authorize them, please go to:
@@ -404,35 +416,41 @@ System time status:
Your system time differs from www.googleapis.com by less than 1 second PASS
Service Account Private Key Authentication:
Authentication PASS
Domain-Wide Delegation authentication:, User: admin@domain.com, Scopes: 28
https://mail.google.com/ PASS (1/28)
https://sites.google.com/feeds PASS (2/28)
https://www.googleapis.com/auth/apps.alerts PASS (3/28)
https://www.googleapis.com/auth/calendar PASS (4/28)
https://www.googleapis.com/auth/classroom.announcements PASS (5/28)
https://www.googleapis.com/auth/classroom.coursework.students PASS (6/28)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (7/28)
https://www.googleapis.com/auth/classroom.profile.emails PASS (8/28)
https://www.googleapis.com/auth/classroom.rosters PASS (9/28)
https://www.googleapis.com/auth/classroom.topics PASS (10/28)
https://www.googleapis.com/auth/cloud-identity PASS (11/28)
https://www.googleapis.com/auth/cloud-platform PASS (12/28)
https://www.googleapis.com/auth/contacts PASS (13/28)
https://www.googleapis.com/auth/contacts.other.readonly PASS (14/28)
https://www.googleapis.com/auth/datastudio PASS (15/28)
https://www.googleapis.com/auth/directory.readonly PASS (16/28)
https://www.googleapis.com/auth/documents PASS (17/28)
https://www.googleapis.com/auth/drive PASS (18/28)
https://www.googleapis.com/auth/drive.activity PASS (19/28)
https://www.googleapis.com/auth/drive.admin.labels PASS (20/28)
https://www.googleapis.com/auth/drive.labels PASS (21/28)
https://www.googleapis.com/auth/gmail.modify PASS (22/28)
https://www.googleapis.com/auth/gmail.settings.basic PASS (23/28)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (24/28)
https://www.googleapis.com/auth/keep PASS (25/28)
https://www.googleapis.com/auth/spreadsheets PASS (26/28)
https://www.googleapis.com/auth/tasks PASS (27/28)
https://www.googleapis.com/auth/userinfo.profile PASS (28/28)
Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 34
https://mail.google.com/ PASS (1/34)
https://sites.google.com/feeds PASS (2/34)
https://www.googleapis.com/auth/analytics.readonly PASS (3/34)
https://www.googleapis.com/auth/apps.alerts PASS (4/34)
https://www.googleapis.com/auth/calendar PASS (5/34)
https://www.googleapis.com/auth/chat.delete PASS (6/34)
https://www.googleapis.com/auth/chat.memberships PASS (7/34)
https://www.googleapis.com/auth/chat.messages PASS (8/34)
https://www.googleapis.com/auth/chat.spaces PASS (9/34)
https://www.googleapis.com/auth/classroom.announcements PASS (10/34)
https://www.googleapis.com/auth/classroom.coursework.students PASS (11/34)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (12/34)
https://www.googleapis.com/auth/classroom.profile.emails PASS (13/34)
https://www.googleapis.com/auth/classroom.rosters PASS (14/34)
https://www.googleapis.com/auth/classroom.topics PASS (15/34)
https://www.googleapis.com/auth/cloud-identity PASS (16/34)
https://www.googleapis.com/auth/cloud-platform PASS (17/34)
https://www.googleapis.com/auth/contacts PASS (18/34)
https://www.googleapis.com/auth/contacts.other.readonly PASS (19/34)
https://www.googleapis.com/auth/datastudio PASS (20/34)
https://www.googleapis.com/auth/directory.readonly PASS (21/34)
https://www.googleapis.com/auth/documents PASS (22/34)
https://www.googleapis.com/auth/drive PASS (23/34)
https://www.googleapis.com/auth/drive.activity PASS (24/34)
https://www.googleapis.com/auth/drive.admin.labels PASS (25/34)
https://www.googleapis.com/auth/drive.labels PASS (26/34)
https://www.googleapis.com/auth/gmail.modify PASS (27/34)
https://www.googleapis.com/auth/gmail.settings.basic PASS (28/34)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (29/34)
https://www.googleapis.com/auth/keep PASS (30/34)
https://www.googleapis.com/auth/spreadsheets PASS (31/34)
https://www.googleapis.com/auth/tasks PASS (32/34)
https://www.googleapis.com/auth/userinfo.profile PASS (33/34)
https://www.googleapis.com/auth/youtube.readonly PASS (34/34)
All scopes PASSED!
Service Account Client name: SVCACCTID is fully authorized.
@@ -696,55 +714,61 @@ Append an 'r' to grant read-only access or an 'a' to grant action-only access.
[*] 0) Calendar API (supports readonly)
[*] 1) Chrome Browser Cloud Management API (supports readonly)
[*] 2) Chrome Management API - Telemetry read only
[*] 3) Chrome Management API - read only
[*] 4) Chrome Policy API (supports readonly)
[*] 5) Chrome Printer Management API (supports readonly)
[*] 6) Chrome Version History API
[*] 7) Classroom API - Course Announcements (supports readonly)
[*] 8) Classroom API - Course Topics (supports readonly)
[*] 9) Classroom API - Course Work/Materials (supports readonly)
[*] 10) Classroom API - Course Work/Submissions (supports readonly)
[*] 11) Classroom API - Courses (supports readonly)
[*] 12) Classroom API - Profile Emails
[*] 13) Classroom API - Profile Photos
[*] 14) Classroom API - Rosters (supports readonly)
[*] 15) Classroom API - Student Guardians (supports readonly)
[*] 16) Cloud Identity Groups API (supports readonly)
[*] 17) Cloud Storage (Vault Export - read only)
[*] 18) Contact Delegation API (supports readonly)
[*] 19) Contacts API - Domain Shared and Users and GAL
[*] 20) Data Transfer API (supports readonly)
[*] 21) Directory API - Chrome OS Devices (supports readonly)
[*] 22) Directory API - Customers (supports readonly)
[*] 23) Directory API - Domains (supports readonly)
[*] 24) Directory API - Groups (supports readonly)
[*] 25) Directory API - Mobile Devices Directory (supports readonly and action)
[*] 26) Directory API - Organizational Units (supports readonly)
[*] 27) Directory API - Resource Calendars (supports readonly)
[*] 28) Directory API - Roles (supports readonly)
[*] 29) Directory API - User Schemas (supports readonly)
[*] 30) Directory API - User Security
[*] 31) Directory API - Users (supports readonly)
[*] 32) Email Audit API
[*] 33) Groups Migration API
[*] 34) Groups Settings API
[*] 35) License Manager API
[*] 36) People API (supports readonly)
[*] 37) People Directory API - read only
[ ] 38) Pub / Sub API
[*] 39) Reports API - Audit Reports
[*] 40) Reports API - Usage Reports
[ ] 41) Reseller API
[*] 42) Site Verification API
[*] 43) Sites API
[*] 44) Vault API (supports readonly)
[*] 2) Chrome Management API - AppDetails read only
[*] 3) Chrome Management API - Telemetry read only
[*] 4) Chrome Management API - read only
[*] 5) Chrome Policy API (supports readonly)
[*] 6) Chrome Printer Management API (supports readonly)
[ ] 7) Chrome Version History API
[*] 8) Classroom API - Course Announcements (supports readonly)
[*] 9) Classroom API - Course Topics (supports readonly)
[*] 10) Classroom API - Course Work/Materials (supports readonly)
[*] 11) Classroom API - Course Work/Submissions (supports readonly)
[*] 12) Classroom API - Courses (supports readonly)
[*] 13) Classroom API - Profile Emails
[*] 14) Classroom API - Profile Photos
[*] 15) Classroom API - Rosters (supports readonly)
[*] 16) Classroom API - Student Guardians (supports readonly)
[*] 17) Cloud Channel API (supports readonly)
[*] 18) Cloud Identity - Inbound SSO Settings (supports readonly)
[*] 19) Cloud Identity Groups API (supports readonly)
[*] 20) Cloud Identity OrgUnits API (supports readonly)
[*] 21) Cloud Identity User Invitations API (supports readonly)
[ ] 22) Cloud Storage API (Read Only, Vault/Takeout Download, Cloud Storage)
[ ] 23) Cloud Storage API (Read/Write, Vault/Takeout Copy/Download, Cloud Storage)
[*] 24) Contact Delegation API (supports readonly)
[*] 25) Contacts API - Domain Shared Contacts and GAL
[*] 26) Data Transfer API (supports readonly)
[*] 27) Directory API - Chrome OS Devices (supports readonly)
[*] 28) Directory API - Customers (supports readonly)
[*] 29) Directory API - Domains (supports readonly)
[*] 30) Directory API - Groups (supports readonly)
[*] 31) Directory API - Mobile Devices Directory (supports readonly and action)
[*] 32) Directory API - Organizational Units (supports readonly)
[*] 33) Directory API - Resource Calendars (supports readonly)
[*] 34) Directory API - Roles (supports readonly)
[*] 35) Directory API - User Schemas (supports readonly)
[*] 36) Directory API - User Security
[*] 37) Directory API - Users (supports readonly)
[ ] 38) Email Audit API
[*] 39) Groups Migration API
[*] 40) Groups Settings API
[*] 41) License Manager API
[*] 42) People API (supports readonly)
[*] 43) People Directory API - read only
[ ] 44) Pub / Sub API
[*] 45) Reports API - Audit Reports
[*] 46) Reports API - Usage Reports
[*] 47) Reseller API
[*] 48) Site Verification API
[ ] 49) Sites API
[*] 50) Vault API (supports readonly)
s) Select all scopes
u) Unselect all scopes
e) Exit without changes
c) Continue to authorization
Please enter 0-44[a|r] or s|u|e|c: c
Please enter 0-50[a|r] or s|u|e|c: c
Enter your Google Workspace admin email address? admin@domain.com
@@ -771,35 +795,41 @@ Service Account Private Key Authentication
Authentication PASS
Service Account Private Key age; Google recommends rotating keys on a routine basis
Service Account Private Key age: 0 days PASS
Domain-Wide Delegation authentication:, User: admin@domain.com, Scopes: 28
https://mail.google.com/ PASS (1/28)
https://sites.google.com/feeds PASS (2/28)
https://www.googleapis.com/auth/apps.alerts PASS (3/28)
https://www.googleapis.com/auth/calendar PASS (4/28)
https://www.googleapis.com/auth/classroom.announcements PASS (5/28)
https://www.googleapis.com/auth/classroom.coursework.students PASS (6/28)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (7/28)
https://www.googleapis.com/auth/classroom.profile.emails PASS (8/28)
https://www.googleapis.com/auth/classroom.rosters PASS (9/28)
https://www.googleapis.com/auth/classroom.topics PASS (10/28)
https://www.googleapis.com/auth/cloud-identity PASS (11/28)
https://www.googleapis.com/auth/cloud-platform PASS (12/28)
https://www.googleapis.com/auth/contacts PASS (13/28)
https://www.googleapis.com/auth/contacts.other.readonly PASS (14/28)
https://www.googleapis.com/auth/datastudio PASS (15/28)
https://www.googleapis.com/auth/directory.readonly PASS (16/28)
https://www.googleapis.com/auth/documents PASS (17/28)
https://www.googleapis.com/auth/drive PASS (18/28)
https://www.googleapis.com/auth/drive.activity PASS (19/28)
https://www.googleapis.com/auth/drive.admin.labels FAIL (20/28)
https://www.googleapis.com/auth/drive.labels FAIL (21/28)
https://www.googleapis.com/auth/gmail.modify PASS (22/28)
https://www.googleapis.com/auth/gmail.settings.basic PASS (23/28)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (24/28)
https://www.googleapis.com/auth/keep PASS (25/28)
https://www.googleapis.com/auth/spreadsheets PASS (26/28)
https://www.googleapis.com/auth/tasks PASS (27/28)
https://www.googleapis.com/auth/userinfo.profile PASS (28/28)
Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 34
https://mail.google.com/ PASS (1/34)
https://sites.google.com/feeds PASS (2/34)
https://www.googleapis.com/auth/analytics.readonly PASS (3/34)
https://www.googleapis.com/auth/apps.alerts PASS (4/34)
https://www.googleapis.com/auth/calendar PASS (5/34)
https://www.googleapis.com/auth/chat.delete PASS (6/34)
https://www.googleapis.com/auth/chat.memberships PASS (7/34)
https://www.googleapis.com/auth/chat.messages PASS (8/34)
https://www.googleapis.com/auth/chat.spaces PASS (9/34)
https://www.googleapis.com/auth/classroom.announcements PASS (10/34)
https://www.googleapis.com/auth/classroom.coursework.students PASS (11/34)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (12/34)
https://www.googleapis.com/auth/classroom.profile.emails PASS (13/34)
https://www.googleapis.com/auth/classroom.rosters PASS (14/34)
https://www.googleapis.com/auth/classroom.topics PASS (15/34)
https://www.googleapis.com/auth/cloud-identity PASS (16/34)
https://www.googleapis.com/auth/cloud-platform PASS (17/34)
https://www.googleapis.com/auth/contacts PASS (18/34)
https://www.googleapis.com/auth/contacts.other.readonly PASS (19/34)
https://www.googleapis.com/auth/datastudio PASS (20/34)
https://www.googleapis.com/auth/directory.readonly PASS (21/34)
https://www.googleapis.com/auth/documents PASS (22/34)
https://www.googleapis.com/auth/drive PASS (23/34)
https://www.googleapis.com/auth/drive.activity PASS (24/34)
https://www.googleapis.com/auth/drive.admin.labels FAIL (25/34)
https://www.googleapis.com/auth/drive.labels FAIL (26/34)
https://www.googleapis.com/auth/gmail.modify PASS (27/34)
https://www.googleapis.com/auth/gmail.settings.basic PASS (28/34)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (29/34)
https://www.googleapis.com/auth/keep PASS (30/34)
https://www.googleapis.com/auth/spreadsheets PASS (31/34)
https://www.googleapis.com/auth/tasks PASS (32/34)
https://www.googleapis.com/auth/userinfo.profile PASS (33/34)
https://www.googleapis.com/auth/youtube.readonly PASS (34/34)
Some scopes FAILED!
To authorize them, please go to:
@@ -827,35 +857,41 @@ System time status:
Your system time differs from www.googleapis.com by less than 1 second PASS
Service Account Private Key Authentication:
Authentication PASS
Domain-Wide Delegation authentication:, User: admin@domain.com, Scopes: 28
https://mail.google.com/ PASS (1/28)
https://sites.google.com/feeds PASS (2/28)
https://www.googleapis.com/auth/apps.alerts PASS (3/28)
https://www.googleapis.com/auth/calendar PASS (4/28)
https://www.googleapis.com/auth/classroom.announcements PASS (5/28)
https://www.googleapis.com/auth/classroom.coursework.students PASS (6/28)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (7/28)
https://www.googleapis.com/auth/classroom.profile.emails PASS (8/28)
https://www.googleapis.com/auth/classroom.rosters PASS (9/28)
https://www.googleapis.com/auth/classroom.topics PASS (10/28)
https://www.googleapis.com/auth/cloud-identity PASS (11/28)
https://www.googleapis.com/auth/cloud-platform PASS (12/28)
https://www.googleapis.com/auth/contacts PASS (13/28)
https://www.googleapis.com/auth/contacts.other.readonly PASS (14/28)
https://www.googleapis.com/auth/datastudio PASS (15/28)
https://www.googleapis.com/auth/directory.readonly PASS (16/28)
https://www.googleapis.com/auth/documents PASS (17/28)
https://www.googleapis.com/auth/drive PASS (18/28)
https://www.googleapis.com/auth/drive.activity PASS (19/28)
https://www.googleapis.com/auth/drive.admin.labels PASS (20/28)
https://www.googleapis.com/auth/drive.labels PASS (21/28)
https://www.googleapis.com/auth/gmail.modify PASS (22/28)
https://www.googleapis.com/auth/gmail.settings.basic PASS (23/28)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (24/28)
https://www.googleapis.com/auth/keep PASS (25/28)
https://www.googleapis.com/auth/spreadsheets PASS (26/28)
https://www.googleapis.com/auth/tasks PASS (27/28)
https://www.googleapis.com/auth/userinfo.profile PASS (28/28)
Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 34
https://mail.google.com/ PASS (1/34)
https://sites.google.com/feeds PASS (2/34)
https://www.googleapis.com/auth/analytics.readonly PASS (3/34)
https://www.googleapis.com/auth/apps.alerts PASS (4/34)
https://www.googleapis.com/auth/calendar PASS (5/34)
https://www.googleapis.com/auth/chat.delete PASS (6/34)
https://www.googleapis.com/auth/chat.memberships PASS (7/34)
https://www.googleapis.com/auth/chat.messages PASS (8/34)
https://www.googleapis.com/auth/chat.spaces PASS (9/34)
https://www.googleapis.com/auth/classroom.announcements PASS (10/34)
https://www.googleapis.com/auth/classroom.coursework.students PASS (11/34)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (12/34)
https://www.googleapis.com/auth/classroom.profile.emails PASS (13/34)
https://www.googleapis.com/auth/classroom.rosters PASS (14/34)
https://www.googleapis.com/auth/classroom.topics PASS (15/34)
https://www.googleapis.com/auth/cloud-identity PASS (16/34)
https://www.googleapis.com/auth/cloud-platform PASS (17/34)
https://www.googleapis.com/auth/contacts PASS (18/34)
https://www.googleapis.com/auth/contacts.other.readonly PASS (19/34)
https://www.googleapis.com/auth/datastudio PASS (20/34)
https://www.googleapis.com/auth/directory.readonly PASS (21/34)
https://www.googleapis.com/auth/documents PASS (22/34)
https://www.googleapis.com/auth/drive PASS (23/34)
https://www.googleapis.com/auth/drive.activity PASS (24/34)
https://www.googleapis.com/auth/drive.admin.labels PASS (25/34)
https://www.googleapis.com/auth/drive.labels PASS (26/34)
https://www.googleapis.com/auth/gmail.modify PASS (27/34)
https://www.googleapis.com/auth/gmail.settings.basic PASS (28/34)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (29/34)
https://www.googleapis.com/auth/keep PASS (30/34)
https://www.googleapis.com/auth/spreadsheets PASS (31/34)
https://www.googleapis.com/auth/tasks PASS (32/34)
https://www.googleapis.com/auth/userinfo.profile PASS (33/34)
https://www.googleapis.com/auth/youtube.readonly PASS (34/34)
All scopes PASSED!
Service Account Client name: SVCACCTID is fully authorized.

View File

@@ -104,55 +104,61 @@ Append an 'r' to grant read-only access or an 'a' to grant action-only access.
[*] 0) Calendar API (supports readonly)
[*] 1) Chrome Browser Cloud Management API (supports readonly)
[*] 2) Chrome Management API - Telemetry read only
[*] 3) Chrome Management API - read only
[*] 4) Chrome Policy API (supports readonly)
[*] 5) Chrome Printer Management API (supports readonly)
[*] 6) Chrome Version History API
[*] 7) Classroom API - Course Announcements (supports readonly)
[*] 8) Classroom API - Course Topics (supports readonly)
[*] 9) Classroom API - Course Work/Materials (supports readonly)
[*] 10) Classroom API - Course Work/Submissions (supports readonly)
[*] 11) Classroom API - Courses (supports readonly)
[*] 12) Classroom API - Profile Emails
[*] 13) Classroom API - Profile Photos
[*] 14) Classroom API - Rosters (supports readonly)
[*] 15) Classroom API - Student Guardians (supports readonly)
[*] 16) Cloud Identity Groups API (supports readonly)
[*] 17) Cloud Storage (Vault Export - read only)
[*] 18) Contact Delegation API (supports readonly)
[*] 19) Contacts API - Domain Shared and Users and GAL
[*] 20) Data Transfer API (supports readonly)
[*] 21) Directory API - Chrome OS Devices (supports readonly)
[*] 22) Directory API - Customers (supports readonly)
[*] 23) Directory API - Domains (supports readonly)
[*] 24) Directory API - Groups (supports readonly)
[*] 25) Directory API - Mobile Devices Directory (supports readonly and action)
[*] 26) Directory API - Organizational Units (supports readonly)
[*] 27) Directory API - Resource Calendars (supports readonly)
[*] 28) Directory API - Roles (supports readonly)
[*] 29) Directory API - User Schemas (supports readonly)
[*] 30) Directory API - User Security
[*] 31) Directory API - Users (supports readonly)
[*] 32) Email Audit API
[*] 33) Groups Migration API
[*] 34) Groups Settings API
[*] 35) License Manager API
[*] 36) People API (supports readonly)
[*] 37) People Directory API - read only
[ ] 38) Pub / Sub API
[*] 39) Reports API - Audit Reports
[*] 40) Reports API - Usage Reports
[ ] 41) Reseller API
[*] 42) Site Verification API
[*] 43) Sites API
[*] 44) Vault API (supports readonly)
[*] 2) Chrome Management API - AppDetails read only
[*] 3) Chrome Management API - Telemetry read only
[*] 4) Chrome Management API - read only
[*] 5) Chrome Policy API (supports readonly)
[*] 6) Chrome Printer Management API (supports readonly)
[ ] 7) Chrome Version History API
[*] 8) Classroom API - Course Announcements (supports readonly)
[*] 9) Classroom API - Course Topics (supports readonly)
[*] 10) Classroom API - Course Work/Materials (supports readonly)
[*] 11) Classroom API - Course Work/Submissions (supports readonly)
[*] 12) Classroom API - Courses (supports readonly)
[*] 13) Classroom API - Profile Emails
[*] 14) Classroom API - Profile Photos
[*] 15) Classroom API - Rosters (supports readonly)
[*] 16) Classroom API - Student Guardians (supports readonly)
[*] 17) Cloud Channel API (supports readonly)
[*] 18) Cloud Identity - Inbound SSO Settings (supports readonly)
[*] 19) Cloud Identity Groups API (supports readonly)
[*] 20) Cloud Identity OrgUnits API (supports readonly)
[*] 21) Cloud Identity User Invitations API (supports readonly)
[ ] 22) Cloud Storage API (Read Only, Vault/Takeout Download, Cloud Storage)
[ ] 23) Cloud Storage API (Read/Write, Vault/Takeout Copy/Download, Cloud Storage)
[*] 24) Contact Delegation API (supports readonly)
[*] 25) Contacts API - Domain Shared Contacts and GAL
[*] 26) Data Transfer API (supports readonly)
[*] 27) Directory API - Chrome OS Devices (supports readonly)
[*] 28) Directory API - Customers (supports readonly)
[*] 29) Directory API - Domains (supports readonly)
[*] 30) Directory API - Groups (supports readonly)
[*] 31) Directory API - Mobile Devices Directory (supports readonly and action)
[*] 32) Directory API - Organizational Units (supports readonly)
[*] 33) Directory API - Resource Calendars (supports readonly)
[*] 34) Directory API - Roles (supports readonly)
[*] 35) Directory API - User Schemas (supports readonly)
[*] 36) Directory API - User Security
[*] 37) Directory API - Users (supports readonly)
[ ] 38) Email Audit API
[*] 39) Groups Migration API
[*] 40) Groups Settings API
[*] 41) License Manager API
[*] 42) People API (supports readonly)
[*] 43) People Directory API - read only
[ ] 44) Pub / Sub API
[*] 45) Reports API - Audit Reports
[*] 46) Reports API - Usage Reports
[*] 47) Reseller API
[*] 48) Site Verification API
[ ] 49) Sites API
[*] 50) Vault API (supports readonly)
s) Select all scopes
u) Unselect all scopes
e) Exit without changes
c) Continue to authorization
Please enter 0-44[a|r] or s|u|e|c: c
Please enter 0-50[a|r] or s|u|e|c: c
Enter your Google Workspace admin email address? admin@domain.com
@@ -180,35 +186,41 @@ Service Account Private Key Authentication
Authentication PASS
Service Account Private Key age; Google recommends rotating keys on a routine basis
Service Account Private Key age: 0 days PASS
Domain-Wide Delegation authentication:, User: admin@domain.com, Scopes: 28
https://mail.google.com/ PASS (1/28)
https://sites.google.com/feeds PASS (2/28)
https://www.googleapis.com/auth/apps.alerts PASS (3/28)
https://www.googleapis.com/auth/calendar PASS (4/28)
https://www.googleapis.com/auth/classroom.announcements PASS (5/28)
https://www.googleapis.com/auth/classroom.coursework.students PASS (6/28)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (7/28)
https://www.googleapis.com/auth/classroom.profile.emails PASS (8/28)
https://www.googleapis.com/auth/classroom.rosters PASS (9/28)
https://www.googleapis.com/auth/classroom.topics PASS (10/28)
https://www.googleapis.com/auth/cloud-identity PASS (11/28)
https://www.googleapis.com/auth/cloud-platform PASS (12/28)
https://www.googleapis.com/auth/contacts PASS (13/28)
https://www.googleapis.com/auth/contacts.other.readonly PASS (14/28)
https://www.googleapis.com/auth/datastudio PASS (15/28)
https://www.googleapis.com/auth/directory.readonly PASS (16/28)
https://www.googleapis.com/auth/documents PASS (17/28)
https://www.googleapis.com/auth/drive PASS (18/28)
https://www.googleapis.com/auth/drive.activity PASS (19/28)
https://www.googleapis.com/auth/drive.admin.labels FAIL (20/28)
https://www.googleapis.com/auth/drive.labels FAIL (21/28)
https://www.googleapis.com/auth/gmail.modify PASS (22/28)
https://www.googleapis.com/auth/gmail.settings.basic PASS (23/28)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (24/28)
https://www.googleapis.com/auth/keep PASS (25/28)
https://www.googleapis.com/auth/spreadsheets PASS (26/28)
https://www.googleapis.com/auth/tasks PASS (27/28)
https://www.googleapis.com/auth/userinfo.profile PASS (28/28)
Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 34
https://mail.google.com/ PASS (1/34)
https://sites.google.com/feeds PASS (2/34)
https://www.googleapis.com/auth/analytics.readonly PASS (3/34)
https://www.googleapis.com/auth/apps.alerts PASS (4/34)
https://www.googleapis.com/auth/calendar PASS (5/34)
https://www.googleapis.com/auth/chat.delete PASS (6/34)
https://www.googleapis.com/auth/chat.memberships PASS (7/34)
https://www.googleapis.com/auth/chat.messages PASS (8/34)
https://www.googleapis.com/auth/chat.spaces PASS (9/34)
https://www.googleapis.com/auth/classroom.announcements PASS (10/34)
https://www.googleapis.com/auth/classroom.coursework.students PASS (11/34)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (12/34)
https://www.googleapis.com/auth/classroom.profile.emails PASS (13/34)
https://www.googleapis.com/auth/classroom.rosters PASS (14/34)
https://www.googleapis.com/auth/classroom.topics PASS (15/34)
https://www.googleapis.com/auth/cloud-identity PASS (16/34)
https://www.googleapis.com/auth/cloud-platform PASS (17/34)
https://www.googleapis.com/auth/contacts PASS (18/34)
https://www.googleapis.com/auth/contacts.other.readonly PASS (19/34)
https://www.googleapis.com/auth/datastudio PASS (20/34)
https://www.googleapis.com/auth/directory.readonly PASS (21/34)
https://www.googleapis.com/auth/documents PASS (22/34)
https://www.googleapis.com/auth/drive PASS (23/34)
https://www.googleapis.com/auth/drive.activity PASS (24/34)
https://www.googleapis.com/auth/drive.admin.labels FAIL (25/34)
https://www.googleapis.com/auth/drive.labels FAIL (26/34)
https://www.googleapis.com/auth/gmail.modify PASS (27/34)
https://www.googleapis.com/auth/gmail.settings.basic PASS (28/34)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (29/34)
https://www.googleapis.com/auth/keep PASS (30/34)
https://www.googleapis.com/auth/spreadsheets PASS (31/34)
https://www.googleapis.com/auth/tasks PASS (32/34)
https://www.googleapis.com/auth/userinfo.profile PASS (33/34)
https://www.googleapis.com/auth/youtube.readonly PASS (34/34)
Some scopes FAILED!
To authorize them, please go to:
@@ -236,35 +248,41 @@ System time status:
Your system time differs from www.googleapis.com by less than 1 second PASS
Service Account Private Key Authentication:
Authentication PASS
Domain-Wide Delegation authentication:, User: admin@domain.com, Scopes: 28
https://mail.google.com/ PASS (1/28)
https://sites.google.com/feeds PASS (2/28)
https://www.googleapis.com/auth/apps.alerts PASS (3/28)
https://www.googleapis.com/auth/calendar PASS (4/28)
https://www.googleapis.com/auth/classroom.announcements PASS (5/28)
https://www.googleapis.com/auth/classroom.coursework.students PASS (6/28)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (7/28)
https://www.googleapis.com/auth/classroom.profile.emails PASS (8/28)
https://www.googleapis.com/auth/classroom.rosters PASS (9/28)
https://www.googleapis.com/auth/classroom.topics PASS (10/28)
https://www.googleapis.com/auth/cloud-identity PASS (11/28)
https://www.googleapis.com/auth/cloud-platform PASS (12/28)
https://www.googleapis.com/auth/contacts PASS (13/28)
https://www.googleapis.com/auth/contacts.other.readonly PASS (14/28)
https://www.googleapis.com/auth/datastudio PASS (15/28)
https://www.googleapis.com/auth/directory.readonly PASS (16/28)
https://www.googleapis.com/auth/documents PASS (17/28)
https://www.googleapis.com/auth/drive PASS (18/28)
https://www.googleapis.com/auth/drive.activity PASS (19/28)
https://www.googleapis.com/auth/drive.admin.labels PASS (20/28)
https://www.googleapis.com/auth/drive.labels PASS (21/28)
https://www.googleapis.com/auth/gmail.modify PASS (22/28)
https://www.googleapis.com/auth/gmail.settings.basic PASS (23/28)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (24/28)
https://www.googleapis.com/auth/keep PASS (25/28)
https://www.googleapis.com/auth/spreadsheets PASS (26/28)
https://www.googleapis.com/auth/tasks PASS (27/28)
https://www.googleapis.com/auth/userinfo.profile PASS (28/28)
Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 34
https://mail.google.com/ PASS (1/34)
https://sites.google.com/feeds PASS (2/34)
https://www.googleapis.com/auth/analytics.readonly PASS (3/34)
https://www.googleapis.com/auth/apps.alerts PASS (4/34)
https://www.googleapis.com/auth/calendar PASS (5/34)
https://www.googleapis.com/auth/chat.delete PASS (6/34)
https://www.googleapis.com/auth/chat.memberships PASS (7/34)
https://www.googleapis.com/auth/chat.messages PASS (8/34)
https://www.googleapis.com/auth/chat.spaces PASS (9/34)
https://www.googleapis.com/auth/classroom.announcements PASS (10/34)
https://www.googleapis.com/auth/classroom.coursework.students PASS (11/34)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (12/34)
https://www.googleapis.com/auth/classroom.profile.emails PASS (13/34)
https://www.googleapis.com/auth/classroom.rosters PASS (14/34)
https://www.googleapis.com/auth/classroom.topics PASS (15/34)
https://www.googleapis.com/auth/cloud-identity PASS (16/34)
https://www.googleapis.com/auth/cloud-platform PASS (17/34)
https://www.googleapis.com/auth/contacts PASS (18/34)
https://www.googleapis.com/auth/contacts.other.readonly PASS (19/34)
https://www.googleapis.com/auth/datastudio PASS (20/34)
https://www.googleapis.com/auth/directory.readonly PASS (21/34)
https://www.googleapis.com/auth/documents PASS (22/34)
https://www.googleapis.com/auth/drive PASS (23/34)
https://www.googleapis.com/auth/drive.activity PASS (24/34)
https://www.googleapis.com/auth/drive.admin.labels PASS (25/34)
https://www.googleapis.com/auth/drive.labels PASS (26/34)
https://www.googleapis.com/auth/gmail.modify PASS (27/34)
https://www.googleapis.com/auth/gmail.settings.basic PASS (28/34)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (29/34)
https://www.googleapis.com/auth/keep PASS (30/34)
https://www.googleapis.com/auth/spreadsheets PASS (31/34)
https://www.googleapis.com/auth/tasks PASS (32/34)
https://www.googleapis.com/auth/userinfo.profile PASS (33/34)
https://www.googleapis.com/auth/youtube.readonly PASS (34/34)
All scopes PASSED!
Service Account Client name: SVCACCTID is fully authorized.
@@ -369,55 +387,61 @@ Append an 'r' to grant read-only access or an 'a' to grant action-only access.
[*] 0) Calendar API (supports readonly)
[*] 1) Chrome Browser Cloud Management API (supports readonly)
[*] 2) Chrome Management API - Telemetry read only
[*] 3) Chrome Management API - read only
[*] 4) Chrome Policy API (supports readonly)
[*] 5) Chrome Printer Management API (supports readonly)
[*] 6) Chrome Version History API
[*] 7) Classroom API - Course Announcements (supports readonly)
[*] 8) Classroom API - Course Topics (supports readonly)
[*] 9) Classroom API - Course Work/Materials (supports readonly)
[*] 10) Classroom API - Course Work/Submissions (supports readonly)
[*] 11) Classroom API - Courses (supports readonly)
[*] 12) Classroom API - Profile Emails
[*] 13) Classroom API - Profile Photos
[*] 14) Classroom API - Rosters (supports readonly)
[*] 15) Classroom API - Student Guardians (supports readonly)
[*] 16) Cloud Identity Groups API (supports readonly)
[*] 17) Cloud Storage (Vault Export - read only)
[*] 18) Contact Delegation API (supports readonly)
[*] 19) Contacts API - Domain Shared and Users and GAL
[*] 20) Data Transfer API (supports readonly)
[*] 21) Directory API - Chrome OS Devices (supports readonly)
[*] 22) Directory API - Customers (supports readonly)
[*] 23) Directory API - Domains (supports readonly)
[*] 24) Directory API - Groups (supports readonly)
[*] 25) Directory API - Mobile Devices Directory (supports readonly and action)
[*] 26) Directory API - Organizational Units (supports readonly)
[*] 27) Directory API - Resource Calendars (supports readonly)
[*] 28) Directory API - Roles (supports readonly)
[*] 29) Directory API - User Schemas (supports readonly)
[*] 30) Directory API - User Security
[*] 31) Directory API - Users (supports readonly)
[*] 32) Email Audit API
[*] 33) Groups Migration API
[*] 34) Groups Settings API
[*] 35) License Manager API
[*] 36) People API (supports readonly)
[*] 37) People Directory API - read only
[ ] 38) Pub / Sub API
[*] 39) Reports API - Audit Reports
[*] 40) Reports API - Usage Reports
[ ] 41) Reseller API
[*] 42) Site Verification API
[*] 43) Sites API
[*] 44) Vault API (supports readonly)
[*] 2) Chrome Management API - AppDetails read only
[*] 3) Chrome Management API - Telemetry read only
[*] 4) Chrome Management API - read only
[*] 5) Chrome Policy API (supports readonly)
[*] 6) Chrome Printer Management API (supports readonly)
[ ] 7) Chrome Version History API
[*] 8) Classroom API - Course Announcements (supports readonly)
[*] 9) Classroom API - Course Topics (supports readonly)
[*] 10) Classroom API - Course Work/Materials (supports readonly)
[*] 11) Classroom API - Course Work/Submissions (supports readonly)
[*] 12) Classroom API - Courses (supports readonly)
[*] 13) Classroom API - Profile Emails
[*] 14) Classroom API - Profile Photos
[*] 15) Classroom API - Rosters (supports readonly)
[*] 16) Classroom API - Student Guardians (supports readonly)
[*] 17) Cloud Channel API (supports readonly)
[*] 18) Cloud Identity - Inbound SSO Settings (supports readonly)
[*] 19) Cloud Identity Groups API (supports readonly)
[*] 20) Cloud Identity OrgUnits API (supports readonly)
[*] 21) Cloud Identity User Invitations API (supports readonly)
[ ] 22) Cloud Storage API (Read Only, Vault/Takeout Download, Cloud Storage)
[ ] 23) Cloud Storage API (Read/Write, Vault/Takeout Copy/Download, Cloud Storage)
[*] 24) Contact Delegation API (supports readonly)
[*] 25) Contacts API - Domain Shared Contacts and GAL
[*] 26) Data Transfer API (supports readonly)
[*] 27) Directory API - Chrome OS Devices (supports readonly)
[*] 28) Directory API - Customers (supports readonly)
[*] 29) Directory API - Domains (supports readonly)
[*] 30) Directory API - Groups (supports readonly)
[*] 31) Directory API - Mobile Devices Directory (supports readonly and action)
[*] 32) Directory API - Organizational Units (supports readonly)
[*] 33) Directory API - Resource Calendars (supports readonly)
[*] 34) Directory API - Roles (supports readonly)
[*] 35) Directory API - User Schemas (supports readonly)
[*] 36) Directory API - User Security
[*] 37) Directory API - Users (supports readonly)
[ ] 38) Email Audit API
[*] 39) Groups Migration API
[*] 40) Groups Settings API
[*] 41) License Manager API
[*] 42) People API (supports readonly)
[*] 43) People Directory API - read only
[ ] 44) Pub / Sub API
[*] 45) Reports API - Audit Reports
[*] 46) Reports API - Usage Reports
[*] 47) Reseller API
[*] 48) Site Verification API
[ ] 49) Sites API
[*] 50) Vault API (supports readonly)
s) Select all scopes
u) Unselect all scopes
e) Exit without changes
c) Continue to authorization
Please enter 0-44[a|r] or s|u|e|c: c
Please enter 0-50[a|r] or s|u|e|c: c
Enter your Google Workspace admin email address? admin@domain.com
@@ -444,35 +468,41 @@ Service Account Private Key Authentication
Authentication PASS
Service Account Private Key age; Google recommends rotating keys on a routine basis
Service Account Private Key age: 0 days PASS
Domain-Wide Delegation authentication:, User: admin@domain.com, Scopes: 28
https://mail.google.com/ PASS (1/28)
https://sites.google.com/feeds PASS (2/28)
https://www.googleapis.com/auth/apps.alerts PASS (3/28)
https://www.googleapis.com/auth/calendar PASS (4/28)
https://www.googleapis.com/auth/classroom.announcements PASS (5/28)
https://www.googleapis.com/auth/classroom.coursework.students PASS (6/28)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (7/28)
https://www.googleapis.com/auth/classroom.profile.emails PASS (8/28)
https://www.googleapis.com/auth/classroom.rosters PASS (9/28)
https://www.googleapis.com/auth/classroom.topics PASS (10/28)
https://www.googleapis.com/auth/cloud-identity PASS (11/28)
https://www.googleapis.com/auth/cloud-platform PASS (12/28)
https://www.googleapis.com/auth/contacts PASS (13/28)
https://www.googleapis.com/auth/contacts.other.readonly PASS (14/28)
https://www.googleapis.com/auth/datastudio PASS (15/28)
https://www.googleapis.com/auth/directory.readonly PASS (16/28)
https://www.googleapis.com/auth/documents PASS (17/28)
https://www.googleapis.com/auth/drive PASS (18/28)
https://www.googleapis.com/auth/drive.activity PASS (19/28)
https://www.googleapis.com/auth/drive.admin.labels FAIL (20/28)
https://www.googleapis.com/auth/drive.labels FAIL (21/28)
https://www.googleapis.com/auth/gmail.modify PASS (22/28)
https://www.googleapis.com/auth/gmail.settings.basic PASS (23/28)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (24/28)
https://www.googleapis.com/auth/keep PASS (25/28)
https://www.googleapis.com/auth/spreadsheets PASS (26/28)
https://www.googleapis.com/auth/tasks PASS (27/28)
https://www.googleapis.com/auth/userinfo.profile PASS (28/28)
Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 34
https://mail.google.com/ PASS (1/34)
https://sites.google.com/feeds PASS (2/34)
https://www.googleapis.com/auth/analytics.readonly PASS (3/34)
https://www.googleapis.com/auth/apps.alerts PASS (4/34)
https://www.googleapis.com/auth/calendar PASS (5/34)
https://www.googleapis.com/auth/chat.delete PASS (6/34)
https://www.googleapis.com/auth/chat.memberships PASS (7/34)
https://www.googleapis.com/auth/chat.messages PASS (8/34)
https://www.googleapis.com/auth/chat.spaces PASS (9/34)
https://www.googleapis.com/auth/classroom.announcements PASS (10/34)
https://www.googleapis.com/auth/classroom.coursework.students PASS (11/34)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (12/34)
https://www.googleapis.com/auth/classroom.profile.emails PASS (13/34)
https://www.googleapis.com/auth/classroom.rosters PASS (14/34)
https://www.googleapis.com/auth/classroom.topics PASS (15/34)
https://www.googleapis.com/auth/cloud-identity PASS (16/34)
https://www.googleapis.com/auth/cloud-platform PASS (17/34)
https://www.googleapis.com/auth/contacts PASS (18/34)
https://www.googleapis.com/auth/contacts.other.readonly PASS (19/34)
https://www.googleapis.com/auth/datastudio PASS (20/34)
https://www.googleapis.com/auth/directory.readonly PASS (21/34)
https://www.googleapis.com/auth/documents PASS (22/34)
https://www.googleapis.com/auth/drive PASS (23/34)
https://www.googleapis.com/auth/drive.activity PASS (24/34)
https://www.googleapis.com/auth/drive.admin.labels FAIL (25/34)
https://www.googleapis.com/auth/drive.labels FAIL (26/34)
https://www.googleapis.com/auth/gmail.modify PASS (27/34)
https://www.googleapis.com/auth/gmail.settings.basic PASS (28/34)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (29/34)
https://www.googleapis.com/auth/keep PASS (30/34)
https://www.googleapis.com/auth/spreadsheets PASS (31/34)
https://www.googleapis.com/auth/tasks PASS (32/34)
https://www.googleapis.com/auth/userinfo.profile PASS (33/34)
https://www.googleapis.com/auth/youtube.readonly PASS (34/34)
Some scopes FAILED!
To authorize them, please go to:
@@ -500,35 +530,41 @@ System time status:
Your system time differs from www.googleapis.com by less than 1 second PASS
Service Account Private Key Authentication:
Authentication PASS
Domain-Wide Delegation authentication:, User: admin@domain.com, Scopes: 28
https://mail.google.com/ PASS (1/28)
https://sites.google.com/feeds PASS (2/28)
https://www.googleapis.com/auth/apps.alerts PASS (3/28)
https://www.googleapis.com/auth/calendar PASS (4/28)
https://www.googleapis.com/auth/classroom.announcements PASS (5/28)
https://www.googleapis.com/auth/classroom.coursework.students PASS (6/28)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (7/28)
https://www.googleapis.com/auth/classroom.profile.emails PASS (8/28)
https://www.googleapis.com/auth/classroom.rosters PASS (9/28)
https://www.googleapis.com/auth/classroom.topics PASS (10/28)
https://www.googleapis.com/auth/cloud-identity PASS (11/28)
https://www.googleapis.com/auth/cloud-platform PASS (12/28)
https://www.googleapis.com/auth/contacts PASS (13/28)
https://www.googleapis.com/auth/contacts.other.readonly PASS (14/28)
https://www.googleapis.com/auth/datastudio PASS (15/28)
https://www.googleapis.com/auth/directory.readonly PASS (16/28)
https://www.googleapis.com/auth/documents PASS (17/28)
https://www.googleapis.com/auth/drive PASS (18/28)
https://www.googleapis.com/auth/drive.activity PASS (19/28)
https://www.googleapis.com/auth/drive.admin.labels PASS (20/28)
https://www.googleapis.com/auth/drive.labels PASS (21/28)
https://www.googleapis.com/auth/gmail.modify PASS (22/28)
https://www.googleapis.com/auth/gmail.settings.basic PASS (23/28)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (24/28)
https://www.googleapis.com/auth/keep PASS (25/28)
https://www.googleapis.com/auth/spreadsheets PASS (26/28)
https://www.googleapis.com/auth/tasks PASS (27/28)
https://www.googleapis.com/auth/userinfo.profile PASS (28/28)
Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 34
https://mail.google.com/ PASS (1/34)
https://sites.google.com/feeds PASS (2/34)
https://www.googleapis.com/auth/analytics.readonly PASS (3/34)
https://www.googleapis.com/auth/apps.alerts PASS (4/34)
https://www.googleapis.com/auth/calendar PASS (5/34)
https://www.googleapis.com/auth/chat.delete PASS (6/34)
https://www.googleapis.com/auth/chat.memberships PASS (7/34)
https://www.googleapis.com/auth/chat.messages PASS (8/34)
https://www.googleapis.com/auth/chat.spaces PASS (9/34)
https://www.googleapis.com/auth/classroom.announcements PASS (10/34)
https://www.googleapis.com/auth/classroom.coursework.students PASS (11/34)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (12/34)
https://www.googleapis.com/auth/classroom.profile.emails PASS (13/34)
https://www.googleapis.com/auth/classroom.rosters PASS (14/34)
https://www.googleapis.com/auth/classroom.topics PASS (15/34)
https://www.googleapis.com/auth/cloud-identity PASS (16/34)
https://www.googleapis.com/auth/cloud-platform PASS (17/34)
https://www.googleapis.com/auth/contacts PASS (18/34)
https://www.googleapis.com/auth/contacts.other.readonly PASS (19/34)
https://www.googleapis.com/auth/datastudio PASS (20/34)
https://www.googleapis.com/auth/directory.readonly PASS (21/34)
https://www.googleapis.com/auth/documents PASS (22/34)
https://www.googleapis.com/auth/drive PASS (23/34)
https://www.googleapis.com/auth/drive.activity PASS (24/34)
https://www.googleapis.com/auth/drive.admin.labels PASS (25/34)
https://www.googleapis.com/auth/drive.labels PASS (26/34)
https://www.googleapis.com/auth/gmail.modify PASS (27/34)
https://www.googleapis.com/auth/gmail.settings.basic PASS (28/34)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (29/34)
https://www.googleapis.com/auth/keep PASS (30/34)
https://www.googleapis.com/auth/spreadsheets PASS (31/34)
https://www.googleapis.com/auth/tasks PASS (32/34)
https://www.googleapis.com/auth/userinfo.profile PASS (33/34)
https://www.googleapis.com/auth/youtube.readonly PASS (34/34)
All scopes PASSED!
Service Account Client name: SVCACCTID is fully authorized.

View File

@@ -97,55 +97,61 @@ Append an 'r' to grant read-only access or an 'a' to grant action-only access.
[*] 0) Calendar API (supports readonly)
[*] 1) Chrome Browser Cloud Management API (supports readonly)
[*] 2) Chrome Management API - Telemetry read only
[*] 3) Chrome Management API - read only
[*] 4) Chrome Policy API (supports readonly)
[*] 5) Chrome Printer Management API (supports readonly)
[*] 6) Chrome Version History API
[*] 7) Classroom API - Course Announcements (supports readonly)
[*] 8) Classroom API - Course Topics (supports readonly)
[*] 9) Classroom API - Course Work/Materials (supports readonly)
[*] 10) Classroom API - Course Work/Submissions (supports readonly)
[*] 11) Classroom API - Courses (supports readonly)
[*] 12) Classroom API - Profile Emails
[*] 13) Classroom API - Profile Photos
[*] 14) Classroom API - Rosters (supports readonly)
[*] 15) Classroom API - Student Guardians (supports readonly)
[*] 16) Cloud Identity Groups API (supports readonly)
[*] 17) Cloud Storage (Vault Export - read only)
[*] 18) Contact Delegation API (supports readonly)
[*] 19) Contacts API - Domain Shared and Users and GAL
[*] 20) Data Transfer API (supports readonly)
[*] 21) Directory API - Chrome OS Devices (supports readonly)
[*] 22) Directory API - Customers (supports readonly)
[*] 23) Directory API - Domains (supports readonly)
[*] 24) Directory API - Groups (supports readonly)
[*] 25) Directory API - Mobile Devices Directory (supports readonly and action)
[*] 26) Directory API - Organizational Units (supports readonly)
[*] 27) Directory API - Resource Calendars (supports readonly)
[*] 28) Directory API - Roles (supports readonly)
[*] 29) Directory API - User Schemas (supports readonly)
[*] 30) Directory API - User Security
[*] 31) Directory API - Users (supports readonly)
[*] 32) Email Audit API
[*] 33) Groups Migration API
[*] 34) Groups Settings API
[*] 35) License Manager API
[*] 36) People API (supports readonly)
[*] 37) People Directory API - read only
[ ] 38) Pub / Sub API
[*] 39) Reports API - Audit Reports
[*] 40) Reports API - Usage Reports
[ ] 41) Reseller API
[*] 42) Site Verification API
[*] 43) Sites API
[*] 44) Vault API (supports readonly)
[*] 2) Chrome Management API - AppDetails read only
[*] 3) Chrome Management API - Telemetry read only
[*] 4) Chrome Management API - read only
[*] 5) Chrome Policy API (supports readonly)
[*] 6) Chrome Printer Management API (supports readonly)
[ ] 7) Chrome Version History API
[*] 8) Classroom API - Course Announcements (supports readonly)
[*] 9) Classroom API - Course Topics (supports readonly)
[*] 10) Classroom API - Course Work/Materials (supports readonly)
[*] 11) Classroom API - Course Work/Submissions (supports readonly)
[*] 12) Classroom API - Courses (supports readonly)
[*] 13) Classroom API - Profile Emails
[*] 14) Classroom API - Profile Photos
[*] 15) Classroom API - Rosters (supports readonly)
[*] 16) Classroom API - Student Guardians (supports readonly)
[*] 17) Cloud Channel API (supports readonly)
[*] 18) Cloud Identity - Inbound SSO Settings (supports readonly)
[*] 19) Cloud Identity Groups API (supports readonly)
[*] 20) Cloud Identity OrgUnits API (supports readonly)
[*] 21) Cloud Identity User Invitations API (supports readonly)
[ ] 22) Cloud Storage API (Read Only, Vault/Takeout Download, Cloud Storage)
[ ] 23) Cloud Storage API (Read/Write, Vault/Takeout Copy/Download, Cloud Storage)
[*] 24) Contact Delegation API (supports readonly)
[*] 25) Contacts API - Domain Shared Contacts and GAL
[*] 26) Data Transfer API (supports readonly)
[*] 27) Directory API - Chrome OS Devices (supports readonly)
[*] 28) Directory API - Customers (supports readonly)
[*] 29) Directory API - Domains (supports readonly)
[*] 30) Directory API - Groups (supports readonly)
[*] 31) Directory API - Mobile Devices Directory (supports readonly and action)
[*] 32) Directory API - Organizational Units (supports readonly)
[*] 33) Directory API - Resource Calendars (supports readonly)
[*] 34) Directory API - Roles (supports readonly)
[*] 35) Directory API - User Schemas (supports readonly)
[*] 36) Directory API - User Security
[*] 37) Directory API - Users (supports readonly)
[ ] 38) Email Audit API
[*] 39) Groups Migration API
[*] 40) Groups Settings API
[*] 41) License Manager API
[*] 42) People API (supports readonly)
[*] 43) People Directory API - read only
[ ] 44) Pub / Sub API
[*] 45) Reports API - Audit Reports
[*] 46) Reports API - Usage Reports
[*] 47) Reseller API
[*] 48) Site Verification API
[ ] 49) Sites API
[*] 50) Vault API (supports readonly)
s) Select all scopes
u) Unselect all scopes
e) Exit without changes
c) Continue to authorization
Please enter 0-44[a|r] or s|u|e|c: c
Please enter 0-50[a|r] or s|u|e|c: c
Enter your Google Workspace admin email address?admin@domain.com
@@ -168,35 +174,41 @@ System time status:
Your system time differs by less than 1 second from Google PASS
Service Account Private Key Authentication:
Authentication PASS
Domain-Wide Delegation authentication:, User: user@domain.com, Scopes: 28
https://mail.google.com/ PASS (1/28)
https://sites.google.com/feeds PASS (2/28)
https://www.googleapis.com/auth/apps.alerts PASS (3/28)
https://www.googleapis.com/auth/calendar PASS (4/28)
https://www.googleapis.com/auth/classroom.announcements PASS (5/28)
https://www.googleapis.com/auth/classroom.coursework.students PASS (6/28)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (7/28)
https://www.googleapis.com/auth/classroom.profile.emails PASS (8/28)
https://www.googleapis.com/auth/classroom.rosters PASS (9/28)
https://www.googleapis.com/auth/classroom.topics PASS (10/28)
https://www.googleapis.com/auth/cloud-identity PASS (11/28)
https://www.googleapis.com/auth/cloud-platform PASS (12/28)
https://www.googleapis.com/auth/contacts PASS (13/28)
https://www.googleapis.com/auth/contacts.other.readonly PASS (14/28)
https://www.googleapis.com/auth/datastudio PASS (15/28)
https://www.googleapis.com/auth/directory.readonly PASS (16/28)
https://www.googleapis.com/auth/documents PASS (17/28)
https://www.googleapis.com/auth/drive PASS (18/28)
https://www.googleapis.com/auth/drive.activity PASS (19/28)
https://www.googleapis.com/auth/drive.admin.labels FAIL (20/28)
https://www.googleapis.com/auth/drive.labels FAIL (21/28)
https://www.googleapis.com/auth/gmail.modify PASS (22/28)
https://www.googleapis.com/auth/gmail.settings.basic PASS (23/28)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (24/28)
https://www.googleapis.com/auth/keep PASS (25/28)
https://www.googleapis.com/auth/spreadsheets PASS (26/28)
https://www.googleapis.com/auth/tasks PASS (27/28)
https://www.googleapis.com/auth/userinfo.profile PASS (28/28)
Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 34
https://mail.google.com/ PASS (1/34)
https://sites.google.com/feeds PASS (2/34)
https://www.googleapis.com/auth/analytics.readonly PASS (3/34)
https://www.googleapis.com/auth/apps.alerts PASS (4/34)
https://www.googleapis.com/auth/calendar PASS (5/34)
https://www.googleapis.com/auth/chat.delete PASS (6/34)
https://www.googleapis.com/auth/chat.memberships PASS (7/34)
https://www.googleapis.com/auth/chat.messages PASS (8/34)
https://www.googleapis.com/auth/chat.spaces PASS (9/34)
https://www.googleapis.com/auth/classroom.announcements PASS (10/34)
https://www.googleapis.com/auth/classroom.coursework.students PASS (11/34)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (12/34)
https://www.googleapis.com/auth/classroom.profile.emails PASS (13/34)
https://www.googleapis.com/auth/classroom.rosters PASS (14/34)
https://www.googleapis.com/auth/classroom.topics PASS (15/34)
https://www.googleapis.com/auth/cloud-identity PASS (16/34)
https://www.googleapis.com/auth/cloud-platform PASS (17/34)
https://www.googleapis.com/auth/contacts PASS (18/34)
https://www.googleapis.com/auth/contacts.other.readonly PASS (19/34)
https://www.googleapis.com/auth/datastudio PASS (20/34)
https://www.googleapis.com/auth/directory.readonly PASS (21/34)
https://www.googleapis.com/auth/documents PASS (22/34)
https://www.googleapis.com/auth/drive PASS (23/34)
https://www.googleapis.com/auth/drive.activity PASS (24/34)
https://www.googleapis.com/auth/drive.admin.labels FAIL (25/34)
https://www.googleapis.com/auth/drive.labels FAIL (26/34)
https://www.googleapis.com/auth/gmail.modify PASS (27/34)
https://www.googleapis.com/auth/gmail.settings.basic PASS (28/34)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (29/34)
https://www.googleapis.com/auth/keep PASS (30/34)
https://www.googleapis.com/auth/spreadsheets PASS (31/34)
https://www.googleapis.com/auth/tasks PASS (32/34)
https://www.googleapis.com/auth/userinfo.profile PASS (33/34)
https://www.googleapis.com/auth/youtube.readonly PASS (34/34)
Some scopes FAILED! Please go to:
https://admin.google.com/domain.com/ManageOauthClients?clientScopeToAdd=https://mail.google.com/,https://sites.google.com/feeds,https://www.google.com/m8/feeds,https://www.googleapis.com/auth/activity,https://www.googleapis.com/auth/apps.alerts,https://www.googleapis.com/auth/calendar,https://www.googleapis.com/auth/classroom.announcements,https://www.googleapis.com/auth/classroom.coursework.students,https://www.googleapis.com/auth/classroom.rosters,https://www.googleapis.com/auth/classroom.topics,https://www.googleapis.com/auth/cloudprint,https://www.googleapis.com/auth/contacts,https://www.googleapis.com/auth/drive,https://www.googleapis.com/auth/drive.activity,https://www.googleapis.com/auth/gmail.modify,https://www.googleapis.com/auth/gmail.settings.basic,https://www.googleapis.com/auth/gmail.settings.sharing,https://www.googleapis.com/auth/iam,https://www.googleapis.com/auth/spreadsheets,https://www.googleapis.com/auth/userinfo.email&clientNameToAdd=SVCACCTID
@@ -221,35 +233,41 @@ System time status:
Your system time differs by less than 1 second from Google PASS
Service Account Private Key Authentication:
Authentication PASS
Domain-Wide Delegation authentication:, User: user@domain.com, Scopes: 28
https://mail.google.com/ PASS (1/28)
https://sites.google.com/feeds PASS (2/28)
https://www.googleapis.com/auth/apps.alerts PASS (3/28)
https://www.googleapis.com/auth/calendar PASS (4/28)
https://www.googleapis.com/auth/classroom.announcements PASS (5/28)
https://www.googleapis.com/auth/classroom.coursework.students PASS (6/28)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (7/28)
https://www.googleapis.com/auth/classroom.profile.emails PASS (8/28)
https://www.googleapis.com/auth/classroom.rosters PASS (9/28)
https://www.googleapis.com/auth/classroom.topics PASS (10/28)
https://www.googleapis.com/auth/cloud-identity PASS (11/28)
https://www.googleapis.com/auth/cloud-platform PASS (12/28)
https://www.googleapis.com/auth/contacts PASS (13/28)
https://www.googleapis.com/auth/contacts.other.readonly PASS (14/28)
https://www.googleapis.com/auth/datastudio PASS (15/28)
https://www.googleapis.com/auth/directory.readonly PASS (16/28)
https://www.googleapis.com/auth/documents PASS (17/28)
https://www.googleapis.com/auth/drive PASS (18/28)
https://www.googleapis.com/auth/drive.activity PASS (19/28)
https://www.googleapis.com/auth/drive.admin.labels PASS (20/28)
https://www.googleapis.com/auth/drive.labels PASS (21/28)
https://www.googleapis.com/auth/gmail.modify PASS (22/28)
https://www.googleapis.com/auth/gmail.settings.basic PASS (23/28)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (24/28)
https://www.googleapis.com/auth/keep PASS (25/28)
https://www.googleapis.com/auth/spreadsheets PASS (26/28)
https://www.googleapis.com/auth/tasks PASS (27/28)
https://www.googleapis.com/auth/userinfo.profile PASS (28/28)
Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 34
https://mail.google.com/ PASS (1/34)
https://sites.google.com/feeds PASS (2/34)
https://www.googleapis.com/auth/analytics.readonly PASS (3/34)
https://www.googleapis.com/auth/apps.alerts PASS (4/34)
https://www.googleapis.com/auth/calendar PASS (5/34)
https://www.googleapis.com/auth/chat.delete PASS (6/34)
https://www.googleapis.com/auth/chat.memberships PASS (7/34)
https://www.googleapis.com/auth/chat.messages PASS (8/34)
https://www.googleapis.com/auth/chat.spaces PASS (9/34)
https://www.googleapis.com/auth/classroom.announcements PASS (10/34)
https://www.googleapis.com/auth/classroom.coursework.students PASS (11/34)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (12/34)
https://www.googleapis.com/auth/classroom.profile.emails PASS (13/34)
https://www.googleapis.com/auth/classroom.rosters PASS (14/34)
https://www.googleapis.com/auth/classroom.topics PASS (15/34)
https://www.googleapis.com/auth/cloud-identity PASS (16/34)
https://www.googleapis.com/auth/cloud-platform PASS (17/34)
https://www.googleapis.com/auth/contacts PASS (18/34)
https://www.googleapis.com/auth/contacts.other.readonly PASS (19/34)
https://www.googleapis.com/auth/datastudio PASS (20/34)
https://www.googleapis.com/auth/directory.readonly PASS (21/34)
https://www.googleapis.com/auth/documents PASS (22/34)
https://www.googleapis.com/auth/drive PASS (23/34)
https://www.googleapis.com/auth/drive.activity PASS (24/34)
https://www.googleapis.com/auth/drive.admin.labels PASS (25/34)
https://www.googleapis.com/auth/drive.labels PASS (26/34)
https://www.googleapis.com/auth/gmail.modify PASS (27/34)
https://www.googleapis.com/auth/gmail.settings.basic PASS (28/34)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (29/34)
https://www.googleapis.com/auth/keep PASS (30/34)
https://www.googleapis.com/auth/spreadsheets PASS (31/34)
https://www.googleapis.com/auth/tasks PASS (32/34)
https://www.googleapis.com/auth/userinfo.profile PASS (33/34)
https://www.googleapis.com/auth/youtube.readonly PASS (34/34)
All scopes PASSED!
Service Account Client name: SVCACCTID is fully authorized.
@@ -350,55 +368,61 @@ Append an 'r' to grant read-only access or an 'a' to grant action-only access.
[*] 0) Calendar API (supports readonly)
[*] 1) Chrome Browser Cloud Management API (supports readonly)
[*] 2) Chrome Management API - Telemetry read only
[*] 3) Chrome Management API - read only
[*] 4) Chrome Policy API (supports readonly)
[*] 5) Chrome Printer Management API (supports readonly)
[*] 6) Chrome Version History API
[*] 7) Classroom API - Course Announcements (supports readonly)
[*] 8) Classroom API - Course Topics (supports readonly)
[*] 9) Classroom API - Course Work/Materials (supports readonly)
[*] 10) Classroom API - Course Work/Submissions (supports readonly)
[*] 11) Classroom API - Courses (supports readonly)
[*] 12) Classroom API - Profile Emails
[*] 13) Classroom API - Profile Photos
[*] 14) Classroom API - Rosters (supports readonly)
[*] 15) Classroom API - Student Guardians (supports readonly)
[*] 16) Cloud Identity Groups API (supports readonly)
[*] 17) Cloud Storage (Vault Export - read only)
[*] 18) Contact Delegation API (supports readonly)
[*] 19) Contacts API - Domain Shared and Users and GAL
[*] 20) Data Transfer API (supports readonly)
[*] 21) Directory API - Chrome OS Devices (supports readonly)
[*] 22) Directory API - Customers (supports readonly)
[*] 23) Directory API - Domains (supports readonly)
[*] 24) Directory API - Groups (supports readonly)
[*] 25) Directory API - Mobile Devices Directory (supports readonly and action)
[*] 26) Directory API - Organizational Units (supports readonly)
[*] 27) Directory API - Resource Calendars (supports readonly)
[*] 28) Directory API - Roles (supports readonly)
[*] 29) Directory API - User Schemas (supports readonly)
[*] 30) Directory API - User Security
[*] 31) Directory API - Users (supports readonly)
[*] 32) Email Audit API
[*] 33) Groups Migration API
[*] 34) Groups Settings API
[*] 35) License Manager API
[*] 36) People API (supports readonly)
[*] 37) People Directory API - read only
[ ] 38) Pub / Sub API
[*] 39) Reports API - Audit Reports
[*] 40) Reports API - Usage Reports
[ ] 41) Reseller API
[*] 42) Site Verification API
[*] 43) Sites API
[*] 44) Vault API (supports readonly)
[*] 2) Chrome Management API - AppDetails read only
[*] 3) Chrome Management API - Telemetry read only
[*] 4) Chrome Management API - read only
[*] 5) Chrome Policy API (supports readonly)
[*] 6) Chrome Printer Management API (supports readonly)
[ ] 7) Chrome Version History API
[*] 8) Classroom API - Course Announcements (supports readonly)
[*] 9) Classroom API - Course Topics (supports readonly)
[*] 10) Classroom API - Course Work/Materials (supports readonly)
[*] 11) Classroom API - Course Work/Submissions (supports readonly)
[*] 12) Classroom API - Courses (supports readonly)
[*] 13) Classroom API - Profile Emails
[*] 14) Classroom API - Profile Photos
[*] 15) Classroom API - Rosters (supports readonly)
[*] 16) Classroom API - Student Guardians (supports readonly)
[*] 17) Cloud Channel API (supports readonly)
[*] 18) Cloud Identity - Inbound SSO Settings (supports readonly)
[*] 19) Cloud Identity Groups API (supports readonly)
[*] 20) Cloud Identity OrgUnits API (supports readonly)
[*] 21) Cloud Identity User Invitations API (supports readonly)
[ ] 22) Cloud Storage API (Read Only, Vault/Takeout Download, Cloud Storage)
[ ] 23) Cloud Storage API (Read/Write, Vault/Takeout Copy/Download, Cloud Storage)
[*] 24) Contact Delegation API (supports readonly)
[*] 25) Contacts API - Domain Shared Contacts and GAL
[*] 26) Data Transfer API (supports readonly)
[*] 27) Directory API - Chrome OS Devices (supports readonly)
[*] 28) Directory API - Customers (supports readonly)
[*] 29) Directory API - Domains (supports readonly)
[*] 30) Directory API - Groups (supports readonly)
[*] 31) Directory API - Mobile Devices Directory (supports readonly and action)
[*] 32) Directory API - Organizational Units (supports readonly)
[*] 33) Directory API - Resource Calendars (supports readonly)
[*] 34) Directory API - Roles (supports readonly)
[*] 35) Directory API - User Schemas (supports readonly)
[*] 36) Directory API - User Security
[*] 37) Directory API - Users (supports readonly)
[ ] 38) Email Audit API
[*] 39) Groups Migration API
[*] 40) Groups Settings API
[*] 41) License Manager API
[*] 42) People API (supports readonly)
[*] 43) People Directory API - read only
[ ] 44) Pub / Sub API
[*] 45) Reports API - Audit Reports
[*] 46) Reports API - Usage Reports
[*] 47) Reseller API
[*] 48) Site Verification API
[ ] 49) Sites API
[*] 50) Vault API (supports readonly)
s) Select all scopes
u) Unselect all scopes
e) Exit without changes
c) Continue to authorization
Please enter 0-44[a|r] or s|u|e|c: c
Please enter 0-50[a|r] or s|u|e|c: c
Enter your Google Workspace admin email address? admin@domain.com
@@ -421,35 +445,41 @@ System time status:
Your system time differs by less than 1 second from Google PASS
Service Account Private Key Authentication:
Authentication PASS
Domain-Wide Delegation authentication:, User: user@domain.com, Scopes: 28
https://mail.google.com/ PASS (1/28)
https://sites.google.com/feeds PASS (2/28)
https://www.googleapis.com/auth/apps.alerts PASS (3/28)
https://www.googleapis.com/auth/calendar PASS (4/28)
https://www.googleapis.com/auth/classroom.announcements PASS (5/28)
https://www.googleapis.com/auth/classroom.coursework.students PASS (6/28)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (7/28)
https://www.googleapis.com/auth/classroom.profile.emails PASS (8/28)
https://www.googleapis.com/auth/classroom.rosters PASS (9/28)
https://www.googleapis.com/auth/classroom.topics PASS (10/28)
https://www.googleapis.com/auth/cloud-identity PASS (11/28)
https://www.googleapis.com/auth/cloud-platform PASS (12/28)
https://www.googleapis.com/auth/contacts PASS (13/28)
https://www.googleapis.com/auth/contacts.other.readonly PASS (14/28)
https://www.googleapis.com/auth/datastudio PASS (15/28)
https://www.googleapis.com/auth/directory.readonly PASS (16/28)
https://www.googleapis.com/auth/documents PASS (17/28)
https://www.googleapis.com/auth/drive PASS (18/28)
https://www.googleapis.com/auth/drive.activity PASS (19/28)
https://www.googleapis.com/auth/drive.admin.labels FAIL (20/28)
https://www.googleapis.com/auth/drive.labels FAIL (21/28)
https://www.googleapis.com/auth/gmail.modify PASS (22/28)
https://www.googleapis.com/auth/gmail.settings.basic PASS (23/28)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (24/28)
https://www.googleapis.com/auth/keep PASS (25/28)
https://www.googleapis.com/auth/spreadsheets PASS (26/28)
https://www.googleapis.com/auth/tasks PASS (27/28)
https://www.googleapis.com/auth/userinfo.profile PASS (28/28)
Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 34
https://mail.google.com/ PASS (1/34)
https://sites.google.com/feeds PASS (2/34)
https://www.googleapis.com/auth/analytics.readonly PASS (3/34)
https://www.googleapis.com/auth/apps.alerts PASS (4/34)
https://www.googleapis.com/auth/calendar PASS (5/34)
https://www.googleapis.com/auth/chat.delete PASS (6/34)
https://www.googleapis.com/auth/chat.memberships PASS (7/34)
https://www.googleapis.com/auth/chat.messages PASS (8/34)
https://www.googleapis.com/auth/chat.spaces PASS (9/34)
https://www.googleapis.com/auth/classroom.announcements PASS (10/34)
https://www.googleapis.com/auth/classroom.coursework.students PASS (11/34)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (12/34)
https://www.googleapis.com/auth/classroom.profile.emails PASS (13/34)
https://www.googleapis.com/auth/classroom.rosters PASS (14/34)
https://www.googleapis.com/auth/classroom.topics PASS (15/34)
https://www.googleapis.com/auth/cloud-identity PASS (16/34)
https://www.googleapis.com/auth/cloud-platform PASS (17/34)
https://www.googleapis.com/auth/contacts PASS (18/34)
https://www.googleapis.com/auth/contacts.other.readonly PASS (19/34)
https://www.googleapis.com/auth/datastudio PASS (20/34)
https://www.googleapis.com/auth/directory.readonly PASS (21/34)
https://www.googleapis.com/auth/documents PASS (22/34)
https://www.googleapis.com/auth/drive PASS (23/34)
https://www.googleapis.com/auth/drive.activity PASS (24/34)
https://www.googleapis.com/auth/drive.admin.labels FAIL (25/34)
https://www.googleapis.com/auth/drive.labels FAIL (26/34)
https://www.googleapis.com/auth/gmail.modify PASS (27/34)
https://www.googleapis.com/auth/gmail.settings.basic PASS (28/34)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (29/34)
https://www.googleapis.com/auth/keep PASS (30/34)
https://www.googleapis.com/auth/spreadsheets PASS (31/34)
https://www.googleapis.com/auth/tasks PASS (32/34)
https://www.googleapis.com/auth/userinfo.profile PASS (33/34)
https://www.googleapis.com/auth/youtube.readonly PASS (34/34)
Some scopes FAILED! Please go to:
https://admin.google.com/domain.com/ManageOauthClients?clientScopeToAdd=https://mail.google.com/,https://sites.google.com/feeds,https://www.google.com/m8/feeds,https://www.googleapis.com/auth/activity,https://www.googleapis.com/auth/apps.alerts,https://www.googleapis.com/auth/calendar,https://www.googleapis.com/auth/classroom.announcements,https://www.googleapis.com/auth/classroom.coursework.students,https://www.googleapis.com/auth/classroom.rosters,https://www.googleapis.com/auth/classroom.topics,https://www.googleapis.com/auth/cloudprint,https://www.googleapis.com/auth/contacts,https://www.googleapis.com/auth/drive,https://www.googleapis.com/auth/drive.activity,https://www.googleapis.com/auth/gmail.modify,https://www.googleapis.com/auth/gmail.settings.basic,https://www.googleapis.com/auth/gmail.settings.sharing,https://www.googleapis.com/auth/iam,https://www.googleapis.com/auth/spreadsheets,https://www.googleapis.com/auth/userinfo.email&clientNameToAdd=SVCACCTID
@@ -474,35 +504,41 @@ System time status:
Your system time differs by less than 1 second from Google PASS
Service Account Private Key Authentication:
Authentication PASS
Domain-Wide Delegation authentication:, User: user@domain.com, Scopes: 28
https://mail.google.com/ PASS (1/28)
https://sites.google.com/feeds PASS (2/28)
https://www.googleapis.com/auth/apps.alerts PASS (3/28)
https://www.googleapis.com/auth/calendar PASS (4/28)
https://www.googleapis.com/auth/classroom.announcements PASS (5/28)
https://www.googleapis.com/auth/classroom.coursework.students PASS (6/28)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (7/28)
https://www.googleapis.com/auth/classroom.profile.emails PASS (8/28)
https://www.googleapis.com/auth/classroom.rosters PASS (9/28)
https://www.googleapis.com/auth/classroom.topics PASS (10/28)
https://www.googleapis.com/auth/cloud-identity PASS (11/28)
https://www.googleapis.com/auth/cloud-platform PASS (12/28)
https://www.googleapis.com/auth/contacts PASS (13/28)
https://www.googleapis.com/auth/contacts.other.readonly PASS (14/28)
https://www.googleapis.com/auth/datastudio PASS (15/28)
https://www.googleapis.com/auth/directory.readonly PASS (16/28)
https://www.googleapis.com/auth/documents PASS (17/28)
https://www.googleapis.com/auth/drive PASS (18/28)
https://www.googleapis.com/auth/drive.activity PASS (19/28)
https://www.googleapis.com/auth/drive.admin.labels PASS (20/28)
https://www.googleapis.com/auth/drive.labels PASS (21/28)
https://www.googleapis.com/auth/gmail.modify PASS (22/28)
https://www.googleapis.com/auth/gmail.settings.basic PASS (23/28)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (24/28)
https://www.googleapis.com/auth/keep PASS (25/28)
https://www.googleapis.com/auth/spreadsheets PASS (26/28)
https://www.googleapis.com/auth/tasks PASS (27/28)
https://www.googleapis.com/auth/userinfo.profile PASS (28/28)
Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 34
https://mail.google.com/ PASS (1/34)
https://sites.google.com/feeds PASS (2/34)
https://www.googleapis.com/auth/analytics.readonly PASS (3/34)
https://www.googleapis.com/auth/apps.alerts PASS (4/34)
https://www.googleapis.com/auth/calendar PASS (5/34)
https://www.googleapis.com/auth/chat.delete PASS (6/34)
https://www.googleapis.com/auth/chat.memberships PASS (7/34)
https://www.googleapis.com/auth/chat.messages PASS (8/34)
https://www.googleapis.com/auth/chat.spaces PASS (9/34)
https://www.googleapis.com/auth/classroom.announcements PASS (10/34)
https://www.googleapis.com/auth/classroom.coursework.students PASS (11/34)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (12/34)
https://www.googleapis.com/auth/classroom.profile.emails PASS (13/34)
https://www.googleapis.com/auth/classroom.rosters PASS (14/34)
https://www.googleapis.com/auth/classroom.topics PASS (15/34)
https://www.googleapis.com/auth/cloud-identity PASS (16/34)
https://www.googleapis.com/auth/cloud-platform PASS (17/34)
https://www.googleapis.com/auth/contacts PASS (18/34)
https://www.googleapis.com/auth/contacts.other.readonly PASS (19/34)
https://www.googleapis.com/auth/datastudio PASS (20/34)
https://www.googleapis.com/auth/directory.readonly PASS (21/34)
https://www.googleapis.com/auth/documents PASS (22/34)
https://www.googleapis.com/auth/drive PASS (23/34)
https://www.googleapis.com/auth/drive.activity PASS (24/34)
https://www.googleapis.com/auth/drive.admin.labels PASS (25/34)
https://www.googleapis.com/auth/drive.labels PASS (26/34)
https://www.googleapis.com/auth/gmail.modify PASS (27/34)
https://www.googleapis.com/auth/gmail.settings.basic PASS (28/34)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (29/34)
https://www.googleapis.com/auth/keep PASS (30/34)
https://www.googleapis.com/auth/spreadsheets PASS (31/34)
https://www.googleapis.com/auth/tasks PASS (32/34)
https://www.googleapis.com/auth/userinfo.profile PASS (33/34)
https://www.googleapis.com/auth/youtube.readonly PASS (34/34)
All scopes PASSED!
Service Account Client name: SVCACCTID is fully authorized.

View File

@@ -106,6 +106,7 @@ Section: DEFAULT
admin_email = ''
api_calls_rate_check = false
api_calls_rate_limit = 100
api_calls_tries_limit = 10
auto_batch_min = 0
bail_on_internal_error_tries = 2
batch_size = 50
@@ -174,6 +175,10 @@ Section: DEFAULT
oauth2_txt = oauth2.txt ; /Users/admin/GAMConfig/oauth2.txt
oauth2service_json = oauth2service.json ; /Users/admin/GAMConfig/oauth2service.json
people_max_results = 100
print_agu_domains = ''
print_cros_ous = ''
print_cros_ous_and_children = ''
process_wait_limit = 0
quick_cros_move = false
quick_info_user = false
reseller_id = ''
@@ -329,7 +334,7 @@ writes the credentials into the file oauth2.txt.
admin@server:/Users/admin/bin/gamadv-xtd3$ rm -f /Users/admin/GAMConfig/oauth2.txt
admin@server:/Users/admin/bin/gamadv-xtd3$ ./gam version
WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
GAMADV-XTD3 6.62.05 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.65.15 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.10.8 64-bit final
MacOS High Sierra 10.13.6 x86_64
@@ -343,55 +348,61 @@ Append an 'r' to grant read-only access or an 'a' to grant action-only access.
[*] 0) Calendar API (supports readonly)
[*] 1) Chrome Browser Cloud Management API (supports readonly)
[*] 2) Chrome Management API - Telemetry read only
[*] 3) Chrome Management API - read only
[*] 4) Chrome Policy API (supports readonly)
[*] 5) Chrome Printer Management API (supports readonly)
[*] 6) Chrome Version History API
[*] 7) Classroom API - Course Announcements (supports readonly)
[*] 8) Classroom API - Course Topics (supports readonly)
[*] 9) Classroom API - Course Work/Materials (supports readonly)
[*] 10) Classroom API - Course Work/Submissions (supports readonly)
[*] 11) Classroom API - Courses (supports readonly)
[*] 12) Classroom API - Profile Emails
[*] 13) Classroom API - Profile Photos
[*] 14) Classroom API - Rosters (supports readonly)
[*] 15) Classroom API - Student Guardians (supports readonly)
[*] 16) Cloud Identity Groups API (supports readonly)
[*] 17) Cloud Storage (Vault Export - read only)
[*] 18) Contact Delegation API (supports readonly)
[*] 19) Contacts API - Domain Shared and Users and GAL
[*] 20) Data Transfer API (supports readonly)
[*] 21) Directory API - Chrome OS Devices (supports readonly)
[*] 22) Directory API - Customers (supports readonly)
[*] 23) Directory API - Domains (supports readonly)
[*] 24) Directory API - Groups (supports readonly)
[*] 25) Directory API - Mobile Devices Directory (supports readonly and action)
[*] 26) Directory API - Organizational Units (supports readonly)
[*] 27) Directory API - Resource Calendars (supports readonly)
[*] 28) Directory API - Roles (supports readonly)
[*] 29) Directory API - User Schemas (supports readonly)
[*] 30) Directory API - User Security
[*] 31) Directory API - Users (supports readonly)
[*] 32) Email Audit API
[*] 33) Groups Migration API
[*] 34) Groups Settings API
[*] 35) License Manager API
[*] 36) People API (supports readonly)
[*] 37) People Directory API - read only
[ ] 38) Pub / Sub API
[*] 39) Reports API - Audit Reports
[*] 40) Reports API - Usage Reports
[ ] 41) Reseller API
[*] 42) Site Verification API
[*] 43) Sites API
[*] 44) Vault API (supports readonly)
[*] 2) Chrome Management API - AppDetails read only
[*] 3) Chrome Management API - Telemetry read only
[*] 4) Chrome Management API - read only
[*] 5) Chrome Policy API (supports readonly)
[*] 6) Chrome Printer Management API (supports readonly)
[ ] 7) Chrome Version History API
[*] 8) Classroom API - Course Announcements (supports readonly)
[*] 9) Classroom API - Course Topics (supports readonly)
[*] 10) Classroom API - Course Work/Materials (supports readonly)
[*] 11) Classroom API - Course Work/Submissions (supports readonly)
[*] 12) Classroom API - Courses (supports readonly)
[*] 13) Classroom API - Profile Emails
[*] 14) Classroom API - Profile Photos
[*] 15) Classroom API - Rosters (supports readonly)
[*] 16) Classroom API - Student Guardians (supports readonly)
[*] 17) Cloud Channel API (supports readonly)
[*] 18) Cloud Identity - Inbound SSO Settings (supports readonly)
[*] 19) Cloud Identity Groups API (supports readonly)
[*] 20) Cloud Identity OrgUnits API (supports readonly)
[*] 21) Cloud Identity User Invitations API (supports readonly)
[ ] 22) Cloud Storage API (Read Only, Vault/Takeout Download, Cloud Storage)
[ ] 23) Cloud Storage API (Read/Write, Vault/Takeout Copy/Download, Cloud Storage)
[*] 24) Contact Delegation API (supports readonly)
[*] 25) Contacts API - Domain Shared Contacts and GAL
[*] 26) Data Transfer API (supports readonly)
[*] 27) Directory API - Chrome OS Devices (supports readonly)
[*] 28) Directory API - Customers (supports readonly)
[*] 29) Directory API - Domains (supports readonly)
[*] 30) Directory API - Groups (supports readonly)
[*] 31) Directory API - Mobile Devices Directory (supports readonly and action)
[*] 32) Directory API - Organizational Units (supports readonly)
[*] 33) Directory API - Resource Calendars (supports readonly)
[*] 34) Directory API - Roles (supports readonly)
[*] 35) Directory API - User Schemas (supports readonly)
[*] 36) Directory API - User Security
[*] 37) Directory API - Users (supports readonly)
[ ] 38) Email Audit API
[*] 39) Groups Migration API
[*] 40) Groups Settings API
[*] 41) License Manager API
[*] 42) People API (supports readonly)
[*] 43) People Directory API - read only
[ ] 44) Pub / Sub API
[*] 45) Reports API - Audit Reports
[*] 46) Reports API - Usage Reports
[*] 47) Reseller API
[*] 48) Site Verification API
[ ] 49) Sites API
[*] 50) Vault API (supports readonly)
s) Select all scopes
u) Unselect all scopes
e) Exit without changes
c) Continue to authorization
Please enter 0-44[a|r] or s|u|e|c: c
Please enter 0-50[a|r] or s|u|e|c: c
Enter your Google Workspace admin email address? admin@domain.com
@@ -419,35 +430,41 @@ Service Account Private Key Authentication
Authentication PASS
Service Account Private Key age; Google recommends rotating keys on a routine basis
Service Account Private Key age: 0 days PASS
Domain-Wide Delegation authentication:, User: admin@domain.com, Scopes: 28
https://mail.google.com/ PASS (1/28)
https://sites.google.com/feeds PASS (2/28)
https://www.googleapis.com/auth/apps.alerts PASS (3/28)
https://www.googleapis.com/auth/calendar PASS (4/28)
https://www.googleapis.com/auth/classroom.announcements PASS (5/28)
https://www.googleapis.com/auth/classroom.coursework.students PASS (6/28)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (7/28)
https://www.googleapis.com/auth/classroom.profile.emails PASS (8/28)
https://www.googleapis.com/auth/classroom.rosters PASS (9/28)
https://www.googleapis.com/auth/classroom.topics PASS (10/28)
https://www.googleapis.com/auth/cloud-identity PASS (11/28)
https://www.googleapis.com/auth/cloud-platform PASS (12/28)
https://www.googleapis.com/auth/contacts PASS (13/28)
https://www.googleapis.com/auth/contacts.other.readonly PASS (14/28)
https://www.googleapis.com/auth/datastudio PASS (15/28)
https://www.googleapis.com/auth/directory.readonly PASS (16/28)
https://www.googleapis.com/auth/documents PASS (17/28)
https://www.googleapis.com/auth/drive PASS (18/28)
https://www.googleapis.com/auth/drive.activity PASS (19/28)
https://www.googleapis.com/auth/drive.admin.labels FAIL (20/28)
https://www.googleapis.com/auth/drive.labels FAIL (21/28)
https://www.googleapis.com/auth/gmail.modify PASS (22/28)
https://www.googleapis.com/auth/gmail.settings.basic PASS (23/28)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (24/28)
https://www.googleapis.com/auth/keep PASS (25/28)
https://www.googleapis.com/auth/spreadsheets PASS (26/28)
https://www.googleapis.com/auth/tasks PASS (27/28)
https://www.googleapis.com/auth/userinfo.profile PASS (28/28)
Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 34
https://mail.google.com/ PASS (1/34)
https://sites.google.com/feeds PASS (2/34)
https://www.googleapis.com/auth/analytics.readonly PASS (3/34)
https://www.googleapis.com/auth/apps.alerts PASS (4/34)
https://www.googleapis.com/auth/calendar PASS (5/34)
https://www.googleapis.com/auth/chat.delete PASS (6/34)
https://www.googleapis.com/auth/chat.memberships PASS (7/34)
https://www.googleapis.com/auth/chat.messages PASS (8/34)
https://www.googleapis.com/auth/chat.spaces PASS (9/34)
https://www.googleapis.com/auth/classroom.announcements PASS (10/34)
https://www.googleapis.com/auth/classroom.coursework.students PASS (11/34)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (12/34)
https://www.googleapis.com/auth/classroom.profile.emails PASS (13/34)
https://www.googleapis.com/auth/classroom.rosters PASS (14/34)
https://www.googleapis.com/auth/classroom.topics PASS (15/34)
https://www.googleapis.com/auth/cloud-identity PASS (16/34)
https://www.googleapis.com/auth/cloud-platform PASS (17/34)
https://www.googleapis.com/auth/contacts PASS (18/34)
https://www.googleapis.com/auth/contacts.other.readonly PASS (19/34)
https://www.googleapis.com/auth/datastudio PASS (20/34)
https://www.googleapis.com/auth/directory.readonly PASS (21/34)
https://www.googleapis.com/auth/documents PASS (22/34)
https://www.googleapis.com/auth/drive PASS (23/34)
https://www.googleapis.com/auth/drive.activity PASS (24/34)
https://www.googleapis.com/auth/drive.admin.labels FAIL (25/34)
https://www.googleapis.com/auth/drive.labels FAIL (26/34)
https://www.googleapis.com/auth/gmail.modify PASS (27/34)
https://www.googleapis.com/auth/gmail.settings.basic PASS (28/34)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (29/34)
https://www.googleapis.com/auth/keep PASS (30/34)
https://www.googleapis.com/auth/spreadsheets PASS (31/34)
https://www.googleapis.com/auth/tasks PASS (32/34)
https://www.googleapis.com/auth/userinfo.profile PASS (33/34)
https://www.googleapis.com/auth/youtube.readonly PASS (34/34)
Some scopes FAILED!
To authorize them, please go to:
@@ -475,35 +492,41 @@ System time status:
Your system time differs from www.googleapis.com by less than 1 second PASS
Service Account Private Key Authentication:
Authentication PASS
Domain-Wide Delegation authentication:, User: admin@domain.com, Scopes: 28
https://mail.google.com/ PASS (1/28)
https://sites.google.com/feeds PASS (2/28)
https://www.googleapis.com/auth/apps.alerts PASS (3/28)
https://www.googleapis.com/auth/calendar PASS (4/28)
https://www.googleapis.com/auth/classroom.announcements PASS (5/28)
https://www.googleapis.com/auth/classroom.coursework.students PASS (6/28)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (7/28)
https://www.googleapis.com/auth/classroom.profile.emails PASS (8/28)
https://www.googleapis.com/auth/classroom.rosters PASS (9/28)
https://www.googleapis.com/auth/classroom.topics PASS (10/28)
https://www.googleapis.com/auth/cloud-identity PASS (11/28)
https://www.googleapis.com/auth/cloud-platform PASS (12/28)
https://www.googleapis.com/auth/contacts PASS (13/28)
https://www.googleapis.com/auth/contacts.other.readonly PASS (14/28)
https://www.googleapis.com/auth/datastudio PASS (15/28)
https://www.googleapis.com/auth/directory.readonly PASS (16/28)
https://www.googleapis.com/auth/documents PASS (17/28)
https://www.googleapis.com/auth/drive PASS (18/28)
https://www.googleapis.com/auth/drive.activity PASS (19/28)
https://www.googleapis.com/auth/drive.admin.labels PASS (20/28)
https://www.googleapis.com/auth/drive.labels PASS (21/28)
https://www.googleapis.com/auth/gmail.modify PASS (22/28)
https://www.googleapis.com/auth/gmail.settings.basic PASS (23/28)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (24/28)
https://www.googleapis.com/auth/keep PASS (25/28)
https://www.googleapis.com/auth/spreadsheets PASS (26/28)
https://www.googleapis.com/auth/tasks PASS (27/28)
https://www.googleapis.com/auth/userinfo.profile PASS (28/28)
Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 34
https://mail.google.com/ PASS (1/34)
https://sites.google.com/feeds PASS (2/34)
https://www.googleapis.com/auth/analytics.readonly PASS (3/34)
https://www.googleapis.com/auth/apps.alerts PASS (4/34)
https://www.googleapis.com/auth/calendar PASS (5/34)
https://www.googleapis.com/auth/chat.delete PASS (6/34)
https://www.googleapis.com/auth/chat.memberships PASS (7/34)
https://www.googleapis.com/auth/chat.messages PASS (8/34)
https://www.googleapis.com/auth/chat.spaces PASS (9/34)
https://www.googleapis.com/auth/classroom.announcements PASS (10/34)
https://www.googleapis.com/auth/classroom.coursework.students PASS (11/34)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (12/34)
https://www.googleapis.com/auth/classroom.profile.emails PASS (13/34)
https://www.googleapis.com/auth/classroom.rosters PASS (14/34)
https://www.googleapis.com/auth/classroom.topics PASS (15/34)
https://www.googleapis.com/auth/cloud-identity PASS (16/34)
https://www.googleapis.com/auth/cloud-platform PASS (17/34)
https://www.googleapis.com/auth/contacts PASS (18/34)
https://www.googleapis.com/auth/contacts.other.readonly PASS (19/34)
https://www.googleapis.com/auth/datastudio PASS (20/34)
https://www.googleapis.com/auth/directory.readonly PASS (21/34)
https://www.googleapis.com/auth/documents PASS (22/34)
https://www.googleapis.com/auth/drive PASS (23/34)
https://www.googleapis.com/auth/drive.activity PASS (24/34)
https://www.googleapis.com/auth/drive.admin.labels PASS (25/34)
https://www.googleapis.com/auth/drive.labels PASS (26/34)
https://www.googleapis.com/auth/gmail.modify PASS (27/34)
https://www.googleapis.com/auth/gmail.settings.basic PASS (28/34)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (29/34)
https://www.googleapis.com/auth/keep PASS (30/34)
https://www.googleapis.com/auth/spreadsheets PASS (31/34)
https://www.googleapis.com/auth/tasks PASS (32/34)
https://www.googleapis.com/auth/userinfo.profile PASS (33/34)
https://www.googleapis.com/auth/youtube.readonly PASS (34/34)
All scopes PASSED!
Service Account Client name: SVCACCTID is fully authorized.
@@ -530,6 +553,7 @@ Section: DEFAULT
admin_email = ''
api_calls_rate_check = false
api_calls_rate_limit = 100
api_calls_tries_limit = 10
auto_batch_min = 0
bail_on_internal_error_tries = 2
batch_size = 50
@@ -595,6 +619,10 @@ Section: DEFAULT
oauth2_txt = oauth2.txt ; /Users/admin/GAMConfig/oauth2.txt
oauth2service_json = oauth2service.json ; /Users/admin/GAMConfig/oauth2service.json
people_max_results = 100
print_agu_domains = ''
print_cros_ous = ''
print_cros_ous_and_children = ''
process_wait_limit = 0
quick_cros_move = false
quick_info_user = False
reseller_id = ''
@@ -727,6 +755,7 @@ Section: DEFAULT
admin_email = ''
api_calls_rate_check = false
api_calls_rate_limit = 100
api_calls_tries_limit = 10
auto_batch_min = 0
bail_on_internal_error_tries = 2
batch_size = 50
@@ -792,6 +821,10 @@ Section: DEFAULT
oauth2_txt = oauth2.txt ; C:\GAMConfig\oauth2.txt
oauth2service_json = oauth2service.json ; C:\GAMConfig\oauth2service.json
people_max_results = 100
print_agu_domains = ''
print_cros_ous = ''
print_cros_ous_and_children = ''
process_wait_limit = 0
quick_cros_move = false
quick_info_user = False
reseller_id = ''
@@ -969,9 +1002,9 @@ writes the credentials into the file oauth2.txt.
C:\GAMADV-XTD3>del C:\GAMConfig\oauth2.txt
C:\GAMADV-XTD3>gam version
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
GAMADV-XTD3 6.62.05 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.65.15 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.11.4 64-bit final
Python 3.12.0 64-bit final
Windows-10-10.0.17134 AMD64
Path: C:\GAMADV-XTD3
Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, customer_id: my_customer, domain.com
@@ -983,55 +1016,61 @@ Append an 'r' to grant read-only access or an 'a' to grant action-only access.
[*] 0) Calendar API (supports readonly)
[*] 1) Chrome Browser Cloud Management API (supports readonly)
[*] 2) Chrome Management API - Telemetry read only
[*] 3) Chrome Management API - read only
[*] 4) Chrome Policy API (supports readonly)
[*] 5) Chrome Printer Management API (supports readonly)
[*] 6) Chrome Version History API
[*] 7) Classroom API - Course Announcements (supports readonly)
[*] 8) Classroom API - Course Topics (supports readonly)
[*] 9) Classroom API - Course Work/Materials (supports readonly)
[*] 10) Classroom API - Course Work/Submissions (supports readonly)
[*] 11) Classroom API - Courses (supports readonly)
[*] 12) Classroom API - Profile Emails
[*] 13) Classroom API - Profile Photos
[*] 14) Classroom API - Rosters (supports readonly)
[*] 15) Classroom API - Student Guardians (supports readonly)
[*] 16) Cloud Identity Groups API (supports readonly)
[*] 17) Cloud Storage (Vault Export - read only)
[*] 18) Contact Delegation API (supports readonly)
[*] 19) Contacts API - Domain Shared and Users and GAL
[*] 20) Data Transfer API (supports readonly)
[*] 21) Directory API - Chrome OS Devices (supports readonly)
[*] 22) Directory API - Customers (supports readonly)
[*] 23) Directory API - Domains (supports readonly)
[*] 24) Directory API - Groups (supports readonly)
[*] 25) Directory API - Mobile Devices Directory (supports readonly and action)
[*] 26) Directory API - Organizational Units (supports readonly)
[*] 27) Directory API - Resource Calendars (supports readonly)
[*] 28) Directory API - Roles (supports readonly)
[*] 29) Directory API - User Schemas (supports readonly)
[*] 30) Directory API - User Security
[*] 31) Directory API - Users (supports readonly)
[*] 32) Email Audit API
[*] 33) Groups Migration API
[*] 34) Groups Settings API
[*] 35) License Manager API
[*] 36) People API (supports readonly)
[*] 37) People Directory API - read only
[ ] 38) Pub / Sub API
[*] 39) Reports API - Audit Reports
[*] 40) Reports API - Usage Reports
[ ] 41) Reseller API
[*] 42) Site Verification API
[*] 43) Sites API
[*] 44) Vault API (supports readonly)
[*] 2) Chrome Management API - AppDetails read only
[*] 3) Chrome Management API - Telemetry read only
[*] 4) Chrome Management API - read only
[*] 5) Chrome Policy API (supports readonly)
[*] 6) Chrome Printer Management API (supports readonly)
[ ] 7) Chrome Version History API
[*] 8) Classroom API - Course Announcements (supports readonly)
[*] 9) Classroom API - Course Topics (supports readonly)
[*] 10) Classroom API - Course Work/Materials (supports readonly)
[*] 11) Classroom API - Course Work/Submissions (supports readonly)
[*] 12) Classroom API - Courses (supports readonly)
[*] 13) Classroom API - Profile Emails
[*] 14) Classroom API - Profile Photos
[*] 15) Classroom API - Rosters (supports readonly)
[*] 16) Classroom API - Student Guardians (supports readonly)
[*] 17) Cloud Channel API (supports readonly)
[*] 18) Cloud Identity - Inbound SSO Settings (supports readonly)
[*] 19) Cloud Identity Groups API (supports readonly)
[*] 20) Cloud Identity OrgUnits API (supports readonly)
[*] 21) Cloud Identity User Invitations API (supports readonly)
[ ] 22) Cloud Storage API (Read Only, Vault/Takeout Download, Cloud Storage)
[ ] 23) Cloud Storage API (Read/Write, Vault/Takeout Copy/Download, Cloud Storage)
[*] 24) Contact Delegation API (supports readonly)
[*] 25) Contacts API - Domain Shared Contacts and GAL
[*] 26) Data Transfer API (supports readonly)
[*] 27) Directory API - Chrome OS Devices (supports readonly)
[*] 28) Directory API - Customers (supports readonly)
[*] 29) Directory API - Domains (supports readonly)
[*] 30) Directory API - Groups (supports readonly)
[*] 31) Directory API - Mobile Devices Directory (supports readonly and action)
[*] 32) Directory API - Organizational Units (supports readonly)
[*] 33) Directory API - Resource Calendars (supports readonly)
[*] 34) Directory API - Roles (supports readonly)
[*] 35) Directory API - User Schemas (supports readonly)
[*] 36) Directory API - User Security
[*] 37) Directory API - Users (supports readonly)
[ ] 38) Email Audit API
[*] 39) Groups Migration API
[*] 40) Groups Settings API
[*] 41) License Manager API
[*] 42) People API (supports readonly)
[*] 43) People Directory API - read only
[ ] 44) Pub / Sub API
[*] 45) Reports API - Audit Reports
[*] 46) Reports API - Usage Reports
[*] 47) Reseller API
[*] 48) Site Verification API
[ ] 49) Sites API
[*] 50) Vault API (supports readonly)
s) Select all scopes
u) Unselect all scopes
e) Exit without changes
c) Continue to authorization
Please enter 0-44![a|r] or s|u|e|c: c
Please enter 0-50[a|r] or s|u|e|c: c
Enter your Google Workspace admin email address? admin@domain.com
@@ -1059,35 +1098,41 @@ Service Account Private Key Authentication
Authentication PASS
Service Account Private Key age; Google recommends rotating keys on a routine basis
Service Account Private Key age: 0 days PASS
Domain-Wide Delegation authentication:, User: admin@domain.com, Scopes: 28
https://mail.google.com/ PASS (1/28)
https://sites.google.com/feeds PASS (2/28)
https://www.googleapis.com/auth/apps.alerts PASS (3/28)
https://www.googleapis.com/auth/calendar PASS (4/28)
https://www.googleapis.com/auth/classroom.announcements PASS (5/28)
https://www.googleapis.com/auth/classroom.coursework.students PASS (6/28)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (7/28)
https://www.googleapis.com/auth/classroom.profile.emails PASS (8/28)
https://www.googleapis.com/auth/classroom.rosters PASS (9/28)
https://www.googleapis.com/auth/classroom.topics PASS (10/28)
https://www.googleapis.com/auth/cloud-identity PASS (11/28)
https://www.googleapis.com/auth/cloud-platform PASS (12/28)
https://www.googleapis.com/auth/contacts PASS (13/28)
https://www.googleapis.com/auth/contacts.other.readonly PASS (14/28)
https://www.googleapis.com/auth/datastudio PASS (15/28)
https://www.googleapis.com/auth/directory.readonly PASS (16/28)
https://www.googleapis.com/auth/documents PASS (17/28)
https://www.googleapis.com/auth/drive PASS (18/28)
https://www.googleapis.com/auth/drive.activity PASS (19/28)
https://www.googleapis.com/auth/drive.admin.labels FAIL (20/28)
https://www.googleapis.com/auth/drive.labels FAIL (21/28)
https://www.googleapis.com/auth/gmail.modify PASS (22/28)
https://www.googleapis.com/auth/gmail.settings.basic PASS (23/28)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (24/28)
https://www.googleapis.com/auth/keep PASS (25/28)
https://www.googleapis.com/auth/spreadsheets PASS (26/28)
https://www.googleapis.com/auth/tasks PASS (27/28)
https://www.googleapis.com/auth/userinfo.profile PASS (28/28)
Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 34
https://mail.google.com/ PASS (1/34)
https://sites.google.com/feeds PASS (2/34)
https://www.googleapis.com/auth/analytics.readonly PASS (3/34)
https://www.googleapis.com/auth/apps.alerts PASS (4/34)
https://www.googleapis.com/auth/calendar PASS (5/34)
https://www.googleapis.com/auth/chat.delete PASS (6/34)
https://www.googleapis.com/auth/chat.memberships PASS (7/34)
https://www.googleapis.com/auth/chat.messages PASS (8/34)
https://www.googleapis.com/auth/chat.spaces PASS (9/34)
https://www.googleapis.com/auth/classroom.announcements PASS (10/34)
https://www.googleapis.com/auth/classroom.coursework.students PASS (11/34)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (12/34)
https://www.googleapis.com/auth/classroom.profile.emails PASS (13/34)
https://www.googleapis.com/auth/classroom.rosters PASS (14/34)
https://www.googleapis.com/auth/classroom.topics PASS (15/34)
https://www.googleapis.com/auth/cloud-identity PASS (16/34)
https://www.googleapis.com/auth/cloud-platform PASS (17/34)
https://www.googleapis.com/auth/contacts PASS (18/34)
https://www.googleapis.com/auth/contacts.other.readonly PASS (19/34)
https://www.googleapis.com/auth/datastudio PASS (20/34)
https://www.googleapis.com/auth/directory.readonly PASS (21/34)
https://www.googleapis.com/auth/documents PASS (22/34)
https://www.googleapis.com/auth/drive PASS (23/34)
https://www.googleapis.com/auth/drive.activity PASS (24/34)
https://www.googleapis.com/auth/drive.admin.labels FAIL (25/34)
https://www.googleapis.com/auth/drive.labels FAIL (26/34)
https://www.googleapis.com/auth/gmail.modify PASS (27/34)
https://www.googleapis.com/auth/gmail.settings.basic PASS (28/34)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (29/34)
https://www.googleapis.com/auth/keep PASS (30/34)
https://www.googleapis.com/auth/spreadsheets PASS (31/34)
https://www.googleapis.com/auth/tasks PASS (32/34)
https://www.googleapis.com/auth/userinfo.profile PASS (33/34)
https://www.googleapis.com/auth/youtube.readonly PASS (34/34)
Some scopes FAILED!
To authorize them, please go to:
@@ -1115,35 +1160,41 @@ System time status:
Your system time differs from www.googleapis.com by less than 1 second PASS
Service Account Private Key Authentication:
Authentication PASS
Domain-Wide Delegation authentication:, User: admin@domain.com, Scopes: 28
https://mail.google.com/ PASS (1/28)
https://sites.google.com/feeds PASS (2/28)
https://www.googleapis.com/auth/apps.alerts PASS (3/28)
https://www.googleapis.com/auth/calendar PASS (4/28)
https://www.googleapis.com/auth/classroom.announcements PASS (5/28)
https://www.googleapis.com/auth/classroom.coursework.students PASS (6/28)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (7/28)
https://www.googleapis.com/auth/classroom.profile.emails PASS (8/28)
https://www.googleapis.com/auth/classroom.rosters PASS (9/28)
https://www.googleapis.com/auth/classroom.topics PASS (10/28)
https://www.googleapis.com/auth/cloud-identity PASS (11/28)
https://www.googleapis.com/auth/cloud-platform PASS (12/28)
https://www.googleapis.com/auth/contacts PASS (13/28)
https://www.googleapis.com/auth/contacts.other.readonly PASS (14/28)
https://www.googleapis.com/auth/datastudio PASS (15/28)
https://www.googleapis.com/auth/directory.readonly PASS (16/28)
https://www.googleapis.com/auth/documents PASS (17/28)
https://www.googleapis.com/auth/drive PASS (18/28)
https://www.googleapis.com/auth/drive.activity PASS (19/28)
https://www.googleapis.com/auth/drive.admin.labels PASS (20/28)
https://www.googleapis.com/auth/drive.labels PASS (21/28)
https://www.googleapis.com/auth/gmail.modify PASS (22/28)
https://www.googleapis.com/auth/gmail.settings.basic PASS (23/28)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (24/28)
https://www.googleapis.com/auth/keep PASS (25/28)
https://www.googleapis.com/auth/spreadsheets PASS (26/28)
https://www.googleapis.com/auth/tasks PASS (27/28)
https://www.googleapis.com/auth/userinfo.profile PASS (28/28)
Domain-wide Delegation authentication:, User: admin@domain.com, Scopes: 34
https://mail.google.com/ PASS (1/34)
https://sites.google.com/feeds PASS (2/34)
https://www.googleapis.com/auth/analytics.readonly PASS (3/34)
https://www.googleapis.com/auth/apps.alerts PASS (4/34)
https://www.googleapis.com/auth/calendar PASS (5/34)
https://www.googleapis.com/auth/chat.delete PASS (6/34)
https://www.googleapis.com/auth/chat.memberships PASS (7/34)
https://www.googleapis.com/auth/chat.messages PASS (8/34)
https://www.googleapis.com/auth/chat.spaces PASS (9/34)
https://www.googleapis.com/auth/classroom.announcements PASS (10/34)
https://www.googleapis.com/auth/classroom.coursework.students PASS (11/34)
https://www.googleapis.com/auth/classroom.courseworkmaterials PASS (12/34)
https://www.googleapis.com/auth/classroom.profile.emails PASS (13/34)
https://www.googleapis.com/auth/classroom.rosters PASS (14/34)
https://www.googleapis.com/auth/classroom.topics PASS (15/34)
https://www.googleapis.com/auth/cloud-identity PASS (16/34)
https://www.googleapis.com/auth/cloud-platform PASS (17/34)
https://www.googleapis.com/auth/contacts PASS (18/34)
https://www.googleapis.com/auth/contacts.other.readonly PASS (19/34)
https://www.googleapis.com/auth/datastudio PASS (20/34)
https://www.googleapis.com/auth/directory.readonly PASS (21/34)
https://www.googleapis.com/auth/documents PASS (22/34)
https://www.googleapis.com/auth/drive PASS (23/34)
https://www.googleapis.com/auth/drive.activity PASS (24/34)
https://www.googleapis.com/auth/drive.admin.labels PASS (25/34)
https://www.googleapis.com/auth/drive.labels PASS (26/34)
https://www.googleapis.com/auth/gmail.modify PASS (27/34)
https://www.googleapis.com/auth/gmail.settings.basic PASS (28/34)
https://www.googleapis.com/auth/gmail.settings.sharing PASS (29/34)
https://www.googleapis.com/auth/keep PASS (30/34)
https://www.googleapis.com/auth/spreadsheets PASS (31/34)
https://www.googleapis.com/auth/tasks PASS (32/34)
https://www.googleapis.com/auth/userinfo.profile PASS (33/34)
https://www.googleapis.com/auth/youtube.readonly PASS (34/34)
All scopes PASSED!
Service Account Client name: SVCACCTID is fully authorized.
@@ -1170,6 +1221,7 @@ Section: DEFAULT
admin_email = ''
api_calls_rate_check = false
api_calls_rate_limit = 100
api_calls_tries_limit = 10
auto_batch_min = 0
bail_on_internal_error_tries = 2
batch_size = 50
@@ -1237,6 +1289,10 @@ Section: DEFAULT
output_dateformat = ''
output_timeformat = ''
people_max_results = 100
print_agu_domains = ''
print_cros_ous = ''
print_cros_ous_and_children = ''
process_wait_limit = 0
quick_cros_move = false
quick_info_user = False
reseller_id = ''

View File

@@ -24,11 +24,13 @@
| Cloud Identity Free | 101001 |
| Cloud Identity Premium | 101005 |
| Cloud Search | 101035 |
| Duet AI | 101047 |
| Google Chrome Device Management | Google-Chrome-Device-Management |
| Google Drive Storage | Google-Drive-storage |
| Google Meet Global Dialing | 101036 |
| Google Vault |Google-Vault |
| Google Voice | 101033 |
| Google Workspace Additional Storage | 101043 |
| Google Workspace Archived User | 101034 |
| Google Workspace for Education | 101031 |
| Google Workspace for Education | 101037 |
@@ -44,6 +46,7 @@
| Cloud Identity Free | 1010010001 | cloudidentity |
| Cloud Identity Premium | 1010050001 | cloudidentitypremium |
| Cloud Search | 1010350001 | cloudsearch |
| Duet AI | 1010470001 | duetai |
| G Suite Basic | Google-Apps-For-Business | gsuitebasic |
| G Suite Business | Google-Apps-Unlimited | gsuitebusiness |
| G Suite Legacy | Google-Apps | standard |
@@ -65,6 +68,7 @@
| Google Voice Premier | 1010330002 | voicepremier |
| Google Voice Standard | 1010330004 | voicestandard |
| Google Voice Starter | 1010330003 | voicestarter |
| Google Workspace Additional Storage | 1010430001 | gwas |
| Google Workspace Business - Archived User | 1010340002 | gsuitebusinessarchived |
| Google Workspace Business Plus | 1010020025 | wsbizplus |
| Google Workspace Business Plus - Archived User | 1010340003 | wsbizplusarchived |
@@ -92,6 +96,7 @@
| Google Workspace for Education: Teaching and Learning Upgrade | 1010370001 | gwetlu |
| Google Workspace Frontline Starter | 1010020030 | wsflw |
| Google Workspace Frontline Standard | 1010020031 | wsflwstan |
| Google Workspace Labs | 1010470002 | gwlabs | workspacelabs |
## Definitions
```
@@ -108,6 +113,8 @@
101038 |
101039 |
101040 |
101043 |
101047 |
Google-Apps |
Google-Chrome-Device-Management |
Google-Drive-storage |
@@ -134,6 +141,7 @@
cloudidentity | identity | 1010010001 |
cloudidentitypremium | identitypremium | 1010050001 |
cloudsearch | 1010350001 |
duetai | 1010470001 |
gsuitebasic | gafb | gafw | basic | Google-Apps-For-Business |
gsuitebusiness | gau | gsb | unlimited | Google-Apps-Unlimited |
gsuitebusinessarchived | gsbau | businessarchived | 1010340002 |
@@ -149,6 +157,7 @@
gwesstaff | workspaceeducationstandardstaff | 1010310006 |
gwesstudent | workspaceeducationstandardstudent | 1010310007 |
gwetlu | workspaceeducationupgrade | 1010370001 |
gwlabs | workspacelabs | 1010470002
meetdialing | googlemeetglobaldialing | 1010360001 |
postini | gams | gsuitegams | gsuitepostini | gsuitemessagesecurity | Google-Apps-For-Postini |
standard | free | Google-Apps |
@@ -157,6 +166,7 @@
voicepremier | gvpremier | googlevoicepremier | 1010330002 |
voicestandard | gvstandard | googlevoicestandard | 1010330004 |
voicestarter | gvstarter | googlevoicestarter | 1010330003 |
wsas | plusstorage | 1010430001 |
wsbizplus | workspacebusinessplus | 1010020025 |
wsbizplusarchived | workspacebusinessplusarchived | 1010340003 |
wsbizstan | workspacebusinessstandard | 1010020028 |

View File

@@ -30,8 +30,6 @@
<CourseWorkIDList> ::= "<CourseWorkID>(,<CourseWorkID>)*"
<CourseWorkStateList> ::= all|"<CourseWorkState>(,<CourseWorkState>)*"
<CrOSIDList> ::= "<CrOSID>(,<CrOSID>)*"
<DataStudioAssetIDList> ::= "<DataStudioAssetID>(,<DataStudioAssetID>)*"
<DataStudioPermissionList> ::= "<DataStudioPermission>(,<DataStudioPermission>)*"
<DeviceIDList> ::= "<DeviceID>(,<DeviceID>)*"
<DeviceUserList> ::= "<DeviceUserID>(,<DeviceUserID>)*"
<DomainNameList> ::= "<DomainName>(,<DomainName>)*"
@@ -63,6 +61,8 @@
<LabelIDList> ::= "<LabelID>(,<LabelID>)*"
<LabelNameList> ::= "'<LabelName>'(,'<LabelName>')*"
<LanguageList> ::= "<Language>(,<Language>)*"
<LookerStudioAssetIDList> ::= "<LookerStudioAssetID>(,<LookerStudioAssetID>)*"
<LookerStudioPermissionList> ::= "<LookerStudioPermission>(,<LookerStudioPermission>)*"
<MatterItemList> ::= "<MatterItem>(,<MatterItem>)*"
<MatterStateList> ::= "<MatterState>(,<MatterState>)*"
<MessageIDList> ::= "<MessageID>(,<MessageID>)*"
@@ -78,6 +78,7 @@
<QueryBrowserList> ::= "<QueryBrowser>(,<QueryBrowser>)*"
<QueryCrOSList> ::= "<QueryCrOS>(,<QueryCrOS>)*"
<QueryDeviceList> ::= "<QueryDevice>(,<QueryDevice>)*"
<QueryGroupList> ::= "<QueryGroup>(,<QueryGroup>)*"
<QueryMobileList> ::= "<QueryMobile>(,<QueryMobile>)*"
<QueryUserList> ::= "<QueryUser>(,<QueryUser>)*"
<ResourceIDList> ::= "<ResourceID>(,<ResourceID>)*"
@@ -92,10 +93,12 @@
<SharedDriveIDList> ::= "<SharedDriveID>(,<SharedDriveID>)*"
<StringList> ::= "<String>(,<String>)*"
<TasklistIDList> ::= "<TasklistID>(,<TasklistID>)*"
<TasklistTitleList> ::= "'<TasklistTitle>'(,'<TasklistTitle>')*"
<TasklistIDTaskIDList> ::= "<TasklistIDTaskID>(,<TasklistIDTaskID>)*"
<ThreadIDList> ::= "<ThreadID>(,<ThreadID>)*"
<TimeList> ::= "<Time>(,<Time>)*"
<UserList> ::= "<UserItem>(,<UserItem>)*"
<YouTubeChannelIDList> ::= "<YouTubeChannelID>(,<YouTubeChannelID>)*"
```
## List quoting rules
Items in a list can be separated by commas or spaces; if an item itself contains a comma, a space or a single quote, special quoting must be used.

View File

@@ -100,7 +100,7 @@ By default, Gam displays the information as an indented list of keys and values.
## Print mobile devices
```
gam print mobile [todrive <ToDriveAttribute>*]
[(query <QueryMobile>)|(queries <QueryMobileList>) (querytime.* <Time>)*]
[(query <QueryMobile>)|(queries <QueryMobileList>) (querytime<String> <Time>)*]
[orderby <MobileOrderByFieldName> [ascending|descending]]
[basic|full|allfields] <MobileFieldName>* [fields <MobileFieldNameList>]
[delimiter <Character>] [appslimit <Number>] [oneappperrow] [listlimit <Number>]

View File

@@ -70,15 +70,17 @@ See: [List Items](List-Items)
Create, update and delete organization units.
```
gam create org|ou <OrgUnitPath> [description <String>]
[parent <OrgUnitItem>] [inherit|noinherit|(blockinheritance <Boolean>)]
[parent <OrgUnitItem>] [inherit|(blockinheritance False)]
[buildpath]
gam update org|ou <OrgUnitPath> [name <String>] [description <String>]
[parent <OrgUnitItem>] [inherit|noinherit|(blockinheritance <Boolean>)]
[parent <OrgUnitItem>] [inherit|(blockinheritance False)]
gam delete org|ou <OrgUnitPath>
gam update orgs|ous <OrgUnitEntity> [name <String>] [description <String>]
[parent <OrgUnitItem>] [inherit|noinherit|(blockinheritance <Boolean>)]
[parent <OrgUnitItem>] [inherit|(blockinheritance False)]
gam delete orgs|ous <OrgUnitEntity>
```
Inheritance specifies whether sub-OUs of the specified OU inherit its settings.
* `inherit|blockinheritance false` - Sub-OUs inherit settings from the specified OU; this is the default
## Add users to an organizational unit
When adding users to an OU, Gam uses a batch method to speed up processing.

View File

@@ -1,24 +1,18 @@
- [Introduction](#introduction)
- [Requirements](#requirements)
- [Installation - First time GAM installation](#installation---first-time-GAM-installation)
- [Installation - Upgrading from a GAM version other than a prior version of GAMADV-X or GAMADV-XTD or GAMADV-XTD3](#installation---upgrading-from-a-gam-version-other-than-a-prior-version-of-gamadv-x-or-gamadv-xtd-or-gamadv-xtd3)
- [Installation - Upgrading from a prior version of GAMADV-X or GAMADV-XTD or GAMADV-XTD3](#installation---upgrading-from-a-prior-version-of-gamadv-x-or-gamadv-xtd-or-gamadv-xtd3)
# Introduction
GAMADV-XTD3 is a free, open source command line tool for Google Workspace Administrators to manage domain and user settings quickly and easily.
GAMADV-XTD3 is a free, open source command line tool for Google Workspace (formerly G Suite) Administrators to manage domain and user settings quickly and easily.
GAMADV-XTD3 is built with Python 3; as Python 2 support ends on 2020-01-01, this is the version of Advanced GAM that new/existing users should install.
GAMADV-XTD3 is built with Python 3.
This page provides simple instructions for downloading, installing and starting to use GAMADV-XTD3.
GAMADV-XTD3 requires paid, or Education/Non-profit, editions of Google Workspace. G Suite Legacy Free Edition has limited API support and not all GAM commands work.
GAMADV-XTD3 runs on all versions of Google Workspace; Google Apps Free Edition has limited API support and not all GAM commands work.
GAMADV-XTD3 is a rewrite/extension of Jay Lee's [GAM], without his efforts, this version wouldn't exist.
GAMADV-XTD3 is backwards compatible with [GAM], meaning that if your command works with regular GAM, it will also work with GAMADV-XTD3. There may be differences in output, but the syntax is compatible.
# Documentation
Basic GAM documentation is hosted in the [GitHub Wiki]. Documentation specifically for GAMADV-XTD3 is hosted in the [GitHub GAMADV-XTD3 Wiki] and in Gam*.txt files.
Documentation for GAMADV-XTD3 is hosted in the [GitHub GAMADV-XTD3 Wiki] and in Gam*.txt files.
# Mailing List / Discussion group
The GAM mailing list / discussion group is hosted on [Google Groups]. You can join the list and interact via email, or just post from the web itself.
@@ -32,39 +26,48 @@ GAMADV-XTD3 is maintained by <a href="mailto:ross.scroggs@gmail.com">Ross Scrogg
# Requirements
To run all commands properly, GAMADV-XTD3 requires three things:
* An API project which identifies your install of GAMADV-XTD3 to Google and keeps track of API quotas.
* Authorization to act as your Google Workspace Administrator in order to perform management functions like add users, modify group settings and membership and pull domain reports.
* Authorization to act as your G Suite Administrator in order to perform management functions like add users, modify group settings and membership and pull domain reports.
* A special service account that is authorized to act on behalf of your users in order to modify user-specific settings and data such as Drive files, Calendars and Gmail messages and settings like signatures.
# Installation - First time GAM installation
Use these steps if you have never used any version of GAM in your domain. They will create a GAM project
and all necessary authentications.
* Download: [Downloads](Downloads)
* Configuration: [GAM Configuration](gam.cfg)
* Install: [How to Install Advanced GAM](How-to-Install-Advanced-GAM)
| [Downloads] | [Configuration] | [Install] |
| :---: | :---: | :---: |
# Installation - Upgrading from a GAM version other than a prior version of GAMADV-X or GAMADV-XTD or GAMADV-XTD3
Use these steps if you have used any version of GAM in your domain. They will update your GAM project
# Installation - Update Advanced GAM
Use these steps to update your version of GAMADV-XTD3.
| [Downloads] | [Configuration] | [UpdateAdvanced] |
| :---: | :---: | :---: |
# Installation - Upgrading from Standard GAM
Use these steps if you have used any version of Standard GAM in your domain. They will update your GAM project
and all necessary authentications.
* Download: [Downloads](Downloads)
* Configuration: [GAM Configuration](gam.cfg)
* Upgrade: [How to Upgrade from Standard GAM](How-to-Upgrade-from-Standard-GAM)
| [Downloads] | [Configuration] | [UpgradeFromStandard] |
| :---: | :---: | :---: |
# Installation - Upgrading from a prior version of GAMADV-X or GAMADV-XTD or GAMADV-XTD3
Use these steps if you already use GAMADV-X or GAMADV-XTD or GAMADV-XTD3. The updates may tell you to update your GAM project
# Installation - Upgrading from a prior version of GAMADV-X or GAMADV-XTD
Use these steps if you already use GAMADV-X or GAMADV-XTD. The updates may tell you to update your GAM project
or authentications because new features have been included.
* Updates: [GAM Updates]
* Download: [Downloads](Downloads)
| [Updates] | [Downloads] | [UpgradeFromAdvanced] |
| :---: | :---: | :---: |
# Multiple Versions
You can install multiple versions of GAM and GAMADV-XTD3 in different parallel directories.
[GAM]: https://github.com/GAM-team/GAM
[GitHub Releases]: https://github.com/taers232c/GAMADV-XTD3/releases
[GitHub]: https://github.com/taers232c/GAMADV-XTD3/tree/master
[GitHub Wiki]: https://github.com/GAM-team/GAM/wiki/
[GitHub GAMADV-XTD3 Wiki]: https://github.com/taers232c/GAMADV-XTD3/wiki/
[GitHub GAMADV-XTD3 Wiki]: https://github.com/taers232c/GAMADV-XTD3/wiki
[Google Groups]: https://groups.google.com/group/google-apps-manager
[GAM Updates]: https://github.com/taers232c/GAMADV-XTD3/wiki/GamUpdates
[Downloads]: https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads
[Configuration]: https://github.com/taers232c/GAMADV-XTD3/wiki/gam.cfg
[Install]: https://github.com/taers232c/GAMADV-XTD3/wiki/How-to-Install-Advanced-GAM
[UpdateAdvanced]: https://github.com/taers232c/GAMADV-XTD3/wiki/How-to-Update-Advanced-GAM
[UpgradeFromStandard]: https://github.com/taers232c/GAMADV-XTD3/wiki/How-to-Upgrade-from-Standard-GAM
[Updates]: https://github.com/taers232c/GAMADV-XTD3/wiki/GAM-Updates
[UpgradeFromAdvanced]: https://github.com/taers232c/GAMADV-XTD3/wiki/How-to-Upgrade-from-GAMADV-X-or-GAMADV-XTD

View File

@@ -3,6 +3,7 @@
- [Collections of Users](Collections-of-Users)
- [Definitions](#definitions)
- [Activity reports](#activity-reports)
- [Find Shared Drives with no activity](#find-shared-drives-with-no-activity)
- [Customer and user reports parameters](#customer-and-user-reports-parameters)
- [Customer usage reports](#customer-usage-reports)
- [Customer reports](#customer-reports)
@@ -59,6 +60,7 @@ gam report <ActivityApplicationName> [todrive <ToDriveAttributes>*]
[groupidfilter <String>]
[maxactivities <Number>] [maxresults <Number>]
[countsonly [summary] [eventrowfilter]]
(addcsvdata <FieldName> <String>)* [shownoactivities]
```
Select the application with `<ActivityApplicationName>`.
@@ -101,6 +103,12 @@ Limit the total number of activites.
Limit the number of activities downloaded per API call; infrequently used.
* `maxresults <Number>`
Add additional columns of data from the command line to the output.
* `addcsvdata <FieldName> <String>`
Display a row with a key value of `NoActivities` when there are no activities to report.
* `shownoactivities`
By default, individual event details are displayed, these options modify what's displayed.
* `countsonly` - Limit the display to the number of occurences of each event for each user
* `countsonly summary` - Limit the display to the number of occurences of each event summarized across all users
@@ -121,6 +129,43 @@ Number of files summarized across all users
```
gam config csv_output_row_filter "doc_title:regex:\.xyz" report drive event create yesterday countsonly summary eventrowfilter
```
## Find Shared Drives with no activity
Remember that activity events are only available for the past 180 days.
Get Shared Drives ID and Name
```
gam redirect csv ./SharedDrives.csv print shareddrives fields id,name
```
Options:
* `maxactivities 1` - Limits the number of activities displayed for Shared Drives with activity.
* `shownoactivities` - Displays a row for Shared Drives with no activity.
* `addcsvdata shared_drive_id "~id"` adds the Shared Drive ID to the output.
* `addcsvdata shared_drive_name "~name"` adds the Shared Drive name to the output.
Get activities with minimal activty data.
```
gam config csv_output_header_filter "name,id.time,shared_drive_id,shared_drive_name" redirect csv ./SharedDrivesActivity.csv multiprocess redirect stderr - multiprocess csv SharedDrives.csv gam report drive filter "shared_drive_id==~~id~~" maxactivities 1 shownoactivities addcsvdata shared_drive_id "~id" addcsvdata shared_drive_name "~name"
Example output from SharedDrivesActivity.csv:
name,id.time,shared_drive_id,shared_drive_name
NoActivities,,0AERPpMc23znvUkPXYZ,Shared Drive 1
view,2023-10-18T21:27:51-07:00,0AMhgLk82dhsuUkPXYZ,Shared Drive 2
edit,2023-09-05T15:27:01-07:00,0AM8lpdkkJaKYUkPXYZ,Shared Drive 3
```
Get activities with full activty data.
```
gam redirect csv ./SharedDrivesActivity.csv multiprocess redirect stderr - multiprocess csv SharedDrives.csv gam report drive filter "shared_drive_id==~~id~~" maxactivities 1 shownoactivities addcsvdata shared_drive_id "~id" addcsvdata shared_drive_name "~name"
Example output from SharedDrivesActivity.csv:
name,actor.callerType,actor.email,actor.key,actor.profileId,actor_is_collaborator_account,added_role,billable,destination_folder_id,destination_folder_title,doc_id,doc_title,doc_type,id.applicationName,id.customerId,id.time,id.uniqueQualifier,ipAddress,is_encrypted,membership_change_type,new_settings_state,old_settings_state,originating_app_id,owner,owner_is_shared_drive,owner_is_team_drive,owner_team_drive_id,primary_event,removed_role,shared_drive_id,shared_drive_name,shared_drive_settings_change_type,target,team_drive_id,team_drive_settings_change_type,type,visibility
NoActivities,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0AERPpMc23znvUkPXYZ,Shared Drive 1,,,,,,
view,,user1@domain.com,,100016760394505151666,False,,True,,,1SDNu-yzDapqjdJq4y4xKDUATJlOPRIBodpGGeGt1n4I,Digital Poetry Journal,document,drive,C03kt1z99,2023-10-18T21:27:51-07:00,-2856812962461786835,2600:1700:9580:f4b0:2127:3b2:dd21:3806,False,,,,263492796725,Shared Drive 2,True,True,0AMhgLk82dhsuUkPXYZ,True,,0AMhgLk82dhsuUkPXYZ,Shared Drive 2,,,0AMhgLk82dhsuUkPXYZ,,access,people_with_link
edit,,user2@domain.com,,104066776037911136666,False,,True,,,1ZwHi_v-JVXH8W6zwgb7QYoUHrZD6NzIshJEqoTCaDD0,High School Scavenger Hunt,form,drive,C03kt1z99,2023-09-05T15:27:01-07:00,-1272095408714453395,50.204.178.246,False,,,,,Shared Drive 3,True,True,0AM8lpdkkJaKYUkPXYZ,True,,0AM8lpdkkJaKYUkPXYZ,Shared Drive 3,,,0AM8lpdkkJaKYUkPXYZ,,access,shared_internally
```
## Customer and user reports parameters
Display the valid parameters for customer and user reports.

View File

@@ -50,7 +50,9 @@ See [Collections of Items](Collections-of-Items)
<FeatureNameList> ::= "'<FeatureName>'(,'<FeatureName>')*"
<ResourceID> ::= <String>
<ResourceIDList> ::= "<ResourceID>(,<ResourceID>)*"
<ResourceEntity> ::= <ResourceIDList> | <FileSelector> | <CSVkmdSelector>
<ResourceEntity> ::=
<ResourceIDList> | <FileSelector> | <CSVkmdSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<BuildingFieldName> ::=
address|
@@ -163,7 +165,7 @@ The `quotechar <Character>` option allows you to choose an alternate quote chara
## Manage features
```
gam create|add feature <Name>
gam create|add feature name <Name>
gam update feature <Name> name <Name>
gam delete feature <Name>
```
@@ -192,10 +194,10 @@ When updating a resource, use the following options to manage the features.
## Display resources
```
gam info resource <ResourceID>
[acls]Documents/GoogleApps/GAM3/Docs/ [calendar]
[acls] [noselfowner] [calendar]
[formatjson]
gam info resources <ResourceEntity>
[acls]Documents/GoogleApps/GAM3/Docs/ [calendar]
[acls] [noselfowner] [calendar]
[formatjson]
gam show resources
[allfields|<ResourceFieldName>*|(fields <ResourceFieldNameList>)]
@@ -272,11 +274,14 @@ By default, Gam displays the information as an indented list of keys and values.
* `formatjson` - Display the fields in JSON format.
```
gam resources <ResourceEntity> print acls|calendaracls [todrive <ToDriveAttribute>*]
[noselfowner]
[noselfowner] (addcsvdata <FieldName> <String>)*
[formatjson [quotechar <Character>]]
```
Option `noselfowner` suppresses the display of ACLs that reference the calendar itself as its owner.
Add additional columns of data from the command line to the output
* `addcsvdata <FieldName> <String>`
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format,
* `formatjson` - Display the fields in JSON format.

View File

@@ -1,5 +1,5 @@
# Running GAMADV-XTD3 securely on a Google Compute Engine
- [Thanks](#Thanks)
- [thanks](#thanks)
- [Introduction](#introduction)
- [Setup Steps](#setup-steps)
@@ -25,7 +25,7 @@ GAMADV-XTD3 version 6.50.00 or higher is required.
* click on the Permissions tab.
* click "Grant Access".
* In the "New principals text box, paste the service account email you copied.
* Give your service account the "Service Account Token Creator" and "View Service Accounts" roles.
* Give your service account the "Service Account Key Admin", "Service Account Token Creator" and "View Service Accounts" roles.
4. [Create a Windows or Linux virtual machine](https://cloud.google.com/compute/docs/instances/create-start-instance).
* You can choose a region physically close to you though you may be limited in your choices if you want to use the free tier.
@@ -55,8 +55,8 @@ gam enable apis
```
You are given the option to enable them automatically or manually. Automatic enablement will ask you to authenticate to GAMADV-XTD3. You should authenticate as a user with rights to manage project APIs, probably a project owner. If you are not the project owner you can choose manual enablement and GAMADV-XTD3 will provide two or more URLs which you can send to the project owner. When the owner opens these URLs, they'll be prompted to enable all the APIs GAMADV-XTD3 needs.
9. Manage user data
* Run ```gam user user@domain.com check serviceaccount``` and follow the instructions to perform domain-wide delegation.
10. Perform admin actions (manage users, groups, orgunits, Chrome devices, etc)
9. Perform admin actions (manage users, groups, orgunits, Chrome devices, etc)
* [Configure delegated admin service account (DASA)](https://github.com/taers232c/GAMADV-XTD3/wiki/Using-GAMADV-XTD3-with-a-delegated-admin-service-account); start at step 4.
10. Manage user data
* Run ```gam user user@domain.com check serviceaccount``` and follow the instructions to perform domain-wide delegation.

View File

@@ -12,7 +12,9 @@
<SchemaName> ::= <String>
<FieldName> ::= <String>
<SchemaNameList> ::= "<SchemaName>(,<SchemaName>)*"
<SchemaEntity> ::= <SchemaNameList> | <FileSelector> | <CSVkmdSelector>
<SchemaEntity> ::=
<SchemaNameList> | <FileSelector> | <CSVkmdSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<SchemaFieldDefinition> ::=
field <FieldName> [displayname <String>]

View File

@@ -33,7 +33,9 @@ Added the option `mailbox <EmailAddress>` to `gam sendemail` to allow specifying
<String>@<DomainName> |
<String> <<String>@<DomainName>> # The outer <> around <String>@<DomainName> are literal, e.g., IT Group<group@domain.com>
<EmailAddressList> ::= "<EmailAddress>(,<EmailAddress>)*"
<EmailAddressEntity> ::= <EmailAddressList> | <FileSelector> | <CSVkmdSelector>
<EmailAddressEntity> ::=
<EmailAddressList> | <FileSelector> | <CSVkmdSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Users
<RecipientEntity> ::= <EmailAddressEntity> | (select <UserTypeEntity>)
<UserItem> ::= <EmailAddress>|<UniqueID>|<String>

View File

@@ -89,17 +89,14 @@
<DriveFilePermissionEntity> ::=
<DriveFilePermissionList> |
<JSONData> |
<FileSelector> |
<CSVFileSelector> |
<CSVkmdSelector> |
<CSVDataSelector>
<FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<DriveFilePermissionIDEntity> ::=
<DriveFilePermissionIDList> |
<JSONData> |
<FileSelector> |
<CSVFileSelector> |
<CSVkmdSelector> |
<CSVDataSelector>
<FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<DrivePermissionsFieldName> ::=
additionalroles|

View File

@@ -20,13 +20,15 @@
<DomainName> ::= <String>(.<String>)+
<DomainNameList> ::= "<DomainName>(,<DomainName>)*"
<DomainNameEntity> ::=
<DomainNameList>|<FileSelector>|<CSVkmdSelector>| <CSVDataSelector>
<DomainNameList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<SiteName> ::= [a-z,0-9,-]+
<SiteItem> ::= [<DomainName>/]<SiteName>
<SiteList> ::= "<SiteItem>(,<SiteItem>)*"
<SiteEntity> ::=
<SiteList>|<FileSelector>|<CSVkmdSelector>|<CSVDataSelector>
<SiteList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<SiteACLRole> ::= editor|owner|reader|writer
<SiteACLRoleList> ::= "<SiteACLRole>(,<SiteACLRole>)*"
@@ -43,7 +45,8 @@
domain:<DomainName>|domain|default
<SiteACLScopeList> ::= "<SiteACLScope>(,<SiteACLScope>)*"
<SiteACLScopeEntity> ::=
<SiteACLScopeList>|<FileSelector>|<CSVkmdSelector>|<CSVDataSelector>
<SiteACLScopeList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
```
## Manage classic sites
```

View File

@@ -12,6 +12,7 @@
## API documentation
* https://support.google.com/a/answer/6178640
* https://support.google.com/a/answer/11112794
* https://cloud.google.com/identity/docs/how-to/manage-user-invitations
* https://cloud.google.com/identity/docs/reference/rest/v1beta1/customers.userinvitations

View File

@@ -1,7 +1,7 @@
# Users - Analytics Admin
- [API documentation](#api-documentation)
- [Notes](#notes)
- [Collections of Users](Collections-of-Users)
- [Definitions](#definitions)
- [Display Analytic Accounts](#display-analytic-accounts)
- [Display Analytic Account Summaries](#display-analytic-account-summaries)
- [Display Analytic Properties](#display-analytic-properties)
@@ -19,6 +19,9 @@ gam update project
gam user user@domain.com check serviceaccount
```
## Definitions
* [`<UserTypeEntity>`](Collections-of-Users)
## Display Analytic Accounts
```
gam <UserTypeEntity> show analyticaccounts

View File

@@ -1,6 +1,5 @@
# Users - Application Specific Passwords
- [API documentation](#api-documentation)
- [Collections of Users](Collections-of-Users)
- [Definitions](#definitions)
- [Manage application specific passwords](#manage-application-specific-passwords)
- [Display application specific passwords](#display-application-specific-passwords)

View File

@@ -1,7 +1,6 @@
# Users - Backup Verification Codes
- [API documentation](#api-documentation)
- [Definitions](#definitions)
- [Collections of Users](Collections-of-Users)
- [Manage backup verification codes](#manage-backup-verification-codes)
- [Display backup verification codes](#display-backup-verification-codes)

View File

@@ -1,7 +1,6 @@
# Users - Calendars - Access
- [Notes](#Notes)
- [API documentation](#api-documentation)
- [Collections of Users](Collections-of-Users)
- [Definitions](#definitions)
- [Calendar selection](#calendar-selection)
- [Manage calendar access](#manage-calendar-access)
@@ -99,7 +98,7 @@ gam <UserTypeEntity> add calendaracls <UserCalendarEntity>
gam <UserTypeEntity> update calendaracls <UserCalendarEntity>
<CalendarACLRole> <CalendarACLScopeEntity> [sendnotifications <Boolean>]
gam <UserTypeEntity> delete calendaracls <UserCalendarEntity>
<CalendarACLRole>] <CalendarACLScopeEntity>
[<CalendarACLRole>] <CalendarACLScopeEntity>
```
By default, when you add or update a calendar ACL, notification is sent to the members referenced in the `<CalendarACLScopeEntity>`.
Use `sendnotifications false` to suppress sending the notification.
@@ -118,11 +117,14 @@ By default, Gam displays the information as an indented list of keys and values.
* `formatjson` - Display the fields in JSON format.
```
gam <UserTypeEntity> print calendaracls <UserCalendarEntity> [todrive <ToDriveAttribute>*]
[noselfowner]
[noselfowner] (addcsvdata <FieldName> <String>)*
[formatjson [quotechar <Character>]]
```
Option `noselfowner` suppresses the display of ACLs that reference the calendar itself as its owner.
Add additional columns of data from the command line to the output
* `addcsvdata <FieldName> <String>`
By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain
the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled.
When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output.

View File

@@ -1,7 +1,6 @@
# Users - Calendars - Events
- [API documentation](#api-documentation)
- [Python Regular Expressions](Python-Regular-Expressions) Search function
- [Collections of Users](Collections-of-Users)
- [Definitions](#definitions)
- [Recurrence rules](#recurrence-rules)
- [Event colors](#event-colors)
@@ -11,17 +10,21 @@
- [Update calendar events](#update-calendar-events)
- [Add calendar attendees](#add-calendar-attendees)
- [Update calendar attendees](#update-calendar-attendees)
- [Specify calendar attendees with JSON data](#specify-calendar-attendees-with-JSON-data)
- [Specify calendar attendees with JSON data](#specify-calendar-attendees-with-json-data)
- [Delete selected calendar events](#delete-selected-calendar-events)
- [Delete all calendar events](#delete-all-calendar-events)
- [Move calendar events to another calendar](#move-calendar-events-to-another-calendar)
- [Empty calendar trash](#empty-calendar-trash)
- [Display calendar events](#display-calendar-events)
- [Update calendar event attendees](#update-calendar-event-attendees)
- [Working location events](#working-location-events)
- [Manage working location events](#manage-working-location-events)
- [Display working location events](#display-working-location-events)
## API documentation
* https://developers.google.com/calendar/v3/reference/events
* https://developers.google.com/calendar/v3/reference/events/import
* https://developers.google.com/calendar/api/guides/working-hours-and-location
## Definitions
* [`<UserTypeEntity>`](Collections-of-Users)
@@ -90,8 +93,9 @@
<EmailAddress> ::= <String>@<DomainName>
<EmailAddressList> ::= "<EmailAddress>(,<EmailAddress>)*"
<EmailAddressEntity> ::=
<EmailAddressList>|<FileSelector>|<CSVFileSelector>|
<CSVkmdSelector>|<CSVDataSelector>
<EmailAddressList> | <FileSelector> | <CSVFileSelector> |
<CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Users
<CalendarItem> ::= <EmailAddress>
<CalendarList> ::= "<CalendarItem>(,<CalendarItem>)*"
<CourseAlias> ::= <String>
@@ -125,7 +129,7 @@
(resource <ResourceID>)|
(resources <ResourceIDList>)|
((calendars <CalendarList>)|<FileSelector>|<CSVFileSelector>|
<CSVkmdSelector>|<CSVDataSelector>)|
<CSVkmdSelector> | <CSVDataSelector>)|
<CalendarSelectProperty>+
```
```
@@ -246,6 +250,7 @@
(matchfield location <RegularExpression>)|
(matchfield organizeremail <RegularExpression>)|
(matchfield organizername <RegularExpression>)|
(matchfield organizerself <Boolean>)|
(matchfield status <RegularExpression>)|
(matchfield summary <RegularExpression>)|
(matchfield transparency <RegularExpression>)|
@@ -255,7 +260,7 @@
(id|eventid <EventId>) |
(event|events <EventIdList> |
<FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVSubkeySelector> | <CSVDataSelector>)
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<EventSelectEntity> ::=
(<EventSelectProperty>+ <EventMatchProperty>*)
@@ -306,7 +311,11 @@
tentative|
(timezone <TimeZone>)|
(transparency opaque|transparent)|
(visibility default|public|private)
(visibility default|public|private)|
(workinglocation (home|
(custom <String>)|
(office <String> [building|buildingid <String>] [floor|floorname <String>]
[section|floorsection <String>] [desk|deskcode <String>])))
The following attributes are equivalent:
available - transparency transparent
@@ -540,8 +549,8 @@ No events are deleted unless you specify the `doit` option; omit `doit` to verif
When events are deleted from a calendar, they are moved to the calendar's trash and are only permanently deleted (purged) after 30 days.
Following a suggestion here (https://stackoverflow.com/questions/41043053/how-to-empty-calendar-trash-via-google-services) you can permanently delete
calendar events. This is achieved by creating a temporary calendar, deleting the events, moving the deleted events to the temporary calendar
and then deleting the temporary calendar.
calendar events with `purge events`. This is achieved by creating a temporary calendar, deleting the events, moving the deleted events to the temporary calendar
and then deleting the temporary calendar.
## Delete all calendar events
For a user's primary calendar:
@@ -682,3 +691,76 @@ option causes GAM to make two updates to the attendee list; the first removes th
the second adds the primary email.
The attendee changes are displayed but not processed unless `doit` is specified.
## Working location events
## Manage working location events
You can create and delete working location events; they can not be updated.
To update a working location event, delete the working location event and recreate it.
```
gam <UserTypeEntity> create workinglocation
(home|
(custom <String>)|
(office <String> [building|buildingid <String>] [floor|floorname <String>]
[section|floorsection <String>] [desk|deskcode <String>]))
((date yyyy-mm-dd)|
(range yyyy-mm-dd yyyy-mm-dd)|
(daily yyyy-mm-dd <Number>)|
(weekly yyyy-mm-dd <Number>)|
(timerange <Time> <Time>))+
gam <UserTypeEntity> delete workinglocation
((date yyyy-mm-dd)|
(range yyyy-mm-dd yyyy-mm-dd)|
(daily yyyy-mm-dd <Number>)|
(weekly yyyy-mm-dd <Number>)|
(timerange <Time> <Time>))+
```
Use one of `home`, `custom <String>` and `office <String>` to specify the working location event label.
Working location events are either single all day events or span a time range:
* `date yyyy-mm-dd` - A specific day
* `range yyyy-mm-dd yyyy-mm-dd` - Every day in the range
* `daily yyyy-mm-dd <Number>` - Every day starting on the date for `<Number>` total days
* `weekly yyyy-mm-dd <Number>` - A day per week starting on the date for `<Number>` total weeks
* `timerange <Time> <Time>` - A time range, may span multiple days
## Display working location events
```
gam <UserTypeEntity> show workinglocation
((date yyyy-mm-dd)|
(range yyyy-mm-dd yyyy-mm-dd)|
(daily yyyy-mm-dd <Number>)|
(weekly yyyy-mm-dd <Number>)|
(timerange <Time> <Time>))+
[showdayofweek]
[formatjson]
```
`showdayofweek` displays `dayOfWeek` when event start and end times are displayed.
By default, Gam displays the information as an indented list of keys and values.
* `formatjson` - Display the fields in JSON format.
```
gam <UserTypeEntity> print workinglocation
((date yyyy-mm-dd)|
(range yyyy-mm-dd yyyy-mm-dd)|
(daily yyyy-mm-dd <Number>)|
(weekly yyyy-mm-dd <Number>)|
(timerange <Time> <Time>))+
[showdayofweek]
[formatjson [quotechar <Character>]] [todrive <ToDriveAttribute>*]
```
`showdayofweek` displays columns `start.dayOfWeek` and `end.dayOfWeek` when event start and end times are displayed.
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format,
* `formatjson` - Display the fields in JSON format.
By default, Gam displays event details, use `countsonly` to display only the number of events. `formatjson` does not apply in this case.
By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain
the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled.
When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output.
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.

View File

@@ -1,6 +1,5 @@
# Users - Calendars
- [API documentation](#api-documentation)
- [Collections of Users](Collections-of-Users)
- [Definitions](#definitions)
- [Calendar colors](#calendar-colors)
- [Calendar selection](#calendar-selection)
@@ -56,6 +55,7 @@
(resources <ResourceIDList>)|
((calendars <CalendarList>) | <FileSelector> | <CSVFileSelector> |
<CSVkmdSelector> | <CSVDataSelector>)
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<UserCalendarEntity> ::=
allcalendars|
@@ -72,6 +72,7 @@
((calendars <CalendarList>) | <FileSelector> | <CSVFileSelector> |
<CSVkmdSelector> | <CSVDataSelector>)|
<CalendarSelectProperty>*
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<UserCalendarSettingsField> ::=
autoaddhangouts|

View File

@@ -82,6 +82,7 @@ Google requires that you have a Chat Bot configured in order to use the Chat API
```
gam <UserTypeEntity> create chatspace
[type <ChatSpaceType>]
[externalusersrallowed <Boolean>]
[members <UserTypeEntity>]
[displayname <String>]
[description <String>] [guidelines <String>]
@@ -178,6 +179,27 @@ When using the `formatjson` option, double quotes are used extensively in the da
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
### Display information about all chat spaces
```
# Local file
gam config auto_batch_min 1 redirect csv ./AllChatSpaces.csv multiprocess redirect stdout - multiprocess redirect stderr stdout all users print chatspaces
# Google sheet
gam config auto_batch_min 1 redirect csv - todrive <ToDriveAttribute>* multiprocess redirect stdout - multiprocess redirect stderr stdout all users print chatspaces
```
Add these options as desired:
```
[types <ChatSpaceTypeList>]
[formatjson [quotechar <Character>]]
```
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format,
* `formatjson` - Display the fields in JSON format.
By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain
the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled.
When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output.
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
## Manage Chat Members
### Add members to a chat space
```

View File

@@ -24,7 +24,9 @@ Contact delegation must be enabled, see the following:
<UniqueID> ::= id:<String>
<UserItem> ::= <EmailAddress>|<UniqueID>|<String>
<UserList> ::= "<UserItem>(,<UserItem>)*"
<UserEntity> ::= <UserList>|<FileSelector>|<CSVkmdSelector>|<CSVDataSelector>
<UserEntity> ::=
<UserList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Users
```
## Create contact delegates
```

View File

@@ -92,6 +92,7 @@ gam <UserTypeEntity> copy drivefile <DriveFileEntity>
[excludepermissionsfromdomains|includepermissionsfromdomains <DomainNameList>]
(mappermissionsdomain <DomainName> <DomainName>)*
[sendemailifrequired [<Boolean>]]
[verifyorganizer [<Boolean>]]
```
The files/folders specified by `<DriveFileEntity>` are referred to as `source`, `target` refers to where those files are being copied.
The files/folders specified by `<DriveFileEntity>` are referred to as `top`; when a folder is being copied recursively, the files/folders that it contains are referred as `sub`.
@@ -100,6 +101,10 @@ At its simplest, you copy files/folders by giving the copy a new name and parent
By default, files/folders in the Trash are copied; use `excludetrashed` to prevent these files/folders from being copied.
When a copy operation involves a Shared Drive, GAM verifies that the user is an organizer. Unfortunatley, this fails
when the user is not a direct organizer but is a member of a group that is an organizer. Specifying
`verifyorganizer false` suppresses the verification.
When copying folders, you have three modes of operation:
### Copy the top folder but none of its sub files/folders
@@ -132,18 +137,13 @@ By default, GAM displays a message referencing files and folders not selected fo
* `suppressnotselectedmessages false` - Do not suppress these messages; this is the default
* `suppressnotselectedmessages [true]` - Suppress these messages
### By default, when copying sub files, all files, regardless of MIME type, are copied. You can specify
restrictions on the MIME types to be copied.
### By default, when copying sub files, all files, regardless of MIME type, are copied.
You can specify restrictions on the MIME types to be copied.
* `filemimetypes <MimeTypeList>` - Copy sub files with the specified MIME types
* `filemimetypes not <MimeTypeList>` - Copy sub files with MIME types other than those specified
* `filemimetypes not <MimeTypeList>` - Copy sub files with MIME types other than those specified
that limit the items copied based on their name.
* `filenamematchpattern <RegularExpression>` - Only files whose name matches `<RegularExpression>` are copied
* `foldernamematchpattern <RegularExpression>` - Only folders whose name matches `<RegularExpression>` are copied
* `shortcutnamematchpattern <RegularExpression>` - Only shortcuts whose name matches `<RegularExpression>` are copied
### By default, when copying sub files, folders and shortcuts, all are copied. You can specify `<RegularExpression>` patterns
that limit the items copied based on their name.
### By default, when copying sub files, folders and shortcuts, all are copied.
You can specify `<RegularExpression>` patterns that limit the items copied based on their name.
* `filenamematchpattern <RegularExpression>` - Only files whose name matches `<RegularExpression>` are copied
* `foldernamematchpattern <RegularExpression>` - Only folders whose name matches `<RegularExpression>` are copied
* `shortcutnamematchpattern <RegularExpression>` - Only shortcuts whose name matches `<RegularExpression>` are copied
@@ -448,12 +448,17 @@ gam <UserTypeEntity> move drivefile <DriveFileEntity> [newfilename <DriveFileNam
[updatefilepermissions [<Boolean>]]
[retainsourcefolders [<Boolean>]]
[sendemailifrequired [<Boolean>]]
[verifyorganizer [<Boolean>]]
```
The files/folders specified by `<DriveFileEntity>` are referred to as `source`, `target` refers to where those files are being moved.
The files/folders specified by `<DriveFileEntity>` are referred to as `top`; when a folder is being moved, the files/folders that it contains are referred as `sub`.
At its simplest, you move files/folders by giving them a new name and parent location.
When a move operation involves a Shared Drive, GAM verifies that the user is an organizer. Unfortunatley, this fails
when the user is not a direct organizer but is a member of a group that is an organizer. Specifying
`verifyorganizer false` suppresses the verification.
When moving folders, you have two modes of operation:
### Move the top folder and its sub files/folders
@@ -605,7 +610,7 @@ Moving a Drive folder to a Shared Drive is not directly supported by the API; GA
recursively adjust the files/folders within it to point to the new parent folder. Once the original folder is emptied, it is deleted unless `retainsourcefolders` is specified.
### Move content of a Shared Drive to another Shared Drive
Suppose you have a source Shared Drive called 0AC_1AB with multiple files and folders, and want to move all of its content to the target Shared Drive 0AE_9ZX.
Suppose you have a source Shared Drive with ID 0AC_1AB with multiple files and folders, and want to move all of its content to the target Shared Drive with ID 0AE_9ZX.
The following command will change the parents of the top level files and folders from 0AC_1AB to 0AE_9ZX; the sub files and folders will move along with their top level folder.
@@ -614,3 +619,7 @@ The following command will change the parents of the top level files and folders
gam user user@domain.com move drivefile teamdriveid 0AC_1AB teamdriveparentid 0AE_9ZX mergewithparent
```
If you want the source Shared Drive with ID 0AC_1AB to be contained in a top level folder of the target Shared Drive with ID 0AE_9ZX, omit the `mergewithparent` argument.
```
gam user user@domain.com move drivefile teamdriveid 0AC_1AB teamdriveparentid 0AE_9ZX
```

View File

@@ -5,9 +5,10 @@
- [Permission Matches](Permission-Matches)
- [Definitions](#definitions)
- [Return Codes](#return-codes)
- [File size fields](#file-size-fields)
- [Display file information](#display-file-information)
- [Display file paths](#display-file-paths)
- [Select files for Display file counts, list, tree](#select-files-for-Display-file-counts-list-tree)
- [Select files for Display file counts, list, tree](#select-files-for-display-file-counts-list-tree)
- [File selection definitions](#file-selection-definitions)
- [File selection defaults](#file-selection-defaults)
- [File selection by query](#file-selection-by-query)
@@ -59,6 +60,7 @@
gfolder|gdirectory|
gform|
gfusion|
gjam|
gmap|
gpresentation|
gscript|
@@ -318,7 +320,7 @@ you can specify `permissions` to get all of the fields, enumerate the specific f
specify `basicpermissions` and additional permission fields, e.g., `permissions.displayName`.
```
<<DriveOrderByFieldName> ::=
<DriveOrderByFieldName> ::=
createddate|createdtime|
folder|
modifiedbyme|modifiedbymedate|modifiedbymetime|modifiedbyuser|
@@ -357,6 +359,29 @@ $ echo $?
60
```
## File size fields
The Drive API defines two fields that relate to file size: `quotaBytesUsed` and `size`.
```
quotaBytesUsed - The number of storage quota bytes used by the file.
This includes the head revision as well as previous revisions with keepForever enabled.
size - Size in bytes of blobs and first party editor files.
```
Previously, GAM used the `size` field when totaling file sizes, it now uses the `quotaBytesUsed` field.
The option `sizefield quotabytesused|size` allows you to select which field to use.
For most MIME types, the values are the same; for the following MIME types, `quotabytesused` is larger.
```
application/pdf
application/vnd.ms-powerpoint
application/vnd.openxmlformats-officedocument.presentationml.presentation
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
application/vnd.openxmlformats-officedocument.wordprocessingml.document
application/zip
audio/mpeg
image/jpeg
image/png
```
## Display file information
Display file details in indented keyword: value format. The two forms are equivalent.
```
@@ -482,6 +507,7 @@ See: [Drive File Selection](Drive-File-Selection) for details of `<DriveFileName
<DriveFileQueryShortcut> ::=
all_files |
all_folders |
all_forms |
all_google_files |
all_non_google_files |
all_shortcuts |
@@ -489,13 +515,16 @@ See: [Drive File Selection](Drive-File-Selection) for details of `<DriveFileName
all_items |
my_files |
my_folders |
my_forms |
my_google_files |
my_non_google_files |
my_shortcuts |
my_3p_shortcuts |
my_items |
my_forms |
others_files |
others_folders |
others_forms |
others_google_files |
others_non_google_files |
others_shortcuts |
@@ -612,29 +641,35 @@ gam <UserTypeEntity> print filecounts [todrive <ToDriveAttribute>*]
[corpora <CorporaAttribute>]
[select <SharedDriveEntity>]
[anyowner|(showownedby any|me|others)]
[showmimetype [not] <MimeTypeList>] [minimumfilesize <Integer>] [maximumfilesize <Integer>]
[showmimetype [not] <MimeTypeList>]
[sizefield quotabytesused|size] [minimumfilesize <Integer>] [maximumfilesize <Integer>]
[filenamematchpattern <RegularExpression>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
[excludetrashed]
[summary none|only|plus] [summaryuser <String>] [showsize]
[showsize] [showmimetypesize]
[summary none|only|plus] [summaryuser <String>]
gam <UserTypeEntity> show filecounts
[((query <QueryDriveFile>) | (fullquery <QueryDriveFile>) | <DriveFileQueryShortcut>)
(querytime<String> <Time>)*]
[corpora <CorporaAttribute>]
[select <SharedDriveEntity>]
[anyowner|(showownedby any|me|others)]
[showmimetype [not] <MimeTypeList>] [minimumfilesize <Integer>] [maximumfilesize <Integer>]
[showmimetype [not] <MimeTypeList>]
[sizefield quotabytesused|size] [minimumfilesize <Integer>] [maximumfilesize <Integer>]
[filenamematchpattern <RegularExpression>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
[excludetrashed]
[summary none|only|plus] [summaryuser <String>] [showsize]
[showsize] [showmimetypesize]
[summary none|only|plus] [summaryuser <String>]
```
By default, print filecounts displays counts of all files owned by the specified `<UserTypeEntity>`.
By default, print filecounts displays counts of all files owned by the specified [`<UserTypeEntity>`](Collections-of-Users).
The `showsize` option displays the total size (in bytes) of the files counted.
See [Select files for Display file counts, list, tree](#select-files-for-Display-file-counts-list-tree)
The showmimetypesize' displays the total size (in bytes) of each MIME type counted.
See [Select files for Display file counts, list, tree](#select-files-for-display-file-counts-list-tree)
Use the `excludetrashed` option to suppress counting files in the trash.
@@ -646,7 +681,83 @@ that can display a summarization of file counts across all users specified in th
The `summaryuser <String>` option replaces the default summary user `Summary` with `<String>`.
### Example
### Examples
Show file counts for a user.
```
$ gam user testuser@domain.com show filecounts showsize
Getting all Drive Files/Folders that match query ('me' in owners) for testuser@domain.com
Got 261 Drive Files/Folders that matched query ('me' in owners) for testuser@domain.com...
User: testuser@domain.com, Drive Files/Folders: 261, Size: 13822521
application/octet-stream: 8
application/pdf: 1
application/vnd.google-apps.document: 98
application/vnd.google-apps.drawing: 2
application/vnd.google-apps.drive-sdk.423565144751: 1
application/vnd.google-apps.folder: 68
application/vnd.google-apps.form: 3
application/vnd.google-apps.jam: 1
application/vnd.google-apps.presentation: 1
application/vnd.google-apps.shortcut: 14
application/vnd.google-apps.site: 1
application/vnd.google-apps.spreadsheet: 24
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet: 1
application/vnd.openxmlformats-officedocument.wordprocessingml.document: 3
application/vnd.openxmlformats-officedocument.wordprocessingml.template: 1
application/x-gzip: 4
application/zip: 2
image/jpeg: 8
image/vnd.adobe.photoshop: 1
text/csv: 2
text/plain: 13
text/rtf: 3
text/x-sh: 1
```
Show file counts for a user including sizes for each MIME type.
```
$ gam user testuser@domain.com show filecounts showmimetypesize
Getting all Drive Files/Folders that match query ('me' in owners) for testuser@domain.com
Got 261 Drive Files/Folders that matched query ('me' in owners) for testuser@domain.com...
User: testuser@domain.com, Drive Files/Folders: 261, Size: 13822521
application/octet-stream: 8, 17
application/pdf: 1, 9879
application/vnd.google-apps.document: 98, 52858
application/vnd.google-apps.drawing: 2, 2048
application/vnd.google-apps.drive-sdk.423565144751: 1, 0
application/vnd.google-apps.folder: 68, 0
application/vnd.google-apps.form: 3, 0
application/vnd.google-apps.jam: 1, 1024
application/vnd.google-apps.presentation: 1, 0
application/vnd.google-apps.shortcut: 14, 0
application/vnd.google-apps.site: 1, 0
application/vnd.google-apps.spreadsheet: 24, 11264
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet: 1, 8157
application/vnd.openxmlformats-officedocument.wordprocessingml.document: 3, 34407
application/vnd.openxmlformats-officedocument.wordprocessingml.template: 1, 25906
application/x-gzip: 4, 2768
application/zip: 2, 765
image/jpeg: 8, 16498
image/vnd.adobe.photoshop: 1, 13613198
text/csv: 2, 397
text/plain: 13, 41461
text/rtf: 3, 1738
text/x-sh: 1, 136
```
Print file counts for a user.
```
$ gam user testuser@domain,com print filecounts showsize
Getting all Drive Files/Folders that match query ('me' in owners) for testuser@domain.com
Got 261 Drive Files/Folders that matched query ('me' in owners) for testuser@domain.com...
User,Total,Size,application/octet-stream,application/pdf,application/vnd.google-apps.document,application/vnd.google-apps.drawing,application/vnd.google-apps.drive-sdk.423565144751,application/vnd.google-apps.folder,application/vnd.google-apps.form,application/vnd.google-apps.jam,application/vnd.google-apps.presentation,application/vnd.google-apps.shortcut,application/vnd.google-apps.site,application/vnd.google-apps.spreadsheet,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.openxmlformats-officedocument.wordprocessingml.template,application/x-gzip,application/zip,image/jpeg,image/vnd.adobe.photoshop,text/csv,text/plain,text/rtf,text/x-sh
testuser@domain.com,261,13822521,8,1,98,2,1,68,3,1,1,14,1,24,1,3,1,4,2,8,1,2,13,3,1
```
Print file counts for a user including sizes for each MIME type.
```
$ gam user testuser@domain.com print filecounts showmimetypesize
Getting all Drive Files/Folders that match query ('me' in owners) for testuser@domain.com
Got 261 Drive Files/Folders that matched query ('me' in owners) for testuser@domain.com...
User,Total,Size,application/octet-stream,application/octet-stream-size,application/pdf,application/pdf-size,application/vnd.google-apps.document,application/vnd.google-apps.document-size,application/vnd.google-apps.drawing,application/vnd.google-apps.drawing-size,application/vnd.google-apps.drive-sdk.423565144751,application/vnd.google-apps.drive-sdk.423565144751-size,application/vnd.google-apps.folder,application/vnd.google-apps.folder-size,application/vnd.google-apps.form,application/vnd.google-apps.form-size,application/vnd.google-apps.jam,application/vnd.google-apps.jam-size,application/vnd.google-apps.presentation,application/vnd.google-apps.presentation-size,application/vnd.google-apps.shortcut,application/vnd.google-apps.shortcut-size,application/vnd.google-apps.site,application/vnd.google-apps.site-size,application/vnd.google-apps.spreadsheet,application/vnd.google-apps.spreadsheet-size,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet-size,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.openxmlformats-officedocument.wordprocessingml.document-size,application/vnd.openxmlformats-officedocument.wordprocessingml.template,application/vnd.openxmlformats-officedocument.wordprocessingml.template-size,application/x-gzip,application/x-gzip-size,application/zip,application/zip-size,image/jpeg,image/jpeg-size,image/vnd.adobe.photoshop,image/vnd.adobe.photoshop-size,text/csv,text/csv-size,text/plain,text/plain-size,text/rtf,text/rtf-size,text/x-sh,text/x-sh-size
testuser@domain.com,261,13822521,8,17,1,9879,98,52858,2,2048,1,0,68,0,3,0,1,1024,1,0,14,0,1,0,24,11264,1,8157,3,34407,1,25906,4,2768,2,765,8,16498,1,13613198,2,397,13,41461,3,1738,1,136
```
Get file count summaries by OU; top level selector is ou, sub level selectors are ou_and_children
```
gam redirect csv ./TopLevelOUs.csv print ous showparent toplevelonly parentselector ou childselector ou_and_children fields orgunitpath
@@ -775,7 +886,8 @@ gam <UserTypeEntity> print filetree [todrive <ToDriveAttribute>*]
[select <DriveFileEntity> [selectsubquery <QueryDriveFile>]
[depth <Number>]]
[anyowner|(showownedby any|me|others)]
[showmimetype [not] <MimeTypeList>] [minimumfilesize <Integer>] [maximumfilesize <Integer>]
[showmimetype [not] <MimeTypeList>]
[sizefield quotabytesused|size] [minimumfilesize <Integer>] [maximumfilesize <Integer>]
[filenamematchpattern <RegularExpression>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
[excludetrashed]
@@ -786,7 +898,8 @@ gam <UserTypeEntity> show filetree
[select <DriveFileEntity> [selectsubquery <QueryDriveFile>]
[depth <Number>]]
[anyowner|(showownedby any|me|others)]
[showmimetype [not] <MimeTypeList>] [minimumfilesize <Integer>] [maximumfilesize <Integer>]
[showmimetype [not] <MimeTypeList>]
[sizefield quotabytesused|size] [minimumfilesize <Integer>] [maximumfilesize <Integer>]
[filenamematchpattern <RegularExpression>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
[excludetrashed]
@@ -796,7 +909,7 @@ gam <UserTypeEntity> show filetree
```
By default, the file tree starting at the root and all orphans are shown.
See [Select files for Display file counts, list, tree](#select-files-for-Display-file-counts-list-tree)
See [Select files for Display file counts, list, tree](#select-files-for-display-file-counts-list-tree)
## File selection starting point for Display file tree
You can specify a specific folder from which to select files.
@@ -825,7 +938,7 @@ The `stripcrsfromname` option strips nulls, carriage returns and linefeeds from
This option is special purpose and will not generally be used.
### Examples
Show full file tree including the file id and mimetype:
Show full file tree including the file id and MIME type:
```
gam user testuser show filetree fields id,mimetype
```
@@ -844,12 +957,14 @@ gam <UserTypeEntity> print|show filelist [todrive <ToDriveAttribute>*]
[select <DriveFileEntity> [selectsubquery <QueryDriveFile>]
[(norecursion [<Boolean>])|(depth <Number>)] [showparent]]
[anyowner|(showownedby any|me|others)]
[showmimetype [not] <MimeTypeList>] [minimumfilesize <Integer>] [maximumfilesize <Integer>]
[showmimetype [not] <MimeTypeList>]
[sizefield quotabytesused|size] [minimumfilesize <Integer>] [maximumfilesize <Integer>]
[filenamematchpattern <RegularExpression>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>] [pmfilter] [oneitemperrow]
[excludetrashed]
[maxfiles <Integer>] [nodataheaders <String>]
[countsonly [summary none|only|plus] [summaryuser <String>] [showsource] [showsize]] [countsrowfilter]
[countsonly [summary none|only|plus] [summaryuser <String>]
[showsource] [showsize] [showmimetypesize]] [countsrowfilter]
[filepath|fullpath [pathdelimiter <Character>] [addpathstojson] [showdepth]] [buildtree]
[allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)]
[showdrivename] [showshareddrivepermissions]
@@ -860,13 +975,13 @@ gam <UserTypeEntity> print|show filelist [todrive <ToDriveAttribute>*]
(addcsvdata <FieldName> <String>)*
[formatjson [quotechar <Character>]]
```
By default, `print filelist` displays all files owned by the specified `<UserTypeEntity>`.
By default, `print filelist` displays all files owned by the specified [`<UserTypeEntity>`](https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Users)
When `allfields` is specified (or no fields are specified), use `showshareddrivepermissions` to display permissions
when shared drives are queried/selected. In this case, the Drive API returns the permission IDs
but not the permissions themselves so GAM makes an additional API call per file to get the permissions.
See [Select files for Display file counts, list, tree](#select-files-for-Display-file-counts-list-tree)
See [Select files for Display file counts, list, tree](#select-files-for-display-file-counts-list-tree)
## File selection by name and entity shortcuts for Display file list
Select a subset of files by pre-defined queries.
@@ -1006,7 +1121,7 @@ The `labels` column indicates the number of drive labels a file has and there ar
```
...labels,labelsIds,...
```
The `labels` column indicates the number of drive labels a file has and the `labelssIds` column is a list of the drive label IDs
The `labels` column indicates the number of drive labels a file has and the `labelsIds` column is a list of the drive label IDs
separated by `delimiter <Character>`; the default value is `csv_output_field_delimiter` from `gam.cfg`.
By default, all ACLS are displayed; use the following option in conjunction with `<PermissionMatch>* [<PermissionMatchAction>]`
@@ -1021,7 +1136,7 @@ By default, all ACLs are displayed with the other file fields on a single row.
* `oneitemperrow` - Display each of a files ACls on a separate row with all of the other file fields.
This produces a CSV file that can be used in subsequent commands without further script processing.
The `countsonly` option doesn't display any indididual file data, it lists the total number of files that the use can access
The `countsonly` option doesn't display any indididual file data, it lists the total number of files that the user can access
and the mumber of files by MIME type.
The `countsonly` suboption `summary none|only|plus` specifies display of a summarization of file counts across all users specified in the command.
@@ -1035,6 +1150,8 @@ The `countsonly` suboption `showsource` adds additional columns `Source` and `Na
The `countsonly` suboption `showsize` adds an additional column `Size` that indicates the total size (in bytes) of the files represented on the row.
The `countsonly` suboption `showmimetypesize` adds additional columns `<MimeType>:Size` that indicate the total size (in bytes) of each MIME type.
By default, when `countsonly` is specified, GAM applies `config csv_output_row_filter` to the file details to select which files are counted.
Use the `countsrowfilter` option to have GAM to apply `config csv_output_row_filter` to the file counts rather than the file details.
@@ -1355,11 +1472,12 @@ BadNews-NoData
```
gam <UserTypeEntity> print diskusage <DriveFileEntity> [todrive <ToDriveAttribute>*]
[anyowner|(showownedby any|me|others)]
[sizefield quotabytesused|size]
[pathdelimiter <Character>] [excludetrashed] [stripcrsfromname]
(addcsvdata <FieldName> <String>)*
[noprogress] [show all|summary|summaryandtrash]
```
For each folder in `<DiskFileEntity>`, the following items are displayed:
For each folder in `<DriveFileEntity>`, the following items are displayed:
* `User` - The email address of the user in `<UserTypeEntity>`
* `Owner` - The email address of the owner of the folder; omitted when displaying disk usage on Shared Drives
* `ownedByMe` - True if the folder is owned by `User`, False otherwise; omitted when displaying disk usage on Shared Drives
@@ -1411,9 +1529,9 @@ Add additional columns of data from the command line to the output:
By default, progress messages are displayed for each folder, use `noprogress` to suppress these messages.
Use the `show` option to control the display of data:
* `all` - Display a row for every folder in `<DriveFileEntity>` and a row detailing items in the trash when `excludetrashed` is omitted. This is the default.
* `summary` - Display a single row for the first folder in `<DriveFileEntity>`
* `summaryandtrash` - Display a single row for the first folder in `<DriveFileEntity>` and a row detailing items in the trash when `excludetrashed` is omitted.
* `show all` - Display a row for every folder in `<DriveFileEntity>` and a row detailing items in the trash when `excludetrashed` is omitted. This is the default.
* `show summary` - Display a single row for the first folder in `<DriveFileEntity>`
* `show summaryandtrash` - Display a single row for the first folder in `<DriveFileEntity>` and a row detailing items in the trash when `excludetrashed` is omitted.
### Examples
```

View File

@@ -93,6 +93,7 @@
gfolder|gdirectory|
gform|
gfusion|
gjam|
gmap|
gpresentation|
gscript|
@@ -164,7 +165,7 @@
gam <UserTypeEntity> create|add drivefile
[(localfile <FileName>|-)|(url <URL>)]
[(drivefilename|newfilename <DriveFileName>) | (replacefilename <RegularExpression> <String>)*]
[stripnameprefix <String>]
[stripnameprefix <String>] [noduplicate]
<DriveFileCreateAttribute>*
[(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*) |
(returnidonly|returnlinkonly|returneditlinkonly|showdetails)]
@@ -200,6 +201,18 @@ These are the naming rules:
If `stripnameprefix <String>` is specified, `<String>` will be stripped from the front of the Google Drive file name if present.
If `noduplicate` is specfied, GAM will issue a warning and not perform the create if a non-trashed item with the same name (regardless of MIME type)
exists in the parent folder.
By default, when files are uploaded from local content, they are created with `binary` format, i.e., the data is uploaded
without any conversion. Standard GAM had an option `convert` that was passed to the Drive API v2 that it used.
* convert - Whether to convert this file to the corresponding Docs Editors format
Advanced GAM uses Drive API v3 that doesn't support the `convert` option; it uses the `mimetype` argument to cause conversions.
* `mimetype gdoc` - Convert the uploaded content to a Google Doc; e.g., convert a Word (.docx) or text (.txt) file to a Google Doc
* `mimetype gsheet` - Convert the uploaded content to a Google Sheet; e.g., convert an Excel (.xlsx) or CSV (.csv) file to a Google Sheet
* `mimetype gpresentation` - Convert the uploaded content to a Google Slides; e.g., convert a PowerPoint (.pptx) file to a Google Slides
By default, the user, file name and id values are displayed on stdout.
* `returnidonly` - Display just the file ID of the created file on stdout
* `returnlinkonly` - Display just the file webViewLink of the created file on stdout
@@ -224,19 +237,19 @@ The file ID will only be valid when the return code of the command is 0; program
Google Drive folders to GAM are just like files, with the MimeType for a folder. To create a folder `FooFolder` in the root of the Drive for user `Fred`:
```
user Fred@yourdomain.com create drivefile drivefilename FooFolder mimetype gfolder
gam user Fred@yourdomain.com create drivefile drivefilename FooFolder mimetype gfolder
```
The same, but created in the existing folder `BarFolder`:
```
user Fred@yourdomain.com create drivefile drivefilename FooFolder mimetype gfolder parentname BarFolder
gam user Fred@yourdomain.com create drivefile drivefilename FooFolder mimetype gfolder parentname BarFolder
```
This only works if the folder name for the parent is unique. An alternative is to use the folder ID:
```
user Fred@yourdomain.com create drivefile drivefilename FooFolder mimetype gfolder parentid <FolderID>
gam user Fred@yourdomain.com create drivefile drivefilename FooFolder mimetype gfolder parentid <FolderID>
```
## Bulk Create Files and Folders

View File

@@ -35,12 +35,13 @@ Supported editions for this feature: Business Standard and Business Plus; Enterp
<DriveLabelNameList> ::= "<DriveLabelName>(,<DriveLabelName)*"
<DriveLabelNameEntity> ::=
<DriveLabelNameList> | <FileSelector> | <CSVFileSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<DriveLabelFieldID> ::= <String>
<DriveLabelSelectionID> ::= <String>
<DriveLabelSelectionIDList> ::= "<DriveLabelSelectionID>(,<DriveLabelSelectionID)*"
<DriveLabelLanguageCode> ::=
<BCP47LanguageCode> ::=
ar-sa| # Arabic Saudi Arabia
cs-cz| # Czech Czech Republic
da-dk| # Danish Denmark
@@ -93,12 +94,12 @@ Three forms of the commands are available:
```
gam [<UserTypeEntity>] info drivelabels <DriveLabelNameEntity>
[[basic|full] [languagecode <DriveLabelLanguageCode>]
[[basic|full] [languagecode <BCP47LanguageCode>]
[formatjson] [adminaccess|asadmin]
```
* `basic` - Display fields: name,id,revisionId,labelType,properties.*; this is the default
* `full` - Display all possible fields
* `languagecode <DriveLabelLanguageCode>` - The BCP-47 language code to use for evaluating localized Field labels. When not specified, values in the default configured language will be used.
* `languagecode <BCP47LanguageCode>` - The BCP-47 language code to use for evaluating localized Field labels. When not specified, values in the default configured language will be used.
* `adminaccess|asadmin` - Use the user's admin credentials. This will return all Labels within the customer.
By default, Gam displays the information as an indented list of keys and values.
@@ -106,13 +107,13 @@ By default, Gam displays the information as an indented list of keys and values.
```
gam [<UserTypeEntity>] show drivelabels
[basic|full] [languagecode <DriveLabelLanguageCode>]
[basic|full] [languagecode <BCP47LanguageCode>]
[publishedonly [<Boolean>]] [minimumrole applier|editor|organizer|reader]
[formatjson] [adminaccess|asadmin]
```
* `basic` - Display fields: name,id,revisionId,labelType,properties.*; this is the default
* `full` - Display all possible fields
* `languagecode <DriveLabelLanguageCode>` - The BCP-47 language code to use for evaluating localized Field labels. When not specified, values in the default configured language will be used.
* `languagecode <BCP47LanguageCode>` - The BCP-47 language code to use for evaluating localized Field labels. When not specified, values in the default configured language will be used.
* `minimumrole applier|editor|organizer|reader` - Specifies the level of access the user must have on the returned Labels. Defaults to READER.
* `adminaccess|asadmin` - Use the user's admin credentials. This will return all Labels within the customer.
@@ -121,13 +122,13 @@ By default, Gam displays the information as an indented list of keys and values.
```
gam [<UserTypeEntity>] print drivelabels [todrive <ToDriveAttribute>*]
[basic|full] [languagecode <DriveLabelLanguageCode>]
[basic|full] [languagecode <BCP47LanguageCode>]
[publishedonly [<Boolean>]] [minimumrole applier|editor|organizer|reader]
[formatjson [quotechar <Character>]] [adminaccess|asadmin]
```
* `basic` - Display fields: name,id,revisionId,labelType,properties.*; this is the default
* `full` - Display all possible fields
* `languagecode <DriveLabelLanguageCode>` - The BCP-47 language code to use for evaluating localized Field labels. When not specified, values in the default configured language will be used.
* `languagecode <BCP47LanguageCode>` - The BCP-47 language code to use for evaluating localized Field labels. When not specified, values in the default configured language will be used.
* `minimumrole applier|editor|organizer|reader` - Specifies the level of access the user must have on the returned Labels. Defaults to READER.
* `adminaccess|asadmin` - Use the user's admin credentials. This will return all Labels within the customer.

View File

@@ -104,17 +104,13 @@ specify `basicpermissions` and additional permission fields, e.g., `permissions.
<DriveFilePermissionEntity> ::=
<DriveFilePermissionList> |
(json [charset <Charset>] <JSONData>)|(json file <FileName> [charset <Charset>]) |
<FileSelector> |
<CSVFileSelector> |
<CSVkmdSelector> |
<CSVDataSelector>
<FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<DriveFilePermissionIDEntity> ::=
<DriveFilePermissionIDList> |
(json [charset <Charset>] <JSONData>)|(json file <FileName> [charset <Charset>]) |
<FileSelector> |
<CSVFileSelector> |
<CSVkmdSelector> |
<CSVDataSelector>
<FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
```
## GUI API permission name mapping

View File

@@ -6,6 +6,7 @@
- [Delete Gmail delegates](#delete-gmail-delegates)
- [Update Gmail delegates](#update-gmail-delegates)
- [Display Gmail delegates](#display-gmail-delegates)
- [Delete all delegates for a user](#delete-all-delegates-for-a-user)
## API documentation
* https://developers.google.com/gmail/api/v1/reference/users/settings/delegates
@@ -20,7 +21,9 @@
<UniqueID> ::= id:<String>
<UserItem> ::= <EmailAddress>|<UniqueID>|<String>
<UserList> ::= "<UserItem>(,<UserItem>)*"
<UserEntity> ::= <UserList>|<FileSelector>|<CSVkmdSelector>|<CSVDataSelector>
<UserEntity> ::=
<UserList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Users
```
## Aliases
@@ -64,3 +67,19 @@ This involves an extra API call per delegate email address.
By default, `show delegates` displays indented keys and values; use the `csv` option to have just the values
shown as a comma separated list.
## Delete all delegates for a user
```
$ gam redirect csv ./Delegates.csv user testsimple print delegates
Getting all Delegates for testsimple@domain.com
$ gam redirect stdout - multiprocess csv Delegates.csv gam user "~User" delete delegate "~delegateAddress"
2023-11-10T06:56:04.118-08:00,0/3,Using 3 processes...
2023-11-10T06:56:04.123-08:00,0,Processing item 3/3
User: testsimple@domain.com, Delete 1 Delegate
User: testsimple@domain.com, Delegate: testuser1@domain.com, Deleted
User: testsimple@domain.com, Delete 1 Delegate
User: testsimple@domain.com, Delegate: testuser2@domain.com, Deleted
User: testsimple@domain.com, Delete 1 Delegate
User: testsimple@domain.com, Delegate: testgroup@domain.com, Deleted
2023-11-10T06:56:07.253-08:00,0/3,Processing complete
```

View File

@@ -22,7 +22,9 @@
<FilterID> ::= <String>
<FilterIDList> ::= "<FilterID>(,<FilterID>)*"
<FilterIDEntity> ::= <FilterIDList>|<FileSelector>|<CSVkmdSelector>|<CSVDataSelector>
<FilterIDEntity> ::=
<FilterIDList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<GmailCategory> ::=
forums|

View File

@@ -21,7 +21,9 @@
<DomainName> ::= <String>(.<String>)+
<EmailAddress> ::= <String>@<DomainName>
<EmailAddressList> ::= "<EmailAddress>(,<EmailAddress>)*"
<EmailAddressEntity> ::= <EmailAddressList>|<FileSelector>|<CSVkmdSelector>|<CSVDataSelector>
<EmailAddressEntity> ::=
<EmailAddressList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Users
```
## Introduction
An email address must be defined as a forwarding address before it can be used to forward.

View File

@@ -40,10 +40,12 @@
<LabelIDList> ::= "<LabelID>(,<LabelID)*"
<LabelIDEntity> ::=
<LabelIDList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<LabelName> ::= <String>
<LabelNameList> ::= "'<LabelName>'(,'<LabelName>')*"
<LabelNameEntity> ::=
<LabelNameList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
```
## Special quoting
You specify a single label name with `label <LabelName>` and a list of labels with `labellist <LabelNameList>`.

View File

@@ -148,7 +148,9 @@
<MessageID> ::= <String>
<MessageIDList> ::= "<MessageID>(,<MessageID>)*"
<MessageIDEntity> ::= <MessageIDList>|<FileSelector>|<CSVkmdSelector>|<CSVDataSelector>
<MessageIDEntity> ::=
<MessageIDList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<ThreadID> ::= <String>
<ThreadIDList> ::= "<ThreadID>(,<ThreadID>)*"
<ThreadIDEntity> ::= <ThreadIDList>|<FileSelector>|<CSVkmdSelector>|<CSVDataSelector>
@@ -171,6 +173,22 @@
(gcsdoc|gcshtml <StorageBucketObjectName>)|
(emlfile <FileName>)
```
## Message queries with dates
```
query <QueryGmail> [querytime<String> <Date>]*
```
* `query "xxx"` - ` xxx` is appended to the current query; you can repeat the query argument to build up a longer query.
Use the `querytime<String> <Date>` option to allow dates, usually relative, to be substituted into the `query <QueryGmail>` option.
The `querytime<String> <Date>` value replaces the string `#querytime<String>#` in any queries.
The characters following `querytime` can be any combination of lowercase letters and numbers. This is most useful in scripts
where you can specify a relative date without having to change the script.
For example, query for messages from moree than 5 years ago:
```
querytime5years -5y query "before:#querytime5years#"
```
## Subject and label queries
Using a query to select messages by subject or label requires some attention in order to achieve the desired effect.
* https://support.google.com/mail/answer/7190
@@ -314,7 +332,7 @@ Your command line will have: `embedimage file1.jpg image1` embedimage file2.jpg
## Archive messages
```
gam <UserTypeEntity> archive messages <GroupItem>
(((query <QueryGmail>) (matchlabel <LabelName>) [or|and])+
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[quick|notquick] [doit] [max_to_archive <Number>])|(ids <MessageIDEntity>)
```
@@ -326,10 +344,10 @@ See below for message selection.
Export messages in EML format.
```
gam <UserTypeEntity> export message|messages
(((query <QueryGmail>) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_export <Number>])|(ids <MessageIDEntity>)
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_export <Number>])|(ids <MessageIDEntity>)
[targetfolder <FilePath>] [targetname <FileName>] [overwrite [<Boolean>]]
gam <UserTypeEntity> export thread|threads
(((query <QueryGmail>) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_export <Number>])|(ids <ThreadIDEntity>)
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_export <Number>])|(ids <ThreadIDEntity>)
[targetfolder <FilePath>] [targetname <FileName>] [overwrite [<Boolean>]]
```
@@ -352,11 +370,11 @@ See below for message selection.
## Forward messages/threads
```
gam <UserTypeEntity> forward message|messages recipient|to <RecipientEntity>
(((query <QueryGmail>) (matchlabel <LabelName>) [or|and])+
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[quick|notquick] [doit] [max_to_forward <Number>])|(ids <MessageIDEntity>)
[subject <String>]
gam <UserTypeEntity> forward thread|threads recipient|to <RecipientEntity>
(((query <QueryGmail>) (matchlabel <LabelName>) [or|and])+
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[quick|notquick] [doit] [max_to_forward <Number>])|(ids <ThreadIDEntity>)
[subject <String>]
```
@@ -370,27 +388,27 @@ See below for message selection.
## Manage messages/threads
```
gam <UserTypeEntity> delete messages|threads
(((query <QueryGmail>) (matchlabel <LabelName>) [or|and])+
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[quick|notquick] [doit] [max_to_delete <Number>])|(ids <MessageIDEntity>)
gam <UserTypeEntity> modify messages|threads
(((query <QueryGmail>) (matchlabel <LabelName>) [or|and])+
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[quick|notquick] [doit] [max_to_modify <Number>])|(ids <MessageIDEntity>)
(addlabel <LabelName>)* (removelabel <LabelName>)*
gam <UserTypeEntity> spam messages|threads
(((query <QueryGmail>) (matchlabel <LabelName>) [or|and])+
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[quick|notquick] [doit] [max_to_spam <Number>])|(ids <MessageIDEntity>)
gam <UserTypeEntity> trash messages|threads
(((query <QueryGmail>) (matchlabel <LabelName>) [or|and])+
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[quick|notquick] [doit] [max_to_trash <Number>])|(ids <MessageIDEntity>)
gam <UserTypeEntity> untrash messages|threads
(((query <QueryGmail>) (matchlabel <LabelName>) [or|and])+
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[quick|notquick] [doit] [max_to_untrash <Number>])|(ids <MessageIDEntity>)
```
### Manage a specific set of messages
* `ids <MessageIDEntity>` - A list of message ids
### Manage a selected set of messages
* `((query <QueryGmail>) (matchlabel <LabelName>) [or|and])+` - Criteria to select messages
* `((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+` - Criteria to select messages
* `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.
@@ -437,7 +455,7 @@ gam config auto_batch_min 1 groups_inde EastOffice delete message query "rfc822m
## Display messages/threads
```
gam <UserTypeEntity> show messages|threads
(((query <QueryGmail>) (matchlabel <LabelName>) [or|and])*
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])*
[quick|notquick] [max_to_show <Number>] [includespamtrash])|(ids <MessageIDEntity>)
[labelmatchpattern <RegularExpression>] [sendermatchpattern <RegularExpression>]
[countsonly|positivecountsonly] [useronly]
@@ -447,7 +465,7 @@ gam <UserTypeEntity> show messages|threads
[saveattachments [attachmentnamepattern <RegularExpression>]]
[targetfolder <FilePath>] [overwrite [<Boolean>]]
gam <UserTypeEntity> print messages|threads [todrive <ToDriveAttribute>*]
(((query <QueryGmail>) (matchlabel <LabelName>) [or|and])*
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])*
[quick|notquick] [max_to_print <Number>] [includespamtrash])|(ids <MessageIDEntity>)
[labelmatchpattern <RegularExpression>] [sendermatchpattern <RegularExpression>]
[countsonly|positivecountsonly] [useronly]
@@ -465,7 +483,7 @@ By default, Gam displays all messages.
* `ids <MessageIDEntity>` - A list of message ids
## Display a selected set of messages
* `((query <QueryGmail>) (matchlabel <LabelName>) [or|and])+` - Criteria to select messages
* `((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+` - Criteria to select messages
* `max_to_xxx` - Limit the number of messages that will be displayed
* `includespamtrash` - Include messages in the Spam and Trash folders
* `labelmatchpattern <RegularExpression>` - Only display messages with some label that matches `<RegularExpression>`

View File

@@ -24,7 +24,8 @@
<EmailAddress> ::= <String>@<DomainName>
<EmailAddressList> ::= "<EmailAddress>(,<EmailAddress>)*"
<EmailAddressEntity> ::=
<EmailAddressList>|<FileSelector>|<CSVkmdSelector>|<CSVDataSelector>
<EmailAddressList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Users
<Charset> ::= ascii|mbcs|utf-8|utf-8-sig|utf-16|<String>
<Password> ::= <String>
<SMTPHostName> ::= <String>

View File

@@ -35,7 +35,9 @@
<UniqueID> ::= id:<String>
<GroupItem> ::= <EmailAddress>|<UniqueID>|<String>
<GroupList> ::= "<GroupItem>(,<GroupItem>)*"
<GroupEntity> ::= <GroupList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<GroupEntity> ::=
<GroupList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<GroupRole> ::= owner|manager|member
<GroupRoleList> ::= "<GroupRole>(,<GroupRole>)*"
```

View File

@@ -51,6 +51,7 @@ gam user user@domain.com check serviceaccount
<NotesNameList> ::= "<NotesName>(,<NotesName)*"
<NotesNameEntity> ::=
<NotesNameList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<NotesField> ::=
attachments|

View File

@@ -1,19 +1,19 @@
# Users - Data Studio
# Users - Looker Studio
- [API documentation](#api-documentation)
- [Notes](#notes)
- [Definitions](#definitions)
- [Display Data Studio assets](#display-data-studio-assets)
- [Manage Data Studio permissions](#manage-data-studio-permissions)
- [Display Looker Studio assets](#display-data-studio-assets)
- [Manage Looker Studio permissions](#manage-data-studio-permissions)
- [Add Permissions](#add-permissions)
- [Delete Permissions](#delete-permissions)
- [Update Permissions](#update-permissions)
- [Display Data Studio permissions](#display-data-studio-permissions)
- [Display Looker Studio permissions](#display-data-studio-permissions)
## API documentation
* https://developers.google.com/datastudio/api/reference
* https://developers.google.com/looker-studio/integrate/api/reference
## Notes
To use these commands you must add the 'Data Studio API' to your project and update your service account authorization.
To use these commands you must add the 'Looker Studio API' to your project and update your service account authorization.
```
gam update project
gam user user@domain.com check serviceaccount
@@ -27,31 +27,33 @@ gam user user@domain.com check serviceaccount
<UniqueID> ::= id:<String>
<UserItem> ::= <EmailAddress>|<UniqueID>|<String>
<DataStudioAssetID> ::= <String>
<DataStudioAssetIDList> ::= "<DataStudioAssetID>(,<DataStudioAssetID>)*"
<DataStudioAssetIDEntity> ::=
<DataStudioAssetIDList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<LookerStudioAssetID> ::= <String>
<LookerStudioAssetIDList> ::= "<LookerStudioAssetID>(,<LookerStudioAssetID>)*"
<LookerStudioAssetIDEntity> ::=
<LookerStudioAssetIDList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<DataStudioPermission> ::=
<LookerStudioPermission> ::=
user:<EmailAddress>|
group:<EmailAddress>|
domain:<DomainName>|
serviceAccount:<EmailAddress>
<DataStudioPermissionList> ::= "<DataStudioPermission>(,<DataStudioPermission>)*"
<DataStudioPermissionEntity> ::=
<DataStudioPermissionList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
<LookerStudioPermissionList> ::= "<LookerStudioPermission>(,<LookerStudioPermission>)*"
<LookerStudioPermissionEntity> ::=
<LookerStudioPermissionList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
```
Data Studio assets have an ID that is referred to by Google as its `name`; this is the value
you will use wherever `<DataStudioAssetID>` is required.
Looker Studio assets have an ID that is referred to by Google as its `name`; this is the value
you will use wherever `<LookerStudioAssetID>` is required.
## Display Data Studio assets
## Display Looker Studio assets
```
gam <UserTypeEntity> show datastudioassets
gam <UserTypeEntity> show lookerstudioassets
[([assettype report|datasource|all] [title <String>]
[owner <Emailddress>] [includetrashed]
[orderby title [ascending|descending]]) |
(assetids <DataStudioAssetIDEntity>)]
(assetids <LookerStudioAssetIDEntity>)]
[stripcrsfromtitle]
[formatjson]
```
@@ -63,7 +65,7 @@ By default, all assets of type `report` not in the trash are displayed; use the
* `includetrashed` - Display assets in the trash
* `orderby title [ascending|descending]` - Order of assets
* Specific
* `assetids <DataStudioAssetIDEntity>` - Display a specific list of `assetids`
* `assetids <LookerStudioAssetIDEntity>` - Display a specific list of `assetids`
The `stripcrsfromtitle` option strips nulls, carriage returns and linefeeds from asset titles.
Use this option if you discover asset titles containing these special characters; it is not common.
@@ -71,11 +73,11 @@ Use this option if you discover asset titles containing these special characters
By default, Gam displays the information as an indented list of keys and values.
* `formatjson` - Display the fields in JSON format.
```
gam <UserTypeEntity> print datastudioassets [todrive <ToDriveAttribute>*]
gam <UserTypeEntity> print lookerstudioassets [todrive <ToDriveAttribute>*]
[([assettype report|datasource|all] [title <String>]
[owner <Emailddress>] [includetrashed]
[orderby title [ascending|descending]]) |
(assetids <DataStudioAssetIDEntity>)]
(assetids <LookerStudioAssetIDEntity>)]
[stripcrsfromtitle]
[formatjson [quotechar <Character>]]
```
@@ -87,7 +89,7 @@ By default, all assets of type `report` not in the trash are displayed; use the
* `includetrashed` - Display assets in the trash
* `orderby title [ascending|descending]` - Order of assets
* Specific
* `assetids <DataStudioAssetIDEntity>` - Display a specific list of `assetids`
* `assetids <LookerStudioAssetIDEntity>` - Display a specific list of `assetids`
The `stripcrsfromtitle` option strips nulls, carriage returns and linefeeds from asset titles.
Use this option if you discover asset titles containing these special characters; it is not common.
@@ -98,22 +100,22 @@ When using the `formatjson` option, double quotes are used extensively in the da
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
## Manage Data Studio permissions
## Manage Looker Studio permissions
* The owner of an asset can not have it's role changed.
* The owner of an asset can not be deleted.
* A new owner can not be added to an asset.
`<EmailAddress>` in `<DataStudioPermission>` must be complete, GAM will not add a domain name.
`<EmailAddress>` in `<LookerStudioPermission>` must be complete, GAM will not add a domain name.
A viewer can not manage permissions.
### Add permissions
```
gam <UserTypeEntity> add datastudiopermissions
gam <UserTypeEntity> add lookerstudiopermissions
[([assettype report|datasource|all] [title <String>]
[owner <Emailddress>] [includetrashed]
[orderby title [ascending|descending]]) |
(assetids <DataStudioAssetIDEntity)]
(role editor|viewer <DataStudioPermissionEntity>)+
(assetids <LookerStudioAssetIDEntity)]
(role editor|viewer <LookerStudioPermissionEntity>)+
[nodetails]
```
By default, the permission is added to all assets of type `report` not in the trash; use the following options to select a subset of assets.
@@ -124,19 +126,19 @@ By default, the permission is added to all assets of type `report` not in the tr
* `includetrashed` - Add permission to assets in the trash
* `orderby title [ascending|descending]` - Order of assets
* Specific
* `assetids <DataStudioAssetIDEntity>` - Add permission to a specific list of `assetids`
* `assetids <LookerStudioAssetIDEntity>` - Add permission to a specific list of `assetids`
By default, when a permission is added, GAM outputs details of the permission. The `nodetails` option
suppresses this output.
### Delete permissions
```
gam <UserTypeEntity> delete datastudiopermissions
gam <UserTypeEntity> delete lookerstudiopermissions
[([assettype report|datasource|all] [title <String>]
[owner <Emailddress>] [includetrashed]
[orderby title [ascending|descending]]) |
(assetids <DataStudioAssetIDEntity)]
(role any <DataStudioPermissionEntity>)+
(assetids <LookerStudioAssetIDEntity)]
(role any <LookerStudioPermissionEntity>)+
[nodetails]
```
By default, the permission is deleted from all assets of type `report` not in the trash; use the following options to select a subset of assets.
@@ -147,7 +149,7 @@ By default, the permission is deleted from all assets of type `report` not in th
* `includetrashed` - Delete permission from assets in the trash
* `orderby title [ascending|descending]` - Order of assets
* Specific
* `assetids <DataStudioAssetIDEntity>` - Delete permission from a specific list of `assetids`
* `assetids <LookerStudioAssetIDEntity>` - Delete permission from a specific list of `assetids`
By default, when a permission is deleted, GAM outputs details of the permission. The `nodetails` option
suppresses this output.
@@ -155,12 +157,12 @@ suppresses this output.
### Update permissions
A permission is updated by deleting the existing permission and then adding the new permission.
```
gam <UserTypeEntity> update datastudiopermissions
gam <UserTypeEntity> update lookerstudiopermissions
[([assettype report|datasource|all] [title <String>]
[owner <Emailddress>] [includetrashed]
[orderby title [ascending|descending]]) |
(assetids <DataStudioAssetIDEntity)]
(role editor|viewer <DataStudioPermissionEntity>)+
(assetids <LookerStudioAssetIDEntity)]
(role editor|viewer <LookerStudioPermissionEntity>)+
[nodetails]
```
By default, the permission is updated in all assets of type `report` not in the trash; use the following options to select a subset of assets.
@@ -171,20 +173,20 @@ By default, the permission is updated in all assets of type `report` not in the
* `includetrashed` - Update permission in assets in the trash
* `orderby title [ascending|descending]` - Order of assets
* Specific
* `assetids <DataStudioAssetIDEntity>` - Update permission in a specific list of `assetids`
* `assetids <LookerStudioAssetIDEntity>` - Update permission in a specific list of `assetids`
By default, when a permission is updated, GAM outputs details of the permission. The `nodetails` option
suppresses this output.
## Display Data Studio permissions
## Display Looker Studio permissions
A viewer can not display permissions.
```
gam <UserTypeEntity> show datastudiopermissions
gam <UserTypeEntity> show lookerstudiopermissions
[([assettype report|datasource|all] [title <String>]
[owner <Emailddress>] [includetrashed]
[orderby title [ascending|descending]]) |
(assetids <DataStudioAssetIDEntity>)]
(assetids <LookerStudioAssetIDEntity>)]
[role editor|owner|viewer]
[formatjson]
```
@@ -196,19 +198,19 @@ By default, permissions for all assets of type `report` not in the trash are dis
* `includetrashed` - Display permissions for assets in the trash
* `orderby title [ascending|descending]` - Order of assets
* Specific
* `assetids <DataStudioAssetIDEntity>` - Display permissions for a specific list of `assetids`
* `assetids <LookerStudioAssetIDEntity>` - Display permissions for a specific list of `assetids`
The Data Studio API defines this parameter `role editor|owner|viewer` but it doesn't seem to have any effect.
The Looker Studio API defines this parameter `role editor|owner|viewer` but it doesn't seem to have any effect.
By default, Gam displays the information as an indented list of keys and values.
* `formatjson` - Display the fields in JSON format.
```
gam <UserTypeEntity> print datastudiopermissions [todrive <ToDriveAttribute>*]
gam <UserTypeEntity> print lookerstudiopermissions [todrive <ToDriveAttribute>*]
[([assettype report|datasource|all] [title <String>]
[owner <Emailddress>] [includetrashed]
[orderby title [ascending|descending]]) |
(assetids <DataStudioAssetIDEntity>)]
(assetids <LookerStudioAssetIDEntity>)]
[role editor|owner|viewer]
[formatjson [quotechar <Character>]]
```
@@ -220,9 +222,9 @@ By default, permissions for all assets of type `report` not in the trash are dis
* `includetrashed` - Display permissions for assets in the trash
* `orderby title [ascending|descending]` - Order of assets
* Specific
* `assetids <DataStudioAssetIDEntity>` - Display permissions for a specific list of `assetids`
* `assetids <LookerStudioAssetIDEntity>` - Display permissions for a specific list of `assetids`
The Data Studio API defines this parameter `role editor|owner|viewer` but it doesn't seem to have any effect.
The Looker Studio API defines this parameter `role editor|owner|viewer` but it doesn't seem to have any effect.
By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain
the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled.

View File

@@ -21,6 +21,7 @@
- [Manage User Contact Groups](#manage-user-contact-groups)
- [Display User Contact Groups](#display-user-contact-groups)
- [Display User People Profile](#display-user-people-profile)
- [Copy User Contacts to another User](#copy-user-contacts-to-another-user)
## Notes
As of version `6.08.00`, GAM uses the People API to manage user contacts rather than the Contacts API.
@@ -63,6 +64,7 @@ gam user user@domain.com check serviceaccount
<PeopleResourceNameList> ::= "<PeopleResourceName>(,<PeopleResourceName>)*"
<PeopleResourceNameEntity> ::=
<PeopleResourceNameNameList> | <FileSelector> | <CSVFileSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<PeopleContactGroupName> ::= <String>
<PeopleContactGroupResourceName> ::= (contactgroup/<String>)|<String>
@@ -70,6 +72,7 @@ gam user user@domain.com check serviceaccount
<PeopleContactGroupList> ::= "<PeopleContactGroupItem>(,<PeopleContactGroupItem>)*"
<PeopleContactGroupEntity> ::=
<PeopleContactGroupList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<PeopleUserContactSelection> ::=
[(selectcontactgroup <PeopleContactGroupItem>)|
[query <QueryContact>]]
@@ -175,6 +178,7 @@ gam user user@domain.com check serviceaccount
<OtherContactsResourceNameList> ::= "<OtherContactsResourceName>(,<OtherContactsResourceName>)*"
<OtherContactsResourceNameEntity> ::=
<OtherContactsResourceNameList> | <FileSelector> | <CSVFileSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<OtherContactsSelection> ::=
[query <QueryContact>]
@@ -250,10 +254,24 @@ then filters the list to only those in `<PeopleContactGroupItem>`; quota limits
gam <UserTypeEntity> create contact
[<PeopleContactAttribute>+]
(contactgroup <PeopleContactGroupItem>)*
[(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*))| returnidonly]
```
You may specify zero or more contact groups with `(contactgroup <PeopleContactGroupItem>)*`;
these contact groups define the complete contact group list for the contact.
By default, the user name and contact ID are displayed on stdout.
* `csv [todrive <ToDriveAttribute>*]` - Write user name and contact ID values to a CSV file.
* `addcsvdata <FieldName> <String>` - Add additional columns of data from the command line to the output
* `returnidonly` - Display just the contact ID on stdout
To retrieve the contact ID with `returnidonly`:
```
Linux/MacOS
contactId=$(gam user user@domain.com create contact ... returnidonly)
Windows PowerShell
$contactId = & gam user user@domain.com create contact ... returnidonly
```
## Update User Contacts
```
gam <UserTypeEntity> update contacts
@@ -344,6 +362,11 @@ If `<PeopleUserContactSelection>` specifies `emailmatchpattern <RegularExpressio
are updated.
## Display User Contacts
### User Contact Group information
In the following commands, specifying `allfields` or including `memberships` in `fields <PeopleFieldNameList>`
yields contact group information but only gives the contact group ID. Use the `showgroups` option to have GAM
make additional API calls to get the contact group name associated with the ID.
### Display as an indented list of keys and values.
```
gam <UserTypeEntity> info contacts
@@ -546,6 +569,21 @@ The `quotechar <Character>` option allows you to choose an alternate quote chara
## Manage User Contact Groups
```
gam <UserTypeEntity> create contactgroup <PeopleContactGroupAttribute>+
[(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*))| returnidonly]
```
By default, the user name and contactgroup ID are displayed on stdout.
* `csv [todrive <ToDriveAttribute>*]` - Write user name and contactgroup ID values to a CSV file.
* `addcsvdata <FieldName> <String>` - Add additional columns of data from the command line to the output
* `returnidonly` - Display just the contactgroup ID on stdout
To retrieve the contactgroup ID with `returnidonly`:
```
Linux/MacOS
contactGroupId=$(gam user user@domain.com create contactgroup ... returnidonly)
Windows PowerShell
$contactGroupId = & gam user user@domain.com create contactgroup ... returnidonly
```
```
gam <UserTypeEntity> update contactgroup <PeopleContactGroupItem> <PeopleContactGroupAttribute>+
gam <UserTypeEntity> delete contactgroups <PeopleContactGroupEntity>
```
@@ -615,3 +653,15 @@ When using the `formatjson` option, double quotes are used extensively in the da
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
## Copy User Contacts to another User
To copy one user's contacts to another user perform the following steps.
```
# Copy contact groups
gam redirect csv ./ContactGroups.csv user sourceuser@domain.com print contactgroups formatjson
gam redirect stdout ./CopyContactGroups.txt multiprocess redirect stderr stdout csv ContactGroups.csv gam user targetuser@domain.com create contactgroup json "~JSON"
# Copy contacts
gam redirect csv ./Contacts.csv user sourceuser@domain.com print contacts selectmaincontacts allfields showgroups formatjson
gam redirect stdout ./CopyContacts.txt multiprocess redirect stderr stdout csv Contacts.csv gam user targetuser@domain.com create contact json "~JSON"
```

View File

@@ -1,8 +1,8 @@
# Users - Tasks
- [API documentation](#api-documentation)
- [Notes](#notes)
- [Collections of Users](Collections-of-Users)
- [Definitions](#definitions)
- [Specifying task lists](#specifying-task-lists)
- [Create Tasks](#create-tasks)
- [Update Tasks](#update-tasks)
- [Delete Tasks](#delete-tasks)
@@ -29,13 +29,17 @@ gam user user@domain.com check serviceaccount
```
<TaskID> ::= <String>
<TaskListID> ::= <String>
<TaskListTitle> ::= tltitle:<String>
<TasklistTitleList> ::= "'<TasklistTitle>'(,'<TasklistTitle>')*"
<TasklistIDTaskID> ::= <TasklistID>/<TaskID>
<TasklistIDList> ::= "<TasklistID>(,<TasklistID>)*"
<TasklistIDTaskIDList> ::= "<TasklistIDTaskID>(,<TasklistIDTaskID>)*"
<TasklistIDEntity> ::=
<TasklistIDList> | <FileSelector> | <CSVFileSelector>
<TasklistEntity> ::=
<TasklistIDList> | <TaskListTitleList> | <FileSelector> | <CSVFileSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<TasklistIDTaskIDEntity> ::=
<TasklistIDTaskIDList> | <FileSelector> | <CSVFileSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<TaskAttribute> ::=
(title <String>)|
@@ -46,9 +50,22 @@ gam user user@domain.com check serviceaccount
<TasklistAttribute> ::=
(title <String>)
```
## Specifying task lists
The Tasks API requires that a task list be specified by its ID; GAM allows specification of a task list
by its title and makes an additional API call to convert the title to an ID.
Note the quoting in `<TasklistTitleList>`; the entire list should be enclosed in `"` and
each `tltitle:<String>` must be enclosed in `'` if `<String>` contains a space.
```
gam user user@domain.com create task "'tltitle:My Tasks'" title "Task title" notes "Task Notes"
gam user user@domain.com info tasklist "'tltitle:My Tasks'"
```
## Create Tasks
```
gam <UserTypeEntity> create task <TasklistIDEntity>
gam <UserTypeEntity> create task <TasklistEntity>
<TaskAttribute>* [parent <TaskID>] [previous <TaskID>]
[compact|formatjson|returnidonly]
```
@@ -94,7 +111,7 @@ By default, Gam displays the tasks as an indented list of keys and values; the t
### Display all tasks
```
gam <UserTypeEntity> show tasks [tasklists <TasklistIDEntity>]
gam <UserTypeEntity> show tasks [tasklists <TasklistEntity>]
[completedmin <Time>] [completedmax <Time>]
[duemin <Time>] [duemax <Time>]
[updatedmin <Time>]
@@ -117,7 +134,7 @@ By default, only tasks with status `needsAction` are displayed.
* `showcompleted` - Add completed tasks to the display. `showHidden` must also be True to show tasks completed in first party clients, such as the web UI and Google's mobile apps.
* `showall` - Equivalent to `showdeleted` `showhidden` `showcompleted`
```
gam <UserTypeEntity> print tasks [tasklists <TasklistIDEntity>] [todrive <ToDriveAttribute>*]
gam <UserTypeEntity> print tasks [tasklists <TasklistEntity>] [todrive <ToDriveAttribute>*]
[completedmin <Time>] [completedmax <Time>]
[duemin <Time>] [duemax <Time>]
[updatedmin <Time>]
@@ -136,6 +153,9 @@ By default, only tasks with status `needsAction` are displayed.
* `showcompleted` - Add completed tasks to the display. `showHidden` must also be True to show tasks completed in first party clients, such as the web UI and Google's mobile apps.
* `showall` - Equivalent to `showdeleted` `showhidden` `showcompleted`
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format,
* `formatjson` - Display the fields in JSON format.
By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain
the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled.
When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output.
@@ -154,7 +174,7 @@ By default, Gam displays the created task list as an indented list of keys and v
## Update Task Lists
```
gam <UserTypeEntity> update tasklist <TasklistIDEntity>
gam <UserTypeEntity> update tasklist <TasklistEntity>
<TasklistAttribute>*
[formatjson]
```
@@ -163,19 +183,19 @@ By default, Gam displays the updated task list as an indented list of keys and v
## Delete Task Lists
```
gam <UserTypeEntity> delete tasklist <TasklistIDEntity>
gam <UserTypeEntity> delete tasklist <TasklistEntity>
```
## Clear Task Lists
Clears all completed tasks from the specified task lists.
```
gam <UserTypeEntity> clear tasklist <TasklistIDEntity>
gam <UserTypeEntity> clear tasklist <TasklistEntity>
```
## Display Task Lists
### Display selected task lists
```
gam <UserTypeEntity> info tasklist <TasklistIDEntity>
gam <UserTypeEntity> info tasklist <TasklistEntity>
[formatjson]
```
By default, Gam displays the task lists as an indented list of keys and values.
@@ -193,6 +213,9 @@ By default, Gam displays the task lists as an indented list of keys and values.
gam <UserTypeEntity> print tasklists [todrive <ToDriveAttribute>*]
[countsonly | (formatjson [quotechar <Character>])]
```
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format,
* `formatjson` - Display the fields in JSON format.
By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain
the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled.
When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output.

View File

@@ -1,6 +1,5 @@
# Users - Tokens
- [API documentation](#api-documentation)
- [Collections of Users](Collections-of-Users)
- [Definitions](#definitions)
- [Delete a user's token](#delete-a-users-token)
- [Display individual user's tokens](#display-individual-users-tokens)

146
docs/Users-YouTube.md Normal file
View File

@@ -0,0 +1,146 @@
# Users - YouTube
- [API documentation](#api-documentation)
- [Notes](#notes)
- [Definitions](#definitions)
- [Display Selected YouTube Channels](#display-selected-youtube-channels)
- [Display Owned YouTube Channels](#display-owned-youtube-channels)
## API documentation
* https://developers.google.com/youtube/v3/docs/channels/list
## Notes
To use these commands you must add the 'YouTube API' to your project and update your service account authorization.
```
gam update project
gam user user@domain.com update serviceaccount
```
## Definitions
* [`<UserTypeEntity>`](Collections-of-Users)
```
<BCP47LanguageCode> ::=
ar-sa| # Arabic Saudi Arabia
cs-cz| # Czech Czech Republic
da-dk| # Danish Denmark
de-de| # German Germany
el-gr| # Modern Greek Greece
en-au| # English Australia
en-gb| # English United Kingdom
en-ie| # English Ireland
en-us| # English United States
en-za| # English South Africa
es-es| # Spanish Spain
es-mx| # Spanish Mexico
fi-fi| # Finnish Finland
fr-ca| # French Canada
fr-fr| # French France
he-il| # Hebrew Israel
hi-in| # Hindi India
hu-hu| # Hungarian Hungary
id-id| # Indonesian Indonesia
it-it| # Italian Italy
ja-jp| # Japanese Japan
ko-kr| # Korean Republic of Korea
nl-be| # Dutch Belgium
nl-nl| # Dutch Netherlands
no-no| # Norwegian Norway
pl-pl| # Polish Poland
pt-br| # Portuguese Brazil
pt-pt| # Portuguese Portugal
ro-ro| # Romanian Romania
ru-ru| # Russian Russian Federation
sk-sk| # Slovak Slovakia
sv-se| # Swedish Sweden
th-th| # Thai Thailand
tr-tr| # Turkish Turkey
zh-cn| # Chinese China
zh-hk| # Chinese Hong Kong
zh-tw # Chinese Taiwan
<YouTubeChannelID> ::= <String>
<YouTubeChannelIDList> ::= "<YouTubeChannelID>(,<YouTubeChannelID>)*"
<YouTubeChannelFieldName> ::=
brandingsettings|
contentdetails|
contentownerdetails|
id|
localizations|
snippet|
statistics|
status|
topicdetails
<YouTubeChannelFieldNameList> ::= "<YouTubeChannelFieldName>(,<YouTubeChannelFieldName>)*"
```
## Display Selected YouTube Channels
Display YouTube channels selected by ID.
```
gam <UserTypeEntity> show youtubechannels
(mine|
(ids|channels <YouTubeChannelIDList>)|
(forusername <String>)|
(managedbyme <String>))
[languagecode <BCP47LanguageCode>]
[allfields|(fields <YouTubeChannelFieldNameList>)]
[formatjson]
```
By default, only the YouTube channel ID is displayed; use `allfields|fields` to select additional fields for display.
By default, Gam displays the YouTube channels as an indented list of keys and values.
* `formatjson` - Display the YouTube channels in JSON format
```
gam <UserTypeEntity> print youtubechannels [todrive <ToDriveAttribute>*]
(mine|
(ids|channels <YouTubeChannelIDList>)|
(forusername <String>)|
(managedbyme <String>))
[languagecode <BCP47LanguageCode>]
[allfields|(fields <YouTubeChannelFieldNameList>)]
[formatjson [quotechar <Character>]]
```
By default, only the YouTube channel ID is displayed; use `allfields|fields` to select additional fields for display.
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format,
* `formatjson` - Display the fields in JSON format.
By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain
the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled.
When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/proces output.
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/procesable output.
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
## Display Owned YouTube Channels
Display YouTube channels owned by a user.
```
gam <UserTypeEntity> show youtubechannels
[languagecode <BCP47LanguageCode>]
[allfields|(fields <YouTubeChannelFieldNameList>)]
[formatjson]
```
By default, only the YouTube channel ID is displayed; use `allfields|fields` to select additional fields for display.
By default, Gam displays the YouTube channels as an indented list of keys and values.
* `formatjson` - Display the YouTube channels in JSON format
```
gam <UserTypeEntity> print youtubechannels [todrive <ToDriveAttribute>*]
(mine|
(ids|channels <YouTubeChannelIDList>)|
(forusername <String>)|
(managedbyme <String>))
[languagecode <BCP47LanguageCode>]
[allfields|(fields <YouTubeChannelFieldNameList>)]
[formatjson [quotechar <Character>]]
```
By default, only the YouTube channel ID is displayed; use `allfields|fields` to select additional fields for display.
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format,
* `formatjson` - Display the fields in JSON format.
By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain
the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled.
When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/proces output.
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/procesable output.
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.

View File

@@ -4,7 +4,6 @@
- [Query documentation](#query-documentation)
- [Quoting rules](#quoting-rules)
- [Python Regular Expressions](Python-Regular-Expressions) Match function and Search function
- [Collections of Users](Collections-of-Users)
- [Definitions](#definitions)
- [User Attributes](#user-attributes)
- [Admin Console User Info](#admin-console-user-info)
@@ -13,7 +12,7 @@
- [Define schema fields](#define-schema-fields)
- [Clear schema fields](#clear-schema-fields)
- [Create a user](#create-a-user)
- [Specify a user's attributes with JSON data](#specify-a-users-attributes-with-JSON-data)
- [Specify a user's attributes with JSON data](#specify-a-users-attributes-with-json-data)
- [Verify mailbox creation](#verify-mailbox-creation)
- [Update a user](#update-a-user)
- [Special case processing for update user](#special-case-processing-for-update-user)
@@ -21,9 +20,9 @@
- [Update a user's name](#update-a-users-name)
- [Update a user's password](#update-a-users-password)
- [Update a user's primary email address](#update-a-users-primary-email-address)
- [Update a user's attributes with JSON data](#update-a-users-attributes-with-JSON-data)
- [Update a user's attributes with JSON data](#update-a-users-attributes-with-json-data)
- [Update a user's OU based on group membership](#update-a-users-ou-based-on-group-membership)
- [Do not update a user's OU if currently in a special purpose OU](#do-not-update-a-users-OU-if-currently-in-a-special-purpose-ou)
- [Do not update a user's OU if currently in a special purpose OU](#do-not-update-a-users-ou-if-currently-in-a-special-purpose-ou)
- [Delete or suspend users](#delete-or-suspend-users)
- [Undelete or unsuspend users](#undelete-or-unsuspend-users)
- [Display information about users](#display-information-about-users)
@@ -34,11 +33,12 @@
- [Print a header row and primaryEmail for all users](#print-a-header-row-and-primaryemail-for-all-users)
- [Print user details](#print-user-details)
- [Print a header row and fields for selected users](#print-a-header-row-and-fields-for-selected-users)
- [Print a header row and fields for users specified by `<UserTypeEntity>`](#print-a-header-row-and-fields-for-users-specified-by-UserTypeEntity)
- [Print a header row and fields for users specified by `<UserTypeEntity>`](#print-a-header-row-and-fields-for-users-specified-by-usertypeentity)
- [Print user domain counts](#print-user-domain-counts)
- [Print domain counts for users in a specific domain and/or selected by a query](#print-domain-counts-for-users-in-a-specific-domain-and-or-selected-by-a-query)
- [Print domain counts for users specified by `<UserTypeEntity>`](#print-domain-counts-for-users-specified-by-UserTypeEntity)
- [Print domain counts for users specified by `<UserTypeEntity>`](#print-domain-counts-for-users-specified-by-usertypeentity)
- [Print user list](#print-user-list)
- [Display user count](#display-user-count)
## API documentation
* https://developers.google.com/admin-sdk/directory/reference/rest/v1/users
@@ -64,11 +64,18 @@ Typically, you will enclose the entire list in double quotes and quote each item
* ```"'it em' 'it,em' \"it'em\""```
For example, a list of queries for Org Units where the Org Unit names contain spaces:
* Linux and MacOS and Windows Command Prompt
```
queries "\"orgUnitPath='/Students/Middle School'\",\"orgUnitPath='/Students/Lower School'\""
```
* Windows Power Shell
```
queries "`"orgUnitPath=\'/Students/Lower\ School/2027\'`",`"orgUnitPath=\'/Students/Lower\ School/2028\'`""
```
## Definitions
* [`<UserTypeEntity>`](Collections-of-Users)
* [Command data from Google Docs/Sheets/Storage](Command-Data-From-Google-Docs-Sheets-Storage)
```
<DeliverySetting> ::=
@@ -79,6 +86,9 @@ queries "\"orgUnitPath='/Students/Middle School'\",\"orgUnitPath='/Students/Low
none|nomail
<DomainName> ::= <String>(.<String>)+
<DomainNameList> ::= "<DomainName>(,<DomainName>)*"
<DomainNameEntity> ::=
<DomainNameList> | <FileSelector> | <CSVFileSelector>
<EmailAddress> ::=
<String>@<DomainName> |
<String> <<String>@<DomainName>> # The outer <> around <String>@<DomainName> are literal, e.g., IT Group<group@domain.com>
@@ -89,6 +99,7 @@ queries "\"orgUnitPath='/Students/Middle School'\",\"orgUnitPath='/Students/Low
<GroupItem> ::= <EmailAddress>|<UniqueID>|<String>
<GroupList> ::= "<GroupItem>(,<GroupItem>)*"
<GroupEntity> ::= <GroupList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<GroupRole> ::= owner|manager|member
<OrgUnitID> ::= id:<String>
@@ -360,7 +371,8 @@ When creating a user or updating a user's password, you can send a message with
[subject <String>]
[notifypassword <String>]
[from <EmailAaddress>]
[replyto <EmailAaddress>]
[mailbox <EmailAddress>]
[replyto <EmailAddress>]
[<NotifyMessageContent>]
(replace <Tag> <UserReplacement>)*]
[notifyonupdate [<Boolean>]]
@@ -409,6 +421,7 @@ is sent when the user is updated or created. Use `notifyonupdate false` to suppr
By default, the email is sent from the admin user identified in oauth2.txt, `gam oauth info` will show the value.
Use `from <EmailAddress>` to specify an alternate from address.
Use `mailbox <EmailAddress>` if `from <EmailAddress>` specifies a group; GAM has to login as a user to be able to send a message.
Gam gets no indication as to the status of the message delivery; the from user will get a non-delivery receipt if the message could not be sent to the `notify <EmailAddressList>`.
By default, messages are sent as plain text, use `html` or `html true` to indicate that the message is HTML.
@@ -475,7 +488,7 @@ clearschema <SchemaName>.<FieldName>
## Create a user
```
gam create user <EmailAddress> [ignorenullpassword] <UserAttribute>*
[verifynotinvitable]
[verifynotinvitable|alwaysevict]
(groups [<GroupRole>] [[delivery] <DeliverySetting>] <GroupEntity>)*
[alias|aliases <EmailAddressList>]
[license <SKUIDList> [product|productid <ProductID>]]
@@ -483,15 +496,22 @@ gam create user <EmailAddress> [ignorenullpassword] <UserAttribute>*
[subject <String>]
[notifypassword <String>]
[from <EmailAaddress>]
[mailbox <EmailAddress>]
[replyto <EmailAaddress>]
[<NotifyMessageContent>]
(replace <Tag> <UserReplacement>)*]
[lograndompassword <FileName>]
[addnumericsuffixonduplicate <Number>]
```
When `verifynotinvitable` is specified, GAM verifies that the email address being updated is not that of an unmanaged account;
When `verifynotinvitable` is specified, GAM verifies that the email address being created is not that of an unmanaged account;
if it is, the command is not performed.
By default, when creating a user that has a conflict with an unmanaged account, GAM will honor the setting as described on these pages.
* https://support.google.com/a/answer/11112794
* https://admin.google.com/ac/accountsettings/conflictaccountmanagement
Specifying `alwaysevict` forces GAM to select this setting: `Replace conflicting unmanaged accounts with managed ones`
The user will be added to the groups specified by `groups [<GroupRole>] [[delivery] <DeliverySetting>] <GroupEntity>`.
The user aliases in `alias|aliases <EmailAddressList>` will be created.
@@ -575,7 +595,7 @@ If the mailbox is setup, a zero return code is returned; if the retries are exha
## Update a user
```
gam update user <UserItem> [ignorenullpassword] <UserAttribute>*
[verifynotinvitable] [noactionifalias]
[verifynotinvitable|alwaysevict] [noactionifalias]
[updateprimaryemail <RegularExpression> <EmailReplacement>]
[updateoufromgroup <FileName> [charset <CharSet>]
[columndelimiter <Character>] [quotechar <Character>]
@@ -588,6 +608,7 @@ gam update user <UserItem> [ignorenullpassword] <UserAttribute>*
[subject <String>]
[notifypassword <String>]
[from <EmailAaddress>]
[mailbox <EmailAddress>]
[replyto <EmailAaddress>]
[<NotifyMessageContent>]
(replace <Tag> <UserReplacement>)*]
@@ -595,7 +616,7 @@ gam update user <UserItem> [ignorenullpassword] <UserAttribute>*
(replace <Tag> <UserReplacement>)*
[lograndompassword <FileName>]
gam update users <UserTypeEntity> [ignorenullpassword] <UserAttribute>*
[verifynotinvitable] [noactionifalias]
[verifynotinvitable|alwaysevict] [noactionifalias]
[updateprimaryemail <RegularExpression> <EmailReplacement>]
[updateoufromgroup <FileName> [charset <CharSet>]
[columndelimiter <Character>] [quotechar <Character>]
@@ -608,6 +629,7 @@ gam update users <UserTypeEntity> [ignorenullpassword] <UserAttribute>*
[subject <String>]
[notifypassword <String>]
[from <EmailAaddress>]
[mailbox <EmailAddress>]
[replyto <EmailAaddress>]
[<NotifyMessageContent>]
(replace <Tag> <UserReplacement>)*]
@@ -615,7 +637,7 @@ gam update users <UserTypeEntity> [ignorenullpassword] <UserAttribute>*
(replace <Tag> <UserReplacement>)*
[lograndompassword <FileName>]
gam <UserTypeEntity> update users [ignorenullpassword] <UserAttribute>*
[verifynotinvitable] [noactionifalias]
[verifynotinvitable|alwaysevict] [noactionifalias]
[updateprimaryemail <RegularExpression> <EmailReplacement>]
[updateoufromgroup <FileName> [charset <CharSet>]
[columndelimiter <Character>] [quotechar <Character>]
@@ -628,6 +650,7 @@ gam <UserTypeEntity> update users [ignorenullpassword] <UserAttribute>*
[subject <String>]
[notifypassword <String>]
[from <EmailAaddress>]
[mailbox <EmailAddress>]
[replyto <EmailAaddress>]
[<NotifyMessageContent>]
(replace <Tag> <UserReplacement>)*]
@@ -639,6 +662,14 @@ gam <UserTypeEntity> update users [ignorenullpassword] <UserAttribute>*
When `verifynotinvitable` is specified, GAM verifies that the email address being updated is not that of an unmanaged account;
if it is, the command is not performed.
If `createifnotfound` is specified and the user was not found to update and must be created, the following applies.
By default, when creating a user that has a conflict with an unmanaged account, GAM will honor the setting as described on these pages.
* https://support.google.com/a/answer/11112794
* https://admin.google.com/ac/accountsettings/conflictaccountmanagement
Specifying `alwaysevict` forces GAM to select this setting: `Replace conflicting unmanaged accounts with managed ones`
When `noactionifalias` is specified, no action is performed if `<UserItem>` or `<UserTypeEntity>` specifies an alias rather than a primary email address.
**Note that when `changepassword true` is specified, the user is immediately logged out.**
@@ -937,8 +968,8 @@ gam print users
See: https://developers.google.com/admin-sdk/directory/v1/guides/search-users
```
gam print users [todrive <ToDriveAttribute>*]
([domain <DomainName>] [(query <QueryUser>)|(queries <QueryUserList>)]
[limittoou <OrgUnitPath>|<OrgUnitID>] [deleted_only|only_deleted])
([domain|domains <DomainNameEntity>] [(query <QueryUser>)|(queries <QueryUserList>)]
[limittoou <OrgUnitItem>] [deleted_only|only_deleted])
[orderby <UserOrderByFieldName> [ascending|descending]]
[groups|groupsincolumns] [license|licenses|licence|licences]
[schemas|custom|customschemas all|<SchemaNameList>]
@@ -950,9 +981,10 @@ gam print users [todrive <ToDriveAttribute>*]
```
By default, users in all domains in the account are selected; these options allow selection of subsets of users:
* `domain <DomainName>` - Limit users to those in `<DomainName>`
* `(query <QueryUser>)|(queries <QueryUserList>)` - Limit users to those that match a query
* `limittoou <OrgUnitPath>|<OrgUnitID>` - Limit users to those in the specified `<OrgUnitPath>|<OrgUnitID>`
* `domain|domains <DomainNameEntity>` - Limit users to those in the domains specified by `<DomainNameEntity>`
* You can predefine this list with the `print_agu_domains` variable in `gam.cfg`.
* `(query <QueryUser>)|(queries <QueryUserList>)` - Limit users to those that match a query; each query is run against each domain
* `limittoou <OrgUnitPath>|<OrgUnitID>` - Limit users to those in the specified `<OrgUnitItem>>`
* `deleted_only|only_deleted` - Only display deleted users
* `issuspended <Boolean>` - Limit users based on their status
@@ -1044,15 +1076,16 @@ Print a CSV file with headers `domain,count` that gives the number of users in e
### Print domain counts for users in a specific domain and/or selected by a query
```
gam print users [todrive <ToDriveAttribute>*]
([domain <DomainName>] [(query <QueryUser>)|(queries <QueryUserList>)]
[limittoou <OrgUnitPath>|<OrgUnitID>] [deleted_only|only_deleted])
([domain|domains <DomainNameEntity>] [(query <QueryUser>)|(queries <QueryUserList>)]
[limittoou <OrgUnitItem>] [deleted_only|only_deleted])
[formatjson [quotechar <Character>]] [countonly]
[issuspended <Boolean>]
```
By default, users in all domains in the account are selected; these options allow selection of subsets of users:
* `domain <DomainName>` - Limit users to those in `<DomainName>`
* `(query <QueryUser>)|(queries <QueryUserList>)` - Limit users to those that match a query
* `limittoou <OrgUnitPath>|<OrgUnitID>` - Limit users to those in the specified `<OrgUnitPath>|<OrgUnitID>`
* `domain|domains <DomainNameEntity>` - Limit users to those in the domains specified by `<DomainNameEntity>`
* You can predefine this list with the `print_agu_domains` variable in `gam.cfg`.
* `(query <QueryUser>)|(queries <QueryUserList>)` - Limit users to those that match a query; each query is run against each domain
* `limittoou <OrgUnitPath>|<OrgUnitID>` - Limit users to those in the specified `<OrgUnitItem>>`
* `deleted_only|only_deleted` - Only display deleted users
* `issuspended <Boolean>` - Limit users based on their status
@@ -1072,7 +1105,7 @@ When using the `formatjson` option, double quotes are used extensively in the da
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
### Print user list
## Print user list
Print a CSV file with headers `title,count,users` that displays the list of users in `<UserTypeEntity>` in a single row.
```
gam <UserTypeEntity> print userlist [todrive <ToDriveAttribute>*]
@@ -1162,4 +1195,11 @@ Got 12 Users in the Organizational Unit for /Test...
Got 4 Users directly in the Organizational Unit for /Test
$ more UsersList.csv
["testuser1@domain.org", "testuser2@domain.org", "testuser3@domain.org", "testuser4@domain.org"]
```
```
## Display user count
Display the number of users in an entity.
```
gam <UserTypeEntity> show count
```

View File

@@ -1,5 +1,6 @@
# Using GAMADV-XTD3 with a YubiKey
- [Thanks](#Thanks)
- [Thanks](#thanks)
- [Yubikey ykman PIV Commands](https://docs.yubico.com/software/yubikey/tools/ykman/PIV_Commands.html)
- [Introduction](#introduction)
- [FAQs](#faqs)
- [Setup Steps](#setup-steps)
@@ -42,11 +43,11 @@ When using domain-wide delegation with GAMADV-XTD3, the service account and anyo
4. **If you are already using the YubiKey and wish to preserve the PIV app data and keys**
1. You need to configure one of the PIV slots for a private key GAMADV-XTD3 can use.
* [ykman piv keys generate](https://docs.yubico.com/software/yubikey/tools/ykman/PIV_Commands.html#ykman-piv-keys-options-command-args)
`ykman piv keys generate -P some_pin --pin-policy ALWAYS --touch-policy NEVER --algorithm RSA2048 9a new_pubkey.txt`
`ykman piv keys generate -P <Text> --pin-policy ALWAYS --touch-policy NEVER --algorithm RSA2048 9a new_pubkey.txt`
* Use `9a` for the `AUTHENTICATION` slot, `9c` for the `SIGNATURE` slot
2. You need to generate a certificate for that slot.
* [ykman piv certificates generate](https://docs.yubico.com/software/yubikey/tools/ykman/PIV_Commands.html#ykman-piv-certificates-generate-options-slot-public-key)
`ykman piv certificates generate -P some_pin --subject "GAM Service Account" -d 36500 9a new_pubkey.txt`
`ykman piv certificates generate -P <Text> --subject "GAM Service Account" -d 36500 9a new_pubkey.txt`
* Use `9a` for the `AUTHENTICATION` slot, `9c` for the `SIGNATURE` slot
5. Now that you have a private key on your YubiKey, tell GAMADV-XTD3 to use that instead of the private_key stored in oauth2service.json. We can do that by rotating the key:

View File

@@ -1,5 +1,5 @@
# Using GAMADV-XTD3 with a delegated admin service account
- [Thanks](#Thanks)
- [Thanks](#thanks)
- [Introduction](#introduction)
- [Advantages](#advantages)
- [Disadvantages](#disadvantages)

View File

@@ -41,6 +41,7 @@
<EmailItemList> ::= "<EmailItem>(,<EmailItem>)*"
<EmailAddressList> ::= "<EmailAddess>(,<EmailAddress>)*"
<EmailAddressEntity> ::= <EmailAddressList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
<TimeZone> ::= <String>
See: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
<UniqueID> ::= id:<String>

View File

@@ -1,12 +1,13 @@
# Version and Help
Print the current version of Gam with details
```
gam version
GAMADV-XTD3 6.22.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.65.15 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.11.4 64-bit final
MacOS Monterey 12.6.6 x86_64
Python 3.12.0 64-bit final
MacOS Monterey 12.7 x86_64
Path: /Users/Admin/bin/gamadv-xtd3
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain.com
Time: 2023-06-02T21:10:00-07:00
@@ -15,10 +16,10 @@ Time: 2023-06-02T21:10:00-07:00
Print the current version of Gam with details and time offset information
```
gam version timeoffset
GAMADV-XTD3 6.22.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.65.15 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.11.4 64-bit final
MacOS Monterey 12.6.6 x86_64
Python 3.12.0 64-bit final
MacOS Monterey 12.7 x86_64
Path: /Users/Admin/bin/gamadv-xtd3
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain.com
Your system time differs from www.googleapis.com by less than 1 second
@@ -27,10 +28,10 @@ Your system time differs from www.googleapis.com by less than 1 second
Print the current version of Gam with extended details and SSL information
```
gam version extended
GAMADV-XTD3 6.22.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.65.15 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.11.4 64-bit final
MacOS Monterey 12.6.6 x86_64
Python 3.12.0 64-bit final
MacOS Monterey 12.7 x86_64
Path: /Users/Admin/bin/gamadv-xtd3
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain.com
Time: 2023-06-02T21:10:00-07:00
@@ -64,7 +65,7 @@ MacOS High Sierra 10.13.6 x86_64
Path: /Users/Admin/bin/gamadv-xtd3
Version Check:
Current: 5.35.08
Latest: 6.22.00
Latest: 6.65.15
echo $?
1
```
@@ -72,7 +73,7 @@ echo $?
Print the current version number without details
```
gam version simple
6.22.00
6.65.15
```
In Linux/MacOS you can do:
```
@@ -82,10 +83,10 @@ echo $VER
Print the current version of Gam and address of this Wiki
```
gam help
GAM 6.22.00 - https://github.com/taers232c/GAMADV-XTD3
GAM 6.65.15 - https://github.com/taers232c/GAMADV-XTD3
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.11.4 64-bit final
MacOS Monterey 12.6.6 x86_64
Python 3.12.0 64-bit final
MacOS Monterey 12.7 x86_64
Path: /Users/Admin/bin/gamadv-xtd3
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain.com
Time: 2023-06-02T21:10:00-07:00

View File

@@ -17,6 +17,7 @@ Installation
Configuration
* [Authorization](Authorization)
* [GAM Configuration](gam.cfg)
* [Multiple Customers and Domains](https://github.com/taers232c/GAMADV-XTD3/wiki/gam.cfg#multiple-customers-and-domains)
* [Running GAMADV-XTD3 securely on a Google Compute Engine](Running-GAMADV-XTD3-securely-on-a-Google-Compute-Engine)
* [Using GAMADV-XTD3 with a delegated admin service account](Using-GAMADV-XTD3-with-a-delegated-admin-service-account)
* [Using GAMADV-XTD3 with a YubiKey](Using-GAMADV-XTD3-with-a-YubiKey)
@@ -66,7 +67,7 @@ Client Access
* [Chrome Auto Update Expiration Counts](Chrome-AUE-Counts)
* [Chrome Browser Cloud Management](Chrome-Browser-Cloud-Management)
* [Chrome Device Needs Attention Counts](Chrome-Needs-Attention-Counts)
* [Chrome Installed Apps Counts](Chrome-Installed-Apps-Counts)
* [Chrome Installed Apps](Chrome-Installed-Apps)
* [Chrome Policies](Chrome-Policies)
* [Chrome Printers](Chrome-Printers)
* [Chrome Version Counts](Chrome-Version-Counts)
@@ -124,7 +125,6 @@ Service Account Access
* [Users - Deprovision](Users-Deprovision)
* [Users - Contacts](Users-People-Contacts-Profiles)
* [Users - Contacts - Delegates](Users-Contacts-Delegates)
* [Users - Data Studio](Users-DataStudio)
* [Users - Drive - File Selection](Drive-File-Selection)
* [Users - Drive - Activity/Settings](Users-Drive-Activity-Settings)
* [Users - Drive - Cleanup](Users-Drive-Cleanup)
@@ -151,6 +151,7 @@ Service Account Access
* [Users - Gmail - Settings](Users-Gmail-Settings)
* [Users - Group Membership](Users-Group-Membership)
* [Users - Keep](Users-Keep)
* [Users - Looker Studio](Users-Looker-Studio)
* [Users - People - Contacts & Profiles](Users-People-Contacts-Profiles)
* [Users - Photo](Users-Photo)
* [Users - Profile Sharing](Users-Profile-Sharing)
@@ -158,3 +159,4 @@ Service Account Access
* [Users - Spreadsheets](Users-Spreadsheets)
* [Users - Tasks](Users-Tasks)
* [Users - Tokens](Users-Tokens)
* [Users - YouTube](Users-YouTube)

View File

@@ -61,6 +61,11 @@ api_calls_rate_limit
Limit on number of Google API calls per 60 seconds
Default: 1000
Range: 100 - Unlimited
api_calls_tries_limit
Limit the number of tries for Google API calls that return an error
that indicates a retry should be performed
Default: 10
Range: 3-10
auto_batch_min
Automatically generate gam batch command if number of users
specified in gam users xxx command exceeds this number
@@ -401,6 +406,31 @@ people_max_results
how many should be retrieved in each API call
Default: 100
Range: 1 - 1000
print_agu_domains
A comma separated list of domain names that are used in these commands:
gam print aliases
gam print groups
gam print|show group-members
gam print users
This allows predefining the list of domains so they don't have to be specified in each command.
Default: Blank
print_cros_ous
A comma separated list of org unit that are used in these commands:
gam print cros
gam print crosactivity
This allows predefining the list of org units so they don't have to be specified in each command.
Default: Blank
print_cros_ous_and_children
A comma separated list of org unit names that are used in these commands:
gam print cros
gam print crosactivity
This allows predefining the list of org units so they don't have to be specified in each command.
Default: Blank
process_wait_limit
When processing batch/CSV files, how long (in seconds) GAM should wait for all batch|csv processes to complete
after all have been started. If the limit is reached, GAM terminates any remaining processes.
Default: 0: no limit
Range: 0 - Unlimited
quick_cros_move
Default value for "quickcrosmove [<Boolean>]" in commands that update Chromebook OUs.
Default: False
@@ -557,6 +587,7 @@ Section: DEFAULT
admin_email = ''
api_calls_rate_check = false
api_calls_rate_limit = 100
api_calls_tries_limit = 10
auto_batch_min = 0
bail_on_internal_error_tries = 2
batch_size = 50
@@ -628,6 +659,10 @@ Section: DEFAULT
output_dateformat = ''
output_timeformat = ''
people_max_results = 100
print_agu_domains = ''
print_cros_ous = ''
print_cros_ous_and_children = ''
process_wait_limit = 0
quick_cros_move = false
quick_info_user = false
reseller_id = ''
@@ -744,6 +779,7 @@ activity_max_results = 100
admin_email = ''
api_calls_rate_check = false
api_calls_rate_limit = 1000
api_calls_tries_limit = 10
auto_batch_min = 0
bail_on_internal_error_tries = 2
batch_size = 50
@@ -808,6 +844,10 @@ oauth2service_json = oauth2service.json
output_dateformat = ''
output_timeformat = ''
people_max_results = 100
print_agu_domains = ''
print_cros_ous = ''
print_cros_ous_and_children = ''
process_wait_limit = 0
quick_cros_move = False
quick_info_user = False
reseller_id = ''

94
docs~
View File

@@ -1,94 +0,0 @@
# Version and Help
Print the current version of Gam with details
```
gam version
GAMADV-XTD3 6.61.18 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.11.4 64-bit final
MacOS Monterey 12.6.6 x86_64
Path: /Users/Admin/bin/gamadv-xtd3
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain.com
Time: 2023-06-02T21:10:00-07:00
```
Print the current version of Gam with details and time offset information
```
gam version timeoffset
GAMADV-XTD3 6.61.18 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.11.4 64-bit final
MacOS Monterey 12.6.6 x86_64
Path: /Users/Admin/bin/gamadv-xtd3
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain.com
Your system time differs from www.googleapis.com by less than 1 second
```
Print the current version of Gam with extended details and SSL information
```
gam version extended
GAMADV-XTD3 6.61.18 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.11.4 64-bit final
MacOS Monterey 12.6.6 x86_64
Path: /Users/Admin/bin/gamadv-xtd3
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain.com
Time: 2023-06-02T21:10:00-07:00
Your system time differs from admin.googleapis.com by less than 1 second
OpenSSL 3.1.1 30 May 2023
cryptography 41.0.1
filelock 3.12.0
google-api-python-client 2.88.0
google-auth-httplib2 0.1.0
google-auth-oauthlib 1.0.0
google-auth 2.19.1
httplib2 0.22.0
passlib 1.7.4
python-dateutil 2.8.2
yubikey-manager 5.1.1
admin.googleapis.com connects using TLSv1.3 TLS_AES_256_GCM_SHA384
```
Print the current and latest versions of Gam and:
* set the return code to 0 if the current version is the latest version
* set the return code to 1 if the current version is not the latest
```
gam version checkrc
GAM 5.35.08 - https://github.com/taers232c/GAMADV-XTD3
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.8.1 64-bit final
google-api-python-client 2.77.0
httplib2 0.16.0
oauth2client 4.1.3
MacOS High Sierra 10.13.6 x86_64
Path: /Users/Admin/bin/gamadv-xtd3
Version Check:
Current: 5.35.08
Latest: 6.61.18
echo $?
1
```
Print the current version number without details
```
gam version simple
6.61.18
```
In Linux/MacOS you can do:
```
VER=`gam version simple`
echo $VER
```
Print the current version of Gam and address of this Wiki
```
gam help
GAM 6.61.18 - https://github.com/taers232c/GAMADV-XTD3
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.11.4 64-bit final
MacOS Monterey 12.6.6 x86_64
Path: /Users/Admin/bin/gamadv-xtd3
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain.com
Time: 2023-06-02T21:10:00-07:00
Help: Syntax in file /Users/Admin/bin/gamadv-xtd3/GamCommands.txt
Help: Documentation is at https://github.com/taers232c/GAMADV-XTD3/wiki
```

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,495 @@
Merged GAM-Team version
6.65.15
Added additional options to `gam <UserTypeEntity> print|show youtubechannels`.
6.65.14
Fixed bug in gam <UserTypeEntity> copy|move drivefile` that caused a trap.
```
UnboundLocalError: cannot access local variable 'emailAddress' where it is not associated with a value
```
6.65.13
Added support for user language `en-CA`.
Added option `sizefield quotabytesused|size` to the following commands that specifies which
file size field to use when totaling file sizes; the default value is `quotabytesused`; previous versions used `size`.
```
gam <UserTypeEntity> print|show filecounts
gam <UserTypeEntity> print filelist
gam <UserTypeEntity> print|show filetree
gam <UserTypeEntity> print diskusage
```
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-Drive-Files-Display#file-size-fields
6.65.12
Additional updates on MacOS when a `gam csv` command is interrupted with a contol-C.
6.65.11
Updated multiprocessing to handle the following error that occurs on MacOS when a `gam csv` command
is interrupted with a contol-C.
```
multiprocessing/resource_tracker.py:224: UserWarning: resource_tracker: There appear to be N leaked semaphore objects to clean up at shutdown
```
Fixed bug in `gam print|show crostelemetry` where no CrOS device data was displayed if no selection
options were chosen; now, data is displayed for all CrOS devices as documented.
6.65.10
Fixed bug in `gam print crostelemetry` that caused a trap: `KeyError: 'reportTime'`.
6.65.09
Added option `noduplicate` to `gam <UserTypeEntity> create drivefile` that causes GAM
to issue a warning and not perform the create if a non-trashed item with the same name (regardless of MIME type)
exists in the parent folder.
Updated `gam <UserTypeEntity> get drivefile <DriveFileEntity>` to handle the following error
that seems to occur when multiple tabs from a Google sheet are being downloaded in parallel.
```
Download Failed: HTTP Error: 429
```
6.65.08
Added option `addcsvdata <FieldName> <String>` to `gam report <ActivityApplicationName>` that adds
additional columns of data to the CSV file output.
Added option `shownoactivities` to `gam report <ActivityApplicationName>` that causes GAM to display
a row with a key value of `NoActivities` when there are no activities to report.
For example, to find Shared Drives with no activity, see: https://github.com/taers232c/GAMADV-XTD3/wiki/Reports#find-shared-drives-with-no-activity
6.65.07
Updated `gam delete building` to handle the following error:
```
ERROR: 412: conditionNotMet - Cannot delete building because there are Calendar resources associated with it.
```
6.65.06
Improved error message when trying to add external students/teachers to a course.
```
gam courses 544906261666 add student user@gmail.com
Course: 544906261666, Add 1 Student
Course: 544906261666, Student: user@gmail.com, Add Failed: 403: permissionDenied - @CannotDirectAddUser Unable to directly add the user to the course. Please check that the user account exists and is within the course admin's domain. Add external user with: gam user user@gmail.com create classroominvitation courses 544906261666 role Student
```
6.65.05
Updated `gam info users <UserTypeEntity>` to make option `grouptree` effective when used
with option `formatjson`.
Added option `[formatjson [quotechar <Character>]]]`
to these commands so that event details are displayed in CSV format.
```
gam print|show grouptree <GroupEntity>
gam <UserTypeEntity> print|show grouptree
```
Added option `querytime<String> <Date>` to all commands that process messages.
For example, you can identify all messages within a particular time period, in this case, all messages unread
in the last 30 days.
```
gam user user@domain.com print messages querytime30d -30d query "after:#querytime30d# is:unread"
```
Updated `gam <UserTypeEntity> import|insert message` to allow `replace <Tag> <UserReplacement>` as documented.
Updated non-owner permission handling in `gam <UserTypeEntity> copy|move drivefile`.
6.65.04
Fixed bug where license SKU `1010020031` (Google Workspace Frontline Standard) was improperly entered making it unusable;
its alias `wsflwstan` was usable.
Added support for Google Workspace Additional Storage.
* ProductID - 101043
* SKUID - 1010430001 | gwas | plusstorage
6.65.03
Fixed bug in commands that display calendar events where event start and end times were not properly displayed
when `gam.cfg` had `timezone utc`. The API returns the start and end times expressed in the calendar timezone
but GAM replaced the timezone specifier with a `Z`; the date and time values were as expected. This became
a problem when event data was exported and used to create or update events.
6.65.02
Updated `gam print|show browsers` to handle the following error:
```
ERROR: 503: serviceNotAvailable - The service is currently unavailable.
```
6.65.01
Added option `showmimetypesize` to `gam <UserTypeEntity> print|show filecounts` and
`gam <UserTypeEntity> print filelist countsonly` that displays the total file size for each MIME type.
6.65.00
Fixed bug in `gam <UserTypeEntity> create contact <JSONData>` that caused a trap when
contacts were being copied from one user to another.
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-People-Contacts-Profiles#copy-user-contacts-to-another-user
Updated the following commands to allow specification of a task list by its title.
```
<TaskListTitle> ::= tltitle:<String>
<TasklistTitleList> ::= "'<TasklistTitle>'(,'<TasklistTitle>')*"
<TasklistEntity> ::=
<TasklistIDList> | <TaskListTitleList> | <FileSelector> | <CSVFileSelector>
gam <UserTypeEntity> create task <TasklistEntity>
gam <UserTypeEntity> show tasks [tasklists <TasklistEntity>]
gam <UserTypeEntity> print tasks [tasklists <TasklistEntity>]
gam <UserTypeEntity> update tasklist <TasklistEntity>
gam <UserTypeEntity> delete tasklist <TasklistEntity>
gam <UserTypeEntity> clear tasklist <TasklistEntity>
gam <UserTypeEntity> info tasklist <TasklistEntity>
```
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-Tasks#specifying-task-lists
6.64.16
Fixed bug in `gam <UserTypeEntity> create task <TasklistIDEntity>` that caused a trap
when an invalid TaskListID was specified.
6.64.15
Updated `lookerstudioassets|lookerstudiopermissions` commands to handle the following error:
```
ERROR: 500: internalError - Internal error encountered.
```
6.64.14
Cleaned up and renamed `gam info appdetails` to `gam info chromeapp`.
6.64.13
Added command to get chrome app details.
```
gam info appdetails android|chrome|web <AppID> [formatjson]
```
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Chrome-Installed-Apps
6.64.12
Upgraded to Python 3.12.0 where possible.
Upgraded to OpenSSL 3.1.3 where possible.
6.64.11
Added support for Google Workspace Labs license.
* ProductID - 101047
* SKUID - 1010470002 | gwlabs | workspacelabs
6.64.10
Fixed bug introduced in 6.64.09 that caused a trap when `gam redirect csv <FileName> multiprocess` was used.
6.64.09
Eliminated extraneous `permisssions.0.xxxx` headers in `gam <UserTypeEntity> print filelist ... oneitemperrow`
that appeared when some user in `<UserTypeEntity>` had no files to display.
6.64.08
Fixed bug in `redirect csv - todrive tdtitle "File Title" tdsheettitle "Sheet Title"` where
"Sheet Title" was not assigned to the new sheet.
6.64.07
Updated `gam <UserTypeEntity> move drivefile` to handle the following error:
```
ERROR: 403: targetUserRoleLimitedByLicenseRestriction - Cannot set the requested role for that user as they lack the necessary license
```
6.64.06
Added fields `devicelicensetype` and `osupdatestatus` to `<CrOSFieldName>`.
6.64.05
Added `matchfield organizerself <Boolean>` to `<EventMatchProperty>` to simplify selecting events
where the user in the following commands is/is not the organizer of the event.
```
gam <UserTypeEntity> update events <UserCalendarEntity> [<EventEntity>]
gam <UserTypeEntity> delete events <UserCalendarEntity> [<EventEntity>]
gam <UserTypeEntity> purge events <UserCalendarEntity> [<EventEntity>]
gam <UserTypeEntity> move events <UserCalendarEntity> [<EventEntity>]
gam <UserTypeEntity> info events <UserCalendarEntity> [<EventEntity>]
gam <UserTypeEntity> show events <UserCalendarEntity> [<EventEntity>]
gam <UserTypeEntity> print events <UserCalendarEntity> [<EventEntity>]
gam <UserTypeEntity> update calattendees <UserCalendarEntity> <EventEntity>
```
6.64.04
Updated `gam calendars <CalendarEntity> move events` and `gam <UserTypeEntity> move events <UserCalendarEntity>`
to handle the following error:
```
ERROR: 400: badRequest - Bad Request
```
6.64.03
Updated `gam <UserTypeEntity> get drivefile` to allow downloading Jamboard files; they must be downloaded with `format pdf`.
6.64.02
Updated `gam <UserTypeEntity> transfer drive` to handle the following error:
```
ERROR: 400: Bad Request. User message: "The action cannot be performed on an item of mime-type: application/vnd.google-apps.shortcut" - invalidSharingRequest
```
6.64.01
Updated `gam <UserTypeEntity> print|show youtubechannels` to handle the following error:
```
ERROR: 403: unsupportedSupervisedAccount - Access Forbidden. The authenticated user cannot access this service.
```
6.64.00
Added support for displaying users YouTube channels.
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-YouTube
6.63.19
Fixed bug in `gam print vacation` where `endDate` value was not converted to `yyyy-mm-dd` format.
6.63.18
Updated `gam print|show ownership` to show the correct file owner when the most recent event is `change_owner`.
6.63.17
Added support for Duet AI license.
* ProductID - 101047
* SKUID - 1010470001 | duetai
Added `api_call_tries_limit` variable to `gam.cfg` that limits the number of tries
for Google API calls that return an error that indicates a retry should be performed.
The default value is 10 and the range of allowable values is 3-10.
6.63.16
Arguments `noinherit`, `blockinheritance` and `blockinheritance true` have been removed from the following
commands due to an upcoming API change that no longer allows blocking OU setting inheritance.
Arguments `inherit` and `blockinheritance false` are still valid.
```
gam create org <OrgUnitPath>
gam update org <OrgUnitItem>
gam update orgs <OrgUnitEntity>
```
6.63.15
Added `print_cros_ous` and `print_cros_ous_and_children` variables to `gam.cfg` that provide a default list of OUs for these commands:
```
gam print cros
gam print crosactivity
```
Updated `group` commands that manage members to handle the following error:
```
ERROR: 503: serviceNotAvailable - The service is currently unavailable.
```
Updated Data Studio to Looker Studio; added the following command synonyms:
* `lookerstudioassets` for `datastudioassets`
* 'lookerstudiopermissions` for `datastudiopermissions`
Corrected error message in `gam add datastudiopermissions`:
* Old -`ERROR: Missing argument: Expected <DataStudioAssetMembersEntity>`
* New - `ERROR: Missing argument: Expected <LookerStudioPermissionEntity>
6.63.14
Added option `verifyorganizer [<Boolean>]` to `gam <UserTypeEntity> copy|move drivefile`. When a copy/move
operation involves a Shared Drive, GAM verifies that the user is an organizer. Unfortunatley, this fails
when the user is not a direct organizer but is a member of a group that is an organizer. Specifying
`verifyorganizer false` suppresses the verification.
Updated the following commands to be able to specify a list of domains rather than a single domain:
```
gam print alias|aliases
gam print groups
gam print|show group-members
gam print users
```
Added `print_agu_domains` variable to `gam.cfg` that provides a default list of domains for these commands.
When multiple domains are specified and a query/queries are specified, an API call is made for each domain/query combination.
```
$ gam print users domains school.org,students.school.org queries "'email:admin*','email:test*'"
Getting all Users that match query (domain=school.org, query="email:admin*"), may take some time on a large Google Workspace Account...
Got 3 Users: admin@school.org - admindirector@school.org
Getting all Users that match query (domain=school.org, query="email:test*"), may take some time on a large Google Workspace Account...
Got 20 Users: testusera@school.org - testuserx@school.org
Getting all Users that match query (domain=students.school.org, query="email:admin*"), may take some time on a large Google Workspace Account...
Got 1 User: admin@students.school.org - admin@students.school.org
Getting all Users that match query (domain=students.school.org, query="email:test*"), may take some time on a large Google Workspace Account...
Got 1 User: testuser1@students.school.org - testuser1@students.school.org
primaryEmail
...
```
6.63.13
Updated `gam <UserTypeEntity> print filelist ... showdrivename` and `gam <UserTypeEntity> show fileinfo <DriveFileEntity> ... showdrivename`
to show the actual name of Shared Drives in other domains rather than `Drive`.
6.63.12
Updated commands that call the Reports API (including `gam info domain`) to handle a change
in the Reports API that generated the following warning:
```
WARNING: End date greater than LastReportedDate.
```
Added option `showdeleted [<Boolean>]' to `gam <UserTypeEntity> print|show chatmessages`.
6.63.11
Added option `ou_and_children <OrgUnitItem>` to `gam print|show crostelemetry` to simplify getting
telemetry data for all ChromeOS devices in an OU and its children.
6.63.10
Added option `addcsvdata <FieldName> <String>` to these commands. This adds additional columns of data to the CSV file output
when the `csv` option is used. If a CSV file of calendar information is being used to specify the calenders, fields, e.g., summary
can be added to the ACL output file.
```
gam <UserTypeEntity> print calendaracls <UserCalendarEntity>
gam resource <ResourceID> print calendaracls
gam resources <ResourceEntity> print calendaracls
gam calendar <CalendarEntity> printacl
gam calendars <CalendarEntity> print acls
```
Added commands to show the number of CrOS devices or Users in an entity.
```
gam <CrOSTypeEntity> show count
gam <UserTypeEntity> show count
```
Updated `gam create project` to prompt user to mark `GAM Project Creation` as a trusted app.
6.63.09
Updated `gam create teamdrive` to handle the following error:
```
ERROR: 403: userCannotCreateTeamDrives - The authenticated user cannot create new shared drives.
```
6.63.08
Updated `cigroup` commands to handle the following error:
```
ERROR: 400: invalidArgument - Request contains an invalid argument.
```
6.63.07
Fixed bug in `gam <UserTypeEntity> append sheetrange` that caused a trap when appending to an empty sheet.
Upgraded to Python 3.11.5 where possible.
6.63.06
Updated `cigroup` commands to handle the following error:
```
ERROR: 503: serviceNotAvailable - The service is currently unavailable.
```
6.63.05
Updated `inboundsso` commands to handle the following error:
```
ERROR: 503: serviceNotAvailable - The service is currently unavailable.
```
6.63.04
Added option `ignorerole` to `gam update groups|cigroups <GroupEntity> sync [<GroupRole>|ignorerole] ... <UserTypeEntity>` that causes GAM
to remove members regardless of role and add new members with role MEMBER. This is a special purpose option, use with caution
and ensure that `<UserTypeEntity>` specifies the full desired membership list of all roles.
6.63.03
Added option `externalusersallowed <Boolean>` to `gam <UserTypeEntity> create chatspace`
that allows creation of chat spaces that allow external users.
Updated commands that process chat members to allow external users.
6.63.02
Fixed bug in `gam <UserTypeEntity> collect orphans` where shortcuts were being created unnecessarily
when `useshortcuts` was false; either by default or when explicitly set.
6.63.01
Added `process_wait_limit` variable to `gam.cfg` that controls how long (in seconds) GAM should wait for all batch|csv processes to complete
after all have been started. If the limit is reached, GAM terminates any remaining processes. The default is 0 which specifies no limit.
Following Jay's lead, added option `alwaysevict` to `gam create|update user` that is used to specify GAM's
behavior when `verifynotinvitable` is not specified and there is a conflict with an unmanaged account.
By default, when creating a user that has a conflict with an unmanaged account, GAM will honor the setting on this page:
* https://admin.google.com/ac/accountsettings/conflictaccountmanagement
Specifying `alwaysevict` forces GAM to select this setting: `Replace conflicting unmanaged accounts with managed ones`
With `gam update user`, `alwaysevict` only applies if `createifnotfound` is specified and the user was not found to update and must be created.
6.63.00
Added support for calendar working location events.
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-Calendars-Events#working-location-events
6.62.08
Added option `addcsvdata <FieldName> <String>` to these commands. This adds additional columns of data to the CSV file output
when the `csv` option is used.
```
gam create contact
gam <UserTypeEntity> create contact
gam <UserTypeEntity> create contactgroup
```
6.62.07
Added option `csv [todrive <ToDriveAttribute>*]` to these commands that causes GAM to output
the contact creator and contact ID in CSV form. This will be useful when bulk contacts are created.
Added `returnidonly` to these commands that causes GAM to return just the
contact ID as output. This will be useful in scripts that create a contact and then
want to perform subsequent GAM commands on the contact.
```
gam create contact
gam <UserTypeEntity> create contact
gam <UserTypeEntity> create contactgroup
```
6.62.06
Added output `Item cap` to `gam <UserTypeEntity> print filecounts select select <SharedDriveEntity>` that
displays the total number of files/folders on the Shared Drive divided by 400000, the maximum number of file/folders on a Shared Drive.
6.62.05
Added progress messages (suppressible) to `gam <UserTypeEntity> print diskusage`.
@@ -4723,7 +5212,7 @@ Updated `gam [<UserTypeEntity>] create teamdrive <Name>` to output the name of t
Team Drive in addition to its ID.
```
$ gam user user@domain.com create teamdrive Test
User: user@domain.com, Shared Drive Name: Test, Shared Drive ID: 0ALHCDtCDTx_4Uk9PVA, Created
User: user@domain.com, Shared Drive Name: Test, Shared Drive ID: 0ALHCDtCDTx_4Uk9XYZ, Created
```
6.03.20

View File

@@ -818,16 +818,16 @@ smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited
# Subject: CN=COMODO Certification Authority O=COMODO CA Limited
# Label: "COMODO Certification Authority"
# Serial: 104350513648249232941998508985834464573
# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75
# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b
# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66
# Serial: 43390818032842818540635488309124489234
# MD5 Fingerprint: 20:E7:4F:82:C2:7E:94:80:34:82:8A:13:A9:17:1D:97
# SHA1 Fingerprint EE:86:93:87:FF:FD:83:49:AB:5A:D1:43:22:58:87:89:A4:57:B0:12
# SHA256 Fingerprint: 1A:0D:20:44:5D:E5:BA:18:62:D1:9E:F8:80:85:8C:BC:E5:01:02:B3:6E:8F:0A:04:0C:3C:69:E7:45:22:FE:6E
-----BEGIN CERTIFICATE-----
MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB
MIID0DCCArigAwIBAgIQIKTEf93f4cdTYwcTiHdgEjANBgkqhkiG9w0BAQUFADCB
gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV
BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw
MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl
BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xMTAxMDEwMDAw
MDBaFw0zMDEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl
YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P
RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0
aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3
@@ -836,16 +836,14 @@ UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI
Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp
+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+
DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O
nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW
/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g
PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u
QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY
SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv
IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4
zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd
BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB
ZQ==
nKVIrLsm9wIDAQABo0IwQDAdBgNVHQ4EFgQUC1jli8ZMFTekQKkwqSG+RzZaVv8w
DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
ggEBAC/JxBwHO89hAgCx2SFRdXIDMLDEFh9sAIsQrK/xR9SuEDwMGvjUk2ysEDd8
t6aDZK3N3w6HM503sMZ7OHKx8xoOo/lVem0DZgMXlUrxsXrfViEGQo+x06iF3u6X
HWLrp+cxEmbDD6ZLLkGC9/3JG6gbr+48zuOcrigHoSybJMIPIyaDMouGDx8rEkYl
Fo92kANr3ryqImhrjKGsKxE5pttwwn1y6TPn/CbxdFqR5p2ErPioBhlG5qfpqjQi
pKGfeq23sqSaM4hxAjwu1nqyH6LKwN0vEJT9s4yEIHlG1QXUEOTS22RPuFvuG8Ug
R1uUq27UlTMdphVx8fiUylQ5PsE=
-----END CERTIFICATE-----
# Operating CA: Sectigo

File diff suppressed because it is too large Load Diff

View File

@@ -32,6 +32,7 @@ CHAT_MESSAGES = 'chatmessages'
CHAT_SPACES = 'chatspaces'
CHAT_SPACES_DELETE = 'chatspacesdelete'
CHROMEMANAGEMENT = 'chromemanagement'
CHROMEMANAGEMENT_APPDETAILS = 'chromemanagementappdetails'
CHROMEMANAGEMENT_TELEMETRY = 'chromemanagementtelemetry'
CHROMEPOLICY = 'chromepolicy'
CHROMEVERSIONHISTORY = 'versionhistory'
@@ -47,7 +48,6 @@ CLOUDRESOURCEMANAGER = 'cloudresourcemanager'
CLOUDRESOURCEMANAGER_V1 = 'cloudresourcemanager1'
CONTACTS = 'contacts'
CONTACTDELEGATION = 'contactdelegation'
DATASTUDIO = 'datastudio'
DATATRANSFER = 'datatransfer'
DIRECTORY = 'directory'
DIRECTORY_BETA = 'directory_beta'
@@ -69,6 +69,7 @@ IAM_CREDENTIALS = 'iamcredentials'
IAP = 'iap'
KEEP = 'keep'
LICENSING = 'licensing'
LOOKERSTUDIO = 'datastudio'
OAUTH2 = 'oauth2'
PEOPLE = 'people'
PEOPLE_DIRECTORY = 'peopledirectory'
@@ -88,6 +89,7 @@ STORAGEREAD = 'storageread'
STORAGEWRITE = 'storagewrite'
TASKS = 'tasks'
VAULT = 'vault'
YOUTUBE = 'youtube'
#
CHROMEVERSIONHISTORY_URL = 'https://versionhistory.googleapis.com/v1/chrome/platforms'
DRIVE_SCOPE = 'https://www.googleapis.com/auth/drive'
@@ -177,6 +179,7 @@ PROJECT_APIS = [
'storage-api.googleapis.com',
'tasks.googleapis.com',
'vault.googleapis.com',
'youtube.googleapis.com',
]
_INFO = {
@@ -193,6 +196,7 @@ _INFO = {
CHAT_SPACES_DELETE: {'name': 'Chat API - Spaces Delete', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT},
CLASSROOM: {'name': 'Classroom API', 'version': 'v1', 'v2discovery': True},
CHROMEMANAGEMENT: {'name': 'Chrome Management API', 'version': 'v1', 'v2discovery': True},
CHROMEMANAGEMENT_APPDETAILS: {'name': 'Chrome Management API - AppDetails', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHROMEMANAGEMENT},
CHROMEMANAGEMENT_TELEMETRY: {'name': 'Chrome Management API - Telemetry', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHROMEMANAGEMENT},
CHROMEPOLICY: {'name': 'Chrome Policy API', 'version': 'v1', 'v2discovery': True},
CHROMEVERSIONHISTORY: {'name': 'Chrome Version History API', 'version': 'v1', 'v2discovery': True},
@@ -206,7 +210,6 @@ _INFO = {
CLOUDRESOURCEMANAGER: {'name': 'Cloud Resource Manager API v3', 'version': 'v3', 'v2discovery': True},
CONTACTS: {'name': 'Contacts API', 'version': 'v3', 'v2discovery': False},
CONTACTDELEGATION: {'name': 'Contact Delegation API', 'version': 'v1', 'v2discovery': True, 'localjson': True},
DATASTUDIO: {'name': 'Data Studio API', 'version': 'v1', 'v2discovery': True, 'localjson': True},
DATATRANSFER: {'name': 'Data Transfer API', 'version': 'datatransfer_v1', 'v2discovery': True, 'mappedAPI': 'admin'},
DIRECTORY: {'name': 'Directory API', 'version': 'directory_v1', 'v2discovery': True, 'mappedAPI': 'admin'},
DIRECTORY_BETA: {'name': 'Directory API', 'version': 'directory_v1.1beta1', 'v2discovery': True, 'mappedAPI': 'admin', 'localjson': True},
@@ -227,6 +230,7 @@ _INFO = {
IAP: {'name': 'Cloud Identity-Aware Proxy API', 'version': 'v1', 'v2discovery': True},
KEEP: {'name': 'Keep API', 'version': 'v1', 'v2discovery': True},
LICENSING: {'name': 'License Manager API', 'version': 'v1', 'v2discovery': True},
LOOKERSTUDIO: {'name': 'Looker Studio API', 'version': 'v1', 'v2discovery': True, 'localjson': True},
OAUTH2: {'name': 'OAuth2 API', 'version': 'v2', 'v2discovery': False},
PEOPLE: {'name': 'People API', 'version': 'v1', 'v2discovery': True},
PEOPLE_DIRECTORY: {'name': 'People Directory API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': PEOPLE},
@@ -246,6 +250,7 @@ _INFO = {
STORAGEWRITE: {'name': 'Cloud Storage API - Write', 'version': 'v1', 'v2discovery': True, 'mappedAPI': STORAGE},
TASKS: {'name': 'Tasks API', 'version': 'v1', 'v2discovery': True},
VAULT: {'name': 'Vault API', 'version': 'v1', 'v2discovery': True},
YOUTUBE: {'name': 'Youtube API', 'version': 'v3', 'v2discovery': True},
}
READONLY = ['readonly',]
@@ -263,6 +268,10 @@ _CLIENT_SCOPES = [
'api': CHROMEMANAGEMENT,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/chrome.management.reports.readonly'},
{'name': 'Chrome Management API - AppDetails read only',
'api': CHROMEMANAGEMENT_APPDETAILS,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/chrome.management.appdetails.readonly'},
{'name': 'Chrome Management API - Telemetry read only',
'api': CHROMEMANAGEMENT_TELEMETRY,
'subscopes': [],
@@ -546,10 +555,6 @@ _SVCACCT_SCOPES = [
# 'api': CONTACTS,
# 'subscopes': [],
# 'scope': 'https://www.google.com/m8/feeds'},
{'name': 'Data Studio API',
'api': DATASTUDIO,
'subscopes': READONLY,
'scope': 'https://www.googleapis.com/auth/datastudio'},
{'name': 'Drive API',
'api': DRIVE3,
'subscopes': READONLY,
@@ -598,6 +603,10 @@ _SVCACCT_SCOPES = [
'api': KEEP,
'subscopes': READONLY,
'scope': 'https://www.googleapis.com/auth/keep'},
{'name': 'Looker Studio API',
'api': LOOKERSTUDIO,
'subscopes': READONLY,
'scope': 'https://www.googleapis.com/auth/datastudio'},
{'name': 'OAuth2 API',
'api': OAUTH2,
'subscopes': [],
@@ -626,6 +635,10 @@ _SVCACCT_SCOPES = [
'api': TASKS,
'subscopes': READONLY,
'scope': 'https://www.googleapis.com/auth/tasks'},
{'name': 'Youtube API - read only',
'api': YOUTUBE,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/youtube.readonly'},
]
_SVCACCT_SPECIAL_SCOPES = [

View File

@@ -50,6 +50,8 @@ ADMIN_EMAIL = 'admin_email'
API_CALLS_RATE_CHECK = 'api_calls_rate_check'
# API calls per 100 seconds limit
API_CALLS_RATE_LIMIT = 'api_calls_rate_limit'
# API calls tries limit
API_CALLS_TRIES_LIMIT = 'api_calls_tries_limit'
# Automatically generate gam batch command if number of users specified in gam users xxx command exceeds this number
# Default: 0, do not automatically generate gam batch commands
AUTO_BATCH_MIN = 'auto_batch_min'
@@ -198,6 +200,14 @@ OUTPUT_DATEFORMAT = 'output_dateformat'
OUTPUT_TIMEFORMAT = 'output_timeformat'
# When retrieving lists of people from API, how many should be retrieved in each chunk
PEOPLE_MAX_RESULTS = 'people_max_results'
# Domains for print alises|groups|users
PRINT_AGU_DOMAINS = 'print_agu_domains'
# OrgUnits for print cros
PRINT_CROS_OUS = 'print_cros_ous'
# OrgUnits and children for print cros
PRINT_CROS_OUS_AND_CHILDREN = 'print_cros_ous_and_children'
# Number of seconds to wait for batch/csv processes to complete
PROCESS_WAIT_LIMIT = 'process_wait_limit'
# Use quick method to move Chromebooks to OU
QUICK_CROS_MOVE = 'quick_cros_move'
# Quick info user: nogroups nolicenses noschemas
@@ -289,6 +299,7 @@ Defaults = {
ADMIN_EMAIL: '',
API_CALLS_RATE_CHECK: FALSE,
API_CALLS_RATE_LIMIT: '100',
API_CALLS_TRIES_LIMIT: '10',
AUTO_BATCH_MIN: '0',
BAIL_ON_INTERNAL_ERROR_TRIES: '2',
BATCH_SIZE: '50',
@@ -361,6 +372,10 @@ Defaults = {
OUTPUT_DATEFORMAT: '',
OUTPUT_TIMEFORMAT: '',
PEOPLE_MAX_RESULTS: '100',
PRINT_AGU_DOMAINS: '',
PRINT_CROS_OUS: '',
PRINT_CROS_OUS_AND_CHILDREN: '',
PROCESS_WAIT_LIMIT: '0',
QUICK_CROS_MOVE: FALSE,
QUICK_INFO_USER: FALSE,
RESELLER_ID: '',
@@ -436,6 +451,7 @@ VAR_INFO = {
ADMIN_EMAIL: {VAR_TYPE: TYPE_STRING, VAR_ENVVAR: 'GA_ADMIN_EMAIL', VAR_LIMITS: (0, None)},
API_CALLS_RATE_CHECK: {VAR_TYPE: TYPE_BOOLEAN},
API_CALLS_RATE_LIMIT: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (50, None)},
API_CALLS_TRIES_LIMIT: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (3, 10)},
AUTO_BATCH_MIN: {VAR_TYPE: TYPE_INTEGER, VAR_ENVVAR: 'GAM_AUTOBATCH', VAR_LIMITS: (0, 100)},
BAIL_ON_INTERNAL_ERROR_TRIES: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 10)},
BATCH_SIZE: {VAR_TYPE: TYPE_INTEGER, VAR_ENVVAR: 'GAM_BATCH_SIZE', VAR_LIMITS: (1, 1000)},
@@ -508,6 +524,10 @@ VAR_INFO = {
OUTPUT_DATEFORMAT: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)},
OUTPUT_TIMEFORMAT: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)},
PEOPLE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (0, 1000)},
PRINT_AGU_DOMAINS: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)},
PRINT_CROS_OUS: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)},
PRINT_CROS_OUS_AND_CHILDREN: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)},
PROCESS_WAIT_LIMIT: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (0, None)},
QUICK_CROS_MOVE: {VAR_TYPE: TYPE_BOOLEAN},
QUICK_INFO_USER: {VAR_TYPE: TYPE_BOOLEAN},
RESELLER_ID: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)},

View File

@@ -428,6 +428,7 @@ class GamCLArgs():
ARG_APIS = 'apis'
ARG_APIPROJECT = 'apiproject'
ARG_APPACCESSSETTINGS = 'appaccesssettings'
ARG_APPDETAILS = 'appdetails'
ARG_APPLICATIONSPECIFICPASSWORDS = 'applicationspecificpasswords'
ARG_ASP = 'asp'
ARG_ASPS = 'asps'
@@ -468,6 +469,7 @@ class GamCLArgs():
ARG_CHATSPACE = 'chatspace'
ARG_CHATSPACES = 'chatspaces'
ARG_CHATSPACEDM = 'chatspacedm'
ARG_CHROMEAPP = 'chromeapp'
ARG_CHROMEAPPS = 'chromeapps'
ARG_CHROMEAPPDEVICES = 'chromeappdevices'
ARG_CHROMEAUES = 'chromeaues'
@@ -503,6 +505,8 @@ class GamCLArgs():
ARG_CONTACTGROUPS = 'contactgroups'
ARG_CONTACTPHOTO = 'contactphoto'
ARG_CONTACTPHOTOS = 'contactphotos'
ARG_COUNT = 'count'
ARG_COUNTS = 'counts'
ARG_COURSE = 'course'
ARG_COURSES = 'courses'
ARG_COURSEANNOUNCEMENTS = 'courseannouncements'
@@ -521,6 +525,10 @@ class GamCLArgs():
ARG_DATASTUDIOASSETS = 'datastudioassets'
ARG_DATASTUDIOPERMISSION = 'datastudiopermission'
ARG_DATASTUDIOPERMISSIONS = 'datastudiopermissions'
ARG_LOOKERSTUDIOASSET = 'lookerstudioasset'
ARG_LOOKERSTUDIOASSETS = 'lookerstudioassets'
ARG_LOOKERSTUDIOPERMISSION = 'lookerstudiopermission'
ARG_LOOKERSTUDIOPERMISSIONS = 'lookerstudiopermissions'
ARG_DATATRANSFER = 'datatransfer'
ARG_DATATRANSFERS = 'datatransfers'
ARG_DELEGATE = 'delegate'
@@ -578,6 +586,8 @@ class GamCLArgs():
ARG_FILETREE = 'filetree'
ARG_FILTER = 'filter'
ARG_FILTERS = 'filters'
ARG_FOCUSTIME = 'focustime'
ARG_FOCUSTIMES = 'focustimes'
ARG_FORM = 'form'
ARG_FORMS = 'forms'
ARG_FORMRESPONSE = 'formresponse'
@@ -659,6 +669,8 @@ class GamCLArgs():
ARG_OUS = 'ous'
ARG_OUSHAREDDRIVE = 'oushareddrive'
ARG_OUSHAREDDRIVES = 'oushareddrives'
ARG_OUTOFOFFICE = 'outofoffice'
ARG_OUTOFOFFICES = 'outofoffices'
ARG_OUTREE = 'outree'
ARG_OWNERSHIP = 'ownership'
ARG_PARTICIPANTS = 'participants'
@@ -771,6 +783,8 @@ class GamCLArgs():
ARG_VERIFY = 'verify'
ARG_WORKINGLOCATION = 'workinglocation'
ARG_WORKINGLOCATIONS = 'workinglocations'
ARG_YOUTUBECHANNEL = 'youtubechannel'
ARG_YOUTUBECHANNELS = 'youtubechannels'
# Lists of arguments for use in checkArgumentPresent
CLEAR_NONE_ARGUMENT = ['clear', 'none',]
@@ -832,7 +846,6 @@ class GamCLArgs():
OB_CROS_ENTITY = 'CrOSEntity'
OB_CUSTOMER_ID = 'CustomerID'
OB_CUSTOMER_AUTH_TOKEN = 'CustomerAuthToken'
OB_DATASTUDIO_ASSET_MEMBERS_ENTITY = 'DataStudioAssetMembersEntity'
OB_DEVICE_FILE_ENTITY = 'DeviceFileEntity'
OB_DEVICE_ENTITY = 'DeviceEntity'
OB_DEVICE_ID = 'DeviceID'
@@ -901,6 +914,7 @@ class GamCLArgs():
OB_LABEL_NAME_LIST = 'LabelNameList'
OB_LABEL_REPLACEMENT = 'LabelReplacement'
OB_LANGUAGE_LIST = 'LanguageList'
OB_LOOKERSTUDIO_PERMISSION_ENTITY = 'LookerStudioPermissionEntity'
OB_MATTER_ITEM = 'MatterItem'
OB_MATTER_ITEM_LIST = 'MatterItemList'
OB_MESSAGE_ID = 'MessageID'
@@ -979,6 +993,7 @@ class GamCLArgs():
OB_USER_ENTITY = 'UserEntity'
OB_USER_ITEM = 'UserItem'
OB_USER_NAME = 'UserName'
OB_YOUTUBE_CHANNEL_ID_LIST = 'YouTubeChannelIDlist'
#
# Error message types; keys into ARGUMENT_ERROR_NAMES; arbitrary values but must be unique

View File

@@ -31,6 +31,7 @@ class GamEntity():
ROLE_MEMBER_OWNER = ','.join([ROLE_MEMBER, ROLE_OWNER])
ROLE_MANAGER_MEMBER_OWNER = ','.join([ROLE_MANAGER, ROLE_MEMBER, ROLE_OWNER])
ROLE_PUBLIC = 'PUBLIC'
ROLE_ALL = ROLE_MANAGER_MEMBER_OWNER
TYPE_CUSTOMER = 'CUSTOMER'
TYPE_EXTERNAL = 'EXTERNAL'
@@ -148,11 +149,6 @@ class GamEntity():
CROS_SERIAL_NUMBER = 'crsn'
CUSTOMER_DOMAIN = 'cudo'
CUSTOMER_ID = 'cuid'
DATASTUDIO_ASSET = 'dsas'
DATASTUDIO_ASSET_DATASOURCE = 'dsad'
DATASTUDIO_ASSETID = 'dsai'
DATASTUDIO_ASSET_REPORT = 'dsar'
DATASTUDIO_PERMISSION = 'dspe'
DATE = 'date'
DEFAULT_LANGUAGE = 'dfla'
DELEGATE = 'dele'
@@ -205,6 +201,9 @@ class GamEntity():
END_TIME = 'endt'
ENTITY = 'enti'
EVENT = 'evnt'
EVENT_FOCUSTIME = 'evft'
EVENT_OUTOFOFFICE = 'evoo'
EVENT_WORKINGLOCATION = 'evwl'
FEATURE = 'feat'
FIELD = 'fiel'
FILE = 'file'
@@ -240,6 +239,11 @@ class GamEntity():
LANGUAGE = 'lang'
LICENSE = 'lice'
LOCATION = 'loca'
LOOKERSTUDIO_ASSET = 'lsas'
LOOKERSTUDIO_ASSET_DATASOURCE = 'lsad'
LOOKERSTUDIO_ASSETID = 'lsai'
LOOKERSTUDIO_ASSET_REPORT = 'lsar'
LOOKERSTUDIO_PERMISSION = 'lspe'
MD5HASH = 'md5h'
MEMBER = 'memb'
MEMBER_NOT_ARCHIVED = 'mena'
@@ -361,7 +365,7 @@ class GamEntity():
VAULT_OPERATION = 'vlto'
VAULT_QUERY = 'vltq'
WEBCLIPS_ENABLED = 'webc'
WORKING_LOCATION = 'wrkl'
YOUTUBE_CHANNEL = 'ytch'
# _NAMES[0] is plural, _NAMES[1] is singular unless the item name is explicitly plural (Calendar Settings)
# For items with Boolean values, both entries are singular (Forward, POP)
# These values can be translated into other languages
@@ -474,11 +478,6 @@ class GamEntity():
CROS_SERIAL_NUMBER: ['CrOS Serial Numbers', 'CrOS Serial Numbers'],
CUSTOMER_DOMAIN: ['Customer Domains', 'Customer Domain'],
CUSTOMER_ID: ['Customer IDs', 'Customer ID'],
DATASTUDIO_ASSET: ['Data Studio Assets', 'Data Studio Asset'],
DATASTUDIO_ASSET_DATASOURCE: ['Data Studio DATA_SOURCE Assets', 'Data Studio DATA_SOURCE Asset'],
DATASTUDIO_ASSETID: ['Data Studio Asset IDs', 'Data Studio Asset ID'],
DATASTUDIO_ASSET_REPORT: ['Data Studio REPORT Assets', 'Data Studio REPORT Asset'],
DATASTUDIO_PERMISSION: ['Data Studio Permissions', 'Data Studio Permission'],
DATE: ['Dates', 'Date'],
DEFAULT_LANGUAGE: ['Default Language', 'Default Language'],
DELEGATE: ['Delegates', 'Delegate'],
@@ -531,6 +530,9 @@ class GamEntity():
END_TIME: ['End Times', 'End Time'],
ENTITY: ['Entities', 'Entity'],
EVENT: ['Events', 'Event'],
EVENT_FOCUSTIME: ['Focus Time Events', 'Focus Time Event'],
EVENT_OUTOFOFFICE: ['Out of Office Events', 'Out of Office Event'],
EVENT_WORKINGLOCATION: ['Working Location Events', 'Working Location Event'],
FEATURE: ['Features', 'Feature'],
FIELD: ['Fields', 'Field'],
FILE: ['Files', 'File'],
@@ -566,6 +568,11 @@ class GamEntity():
LANGUAGE: ['Languages', 'Language'],
LICENSE: ['Licenses', 'License'],
LOCATION: ['Locations', 'Location'],
LOOKERSTUDIO_ASSET: ['Looker Studio Assets', 'Looker Studio Asset'],
LOOKERSTUDIO_ASSET_DATASOURCE: ['Looker Studio DATA_SOURCE Assets', 'Looker Studio DATA_SOURCE Asset'],
LOOKERSTUDIO_ASSETID: ['Looker Studio Asset IDs', 'Looker Studio Asset ID'],
LOOKERSTUDIO_ASSET_REPORT: ['Looker Studio REPORT Assets', 'Looker Studio REPORT Asset'],
LOOKERSTUDIO_PERMISSION: ['Looker Studio Permissions', 'Looker Studio Permission'],
MD5HASH: ['MD5 hash', 'MD5 Hash'],
MEMBER: ['Members', 'Member'],
MEMBER_NOT_ARCHIVED: ['Members (Not Archived)', 'Member (Not Archived)'],
@@ -687,10 +694,11 @@ class GamEntity():
VAULT_OPERATION: ['Vault Operations', 'Vault Operation'],
VAULT_QUERY: ['Vault Queries', 'Vault Query'],
WEBCLIPS_ENABLED: ['Web Clips Enabled', 'Web Clips Enabled'],
WORKING_LOCATION: ['Working Locations', 'Working Location'],
YOUTUBE_CHANNEL: ['YouTube Channels', 'YouTube Channel'],
ROLE_MANAGER: ['Managers', 'Manager'],
ROLE_MEMBER: ['Members', 'Member'],
ROLE_OWNER: ['Owners', 'Owner'],
ROLE_ALL: ['Members, Managers, Owners', 'Member, Manager, Owner'],
ROLE_USER: ['Users', 'User'],
ROLE_MANAGER_MEMBER: ['Members, Managers', 'Member, Manager'],
ROLE_MANAGER_OWNER: ['Managers, Owners', 'Manager, Owner'],

View File

@@ -52,6 +52,7 @@ CANNOT_SHARE_TEAMDRIVE_WITH_NONGOOGLE_ACCOUNTS = 'cannotShareTeamDriveWithNonGoo
CANNOT_UPDATE_PERMISSION = 'cannotUpdatePermission'
CONDITION_NOT_MET = 'conditionNotMet'
CONFLICT = 'conflict'
CONTENT_OWNER_ACCOUNT_NOT_FOUND = 'contentOwnerAccountNotFound'
CROSS_DOMAIN_MOVE_RESTRICTION = 'crossDomainMoveRestriction'
CUSTOMER_EXCEEDED_ROLE_ASSIGNMENTS_LIMIT = 'CUSTOMER_EXCEEDED_ROLE_ASSIGNMENTS_LIMIT'
CUSTOMER_NOT_FOUND = 'customerNotFound'
@@ -164,33 +165,37 @@ TEAMDRIVES_SHORTCUT_FILE_NOT_SUPPORTED = 'teamDrivesShortcutFileNotSupported'
TIME_RANGE_EMPTY = 'timeRangeEmpty'
TRANSIENT_ERROR = 'transientError'
UNKNOWN_ERROR = 'unknownError'
UNSUPPORTED_LANGUAGE_CODE = 'unsupportedLanguageCode'
UNSUPPORTED_SUPERVISED_ACCOUNT = 'unsupportedSupervisedAccount'
UPLOAD_TOO_LARGE = 'uploadTooLarge'
USER_CANNOT_CREATE_TEAMDRIVES = 'userCannotCreateTeamDrives'
USER_ACCESS = 'userAccess'
USER_NOT_FOUND = 'userNotFound'
USER_RATE_LIMIT_EXCEEDED = 'userRateLimitExceeded'
#
DEFAULT_RETRY_REASONS = [QUOTA_EXCEEDED, RATE_LIMIT_EXCEEDED, SHARING_RATE_LIMIT_EXCEEDED, USER_RATE_LIMIT_EXCEEDED,
BACKEND_ERROR, BAD_GATEWAY, GATEWAY_TIMEOUT, INTERNAL_ERROR, TRANSIENT_ERROR]
SERVICE_NOT_AVAILABLE_RETRY_REASONS = [SERVICE_NOT_AVAILABLE]
ACTIVITY_THROW_REASONS = [SERVICE_NOT_AVAILABLE, BAD_REQUEST]
ALERT_THROW_REASONS = [SERVICE_NOT_AVAILABLE, AUTH_ERROR]
CALENDAR_THROW_REASONS = [SERVICE_NOT_AVAILABLE, AUTH_ERROR, NOT_A_CALENDAR_USER]
CIGROUP_CREATE_THROW_REASONS = [ALREADY_EXISTS, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, INVALID, INVALID_ARGUMENT, PERMISSION_DENIED]
CIGROUP_GET_THROW_REASONS = [NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, BAD_REQUEST, INVALID, SYSTEM_ERROR, PERMISSION_DENIED]
CIGROUP_LIST_THROW_REASONS = [RESOURCE_NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, BAD_REQUEST, INVALID, SYSTEM_ERROR, PERMISSION_DENIED]
CIGROUP_CREATE_THROW_REASONS = [SERVICE_NOT_AVAILABLE, ALREADY_EXISTS, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, INVALID, INVALID_ARGUMENT, PERMISSION_DENIED]
CIGROUP_GET_THROW_REASONS = [SERVICE_NOT_AVAILABLE, NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, BAD_REQUEST, INVALID, SYSTEM_ERROR, PERMISSION_DENIED]
CIGROUP_LIST_THROW_REASONS = [SERVICE_NOT_AVAILABLE, RESOURCE_NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, BAD_REQUEST, INVALID, INVALID_ARGUMENT, SYSTEM_ERROR, PERMISSION_DENIED]
CIGROUP_LIST_USERKEY_THROW_REASONS = CIGROUP_LIST_THROW_REASONS+[INVALID_ARGUMENT]
CIGROUP_UPDATE_THROW_REASONS = [NOT_FOUND, GROUP_NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS,
CIGROUP_UPDATE_THROW_REASONS = [SERVICE_NOT_AVAILABLE, NOT_FOUND, GROUP_NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS,
FORBIDDEN, BAD_REQUEST, INVALID, INVALID_INPUT, INVALID_ARGUMENT,
SYSTEM_ERROR, PERMISSION_DENIED, FAILED_PRECONDITION]
CIMEMBERS_THROW_REASONS = [MEMBER_NOT_FOUND, INVALID_MEMBER]
CISSO_CREATE_THROW_REASONS = [FAILED_PRECONDITION, NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, INVALID, INVALID_ARGUMENT, PERMISSION_DENIED, INTERNAL_ERROR]
CISSO_GET_THROW_REASONS = [NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, BAD_REQUEST, INVALID, SYSTEM_ERROR, PERMISSION_DENIED, INTERNAL_ERROR]
CISSO_LIST_THROW_REASONS = [NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, BAD_REQUEST, INVALID, SYSTEM_ERROR, PERMISSION_DENIED, INTERNAL_ERROR]
CISSO_UPDATE_THROW_REASONS = [NOT_FOUND, FAILED_PRECONDITION, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS,
CIGROUP_RETRY_REASONS = [INVALID, SYSTEM_ERROR, SERVICE_NOT_AVAILABLE]
CIMEMBERS_THROW_REASONS = [SERVICE_NOT_AVAILABLE, MEMBER_NOT_FOUND, INVALID_MEMBER]
CISSO_CREATE_THROW_REASONS = [SERVICE_NOT_AVAILABLE, FAILED_PRECONDITION, NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, INVALID, INVALID_ARGUMENT, PERMISSION_DENIED, INTERNAL_ERROR]
CISSO_GET_THROW_REASONS = [SERVICE_NOT_AVAILABLE, NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, BAD_REQUEST, INVALID, SYSTEM_ERROR, PERMISSION_DENIED, INTERNAL_ERROR]
CISSO_LIST_THROW_REASONS = [SERVICE_NOT_AVAILABLE, NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, BAD_REQUEST, INVALID, SYSTEM_ERROR, PERMISSION_DENIED, INTERNAL_ERROR]
CISSO_UPDATE_THROW_REASONS = [SERVICE_NOT_AVAILABLE, NOT_FOUND, FAILED_PRECONDITION, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS,
FORBIDDEN, BAD_REQUEST, INVALID, INVALID_INPUT, INVALID_ARGUMENT,
SYSTEM_ERROR, PERMISSION_DENIED, INTERNAL_ERROR]
CONTACT_DELEGATE_THROW_REASONS = [SERVICE_NOT_AVAILABLE, BAD_REQUEST, FAILED_PRECONDITION, PERMISSION_DENIED, FORBIDDEN, INVALID_ARGUMENT]
COURSE_ACCESS_THROW_REASONS = [NOT_FOUND, INSUFFICIENT_PERMISSIONS, PERMISSION_DENIED, FORBIDDEN, INVALID_ARGUMENT]
DATASTUDIO_THROW_REASONS = [INVALID_ARGUMENT, SERVICE_NOT_AVAILABLE, BAD_REQUEST, NOT_FOUND, PERMISSION_DENIED]
DRIVE_USER_THROW_REASONS = [SERVICE_NOT_AVAILABLE, AUTH_ERROR, DOMAIN_POLICY]
DRIVE_ACCESS_THROW_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, FORBIDDEN, INTERNAL_ERROR, INSUFFICIENT_FILE_PERMISSIONS, UNKNOWN_ERROR, INVALID]
DRIVE_COPY_THROW_REASONS = DRIVE_ACCESS_THROW_REASONS+[CANNOT_COPY_FILE, BAD_REQUEST, RESPONSE_PREPARATION_FAILURE, TEAMDRIVES_SHARING_RESTRICTION_NOT_ALLOWED,
@@ -250,7 +255,8 @@ GROUP_SETTINGS_RETRY_REASONS = [INVALID, SERVICE_LIMIT, SERVICE_NOT_AVAILABLE]
GROUP_LIST_THROW_REASONS = [RESOURCE_NOT_FOUND, DOMAIN_NOT_FOUND, FORBIDDEN, BAD_REQUEST]
GROUP_LIST_USERKEY_THROW_REASONS = GROUP_LIST_THROW_REASONS+[INVALID_MEMBER, INVALID_INPUT]
KEEP_THROW_REASONS = [SERVICE_NOT_AVAILABLE, BAD_REQUEST, PERMISSION_DENIED, INVALID_ARGUMENT, NOT_FOUND]
MEMBERS_THROW_REASONS = [GROUP_NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, INVALID, FORBIDDEN]
LOOKERSTUDIO_THROW_REASONS = [INVALID_ARGUMENT, SERVICE_NOT_AVAILABLE, BAD_REQUEST, NOT_FOUND, PERMISSION_DENIED, INTERNAL_ERROR]
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]
@@ -259,6 +265,7 @@ SHEETS_ACCESS_THROW_REASONS = DRIVE_USER_THROW_REASONS+[NOT_FOUND, PERMISSION_DE
TASK_THROW_REASONS = [SERVICE_NOT_AVAILABLE, BAD_REQUEST, PERMISSION_DENIED, INVALID, NOT_FOUND, ACCESS_NOT_CONFIGURED]
TASKLIST_THROW_REASONS = [SERVICE_NOT_AVAILABLE, BAD_REQUEST, PERMISSION_DENIED, INVALID, NOT_FOUND, ACCESS_NOT_CONFIGURED]
USER_GET_THROW_REASONS = [USER_NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, BAD_REQUEST, SYSTEM_ERROR]
YOUTUBE_THROW_REASONS = [SERVICE_NOT_AVAILABLE, AUTH_ERROR, UNSUPPORTED_SUPERVISED_ACCOUNT, UNSUPPORTED_LANGUAGE_CODE, CONTENT_OWNER_ACCOUNT_NOT_FOUND]
REASON_MESSAGE_MAP = {
ABORTED: [
@@ -389,6 +396,8 @@ class conditionNotMet(Exception):
pass
class conflict(Exception):
pass
class contentOwnerAccountNotFound(Exception):
pass
class crossDomainMoveRestriction(Exception):
pass
class customerExceededRoleAssignmentsLimit(Exception):
@@ -609,8 +618,14 @@ class transientError(Exception):
pass
class unknownError(Exception):
pass
class unsupportedLanguageCode(Exception):
pass
class unsupportedSupervisedAccount(Exception):
pass
class uploadTooLarge(Exception):
pass
class userCannotCreateTeamDrives(Exception):
pass
class userAccess(Exception):
pass
class userNotFound(Exception):
@@ -650,6 +665,7 @@ REASON_EXCEPTION_MAP = {
CANNOT_UPDATE_PERMISSION: cannotUpdatePermission,
CONDITION_NOT_MET: conditionNotMet,
CONFLICT: conflict,
CONTENT_OWNER_ACCOUNT_NOT_FOUND: contentOwnerAccountNotFound,
CROSS_DOMAIN_MOVE_RESTRICTION: crossDomainMoveRestriction,
CUSTOMER_EXCEEDED_ROLE_ASSIGNMENTS_LIMIT: customerExceededRoleAssignmentsLimit,
CUSTOMER_NOT_FOUND: customerNotFound,
@@ -760,7 +776,10 @@ REASON_EXCEPTION_MAP = {
TIME_RANGE_EMPTY: timeRangeEmpty,
TRANSIENT_ERROR: transientError,
UNKNOWN_ERROR: unknownError,
UNSUPPORTED_LANGUAGE_CODE: unsupportedLanguageCode,
UNSUPPORTED_SUPERVISED_ACCOUNT: unsupportedSupervisedAccount,
UPLOAD_TOO_LARGE: uploadTooLarge,
USER_CANNOT_CREATE_TEAMDRIVES: userCannotCreateTeamDrives,
USER_ACCESS: userAccess,
USER_NOT_FOUND: userNotFound,
USER_RATE_LIMIT_EXCEEDED: userRateLimitExceeded,

View File

@@ -156,6 +156,12 @@ OUTPUT_TIMEFORMAT = 'outf'
PARSER = 'pars'
# Process ID
PID = 'pid '
# Domains for print alises|groups|users
PRINT_AGU_DOMAINS = 'pagu'
# OrgUnits for print cros
PRINT_CROS_OUS = 'pcou'
# OrgUnits and children for print cros
PRINT_CROS_OUS_AND_CHILDREN = 'pcoc'
# Check API calls rate
RATE_CHECK_COUNT = 'rccn'
RATE_CHECK_START = 'rcst'
@@ -269,6 +275,9 @@ Globals = {
OUTPUT_TIMEFORMAT: '',
PARSER: None,
PID: 0,
PRINT_AGU_DOMAINS: '',
PRINT_CROS_OUS: '',
PRINT_CROS_OUS_AND_CHILDREN: '',
RATE_CHECK_COUNT: 0,
RATE_CHECK_START: 0,
SECTION: None,

View File

@@ -72,7 +72,7 @@ Is not a valid Client Secret.
Please make sure you are following the directions exactly and that there are no extra spaces in your Client Secret.
'''
TRUST_GAM_CLIENT_ID = '''
Now it's important to mark the GAM Client ID as trusted by your Workspace instance.
It's important to mark the {0} Client ID as trusted by your Workspace instance.
Please go to:
@@ -81,13 +81,14 @@ Please go to:
1. Click on: Add app > OAuth App Name Or Client ID.
2. Enter the following Client ID value:
{0}
{1}
3. Press Search, select the GAM app, press Select, check the box and press Select.
3. Press Search, select the {0} app, press Select, check the box and press Select.
4. Keep the default scope or select a preferred scope that includes your GAM admin.
5. Press Continue
6. Select Trusted radio button, press Continue and Finish.
7. Press enter once trust is complete.'
7. Press Confirm if Confirm parental consent pops up
8. Press enter here on the terminal once trust is complete.
'''
YOUR_GAM_PROJECT_IS_CREATED_AND_READY_TO_USE = 'That\'s it! Your GAM Project is created and ready to use.\n'
@@ -162,8 +163,10 @@ BAD_ENTITIES_IN_SOURCE = '{0} {1} {2} in source marked >>> <<< above'
BAD_REQUEST = 'Bad Request'
BATCH = 'Batch'
BATCH_CSV_LOOP_DASH_DEBUG_INCOMPATIBLE = '"gam {0} - ..." is not compatible with debugging. Disable debugging by setting debug_level = 0 in gam.cfg'
BATCH_CSV_WAIT_N_PROCESSES = '{0},0/{1},Waiting for {2} running {3} to finish before terminating\n'
BATCH_CSV_PROCESSING_COMPLETE = '{0},0/{1},Processing complete\n'
BATCH_CSV_TERMINATE_N_PROCESSES = '{0},0/{1},Terminating {2} running {3}\n'
BATCH_CSV_WAIT_LIMIT = ', wait limit {0} seconds'
BATCH_CSV_WAIT_N_PROCESSES = '{0},0/{1},Waiting for {2} running {3} to finish before terminating{4}\n'
BATCH_NOT_PROCESSED_ERRORS = '{0}batch file: {1}, not processed, {2} {3}\n'
CALLING_GCLOUD_FOR_REAUTH = 'Calling gcloud for reauth credentials..."\n'
CAN_NOT_DELETE_USER_WITH_VAULT_HOLD = '{0}: The user may be (or have recently been) on Google Vault Hold and thus not eligible for deletion. You can check holds with "gam user {1} show vaultholds".'
@@ -435,6 +438,7 @@ STRING_LENGTH = 'string length'
SUBKEY_FIELD_MISMATCH = 'subkeyfield {0} does not match saved subkeyfield {1}'
SUBSCRIPTION_NOT_FOUND = 'Could not find subscription'
SUFFIX_NOT_ALLOWED_WITH_CUSTOMLANGUAGE = 'Suffix {0} not allowed with customLanguage {1}'
TASKLIST_TITLE_NOT_FOUND = 'Task list title not found'
THREAD = 'thread'
THREADS = 'threads'
TO = 'To'
@@ -460,6 +464,7 @@ UPDATE_USER_PASSWORD_CHANGE_NOTIFY_SUBJECT = 'Account #user# password has been c
UPLOAD_CSV_FILE_INTERNAL_ERROR = 'Google reported "{0}" but the file was probably uploaded, check that it has {1} rows'
UPLOADING_NEW_PUBLIC_CERTIFICATE_TO_GOOGLE = 'Uploading new public certificate to Google...\n'
URL_ERROR = 'URL error: {0}'
USE_MIMETYPE_TO_SPECIFY_GOOGLE_FORMAT = 'Use "mimetype <MimeType>" to specify Google file format\n'
USED = 'Used'
USER_BELONGS_TO_N_GROUPS_THAT_MAP_TO_ORGUNITS = 'User belongs to {0} groups ({1}) that map to OUs'
USER_CANCELLED = 'User cancelled'

View File

@@ -33,6 +33,8 @@ _PRODUCTS = {
'101038': 'AppSheet',
'101039': 'Assured Controls',
'101040': 'Beyond Corp Enterprise',
'101043': 'Google Workspace Additional Storage',
'101047': 'Duet AI',
'Google-Apps': 'Google Workspace',
'Google-Chrome-Device-Management': 'Google Chrome Device Management',
'Google-Drive-storage': 'Google Drive Storage',
@@ -81,6 +83,12 @@ _SKUS = {
'product': '101039', 'aliases': ['assuredcontrols'], 'displayName': 'Assured Controls'},
'1010400001': {
'product': '101040', 'aliases': ['beyondcorp', 'beyondcorpenterprise', 'bce'], 'displayName': 'Beyond Corp Enterprise'},
'1010430001': {
'product': '101043', 'aliases': ['gwas', 'plusstorage'], 'displayName': 'Google Workspace Additional Storage'},
'1010470001': {
'product': '101047', 'aliases': ['duetai'], 'displayName': 'Duet AI for Enterprise'},
'1010470002': {
'product': '101047', 'aliases': ['gwlabs', 'workspacelabs'], 'displayName': 'Google Workspace Labs'},
'Google-Apps': {
'product': 'Google-Apps', 'aliases': ['standard', 'free'], 'displayName': 'G Suite Legacy'},
'Google-Apps-For-Business': {
@@ -108,7 +116,7 @@ _SKUS = {
'product': 'Google-Apps', 'aliases': ['wes', 'wsentstarter', 'workspaceenterprisestarter'], 'displayName': 'Workspace Enterprise Starter'},
'1010020030': {
'product': 'Google-Apps', 'aliases': ['wsflw', 'workspacefrontline', 'workspacefrontlineworker'], 'displayName': 'Google Workspace Frontline Starter'},
'1010020031`': {
'1010020031': {
'product': 'Google-Apps', 'aliases': ['wsflwstan', 'workspacefrontlinestan', 'workspacefrontlineworkerstan'], 'displayName': 'Google Workspace Frontline Standard'},
'1010340001': {
'product': '101034', 'aliases': ['gseau', 'enterprisearchived', 'gsuiteenterprisearchived'], 'displayName': 'Google Workspace Enterprise Plus - Archived User'},

View File

@@ -1,952 +0,0 @@
#!/usr/bin/python
#
# Copyright (C) 2007 - 2009 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import cgi
import math
import random
import re
import time
import types
import urllib.request, urllib.parse, urllib.error
import atom.http_interface
import atom.token_store
import atom.url
import gdata.oauth as oauth
import gdata.oauth.rsa as oauth_rsa
import gdata.tlslite.utils.keyfactory as keyfactory
from base64 import encodebytes
import gdata.gauth
__author__ = 'api.jscudder (Jeff Scudder)'
PROGRAMMATIC_AUTH_LABEL = 'GoogleLogin auth='
AUTHSUB_AUTH_LABEL = 'AuthSub token='
"""This module provides functions and objects used with Google authentication.
Details on Google authorization mechanisms used with the Google Data APIs can
be found here:
http://code.google.com/apis/gdata/auth.html
http://code.google.com/apis/accounts/
The essential functions are the following.
Related to ClientLogin:
generate_client_login_request_body: Constructs the body of an HTTP request to
obtain a ClientLogin token for a specific
service.
extract_client_login_token: Creates a ClientLoginToken with the token from a
success response to a ClientLogin request.
get_captcha_challenge: If the server responded to the ClientLogin request
with a CAPTCHA challenge, this method extracts the
CAPTCHA URL and identifying CAPTCHA token.
Related to AuthSub:
generate_auth_sub_url: Constructs a full URL for a AuthSub request. The
user's browser must be sent to this Google Accounts
URL and redirected back to the app to obtain the
AuthSub token.
extract_auth_sub_token_from_url: Once the user's browser has been
redirected back to the web app, use this
function to create an AuthSubToken with
the correct authorization token and scope.
token_from_http_body: Extracts the AuthSubToken value string from the
server's response to an AuthSub session token upgrade
request.
"""
def generate_client_login_request_body(email, password, service, source,
account_type='HOSTED_OR_GOOGLE', captcha_token=None,
captcha_response=None):
"""Creates the body of the autentication request
See http://code.google.com/apis/accounts/AuthForInstalledApps.html#Request
for more details.
Args:
email: str
password: str
service: str
source: str
account_type: str (optional) Defaul is 'HOSTED_OR_GOOGLE', other valid
values are 'GOOGLE' and 'HOSTED'
captcha_token: str (optional)
captcha_response: str (optional)
Returns:
The HTTP body to send in a request for a client login token.
"""
return gdata.gauth.generate_client_login_request_body(email, password,
service, source, account_type, captcha_token, captcha_response)
GenerateClientLoginRequestBody = generate_client_login_request_body
def GenerateClientLoginAuthToken(http_body):
"""Returns the token value to use in Authorization headers.
Reads the token from the server's response to a Client Login request and
creates header value to use in requests.
Args:
http_body: str The body of the server's HTTP response to a Client Login
request
Returns:
The value half of an Authorization header.
"""
token = get_client_login_token(http_body)
if token:
return 'GoogleLogin auth=%s' % token
return None
def get_client_login_token(http_body):
"""Returns the token value for a ClientLoginToken.
Reads the token from the server's response to a Client Login request and
creates the token value string to use in requests.
Args:
http_body: str The body of the server's HTTP response to a Client Login
request
Returns:
The token value string for a ClientLoginToken.
"""
return gdata.gauth.get_client_login_token_string(http_body)
def extract_client_login_token(http_body, scopes):
"""Parses the server's response and returns a ClientLoginToken.
Args:
http_body: str The body of the server's HTTP response to a Client Login
request. It is assumed that the login request was successful.
scopes: list containing atom.url.Urls or strs. The scopes list contains
all of the partial URLs under which the client login token is
valid. For example, if scopes contains ['http://example.com/foo']
then the client login token would be valid for
http://example.com/foo/bar/baz
Returns:
A ClientLoginToken which is valid for the specified scopes.
"""
token_string = get_client_login_token(http_body)
token = ClientLoginToken(scopes=scopes)
token.set_token_string(token_string)
return token
def get_captcha_challenge(http_body,
captcha_base_url='http://www.google.com/accounts/'):
"""Returns the URL and token for a CAPTCHA challenge issued by the server.
Args:
http_body: str The body of the HTTP response from the server which
contains the CAPTCHA challenge.
captcha_base_url: str This function returns a full URL for viewing the
challenge image which is built from the server's response. This
base_url is used as the beginning of the URL because the server
only provides the end of the URL. For example the server provides
'Captcha?ctoken=Hi...N' and the URL for the image is
'http://www.google.com/accounts/Captcha?ctoken=Hi...N'
Returns:
A dictionary containing the information needed to repond to the CAPTCHA
challenge, the image URL and the ID token of the challenge. The
dictionary is in the form:
{'token': string identifying the CAPTCHA image,
'url': string containing the URL of the image}
Returns None if there was no CAPTCHA challenge in the response.
"""
return gdata.gauth.get_captcha_challenge(http_body, captcha_base_url)
GetCaptchaChallenge = get_captcha_challenge
def GenerateOAuthRequestTokenUrl(
oauth_input_params, scopes,
request_token_url='https://www.google.com/accounts/OAuthGetRequestToken',
extra_parameters=None):
"""Generate a URL at which a request for OAuth request token is to be sent.
Args:
oauth_input_params: OAuthInputParams OAuth input parameters.
scopes: list of strings The URLs of the services to be accessed.
request_token_url: string The beginning of the request token URL. This is
normally 'https://www.google.com/accounts/OAuthGetRequestToken' or
'/accounts/OAuthGetRequestToken'
extra_parameters: dict (optional) key-value pairs as any additional
parameters to be included in the URL and signature while making a
request for fetching an OAuth request token. All the OAuth parameters
are added by default. But if provided through this argument, any
default parameters will be overwritten. For e.g. a default parameter
oauth_version 1.0 can be overwritten if
extra_parameters = {'oauth_version': '2.0'}
Returns:
atom.url.Url OAuth request token URL.
"""
scopes_string = ' '.join([str(scope) for scope in scopes])
parameters = {'scope': scopes_string}
if extra_parameters:
parameters.update(extra_parameters)
oauth_request = oauth.OAuthRequest.from_consumer_and_token(
oauth_input_params.GetConsumer(), http_url=request_token_url,
parameters=parameters)
oauth_request.sign_request(oauth_input_params.GetSignatureMethod(),
oauth_input_params.GetConsumer(), None)
return atom.url.parse_url(oauth_request.to_url())
def GenerateOAuthAuthorizationUrl(
request_token,
authorization_url='https://www.google.com/accounts/OAuthAuthorizeToken',
callback_url=None, extra_params=None,
include_scopes_in_callback=False, scopes_param_prefix='oauth_token_scope'):
"""Generates URL at which user will login to authorize the request token.
Args:
request_token: gdata.auth.OAuthToken OAuth request token.
authorization_url: string The beginning of the authorization URL. This is
normally 'https://www.google.com/accounts/OAuthAuthorizeToken' or
'/accounts/OAuthAuthorizeToken'
callback_url: string (optional) The URL user will be sent to after
logging in and granting access.
extra_params: dict (optional) Additional parameters to be sent.
include_scopes_in_callback: Boolean (default=False) if set to True, and
if 'callback_url' is present, the 'callback_url' will be modified to
include the scope(s) from the request token as a URL parameter. The
key for the 'callback' URL's scope parameter will be
OAUTH_SCOPE_URL_PARAM_NAME. The benefit of including the scope URL as
a parameter to the 'callback' URL, is that the page which receives
the OAuth token will be able to tell which URLs the token grants
access to.
scopes_param_prefix: string (default='oauth_token_scope') The URL
parameter key which maps to the list of valid scopes for the token.
This URL parameter will be included in the callback URL along with
the scopes of the token as value if include_scopes_in_callback=True.
Returns:
atom.url.Url OAuth authorization URL.
"""
scopes = request_token.scopes
if isinstance(scopes, list):
scopes = ' '.join(scopes)
if include_scopes_in_callback and callback_url:
if callback_url.find('?') > -1:
callback_url += '&'
else:
callback_url += '?'
callback_url += urllib.parse.urlencode({scopes_param_prefix:scopes})
oauth_token = oauth.OAuthToken(request_token.key, request_token.secret)
oauth_request = oauth.OAuthRequest.from_token_and_callback(
token=oauth_token, callback=callback_url,
http_url=authorization_url, parameters=extra_params)
return atom.url.parse_url(oauth_request.to_url())
def GenerateOAuthAccessTokenUrl(
authorized_request_token,
oauth_input_params,
access_token_url='https://www.google.com/accounts/OAuthGetAccessToken',
oauth_version='1.0',
oauth_verifier=None):
"""Generates URL at which user will login to authorize the request token.
Args:
authorized_request_token: gdata.auth.OAuthToken OAuth authorized request
token.
oauth_input_params: OAuthInputParams OAuth input parameters.
access_token_url: string The beginning of the authorization URL. This is
normally 'https://www.google.com/accounts/OAuthGetAccessToken' or
'/accounts/OAuthGetAccessToken'
oauth_version: str (default='1.0') oauth_version parameter.
oauth_verifier: str (optional) If present, it is assumed that the client
will use the OAuth v1.0a protocol which includes passing the
oauth_verifier (as returned by the SP) in the access token step.
Returns:
atom.url.Url OAuth access token URL.
"""
oauth_token = oauth.OAuthToken(authorized_request_token.key,
authorized_request_token.secret)
parameters = {'oauth_version': oauth_version}
if oauth_verifier is not None:
parameters['oauth_verifier'] = oauth_verifier
oauth_request = oauth.OAuthRequest.from_consumer_and_token(
oauth_input_params.GetConsumer(), token=oauth_token,
http_url=access_token_url, parameters=parameters)
oauth_request.sign_request(oauth_input_params.GetSignatureMethod(),
oauth_input_params.GetConsumer(), oauth_token)
return atom.url.parse_url(oauth_request.to_url())
def GenerateAuthSubUrl(next, scope, secure=False, session=True,
request_url='https://www.google.com/accounts/AuthSubRequest',
domain='default'):
"""Generate a URL at which the user will login and be redirected back.
Users enter their credentials on a Google login page and a token is sent
to the URL specified in next. See documentation for AuthSub login at:
http://code.google.com/apis/accounts/AuthForWebApps.html
Args:
request_url: str The beginning of the request URL. This is normally
'http://www.google.com/accounts/AuthSubRequest' or
'/accounts/AuthSubRequest'
next: string The URL user will be sent to after logging in.
scope: string The URL of the service to be accessed.
secure: boolean (optional) Determines whether or not the issued token
is a secure token.
session: boolean (optional) Determines whether or not the issued token
can be upgraded to a session token.
domain: str (optional) The Google Apps domain for this account. If this
is not a Google Apps account, use 'default' which is the default
value.
"""
# Translate True/False values for parameters into numeric values acceoted
# by the AuthSub service.
if secure:
secure = 1
else:
secure = 0
if session:
session = 1
else:
session = 0
request_params = urllib.parse.urlencode({'next': next, 'scope': scope,
'secure': secure, 'session': session,
'hd': domain})
if request_url.find('?') == -1:
return '%s?%s' % (request_url, request_params)
else:
# The request URL already contained url parameters so we should add
# the parameters using the & seperator
return '%s&%s' % (request_url, request_params)
def generate_auth_sub_url(next, scopes, secure=False, session=True,
request_url='https://www.google.com/accounts/AuthSubRequest',
domain='default', scopes_param_prefix='auth_sub_scopes'):
"""Constructs a URL string for requesting a multiscope AuthSub token.
The generated token will contain a URL parameter to pass along the
requested scopes to the next URL. When the Google Accounts page
redirects the broswser to the 'next' URL, it appends the single use
AuthSub token value to the URL as a URL parameter with the key 'token'.
However, the information about which scopes were requested is not
included by Google Accounts. This method adds the scopes to the next
URL before making the request so that the redirect will be sent to
a page, and both the token value and the list of scopes can be
extracted from the request URL.
Args:
next: atom.url.URL or string The URL user will be sent to after
authorizing this web application to access their data.
scopes: list containint strings The URLs of the services to be accessed.
secure: boolean (optional) Determines whether or not the issued token
is a secure token.
session: boolean (optional) Determines whether or not the issued token
can be upgraded to a session token.
request_url: atom.url.Url or str The beginning of the request URL. This
is normally 'http://www.google.com/accounts/AuthSubRequest' or
'/accounts/AuthSubRequest'
domain: The domain which the account is part of. This is used for Google
Apps accounts, the default value is 'default' which means that the
requested account is a Google Account (@gmail.com for example)
scopes_param_prefix: str (optional) The requested scopes are added as a
URL parameter to the next URL so that the page at the 'next' URL can
extract the token value and the valid scopes from the URL. The key
for the URL parameter defaults to 'auth_sub_scopes'
Returns:
An atom.url.Url which the user's browser should be directed to in order
to authorize this application to access their information.
"""
if isinstance(next, str):
next = atom.url.parse_url(next)
scopes_string = ' '.join([str(scope) for scope in scopes])
next.params[scopes_param_prefix] = scopes_string
if isinstance(request_url, str):
request_url = atom.url.parse_url(request_url)
request_url.params['next'] = str(next)
request_url.params['scope'] = scopes_string
if session:
request_url.params['session'] = 1
else:
request_url.params['session'] = 0
if secure:
request_url.params['secure'] = 1
else:
request_url.params['secure'] = 0
request_url.params['hd'] = domain
return request_url
def AuthSubTokenFromUrl(url):
"""Extracts the AuthSub token from the URL.
Used after the AuthSub redirect has sent the user to the 'next' page and
appended the token to the URL. This function returns the value to be used
in the Authorization header.
Args:
url: str The URL of the current page which contains the AuthSub token as
a URL parameter.
"""
token = TokenFromUrl(url)
if token:
return 'AuthSub token=%s' % token
return None
def TokenFromUrl(url):
"""Extracts the AuthSub token from the URL.
Returns the raw token value.
Args:
url: str The URL or the query portion of the URL string (after the ?) of
the current page which contains the AuthSub token as a URL parameter.
"""
if url.find('?') > -1:
query_params = url.split('?')[1]
else:
query_params = url
for pair in query_params.split('&'):
if pair.startswith('token='):
return pair[6:]
return None
def extract_auth_sub_token_from_url(url,
scopes_param_prefix='auth_sub_scopes', rsa_key=None):
"""Creates an AuthSubToken and sets the token value and scopes from the URL.
After the Google Accounts AuthSub pages redirect the user's broswer back to
the web application (using the 'next' URL from the request) the web app must
extract the token from the current page's URL. The token is provided as a
URL parameter named 'token' and if generate_auth_sub_url was used to create
the request, the token's valid scopes are included in a URL parameter whose
name is specified in scopes_param_prefix.
Args:
url: atom.url.Url or str representing the current URL. The token value
and valid scopes should be included as URL parameters.
scopes_param_prefix: str (optional) The URL parameter key which maps to
the list of valid scopes for the token.
Returns:
An AuthSubToken with the token value from the URL and set to be valid for
the scopes passed in on the URL. If no scopes were included in the URL,
the AuthSubToken defaults to being valid for no scopes. If there was no
'token' parameter in the URL, this function returns None.
"""
if isinstance(url, str):
url = atom.url.parse_url(url)
if 'token' not in url.params:
return None
scopes = []
if scopes_param_prefix in url.params:
scopes = url.params[scopes_param_prefix].split(' ')
token_value = url.params['token']
if rsa_key:
token = SecureAuthSubToken(rsa_key, scopes=scopes)
else:
token = AuthSubToken(scopes=scopes)
token.set_token_string(token_value)
return token
def AuthSubTokenFromHttpBody(http_body):
"""Extracts the AuthSub token from an HTTP body string.
Used to find the new session token after making a request to upgrade a
single use AuthSub token.
Args:
http_body: str The repsonse from the server which contains the AuthSub
key. For example, this function would find the new session token
from the server's response to an upgrade token request.
Returns:
The header value to use for Authorization which contains the AuthSub
token.
"""
token_value = token_from_http_body(http_body)
if token_value:
return '%s%s' % (AUTHSUB_AUTH_LABEL, token_value)
return None
def token_from_http_body(http_body):
"""Extracts the AuthSub token from an HTTP body string.
Used to find the new session token after making a request to upgrade a
single use AuthSub token.
Args:
http_body: str The repsonse from the server which contains the AuthSub
key. For example, this function would find the new session token
from the server's response to an upgrade token request.
Returns:
The raw token value to use in an AuthSubToken object.
"""
for response_line in http_body.splitlines():
if response_line.startswith('Token='):
# Strip off Token= and return the token value string.
return response_line[6:]
return None
TokenFromHttpBody = token_from_http_body
def OAuthTokenFromUrl(url, scopes_param_prefix='oauth_token_scope'):
"""Creates an OAuthToken and sets token key and scopes (if present) from URL.
After the Google Accounts OAuth pages redirect the user's broswer back to
the web application (using the 'callback' URL from the request) the web app
can extract the token from the current page's URL. The token is same as the
request token, but it is either authorized (if user grants access) or
unauthorized (if user denies access). The token is provided as a
URL parameter named 'oauth_token' and if it was chosen to use
GenerateOAuthAuthorizationUrl with include_scopes_in_param=True, the token's
valid scopes are included in a URL parameter whose name is specified in
scopes_param_prefix.
Args:
url: atom.url.Url or str representing the current URL. The token value
and valid scopes should be included as URL parameters.
scopes_param_prefix: str (optional) The URL parameter key which maps to
the list of valid scopes for the token.
Returns:
An OAuthToken with the token key from the URL and set to be valid for
the scopes passed in on the URL. If no scopes were included in the URL,
the OAuthToken defaults to being valid for no scopes. If there was no
'oauth_token' parameter in the URL, this function returns None.
"""
if isinstance(url, str):
url = atom.url.parse_url(url)
if 'oauth_token' not in url.params:
return None
scopes = []
if scopes_param_prefix in url.params:
scopes = url.params[scopes_param_prefix].split(' ')
token_key = url.params['oauth_token']
token = OAuthToken(key=token_key, scopes=scopes)
return token
def OAuthTokenFromHttpBody(http_body):
"""Parses the HTTP response body and returns an OAuth token.
The returned OAuth token will just have key and secret parameters set.
It won't have any knowledge about the scopes or oauth_input_params. It is
your responsibility to make it aware of the remaining parameters.
Returns:
OAuthToken OAuth token.
"""
token = oauth.OAuthToken.from_string(http_body)
oauth_token = OAuthToken(key=token.key, secret=token.secret)
return oauth_token
class OAuthSignatureMethod(object):
"""Holds valid OAuth signature methods.
RSA_SHA1: Class to build signature according to RSA-SHA1 algorithm.
HMAC_SHA1: Class to build signature according to HMAC-SHA1 algorithm.
"""
HMAC_SHA1 = oauth.OAuthSignatureMethod_HMAC_SHA1
class RSA_SHA1(oauth_rsa.OAuthSignatureMethod_RSA_SHA1):
"""Provides implementation for abstract methods to return RSA certs."""
def __init__(self, private_key, public_cert):
self.private_key = private_key
self.public_cert = public_cert
def _fetch_public_cert(self, unused_oauth_request):
return self.public_cert
def _fetch_private_cert(self, unused_oauth_request):
return self.private_key
class OAuthInputParams(object):
"""Stores OAuth input parameters.
This class is a store for OAuth input parameters viz. consumer key and secret,
signature method and RSA key.
"""
def __init__(self, signature_method, consumer_key, consumer_secret=None,
rsa_key=None, requestor_id=None):
"""Initializes object with parameters required for using OAuth mechanism.
NOTE: Though consumer_secret and rsa_key are optional, either of the two
is required depending on the value of the signature_method.
Args:
signature_method: class which provides implementation for strategy class
oauth.oauth.OAuthSignatureMethod. Signature method to be used for
signing each request. Valid implementations are provided as the
constants defined by gdata.auth.OAuthSignatureMethod. Currently
they are gdata.auth.OAuthSignatureMethod.RSA_SHA1 and
gdata.auth.OAuthSignatureMethod.HMAC_SHA1. Instead of passing in
the strategy class, you may pass in a string for 'RSA_SHA1' or
'HMAC_SHA1'. If you plan to use OAuth on App Engine (or another
WSGI environment) I recommend specifying signature method using a
string (the only options are 'RSA_SHA1' and 'HMAC_SHA1'). In these
environments there are sometimes issues with pickling an object in
which a member references a class or function. Storing a string to
refer to the signature method mitigates complications when
pickling.
consumer_key: string Domain identifying third_party web application.
consumer_secret: string (optional) Secret generated during registration.
Required only for HMAC_SHA1 signature method.
rsa_key: string (optional) Private key required for RSA_SHA1 signature
method.
requestor_id: string (optional) User email adress to make requests on
their behalf. This parameter should only be set when performing
2 legged OAuth requests.
"""
if (signature_method == OAuthSignatureMethod.RSA_SHA1
or signature_method == 'RSA_SHA1'):
self.__signature_strategy = 'RSA_SHA1'
elif (signature_method == OAuthSignatureMethod.HMAC_SHA1
or signature_method == 'HMAC_SHA1'):
self.__signature_strategy = 'HMAC_SHA1'
else:
self.__signature_strategy = signature_method
self.rsa_key = rsa_key
self._consumer = oauth.OAuthConsumer(consumer_key, consumer_secret)
self.requestor_id = requestor_id
def __get_signature_method(self):
if self.__signature_strategy == 'RSA_SHA1':
return OAuthSignatureMethod.RSA_SHA1(self.rsa_key, None)
elif self.__signature_strategy == 'HMAC_SHA1':
return OAuthSignatureMethod.HMAC_SHA1()
else:
return self.__signature_strategy()
def __set_signature_method(self, signature_method):
if (signature_method == OAuthSignatureMethod.RSA_SHA1
or signature_method == 'RSA_SHA1'):
self.__signature_strategy = 'RSA_SHA1'
elif (signature_method == OAuthSignatureMethod.HMAC_SHA1
or signature_method == 'HMAC_SHA1'):
self.__signature_strategy = 'HMAC_SHA1'
else:
self.__signature_strategy = signature_method
_signature_method = property(__get_signature_method, __set_signature_method,
doc="""Returns object capable of signing the request using RSA of HMAC.
Replaces the _signature_method member to avoid pickle errors.""")
def GetSignatureMethod(self):
"""Gets the OAuth signature method.
Returns:
object of supertype <oauth.oauth.OAuthSignatureMethod>
"""
return self._signature_method
def GetConsumer(self):
"""Gets the OAuth consumer.
Returns:
object of type <oauth.oauth.Consumer>
"""
return self._consumer
class ClientLoginToken(atom.http_interface.GenericToken):
"""Stores the Authorization header in auth_header and adds to requests.
This token will add it's Authorization header to an HTTP request
as it is made. Ths token class is simple but
some Token classes must calculate portions of the Authorization header
based on the request being made, which is why the token is responsible
for making requests via an http_client parameter.
Args:
auth_header: str The value for the Authorization header.
scopes: list of str or atom.url.Url specifying the beginnings of URLs
for which this token can be used. For example, if scopes contains
'http://example.com/foo', then this token can be used for a request to
'http://example.com/foo/bar' but it cannot be used for a request to
'http://example.com/baz'
"""
def __init__(self, auth_header=None, scopes=None):
self.auth_header = auth_header
self.scopes = scopes or []
def __str__(self):
return self.auth_header
def perform_request(self, http_client, operation, url, data=None,
headers=None):
"""Sets the Authorization header and makes the HTTP request."""
if headers is None:
headers = {'Authorization':self.auth_header}
else:
headers['Authorization'] = self.auth_header
return http_client.request(operation, url, data=data, headers=headers)
def get_token_string(self):
"""Removes PROGRAMMATIC_AUTH_LABEL to give just the token value."""
return self.auth_header[len(PROGRAMMATIC_AUTH_LABEL):]
def set_token_string(self, token_string):
self.auth_header = '%s%s' % (PROGRAMMATIC_AUTH_LABEL, token_string)
def valid_for_scope(self, url):
"""Tells the caller if the token authorizes access to the desired URL.
"""
if isinstance(url, str):
url = atom.url.parse_url(url)
for scope in self.scopes:
if scope == atom.token_store.SCOPE_ALL:
return True
if isinstance(scope, str):
scope = atom.url.parse_url(scope)
if scope == url:
return True
# Check the host and the path, but ignore the port and protocol.
elif scope.host == url.host and not scope.path:
return True
elif scope.host == url.host and scope.path and not url.path:
continue
elif scope.host == url.host and url.path.startswith(scope.path):
return True
return False
class AuthSubToken(ClientLoginToken):
def get_token_string(self):
"""Removes AUTHSUB_AUTH_LABEL to give just the token value."""
return self.auth_header[len(AUTHSUB_AUTH_LABEL):]
def set_token_string(self, token_string):
self.auth_header = '%s%s' % (AUTHSUB_AUTH_LABEL, token_string)
class OAuthToken(atom.http_interface.GenericToken):
"""Stores the token key, token secret and scopes for which token is valid.
This token adds the authorization header to each request made. It
re-calculates authorization header for every request since the OAuth
signature to be added to the authorization header is dependent on the
request parameters.
Attributes:
key: str The value for the OAuth token i.e. token key.
secret: str The value for the OAuth token secret.
scopes: list of str or atom.url.Url specifying the beginnings of URLs
for which this token can be used. For example, if scopes contains
'http://example.com/foo', then this token can be used for a request to
'http://example.com/foo/bar' but it cannot be used for a request to
'http://example.com/baz'
oauth_input_params: OAuthInputParams OAuth input parameters.
"""
def __init__(self, key=None, secret=None, scopes=None,
oauth_input_params=None):
self.key = key
self.secret = secret
self.scopes = scopes or []
self.oauth_input_params = oauth_input_params
def __str__(self):
return self.get_token_string()
def get_token_string(self):
"""Returns the token string.
The token string returned is of format
oauth_token=[0]&oauth_token_secret=[1], where [0] and [1] are some strings.
Returns:
A token string of format oauth_token=[0]&oauth_token_secret=[1],
where [0] and [1] are some strings. If self.secret is absent, it just
returns oauth_token=[0]. If self.key is absent, it just returns
oauth_token_secret=[1]. If both are absent, it returns None.
"""
if self.key and self.secret:
return urllib.parse.urlencode({'oauth_token': self.key,
'oauth_token_secret': self.secret})
elif self.key:
return 'oauth_token=%s' % self.key
elif self.secret:
return 'oauth_token_secret=%s' % self.secret
else:
return None
def set_token_string(self, token_string):
"""Sets the token key and secret from the token string.
Args:
token_string: str Token string of form
oauth_token=[0]&oauth_token_secret=[1]. If oauth_token is not present,
self.key will be None. If oauth_token_secret is not present,
self.secret will be None.
"""
token_params = cgi.parse_qs(token_string, keep_blank_values=False)
if 'oauth_token' in token_params:
self.key = token_params['oauth_token'][0]
if 'oauth_token_secret' in token_params:
self.secret = token_params['oauth_token_secret'][0]
def GetAuthHeader(self, http_method, http_url, realm=''):
"""Get the authentication header.
Args:
http_method: string HTTP method i.e. operation e.g. GET, POST, PUT, etc.
http_url: string or atom.url.Url HTTP URL to which request is made.
realm: string (default='') realm parameter to be included in the
authorization header.
Returns:
dict Header to be sent with every subsequent request after
authentication.
"""
if isinstance(http_url, str):
http_url = atom.url.parse_url(http_url)
header = None
token = None
if self.key or self.secret:
token = oauth.OAuthToken(self.key, self.secret)
oauth_request = oauth.OAuthRequest.from_consumer_and_token(
self.oauth_input_params.GetConsumer(), token=token,
http_url=str(http_url), http_method=http_method,
parameters=http_url.params)
oauth_request.sign_request(self.oauth_input_params.GetSignatureMethod(),
self.oauth_input_params.GetConsumer(), token)
header = oauth_request.to_header(realm=realm)
header['Authorization'] = header['Authorization'].replace('+', '%2B')
return header
def perform_request(self, http_client, operation, url, data=None,
headers=None):
"""Sets the Authorization header and makes the HTTP request."""
if not headers:
headers = {}
if self.oauth_input_params.requestor_id:
url.params['xoauth_requestor_id'] = self.oauth_input_params.requestor_id
headers.update(self.GetAuthHeader(operation, url))
return http_client.request(operation, url, data=data, headers=headers)
def valid_for_scope(self, url):
if isinstance(url, str):
url = atom.url.parse_url(url)
for scope in self.scopes:
if scope == atom.token_store.SCOPE_ALL:
return True
if isinstance(scope, str):
scope = atom.url.parse_url(scope)
if scope == url:
return True
# Check the host and the path, but ignore the port and protocol.
elif scope.host == url.host and not scope.path:
return True
elif scope.host == url.host and scope.path and not url.path:
continue
elif scope.host == url.host and url.path.startswith(scope.path):
return True
return False
class SecureAuthSubToken(AuthSubToken):
"""Stores the rsa private key, token, and scopes for the secure AuthSub token.
This token adds the authorization header to each request made. It
re-calculates authorization header for every request since the secure AuthSub
signature to be added to the authorization header is dependent on the
request parameters.
Attributes:
rsa_key: string The RSA private key in PEM format that the token will
use to sign requests
token_string: string (optional) The value for the AuthSub token.
scopes: list of str or atom.url.Url specifying the beginnings of URLs
for which this token can be used. For example, if scopes contains
'http://example.com/foo', then this token can be used for a request to
'http://example.com/foo/bar' but it cannot be used for a request to
'http://example.com/baz'
"""
def __init__(self, rsa_key, token_string=None, scopes=None):
self.rsa_key = keyfactory.parsePEMKey(rsa_key)
self.token_string = token_string or ''
self.scopes = scopes or []
def __str__(self):
return self.get_token_string()
def get_token_string(self):
return str(self.token_string)
def set_token_string(self, token_string):
self.token_string = token_string
def GetAuthHeader(self, http_method, http_url):
"""Generates the Authorization header.
The form of the secure AuthSub Authorization header is
Authorization: AuthSub token="token" sigalg="sigalg" data="data" sig="sig"
and data represents a string in the form
data = http_method http_url timestamp nonce
Args:
http_method: string HTTP method i.e. operation e.g. GET, POST, PUT, etc.
http_url: string or atom.url.Url HTTP URL to which request is made.
Returns:
dict Header to be sent with every subsequent request after authentication.
"""
timestamp = int(math.floor(time.time()))
nonce = '%lu' % random.randrange(1, 2**64)
data = '%s %s %d %s' % (http_method, str(http_url), timestamp, nonce)
sig = encodebytes(str(self.rsa_key.hashAndSign(data))).rstrip()
header = {'Authorization': '%s"%s" data="%s" sig="%s" sigalg="rsa-sha1"' %
(AUTHSUB_AUTH_LABEL, self.token_string, data, sig)}
return header
def perform_request(self, http_client, operation, url, data=None,
headers=None):
"""Sets the Authorization header and makes the HTTP request."""
if not headers:
headers = {}
headers.update(self.GetAuthHeader(operation, url))
return http_client.request(operation, url, data=data, headers=headers)

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +0,0 @@
1. Moved oauth.py to __init__.py
2. Refactored __init__.py for compatibility with python 2.2 (Issue 59)
3. Refactored rsa.py for compatibility with python 2.2 (Issue 59)
4. Refactored OAuthRequest.from_token_and_callback since the callback url was
getting double url-encoding the callback url in place of single. (Issue 43)
5. Added build_signature_base_string method to rsa.py since it used the
implementation of this method from oauth.OAuthSignatureMethod_HMAC_SHA1 which
was incorrect since it enforced the presence of a consumer secret and a token
secret. Also, changed its super class from oauth.OAuthSignatureMethod_HMAC_SHA1
to oauth.OAuthSignatureMethod (Issue 64)
6. Refactored <OAuthRequest>.to_header method since it returned non-oauth params
as well which was incorrect. (Issue 31)

View File

@@ -1,524 +0,0 @@
import cgi
import urllib.request, urllib.parse, urllib.error
import time
import random
import urllib.parse
import hmac
import binascii
VERSION = '1.0' # Hi Blaine!
HTTP_METHOD = 'GET'
SIGNATURE_METHOD = 'PLAINTEXT'
# Generic exception class
class OAuthError(RuntimeError):
def __init__(self, message='OAuth error occured.'):
self.message = message
# optional WWW-Authenticate header (401 error)
def build_authenticate_header(realm=''):
return {'WWW-Authenticate': 'OAuth realm="%s"' % realm}
# url escape
def escape(s):
# escape '/' too
return urllib.parse.quote(s, safe='~')
# util function: current timestamp
# seconds since epoch (UTC)
def generate_timestamp():
return int(time.time())
# util function: nonce
# pseudorandom number
def generate_nonce(length=8):
return ''.join([str(random.randint(0, 9)) for i in range(length)])
# OAuthConsumer is a data type that represents the identity of the Consumer
# via its shared secret with the Service Provider.
class OAuthConsumer(object):
key = None
secret = None
def __init__(self, key, secret):
self.key = key
self.secret = secret
# OAuthToken is a data type that represents an End User via either an access
# or request token.
class OAuthToken(object):
# access tokens and request tokens
key = None
secret = None
'''
key = the token
secret = the token secret
'''
def __init__(self, key, secret):
self.key = key
self.secret = secret
def to_string(self):
return urllib.parse.urlencode({'oauth_token': self.key, 'oauth_token_secret': self.secret})
# return a token from something like:
# oauth_token_secret=digg&oauth_token=digg
def from_string(s):
params = cgi.parse_qs(s, keep_blank_values=False)
key = params['oauth_token'][0]
secret = params['oauth_token_secret'][0]
return OAuthToken(key, secret)
from_string = staticmethod(from_string)
def __str__(self):
return self.to_string()
# OAuthRequest represents the request and can be serialized
class OAuthRequest(object):
'''
OAuth parameters:
- oauth_consumer_key
- oauth_token
- oauth_signature_method
- oauth_signature
- oauth_timestamp
- oauth_nonce
- oauth_version
... any additional parameters, as defined by the Service Provider.
'''
parameters = None # oauth parameters
http_method = HTTP_METHOD
http_url = None
version = VERSION
def __init__(self, http_method=HTTP_METHOD, http_url=None, parameters=None):
self.http_method = http_method
self.http_url = http_url
self.parameters = parameters or {}
def set_parameter(self, parameter, value):
self.parameters[parameter] = value
def get_parameter(self, parameter):
try:
return self.parameters[parameter]
except:
raise OAuthError('Parameter not found: %s' % parameter)
def _get_timestamp_nonce(self):
return self.get_parameter('oauth_timestamp'), self.get_parameter('oauth_nonce')
# get any non-oauth parameters
def get_nonoauth_parameters(self):
parameters = {}
for k, v in self.parameters.items():
# ignore oauth parameters
if k.find('oauth_') < 0:
parameters[k] = v
return parameters
# serialize as a header for an HTTPAuth request
def to_header(self, realm=''):
auth_header = 'OAuth realm="%s"' % realm
# add the oauth parameters
if self.parameters:
for k, v in self.parameters.items():
if k[:6] == 'oauth_':
auth_header += ', %s="%s"' % (k, escape(str(v)))
return {'Authorization': auth_header}
# serialize as post data for a POST request
def to_postdata(self):
return '&'.join(['%s=%s' % (escape(str(k)), escape(str(v))) for k, v in self.parameters.items()])
# serialize as a url for a GET request
def to_url(self):
return '%s?%s' % (self.get_normalized_http_url(), self.to_postdata())
# return a string that consists of all the parameters that need to be signed
def get_normalized_parameters(self):
params = self.parameters
try:
# exclude the signature if it exists
del params['oauth_signature']
except:
pass
key_values = list(params.items())
# sort lexicographically, first after key, then after value
key_values.sort()
# combine key value pairs in string and escape
return '&'.join(['%s=%s' % (escape(str(k)), escape(str(v))) for k, v in key_values])
# just uppercases the http method
def get_normalized_http_method(self):
return self.http_method.upper()
# parses the url and rebuilds it to be scheme://host/path
def get_normalized_http_url(self):
parts = urllib.parse.urlparse(self.http_url)
url_string = '%s://%s%s' % (parts[0], parts[1], parts[2]) # scheme, netloc, path
return url_string
# set the signature parameter to the result of build_signature
def sign_request(self, signature_method, consumer, token):
# set the signature method
self.set_parameter('oauth_signature_method', signature_method.get_name())
# set the signature
self.set_parameter('oauth_signature', self.build_signature(signature_method, consumer, token))
def build_signature(self, signature_method, consumer, token):
# call the build signature method within the signature method
return signature_method.build_signature(self, consumer, token)
def from_request(http_method, http_url, headers=None, parameters=None, query_string=None):
# combine multiple parameter sources
if parameters is None:
parameters = {}
# headers
if headers and 'Authorization' in headers:
auth_header = headers['Authorization']
# check that the authorization header is OAuth
if auth_header.index('OAuth') > -1:
try:
# get the parameters from the header
header_params = OAuthRequest._split_header(auth_header)
parameters.update(header_params)
except:
raise OAuthError('Unable to parse OAuth parameters from Authorization header.')
# GET or POST query string
if query_string:
query_params = OAuthRequest._split_url_string(query_string)
parameters.update(query_params)
# URL parameters
param_str = urllib.parse.urlparse(http_url)[4] # query
url_params = OAuthRequest._split_url_string(param_str)
parameters.update(url_params)
if parameters:
return OAuthRequest(http_method, http_url, parameters)
return None
from_request = staticmethod(from_request)
def from_consumer_and_token(oauth_consumer, token=None, http_method=HTTP_METHOD, http_url=None, parameters=None):
if not parameters:
parameters = {}
defaults = {
'oauth_consumer_key': oauth_consumer.key,
'oauth_timestamp': generate_timestamp(),
'oauth_nonce': generate_nonce(),
'oauth_version': OAuthRequest.version,
}
defaults.update(parameters)
parameters = defaults
if token:
parameters['oauth_token'] = token.key
return OAuthRequest(http_method, http_url, parameters)
from_consumer_and_token = staticmethod(from_consumer_and_token)
def from_token_and_callback(token, callback=None, http_method=HTTP_METHOD, http_url=None, parameters=None):
if not parameters:
parameters = {}
parameters['oauth_token'] = token.key
if callback:
parameters['oauth_callback'] = callback
return OAuthRequest(http_method, http_url, parameters)
from_token_and_callback = staticmethod(from_token_and_callback)
# util function: turn Authorization: header into parameters, has to do some unescaping
def _split_header(header):
params = {}
parts = header.split(',')
for param in parts:
# ignore realm parameter
if param.find('OAuth realm') > -1:
continue
# remove whitespace
param = param.strip()
# split key-value
param_parts = param.split('=', 1)
# remove quotes and unescape the value
params[param_parts[0]] = urllib.parse.unquote(param_parts[1].strip('\"'))
return params
_split_header = staticmethod(_split_header)
# util function: turn url string into parameters, has to do some unescaping
def _split_url_string(param_str):
parameters = cgi.parse_qs(param_str, keep_blank_values=False)
for k, v in parameters.items():
parameters[k] = urllib.parse.unquote(v[0])
return parameters
_split_url_string = staticmethod(_split_url_string)
# OAuthServer is a worker to check a requests validity against a data store
class OAuthServer(object):
timestamp_threshold = 300 # in seconds, five minutes
version = VERSION
signature_methods = None
data_store = None
def __init__(self, data_store=None, signature_methods=None):
self.data_store = data_store
self.signature_methods = signature_methods or {}
def set_data_store(self, oauth_data_store):
self.data_store = data_store
def get_data_store(self):
return self.data_store
def add_signature_method(self, signature_method):
self.signature_methods[signature_method.get_name()] = signature_method
return self.signature_methods
# process a request_token request
# returns the request token on success
def fetch_request_token(self, oauth_request):
try:
# get the request token for authorization
token = self._get_token(oauth_request, 'request')
except OAuthError:
# no token required for the initial token request
version = self._get_version(oauth_request)
consumer = self._get_consumer(oauth_request)
self._check_signature(oauth_request, consumer, None)
# fetch a new token
token = self.data_store.fetch_request_token(consumer)
return token
# process an access_token request
# returns the access token on success
def fetch_access_token(self, oauth_request):
version = self._get_version(oauth_request)
consumer = self._get_consumer(oauth_request)
# get the request token
token = self._get_token(oauth_request, 'request')
self._check_signature(oauth_request, consumer, token)
new_token = self.data_store.fetch_access_token(consumer, token)
return new_token
# verify an api call, checks all the parameters
def verify_request(self, oauth_request):
# -> consumer and token
version = self._get_version(oauth_request)
consumer = self._get_consumer(oauth_request)
# get the access token
token = self._get_token(oauth_request, 'access')
self._check_signature(oauth_request, consumer, token)
parameters = oauth_request.get_nonoauth_parameters()
return consumer, token, parameters
# authorize a request token
def authorize_token(self, token, user):
return self.data_store.authorize_request_token(token, user)
# get the callback url
def get_callback(self, oauth_request):
return oauth_request.get_parameter('oauth_callback')
# optional support for the authenticate header
def build_authenticate_header(self, realm=''):
return {'WWW-Authenticate': 'OAuth realm="%s"' % realm}
# verify the correct version request for this server
def _get_version(self, oauth_request):
try:
version = oauth_request.get_parameter('oauth_version')
except:
version = VERSION
if version and version != self.version:
raise OAuthError('OAuth version %s not supported.' % str(version))
return version
# figure out the signature with some defaults
def _get_signature_method(self, oauth_request):
try:
signature_method = oauth_request.get_parameter('oauth_signature_method')
except:
signature_method = SIGNATURE_METHOD
try:
# get the signature method object
signature_method = self.signature_methods[signature_method]
except:
signature_method_names = ', '.join(list(self.signature_methods.keys()))
raise OAuthError('Signature method %s not supported try one of the following: %s' % (signature_method, signature_method_names))
return signature_method
def _get_consumer(self, oauth_request):
consumer_key = oauth_request.get_parameter('oauth_consumer_key')
if not consumer_key:
raise OAuthError('Invalid consumer key.')
consumer = self.data_store.lookup_consumer(consumer_key)
if not consumer:
raise OAuthError('Invalid consumer.')
return consumer
# try to find the token for the provided request token key
def _get_token(self, oauth_request, token_type='access'):
token_field = oauth_request.get_parameter('oauth_token')
token = self.data_store.lookup_token(token_type, token_field)
if not token:
raise OAuthError('Invalid %s token: %s' % (token_type, token_field))
return token
def _check_signature(self, oauth_request, consumer, token):
timestamp, nonce = oauth_request._get_timestamp_nonce()
self._check_timestamp(timestamp)
self._check_nonce(consumer, token, nonce)
signature_method = self._get_signature_method(oauth_request)
try:
signature = oauth_request.get_parameter('oauth_signature')
except:
raise OAuthError('Missing signature.')
# validate the signature
valid_sig = signature_method.check_signature(oauth_request, consumer, token, signature)
if not valid_sig:
key, base = signature_method.build_signature_base_string(oauth_request, consumer, token)
raise OAuthError('Invalid signature. Expected signature base string: %s' % base)
built = signature_method.build_signature(oauth_request, consumer, token)
def _check_timestamp(self, timestamp):
# verify that timestamp is recentish
timestamp = int(timestamp)
now = int(time.time())
lapsed = now - timestamp
if lapsed > self.timestamp_threshold:
raise OAuthError('Expired timestamp: given %d and now %s has a greater difference than threshold %d' % (timestamp, now, self.timestamp_threshold))
def _check_nonce(self, consumer, token, nonce):
# verify that the nonce is uniqueish
nonce = self.data_store.lookup_nonce(consumer, token, nonce)
if nonce:
raise OAuthError('Nonce already used: %s' % str(nonce))
# OAuthClient is a worker to attempt to execute a request
class OAuthClient(object):
consumer = None
token = None
def __init__(self, oauth_consumer, oauth_token):
self.consumer = oauth_consumer
self.token = oauth_token
def get_consumer(self):
return self.consumer
def get_token(self):
return self.token
def fetch_request_token(self, oauth_request):
# -> OAuthToken
raise NotImplementedError
def fetch_access_token(self, oauth_request):
# -> OAuthToken
raise NotImplementedError
def access_resource(self, oauth_request):
# -> some protected resource
raise NotImplementedError
# OAuthDataStore is a database abstraction used to lookup consumers and tokens
class OAuthDataStore(object):
def lookup_consumer(self, key):
# -> OAuthConsumer
raise NotImplementedError
def lookup_token(self, oauth_consumer, token_type, token_token):
# -> OAuthToken
raise NotImplementedError
def lookup_nonce(self, oauth_consumer, oauth_token, nonce, timestamp):
# -> OAuthToken
raise NotImplementedError
def fetch_request_token(self, oauth_consumer):
# -> OAuthToken
raise NotImplementedError
def fetch_access_token(self, oauth_consumer, oauth_token):
# -> OAuthToken
raise NotImplementedError
def authorize_request_token(self, oauth_token, user):
# -> OAuthToken
raise NotImplementedError
# OAuthSignatureMethod is a strategy class that implements a signature method
class OAuthSignatureMethod(object):
def get_name(self):
# -> str
raise NotImplementedError
def build_signature_base_string(self, oauth_request, oauth_consumer, oauth_token):
# -> str key, str raw
raise NotImplementedError
def build_signature(self, oauth_request, oauth_consumer, oauth_token):
# -> str
raise NotImplementedError
def check_signature(self, oauth_request, consumer, token, signature):
built = self.build_signature(oauth_request, consumer, token)
return built == signature
class OAuthSignatureMethod_HMAC_SHA1(OAuthSignatureMethod):
def get_name(self):
return 'HMAC-SHA1'
def build_signature_base_string(self, oauth_request, consumer, token):
sig = (
escape(oauth_request.get_normalized_http_method()),
escape(oauth_request.get_normalized_http_url()),
escape(oauth_request.get_normalized_parameters()),
)
key = '%s&' % escape(consumer.secret)
if token:
key += escape(token.secret)
raw = '&'.join(sig)
return key, raw
def build_signature(self, oauth_request, consumer, token):
# build the base signature string
key, raw = self.build_signature_base_string(oauth_request, consumer, token)
# hmac object
try:
import hashlib # 2.5
hashed = hmac.new(key, raw, hashlib.sha1)
except:
import sha # deprecated
hashed = hmac.new(key, raw, sha)
# calculate the digest base 64
return binascii.b2a_base64(hashed.digest())[:-1]
class OAuthSignatureMethod_PLAINTEXT(OAuthSignatureMethod):
def get_name(self):
return 'PLAINTEXT'
def build_signature_base_string(self, oauth_request, consumer, token):
# concatenate the consumer key and secret
sig = escape(consumer.secret) + '&'
if token:
sig = sig + escape(token.secret)
return sig
def build_signature(self, oauth_request, consumer, token):
return self.build_signature_base_string(oauth_request, consumer, token)

View File

@@ -1,120 +0,0 @@
#!/usr/bin/python
"""
requires tlslite - http://trevp.net/tlslite/
"""
import binascii
from gdata.tlslite.utils import keyfactory
from gdata.tlslite.utils import cryptomath
# XXX andy: ugly local import due to module name, oauth.oauth
import gdata.oauth as oauth
class OAuthSignatureMethod_RSA_SHA1(oauth.OAuthSignatureMethod):
def get_name(self):
return "RSA-SHA1"
def _fetch_public_cert(self, oauth_request):
# not implemented yet, ideas are:
# (1) do a lookup in a table of trusted certs keyed off of consumer
# (2) fetch via http using a url provided by the requester
# (3) some sort of specific discovery code based on request
#
# either way should return a string representation of the certificate
raise NotImplementedError
def _fetch_private_cert(self, oauth_request):
# not implemented yet, ideas are:
# (1) do a lookup in a table of trusted certs keyed off of consumer
#
# either way should return a string representation of the certificate
raise NotImplementedError
def build_signature_base_string(self, oauth_request, consumer, token):
sig = (
oauth.escape(oauth_request.get_normalized_http_method()),
oauth.escape(oauth_request.get_normalized_http_url()),
oauth.escape(oauth_request.get_normalized_parameters()),
)
key = ''
raw = '&'.join(sig)
return key, raw
def build_signature(self, oauth_request, consumer, token):
key, base_string = self.build_signature_base_string(oauth_request,
consumer,
token)
# Fetch the private key cert based on the request
cert = self._fetch_private_cert(oauth_request)
# Pull the private key from the certificate
privatekey = keyfactory.parsePrivateKey(cert)
# Convert base_string to bytes
#base_string_bytes = cryptomath.createByteArraySequence(base_string)
# Sign using the key
signed = privatekey.hashAndSign(base_string)
return binascii.b2a_base64(signed)[:-1]
def check_signature(self, oauth_request, consumer, token, signature):
decoded_sig = base64.b64decode(signature);
key, base_string = self.build_signature_base_string(oauth_request,
consumer,
token)
# Fetch the public key cert based on the request
cert = self._fetch_public_cert(oauth_request)
# Pull the public key from the certificate
publickey = keyfactory.parsePEMKey(cert, public=True)
# Check the signature
ok = publickey.hashAndVerify(decoded_sig, base_string)
return ok
class TestOAuthSignatureMethod_RSA_SHA1(OAuthSignatureMethod_RSA_SHA1):
def _fetch_public_cert(self, oauth_request):
cert = """
-----BEGIN CERTIFICATE-----
MIIBpjCCAQ+gAwIBAgIBATANBgkqhkiG9w0BAQUFADAZMRcwFQYDVQQDDA5UZXN0
IFByaW5jaXBhbDAeFw03MDAxMDEwODAwMDBaFw0zODEyMzEwODAwMDBaMBkxFzAV
BgNVBAMMDlRlc3QgUHJpbmNpcGFsMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
gQC0YjCwIfYoprq/FQO6lb3asXrxLlJFuCvtinTF5p0GxvQGu5O3gYytUvtC2JlY
zypSRjVxwxrsuRcP3e641SdASwfrmzyvIgP08N4S0IFzEURkV1wp/IpH7kH41Etb
mUmrXSwfNZsnQRE5SYSOhh+LcK2wyQkdgcMv11l4KoBkcwIDAQABMA0GCSqGSIb3
DQEBBQUAA4GBAGZLPEuJ5SiJ2ryq+CmEGOXfvlTtEL2nuGtr9PewxkgnOjZpUy+d
4TvuXJbNQc8f4AMWL/tO9w0Fk80rWKp9ea8/df4qMq5qlFWlx6yOLQxumNOmECKb
WpkUQDIDJEoFUzKMVuJf4KO/FJ345+BNLGgbJ6WujreoM1X/gYfdnJ/J
-----END CERTIFICATE-----
"""
return cert
def _fetch_private_cert(self, oauth_request):
cert = """
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALRiMLAh9iimur8V
A7qVvdqxevEuUkW4K+2KdMXmnQbG9Aa7k7eBjK1S+0LYmVjPKlJGNXHDGuy5Fw/d
7rjVJ0BLB+ubPK8iA/Tw3hLQgXMRRGRXXCn8ikfuQfjUS1uZSatdLB81mydBETlJ
hI6GH4twrbDJCR2Bwy/XWXgqgGRzAgMBAAECgYBYWVtleUzavkbrPjy0T5FMou8H
X9u2AC2ry8vD/l7cqedtwMPp9k7TubgNFo+NGvKsl2ynyprOZR1xjQ7WgrgVB+mm
uScOM/5HVceFuGRDhYTCObE+y1kxRloNYXnx3ei1zbeYLPCHdhxRYW7T0qcynNmw
rn05/KO2RLjgQNalsQJBANeA3Q4Nugqy4QBUCEC09SqylT2K9FrrItqL2QKc9v0Z
zO2uwllCbg0dwpVuYPYXYvikNHHg+aCWF+VXsb9rpPsCQQDWR9TT4ORdzoj+Nccn
qkMsDmzt0EfNaAOwHOmVJ2RVBspPcxt5iN4HI7HNeG6U5YsFBb+/GZbgfBT3kpNG
WPTpAkBI+gFhjfJvRw38n3g/+UeAkwMI2TJQS4n8+hid0uus3/zOjDySH3XHCUno
cn1xOJAyZODBo47E+67R4jV1/gzbAkEAklJaspRPXP877NssM5nAZMU0/O/NGCZ+
3jPgDUno6WbJn5cqm8MqWhW1xGkImgRk+fkDBquiq4gPiT898jusgQJAd5Zrr6Q8
AO/0isr/3aa6O6NLQxISLKcPDk2NOccAfS/xOtfOz4sJYM3+Bs4Io9+dZGSDCA54
Lw03eHTNQghS0A==
-----END PRIVATE KEY-----
"""
return cert

View File

@@ -69,8 +69,6 @@ import gdata
import atom
import atom.http_interface
import atom.token_store
import gdata.auth
import gdata.gauth
AUTH_SERVER_HOST = 'https://www.google.com'
@@ -87,8 +85,6 @@ SCOPE_URL_PARAM_NAME = 'authsub_token_scope'
# 'callback' URL which contains the requested scope. This constant is the
# default name (AKA key) for the URL parameter.
OAUTH_SCOPE_URL_PARAM_NAME = 'oauth_token_scope'
# Maps the service names used in ClientLogin to scope URLs.
CLIENT_LOGIN_SCOPES = gdata.gauth.AUTH_SCOPES
# Default parameters for GDataService.GetWithRetries method
DEFAULT_NUM_RETRIES = 3
DEFAULT_DELAY = 1
@@ -1091,7 +1087,7 @@ class GDataService(atom.service.AtomService):
location = (server_response.getheader('Location')
or server_response.getheader('location'))
if location is not None:
m = re.compile('[\?\&]gsessionid=(\w*)').search(location)
m = re.compile(r'[?&]gsessionid=(\w*)').search(location)
if m is not None:
self.__gsessionid = m.group(1)
return GDataService.Get(self, location, extra_headers, redirects_remaining - 1,
@@ -1339,7 +1335,7 @@ class GDataService(atom.service.AtomService):
location = (server_response.getheader('Location')
or server_response.getheader('location'))
if location is not None:
m = re.compile('[\?\&]gsessionid=(\w*)').search(location)
m = re.compile(r'[?&]gsessionid=(\w*)').search(location)
if m is not None:
self.__gsessionid = m.group(1)
return GDataService.PostOrPut(self, verb, data, location,
@@ -1437,7 +1433,7 @@ class GDataService(atom.service.AtomService):
location = (server_response.getheader('Location')
or server_response.getheader('location'))
if location is not None:
m = re.compile('[\?\&]gsessionid=(\w*)').search(location)
m = re.compile(r'[?&]gsessionid=(\w*)').search(location)
if m is not None:
self.__gsessionid = m.group(1)
return GDataService.Delete(self, location, extra_headers,

View File

@@ -1,120 +0,0 @@
"""Base class for SharedKeyDB and VerifierDB."""
import dbm
import _thread
class BaseDB:
def __init__(self, filename, type):
self.type = type
self.filename = filename
if self.filename:
self.db = None
else:
self.db = {}
self.lock = _thread.allocate_lock()
def create(self):
"""Create a new on-disk database.
@raise anydbm.error: If there's a problem creating the database.
"""
if self.filename:
self.db = dbm.open(self.filename, "n") #raises anydbm.error
self.db["--Reserved--type"] = self.type
self.db.sync()
else:
self.db = {}
def open(self):
"""Open a pre-existing on-disk database.
@raise anydbm.error: If there's a problem opening the database.
@raise ValueError: If the database is not of the right type.
"""
if not self.filename:
raise ValueError("Can only open on-disk databases")
self.db = dbm.open(self.filename, "w") #raises anydbm.error
try:
if self.db["--Reserved--type"] != self.type:
raise ValueError("Not a %s database" % self.type)
except KeyError:
raise ValueError("Not a recognized database")
def __getitem__(self, username):
if self.db == None:
raise AssertionError("DB not open")
self.lock.acquire()
try:
valueStr = self.db[username]
finally:
self.lock.release()
return self._getItem(username, valueStr)
def __setitem__(self, username, value):
if self.db == None:
raise AssertionError("DB not open")
valueStr = self._setItem(username, value)
self.lock.acquire()
try:
self.db[username] = valueStr
if self.filename:
self.db.sync()
finally:
self.lock.release()
def __delitem__(self, username):
if self.db == None:
raise AssertionError("DB not open")
self.lock.acquire()
try:
del(self.db[username])
if self.filename:
self.db.sync()
finally:
self.lock.release()
def __contains__(self, username):
"""Check if the database contains the specified username.
@type username: str
@param username: The username to check for.
@rtype: bool
@return: True if the database contains the username, False
otherwise.
"""
if self.db == None:
raise AssertionError("DB not open")
self.lock.acquire()
try:
return username in self.db
finally:
self.lock.release()
def check(self, username, param):
value = self.__getitem__(username)
return self._checkItem(value, username, param)
def keys(self):
"""Return a list of usernames in the database.
@rtype: list
@return: The usernames in the database.
"""
if self.db == None:
raise AssertionError("DB not open")
self.lock.acquire()
try:
usernames = list(self.db.keys())
finally:
self.lock.release()
usernames = [u for u in usernames if not u.startswith("--Reserved--")]
return usernames

View File

@@ -1,146 +0,0 @@
"""Class for post-handshake certificate checking."""
from .utils.cryptomath import hashAndBase64
from .X509 import X509
from .X509CertChain import X509CertChain
from .errors import *
class Checker:
"""This class is passed to a handshake function to check the other
party's certificate chain.
If a handshake function completes successfully, but the Checker
judges the other party's certificate chain to be missing or
inadequate, a subclass of
L{tlslite.errors.TLSAuthenticationError} will be raised.
Currently, the Checker can check either an X.509 or a cryptoID
chain (for the latter, cryptoIDlib must be installed).
"""
def __init__(self, cryptoID=None, protocol=None,
x509Fingerprint=None,
x509TrustList=None, x509CommonName=None,
checkResumedSession=False):
"""Create a new Checker instance.
You must pass in one of these argument combinations:
- cryptoID[, protocol] (requires cryptoIDlib)
- x509Fingerprint
- x509TrustList[, x509CommonName] (requires cryptlib_py)
@type cryptoID: str
@param cryptoID: A cryptoID which the other party's certificate
chain must match. The cryptoIDlib module must be installed.
Mutually exclusive with all of the 'x509...' arguments.
@type protocol: str
@param protocol: A cryptoID protocol URI which the other
party's certificate chain must match. Requires the 'cryptoID'
argument.
@type x509Fingerprint: str
@param x509Fingerprint: A hex-encoded X.509 end-entity
fingerprint which the other party's end-entity certificate must
match. Mutually exclusive with the 'cryptoID' and
'x509TrustList' arguments.
@type x509TrustList: list of L{tlslite.X509.X509}
@param x509TrustList: A list of trusted root certificates. The
other party must present a certificate chain which extends to
one of these root certificates. The cryptlib_py module must be
installed. Mutually exclusive with the 'cryptoID' and
'x509Fingerprint' arguments.
@type x509CommonName: str
@param x509CommonName: The end-entity certificate's 'CN' field
must match this value. For a web server, this is typically a
server name such as 'www.amazon.com'. Mutually exclusive with
the 'cryptoID' and 'x509Fingerprint' arguments. Requires the
'x509TrustList' argument.
@type checkResumedSession: bool
@param checkResumedSession: If resumed sessions should be
checked. This defaults to False, on the theory that if the
session was checked once, we don't need to bother
re-checking it.
"""
if cryptoID and (x509Fingerprint or x509TrustList):
raise ValueError()
if x509Fingerprint and x509TrustList:
raise ValueError()
if x509CommonName and not x509TrustList:
raise ValueError()
if protocol and not cryptoID:
raise ValueError()
if cryptoID:
import cryptoIDlib #So we raise an error here
if x509TrustList:
import cryptlib_py #So we raise an error here
self.cryptoID = cryptoID
self.protocol = protocol
self.x509Fingerprint = x509Fingerprint
self.x509TrustList = x509TrustList
self.x509CommonName = x509CommonName
self.checkResumedSession = checkResumedSession
def __call__(self, connection):
"""Check a TLSConnection.
When a Checker is passed to a handshake function, this will
be called at the end of the function.
@type connection: L{tlslite.TLSConnection.TLSConnection}
@param connection: The TLSConnection to examine.
@raise tlslite.errors.TLSAuthenticationError: If the other
party's certificate chain is missing or bad.
"""
if not self.checkResumedSession and connection.resumed:
return
if self.cryptoID or self.x509Fingerprint or self.x509TrustList:
if connection._client:
chain = connection.session.serverCertChain
else:
chain = connection.session.clientCertChain
if self.x509Fingerprint or self.x509TrustList:
if isinstance(chain, X509CertChain):
if self.x509Fingerprint:
if chain.getFingerprint() != self.x509Fingerprint:
raise TLSFingerprintError(\
"X.509 fingerprint mismatch: %s, %s" % \
(chain.getFingerprint(), self.x509Fingerprint))
else: #self.x509TrustList
if not chain.validate(self.x509TrustList):
raise TLSValidationError("X.509 validation failure")
if self.x509CommonName and \
(chain.getCommonName() != self.x509CommonName):
raise TLSAuthorizationError(\
"X.509 Common Name mismatch: %s, %s" % \
(chain.getCommonName(), self.x509CommonName))
elif chain:
raise TLSAuthenticationTypeError()
else:
raise TLSNoAuthenticationError()
elif self.cryptoID:
import cryptoIDlib.CertChain
if isinstance(chain, cryptoIDlib.CertChain.CertChain):
if chain.cryptoID != self.cryptoID:
raise TLSFingerprintError(\
"cryptoID mismatch: %s, %s" % \
(chain.cryptoID, self.cryptoID))
if self.protocol:
if not chain.checkProtocol(self.protocol):
raise TLSAuthorizationError(\
"cryptoID protocol mismatch")
if not chain.validate():
raise TLSValidationError("cryptoID validation failure")
elif chain:
raise TLSAuthenticationTypeError()
else:
raise TLSNoAuthenticationError()

View File

@@ -1,220 +0,0 @@
"""Class returned by TLSConnection.makefile()."""
class FileObject:
"""This class provides a file object interface to a
L{tlslite.TLSConnection.TLSConnection}.
Call makefile() on a TLSConnection to create a FileObject instance.
This class was copied, with minor modifications, from the
_fileobject class in socket.py. Note that fileno() is not
implemented."""
default_bufsize = 16384 #TREV: changed from 8192
def __init__(self, sock, mode='rb', bufsize=-1):
self._sock = sock
self.mode = mode # Not actually used in this version
if bufsize < 0:
bufsize = self.default_bufsize
self.bufsize = bufsize
self.softspace = False
if bufsize == 0:
self._rbufsize = 1
elif bufsize == 1:
self._rbufsize = self.default_bufsize
else:
self._rbufsize = bufsize
self._wbufsize = bufsize
self._rbuf = "" # A string
self._wbuf = [] # A list of strings
def _getclosed(self):
return self._sock is not None
closed = property(_getclosed, doc="True if the file is closed")
def close(self):
try:
if self._sock:
for result in self._sock._decrefAsync(): #TREV
pass
finally:
self._sock = None
def __del__(self):
try:
self.close()
except:
# close() may fail if __init__ didn't complete
pass
def flush(self):
if self._wbuf:
buffer = "".join(self._wbuf)
self._wbuf = []
self._sock.sendall(buffer)
#def fileno(self):
# raise NotImplementedError() #TREV
def write(self, data):
data = str(data) # XXX Should really reject non-string non-buffers
if not data:
return
self._wbuf.append(data)
if (self._wbufsize == 0 or
self._wbufsize == 1 and '\n' in data or
self._get_wbuf_len() >= self._wbufsize):
self.flush()
def writelines(self, list):
# XXX We could do better here for very long lists
# XXX Should really reject non-string non-buffers
self._wbuf.extend([_f for _f in map(str, list) if _f])
if (self._wbufsize <= 1 or
self._get_wbuf_len() >= self._wbufsize):
self.flush()
def _get_wbuf_len(self):
buf_len = 0
for x in self._wbuf:
buf_len += len(x)
return buf_len
def read(self, size=-1):
data = self._rbuf
if size < 0:
# Read until EOF
buffers = []
if data:
buffers.append(data)
self._rbuf = ""
if self._rbufsize <= 1:
recv_size = self.default_bufsize
else:
recv_size = self._rbufsize
while True:
data = self._sock.recv(recv_size)
if not data:
break
buffers.append(data)
return "".join(buffers)
else:
# Read until size bytes or EOF seen, whichever comes first
buf_len = len(data)
if buf_len >= size:
self._rbuf = data[size:]
return data[:size]
buffers = []
if data:
buffers.append(data)
self._rbuf = ""
while True:
left = size - buf_len
recv_size = max(self._rbufsize, left)
data = self._sock.recv(recv_size)
if not data:
break
buffers.append(data)
n = len(data)
if n >= left:
self._rbuf = data[left:]
buffers[-1] = data[:left]
break
buf_len += n
return "".join(buffers)
def readline(self, size=-1):
data = self._rbuf
if size < 0:
# Read until \n or EOF, whichever comes first
if self._rbufsize <= 1:
# Speed up unbuffered case
assert data == ""
buffers = []
recv = self._sock.recv
while data != "\n":
data = recv(1)
if not data:
break
buffers.append(data)
return "".join(buffers)
nl = data.find('\n')
if nl >= 0:
nl += 1
self._rbuf = data[nl:]
return data[:nl]
buffers = []
if data:
buffers.append(data)
self._rbuf = ""
while True:
data = self._sock.recv(self._rbufsize)
if not data:
break
buffers.append(data)
nl = data.find('\n')
if nl >= 0:
nl += 1
self._rbuf = data[nl:]
buffers[-1] = data[:nl]
break
return "".join(buffers)
else:
# Read until size bytes or \n or EOF seen, whichever comes first
nl = data.find('\n', 0, size)
if nl >= 0:
nl += 1
self._rbuf = data[nl:]
return data[:nl]
buf_len = len(data)
if buf_len >= size:
self._rbuf = data[size:]
return data[:size]
buffers = []
if data:
buffers.append(data)
self._rbuf = ""
while True:
data = self._sock.recv(self._rbufsize)
if not data:
break
buffers.append(data)
left = size - buf_len
nl = data.find('\n', 0, left)
if nl >= 0:
nl += 1
self._rbuf = data[nl:]
buffers[-1] = data[:nl]
break
n = len(data)
if n >= left:
self._rbuf = data[left:]
buffers[-1] = data[:left]
break
buf_len += n
return "".join(buffers)
def readlines(self, sizehint=0):
total = 0
list = []
while True:
line = self.readline()
if not line:
break
list.append(line)
total += len(line)
if sizehint and total >= sizehint:
break
return list
# Iterator protocols
def __iter__(self):
return self
def __next__(self):
line = self.readline()
if not line:
raise StopIteration
return line

Some files were not shown because too many files have changed in this diff Show More