Compare commits

...

31 Commits

Author SHA1 Message Date
Ross Scroggs
60d6188769 Added option showwebviewlink to gam print|show shareddrives
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2025-06-30 09:43:50 -07:00
Ross Scroggs
626eb1eadc Added option showwebviewlink to gam print|show shareddrives 2025-06-30 09:43:32 -07:00
Ross Scroggs
db40ada5d0 Update Cloud-Identity-Groups.md 2025-06-30 07:46:37 -07:00
Ross Scroggs
ba8c27339e Fixed labelids <LabelIdList> bug 2025-06-29 19:04:47 -07:00
Ross Scroggs
822488dce5 Fixed labelids <LabelIdList> bug
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
2025-06-29 19:04:21 -07:00
Ross Scroggs
bbd76ec23f Update Cloud-Identity-Policies.md
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-06-27 07:29:10 -07:00
Ross Scroggs
e2a6f8badf Update Authorization.md 2025-06-27 06:57:25 -07:00
Jay Lee
2462aa7dcb [no ci] enable manual wiki push actions 2025-06-27 08:26:31 -04:00
Jay Lee
d7a0da6e52 [no ci] update Authorization wiki article with some corrections 2025-06-27 08:23:25 -04:00
Ross Scroggs
9922ed4994 Permissions fix, new license SKU
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2025-06-26 14:16:12 -07:00
Ross Scroggs
3a0c52d8eb Permissions fix, new license SKU
Updated `gam <UserTypeEntity> copy|move drivefile` to hanndle additional instances of
the `cannotModifyInheritedPermission` error.

Added license SKU `Google AI Ultra for Business`
2025-06-26 14:15:15 -07:00
Ross Scroggs
f3e7c46561 Merge branch 'main' of https://github.com/GAM-team/GAM 2025-06-26 14:00:18 -07:00
Ross Scroggs
b42c916516 Updated gam <UserTypeEntity> copy|move drivefile
to hanndle additional instances of
the `cannotModifyInheritedPermission` error.
2025-06-26 14:00:15 -07:00
Jay Lee
4fd7172f7a Merge branch 'main' of https://github.com/GAM-team/GAM 2025-06-26 18:31:20 +00:00
Jay Lee
e670cf3e6a Add license for new Google AI Ultra SKU 2025-06-26 18:31:13 +00:00
Ross Scroggs
e305cc0789 Merge branch 'main' of https://github.com/GAM-team/GAM 2025-06-26 10:12:20 -07:00
Ross Scroggs
d7b9d43c63 Add clientstates to gam print devices 2025-06-26 10:12:08 -07:00
Jay Lee
75e3ae8144 actions: custom win-arm64 lxml wheel no longer needed 2025-06-26 13:03:07 -04:00
Jay Lee
130a483e4d [actions] test clientstates argument
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2025-06-26 15:15:32 +00:00
Jay Lee
cbd04bcec4 gam print devices clientstates 2025-06-26 15:14:33 +00:00
Jay Lee
a51b245015 [no ci] wiki DASA article update 2025-06-26 09:58:54 -04:00
Ross Scroggs
64356a9736 Handle invalid photo data error
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-06-24 18:01:18 -07:00
Ross Scroggs
c18375abb7 Google renamed an error: cannotModifyInheritedTeamDrivePermission became cannotModifyInheritedPermission 2025-06-24 15:40:08 -07:00
Ross Scroggs
c9c0cac57e Google renamed an error: cannotModifyInheritedTeamDrivePermission became cannotModifyInheritedPermission
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
2025-06-24 15:39:55 -07:00
Ross Scroggs
8ca3717f97 Updated gam report <ActivityApplicationName>
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2025-06-22 12:32:52 -07:00
Ross Scroggs
cd0d82e994 Updated gam report <ActivityApplicationName> 2025-06-22 12:31:13 -07:00
Ross Scroggs
f29f27577c Update Users-Gmail-Send-As-Signature-Vacation.md
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
2025-06-22 06:41:43 -07:00
Ross Scroggs
cb5e5d1943 Update Users-Gmail-Send-As-Signature-Vacation.md 2025-06-22 06:34:31 -07:00
Ross Scroggs
88bdfd2883 _finalizeMessageSelectParameter
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
2025-06-21 06:32:12 -07:00
Ross Scroggs
e875acf428 Fixed labelids <LabelIdList> bug
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
2025-06-21 06:31:58 -07:00
Ross Scroggs
5d213e9951 Added option labelids <LabelIdList> to all commands that process messages
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2025-06-20 10:22:05 -07:00
23 changed files with 410 additions and 140 deletions

View File

@@ -457,10 +457,6 @@ jobs:
- name: Custom wheels for Win arm64 - name: Custom wheels for Win arm64
if: runner.os == 'Windows' && runner.arch == 'ARM64' if: runner.os == 'Windows' && runner.arch == 'ARM64'
run: | run: |
latest_lxml_whl=$(curl https://api.github.com/repos/GAM-team/lxml-wheel/releases/latest -s | jq -r .assets.[0].browser_download_url)
echo "Downloading ${latest_lxml_whl}..."
curl -O -L "$latest_lxml_whl"
"$PYTHON" -m pip install lxml*.whl
latest_crypt_whl=$(curl https://api.github.com/repos/jay0lee/cryptography/releases/latest -s | jq -r .assets.[0].browser_download_url) latest_crypt_whl=$(curl https://api.github.com/repos/jay0lee/cryptography/releases/latest -s | jq -r .assets.[0].browser_download_url)
echo "Downloading ${latest_crypt_whl}..." echo "Downloading ${latest_crypt_whl}..."
curl -O -L "$latest_crypt_whl" curl -O -L "$latest_crypt_whl"
@@ -810,7 +806,7 @@ jobs:
echo "Created shared drive ${driveid}" echo "Created shared drive ${driveid}"
$gam create user $newuser firstname GHA lastname $JID displayname "Github Actions ${JID}" password random recoveryphone 12125121110 recoveryemail jay0lee@gmail.com gha.jid $JID languages en+,en-GB- ou "${newou}" $gam create user $newuser firstname GHA lastname $JID displayname "Github Actions ${JID}" password random recoveryphone 12125121110 recoveryemail jay0lee@gmail.com gha.jid $JID languages en+,en-GB- ou "${newou}"
$gam user $newuser add license workspaceenterpriseplus $gam user $newuser add license workspaceenterpriseplus
$gam user $newuser update photo https://dummyimage.com/400x600/000/fff $gam user $newuser update photo https://dummyimage.com/98x98/000/fff.jpg
$gam user $newuser get photo $gam user $newuser get photo
$gam user $newuser delete photo $gam user $newuser delete photo
$gam create alias $newalias user $newuser $gam create alias $newalias user $newuser
@@ -920,7 +916,7 @@ jobs:
$gam config enable_dasa true save $gam config enable_dasa true save
$gam print users query "gha.jid=$JID" | $gam csv - gam delete user ~primaryEmail || if [ $? != 50 ]; then exit $?; fi # expect a 50 return code (vault hold on user) $gam print users query "gha.jid=$JID" | $gam csv - gam delete user ~primaryEmail || if [ $? != 50 ]; then exit $?; fi # expect a 50 return code (vault hold on user)
$gam print mobile $gam print mobile
$gam print devices $gam print devices clientstates
$gam print browsers $gam print browsers
$gam print cros allfields orderby serialnumber $gam print cros allfields orderby serialnumber
$gam show crostelemetry storagepercentonly $gam show crostelemetry storagepercentonly

View File

@@ -5,6 +5,8 @@ on:
push: push:
paths: paths:
- 'wiki/**' - 'wiki/**'
workflow_dispatch:
jobs: jobs:
pushwiki: pushwiki:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@@ -279,6 +279,7 @@ If an item contains spaces, it should be surrounded by ".
geminiedu | 1010470004 | Gemini Education | geminiedu | 1010470004 | Gemini Education |
geminiedupremium| 1010470005 | Gemini Education Premium | geminiedupremium| 1010470005 | Gemini Education Premium |
geminient| duetai | 1010470001 | Gemini Enterprise | geminient| duetai | 1010470001 | Gemini Enterprise |
geminiultra | 1010470008 | Google AI Ultra for Business |
gsuitebasic | gafb | gafw | basic | Google-Apps-For-Business | gsuitebasic | gafb | gafw | basic | Google-Apps-For-Business |
gsuitebusiness | gau | gsb | unlimited | Google-Apps-Unlimited | gsuitebusiness | gau | gsb | unlimited | Google-Apps-Unlimited |
gsuitebusinessarchived | gsbau | businessarchived | 1010340002 | Google Workspace Business - Archived User | gsuitebusinessarchived | gsbau | businessarchived | 1010340002 | Google Workspace Business - Archived User |
@@ -4124,6 +4125,7 @@ gam print devices [todrive <ToDriveAttribute>*]
[orderby <DeviceOrderByFieldName> [ascending|descending]] [orderby <DeviceOrderByFieldName> [ascending|descending]]
[all|company|personal|nocompanydevices|nopersonaldevices] [all|company|personal|nocompanydevices|nopersonaldevices]
[nodeviceusers|oneuserperrow] [nodeviceusers|oneuserperrow]
[clientstates]
[formatjson [quotechar <Character>]] [formatjson [quotechar <Character>]]
[showitemcountonly] [showitemcountonly]
@@ -4435,20 +4437,18 @@ gam report usage customer [todrive <ToDriveAttribute>*]
[convertmbtogb] [convertmbtogb]
<ActivityApplicationName> ::= <ActivityApplicationName> ::=
access|accesstransparency| accesstransparency|access|
admin| admin|
calendar|calendars| calendar|calendars|
chat| chat|
chrome| chrome|
classroom| classroom|
contextawareaccess| contextawareaccess|
currents|gplus|google+| gplus|currents|google+|
datastudio| datastudio|
devices|mobile|
domain|
drive|doc|docs| drive|doc|docs|
gcp|cloud| gcp|cloud|
gemini|geminiforworkspace| geminiinworkspaceapps|gemini|geminiforworkspace|
groups|group| groups|group|
groupsenterprise|enterprisegroups| groupsenterprise|enterprisegroups|
jamboard| jamboard|
@@ -4466,7 +4466,7 @@ gam report <ActivityApplicationName> [todrive <ToDriveAttribute>*]
[(user all|<UserItem>)|(orgunit|org|ou <OrgUnitPath> [showorgunit])|(select <UserTypeEntity>)] [(user all|<UserItem>)|(orgunit|org|ou <OrgUnitPath> [showorgunit])|(select <UserTypeEntity>)]
[([start <Time>] [end <Time>])|(range <Time> <Time>)| [([start <Time>] [end <Time>])|(range <Time> <Time>)|
yesterday|today|thismonth|(previousmonths <Integer>)] yesterday|today|thismonth|(previousmonths <Integer>)]
[filtertime.String> <Time>] [filter|filters <String>] [filtertime.<String> <Time>] [filter|filters <String>]
[event|events <EventNameList>] [ip <String>] [event|events <EventNameList>] [ip <String>]
[groupidfilter <String>] [groupidfilter <String>]
[maxactivities <Number>] [maxevents <Number>] [maxresults <Number>] [maxactivities <Number>] [maxevents <Number>] [maxresults <Number>]
@@ -4817,11 +4817,13 @@ gam print shareddrives [todrive <ToDriveAttribute>*]
[teamdriveadminquery|query <QueryTeamDrive>] [teamdriveadminquery|query <QueryTeamDrive>]
[matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>] [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>]
[fields <SharedDriveFieldNameList>] [noorgunits [<Boolean>]] [fields <SharedDriveFieldNameList>] [noorgunits [<Boolean>]]
[showwebviewlink]
[formatjson [quotechar <Character>]] [formatjson [quotechar <Character>]]
gam show shareddrives gam show shareddrives
[teamdriveadminquery|query <QueryTeamDrive>] [teamdriveadminquery|query <QueryTeamDrive>]
[matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>] [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>]
[fields <SharedDriveFieldNameList>] [noorgunits [<Boolean>]] [fields <SharedDriveFieldNameList>] [noorgunits [<Boolean>]]
[showwebviewlink]
[formatjson] [noorgunits [<Boolean>]] [formatjson] [noorgunits [<Boolean>]]
gam print shareddriveorganizers [todrive <ToDriveAttribute>*] gam print shareddriveorganizers [todrive <ToDriveAttribute>*]
@@ -4902,12 +4904,14 @@ gam <UserTypeEntity> print shareddrives [todrive <ToDriveAttribute>*]
[matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>] [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>]
(role|roles <SharedDriveACLRoleList>)* (role|roles <SharedDriveACLRoleList>)*
[fields <SharedDriveFieldNameList>] [fields <SharedDriveFieldNameList>]
[showwebviewlink]
[guiroles [<Boolean>]] [formatjson [quotechar <Character>]] [guiroles [<Boolean>]] [formatjson [quotechar <Character>]]
gam <UserTypeEntity> show shareddrives gam <UserTypeEntity> show shareddrives
[teamdriveadminquery|query <QueryTeamDrive>] [teamdriveadminquery|query <QueryTeamDrive>]
[matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>] [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>]
(role|roles <SharedDriveACLRoleList>)* (role|roles <SharedDriveACLRoleList>)*
[fields <SharedDriveFieldNameList>] [fields <SharedDriveFieldNameList>]
[showwebviewlink]
[guiroles [<Boolean>]] [formatjson] [guiroles [<Boolean>]] [formatjson]
<PermissionMatch> ::= <PermissionMatch> ::=

View File

@@ -1,3 +1,45 @@
7.10.09
Added option `showwebviewlink` to `gam [<UserTypeEntity>] print|show shareddrives` that
displays the web view link for the Shared Drive: `https://drive.google.com/drive/folders/<SharedDriveID>`.
7.10.08
Fixed bug in commands that modify messages where the `labelids <LabelIdList>` option
could not be used unless one of these options was also specified: `query`, `matchlabel`, `ids`;
it can be now be used by itself.
7.10.07
Updated `gam <UserTypeEntity> copy|move drivefile` to hanndle additional instances of
the `cannotModifyInheritedPermission` error.
Added license SKU `Google AI Ultra for Business`
* ProductID - 101047
* SKUID - 1010470008 | geminiultra
7.10.06
Added option `clientstates` to `gam print devices` to include client states in device output.
7.10.05
Google renamed an error: `cannotModifyInheritedTeamDrivePermission` became `cannotModifyInheritedPermission`.
GAM will now handle the new error.
7.10.04
Updated `gam report <ActivityApplicationName>` to accept accept application names as defined
in the Reports API discovery document; this means that GAM does not have to be updated when
Google defines a new application name.
`gemini_in_workspace_apps` is now available in `gam report`.
7.10.03
Fixed bug in commands that modify messages where the `labelids <LabelIdList>` option
was not being applied.
7.10.02 7.10.02
Added option `labelids <LabelIdList>` to all commands that process messages; Added option `labelids <LabelIdList>` to all commands that process messages;

View File

@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
""" """
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>' __author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
__version__ = '7.10.02' __version__ = '7.10.09'
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)' __license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
#pylint: disable=wrong-import-position #pylint: disable=wrong-import-position
@@ -5187,6 +5187,12 @@ def checkGAPIError(e, softErrors=False, retryOnHttpError=False, mapNotFound=True
return (0, None, None) return (0, None, None)
else: else:
systemErrorExit(HTTP_ERROR_RC, eContent) systemErrorExit(HTTP_ERROR_RC, eContent)
requiredScopes = ''
wwwAuthenticate = e.resp.get('www-authenticate', '')
if 'insufficient_scope' in wwwAuthenticate:
mg = re.match(r'.+scope="(.+)"', wwwAuthenticate)
if mg:
requiredScopes = mg.group(1).split(' ')
if 'error' in error: if 'error' in error:
http_status = error['error']['code'] http_status = error['error']['code']
reason = '' reason = ''
@@ -5256,6 +5262,8 @@ def checkGAPIError(e, softErrors=False, retryOnHttpError=False, mapNotFound=True
elif 'the authenticated user cannot access this service' in lmessage: elif 'the authenticated user cannot access this service' in lmessage:
error = makeErrorDict(http_status, GAPI.SERVICE_NOT_AVAILABLE, message) error = makeErrorDict(http_status, GAPI.SERVICE_NOT_AVAILABLE, message)
elif status == 'PERMISSION_DENIED' or 'the caller does not have permission' in lmessage or 'permission iam.serviceaccountkeys' in lmessage: elif status == 'PERMISSION_DENIED' or 'the caller does not have permission' in lmessage or 'permission iam.serviceaccountkeys' in lmessage:
if requiredScopes:
message += f', {Msg.NO_SCOPES_FOR_API.format(API.findAPIforScope(requiredScopes))}'
error = makeErrorDict(http_status, GAPI.PERMISSION_DENIED, message) error = makeErrorDict(http_status, GAPI.PERMISSION_DENIED, message)
elif http_status == 404: elif http_status == 404:
if status == 'NOT_FOUND' or 'requested entity was not found' in lmessage or 'does not exist' in lmessage: if status == 'NOT_FOUND' or 'requested entity was not found' in lmessage or 'does not exist' in lmessage:
@@ -8864,6 +8872,7 @@ class CSVPrintFile():
GAPI.fileOrganizerNotYetEnabledForThisTeamDrive, GAPI.fileOrganizerNotYetEnabledForThisTeamDrive,
GAPI.fileOrganizerOnFoldersInSharedDriveOnly, GAPI.fileOrganizerOnFoldersInSharedDriveOnly,
GAPI.fileOrganizerOnNonTeamDriveNotSupported, GAPI.fileOrganizerOnNonTeamDriveNotSupported,
GAPI.cannotModifyInheritedPermission,
GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility, GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility,
GAPI.invalidSharingRequest, GAPI.fileNeverWritable, GAPI.abusiveContentRestriction) as e: GAPI.invalidSharingRequest, GAPI.fileNeverWritable, GAPI.abusiveContentRestriction) as e:
entityActionFailedWarning([Ent.USER, user, Ent.SPREADSHEET, title, entityActionFailedWarning([Ent.USER, user, Ent.SPREADSHEET, title,
@@ -13548,52 +13557,55 @@ def doReportUsage():
NL_SPACES_PATTERN = re.compile(r'\n +') NL_SPACES_PATTERN = re.compile(r'\n +')
DISABLED_REASON_TIME_PATTERN = re.compile(r'.*(\d{4}/\d{2}/\d{2}-\d{2}:\d{2}:\d{2})') DISABLED_REASON_TIME_PATTERN = re.compile(r'.*(\d{4}/\d{2}/\d{2}-\d{2}:\d{2}:\d{2})')
REPORT_CHOICE_MAP = { REPORT_ALIASES_CHOICE_MAP = {
'access': 'access_transparency', 'access': 'accesstransparency',
'accesstransparency': 'access_transparency',
'admin': 'admin',
'calendar': 'calendar',
'calendars': 'calendar', 'calendars': 'calendar',
'chat': 'chat',
'chrome': 'chrome',
'classroom': 'classroom',
'cloud': 'gcp', 'cloud': 'gcp',
'contextawareaccess': 'context_aware_access',
'currents': 'gplus', 'currents': 'gplus',
'customer': 'customer',
'customers': 'customer', 'customers': 'customer',
'datastudio': 'data_studio', 'domain': 'customer',
'devices': 'mobile', 'devices': 'mobile',
'doc': 'drive', 'doc': 'drive',
'docs': 'drive', 'docs': 'drive',
'domain': 'customer', 'enterprisegroups': 'groupsenterprise',
'drive': 'drive', 'gemini': 'geminiinworkspaceapps',
'enterprisegroups': 'groups_enterprise', 'geminiforworkspace': 'geminiinworkspaceapps',
'gcp': 'gcp',
'gemini': 'gemini_for_workspace',
'geminiforworkspace': 'gemini_for_workspace',
'gplus': 'gplus',
'google+': 'gplus',
'group': 'groups', 'group': 'groups',
'google+': 'gplus',
'hangoutsmeet': 'meet',
'logins': 'login',
'lookerstudio': 'datastudio',
'oauthtoken': 'token',
'tokens': 'token',
'users': 'user',
}
REPORT_CHOICE_MAP = {
'accesstransparency': 'access_transparency',
'admin': 'admin',
'calendar': 'calendar',
'chat': 'chat',
'chrome': 'chrome',
'contextawareaccess': 'context_aware_access',
'customer': 'customer',
'datastudio': 'data_studio',
'drive': 'drive',
'gcp': 'gcp',
'geminiinworkspaceapps': 'gemini_in_workspace_apps',
'gplus': 'gplus',
'groups': 'groups', 'groups': 'groups',
'groupsenterprise': 'groups_enterprise', 'groupsenterprise': 'groups_enterprise',
'hangoutsmeet': 'meet',
'jamboard': 'jamboard', 'jamboard': 'jamboard',
'keep': 'keep', 'keep': 'keep',
'login': 'login', 'login': 'login',
'logins': 'login',
'lookerstudio': 'data_studio',
'meet': 'meet', 'meet': 'meet',
'mobile': 'mobile', 'mobile': 'mobile',
'oauthtoken': 'token',
'rules': 'rules', 'rules': 'rules',
'saml': 'saml', 'saml': 'saml',
'token': 'token', 'token': 'token',
'tokens': 'token',
'usage': 'usage', 'usage': 'usage',
'usageparameters': 'usageparameters', 'usageparameters': 'usageparameters',
'user': 'user', 'user': 'user',
'users': 'user',
'useraccounts': 'user_accounts', 'useraccounts': 'user_accounts',
'vault': 'vault', 'vault': 'vault',
} }
@@ -13883,7 +13895,7 @@ def doReport():
if dyn_choice.replace('_', '') not in REPORT_CHOICE_MAP and \ if dyn_choice.replace('_', '') not in REPORT_CHOICE_MAP and \
dyn_choice not in REPORT_CHOICE_MAP.values(): dyn_choice not in REPORT_CHOICE_MAP.values():
REPORT_CHOICE_MAP[dyn_choice.replace('_', '')] = dyn_choice REPORT_CHOICE_MAP[dyn_choice.replace('_', '')] = dyn_choice
report = getChoice(REPORT_CHOICE_MAP, mapChoice=True) report = getChoice(REPORT_CHOICE_MAP, choiceAliases=REPORT_ALIASES_CHOICE_MAP, mapChoice=True)
if report == 'usage': if report == 'usage':
doReportUsage() doReportUsage()
return return
@@ -29505,6 +29517,7 @@ def getCIDeviceEntity():
return ([], ci, customer, False) return ([], ci, customer, False)
DEVICE_USERNAME_PATTERN = re.compile(r'^(devices/.+)/(deviceUsers/.+)$') DEVICE_USERNAME_PATTERN = re.compile(r'^(devices/.+)/(deviceUsers/.+)$')
DEVICE_USERNAME_CLIENT_STATE_PATTERN = re.compile(r'^(devices/.+/deviceUsers/.+)/clientStates/(.+)$')
DEVICE_USERNAME_FORMAT_REQUIRED = 'devices/<String>/deviceUsers/<String>' DEVICE_USERNAME_FORMAT_REQUIRED = 'devices/<String>/deviceUsers/<String>'
def getCIDeviceUserEntity(): def getCIDeviceUserEntity():
ci = buildGAPICIDeviceServiceObject() ci = buildGAPICIDeviceServiceObject()
@@ -29953,6 +29966,7 @@ DEVICE_ORDERBY_CHOICE_MAP = {
# [orderby <DeviceOrderByFieldName> [ascending|descending]] # [orderby <DeviceOrderByFieldName> [ascending|descending]]
# [all|company|personal|nocompanydevices|nopersonaldevices] # [all|company|personal|nocompanydevices|nopersonaldevices]
# [nodeviceusers|oneuserperrow] # [nodeviceusers|oneuserperrow]
# [clientstates]
# [formatjson [quotechar <Character>]] # [formatjson [quotechar <Character>]]
# [showitemcountonly] # [showitemcountonly]
def doPrintCIDevices(): def doPrintCIDevices():
@@ -29968,6 +29982,7 @@ def doPrintCIDevices():
queries = [None] queries = [None]
view, entityType = DEVICE_VIEW_CHOICE_MAP['all'] view, entityType = DEVICE_VIEW_CHOICE_MAP['all']
getDeviceUsers = True getDeviceUsers = True
getClientStates = False
oneUserPerRow = showItemCountOnly = False oneUserPerRow = showItemCountOnly = False
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
@@ -29983,6 +29998,8 @@ def doPrintCIDevices():
view, entityType = DEVICE_VIEW_CHOICE_MAP[myarg] view, entityType = DEVICE_VIEW_CHOICE_MAP[myarg]
elif myarg == 'nodeviceusers': elif myarg == 'nodeviceusers':
getDeviceUsers = False getDeviceUsers = False
elif myarg == 'clientstates':
getClientStates = True
elif myarg in {'oneuserperrow', 'oneitemperrow'}: elif myarg in {'oneuserperrow', 'oneitemperrow'}:
getDeviceUsers = oneUserPerRow = True getDeviceUsers = oneUserPerRow = True
elif getFieldsList(myarg, DEVICE_FIELDS_CHOICE_MAP, fieldsList, initialField='name'): elif getFieldsList(myarg, DEVICE_FIELDS_CHOICE_MAP, fieldsList, initialField='name'):
@@ -30001,14 +30018,16 @@ def doPrintCIDevices():
if FJQC.formatJSON and oneUserPerRow: if FJQC.formatJSON and oneUserPerRow:
csvPF.SetJSONTitles(['name', 'user.name', 'JSON']) csvPF.SetJSONTitles(['name', 'user.name', 'JSON'])
itemCount = 0 itemCount = 0
throwReasons = [GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED]
retryReasons = GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS
for query in queries: for query in queries:
printGettingAllAccountEntities(entityType, query) printGettingAllAccountEntities(entityType, query)
pageMessage = getPageMessage() pageMessage = getPageMessage()
try: try:
devices = callGAPIpages(ci.devices(), 'list', 'devices', devices = callGAPIpages(ci.devices(), 'list', 'devices',
pageMessage=pageMessage, pageMessage=pageMessage,
throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED], throwReasons=throwReasons,
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS, retryReasons=retryReasons,
customer=customer, filter=query, customer=customer, filter=query,
orderBy=OBY.orderBy, view=view, fields=fields, pageSize=100) orderBy=OBY.orderBy, view=view, fields=fields, pageSize=100)
if showItemCountOnly: if showItemCountOnly:
@@ -30027,10 +30046,27 @@ def doPrintCIDevices():
try: try:
deviceUsers = callGAPIpages(ci.devices().deviceUsers(), 'list', 'deviceUsers', deviceUsers = callGAPIpages(ci.devices().deviceUsers(), 'list', 'deviceUsers',
pageMessage=pageMessage, pageMessage=pageMessage,
throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED], throwReasons=throwReasons,
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS, retryReasons=retryReasons,
customer=customer, filter=query, parent=parent, customer=customer, filter=query, parent=parent,
orderBy=OBY.orderBy, fields=userFields, pageSize=20) orderBy=OBY.orderBy, fields=userFields, pageSize=20)
if getClientStates:
printGettingAllAccountEntities(Ent.DEVICE_USER_CLIENT_STATE, None)
states = callGAPIpages(ci.devices().deviceUsers().clientStates(), 'list', 'clientStates',
pageMessage=pageMessage,
throwReasons=throwReasons,
retryReasons=retryReasons,
customer=customer, filter=query, parent='devices/-/deviceUsers/-')
for state in states:
mg = DEVICE_USERNAME_CLIENT_STATE_PATTERN.match(state['name'])
if mg:
du = mg.group(1)
state_name = mg.group(2)
for i in range(len(deviceUsers)):
if deviceUsers[i]['name'] == du:
deviceUsers[i].setdefault('clientstates', {})
deviceUsers[i]['clientstates'][state_name] = state
break
for deviceUser in deviceUsers: for deviceUser in deviceUsers:
mg = DEVICE_USERNAME_PATTERN.match(deviceUser['name']) mg = DEVICE_USERNAME_PATTERN.match(deviceUser['name'])
if mg: if mg:
@@ -59495,6 +59531,7 @@ def _copyPermissions(drive, user, i, count, j, jcount,
GAPI.fileOrganizerNotYetEnabledForThisTeamDrive, GAPI.fileOrganizerNotYetEnabledForThisTeamDrive,
GAPI.fileOrganizerOnFoldersInSharedDriveOnly, GAPI.fileOrganizerOnFoldersInSharedDriveOnly,
GAPI.fileOrganizerOnNonTeamDriveNotSupported, GAPI.fileOrganizerOnNonTeamDriveNotSupported,
GAPI.cannotModifyInheritedPermission,
GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility, GAPI.abusiveContentRestriction) as e: GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility, GAPI.abusiveContentRestriction) as e:
entityActionFailedWarning(kvList, str(e), k, kcount) entityActionFailedWarning(kvList, str(e), k, kcount)
break break
@@ -59524,7 +59561,8 @@ def _copyPermissions(drive, user, i, count, j, jcount,
entityActionPerformed(kvList, k, kcount) entityActionPerformed(kvList, k, kcount)
except (GAPI.notFound, GAPI.permissionNotFound, except (GAPI.notFound, GAPI.permissionNotFound,
GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError, GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission, GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner,
GAPI.cannotModifyInheritedTeamDrivePermission, GAPI.cannotModifyInheritedPermission,
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e: GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e:
entityActionFailedWarning(kvList, str(e), k, kcount) entityActionFailedWarning(kvList, str(e), k, kcount)
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e: except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
@@ -59551,7 +59589,8 @@ def _copyPermissions(drive, user, i, count, j, jcount,
entityActionPerformed(kvList, k, kcount) entityActionPerformed(kvList, k, kcount)
except (GAPI.notFound, GAPI.permissionNotFound, except (GAPI.notFound, GAPI.permissionNotFound,
GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError, GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission, GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner,
GAPI.cannotModifyInheritedTeamDrivePermission, GAPI.cannotModifyInheritedPermission,
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded) as e: GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded) as e:
entityActionFailedWarning(kvList, str(e), k, kcount) entityActionFailedWarning(kvList, str(e), k, kcount)
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e: except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
@@ -60558,7 +60597,8 @@ def _updateMoveFilePermissions(drive, user, i, count,
entityActionPerformed(kvList, k, kcount) entityActionPerformed(kvList, k, kcount)
except (GAPI.notFound, GAPI.permissionNotFound, except (GAPI.notFound, GAPI.permissionNotFound,
GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError, GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission, GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner,
GAPI.cannotModifyInheritedTeamDrivePermission, GAPI.cannotModifyInheritedPermission,
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e: GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e:
entityActionFailedWarning(kvList, str(e), k, kcount) entityActionFailedWarning(kvList, str(e), k, kcount)
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e: except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
@@ -60599,6 +60639,7 @@ def _updateMoveFilePermissions(drive, user, i, count,
GAPI.fileOrganizerNotYetEnabledForThisTeamDrive, GAPI.fileOrganizerNotYetEnabledForThisTeamDrive,
GAPI.fileOrganizerOnFoldersInSharedDriveOnly, GAPI.fileOrganizerOnFoldersInSharedDriveOnly,
GAPI.fileOrganizerOnNonTeamDriveNotSupported, GAPI.fileOrganizerOnNonTeamDriveNotSupported,
GAPI.cannotModifyInheritedPermission,
GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility, GAPI.abusiveContentRestriction) as e: GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility, GAPI.abusiveContentRestriction) as e:
entityActionFailedWarning(kvList, str(e), k, kcount) entityActionFailedWarning(kvList, str(e), k, kcount)
break break
@@ -63853,6 +63894,7 @@ def createDriveFileACL(users, useDomainAdminAccess=False):
GAPI.fileOrganizerNotYetEnabledForThisTeamDrive, GAPI.fileOrganizerNotYetEnabledForThisTeamDrive,
GAPI.fileOrganizerOnFoldersInSharedDriveOnly, GAPI.fileOrganizerOnFoldersInSharedDriveOnly,
GAPI.fileOrganizerOnNonTeamDriveNotSupported, GAPI.fileOrganizerOnNonTeamDriveNotSupported,
GAPI.cannotModifyInheritedPermission,
GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility, GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility,
GAPI.invalidSharingRequest, GAPI.fileNeverWritable, GAPI.abusiveContentRestriction) as e: GAPI.invalidSharingRequest, GAPI.fileNeverWritable, GAPI.abusiveContentRestriction) as e:
entityActionFailedWarning([Ent.USER, user, entityType, fileName, Ent.PERMISSION_ID, permissionId], str(e), j, jcount) entityActionFailedWarning([Ent.USER, user, entityType, fileName, Ent.PERMISSION_ID, permissionId], str(e), j, jcount)
@@ -63981,7 +64023,8 @@ def updateDriveFileACLs(users, useDomainAdminAccess=False):
GAPI.targetUserRoleLimitedByLicenseRestriction, GAPI.insufficientAdministratorPrivileges, GAPI.targetUserRoleLimitedByLicenseRestriction, GAPI.insufficientAdministratorPrivileges,
GAPI.publishOutNotPermitted, GAPI.shareInNotPermitted, GAPI.shareOutNotPermitted, GAPI.shareOutNotPermittedToUser, GAPI.publishOutNotPermitted, GAPI.shareInNotPermitted, GAPI.shareOutNotPermitted, GAPI.shareOutNotPermittedToUser,
GAPI.organizerOnNonTeamDriveItemNotSupported, GAPI.fileOrganizerOnNonTeamDriveNotSupported, GAPI.organizerOnNonTeamDriveItemNotSupported, GAPI.fileOrganizerOnNonTeamDriveNotSupported,
GAPI.cannotUpdatePermission, GAPI.cannotModifyInheritedTeamDrivePermission, GAPI.fieldNotWritable) as e: GAPI.cannotUpdatePermission, GAPI.cannotModifyInheritedTeamDrivePermission, GAPI.cannotModifyInheritedPermission,
GAPI.fieldNotWritable) as e:
entityActionFailedWarning([Ent.USER, user, entityType, fileName], str(e), j, jcount) entityActionFailedWarning([Ent.USER, user, entityType, fileName], str(e), j, jcount)
except (GAPI.notFound, GAPI.teamDriveDomainUsersOnlyRestriction, GAPI.teamDriveTeamMembersOnlyRestriction, except (GAPI.notFound, GAPI.teamDriveDomainUsersOnlyRestriction, GAPI.teamDriveTeamMembersOnlyRestriction,
GAPI.cannotShareTeamDriveTopFolderWithAnyoneOrDomains, GAPI.ownerOnTeamDriveItemNotSupported, GAPI.cannotShareTeamDriveTopFolderWithAnyoneOrDomains, GAPI.ownerOnTeamDriveItemNotSupported,
@@ -64087,6 +64130,7 @@ def createDriveFilePermissions(users, useDomainAdminAccess=False):
GAPI.fileOrganizerNotYetEnabledForThisTeamDrive, GAPI.fileOrganizerNotYetEnabledForThisTeamDrive,
GAPI.fileOrganizerOnFoldersInSharedDriveOnly, GAPI.fileOrganizerOnFoldersInSharedDriveOnly,
GAPI.fileOrganizerOnNonTeamDriveNotSupported, GAPI.fileOrganizerOnNonTeamDriveNotSupported,
GAPI.cannotModifyInheritedPermission,
GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility, GAPI.teamDrivesFolderSharingNotSupported, GAPI.invalidLinkVisibility,
GAPI.invalidSharingRequest, GAPI.fileNeverWritable, GAPI.abusiveContentRestriction, GAPI.invalidSharingRequest, GAPI.fileNeverWritable, GAPI.abusiveContentRestriction,
GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e: GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
@@ -64254,7 +64298,8 @@ def deleteDriveFileACLs(users, useDomainAdminAccess=False):
if updateSheetProtectedRanges and mimeType == MIMETYPE_GA_SPREADSHEET: if updateSheetProtectedRanges and mimeType == MIMETYPE_GA_SPREADSHEET:
_updateSheetProtectedRangesACLchange(sheet, user, i, count, j, jcount, fileId, fileName, False, permission) _updateSheetProtectedRangesACLchange(sheet, user, i, count, j, jcount, fileId, fileName, False, permission)
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError, except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission, GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner,
GAPI.cannotModifyInheritedTeamDrivePermission, GAPI.cannotModifyInheritedPermission,
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e: GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e:
entityActionFailedWarning([Ent.USER, user, entityType, fileName], str(e), j, jcount) entityActionFailedWarning([Ent.USER, user, entityType, fileName], str(e), j, jcount)
except GAPI.notFound as e: except GAPI.notFound as e:
@@ -64310,7 +64355,8 @@ def deletePermissions(users, useDomainAdminAccess=False):
fileId=ri[RI_ENTITY], permissionId=ri[RI_ITEM], supportsAllDrives=True) fileId=ri[RI_ENTITY], permissionId=ri[RI_ITEM], supportsAllDrives=True)
entityActionPerformed([Ent.DRIVE_FILE_OR_FOLDER_ID, ri[RI_ENTITY], Ent.PERMISSION_ID, ri[RI_ITEM]], int(ri[RI_J]), int(ri[RI_JCOUNT])) entityActionPerformed([Ent.DRIVE_FILE_OR_FOLDER_ID, ri[RI_ENTITY], Ent.PERMISSION_ID, ri[RI_ITEM]], int(ri[RI_J]), int(ri[RI_JCOUNT]))
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError, except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission, GAPI.badRequest, GAPI.cannotRemoveOwner,
GAPI.cannotModifyInheritedTeamDrivePermission, GAPI.cannotModifyInheritedPermission,
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.permissionNotFound, GAPI.cannotDeletePermission, GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.permissionNotFound, GAPI.cannotDeletePermission,
GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e: GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
entityActionFailedWarning([Ent.DRIVE_FILE_OR_FOLDER_ID, ri[RI_ENTITY], Ent.PERMISSION_ID, ri[RI_ITEM]], str(e), int(ri[RI_J]), int(ri[RI_JCOUNT])) entityActionFailedWarning([Ent.DRIVE_FILE_OR_FOLDER_ID, ri[RI_ENTITY], Ent.PERMISSION_ID, ri[RI_ITEM]], str(e), int(ri[RI_J]), int(ri[RI_JCOUNT]))
@@ -65754,7 +65800,7 @@ def _showSharedDrive(user, shareddrive, j, jcount, FJQC):
printKeyValueList(['hidden', shareddrive['hidden']]) printKeyValueList(['hidden', shareddrive['hidden']])
if 'createdTime' in shareddrive: if 'createdTime' in shareddrive:
printKeyValueList(['createdTime', formatLocalTime(shareddrive['createdTime'])]) printKeyValueList(['createdTime', formatLocalTime(shareddrive['createdTime'])])
for setting in ['backgroundImageLink', 'colorRgb', 'themeId', 'orgUnit', 'orgUnitId']: for setting in ['backgroundImageLink', 'colorRgb', 'themeId', 'orgUnit', 'orgUnitId', 'webViewLink']:
if setting in shareddrive: if setting in shareddrive:
printKeyValueList([setting, shareddrive[setting]]) printKeyValueList([setting, shareddrive[setting]])
if 'role' in shareddrive: if 'role' in shareddrive:
@@ -65829,6 +65875,7 @@ SHAREDDRIVE_ACL_ROLES_MAP = {
# [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>] # [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>]
# (role|roles <SharedDriveACLRoleList>)* # (role|roles <SharedDriveACLRoleList>)*
# [fields <SharedDriveFieldNameList>] [noorgunits [<Boolean>]] # [fields <SharedDriveFieldNameList>] [noorgunits [<Boolean>]]
# [showwebviewlink]
# [guiroles [<Boolean>]] [formatjson [quotechar <Character>]] # [guiroles [<Boolean>]] [formatjson [quotechar <Character>]]
# [showitemcountonly] # [showitemcountonly]
# gam <UserTypeEntity> show shareddrives # gam <UserTypeEntity> show shareddrives
@@ -65836,6 +65883,7 @@ SHAREDDRIVE_ACL_ROLES_MAP = {
# [matchname <REMatchPattrn>] [orgunit|org|ou <OrgUnitPath>] # [matchname <REMatchPattrn>] [orgunit|org|ou <OrgUnitPath>]
# (role|roles <SharedDriveACLRoleLIst>)* # (role|roles <SharedDriveACLRoleLIst>)*
# [fields <SharedDriveFieldNameList>] [noorgunits [<Boolean>]] # [fields <SharedDriveFieldNameList>] [noorgunits [<Boolean>]]
# [showwebviewlink]
# [guiroles [<Boolean>]] [formatjson] # [guiroles [<Boolean>]] [formatjson]
# [showitemcountonly] # [showitemcountonly]
def printShowSharedDrives(users, useDomainAdminAccess=False): def printShowSharedDrives(users, useDomainAdminAccess=False):
@@ -65844,6 +65892,8 @@ def printShowSharedDrives(users, useDomainAdminAccess=False):
td_ouid = shareddrive.get('orgUnitId') td_ouid = shareddrive.get('orgUnitId')
if td_ouid: if td_ouid:
shareddrive['orgUnit'] = orgUnitIdToPathMap.get(f'id:{td_ouid}', UNKNOWN) shareddrive['orgUnit'] = orgUnitIdToPathMap.get(f'id:{td_ouid}', UNKNOWN)
if showWebViewLink:
shareddrive['webViewLink'] = 'https://drive.google.com/drive/folders/'+shareddrive['id']
if not showFields: if not showFields:
return shareddrive return shareddrive
sshareddrive = {} sshareddrive = {}
@@ -65862,6 +65912,7 @@ def printShowSharedDrives(users, useDomainAdminAccess=False):
showOrgUnitPaths = True showOrgUnitPaths = True
orgUnitIdToPathMap = None orgUnitIdToPathMap = None
guiRoles = showItemCountOnly = False guiRoles = showItemCountOnly = False
showWebViewLink = False
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
if csvPF and myarg == 'todrive': if csvPF and myarg == 'todrive':
@@ -65891,6 +65942,8 @@ def printShowSharedDrives(users, useDomainAdminAccess=False):
showOrgUnitPaths = not getBoolean() showOrgUnitPaths = not getBoolean()
elif myarg == 'guiroles': elif myarg == 'guiroles':
guiRoles = getBoolean() guiRoles = getBoolean()
elif myarg == 'showwebviewlink':
showWebViewLink = True
elif myarg == 'showitemcountonly': elif myarg == 'showitemcountonly':
showItemCountOnly = True showItemCountOnly = True
showOrgUnitPaths = False showOrgUnitPaths = False
@@ -65915,6 +65968,14 @@ def printShowSharedDrives(users, useDomainAdminAccess=False):
orgUnitIdToPathMap = getOrgUnitIdToPathMap(cd) orgUnitIdToPathMap = getOrgUnitIdToPathMap(cd)
if showFields: if showFields:
showFields.add('orgUnit') showFields.add('orgUnit')
if showWebViewLink:
if showFields:
showFields.add('webViewLink')
if csvPF:
csvPF.AddTitle('webViewLink')
if FJQC.formatJSON:
csvPF.AddJSONTitles(['webViewLink'])
csvPF.MoveJSONTitlesToEnd(['JSON'])
i, count, users = getEntityArgument(users) i, count, users = getEntityArgument(users)
for user in users: for user in users:
i += 1 i += 1
@@ -65983,6 +66044,8 @@ def printShowSharedDrives(users, useDomainAdminAccess=False):
row = {'User': user, 'id': shareddrive['id'], 'name': shareddrive['name']} row = {'User': user, 'id': shareddrive['id'], 'name': shareddrive['name']}
if not useDomainAdminAccess: if not useDomainAdminAccess:
row['role'] = shareddrive['role'] if not guiRoles else SHAREDDRIVE_API_GUI_ROLES_MAP[shareddrive['role']] row['role'] = shareddrive['role'] if not guiRoles else SHAREDDRIVE_API_GUI_ROLES_MAP[shareddrive['role']]
if showWebViewLink:
row['webViewLink'] = shareddrive['webViewLink']
row['JSON'] = json.dumps(cleanJSON(shareddrive, timeObjects=SHAREDDRIVE_TIME_OBJECTS), ensure_ascii=False, sort_keys=True) row['JSON'] = json.dumps(cleanJSON(shareddrive, timeObjects=SHAREDDRIVE_TIME_OBJECTS), ensure_ascii=False, sort_keys=True)
csvPF.WriteRow(row) csvPF.WriteRow(row)
else: else:
@@ -70209,14 +70272,16 @@ def _finalizeMessageSelectParameters(parameters, queryOrIdsRequired):
for queryTimeName, queryTimeValue in iter(parameters['queryTimes'].items()): for queryTimeName, queryTimeValue in iter(parameters['queryTimes'].items()):
parameters['query'] = parameters['query'].replace(f'#{queryTimeName}#', queryTimeValue) parameters['query'] = parameters['query'].replace(f'#{queryTimeName}#', queryTimeValue)
_mapMessageQueryDates(parameters) _mapMessageQueryDates(parameters)
elif queryOrIdsRequired and parameters['messageEntity'] is None: elif queryOrIdsRequired and parameters['messageEntity'] is None and not parameters['labelIds']:
missingArgumentExit('query|matchlabel|ids') missingArgumentExit('query|matchlabel|ids|labelids')
else: else:
parameters['query'] = None parameters['query'] = None
parameters['maxItems'] = parameters['maxToProcess'] if parameters['quick'] and not parameters['labelMatchPattern'] else 0 parameters['maxItems'] = parameters['maxToProcess'] if parameters['quick'] and not parameters['labelMatchPattern'] else 0
# gam <UserTypeEntity> archive messages <GroupItem> # gam <UserTypeEntity> archive messages <GroupItem>
# (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_archive <Number>])|(ids <MessageIDEntity>) # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
# [labelids <LabelIDList>]
# [quick|notquick] [doit] [max_to_archive <Number>])|(ids <MessageIDEntity>)
# [csv [todrive <ToDriveAttribute>*]] # [csv [todrive <ToDriveAttribute>*]]
def archiveMessages(users): def archiveMessages(users):
def _processMessageFailed(user, idsList, errMsg, j=0, jcount=0): def _processMessageFailed(user, idsList, errMsg, j=0, jcount=0):
@@ -70267,7 +70332,8 @@ def archiveMessages(users):
listResult = callGAPIpages(service, 'list', parameters['listType'], listResult = callGAPIpages(service, 'list', parameters['listType'],
pageMessage=getPageMessageForWhom(), maxItems=parameters['maxItems'], pageMessage=getPageMessageForWhom(), maxItems=parameters['maxItems'],
throwReasons=GAPI.GMAIL_THROW_REASONS+GAPI.GMAIL_LIST_THROW_REASONS, throwReasons=GAPI.GMAIL_THROW_REASONS+GAPI.GMAIL_LIST_THROW_REASONS,
userId='me', q=parameters['query'], fields=parameters['fields'], userId='me', q=parameters['query'], labelIds=parameters['labelIds'],
fields=parameters['fields'],
maxResults=GC.Values[GC.MESSAGE_MAX_RESULTS]) maxResults=GC.Values[GC.MESSAGE_MAX_RESULTS])
messageIds = [message['id'] for message in listResult] messageIds = [message['id'] for message in listResult]
except (GAPI.failedPrecondition, GAPI.permissionDenied, GAPI.invalid, GAPI.invalidArgument) as e: except (GAPI.failedPrecondition, GAPI.permissionDenied, GAPI.invalid, GAPI.invalidArgument) as e:
@@ -70456,7 +70522,8 @@ def _processMessagesThreads(users, entityType):
listResult = callGAPIpages(service, 'list', parameters['listType'], listResult = callGAPIpages(service, 'list', parameters['listType'],
pageMessage=getPageMessageForWhom(), maxItems=parameters['maxItems'], pageMessage=getPageMessageForWhom(), maxItems=parameters['maxItems'],
throwReasons=GAPI.GMAIL_THROW_REASONS+GAPI.GMAIL_LIST_THROW_REASONS, throwReasons=GAPI.GMAIL_THROW_REASONS+GAPI.GMAIL_LIST_THROW_REASONS,
userId='me', q=parameters['query'], fields=parameters['fields'], includeSpamTrash=includeSpamTrash, userId='me', q=parameters['query'], labelIds=parameters['labelIds'],
fields=parameters['fields'], includeSpamTrash=includeSpamTrash,
maxResults=GC.Values[GC.MESSAGE_MAX_RESULTS]) maxResults=GC.Values[GC.MESSAGE_MAX_RESULTS])
messageIds = [message['id'] for message in listResult] messageIds = [message['id'] for message in listResult]
else: else:
@@ -70499,39 +70566,59 @@ def _processMessagesThreads(users, entityType):
csvPF.writeCSVfile(f'{Act.ToPerform()} Messages') csvPF.writeCSVfile(f'{Act.ToPerform()} Messages')
# gam <UserTypeEntity> delete message|messages # gam <UserTypeEntity> delete message|messages
# (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_delete <Number>])|(ids <MessageIDEntity>) # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
# [labelids <LabelIDList>]
# [quick|notquick] [doit] [max_to_delete <Number>])|(ids <MessageIDEntity>)
# [csv [todrive <ToDriveAttribute>*]] # [csv [todrive <ToDriveAttribute>*]]
# gam <UserTypeEntity> modify message|messages # gam <UserTypeEntity> modify message|messages
# (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_modify <Number>])|(ids <MessageIDEntity>) # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
# [labelids <LabelIDList>]
# [quick|notquick] [doit] [max_to_modify <Number>])|(ids <MessageIDEntity>)
# (addlabel <LabelName>)* (removelabel <LabelName>)* # (addlabel <LabelName>)* (removelabel <LabelName>)*
# [csv [todrive <ToDriveAttribute>*]] # [csv [todrive <ToDriveAttribute>*]]
# gam <UserTypeEntity> spam message|messages # gam <UserTypeEntity> spam message|messages
# (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_spam <Number>])|(ids <MessageIDEntity>) # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
# [labelids <LabelIDList>]
# [quick|notquick] [doit] [max_to_spam <Number>])|(ids <MessageIDEntity>)
# [csv [todrive <ToDriveAttribute>*]] # [csv [todrive <ToDriveAttribute>*]]
# gam <UserTypeEntity> trash message|messages # gam <UserTypeEntity> trash message|messages
# (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_trash <Number>])|(ids <MessageIDEntity>) # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
# [labelids <LabelIDList>]
# [quick|notquick] [doit] [max_to_trash <Number>])|(ids <MessageIDEntity>)
# [csv [todrive <ToDriveAttribute>*]] # [csv [todrive <ToDriveAttribute>*]]
# gam <UserTypeEntity> untrash message|messages # gam <UserTypeEntity> untrash message|messages
# (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_untrash <Number>])|(ids <MessageIDEntity>) # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
# [labelids <LabelIDList>]
# [quick|notquick] [doit] [max_to_untrash <Number>])|(ids <MessageIDEntity>)
# [csv [todrive <ToDriveAttribute>*]] # [csv [todrive <ToDriveAttribute>*]]
def processMessages(users): def processMessages(users):
_processMessagesThreads(users, Ent.MESSAGE) _processMessagesThreads(users, Ent.MESSAGE)
# gam <UserTypeEntity> delete thread|threads # gam <UserTypeEntity> delete thread|threads
# (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_delete <Number>])|(ids <ThreadIDEntity>) # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
# [labelids <LabelIDList>]
# [quick|notquick] [doit] [max_to_delete <Number>])|(ids <ThreadIDEntity>)
# [csv [todrive <ToDriveAttribute>*]] # [csv [todrive <ToDriveAttribute>*]]
# gam <UserTypeEntity> modify thread|threads # gam <UserTypeEntity> modify thread|threads
# (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_modify <Number>])|(ids <ThreadIDEntity>) # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
# [labelids <LabelIDList>]
# [quick|notquick] [doit] [max_to_modify <Number>])|(ids <ThreadIDEntity>)
# (addlabel <LabelName>)* (removelabel <LabelName>)* # (addlabel <LabelName>)* (removelabel <LabelName>)*
# [csv [todrive <ToDriveAttribute>*]] # [csv [todrive <ToDriveAttribute>*]]
# gam <UserTypeEntity> spam thread|threads # gam <UserTypeEntity> spam thread|threads
# (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_spam <Number>])|(ids <ThreadIDEntity>) # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
# [labelids <LabelIDList>]
# [quick|notquick] [doit] [max_to_spam <Number>])|(ids <ThreadIDEntity>)
# [csv [todrive <ToDriveAttribute>*]] # [csv [todrive <ToDriveAttribute>*]]
# gam <UserTypeEntity> trash thread|threads # gam <UserTypeEntity> trash thread|threads
# (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_trash <Number>])|(ids <MessageIDEntity>) # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
# [labelids <LabelIDList>]
# [quick|notquick] [doit] [max_to_trash <Number>])|(ids <ThreadIDEntity>)
# [csv [todrive <ToDriveAttribute>*]] # [csv [todrive <ToDriveAttribute>*]]
# gam <UserTypeEntity> untrash thread|threads # gam <UserTypeEntity> untrash thread|threads
# (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_untrash <Number>])|(ids <ThreadIDEntity>) # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
# [labelids <LabelIDList>]
# [quick|notquick] [doit] [max_to_untrash <Number>])|(ids <ThreadIDEntity>)
# [csv [todrive <ToDriveAttribute>*]] # [csv [todrive <ToDriveAttribute>*]]
def processThreads(users): def processThreads(users):
_processMessagesThreads(users, Ent.THREAD) _processMessagesThreads(users, Ent.THREAD)
@@ -70572,7 +70659,8 @@ def exportMessagesThreads(users, entityType):
listResult = callGAPIpages(service, 'list', parameters['listType'], listResult = callGAPIpages(service, 'list', parameters['listType'],
pageMessage=getPageMessageForWhom(), maxItems=parameters['maxItems'], pageMessage=getPageMessageForWhom(), maxItems=parameters['maxItems'],
throwReasons=GAPI.GMAIL_THROW_REASONS+GAPI.GMAIL_LIST_THROW_REASONS, throwReasons=GAPI.GMAIL_THROW_REASONS+GAPI.GMAIL_LIST_THROW_REASONS,
userId='me', q=parameters['query'], fields=parameters['fields'], includeSpamTrash=includeSpamTrash, userId='me', q=parameters['query'], labelIds=parameters['labelIds'],
fields=parameters['fields'], includeSpamTrash=includeSpamTrash,
maxResults=GC.Values[GC.MESSAGE_MAX_RESULTS]) maxResults=GC.Values[GC.MESSAGE_MAX_RESULTS])
entityIds = [entity['id'] for entity in listResult] entityIds = [entity['id'] for entity in listResult]
except (GAPI.failedPrecondition, GAPI.permissionDenied, GAPI.invalid, GAPI.invalidArgument) as e: except (GAPI.failedPrecondition, GAPI.permissionDenied, GAPI.invalid, GAPI.invalidArgument) as e:
@@ -70707,7 +70795,8 @@ def forwardMessagesThreads(users, entityType):
listResult = callGAPIpages(service, 'list', parameters['listType'], listResult = callGAPIpages(service, 'list', parameters['listType'],
pageMessage=getPageMessageForWhom(), maxItems=parameters['maxItems'], pageMessage=getPageMessageForWhom(), maxItems=parameters['maxItems'],
throwReasons=GAPI.GMAIL_THROW_REASONS+GAPI.GMAIL_LIST_THROW_REASONS, throwReasons=GAPI.GMAIL_THROW_REASONS+GAPI.GMAIL_LIST_THROW_REASONS,
userId='me', q=parameters['query'], fields=parameters['fields'], includeSpamTrash=includeSpamTrash, userId='me', q=parameters['query'], labelIds=parameters['labelIds'],
fields=parameters['fields'], includeSpamTrash=includeSpamTrash,
maxResults=GC.Values[GC.MESSAGE_MAX_RESULTS]) maxResults=GC.Values[GC.MESSAGE_MAX_RESULTS])
entityIds = [entity['id'] for entity in listResult] entityIds = [entity['id'] for entity in listResult]
except (GAPI.failedPrecondition, GAPI.permissionDenied, GAPI.invalid, GAPI.invalidArgument) as e: except (GAPI.failedPrecondition, GAPI.permissionDenied, GAPI.invalid, GAPI.invalidArgument) as e:
@@ -71951,7 +72040,9 @@ def printShowMessagesThreads(users, entityType):
csvPF.writeCSVfile('Message Counts' if not show_labels else 'Message Label Counts') csvPF.writeCSVfile('Message Counts' if not show_labels else 'Message Label Counts')
# gam <UserTypeEntity> print message|messages [todrive <ToDriveAttribute>*] # gam <UserTypeEntity> print message|messages [todrive <ToDriveAttribute>*]
# (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])* [quick|notquick] [max_to_print <Number>] [includespamtrash])|(ids <MessageIDEntity>) # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])*
# [labelids <LabelIDList>]
# [quick|notquick] [max_to_print <Number>] [includespamtrash])|(ids <MessageIDEntity>)
# [labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>] # [labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>]
# [headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]] # [headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]]
# [showlabels] [showbody] [showhtml] [showdate] [showsize] [showsnippet] # [showlabels] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
@@ -71961,7 +72052,9 @@ def printShowMessagesThreads(users, entityType):
# [showattachments [noshowtextplain]]] # [showattachments [noshowtextplain]]]
# (addcsvdata <FieldName> <String>)* # (addcsvdata <FieldName> <String>)*
# gam <UserTypeEntity> show message|messages # gam <UserTypeEntity> show message|messages
# (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])* [quick|notquick] [max_to_show <Number>] [includespamtrash])|(ids <MessageIDEntity>) # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])*
# [labelids <LabelIDList>]
# [quick|notquick] [max_to_show <Number>] [includespamtrash])|(ids <MessageIDEntity>)
# [labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>] # [labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>]
# [headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]] # [headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]]
# [showlabels] [showbody] [showhtml] [showdate] [showsize] [showsnippet] # [showlabels] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
@@ -71974,7 +72067,9 @@ def printShowMessages(users):
printShowMessagesThreads(users, Ent.MESSAGE) printShowMessagesThreads(users, Ent.MESSAGE)
# gam <UserTypeEntity> print thread|threads [todrive <ToDriveAttribute>*] # gam <UserTypeEntity> print thread|threads [todrive <ToDriveAttribute>*]
# (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])* [quick|notquick] [max_to_print <Number>] [includespamtrash])|(ids <ThreadIDEntity>) # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])*
# [labelids <LabelIDList>]
# [quick|notquick] [max_to_print <Number>] [includespamtrash])|(ids <ThreadIDEntity>)
# [labelmatchpattern <REMatchPattern>] # [labelmatchpattern <REMatchPattern>]
# [headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]] # [headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]]
# [showlabels] [showbody] [showhtml] [showdate] [showsize] [showsnippet] # [showlabels] [showbody] [showhtml] [showdate] [showsize] [showsnippet]
@@ -71984,7 +72079,9 @@ def printShowMessages(users):
# [showattachments [noshowtextplain]]] # [showattachments [noshowtextplain]]]
# (addcsvdata <FieldName> <String>)* # (addcsvdata <FieldName> <String>)*
# gam <UserTypeEntity> show thread|threads # gam <UserTypeEntity> show thread|threads
# (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])* [quick|notquick] [max_to_show <Number>] [includespamtrash])|(ids <ThreadIDEntity>) # (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])*
# [labelids <LabelIDList>]
# [quick|notquick] [max_to_show <Number>] [includespamtrash])|(ids <ThreadIDEntity>)
# [labelmatchpattern <REMatchPattern>] # [labelmatchpattern <REMatchPattern>]
# [headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]] # [headers all|<SMTPHeaderList>] [dateheaderformat iso|rfc2822|<String>] [dateheaderconverttimezone [<Boolean>]]
# [showlabels] [showbody] [showhtml] [showdate] [showsize] [showsnippet] # [showlabels] [showbody] [showhtml] [showdate] [showsize] [showsnippet]

View File

@@ -226,15 +226,15 @@ _INFO = {
CHROMEMANAGEMENT_TELEMETRY: {'name': 'Chrome Management API - Telemetry', '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}, CHROMEPOLICY: {'name': 'Chrome Policy API', 'version': 'v1', 'v2discovery': True},
CHROMEVERSIONHISTORY: {'name': 'Chrome Version History API', 'version': 'v1', 'v2discovery': True}, CHROMEVERSIONHISTORY: {'name': 'Chrome Version History API', 'version': 'v1', 'v2discovery': True},
CLOUDCHANNEL: {'name': 'Channel Channel API', 'version': 'v1', 'v2discovery': True}, CLOUDCHANNEL: {'name': 'Cloud Channel API', 'version': 'v1', 'v2discovery': True},
CLOUDIDENTITY_DEVICES: {'name': 'Cloud Identity Devices API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'}, CLOUDIDENTITY_DEVICES: {'name': 'Cloud Identity API - Devices', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
CLOUDIDENTITY_GROUPS: {'name': 'Cloud Identity Groups API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'}, CLOUDIDENTITY_GROUPS: {'name': 'Cloud Identity API - Groups', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
CLOUDIDENTITY_GROUPS_BETA: {'name': 'Cloud Identity Groups API', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'}, CLOUDIDENTITY_GROUPS_BETA: {'name': 'Cloud Identity API - Groups Beta', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
CLOUDIDENTITY_INBOUND_SSO: {'name': 'Cloud Identity Inbound SSO API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'}, CLOUDIDENTITY_INBOUND_SSO: {'name': 'Cloud Identity API - Inbound SSO Settings', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
CLOUDIDENTITY_ORGUNITS: {'name': 'Cloud Identity OrgUnits API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'}, CLOUDIDENTITY_ORGUNITS: {'name': 'Cloud Identity API - OrgUnits', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
CLOUDIDENTITY_ORGUNITS_BETA: {'name': 'Cloud Identity OrgUnits API', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'}, CLOUDIDENTITY_ORGUNITS_BETA: {'name': 'Cloud Identity API - OrgUnits Beta', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
CLOUDIDENTITY_POLICY: {'name': 'Cloud Identity Policy API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'}, CLOUDIDENTITY_POLICY: {'name': 'Cloud Identity API - Policy', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
CLOUDIDENTITY_USERINVITATIONS: {'name': 'Cloud Identity User Invitations API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'}, CLOUDIDENTITY_USERINVITATIONS: {'name': 'Cloud Identity API - User Invitations', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
CLOUDRESOURCEMANAGER: {'name': 'Cloud Resource Manager API v3', 'version': 'v3', 'v2discovery': True}, CLOUDRESOURCEMANAGER: {'name': 'Cloud Resource Manager API v3', 'version': 'v3', 'v2discovery': True},
CONTACTS: {'name': 'Contacts API', 'version': 'v3', 'v2discovery': False}, CONTACTS: {'name': 'Contacts API', 'version': 'v3', 'v2discovery': False},
CONTACTDELEGATION: {'name': 'Contact Delegation API', 'version': 'v1', 'v2discovery': True, 'localjson': True}, CONTACTDELEGATION: {'name': 'Contact Delegation API', 'version': 'v1', 'v2discovery': True, 'localjson': True},
@@ -258,13 +258,13 @@ _INFO = {
LICENSING: {'name': 'License Manager 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}, LOOKERSTUDIO: {'name': 'Looker Studio API', 'version': 'v1', 'v2discovery': True, 'localjson': True},
MEET: {'name': 'Meet API', 'version': 'v2', 'v2discovery': True}, MEET: {'name': 'Meet API', 'version': 'v2', 'v2discovery': True},
MEET_BETA: {'name': 'Meet API', 'version': 'v2beta', 'v2discovery': True, 'localjson': True, 'mappedAPI': MEET}, MEET_BETA: {'name': 'Meet API Beta', 'version': 'v2beta', 'v2discovery': True, 'localjson': True, 'mappedAPI': MEET},
OAUTH2: {'name': 'OAuth2 API', 'version': 'v2', 'v2discovery': False}, OAUTH2: {'name': 'OAuth2 API', 'version': 'v2', 'v2discovery': False},
ORGPOLICY: {'name': 'Organization Policy API', 'version': 'v2', 'v2discovery': True}, ORGPOLICY: {'name': 'Organization Policy API', 'version': 'v2', 'v2discovery': True},
PEOPLE: {'name': 'People API', 'version': 'v1', 'v2discovery': True}, PEOPLE: {'name': 'People API', 'version': 'v1', 'v2discovery': True},
PEOPLE_DIRECTORY: {'name': 'People Directory API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': PEOPLE}, PEOPLE_DIRECTORY: {'name': 'People Directory API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': PEOPLE},
PEOPLE_OTHERCONTACTS: {'name': 'People API - Other Contacts', 'version': 'v1', 'v2discovery': True, 'mappedAPI': PEOPLE}, PEOPLE_OTHERCONTACTS: {'name': 'People API - Other Contacts', 'version': 'v1', 'v2discovery': True, 'mappedAPI': PEOPLE},
PRINTERS: {'name': 'Directory API Printers', 'version': 'directory_v1', 'v2discovery': True, 'mappedAPI': 'admin'}, PRINTERS: {'name': 'Directory API - Printers', 'version': 'directory_v1', 'v2discovery': True, 'mappedAPI': 'admin'},
PUBSUB: {'name': 'Pub / Sub API', 'version': 'v1', 'v2discovery': True}, PUBSUB: {'name': 'Pub / Sub API', 'version': 'v1', 'v2discovery': True},
REPORTS: {'name': 'Reports API', 'version': 'reports_v1', 'v2discovery': True, 'mappedAPI': 'admin'}, REPORTS: {'name': 'Reports API', 'version': 'reports_v1', 'v2discovery': True, 'mappedAPI': 'admin'},
RESELLER: {'name': 'Reseller API', 'version': 'v1', 'v2discovery': True}, RESELLER: {'name': 'Reseller API', 'version': 'v1', 'v2discovery': True},
@@ -362,29 +362,29 @@ _CLIENT_SCOPES = [
'subscopes': READONLY, 'subscopes': READONLY,
'offByDefault': True, 'offByDefault': True,
'scope': 'https://www.googleapis.com/auth/apps.order'}, 'scope': 'https://www.googleapis.com/auth/apps.order'},
{'name': 'Cloud Identity Groups API', {'name': 'Cloud Identity API - Groups',
'api': CLOUDIDENTITY_GROUPS, 'api': CLOUDIDENTITY_GROUPS,
'subscopes': READONLY, 'subscopes': READONLY,
'scope': 'https://www.googleapis.com/auth/cloud-identity.groups'}, 'scope': 'https://www.googleapis.com/auth/cloud-identity.groups'},
{'name': 'Cloud Identity Groups API Beta (Enables group locking/unlocking)', {'name': 'Cloud Identity API - Groups Beta (Enables group locking/unlocking)',
'api': CLOUDIDENTITY_GROUPS_BETA, 'api': CLOUDIDENTITY_GROUPS_BETA,
'subscopes': [], 'subscopes': [],
'scope': 'https://www.googleapis.com/auth/cloud-identity.groups'}, 'scope': 'https://www.googleapis.com/auth/cloud-identity.groups'},
{'name': 'Cloud Identity - Inbound SSO Settings', {'name': 'Cloud Identity API - Inbound SSO Settings',
'api': CLOUDIDENTITY_INBOUND_SSO, 'api': CLOUDIDENTITY_INBOUND_SSO,
'subscopes': READONLY, 'subscopes': READONLY,
'scope': 'https://www.googleapis.com/auth/cloud-identity.inboundsso'}, 'scope': 'https://www.googleapis.com/auth/cloud-identity.inboundsso'},
{'name': 'Cloud Identity OrgUnits API', {'name': 'Cloud Identity API - OrgUnits Beta',
'api': CLOUDIDENTITY_ORGUNITS_BETA, 'api': CLOUDIDENTITY_ORGUNITS_BETA,
'subscopes': READONLY, 'subscopes': READONLY,
'scope': 'https://www.googleapis.com/auth/cloud-identity.orgunits'}, 'scope': 'https://www.googleapis.com/auth/cloud-identity.orgunits'},
{'name': 'Cloud Identity - Policy', {'name': 'Cloud Identity API - Policy',
'api': CLOUDIDENTITY_POLICY, 'api': CLOUDIDENTITY_POLICY,
'subscopes': READONLY, 'subscopes': READONLY,
'roByDefault': True, 'roByDefault': True,
'scope': 'https://www.googleapis.com/auth/cloud-identity.policies' 'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'
}, },
{'name': 'Cloud Identity User Invitations API', {'name': 'Cloud Identity API - User Invitations',
'api': CLOUDIDENTITY_USERINVITATIONS, 'api': CLOUDIDENTITY_USERINVITATIONS,
'subscopes': READONLY, 'subscopes': READONLY,
'scope': 'https://www.googleapis.com/auth/cloud-identity.userinvitations'}, 'scope': 'https://www.googleapis.com/auth/cloud-identity.userinvitations'},
@@ -833,3 +833,27 @@ def getSvcAcctScopesList(userServiceAccountAccessOnly, svcAcctSpecialScopes):
def hasLocalJSON(api): def hasLocalJSON(api):
return _INFO[api].get('localjson', False) return _INFO[api].get('localjson', False)
def findAPIforScope(scopesList):
def checkScopeMatch(scope, cscope):
if cscope['scope'] == scope:
requiredAPIs.append(cscope['name'])
return True
if cscope['subscopes'] == READONLY and cscope['scope']+'.readonly' == scope:
requiredAPIs.append(cscope['name']+' (supports readonly)')
return True
return False
requiredAPIs = []
for scope in scopesList:
for cscope in _CLIENT_SCOPES:
if checkScopeMatch(scope, cscope):
break
else:
for cscope in _SVCACCT_SCOPES:
if checkScopeMatch(scope, cscope):
break
if not requiredAPIs:
requiredAPIs = scopesList
return ' or '.join(requiredAPIs)

View File

@@ -41,6 +41,7 @@ CANNOT_DELETE_PERMISSION = 'cannotDeletePermission'
CANNOT_DELETE_PRIMARY_CALENDAR = 'cannotDeletePrimaryCalendar' CANNOT_DELETE_PRIMARY_CALENDAR = 'cannotDeletePrimaryCalendar'
CANNOT_DELETE_PRIMARY_SENDAS = 'cannotDeletePrimarySendAs' CANNOT_DELETE_PRIMARY_SENDAS = 'cannotDeletePrimarySendAs'
CANNOT_DELETE_RESOURCE_WITH_CHILDREN = 'cannotDeleteResourceWithChildren' CANNOT_DELETE_RESOURCE_WITH_CHILDREN = 'cannotDeleteResourceWithChildren'
CANNOT_MODIFY_INHERITED_PERMISSION = 'cannotModifyInheritedPermission'
CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION = 'cannotModifyInheritedTeamDrivePermission' CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION = 'cannotModifyInheritedTeamDrivePermission'
CANNOT_MODIFY_RESTRICTED_LABEL = 'cannotModifyRestrictedLabel' CANNOT_MODIFY_RESTRICTED_LABEL = 'cannotModifyRestrictedLabel'
CANNOT_MODIFY_VIEWERS_CAN_COPY_CONTENT = 'cannotModifyViewersCanCopyContent' CANNOT_MODIFY_VIEWERS_CAN_COPY_CONTENT = 'cannotModifyViewersCanCopyContent'
@@ -228,6 +229,7 @@ DRIVE3_CREATE_ACL_THROW_REASONS = [BAD_REQUEST, INVALID, INVALID_SHARING_REQUEST
FILE_ORGANIZER_NOT_YET_ENABLED_FOR_THIS_TEAMDRIVE, FILE_ORGANIZER_NOT_YET_ENABLED_FOR_THIS_TEAMDRIVE,
FILE_ORGANIZER_ON_FOLDERS_IN_SHARED_DRIVE_ONLY, FILE_ORGANIZER_ON_FOLDERS_IN_SHARED_DRIVE_ONLY,
FILE_ORGANIZER_ON_NON_TEAMDRIVE_NOT_SUPPORTED, FILE_ORGANIZER_ON_NON_TEAMDRIVE_NOT_SUPPORTED,
CANNOT_MODIFY_INHERITED_PERMISSION,
TEAMDRIVES_FOLDER_SHARING_NOT_SUPPORTED, INVALID_LINK_VISIBILITY, ABUSIVE_CONTENT_RESTRICTION] TEAMDRIVES_FOLDER_SHARING_NOT_SUPPORTED, INVALID_LINK_VISIBILITY, ABUSIVE_CONTENT_RESTRICTION]
DRIVE3_GET_ACL_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, FORBIDDEN, INTERNAL_ERROR, DRIVE3_GET_ACL_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, FORBIDDEN, INTERNAL_ERROR,
INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, INSUFFICIENT_FILE_PERMISSIONS, INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, INSUFFICIENT_FILE_PERMISSIONS,
@@ -248,10 +250,10 @@ DRIVE3_UPDATE_ACL_THROW_REASONS = [BAD_REQUEST, INVALID_OWNERSHIP_TRANSFER, CANN
FILE_ORGANIZER_ON_FOLDERS_IN_SHARED_DRIVE_ONLY, FILE_ORGANIZER_ON_FOLDERS_IN_SHARED_DRIVE_ONLY,
FILE_ORGANIZER_ON_NON_TEAMDRIVE_NOT_SUPPORTED, FILE_ORGANIZER_ON_NON_TEAMDRIVE_NOT_SUPPORTED,
CANNOT_UPDATE_PERMISSION, CANNOT_UPDATE_PERMISSION,
CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION, CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION, CANNOT_MODIFY_INHERITED_PERMISSION,
FIELD_NOT_WRITABLE, PERMISSION_NOT_FOUND] FIELD_NOT_WRITABLE, PERMISSION_NOT_FOUND]
DRIVE3_DELETE_ACL_THROW_REASONS = [BAD_REQUEST, CANNOT_REMOVE_OWNER, DRIVE3_DELETE_ACL_THROW_REASONS = [BAD_REQUEST, CANNOT_REMOVE_OWNER,
CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION, CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION, CANNOT_MODIFY_INHERITED_PERMISSION,
INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, SHARING_RATE_LIMIT_EXCEEDED, INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, SHARING_RATE_LIMIT_EXCEEDED,
NOT_FOUND, PERMISSION_NOT_FOUND, CANNOT_DELETE_PERMISSION] NOT_FOUND, PERMISSION_NOT_FOUND, CANNOT_DELETE_PERMISSION]
DRIVE3_MODIFY_LABEL_THROW_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, NOT_FOUND, FORBIDDEN, INTERNAL_ERROR, DRIVE3_MODIFY_LABEL_THROW_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, NOT_FOUND, FORBIDDEN, INTERNAL_ERROR,
@@ -398,6 +400,8 @@ class cannotDeletePrimarySendAs(Exception):
pass pass
class cannotDeleteResourceWithChildren(Exception): class cannotDeleteResourceWithChildren(Exception):
pass pass
class cannotModifyInheritedPermission(Exception):
pass
class cannotModifyInheritedTeamDrivePermission(Exception): class cannotModifyInheritedTeamDrivePermission(Exception):
pass pass
class cannotModifyRestrictedLabel(Exception): class cannotModifyRestrictedLabel(Exception):
@@ -698,6 +702,7 @@ REASON_EXCEPTION_MAP = {
CANNOT_DELETE_PRIMARY_CALENDAR: cannotDeletePrimaryCalendar, CANNOT_DELETE_PRIMARY_CALENDAR: cannotDeletePrimaryCalendar,
CANNOT_DELETE_PRIMARY_SENDAS: cannotDeletePrimarySendAs, CANNOT_DELETE_PRIMARY_SENDAS: cannotDeletePrimarySendAs,
CANNOT_DELETE_RESOURCE_WITH_CHILDREN: cannotDeleteResourceWithChildren, CANNOT_DELETE_RESOURCE_WITH_CHILDREN: cannotDeleteResourceWithChildren,
CANNOT_MODIFY_INHERITED_PERMISSION: cannotModifyInheritedPermission,
CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION: cannotModifyInheritedTeamDrivePermission, CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION: cannotModifyInheritedTeamDrivePermission,
CANNOT_MODIFY_RESTRICTED_LABEL: cannotModifyRestrictedLabel, CANNOT_MODIFY_RESTRICTED_LABEL: cannotModifyRestrictedLabel,
CANNOT_MODIFY_VIEWERS_CAN_COPY_CONTENT: cannotModifyViewersCanCopyContent, CANNOT_MODIFY_VIEWERS_CAN_COPY_CONTENT: cannotModifyViewersCanCopyContent,

View File

@@ -184,8 +184,8 @@ ALREADY_EXISTS_IN_TARGET_FOLDER = 'Already exists in {0}: {1}'
ALREADY_EXISTS_USE_MERGE_ARGUMENT = 'Already exists; use the "merge" argument to merge the labels' ALREADY_EXISTS_USE_MERGE_ARGUMENT = 'Already exists; use the "merge" argument to merge the labels'
API_ACCESS_DENIED = 'API access Denied' API_ACCESS_DENIED = 'API access Denied'
API_CALLS_RETRY_DATA = 'API calls retry data\n' API_CALLS_RETRY_DATA = 'API calls retry data\n'
API_CHECK_CLIENT_AUTHORIZATION = 'Please make sure the Client ID: {0} is authorized for the appropriate API or scopes:\n{1}\n\nRun: gam oauth create\n' API_CHECK_CLIENT_AUTHORIZATION = 'Please make sure the Client ID: {0} is authorized for the appropriate API or scopes: {1}\n\nRun: gam oauth create\n'
API_CHECK_SVCACCT_AUTHORIZATION = 'Please make sure the Service Account Client ID: {0} is authorized for the appropriate API or scopes:\n{1}\n\nRun: gam user {2} update serviceaccount\n' API_CHECK_SVCACCT_AUTHORIZATION = 'Please make sure the Service Account Client ID: {0} is authorized for the appropriate API or scopes: {1}\n\nRun: gam user {2} update serviceaccount\n'
API_ERROR_SETTINGS = 'API error, some settings not set' API_ERROR_SETTINGS = 'API error, some settings not set'
ARE_BOTH_REQUIRED = 'Arguments {0} and {1} are both required' ARE_BOTH_REQUIRED = 'Arguments {0} and {1} are both required'
ARE_MUTUALLY_EXCLUSIVE = 'Arguments {0} and {1} are mutually exclusive' ARE_MUTUALLY_EXCLUSIVE = 'Arguments {0} and {1} are mutually exclusive'
@@ -425,7 +425,7 @@ NO_LABELS_TO_PROCESS = 'No Labels to process'
NO_MESSAGES_WITH_LABEL = 'No Messages with Label' NO_MESSAGES_WITH_LABEL = 'No Messages with Label'
NO_PARENTS_TO_CONVERT_TO_SHORTCUTS = 'No parents to convert to shortcuts' NO_PARENTS_TO_CONVERT_TO_SHORTCUTS = 'No parents to convert to shortcuts'
NO_REPORT_AVAILABLE = 'No {0} report available.' NO_REPORT_AVAILABLE = 'No {0} report available.'
NO_SCOPES_FOR_API = 'There are no scopes authorized for the {0}' NO_SCOPES_FOR_API = 'There are no scopes authorized for the API(s): {0}'
NO_SERIAL_NUMBERS_SPECIFIED = 'No serial numbers specified' NO_SERIAL_NUMBERS_SPECIFIED = 'No serial numbers specified'
NO_SSO_PROFILE_MATCHES = 'No SSO profile matches display name {0}' NO_SSO_PROFILE_MATCHES = 'No SSO profile matches display name {0}'
NO_SSO_PROFILE_ASSIGNED = 'No SSO profile assigned to {0} {1}' NO_SSO_PROFILE_ASSIGNED = 'No SSO profile assigned to {0} {1}'

View File

@@ -107,6 +107,8 @@ _SKUS = {
'product': '101047', 'aliases': ['aisecurity'], 'displayName': 'AI Security'}, 'product': '101047', 'aliases': ['aisecurity'], 'displayName': 'AI Security'},
'1010470007': { '1010470007': {
'product': '101047', 'aliases': ['aimeetingsandmessaging'], 'displayName': 'AI Meetings and Messaging'}, 'product': '101047', 'aliases': ['aimeetingsandmessaging'], 'displayName': 'AI Meetings and Messaging'},
'1010470008': {
'product': '101047', 'aliases': ['geminiultra'], 'displayName': 'Google AI Ultra for Business'},
'1010490001': { '1010490001': {
'product': '101049', 'aliases': ['eeu'], 'displayName': 'Endpoint Education Upgrade'}, 'product': '101049', 'aliases': ['eeu'], 'displayName': 'Endpoint Education Upgrade'},
'1010500001': { '1010500001': {

View File

@@ -5,7 +5,7 @@
- [Python Regular Expressions](Python-Regular-Expressions) - [Python Regular Expressions](Python-Regular-Expressions)
- [Definitions](#definitions) - [Definitions](#definitions)
- [Manage Projects](#manage-projects) - [Manage Projects](#manage-projects)
- [Authorize a super admin to create projects](#authorize-a-super-admin-to-create-projects) - [Authorize a user to create projects](#authorize-a-user-to-create-projects)
- [Authorize Service Account Key Uploads](#authorize-service-account-key-uploads) - [Authorize Service Account Key Uploads](#authorize-service-account-key-uploads)
- [Authorize GAM to create projects](#authorize-gam-to-create-projects) - [Authorize GAM to create projects](#authorize-gam-to-create-projects)
- [Create a new GCP project folder](#create-a-new-gcp-project-folder) - [Create a new GCP project folder](#create-a-new-gcp-project-folder)
@@ -74,11 +74,6 @@ Verify that all scopes are available:
* Select "ON for everyone" * Select "ON for everyone"
* Click "SAVE" * Click "SAVE"
Verify that internal apps are trusted.
* Access the admin console and go to Security -> Access and data control -> API Controls
* Check that "Trust internal, domain-owned apps" is present in the **Settings** section
* Click "SAVE"
If you run a Google Workspace Education SKU, verify that Classroom API is enabled if required. If you run a Google Workspace Education SKU, verify that Classroom API is enabled if required.
* Access the admin console and go to Apps -> Google Workspace - Classroom * Access the admin console and go to Apps -> Google Workspace - Classroom
* Expand "Data access" * Expand "Data access"
@@ -110,12 +105,13 @@ Verify whether the super admin you'll be using is in an OU where reauthenticatio
* Access the admin console and go to Security -> Overview * Access the admin console and go to Security -> Overview
* Scroll down and open Google Cloud session control section * Scroll down and open Google Cloud session control section
* Select the OU containing the super admin * Select the OU containing the super admin
* If Require reauthentication is selected and Exempt Trusted apps is not checked, you'll have to do `gam oauth create` at whatever frequency is specified * If Require reauthentication is selected, you'll need either:
* If that sounds unappealing, check Exempt Trusted apps * uncheck Google Cloud Storage and any other GCP APIs that you selected on `gam oauth create` (reauth is only necessary for GCP APIs)
* Click "OVERRIDE" * enable "Exempt Trusted apps"
* rerun `gam oauth create` at whatever frequency is specified
Additional steps may be required if errors are encountered. Additional steps may be required if errors are encountered.
* [Authorize a super admin to create projects](#authorize-a-super-admin-to-create-projects) * [Authorize a user to create projects](#authorize-a-user-to-create-projects)
* [Authorize Service Account Key Uploads](#authorize-service-account-key-uploads) * [Authorize Service Account Key Uploads](#authorize-service-account-key-uploads)
* [Authorize GAM to create projects](#authorize-gam-to-create-projects) * [Authorize GAM to create projects](#authorize-gam-to-create-projects)
@@ -169,8 +165,8 @@ For `print|show projects`, you can eliminate the password prompt and authenticat
gam print projects admin admin@domain.com gam print projects admin admin@domain.com
``` ```
## Authorize a super admin to create projects ## Authorize a user to create projects
If you try to create a project and get an error saying that the admin you specified is not authorized to create projects, If you try to create a project and get an error saying that the user you specified is not authorized to create projects,
perform these steps and then retry the create project command. perform these steps and then retry the create project command.
* Login as an existing super admin at console.cloud.google.com * Login as an existing super admin at console.cloud.google.com
@@ -184,13 +180,12 @@ perform these steps and then retry the create project command.
* Click in the Select a role box * Click in the Select a role box
* Type project creator in the Filter box * Type project creator in the Filter box
* Click Project Creator * Click Project Creator
* Click + Add Another Role
* Type orgpolicy.policyAdmin in the Filter box
* Click Organization Policy Administrator
* Click Save * Click Save
## Authorize Service Account Key Uploads ## Authorize Service Account Key Uploads
*IMPORTANT:* Google best practice is to NOT use service account keys. Rather than overriding Google's default policy please consider [running GAM on Google Compute Engine Securely](https://github.com/GAM-team/GAM/wiki/l-Running-GAM-on-Google-Compute-Engine-(GCE)-Securely) so that service account keys are not necessary.
If you try to create a project and get an error saying that Constraint `constraints/iam.disableServiceAccountKeyUpload violated for service account projects/gam-project-xxxxx`, If you try to create a project and get an error saying that Constraint `constraints/iam.disableServiceAccountKeyUpload violated for service account projects/gam-project-xxxxx`,
perform these steps and then you should be able to authorize and use your project. perform these steps and then you should be able to authorize and use your project.

View File

@@ -211,6 +211,7 @@ gam print devices [todrive <ToDriveAttribute>*]
[orderby <DeviceOrderByFieldName> [ascending|descending]] [orderby <DeviceOrderByFieldName> [ascending|descending]]
[all|company|personal|nocompanydevices|nopersonaldevices] [all|company|personal|nocompanydevices|nopersonaldevices]
[nodeviceusers|oneuserperrow] [nodeviceusers|oneuserperrow]
[clientstates]
[formatjson [quotechar <Character>]] [formatjson [quotechar <Character>]]
``` ```
By default, all devices are displayed; use the query options to limit the display. By default, all devices are displayed; use the query options to limit the display.

View File

@@ -20,7 +20,8 @@
## Query documentation ## Query documentation
* [Cloud Identity Groups API - Search Dynamic Groups](https://cloud.google.com/identity/docs/reference/rest/v1/groups#dynamicgroupquery) * [Cloud Identity Groups API - Search Dynamic Groups](https://cloud.google.com/identity/docs/reference/rest/v1/groups#dynamicgroupquery)
* [Member REstrictions](https://cloud.google.com/identity/docs/reference/rest/v1/SecuritySettings#MemberRestriction) * [Dynamic Groups Member Attributes](https://cloud.google.com/identity/docs/how-to/dynamic-groups-attributes)
* [Member Restrictions](https://cloud.google.com/identity/docs/reference/rest/v1/SecuritySettings#MemberRestriction)
## Notes ## Notes

View File

@@ -12,14 +12,28 @@
## Notes ## Notes
To use these commands you must update your client access authentication. To use these commands you must update your client access authentication.
You'll enter 19R to turn on the Cloud Identity Policy scope; then continue You'll enter 20r to turn on the Cloud Identity Policy scope; then continue
with authentication. with authentication.
``` ```
gam oauth delete gam oauth delete
gam oauth create gam oauth create
... ...
[R] 19) Cloud Identity - Policy [R] 20) Cloud Identity - Policy (supports readonly)
``` ```
You must enable access to policies in the GCP cloud console.
* Login at console.cloud.google.com
* In the upper left click the three lines to the left of Google Cloud and select IAM & Admin
* Under IAM & Admin select IAM
* Click in the box to the right of Google Cloud
* Click the three dots at the right and select IAM/Permissions
* Now you should be at "Permissions for organization ..."
* Click on Grant Access
* Enter the GAM project creator address in Principals
* Click in the Select a role box
* Type orgpolicy.policyAdmin in the Filter box
* Click Organization Policy Administrator
* Click Save
## Definitions ## Definitions
``` ```

View File

@@ -10,8 +10,53 @@ Add the `-s` option to the end of the above commands to suppress creating the `g
See [Downloads-Installs-GAM7](https://github.com/GAM-team/GAM/wiki/Downloads-Installs) for Windows or other options, including manual installation See [Downloads-Installs-GAM7](https://github.com/GAM-team/GAM/wiki/Downloads-Installs) for Windows or other options, including manual installation
### 7.10.09
Added option `showwebviewlink` to `gam [<UserTypeEntity>] print|show shareddrives` that
displays the web view link for the Shared Drive: `https://drive.google.com/drive/folders/<SharedDriveID>`.
### 7.10.08
Fixed bug in commands that modify messages where the `labelids <LabelIdList>` option
could not be used unless one of these options was also specified: `query`, `matchlabel`, `ids`;
it can be now be used by itself.
### 7.10.07
Updated `gam <UserTypeEntity> copy|move drivefile` to hanndle additional instances of
the `cannotModifyInheritedPermission` error.
Added license SKU `Google AI Ultra for Business`
* ProductID - 101047
* SKUID - 1010470008 | geminiultra
### 7.10.06
Added option `clientstates` to `gam print devices` to include client states in device output.
### 7.10.05
Google renamed an error: `cannotModifyInheritedTeamDrivePermission` became `cannotModifyInheritedPermission`.
GAM will now handle the new error.
### 7.10.04
Updated `gam report <ActivityApplicationName>` to accept accept application names as defined
in the Reports API discovery document; this means that GAM does not have to be updated when
Google defines a new application name.
`gemini_in_workspace_apps` is now available in `gam report`.
### 7.10.03
Fixed bug in commands that modify messages where the `labelids <LabelIdList>` option
was not being applied.
### 7.10.02 ### 7.10.02
Added option `labelids <LabelIdList>` to all commands that process messages;
this option causes GAM to only return messages with labels that match all of the specified label IDs.
Updated `gam <UserTypeEntity> print|show forms` to always display `isPublished` and Updated `gam <UserTypeEntity> print|show forms` to always display `isPublished` and
`isAcceptingResponses` in `publishSettings/publishState` regardless of their value; `isAcceptingResponses` in `publishSettings/publishState` regardless of their value;
the API doesn't return these values when they are False. the API doesn't return these values when they are False.

View File

@@ -251,7 +251,7 @@ writes the credentials into the file oauth2.txt.
admin@server:/Users/admin$ rm -f /Users/admin/GAMConfig/oauth2.txt admin@server:/Users/admin$ rm -f /Users/admin/GAMConfig/oauth2.txt
admin@server:/Users/admin$ gam version admin@server:/Users/admin$ gam version
WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
GAM 7.10.02 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.10.09 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.5 64-bit final Python 3.13.5 64-bit final
MacOS Sequoia 15.5 x86_64 MacOS Sequoia 15.5 x86_64
@@ -989,7 +989,7 @@ writes the credentials into the file oauth2.txt.
C:\>del C:\GAMConfig\oauth2.txt C:\>del C:\GAMConfig\oauth2.txt
C:\>gam version C:\>gam version
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
GAM 7.10.02 - https://github.com/GAM-team/GAM - pythonsource GAM 7.10.09 - https://github.com/GAM-team/GAM - pythonsource
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.5 64-bit final Python 3.13.5 64-bit final
Windows-10-10.0.17134 AMD64 Windows-10-10.0.17134 AMD64

View File

@@ -62,6 +62,7 @@
| Gemini Education | 1010470004 | geminiedu | | Gemini Education | 1010470004 | geminiedu |
| Gemini Education Premium | 1010470005 | geminiedupremium | | Gemini Education Premium | 1010470005 | geminiedupremium |
| Gemini Enterprise | 1010470001 | geminient | duetai | | Gemini Enterprise | 1010470001 | geminient | duetai |
| Google AI Ultra for Business | 1010470008 | geminiultra |
| Google Apps Message Security | Google-Apps-For-Postini | postini | | Google Apps Message Security | Google-Apps-For-Postini | postini |
| Google Chrome Device Management | Google-Chrome-Device-Management | cdm | | Google Chrome Device Management | Google-Chrome-Device-Management | cdm |
| Google Drive Storage 16TB | Google-Drive-storage-16TB | 16tb | | Google Drive Storage 16TB | Google-Drive-storage-16TB | 16tb |

View File

@@ -39,20 +39,18 @@ config csv_output_row_filter "'\"accounts:used_quota_in_mb\":count>15000'"
## Activity reports ## Activity reports
``` ```
<ActivityApplicationName> ::= <ActivityApplicationName> ::=
access|accesstransparency| accesstransparency|access|
admin| admin|
calendar|calendars| calendar|calendars|
chat| chat|
chrome| chrome|
classroom| classroom|
contextawareaccess| contextawareaccess|
currents|gplus|google+| gplus|currents|google+|
datastudio| datastudio|
devices|mobile|
domain|
drive|doc|docs| drive|doc|docs|
gcp|cloud| gcp|cloud|
gemini|geminiforworkspace| geminiinworkspaceapps|gemini|geminiforworkspace|
groups|group| groups|group|
groupsenterprise|enterprisegroups| groupsenterprise|enterprisegroups|
jamboard| jamboard|

View File

@@ -372,7 +372,9 @@ By default, Gam displays the information as an indented list of keys and values.
gam [<UserTypeEntity>] show shareddrives gam [<UserTypeEntity>] show shareddrives
[adminaccess|asadmin] [teamdriveadminquery|query <QueryTeamDrive>] [adminaccess|asadmin] [teamdriveadminquery|query <QueryTeamDrive>]
[matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>] [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>]
[fields <SharedDriveFieldNameList>] [formatjson] [fields <SharedDriveFieldNameList>]
[showwebviewlink]
[formatjson]
``` ```
By default, all Shared Drives are displayed; use the following options to select a subset of Shared Drives: By default, all Shared Drives are displayed; use the following options to select a subset of Shared Drives:
* `teamdriveadminquery|query <QueryTeamDrive>` - Use a query to select Shared Drives * `teamdriveadminquery|query <QueryTeamDrive>` - Use a query to select Shared Drives
@@ -385,7 +387,9 @@ By default, Gam displays the information as an indented list of keys and values.
gam [<UserTypeEntity>] print shareddrives [todrive <ToDriveAttribute>*] gam [<UserTypeEntity>] print shareddrives [todrive <ToDriveAttribute>*]
[adminaccess|asadmin] [teamdriveadminquery|query <QueryTeamDrive>] [adminaccess|asadmin] [teamdriveadminquery|query <QueryTeamDrive>]
[matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>] [matchname <REMatchPattern>] [orgunit|org|ou <OrgUnitPath>]
[fields <SharedDriveFieldNameList>] [formatjson [quotechar <Character>]] [fields <SharedDriveFieldNameList>]
[showwebviewlink]
[formatjson [quotechar <Character>]]
``` ```
By default, all Shared Drives are displayed; use the following options to select a subset of Shared Drives: By default, all Shared Drives are displayed; use the following options to select a subset of Shared Drives:
* `teamdriveadminquery|query <QueryTeamDrive>` - Use a query to select Shared Drives * `teamdriveadminquery|query <QueryTeamDrive>` - Use a query to select Shared Drives

View File

@@ -72,6 +72,8 @@ This table and other suggestions came from:
<EmailAddress> ::= <String>@<DomainName> <EmailAddress> ::= <String>@<DomainName>
<UniqueID> ::= id:<String> <UniqueID> ::= id:<String>
<GroupItem> ::= <EmailAddress>|<UniqueID>|<String> <GroupItem> ::= <EmailAddress>|<UniqueID>|<String>
<LabelID> ::= <String>
<LabelIDList> ::= "<LabelID>(,<LabelID)*"
<LabelName> ::= <String> <LabelName> ::= <String>
<QueryGmail> ::= <String> See: https://support.google.com/mail/answer/7190 <QueryGmail> ::= <String> See: https://support.google.com/mail/answer/7190
<Time> ::= <Time> ::=
@@ -389,6 +391,7 @@ Your command line will have: `embedimage file1.jpg image1` embedimage file2.jpg
``` ```
gam <UserTypeEntity> archive messages <GroupItem> gam <UserTypeEntity> archive messages <GroupItem>
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[labelids <LabelIDList>]
[quick|notquick] [doit] [max_to_archive <Number>])|(ids <MessageIDEntity>) [quick|notquick] [doit] [max_to_archive <Number>])|(ids <MessageIDEntity>)
[csv [todrive <ToDriveAttribute>*]] [csv [todrive <ToDriveAttribute>*]]
``` ```
@@ -400,6 +403,7 @@ Messages are archived to the group specified by `<GroupItem>`.
### Archive a selected set of messages ### Archive a selected set of messages
* `((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+` - Criteria to select messages * `((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+` - Criteria to select messages
* `labelids <LabelIDList>` - Select messages with labels that match all of the specified label IDs.
* `max_to_archive` - Limit the number of messages that will be archived; use a value of 0 for no limit * `max_to_archive` - Limit the number of messages that will be archived; use a value of 0 for no limit
* `doit` - No messages are archived unless you specify `doit`. By not specifying `doit`, you can preview the messages selected to verify that the results match your expectations. * `doit` - No messages are archived unless you specify `doit`. By not specifying `doit`, you can preview the messages selected to verify that the results match your expectations.
@@ -432,10 +436,14 @@ See below for message selection.
Export messages in EML format. Export messages in EML format.
``` ```
gam <UserTypeEntity> export message|messages gam <UserTypeEntity> export message|messages
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [max_to_export <Number>])|(ids <MessageIDEntity>) (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[labelids <LabelIDList>]
[quick|notquick] [max_to_export <Number>])|(ids <MessageIDEntity>)
[targetfolder <FilePath>] [targetname <FileName>] [overwrite [<Boolean>]] [targetfolder <FilePath>] [targetname <FileName>] [overwrite [<Boolean>]]
gam <UserTypeEntity> export thread|threads gam <UserTypeEntity> export thread|threads
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [max_to_export <Number>])|(ids <ThreadIDEntity>) (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[labelids <LabelIDList>]
[quick|notquick] [max_to_export <Number>])|(ids <MessageIDEntity>)
[targetfolder <FilePath>] [targetname <FileName>] [overwrite [<Boolean>]] [targetfolder <FilePath>] [targetname <FileName>] [overwrite [<Boolean>]]
``` ```
@@ -459,10 +467,12 @@ See below for message selection.
``` ```
gam <UserTypeEntity> forward message|messages recipient|to <RecipientEntity> gam <UserTypeEntity> forward message|messages recipient|to <RecipientEntity>
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[labelids <LabelIDList>]
[quick|notquick] [doit] [max_to_forward <Number>])|(ids <MessageIDEntity>) [quick|notquick] [doit] [max_to_forward <Number>])|(ids <MessageIDEntity>)
[subject <String>] [addorigfieldstosubject] [subject <String>] [addorigfieldstosubject]
gam <UserTypeEntity> forward thread|threads recipient|to <RecipientEntity> gam <UserTypeEntity> forward thread|threads recipient|to <RecipientEntity>
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[labelids <LabelIDList>]
[quick|notquick] [doit] [max_to_forward <Number>])|(ids <ThreadIDEntity>) [quick|notquick] [doit] [max_to_forward <Number>])|(ids <ThreadIDEntity>)
[subject <String>] [addorigfieldstosubject] [subject <String>] [addorigfieldstosubject]
``` ```
@@ -482,23 +492,28 @@ See below for message selection.
``` ```
gam <UserTypeEntity> delete messages|threads gam <UserTypeEntity> delete messages|threads
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[labelids <LabelIDList>]
[quick|notquick] [doit] [max_to_delete <Number>])|(ids <MessageIDEntity>) [quick|notquick] [doit] [max_to_delete <Number>])|(ids <MessageIDEntity>)
[csv [todrive <ToDriveAttribute>*]] [csv [todrive <ToDriveAttribute>*]]
gam <UserTypeEntity> modify messages|threads gam <UserTypeEntity> modify messages|threads
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[labelids <LabelIDList>]
[quick|notquick] [doit] [max_to_modify <Number>])|(ids <MessageIDEntity>) [quick|notquick] [doit] [max_to_modify <Number>])|(ids <MessageIDEntity>)
((addlabel <LabelName>)|(removelabel <LabelName>))+ ((addlabel <LabelName>)|(removelabel <LabelName>))+
[csv [todrive <ToDriveAttribute>*]] [csv [todrive <ToDriveAttribute>*]]
gam <UserTypeEntity> spam messages|threads gam <UserTypeEntity> spam messages|threads
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[labelids <LabelIDList>]
[quick|notquick] [doit] [max_to_spam <Number>])|(ids <MessageIDEntity>) [quick|notquick] [doit] [max_to_spam <Number>])|(ids <MessageIDEntity>)
[csv [todrive <ToDriveAttribute>*]] [csv [todrive <ToDriveAttribute>*]]
gam <UserTypeEntity> trash messages|threads gam <UserTypeEntity> trash messages|threads
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[labelids <LabelIDList>]
[quick|notquick] [doit] [max_to_trash <Number>])|(ids <MessageIDEntity>) [quick|notquick] [doit] [max_to_trash <Number>])|(ids <MessageIDEntity>)
[csv [todrive <ToDriveAttribute>*]] [csv [todrive <ToDriveAttribute>*]]
gam <UserTypeEntity> untrash messages|threads gam <UserTypeEntity> untrash messages|threads
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+
[labelids <LabelIDList>]
[quick|notquick] [doit] [max_to_untrash <Number>])|(ids <MessageIDEntity>) [quick|notquick] [doit] [max_to_untrash <Number>])|(ids <MessageIDEntity>)
[csv [todrive <ToDriveAttribute>*]] [csv [todrive <ToDriveAttribute>*]]
``` ```
@@ -522,6 +537,7 @@ user@domain.com,18e9fc58c5491f4c,Deleted,
### Manage a selected set of messages ### Manage a selected set of messages
* `((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+` - Criteria to select messages * `((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+` - Criteria to select messages
* `labelids <LabelIDList>` - Select messages with labels that match all of the specified label IDs.
* `max_to_xxx` - Limit the number of messages that will be processed; use a value of 0 for no limit * `max_to_xxx` - Limit the number of messages that will be processed; use a value of 0 for no limit
* `doit` - No messages are processed unless you specify `doit`. By not specifying `doit`, you can preview the messages selected to verify that the results match your expectations. * `doit` - No messages are processed unless you specify `doit`. By not specifying `doit`, you can preview the messages selected to verify that the results match your expectations.
@@ -570,6 +586,7 @@ gam config auto_batch_min 1 groups_inde EastOffice delete message query "rfc822m
``` ```
gam <UserTypeEntity> show messages|threads gam <UserTypeEntity> show messages|threads
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])* (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])*
[labelids <LabelIDList>]
[quick|notquick] [max_to_show <Number>] [includespamtrash])|(ids <MessageIDEntity>) [quick|notquick] [max_to_show <Number>] [includespamtrash])|(ids <MessageIDEntity>)
[labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>] [labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>]
[countsonly|positivecountsonly] [useronly] [countsonly|positivecountsonly] [useronly]
@@ -581,6 +598,7 @@ gam <UserTypeEntity> show messages|threads
[targetfolder <FilePath>] [overwrite [<Boolean>]] [targetfolder <FilePath>] [overwrite [<Boolean>]]
gam <UserTypeEntity> print messages|threads [todrive <ToDriveAttribute>*] gam <UserTypeEntity> print messages|threads [todrive <ToDriveAttribute>*]
(((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])* (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])*
[labelids <LabelIDList>]
[quick|notquick] [max_to_print <Number>] [includespamtrash])|(ids <MessageIDEntity>) [quick|notquick] [max_to_print <Number>] [includespamtrash])|(ids <MessageIDEntity>)
[labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>] [labelmatchpattern <REMatchPattern>] [sendermatchpattern <REMatchPattern>]
[countsonly|positivecountsonly] [useronly] [countsonly|positivecountsonly] [useronly]
@@ -607,6 +625,7 @@ gam user user@domain.com print|show threads maxmessagesperthread 1
## Display a selected set of messages ## Display a selected set of messages
* `((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+` - Criteria to select messages * `((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+` - Criteria to select messages
* `labelids <LabelIDList>` - Select messages with labels that match all of the specified label IDs.
* `max_to_xxx` - Limit the number of messages that will be displayed * `max_to_xxx` - Limit the number of messages that will be displayed
* `includespamtrash` - Include messages in the Spam and Trash folders * `includespamtrash` - Include messages in the Spam and Trash folders
* `labelmatchpattern <REMatchPattern>` - Only display messages with some label that matches `<REMatchPattern>` * `labelmatchpattern <REMatchPattern>` - Only display messages with some label that matches `<REMatchPattern>`

View File

@@ -108,7 +108,7 @@ Paul shall send emails from the marketing email address with the name Paul from
``` gam user paul add sendas marketing@example.com "Paul from Example" replyto paul``` ``` gam user paul add sendas marketing@example.com "Paul from Example" replyto paul```
## Display sendas ## Display sendas
### Display the information as an indented list of keys and values. ### Display the sendas information as an indented list of keys and values.
``` ```
gam <UserTypeEntity> info sendas <EmailAddressEntity> [compact|format|html] gam <UserTypeEntity> info sendas <EmailAddressEntity> [compact|format|html]
gam <UserTypeEntity> show sendas [compact|format|html] gam <UserTypeEntity> show sendas [compact|format|html]
@@ -126,7 +126,19 @@ By default, all sendas addresses are shown, use these options to limit the displ
Use the `verifyonly` option to display `True` or `False` in the signature field based on whether the signature is non-blank. Use the `verifyonly` option to display `True` or `False` in the signature field based on whether the signature is non-blank.
### Display the information in CSV form. To capture a signature for use as input to GAM, do the following.
```
gam redirect stdout ./signature.html user user@domain.com show sendas compact
```
Edit signature.html and remove the following data leaving just the HTML.
```
SendAs Address: <user@domain.com>
IsPrimary: True
Default: True
Signature:
```
### Display the sendas information in CSV form.
``` ```
gam <UserTypeEntity> print sendas [compact] gam <UserTypeEntity> print sendas [compact]
[primary|default] [verifyonly] [todrive <ToDriveAttribute>*] [primary|default] [verifyonly] [todrive <ToDriveAttribute>*]
@@ -170,7 +182,7 @@ email address signature rather than the alias signature to be set.
If you have a current default signature, the API will update that, but if you delete it, it seems that the API will not over-write any of the other signatures, but instead add a new signature called `My signature`. If you rename that signature, the API will keep on updating that same signature, and not touch the other signatures. If you have a current default signature, the API will update that, but if you delete it, it seems that the API will not over-write any of the other signatures, but instead add a new signature called `My signature`. If you rename that signature, the API will keep on updating that same signature, and not touch the other signatures.
## Display signature ## Display signature
### Display the information as an indented list of keys and values. ### Display the signature as an indented list of keys and values.
``` ```
gam <UserTypeEntity> show signature|sig [compact|format|html] gam <UserTypeEntity> show signature|sig [compact|format|html]
[primary|default] [verifyonly] [primary|default] [verifyonly]
@@ -187,7 +199,19 @@ By default, the signature for `<UserTypeEntity>` is displayed, use these options
Use the `verifyonly` option to display `True` or `False` in the signature field based on whether the signature is non-blank. Use the `verifyonly` option to display `True` or `False` in the signature field based on whether the signature is non-blank.
### Display the information in CSV form. To capture a signature for use as input to GAM, do the following.
```
gam redirect stdout ./signature.html user user@domain.com show signature compact
```
Edit signature.html and remove the following data leaving just the HTML.
```
SendAs Address: <user@domain.com>
IsPrimary: True
Default: True
Signature:
```
### Display the signature in CSV form.
``` ```
gam <UserTypeEntity> print signature [compact] gam <UserTypeEntity> print signature [compact]
[primary|default] [verifyonly] [todrive <ToDriveAttribute>*] [primary|default] [verifyonly] [todrive <ToDriveAttribute>*]

View File

@@ -318,6 +318,7 @@ gam <UserTypeEntity> show shareddriveinfo <SharedDriveEntity>
gam <UserTypeEntity> show shareddrives gam <UserTypeEntity> show shareddrives
[matchname <REMatchPattern>] (role|roles <SharedDriveACLRoleList>)* [matchname <REMatchPattern>] (role|roles <SharedDriveACLRoleList>)*
[fields <SharedDriveFieldNameList>] [fields <SharedDriveFieldNameList>]
[showwebviewlink]
[guiroles [<Boolean>] [formatjson] [guiroles [<Boolean>] [formatjson]
``` ```
By default, Gam displays all Teams Drives accessible by the user. By default, Gam displays all Teams Drives accessible by the user.
@@ -329,7 +330,9 @@ By default, Gam displays the information as an indented list of keys and values.
``` ```
gam <UserTypeEntity> print shareddrives [todrive <ToDriveAttribute>*] gam <UserTypeEntity> print shareddrives [todrive <ToDriveAttribute>*]
[matchname <REMatchPattern>] (role|roles <SharedDriveACLRoleList>)* [matchname <REMatchPattern>] (role|roles <SharedDriveACLRoleList>)*
[fields <SharedDriveFieldNameList>] [formatjson [quotechar <Character>]] [fields <SharedDriveFieldNameList>]
[showwebviewlink]
[guiroles [<Boolean>]] [formatjson [quotechar <Character>]]
``` ```
By default, Gam displays all Teams Drives accessible by the user. By default, Gam displays all Teams Drives accessible by the user.
* `matchname <REMatchPattern>` - Display Shared Drives with names that match a pattern. * `matchname <REMatchPattern>` - Display Shared Drives with names that match a pattern.

View File

@@ -1,19 +1,12 @@
# Using GAM7 with a delegated admin service account # Using GAM7 with a delegated admin service account
- [Thanks](#thanks)
- [Introduction](#introduction) - [Introduction](#introduction)
- [Advantages](#advantages) - [Advantages](#advantages)
- [Disadvantages](#disadvantages) - [Disadvantages](#disadvantages)
- [Setup Steps](#setup-steps) - [Setup Steps](#setup-steps)
## Thanks
Thanks to Jay Lee for the original version of this document.
## Introduction ## Introduction
Delegated admin service accounts (DASA) are regular [GCP service accounts](https://cloud.google.com/iam/docs/service-accounts#what_are_service_accounts) that are granted a Workspace [delegated admin role](https://support.google.com/a/answer/33325). Service accounts have an email address like `gam-project-xuw-sp1-c4b@gam-project-xuw-sp1-c4b.iam.gserviceaccount.com` and are not part of a Workspace or Cloud Identity domain even if they are owned by a project in the domains organization. Service accounts cannot login to Google web services interactively, they are only able to call Google APIs. Delegated admin service accounts (DASA) are regular [GCP service accounts](https://cloud.google.com/iam/docs/service-accounts#what_are_service_accounts) that are granted a Workspace [delegated admin role](https://support.google.com/a/answer/33325). Service accounts have an email address like `gam-project-xuw-sp1-c4b@gam-project-xuw-sp1-c4b.iam.gserviceaccount.com` and are not part of a Workspace or Cloud Identity domain even if they are owned by a project in the domains organization. Service accounts cannot login to Google web services interactively, they are only able to call Google APIs.
GAM7 version 6.50.00 or higher is required.
## Advantages ## Advantages
* DASA accounts dont require a Workspace or Cloud Identity license. * DASA accounts dont require a Workspace or Cloud Identity license.
* DASA accounts dont have a password login that can be phished or captured, they use [RSA private keys](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) to sign authentication requests which makes them very secure. You should however [rotate the key](https://jaylee.us/qwm) on a regular basis and keep it safe and secured! * DASA accounts dont have a password login that can be phished or captured, they use [RSA private keys](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) to sign authentication requests which makes them very secure. You should however [rotate the key](https://jaylee.us/qwm) on a regular basis and keep it safe and secured!

View File

@@ -3,7 +3,7 @@
Print the current version of Gam with details Print the current version of Gam with details
``` ```
gam version gam version
GAM 7.10.02 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.10.09 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.5 64-bit final Python 3.13.5 64-bit final
MacOS Sequoia 15.5 x86_64 MacOS Sequoia 15.5 x86_64
@@ -15,7 +15,7 @@ Time: 2023-06-02T21:10:00-07:00
Print the current version of Gam with details and time offset information Print the current version of Gam with details and time offset information
``` ```
gam version timeoffset gam version timeoffset
GAM 7.10.02 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.10.09 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.5 64-bit final Python 3.13.5 64-bit final
MacOS Sequoia 15.5 x86_64 MacOS Sequoia 15.5 x86_64
@@ -27,7 +27,7 @@ Your system time differs from www.googleapis.com by less than 1 second
Print the current version of Gam with extended details and SSL information Print the current version of Gam with extended details and SSL information
``` ```
gam version extended gam version extended
GAM 7.10.02 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.10.09 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.5 64-bit final Python 3.13.5 64-bit final
MacOS Sequoia 15.5 x86_64 MacOS Sequoia 15.5 x86_64
@@ -64,7 +64,7 @@ MacOS High Sierra 10.13.6 x86_64
Path: /Users/Admin/bin/gam7 Path: /Users/Admin/bin/gam7
Version Check: Version Check:
Current: 5.35.08 Current: 5.35.08
Latest: 7.10.02 Latest: 7.10.09
echo $? echo $?
1 1
``` ```
@@ -72,7 +72,7 @@ echo $?
Print the current version number without details Print the current version number without details
``` ```
gam version simple gam version simple
7.10.02 7.10.09
``` ```
In Linux/MacOS you can do: In Linux/MacOS you can do:
``` ```
@@ -82,7 +82,7 @@ echo $VER
Print the current version of Gam and address of this Wiki Print the current version of Gam and address of this Wiki
``` ```
gam help gam help
GAM 7.10.02 - https://github.com/GAM-team/GAM GAM 7.10.09 - https://github.com/GAM-team/GAM
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.5 64-bit final Python 3.13.5 64-bit final
MacOS Sequoia 15.5 x86_64 MacOS Sequoia 15.5 x86_64