Compare commits

...

43 Commits

Author SHA1 Message Date
Ross Scroggs
dd5616ec0e Added create delegate notifications
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (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-10-26 10:48:18 -07:00
Ross Scroggs
46ad942637 Added create delegate notifications 2025-10-26 09:32:44 -07:00
Ross Scroggs
6db53c6f4c Update Users-Gmail-Delegates.md 2025-10-26 07:52:50 -07:00
Ross Scroggs
87f601dc5e Update chat space roles/permissions
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (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-10-24 12:53:27 -07:00
Ross Scroggs
e3d940c548 Update chat space roles/permissions 2025-10-24 11:40:07 -07:00
Ross Scroggs
90beada55e Update Chat-Bot-Setup-Use.md
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (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-certs (push) Has been cancelled
2025-10-24 09:02:13 -07:00
Ross Scroggs
670e3525f0 Update Cloud-Identity-Groups.md
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (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-certs (push) Has been cancelled
2025-10-23 18:10:11 -07:00
Ross Scroggs
4a4b154d3d Added option clearattachments <String> to gam [<UserTypeMessage>] update chatmessage 2025-10-23 17:14:18 -07:00
Ross Scroggs
8b182b7b37 Added option clearattachments <String> to gam [<UserTypeMessage>] update chatmessage 2025-10-23 17:14:07 -07:00
Jay Lee
e9d911b5cd Merge branch 'main' of https://github.com/GAM-team/GAM
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (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-certs (push) Has been cancelled
2025-10-22 17:32:55 +00:00
Jay Lee
c67a4c9147 CI group locking on create now works 2025-10-22 17:32:50 +00:00
Jay Lee
e583b6e20c remove MacOS 13 workaround from install script
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (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-certs (push) Has been cancelled
2025-10-22 09:02:10 -04:00
Ross Scroggs
8c23cd8e06 Update Domain-SharedContacts.md
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (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-certs (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2025-10-21 17:02:21 -07:00
Ross Scroggs
75fa7155a0 Fixed bug in `gam <UserTypeEntity> claim ownership 2025-10-21 12:14:10 -07:00
Ross Scroggs
90e11162a0 Fixed bug in `gam <UserTypeEntity> claim ownership 2025-10-21 12:13:57 -07:00
Ross Scroggs
b11617c1ea Update version to avoid macOS 26.0 conflict
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (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-10-17 17:14:36 -07:00
Ross Scroggs
cf59f9156e debug_redaction added 2025-10-17 16:07:59 -07:00
Ross Scroggs
35c1e44568 debug_redaction added
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (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-certs (push) Has been cancelled
2025-10-17 14:56:03 -07:00
Jay Lee
5cc68247a3 identify content to redact based on location and content pattern. #1839
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (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-certs (push) Has been cancelled
2025-10-16 19:15:40 +00:00
Jay Lee
906ee82417 Update build.yml
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.15-dev, ubuntu-24.04, 3.15-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (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-certs (push) Has been cancelled
2025-10-16 07:19:30 -04:00
Jay Lee
3d13d4afd8 Merge branch 'main' of https://github.com/GAM-team/GAM
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.14, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (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-certs (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2025-10-15 15:42:40 +00:00
Jay Lee
9d68ce1b46 tweak refresh token regex. #1839 2025-10-15 15:42:22 +00:00
Ross Scroggs
bd0ba995e5 Merge branch 'main' of https://github.com/GAM-team/GAM 2025-10-15 08:03:44 -07:00
Ross Scroggs
0ab4b6d5cd Update Users-Chat.md 2025-10-15 08:03:31 -07:00
Jay Lee
163433f15a redact JWT tokens. #1839 2025-10-15 13:59:06 +00:00
Jay Lee
3d6219b551 TRUE not True
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.14, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (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-certs (push) Has been cancelled
2025-10-15 12:50:13 +00:00
Jay Lee
99e363b5d6 config debug_redaction removes credentials in debug output 2025-10-15 12:38:55 +00:00
Ross Scroggs
ed03da815f Update Cloud-Identity-Policies.md
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.14, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (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-certs (push) Has been cancelled
2025-10-13 08:46:47 -07:00
Jay Lee
ef1a40afa8 Update build.yml
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.14, ubuntu-24.04, 3.14) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14 freethread, ubuntu-24.04, 3.14) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-10-10 09:46:38 -04:00
Jay Lee
cd56f353d8 PyPi require Python 3.10+ 2025-10-10 09:41:32 -04:00
Ross Scroggs
3924722f1c Fixed bug in gam config timezone <String> to handle timezone abbreviations correctly
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14-dev freethread, 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-certs (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2025-10-09 18:10:39 -07:00
Ross Scroggs
3ce48a95c9 Fixed bug in gam config timezone <String> to handle timezone abbreviations correctly 2025-10-09 17:08:44 -07:00
Ross Scroggs
2dafbfbcfc Update limited command data access
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14-dev freethread, 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-certs (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2025-10-08 19:10:14 -07:00
Ross Scroggs
e03086866a Update limited command data access 2025-10-08 18:10:05 -07:00
Jay Lee
0422bf22ea only freeze_support if we are frozen 2025-10-08 21:52:26 +00:00
Jay Lee
f3d9f3d518 remove read command for DwD data 2025-10-08 21:39:01 +00:00
Jay Lee
ea9fd3f363 != not ==
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14-dev freethread, 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-certs (push) Has been cancelled
2025-10-08 14:52:34 +00:00
Jay Lee
bed9db37ad forkserver for Linux, #1843 2025-10-08 14:43:28 +00:00
Jay Lee
072dc4809a force fork on Linux, fixes #1843 2025-10-08 13:55:34 +00:00
Jay Lee
6db2309fc4 actions: rebuild for Python 3.14.0
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14-dev freethread, 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-certs (push) Has been cancelled
2025-10-07 12:53:59 -04:00
Ross Scroggs
cbb0c81652 Handle: ERROR: Authentication Token Error - invalid_account: Forbidden
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14-dev freethread, 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-certs (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2025-10-06 13:00:47 -07:00
Ross Scroggs
f68aca8361 Handle: ERROR: Authentication Token Error - invalid_account: Forbidden 2025-10-06 12:15:18 -07:00
Ross Scroggs
d63fdb4ed9 Add drive/sheets read command data scopes
Some checks failed
Build and test GAM / build (false, build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (false, build, 10, Build x86_64 macOS 15, macos-15-intel) (push) Has been cancelled
Build and test GAM / build (false, build, 11, Build Arm MacOS 26, macos-26) (push) Has been cancelled
Build and test GAM / build (false, build, 12, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (false, build, 13, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (false, build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (false, build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (false, build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (false, build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (false, build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (false, test, 14, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (false, test, 15, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (false, test, 16, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (false, test, 17, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / build (true, test, 18, Test Python 3.14-dev freethread, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (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-10-03 18:06:30 -07:00
24 changed files with 691 additions and 514 deletions

View File

@@ -126,16 +126,16 @@ jobs:
name: Test Python 3.12 name: Test Python 3.12
- os: ubuntu-24.04 - os: ubuntu-24.04
goal: test goal: test
python: "3.14-dev" python: "3.15-dev"
freethreaded: false freethreaded: false
jid: 17 jid: 17
name: Test Python 3.14-dev name: Test Python 3.15-dev
- os: ubuntu-24.04 - os: ubuntu-24.04
goal: test goal: test
python: "3.14-dev" python: "3.14"
freethreaded: true freethreaded: true
jid: 18 jid: 18
name: Test Python 3.14-dev freethread name: Test Python 3.14 freethread
steps: steps:
@@ -158,7 +158,7 @@ jobs:
with: with:
path: | path: |
cache.tar.xz cache.tar.xz
key: gam-${{ matrix.jid }}-20251002 key: gam-${{ matrix.jid }}-20251007
- name: Untar Cache archive - name: Untar Cache archive
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit == 'true' if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit == 'true'
@@ -987,7 +987,7 @@ jobs:
$gam report usageparameters customer $gam report usageparameters customer
$gam report usage customer parameters gmail:num_emails_sent,accounts:num_1day_logins $gam report usage customer parameters gmail:num_emails_sent,accounts:num_1day_logins
$gam report customer todrive tdnobrowser $gam report customer todrive tdnobrowser
#$gam report users fields accounts:is_less_secure_apps_access_allowed,gmail:last_imap_time,gmail:last_pop_time filters "accounts:last_login_time>2019-01-01T00:00:00.000Z" todrive tdnobrowser #$gam report users fields accounts:is_less_secure_apps_access_allowed,gmail:last_imap_time,gmail:last_pop_time filters "accounts:last_login_time>2025-01-01T00:00:00.000Z" todrive tdnobrowser
$gam report users todrive tdnobrowser $gam report users todrive tdnobrowser
$gam report admin start -3d todrive tdnobrowser $gam report admin start -3d todrive tdnobrowser
$gam print devices nopersonaldevices nodeviceusers filter "serial:$JID$JID$JID$JID-" | $gam csv - gam delete device id ~name $gam print devices nopersonaldevices nodeviceusers filter "serial:$JID$JID$JID$JID-" | $gam csv - gam delete device id ~name

View File

@@ -27,7 +27,7 @@ dependencies = [
] ]
description = "CLI tool to manage Google Workspace" description = "CLI tool to manage Google Workspace"
readme = "README.md" readme = "README.md"
requires-python = ">=3.9" requires-python = ">=3.10"
classifiers = [ classifiers = [
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3 :: Only",

View File

@@ -2057,7 +2057,7 @@ gam create chatmessage <ChatSpace>
[(thread <ChatThread>)|(threadkey <String>) [replyoption fail|fallbacktonew]] [(thread <ChatThread>)|(threadkey <String>) [replyoption fail|fallbacktonew]]
[returnidonly] [returnidonly]
gam update chatmessage name <ChatMessage> gam update chatmessage name <ChatMessage>
<ChatContent> [<ChatContent>] [clearattachments <String>]
gam delete chatmessage name <ChatMessage> gam delete chatmessage name <ChatMessage>
<ChatMessageFieldName> ::= <ChatMessageFieldName> ::=
@@ -4086,7 +4086,7 @@ gam print group-members [todrive <ToDriveAttribute>*]
gam create cigroup <EmailAddress> gam create cigroup <EmailAddress>
[copyfrom <GroupItem>] <GroupAttribute>* [copyfrom <GroupItem>] <GroupAttribute>*
[makeowner] [alias|aliases <CIGroupAliasList>] [makeowner] [alias|aliases <CIGroupAliasList>]
[security|makesecuritygroup] [security|makesecuritygroup] [locked]
[dynamic <QueryDynamicGroup>] [dynamic <QueryDynamicGroup>]
gam update cigroup <GroupEntity> [copyfrom <GroupItem>] <GroupAttribute> gam update cigroup <GroupEntity> [copyfrom <GroupItem>] <GroupAttribute>
[security|makesecuritygroup| [security|makesecuritygroup|
@@ -5776,10 +5776,9 @@ gam create|add user <EmailAddress> [ignorenullpassword] <UserAttribute>*
[[notify <EmailAddressList>] [notifyrecoveryemail] [[notify <EmailAddressList>] [notifyrecoveryemail]
[subject <String>] [subject <String>]
[notifypassword <String>] [notifypassword <String>]
[from <EmailAaddress>] [from <EmailAaddress>] [mailbox <EmailAaddress>]
[mailbox <EmailAaddress>]
[replyto <EmailAaddress>] [replyto <EmailAaddress>]
[<NotifyMessageContent>] [<NotifyMessageContent>] [html [<Boolean>]]
(replace <Tag> <UserReplacement>)* (replace <Tag> <UserReplacement>)*
(replaceregex <RESearchPattern> <RESubstitution> <Tag> <UserReplacement>)* (replaceregex <RESearchPattern> <RESubstitution> <Tag> <UserReplacement>)*
] ]
@@ -5802,10 +5801,9 @@ gam update user <UserItem> [ignorenullpassword] <UserAttribute>*
[[notify <EmailAddressList>] [notifyrecoveryemail] [[notify <EmailAddressList>] [notifyrecoveryemail]
[subject <String>] [subject <String>]
[notifypassword <String>] [notifypassword <String>]
[from <EmailAaddress>] [from <EmailAaddress>] [mailbox <EmailAddress>]
[mailbox <EmailAddress>]
[replyto <EmailAddress>] [replyto <EmailAddress>]
[<NotifyMessageContent>] [<NotifyMessageContent>] [html [<Boolean>]]
(replace <Tag> <UserReplacement>)* (replace <Tag> <UserReplacement>)*
(replaceregex <RESearchPattern> <RESubstitution> <Tag> <UserReplacement>)* (replaceregex <RESearchPattern> <RESubstitution> <Tag> <UserReplacement>)*
] ]
@@ -5840,10 +5838,9 @@ gam update users <UserTypeEntity> [ignorenullpassword] <UserAttribute>*
[[notify <EmailAddressList>] [notifyrecoveryemail] [[notify <EmailAddressList>] [notifyrecoveryemail]
[subject <String>] [subject <String>]
[notifypassword <String>] [notifypassword <String>]
[from <EmailAddress>] [from <EmailAddress>] [mailbox <EmailAddress>]
[mailbox <EmailAddress>]
[replyto <EmailAaddress>] [replyto <EmailAaddress>]
[<NotifyMessageContent>] [<NotifyMessageContent>] [html [<Boolean>]]
(replace <Tag> <UserReplacement>)* (replace <Tag> <UserReplacement>)*
(replaceregex <RESearchPattern> <RESubstitution> <Tag> <UserReplacement>)* (replaceregex <RESearchPattern> <RESubstitution> <Tag> <UserReplacement>)*
] ]
@@ -5877,10 +5874,9 @@ gam <UserTypeEntity> update users [ignorenullpassword] <UserAttribute>*
[[notify <EmailAddressList>] [notifyrecoveryemail] [[notify <EmailAddressList>] [notifyrecoveryemail]
[subject <String>] [subject <String>]
[notifypassword <String>] [notifypassword <String>]
[from <EmailAaddress>] [from <EmailAaddress>] [mailbox <EmailAddress>]
[mailbox <EmailAddress>]
[replyto <EmailAddress>] [replyto <EmailAddress>]
[<NotifyMessageContent>] [<NotifyMessageContent>] [html [<Boolean>]]
(replace <Tag> <UserReplacement>)* (replace <Tag> <UserReplacement>)*
(replaceregex <RESearchPattern> <RESubstitution> <Tag> <UserReplacement>)* (replaceregex <RESearchPattern> <RESubstitution> <Tag> <UserReplacement>)*
] ]
@@ -6428,13 +6424,13 @@ gam <UserTypeEntity> update chatspace <ChatSpace>
[type space] [type space]
[description <String>] [guidelines|rules <String>] [description <String>] [guidelines|rules <String>]
[history <Boolean>]) [history <Boolean>])
[managemembersandgroups managers|members] [managemembersandgroups owners|managers|members]
[modifyspacedetails managers|members] [modifyspacedetails owners|managers|members]
[togglehistory managers|members] [togglehistory owners|managers|members]
[useatmentionall managers|members] [useatmentionall owners|managers|members]
[manageapps managers|members] [manageapps owners|managers|members]
[managewebhooks managers|members] [managewebhooks owners|managers|members]
[replymessages managers|members] [replymessages owners|managers|members]
[formatjson] [formatjson]
gam <UserTypeEntity> delete chatspace <ChatSpace> gam <UserTypeEntity> delete chatspace <ChatSpace>
@@ -6495,28 +6491,28 @@ gam <UserItem> print chatspaces asadmin [todrive <ToDriveAttribute>*]
[formatjson [quotechar <Character>]] [formatjson [quotechar <Character>]]
gam <UserTypeEntity> create chatmember <ChatSpace> gam <UserTypeEntity> create chatmember <ChatSpace>
[type human|bot] [role member|manager] [type human|bot] [role member|manager|owner]
(user <UserItem>)* (members <UserTypeEntity>)* (user <UserItem>)* (members <UserTypeEntity>)*
(group <GroupItem>)* (groups <GroupEntity>)* (group <GroupItem>)* (groups <GroupEntity>)*
[formatjson|returnidonly] [formatjson|returnidonly]
gam <UserTypeEntity> delete chatmember <ChatSpace> gam <UserTypeEntity> delete chatmember <ChatSpace>
((user <UserItem>)|(members <UserTypeEntity>)| ((user <UserItem>)|(members <UserTypeEntity>)|
(group <GroupItem>)|(groups <GroupEntity>))+ (group <GroupItem>)|(groups <GroupEntity>))+
gam <UserTypeEntity> remove chatmember members <ChatMemberList> `gam <UserTypeEntity> remove chatmember members <ChatMemberList>
gam <UserTypeEntity> update chatmember <ChatSpace> gam <UserTypeEntity> update chatmember <ChatSpace>
role member|manager role member|manager|owner
((user <UserItem>)|(members <UserTypeEntity>))+ ((user <UserItem>)|(members <UserTypeEntity>))+
gam <UserTypeEntity> modify chatmember gam <UserTypeEntity> modify chatmember
role member|manager role member|manager|owner
members <ChatMemberList> members <ChatMemberList>
gam <UserTypeEntity> sync chatmembers <ChatSpace> gam <UserTypeEntity> sync chatmembers <ChatSpace>
[role member|manager] [type human|bot] [role member|manager|owner] [type human|bot]
[addonly|removeonly] [addonly|removeonly]
[preview [actioncsv]] [preview [actioncsv]]
(users <UserTypeEntity>)* (groups <GroupEntity>)* (users <UserTypeEntity>)* (groups <GroupEntity>)*
gam <UserItem> create chatmember asadmin <ChatSpace> gam <UserItem> create chatmember asadmin <ChatSpace>
[type human|bot] [role member|manager] [type human|bot] [role member|manager|owner]
(user <UserItem>)* (members <UserTypeEntity>)* (user <UserItem>)* (members <UserTypeEntity>)*
(group <GroupItem>)* (groups <GroupEntity>)* (group <GroupItem>)* (groups <GroupEntity>)*
[formatjson|returnidonly] [formatjson|returnidonly]
@@ -6525,13 +6521,13 @@ gam <UserItem> delete chatmember asadmin <ChatSpace>
((user <UserItem>)|(members <UserTypeEntity>)| ((user <UserItem>)|(members <UserTypeEntity>)|
(group <GroupItem>)|(groups <GroupEntity>))+ (group <GroupItem>)|(groups <GroupEntity>))+
gam <UserItem> update chatmember asadmin <ChatSpace> gam <UserItem> update chatmember asadmin <ChatSpace>
role member|manager role member|manager|owner
((user <UserItem>)|(members <UserTypeEntity>))+ ((user <UserItem>)|(members <UserTypeEntity>))+
gam <UserItem> modify chatmember asadmin gam <UserItem> modify chatmember asadmin
role member|manager role member|manager|owner
members <ChatMemberList> members <ChatMemberList>
gam <UserItem> sync chatmembers asadmin <ChatSpace> gam <UserItem> sync chatmembers asadmin <ChatSpace>
[role member|manager] [type human|bot] [role member|manager|owner`] [type human|bot]
[addonly|removeonly] [addonly|removeonly]
[preview [actioncsv]] [preview [actioncsv]]
(users <UserTypeEntity>)* (groups <GroupEntity>)* (users <UserTypeEntity>)* (groups <GroupEntity>)*
@@ -6586,7 +6582,7 @@ gam <UserTypeEntity> create chatmessage <ChatSpace>
[replyoption fail|fallback] [replyoption fail|fallback]
[returnidonly] [returnidonly]
gam <UserTypeEntity> update chatmessage name <ChatMessage> gam <UserTypeEntity> update chatmessage name <ChatMessage>
<ChatContent> [<ChatContent>] [clearattachments <String>]
gam <UserTypeEntity> delete chatmessage name <ChatMessage> gam <UserTypeEntity> delete chatmessage name <ChatMessage>
<ChatMessageFieldName> ::= <ChatMessageFieldName> ::=
@@ -7579,7 +7575,19 @@ gam <UserTypeEntity> deprovision|deprov [popimap] [signout] [turnoff2sv]
# Users - Gmail - Delegates # Users - Gmail - Delegates
gam <UserTypeEntity> delegate to [convertalias] <UserEntity> gam <UserTypeEntity> delegate to [convertalias] <UserEntity>
[notify [<Boolean>]
[subject <String>]
[from <EmailAaddress>] [mailbox <EmailAddress>]
[replyto <EmailAaddress>]
[<NotifyMessageContent>] [html [<Boolean>]]
]
gam <UserTypeEntity> create|add delegate|delegates [convertalias] <UserEntity> gam <UserTypeEntity> create|add delegate|delegates [convertalias] <UserEntity>
[notify [<Boolean>]
[subject <String>]
[from <EmailAaddress>] [mailbox <EmailAddress>]
[replyto <EmailAaddress>]
[<NotifyMessageContent>] [html [<Boolean>]]
]
gam <UserTypeEntity> delete delegate|delegates [convertalias] <UserEntity> gam <UserTypeEntity> delete delegate|delegates [convertalias] <UserEntity>
gam <UserTypeEntity> update delegate|delegates [convertalias] [<UserEntity>] gam <UserTypeEntity> update delegate|delegates [convertalias] [<UserEntity>]
gam <UserTypeEntity> show delegates|delegate [shownames] [csv] gam <UserTypeEntity> show delegates|delegate [shownames] [csv]

View File

@@ -1,3 +1,85 @@
7.27.04
Added options to `gam <UserTypeEntity> create delegate` that support
sending email notifications when a user adds a delegate.
* See: https://github.com/GAM-team/GAM/wiki/Users-Gmail-Delegates#delegation-notification
7.27.03
Updated `gam <UserTypeEntity> create|update|sync chatmember` role specification to `role member|manager|owner`.
This is the mapping between the Chat UI and Chat API; GAM uses the Chat UI role names.
```
UI: Member, API: ROLE_MEMBER
UI: Manager, API: ROLE_ASSISTANT_MANAGER
UI: Owner, API: ROLE_MANAGER
```
Updated `gam <UserTypeEntity> update chatspace` options for permission settings.
```
[managemembersandgroups owners|managers|members]
[modifyspacedetails owners|managers|members]
[togglehistory owners|managers|members]
[useatmentionall owners|managers|members]
[manageapps owners|managers|members]
[managewebhooks owners|managers|members]
[replymessages owners|managers|members]
```
7.27.02
Added option `clearattachments <String>` to `gam [<UserTypeMessage>] update chatmessage`
that clears all attachments from a Chat message. If `<ChatContent>` is not specified,
the current message text is retained and `<String>` is appended; `<String>` must be specified
but can be empty in which case the current message test is preserved as-is.
7.27.01
Fixed bug in `gam <UserTypeEntity> claim ownership <DriveFileEntity> ... onlyUsers|skipusers <UserTypeEntity>`
where the email addresses in `onlyUsers|skipusers <UserTypeEntity>` were not normalized.
7.27.00
Added `debug_redaction` Boolean variable to `gam.cfg`. When True, the default,
sensitive data like access/refresh tokens, client secret and authorization codes
are redacted from debug output. This allows you to post debug output without
compromising your account information. Even with debug redaction,
anything shared publicly should be double-checked for sensitive content.
7.25.01
Fixed bug in `gam config timezone <String>` to handle timezone abbreviations correctly;
they were incorrectly shifted to lowercase.
7.25.00
Removed a capabilty added in 7.24.00 that allowed reading command data from Google Docs and Sheets
when a user's service account access to Drive and Sheets had been disabled. Jay was concerned
that this change could be exploited to give access to all user's files.
This capability has been replaced by issuing the following commands. The admin specified in `gam oauth create`
can read command data from Docs and Sheets to which it has access.
```
gam config commanddata_clientaccess true save
gam oauth create
Enable the following and proceed to authorization.
[*] 42) Drive API - commanddata_clientaccess
[*] 54) Sheets API - commanddata_clientaccess
```
Fixed in bug in `gam report` that caused a trap with either of the `thismonth` or `previousmonths` options were used.
Upgraded to Python 3.14.0.
7.24.01
Updated GAM to handle the following error that occurs when GAM tries to authenticate
as a user that has been disabled by Google.
```
ERROR: Authentication Token Error - invalid_account: Forbidden
```
7.24.00 7.24.00
If you want to disable a user's service account access to Drive and Sheets but still allow reading command data from Google Docs and Sheets, If you want to disable a user's service account access to Drive and Sheets but still allow reading command data from Google Docs and Sheets,

View File

@@ -83,13 +83,8 @@ echo -e '\x1B[0m'
version_gt() version_gt()
{ {
# MacOS < 10.13 doesn't support sort -V
echo "" | sort -V > /dev/null 2>&1
vsort_failed=$?
if [ "${1}" = "${2}" ]; then if [ "${1}" = "${2}" ]; then
true true
elif (( $vsort_failed != 0 )); then
false
else else
test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1" test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"
fi fi

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.24.00' __version__ = '7.27.04'
__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
@@ -49,7 +49,7 @@ from email.policy import SMTP as policySMTP
import hashlib import hashlib
from html.entities import name2codepoint from html.entities import name2codepoint
from html.parser import HTMLParser from html.parser import HTMLParser
import http.client as http_client import http.client
import importlib import importlib
from importlib.metadata import version as lib_version from importlib.metadata import version as lib_version
import io import io
@@ -375,6 +375,37 @@ YUBIKEY_VALUE_ERROR_RC = 85
YUBIKEY_MULTIPLE_CONNECTED_RC = 86 YUBIKEY_MULTIPLE_CONNECTED_RC = 86
YUBIKEY_NOT_FOUND_RC = 87 YUBIKEY_NOT_FOUND_RC = 87
DEBUG_REDACTION_PATTERNS = [
# Positional patterns that redact sensitive credentials based on their location
(r'(Bearer\s+)\S+', r'\1*****'), # access tokens and JWTs in auth header
(r'([?&]refresh_token=)[^&]*', r'\1*****'), # refresh token URL parameter
(r'([?&]client_secret=)[^&]*', r'\1*****'), # client secret URL parameter
(r'([?&]key=)[^&]*', r'\1*****'), # API key URL parameter
(r'([?&]code=)[^&]*', r'\1*****'), # auth code URL parameter
# Pattern match patterns that redact sensitive credentials based on known credential pattern
(r'ya29.[0-9A-Za-z-_]+', '*****'), # Access token
(r'1%2F%2F[0-9A-Za-z-_]{100}|1%2F%2F[0-9A-Za-z-_]{64}|1%2F%2F[0-9A-Za-z-_]{43}', '*****'), # Refresh token
(r'4/[0-9A-Za-z-_]+', '*****'), # Auth code
(r'GOCSPX-[0-9a-zA-Z-_]{28}', '*****'), # Client secret
(r'AIza[0-9A-Za-z-_]{35}', '*****'), # API key
(r'eyJ[a-zA-Z0-9\-_]+\.eyJ[a-zA-Z0-9\-_]+\.[a-zA-Z0-9\-_]*', '*****'), # JWT
]
def redactable_debug_print(*args):
processed_args = []
for arg in args:
if arg.startswith('b\''):
sbytes = arg[2:-1]
sbytes = bytes(sbytes, 'utf-8')
arg = sbytes.decode()
arg = arg.replace('\\r\\n', "\n ")
if GC.Values[GC.DEBUG_REDACTION]:
for pattern, replace in DEBUG_REDACTION_PATTERNS:
arg = re.sub(pattern, replace, arg)
processed_args.append(arg)
print(*processed_args)
# Multiprocessing lock # Multiprocessing lock
mplock = None mplock = None
@@ -2113,12 +2144,12 @@ class StartEndTime():
else: else:
firstMonth = getInteger(minVal=1, maxVal=6) firstMonth = getInteger(minVal=1, maxVal=6)
currDate = todaysDate() currDate = todaysDate()
self.startDateTime = currDate.shift(months=-firstMonth, day=1, hour=0, minute=0, second=0, microsecond=0) self.startDateTime = currDate.replace(day=1, hour=0, minute=0, second=0, microsecond=0).shift(months=-firstMonth)
self.startTime = ISOformatTimeStamp(self.startDateTime) self.startTime = ISOformatTimeStamp(self.startDateTime)
if myarg == 'thismonth': if myarg == 'thismonth':
self.endDateTime = todaysTime() self.endDateTime = todaysTime()
else: else:
self.endDateTime = currDate.shift(day=1, hour=23, minute=59, second=59, microsecond=0).shift(days=-1) self.endDateTime = currDate.replace(day=1, hour=23, minute=59, second=59, microsecond=0).shift(days=-1)
self.endTime = ISOformatTimeStamp(self.endDateTime) self.endTime = ISOformatTimeStamp(self.endDateTime)
if self.startDateTime and self.endDateTime and self.endDateTime < self.startDateTime: if self.startDateTime and self.endDateTime and self.endDateTime < self.startDateTime:
Cmd.Backup() Cmd.Backup()
@@ -3049,7 +3080,10 @@ def getGDocData(gformat):
mimeType = GDOC_FORMAT_MIME_TYPES[gformat] mimeType = GDOC_FORMAT_MIME_TYPES[gformat]
user = getEmailAddress() user = getEmailAddress()
fileIdEntity = getDriveFileEntity(queryShortcutsOK=False) fileIdEntity = getDriveFileEntity(queryShortcutsOK=False)
_, drive = buildGAPIServiceObject(chooseSaAPI(API.DRIVECD, API.DRIVE3), user) if not GC.Values[GC.COMMANDDATA_CLIENTACCESS]:
_, drive = buildGAPIServiceObject(API.DRIVE3, user)
else:
drive = buildGAPIObject(API.DRIVE3)
if not drive: if not drive:
sys.exit(GM.Globals[GM.SYSEXITRC]) sys.exit(GM.Globals[GM.SYSEXITRC])
_, _, jcount = _validateUserGetFileIDs(user, 0, 0, fileIdEntity, drive=drive) _, _, jcount = _validateUserGetFileIDs(user, 0, 0, fileIdEntity, drive=drive)
@@ -3106,7 +3140,10 @@ def getGSheetData():
user = getEmailAddress() user = getEmailAddress()
fileIdEntity = getDriveFileEntity(queryShortcutsOK=False) fileIdEntity = getDriveFileEntity(queryShortcutsOK=False)
sheetEntity = getSheetEntity(False) sheetEntity = getSheetEntity(False)
user, drive = buildGAPIServiceObject(chooseSaAPI(API.DRIVECD, API.DRIVE3), user) if not GC.Values[GC.COMMANDDATA_CLIENTACCESS]:
user, drive = buildGAPIServiceObject(API.DRIVE3, user)
else:
drive = buildGAPIObject(API.DRIVE3)
if not drive: if not drive:
sys.exit(GM.Globals[GM.SYSEXITRC]) sys.exit(GM.Globals[GM.SYSEXITRC])
_, _, jcount = _validateUserGetFileIDs(user, 0, 0, fileIdEntity, drive=drive) _, _, jcount = _validateUserGetFileIDs(user, 0, 0, fileIdEntity, drive=drive)
@@ -3114,7 +3151,10 @@ def getGSheetData():
getGDocSheetDataFailedExit([Ent.USER, user], Msg.NO_ENTITIES_FOUND.format(Ent.Singular(Ent.DRIVE_FILE))) getGDocSheetDataFailedExit([Ent.USER, user], Msg.NO_ENTITIES_FOUND.format(Ent.Singular(Ent.DRIVE_FILE)))
if jcount > 1: if jcount > 1:
getGDocSheetDataFailedExit([Ent.USER, user], Msg.MULTIPLE_ENTITIES_FOUND.format(Ent.Plural(Ent.DRIVE_FILE), jcount, ','.join(fileIdEntity['list']))) getGDocSheetDataFailedExit([Ent.USER, user], Msg.MULTIPLE_ENTITIES_FOUND.format(Ent.Plural(Ent.DRIVE_FILE), jcount, ','.join(fileIdEntity['list'])))
_, sheet = buildGAPIServiceObject(chooseSaAPI(API.SHEETSCD, API.SHEETS), user) if not GC.Values[GC.COMMANDDATA_CLIENTACCESS]:
_, sheet = buildGAPIServiceObject(API.SHEETS, user)
else:
sheet = buildGAPIObject(API.SHEETS)
if not sheet: if not sheet:
sys.exit(GM.Globals[GM.SYSEXITRC]) sys.exit(GM.Globals[GM.SYSEXITRC])
fileId = fileIdEntity['list'][0] fileId = fileIdEntity['list'][0]
@@ -3707,12 +3747,12 @@ def SetGlobalVariables():
return stringlist return stringlist
def _getCfgTimezone(sectionName, itemName): def _getCfgTimezone(sectionName, itemName):
value = _stripStringQuotes(GM.Globals[GM.PARSER].get(sectionName, itemName).lower()) value = _stripStringQuotes(GM.Globals[GM.PARSER].get(sectionName, itemName))
if value in {'utc', 'z'}: if value.lower() in {'utc', 'z'}:
GM.Globals[GM.CONVERT_TO_LOCAL_TIME] = False GM.Globals[GM.CONVERT_TO_LOCAL_TIME] = False
return arrow.now('utc').tzinfo return arrow.now('utc').tzinfo
GM.Globals[GM.CONVERT_TO_LOCAL_TIME] = True GM.Globals[GM.CONVERT_TO_LOCAL_TIME] = True
if value == 'local': if value.lower() == 'local':
return arrow.now(value).tzinfo return arrow.now(value).tzinfo
try: try:
return arrow.now(value).tzinfo return arrow.now(value).tzinfo
@@ -4115,6 +4155,8 @@ def SetGlobalVariables():
GM.Globals[GM.OAUTH2_TXT_LOCK] = f'{GC.Values[GC.OAUTH2_TXT]}.lock' GM.Globals[GM.OAUTH2_TXT_LOCK] = f'{GC.Values[GC.OAUTH2_TXT]}.lock'
# Override httplib2 settings # Override httplib2 settings
httplib2.debuglevel = GC.Values[GC.DEBUG_LEVEL] httplib2.debuglevel = GC.Values[GC.DEBUG_LEVEL]
# Use our own print function for http.client so we can redact and cleanup
http.client.print = redactable_debug_print
# Reset global variables if required # Reset global variables if required
if prevExtraArgsTxt != GC.Values[GC.EXTRA_ARGS]: if prevExtraArgsTxt != GC.Values[GC.EXTRA_ARGS]:
GM.Globals[GM.EXTRA_ARGS_LIST] = [('prettyPrint', GC.Values[GC.DEBUG_LEVEL] > 0)] GM.Globals[GM.EXTRA_ARGS_LIST] = [('prettyPrint', GC.Values[GC.DEBUG_LEVEL] > 0)]
@@ -4766,7 +4808,7 @@ def getService(api, httpObj):
waitOnFailure(n, triesLimit, INVALID_JSON_RC, str(e)) waitOnFailure(n, triesLimit, INVALID_JSON_RC, str(e))
continue continue
systemErrorExit(INVALID_JSON_RC, str(e)) systemErrorExit(INVALID_JSON_RC, str(e))
except (http_client.ResponseNotReady, OSError, googleapiclient.errors.HttpError) as e: except (http.client.ResponseNotReady, OSError, googleapiclient.errors.HttpError) as e:
errMsg = f'Connection error: {str(e) or repr(e)}' errMsg = f'Connection error: {str(e) or repr(e)}'
if n != triesLimit: if n != triesLimit:
waitOnFailure(n, triesLimit, SOCKET_ERROR_RC, errMsg) waitOnFailure(n, triesLimit, SOCKET_ERROR_RC, errMsg)
@@ -4801,7 +4843,6 @@ def defaultSvcAcctScopes():
saScopes[scope['api']].append(scope['scope']) saScopes[scope['api']].append(scope['scope'])
else: else:
saScopes[scope['api']].extend(scope['scope']) saScopes[scope['api']].extend(scope['scope'])
saScopes[API.DRIVEACTIVITY].append(API.DRIVE_SCOPE)
saScopes[API.DRIVE2] = saScopes[API.DRIVE3] saScopes[API.DRIVE2] = saScopes[API.DRIVE3]
return saScopes return saScopes
@@ -5080,7 +5121,7 @@ def callGData(service, function,
e = e.args[0] e = e.args[0]
handleOAuthTokenError(e, GDATA.SERVICE_NOT_APPLICABLE in throwErrors) handleOAuthTokenError(e, GDATA.SERVICE_NOT_APPLICABLE in throwErrors)
raise GDATA.ERROR_CODE_EXCEPTION_MAP[GDATA.SERVICE_NOT_APPLICABLE](str(e)) raise GDATA.ERROR_CODE_EXCEPTION_MAP[GDATA.SERVICE_NOT_APPLICABLE](str(e))
except (http_client.ResponseNotReady, OSError) as e: except (http.client.ResponseNotReady, OSError) as e:
errMsg = f'Connection error: {str(e) or repr(e)}' errMsg = f'Connection error: {str(e) or repr(e)}'
if n != triesLimit: if n != triesLimit:
waitOnFailure(n, triesLimit, SOCKET_ERROR_RC, errMsg) waitOnFailure(n, triesLimit, SOCKET_ERROR_RC, errMsg)
@@ -5390,7 +5431,7 @@ def callGAPI(service, function,
e = e.args[0] e = e.args[0]
handleOAuthTokenError(e, GAPI.SERVICE_NOT_AVAILABLE in throwReasons) handleOAuthTokenError(e, GAPI.SERVICE_NOT_AVAILABLE in throwReasons)
raise GAPI.REASON_EXCEPTION_MAP[GAPI.SERVICE_NOT_AVAILABLE](str(e)) raise GAPI.REASON_EXCEPTION_MAP[GAPI.SERVICE_NOT_AVAILABLE](str(e))
except (http_client.ResponseNotReady, OSError) as e: except (http.client.ResponseNotReady, OSError) as e:
errMsg = f'Connection error: {str(e) or repr(e)}' errMsg = f'Connection error: {str(e) or repr(e)}'
if n != triesLimit: if n != triesLimit:
waitOnFailure(n, triesLimit, SOCKET_ERROR_RC, errMsg) waitOnFailure(n, triesLimit, SOCKET_ERROR_RC, errMsg)
@@ -9141,7 +9182,7 @@ def showJSON(showName, showValue, skipObjects=None, timeObjects=None,
return return
if objectName is not None: if objectName is not None:
printJSONKey(objectName) printJSONKey(objectName)
subObjectKey = dictObjectsKey.get(objectName) subObjectKey = dictObjectsKey.get(objectName)
if isinstance(objectValue, list): if isinstance(objectValue, list):
if objectName in simpleLists: if objectName in simpleLists:
printJSONValue(' '.join(objectValue)) printJSONValue(' '.join(objectValue))
@@ -9596,7 +9637,7 @@ def CSVFileQueueHandler(mpQueue, mpQueueStdout, mpQueueStderr, csvPF, datetimeNo
clearRowFilters = False clearRowFilters = False
# if sys.platform.startswith('win'): # if sys.platform.startswith('win'):
# signal.signal(signal.SIGINT, signal.SIG_IGN) # signal.signal(signal.SIGINT, signal.SIG_IGN)
if multiprocessing.get_start_method() == 'spawn': if multiprocessing.get_start_method() != 'fork':
signal.signal(signal.SIGINT, signal.SIG_IGN) signal.signal(signal.SIGINT, signal.SIG_IGN)
Cmd = glclargs.GamCLArgs() Cmd = glclargs.GamCLArgs()
else: else:
@@ -9638,7 +9679,7 @@ def CSVFileQueueHandler(mpQueue, mpQueueStdout, mpQueueStderr, csvPF, datetimeNo
Cmd.InitializeArguments(dataItem) Cmd.InitializeArguments(dataItem)
elif dataType == GM.REDIRECT_QUEUE_GLOBALS: elif dataType == GM.REDIRECT_QUEUE_GLOBALS:
GM.Globals = dataItem GM.Globals = dataItem
if multiprocessing.get_start_method() == 'spawn': if multiprocessing.get_start_method() != 'fork':
reopenSTDFile(GM.STDOUT) reopenSTDFile(GM.STDOUT)
reopenSTDFile(GM.STDERR) reopenSTDFile(GM.STDERR)
elif dataType == GM.REDIRECT_QUEUE_VALUES: elif dataType == GM.REDIRECT_QUEUE_VALUES:
@@ -9684,7 +9725,7 @@ def initializeCSVFileQueueHandler(mpManager, mpQueueStdout, mpQueueStderr):
def terminateCSVFileQueueHandler(mpQueue, mpQueueHandler): def terminateCSVFileQueueHandler(mpQueue, mpQueueHandler):
GM.Globals[GM.PARSER] = None GM.Globals[GM.PARSER] = None
GM.Globals[GM.CSVFILE][GM.REDIRECT_QUEUE] = None GM.Globals[GM.CSVFILE][GM.REDIRECT_QUEUE] = None
if multiprocessing.get_start_method() == 'spawn': if multiprocessing.get_start_method() != 'fork':
mpQueue.put((GM.REDIRECT_QUEUE_ARGS, Cmd.AllArguments())) mpQueue.put((GM.REDIRECT_QUEUE_ARGS, Cmd.AllArguments()))
savedValues = saveNonPickleableValues() savedValues = saveNonPickleableValues()
mpQueue.put((GM.REDIRECT_QUEUE_GLOBALS, GM.Globals)) mpQueue.put((GM.REDIRECT_QUEUE_GLOBALS, GM.Globals))
@@ -9714,13 +9755,13 @@ def StdQueueHandler(mpQueue, stdtype, gmGlobals, gcValues):
# if sys.platform.startswith('win'): # if sys.platform.startswith('win'):
# signal.signal(signal.SIGINT, signal.SIG_IGN) # signal.signal(signal.SIGINT, signal.SIG_IGN)
if multiprocessing.get_start_method() == 'spawn': if multiprocessing.get_start_method() != 'fork':
signal.signal(signal.SIGINT, signal.SIG_IGN) signal.signal(signal.SIGINT, signal.SIG_IGN)
GM.Globals = gmGlobals.copy() GM.Globals = gmGlobals.copy()
GC.Values = gcValues.copy() GC.Values = gcValues.copy()
pid0DataItem = [KEYBOARD_INTERRUPT_RC, None] pid0DataItem = [KEYBOARD_INTERRUPT_RC, None]
pidData = {} pidData = {}
if multiprocessing.get_start_method() == 'spawn': if multiprocessing.get_start_method() != 'fork':
if GM.Globals[stdtype][GM.REDIRECT_NAME] == 'null': if GM.Globals[stdtype][GM.REDIRECT_NAME] == 'null':
fd = open(os.devnull, GM.Globals[stdtype][GM.REDIRECT_MODE], encoding=UTF8) fd = open(os.devnull, GM.Globals[stdtype][GM.REDIRECT_MODE], encoding=UTF8)
elif GM.Globals[stdtype][GM.REDIRECT_NAME] == '-': elif GM.Globals[stdtype][GM.REDIRECT_NAME] == '-':
@@ -9808,7 +9849,7 @@ def ProcessGAMCommandMulti(pid, numItems, logCmd, mpQueueCSVFile, mpQueueStdout,
with mplock: with mplock:
initializeLogging() initializeLogging()
# if sys.platform.startswith('win'): # if sys.platform.startswith('win'):
if multiprocessing.get_start_method() == 'spawn': if multiprocessing.get_start_method() != 'fork':
signal.signal(signal.SIGINT, signal.SIG_IGN) signal.signal(signal.SIGINT, signal.SIG_IGN)
GM.Globals[GM.API_CALLS_RETRY_DATA] = {} GM.Globals[GM.API_CALLS_RETRY_DATA] = {}
GM.Globals[GM.CMDLOG_LOGGER] = None GM.Globals[GM.CMDLOG_LOGGER] = None
@@ -9949,7 +9990,7 @@ def MultiprocessGAMCommands(items, showCmds):
mpManager = multiprocessing.Manager() mpManager = multiprocessing.Manager()
l = mpManager.Lock() l = mpManager.Lock()
try: try:
if multiprocessing.get_start_method() == 'spawn': if multiprocessing.get_start_method() != 'fork':
pool = mpManager.Pool(processes=numPoolProcesses, initializer=initGamWorker, initargs=(l,), maxtasksperchild=200) pool = mpManager.Pool(processes=numPoolProcesses, initializer=initGamWorker, initargs=(l,), maxtasksperchild=200)
else: else:
pool = multiprocessing.Pool(processes=numPoolProcesses, initializer=initGamWorker, initargs=(l,), maxtasksperchild=200) pool = multiprocessing.Pool(processes=numPoolProcesses, initializer=initGamWorker, initargs=(l,), maxtasksperchild=200)
@@ -9958,7 +9999,7 @@ def MultiprocessGAMCommands(items, showCmds):
except AssertionError as e: except AssertionError as e:
Cmd.SetLocation(0) Cmd.SetLocation(0)
usageErrorExit(str(e)) usageErrorExit(str(e))
if multiprocessing.get_start_method() == 'spawn': if multiprocessing.get_start_method() != 'fork':
savedValues = saveNonPickleableValues() savedValues = saveNonPickleableValues()
if GM.Globals[GM.STDOUT][GM.REDIRECT_MULTIPROCESS]: if GM.Globals[GM.STDOUT][GM.REDIRECT_MULTIPROCESS]:
mpQueueStdout, mpQueueHandlerStdout = initializeStdQueueHandler(mpManager, GM.STDOUT, GM.Globals, GC.Values) mpQueueStdout, mpQueueHandlerStdout = initializeStdQueueHandler(mpManager, GM.STDOUT, GM.Globals, GC.Values)
@@ -9973,7 +10014,7 @@ def MultiprocessGAMCommands(items, showCmds):
mpQueueStderr = mpQueueStdout mpQueueStderr = mpQueueStdout
else: else:
mpQueueStderr = None mpQueueStderr = None
if multiprocessing.get_start_method() == 'spawn': if multiprocessing.get_start_method() != 'fork':
restoreNonPickleableValues(savedValues) restoreNonPickleableValues(savedValues)
if mpQueueStdout: if mpQueueStdout:
mpQueueStdout.put((0, GM.REDIRECT_QUEUE_DATA, GM.Globals[GM.STDOUT][GM.REDIRECT_MULTI_FD].getvalue())) mpQueueStdout.put((0, GM.REDIRECT_QUEUE_DATA, GM.Globals[GM.STDOUT][GM.REDIRECT_MULTI_FD].getvalue()))
@@ -11137,7 +11178,7 @@ class Credentials(google.oauth2.credentials.Credentials):
def doOAuthRequest(currentScopes, login_hint, verifyScopes=False): def doOAuthRequest(currentScopes, login_hint, verifyScopes=False):
client_id, client_secret = getOAuthClientIDAndSecret() client_id, client_secret = getOAuthClientIDAndSecret()
scopesList = API.getClientScopesList(GC.Values[GC.TODRIVE_CLIENTACCESS]) scopesList = API.getClientScopesList(GC.Values[GC.COMMANDDATA_CLIENTACCESS], GC.Values[GC.TODRIVE_CLIENTACCESS])
if not currentScopes or verifyScopes: if not currentScopes or verifyScopes:
selectedScopes = getScopesFromUser(scopesList, True, currentScopes) selectedScopes = getScopesFromUser(scopesList, True, currentScopes)
if selectedScopes is None: if selectedScopes is None:
@@ -11183,7 +11224,7 @@ def doOAuthCreate():
else: else:
login_hint = None login_hint = None
scopes = [] scopes = []
scopesList = API.getClientScopesList(GC.Values[GC.TODRIVE_CLIENTACCESS]) scopesList = API.getClientScopesList(GC.Values[GC.COMMANDDATA_CLIENTACCESS], GC.Values[GC.TODRIVE_CLIENTACCESS])
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
if myarg == 'admin': if myarg == 'admin':
@@ -11199,7 +11240,9 @@ def doOAuthCreate():
scopes.append(uscope) scopes.append(uscope)
break break
else: else:
invalidChoiceExit(uscope, API.getClientScopesURLs(GC.Values[GC.TODRIVE_CLIENTACCESS]), True) invalidChoiceExit(uscope,
API.getClientScopesURLs(GC.Values[GC.COMMANDDATA_CLIENTACCESS], GC.Values[GC.TODRIVE_CLIENTACCESS]),
True)
else: else:
unknownArgumentExit() unknownArgumentExit()
if len(scopes) == 0: if len(scopes) == 0:
@@ -11310,7 +11353,7 @@ def doOAuthUpdate():
if 'scopes' in jsonDict: if 'scopes' in jsonDict:
currentScopes = jsonDict['scopes'] currentScopes = jsonDict['scopes']
else: else:
currentScopes = API.getClientScopesURLs(GC.Values[GC.TODRIVE_CLIENTACCESS]) currentScopes = API.getClientScopesURLs(GC.Values[GC.COMMANDDATA_CLIENTACCESS], GC.Values[GC.TODRIVE_CLIENTACCESS])
else: else:
currentScopes = [] currentScopes = []
except (AttributeError, IndexError, KeyError, SyntaxError, TypeError, ValueError) as e: except (AttributeError, IndexError, KeyError, SyntaxError, TypeError, ValueError) as e:
@@ -12340,8 +12383,6 @@ def checkServiceAccount(users):
saScopes[scope['api']].append(scope['roscope']) saScopes[scope['api']].append(scope['roscope'])
checkScopesSet.add(scope['roscope']) checkScopesSet.add(scope['roscope'])
i += 1 i += 1
if API.DRIVEACTIVITY in saScopes and API.DRIVE3 in saScopes:
saScopes[API.DRIVEACTIVITY].append(API.DRIVE_SCOPE)
if API.DRIVE3 in saScopes: if API.DRIVE3 in saScopes:
saScopes[API.DRIVE2] = saScopes[API.DRIVE3] saScopes[API.DRIVE2] = saScopes[API.DRIVE3]
GM.Globals[GM.OAUTH2SERVICE_JSON_DATA][API.OAUTH2SA_SCOPES] = saScopes GM.Globals[GM.OAUTH2SERVICE_JSON_DATA][API.OAUTH2SA_SCOPES] = saScopes
@@ -26465,14 +26506,18 @@ CHAT_TIME_OBJECTS = {'createTime', 'deleteTime', 'eventTime', 'lastActiveTime',
def _showChatItem(citem, entityType, FJQC, i=0, count=0): def _showChatItem(citem, entityType, FJQC, i=0, count=0):
if entityType == Ent.CHAT_SPACE: if entityType == Ent.CHAT_SPACE:
_cleanChatSpace(citem) _cleanChatSpace(citem)
dictObjectsKey = {None: 'displayName'}
elif entityType == Ent.CHAT_MESSAGE: elif entityType == Ent.CHAT_MESSAGE:
_cleanChatMessage(citem) _cleanChatMessage(citem)
dictObjectsKey = {None: 'text'}
else:
dictObjectsKey={}
if FJQC.formatJSON: if FJQC.formatJSON:
printLine(json.dumps(cleanJSON(citem, timeObjects=CHAT_TIME_OBJECTS), ensure_ascii=False, sort_keys=True)) printLine(json.dumps(cleanJSON(citem, timeObjects=CHAT_TIME_OBJECTS), ensure_ascii=False, sort_keys=True))
return return
printEntity([entityType, citem['name']], i, count) printEntity([entityType, citem['name']], i, count)
Ind.Increment() Ind.Increment()
showJSON(None, citem, timeObjects=CHAT_TIME_OBJECTS) showJSON(None, citem, timeObjects=CHAT_TIME_OBJECTS, dictObjectsKey=dictObjectsKey)
Ind.Decrement() Ind.Decrement()
def _printChatItem(user, citem, parent, entityType, csvPF, FJQC, addCSVData=None): def _printChatItem(user, citem, parent, entityType, csvPF, FJQC, addCSVData=None):
@@ -26731,14 +26776,14 @@ def getChatSpaceParameters(myarg, body, typeChoicesMap, updateMask):
CHAT_MEMBER_ROLE_MAP = { CHAT_MEMBER_ROLE_MAP = {
'member': 'ROLE_MEMBER', 'member': 'ROLE_MEMBER',
'manager': 'ROLE_MANAGER', 'manager': 'ROLE_ASSISTANT_MANAGER',
'owner': 'ROLE_OWNER', 'owner': 'ROLE_MANAGER',
} }
CHAT_ROLE_ENTITY_TYPE_MAP = { CHAT_ROLE_ENTITY_TYPE_MAP = {
'ROLE_MEMBER': Ent.CHAT_MEMBER_USER, 'ROLE_MEMBER': Ent.CHAT_MEMBER_USER,
'ROLE_MANAGER': Ent.CHAT_MANAGER_USER, 'ROLE_ASSISTANT_MANAGER': Ent.CHAT_MANAGER_USER,
'ROLE_OWNER': Ent.CHAT_OWNER_USER, 'ROLE_MANAGER': Ent.CHAT_OWNER_USER,
} }
CHAT_MEMBER_TYPE_MAP = { CHAT_MEMBER_TYPE_MAP = {
@@ -26872,7 +26917,8 @@ CHAT_UPDATE_SPACE_TYPE_MAP = {
} }
CHAT_SPACE_ROLE_PERMISSIONS_MAP = { CHAT_SPACE_ROLE_PERMISSIONS_MAP = {
'managers': 'managersAllowed', 'owners': 'managersAllowed',
'managers': 'assistantManagersAllowed',
'members': 'membersAllowed', 'members': 'membersAllowed',
} }
@@ -26892,13 +26938,13 @@ CHAT_UPDATE_SPACE_PERMISSIONS_MAP = {
# [type space] # [type space]
# [description <String>] [guidelines|rules <String>] # [description <String>] [guidelines|rules <String>]
# [history <Boolean>]) # [history <Boolean>])
# managemembersandgroups managers|members # [managemembersandgroups owners|managers|members]
# modifyspacedetails managers|members # [modifyspacedetails owners|managers|members]
# togglehistory managers|members # [togglehistory owners|managers|members]
# useatmentionall managers|members # [useatmentionall owners|managers|members]
# manageapps managers|members # [manageapps owners|managers|members]
# managewebhooks managers|members # [managewebhooks owners|managers|members]
# replymessages managers|members 2# [replymessages owners|managers|members]
# [formatjson] # [formatjson]
def updateChatSpace(users): def updateChatSpace(users):
FJQC = FormatJSONQuoteChar() FJQC = FormatJSONQuoteChar()
@@ -26916,9 +26962,13 @@ def updateChatSpace(users):
body.setdefault('permissionSettings', {}) body.setdefault('permissionSettings', {})
permissionSetting = CHAT_UPDATE_SPACE_PERMISSIONS_MAP[myarg] permissionSetting = CHAT_UPDATE_SPACE_PERMISSIONS_MAP[myarg]
role = getChoice(CHAT_SPACE_ROLE_PERMISSIONS_MAP, mapChoice=True) role = getChoice(CHAT_SPACE_ROLE_PERMISSIONS_MAP, mapChoice=True)
body['permissionSettings'][permissionSetting] = {'managersAllowed': True} body['permissionSettings'][permissionSetting] = {}
body['permissionSettings'][permissionSetting][role] = True
if role == 'membersAllowed': if role == 'membersAllowed':
body['permissionSettings'][permissionSetting].update({'membersAllowed': True}) body['permissionSettings'][permissionSetting]['assistantManagersAllowed'] = True
body['permissionSettings'][permissionSetting]['managersAllowed'] = True
elif role == 'assistantManagersAllowed':
body['permissionSettings'][permissionSetting]['managersAllowed'] = True
updateMask.add(f'permissionSettings.{permissionSetting}') updateMask.add(f'permissionSettings.{permissionSetting}')
else: else:
FJQC.GetFormatJSON(myarg) FJQC.GetFormatJSON(myarg)
@@ -27292,12 +27342,12 @@ def getGroupMemberID(cd, group, groupList):
groupList.append(convertEmailAddressToUID(group, cd, emailType='group')) groupList.append(convertEmailAddressToUID(group, cd, emailType='group'))
# gam <UserTypeEntity> create chatmember <ChatSpace> # gam <UserTypeEntity> create chatmember <ChatSpace>
# [type human|bot] [role member|manager] # [type human|bot] [role member|manager|owner]
# (user <UserItem>)* (members <UserTypeEntity>)* # (user <UserItem>)* (members <UserTypeEntity>)*
# (group <GroupItem>)* (groups <GroupEntity>)* # (group <GroupItem>)* (groups <GroupEntity>)*
# [formatjson|returnidonly] # [formatjson|returnidonly]
# gam <UserItem> create chatmember asadmin <ChatSpace> # gam <UserItem> create chatmember asadmin <ChatSpace>
# [type human|bot] [role member|manager] # [type human|bot] [role member|manager|owner]
# (user <UserItem>)* (members <UserTypeEntity>)* # (user <UserItem>)* (members <UserTypeEntity>)*
# (group <GroupItem>)* (groups <GroupEntity>)* # (group <GroupItem>)* (groups <GroupEntity>)*
# [formatjson|returnidonly] # [formatjson|returnidonly]
@@ -27426,16 +27476,16 @@ def _deleteChatMembers(chat, kvList, jcount, memberNames, i, count, kwargsUAA):
# gam <UserItem> remove chatmember asadmin # gam <UserItem> remove chatmember asadmin
# members <ChatMemberList> # members <ChatMemberList>
# gam <UserTypeEntity> update chatmember <ChatSpace> # gam <UserTypeEntity> update chatmember <ChatSpace>
# role member|manager # role member|manager|owner
# ((user <UserItem>)|(members <UserTypeEntity>))+ # ((user <UserItem>)|(members <UserTypeEntity>))+
# gam <UserTypeEntity> modify chatmember # gam <UserTypeEntity> modify chatmember
# role member|manager # role member|manager|owner
# members <ChatMemberList> # members <ChatMemberList>
# gam <UserItem> update chatmember asadmin<ChatSpace> # gam <UserItem> update chatmember asadmin<ChatSpace>
# role member|manager # role member|manager|owner
# ((user <UserItem>)|(members <UserTypeEntity>))+ # ((user <UserItem>)|(members <UserTypeEntity>))+
# gam <UserItem> modify chatmember asadmin # gam <UserItem> modify chatmember asadmin
# role member|manager # role member|manager|owner
# members <ChatMemberList> # members <ChatMemberList>
def deleteUpdateChatMember(users): def deleteUpdateChatMember(users):
cd = buildGAPIObject(API.DIRECTORY) cd = buildGAPIObject(API.DIRECTORY)
@@ -27529,7 +27579,7 @@ def deleteUpdateChatMember(users):
CHAT_SYNC_PREVIEW_TITLES = ['space', 'member', 'role', 'action', 'message'] CHAT_SYNC_PREVIEW_TITLES = ['space', 'member', 'role', 'action', 'message']
# gam <UserTypeEntity> sync chatmembers [asadmin] <ChatSpace> # gam <UserTypeEntity> sync chatmembers [asadmin] <ChatSpace>
# [role member|manager] [type human|bot] # [role member|manager|owner] [type human|bot]
# [addonly|removeonly] # [addonly|removeonly]
# [preview [actioncsv]] # [preview [actioncsv]]
# (users <UserTypeEntity>)* (groups <GroupEntity>)* # (users <UserTypeEntity>)* (groups <GroupEntity>)*
@@ -27945,10 +27995,11 @@ def _getChatSenderEmail(cd, sender):
sender['email'], _ = convertUIDtoEmailAddressWithType(f'uid:{senderUid}', cd, None, emailTypes=['user']) sender['email'], _ = convertUIDtoEmailAddressWithType(f'uid:{senderUid}', cd, None, emailTypes=['user'])
def trimChatMessageIfRequired(body): def trimChatMessageIfRequired(body):
msgLen = len(body['text']) if 'text' in body:
if msgLen > 4096: msgLen = len(body['text'])
stderrWarningMsg(Msg.TRIMMED_MESSAGE_FROM_LENGTH_TO_MAXIMUM.format(msgLen, 4096)) if msgLen > 4096:
body['text'] = body['text'][:4095] stderrWarningMsg(Msg.TRIMMED_MESSAGE_FROM_LENGTH_TO_MAXIMUM.format(msgLen, 4096))
body['text'] = body['text'][:4095]
CHAT_MESSAGE_REPLY_OPTION_MAP = { CHAT_MESSAGE_REPLY_OPTION_MAP = {
'fail': 'REPLY_MESSAGE_OR_FAIL', 'fail': 'REPLY_MESSAGE_OR_FAIL',
@@ -28025,22 +28076,29 @@ def doCreateChatMessage():
createChatMessage([None]) createChatMessage([None])
# gam [<UserTypeMessage>] update chatmessage name <ChatMessage> # gam [<UserTypeMessage>] update chatmessage name <ChatMessage>
# <ChatContent> # [<ChatContent>] [clearattachments <String>]
def updateChatMessage(users): def updateChatMessage(users):
name = None name = None
body = {} body = {}
updateMask = []
clearMsg = ''
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
if myarg == 'name': if myarg == 'name':
name = getString(Cmd.OB_CHAT_MESSAGE) name = getString(Cmd.OB_CHAT_MESSAGE)
elif myarg in SORF_TEXT_ARGUMENTS: elif myarg in SORF_TEXT_ARGUMENTS:
body['text'] = getStringOrFile(myarg, minLen=0, unescapeCRLF=True)[0] body['text'] = getStringOrFile(myarg, minLen=0, unescapeCRLF=True)[0]
updateMask.append('text')
elif myarg == 'clearattachments':
clearMsg = getString(Cmd.OB_STRING, minLen=0)
body['attachment'] = []
updateMask.append('attachment')
else: else:
unknownArgumentExit() unknownArgumentExit()
if not name: if not name:
missingArgumentExit('name') missingArgumentExit('name')
if 'text' not in body: if not updateMask:
missingArgumentExit('text or textfile') missingArgumentExit('text|textfile|clearattachments')
trimChatMessageIfRequired(body) trimChatMessageIfRequired(body)
i, count, users = getEntityArgument(users) i, count, users = getEntityArgument(users)
for user in users: for user in users:
@@ -28049,9 +28107,19 @@ def updateChatMessage(users):
if not chat: if not chat:
continue continue
try: try:
if 'attachment' in updateMask and 'text' not in updateMask:
resp = callGAPI(chat.spaces().messages(), 'get',
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
name=name, fields='text')
body['text'] = resp.get('text', '')
if clearMsg:
body['text'] += clearMsg
elif not body['text']:
body['text'] = 'Attachments cleared'
updateMask.append('text')
resp = callGAPI(chat.spaces().messages(), 'patch', resp = callGAPI(chat.spaces().messages(), 'patch',
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION], throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
name=name, updateMask='text', body=body) name=name, updateMask=','.join(updateMask), body=body)
kvList.extend([Ent.CHAT_THREAD, resp['thread']['name']]) kvList.extend([Ent.CHAT_THREAD, resp['thread']['name']])
entityActionPerformed(kvList, i, count) entityActionPerformed(kvList, i, count)
except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e: except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e:
@@ -32960,6 +33028,8 @@ def doCreateGroup(ciGroupsAPI=False):
initialGroupConfig = 'WITH_INITIAL_OWNER' initialGroupConfig = 'WITH_INITIAL_OWNER'
elif ciGroupsAPI and myarg in {'security', 'makesecuritygroup'}: elif ciGroupsAPI and myarg in {'security', 'makesecuritygroup'}:
body['labels'][CIGROUP_SECURITY_LABEL] = '' body['labels'][CIGROUP_SECURITY_LABEL] = ''
elif ciGroupsAPI and myarg in ['locked']:
body['labels'][CIGROUP_LOCKED_LABEL] = ''
elif myarg == 'verifynotinvitable': elif myarg == 'verifynotinvitable':
verifyNotInvitable = True verifyNotInvitable = True
else: else:
@@ -44166,6 +44236,28 @@ USER_JSON_SKIP_FIELDS = ['agreedToTerms', 'aliases', 'creationTime', 'customerId
ALLOW_EMPTY_CUSTOM_TYPE = 'allowEmptyCustomType' ALLOW_EMPTY_CUSTOM_TYPE = 'allowEmptyCustomType'
def getNotifyArguments(myarg, notify, userNotification):
if myarg == 'notify':
if userNotification:
notify['recipients'].extend(getNormalizedEmailAddressEntity(shlexSplit=True, noLower=True))
else: #delegateNotificatiomn
notify['notify'] = getBoolean()
elif myarg == 'subject':
notify['subject'] = getString(Cmd.OB_STRING)
elif myarg in SORF_MSG_FILE_ARGUMENTS:
notify['message'], notify['charset'], notify['html'] = getStringOrFile(myarg)
elif myarg == 'html':
notify['html'] = getBoolean()
elif myarg == 'from':
notify['from'] = getString(Cmd.OB_EMAIL_ADDRESS)
elif myarg == 'mailbox':
notify['mailbox'] = getString(Cmd.OB_EMAIL_ADDRESS)
elif myarg == 'replyto':
notify['replyto'] = getString(Cmd.OB_EMAIL_ADDRESS)
else:
return False
return True
def getUserAttributes(cd, updateCmd, noUid=False): def getUserAttributes(cd, updateCmd, noUid=False):
def getKeywordAttribute(keywords, attrdict, **opts): def getKeywordAttribute(keywords, attrdict, **opts):
if Cmd.ArgumentsRemaining(): if Cmd.ArgumentsRemaining():
@@ -44281,22 +44373,10 @@ def getUserAttributes(cd, updateCmd, noUid=False):
resolveConflictAccount = True resolveConflictAccount = True
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
if myarg == 'notify': if getNotifyArguments(myarg, notify, True):
notify['recipients'].extend(getNormalizedEmailAddressEntity(shlexSplit=True, noLower=True)) pass
elif myarg == 'notifyrecoveryemail': elif myarg == 'notifyrecoveryemail':
parameters['notifyRecoveryEmail'] = True parameters['notifyRecoveryEmail'] = True
elif myarg == 'subject':
notify['subject'] = getString(Cmd.OB_STRING)
elif myarg in SORF_MSG_FILE_ARGUMENTS:
notify['message'], notify['charset'], notify['html'] = getStringOrFile(myarg)
elif myarg == 'html':
notify['html'] = getBoolean()
elif myarg == 'from':
notify['from'] = getString(Cmd.OB_EMAIL_ADDRESS)
elif myarg == 'replyto':
notify['replyto'] = getString(Cmd.OB_EMAIL_ADDRESS)
elif myarg == 'mailbox':
notify['mailbox'] = getString(Cmd.OB_EMAIL_ADDRESS)
elif PwdOpts.ProcessArgument(myarg, notify, notFoundBody): elif PwdOpts.ProcessArgument(myarg, notify, notFoundBody):
pass pass
elif _getTagReplacement(myarg, tagReplacements, True): elif _getTagReplacement(myarg, tagReplacements, True):
@@ -44702,12 +44782,12 @@ def createUserAddAliases(cd, user, aliasList, i, count):
# [license <SKUID> [product|productid <ProductID>]] # [license <SKUID> [product|productid <ProductID>]]
# [[notify <EmailAddressList>] [notifyrecoveryemail] # [[notify <EmailAddressList>] [notifyrecoveryemail]
# [subject <String>] # [subject <String>]
# [notifypassword <String>] # [from <EmailAaddress>] [mailbox <EmailAddress>]
# [from <EmailAaddress>]
# [replyto <EmailAaddress>] # [replyto <EmailAaddress>]
# [<NotifyMessageContent>] # [notifypassword <String>]
# (replace <Tag> <UserReplacement>)* # [<NotifyMessageContent>] [html [<Boolean>]]
# (replaceregex <REMatchPattern> <RESubstitution> <Tag> <UserReplacement>)*] # (replace <Tag> <UserReplacement>)*
# (replaceregex <REMatchPattern> <RESubstitution> <Tag> <UserReplacement>)*]
# [logpassword <FileName>] [ignorenullpassword] # [logpassword <FileName>] [ignorenullpassword]
# [addnumericsuffixonduplicate <Number>] # [addnumericsuffixonduplicate <Number>]
def doCreateUser(): def doCreateUser():
@@ -44806,12 +44886,12 @@ def verifyUserPrimaryEmail(cd, user, createIfNotFound, i, count):
# [alias|aliases <EmailAddressList>] # [alias|aliases <EmailAddressList>]
# [[notify <EmailAddressList>] [notifyrecoveryemail] # [[notify <EmailAddressList>] [notifyrecoveryemail]
# [subject <String>] # [subject <String>]
# [notifypassword <String>] # [from <EmailAaddress>] [mailbox <EmailAddress>]
# [from <EmailAaddress>]
# [replyto <EmailAaddress>] # [replyto <EmailAaddress>]
# [<NotifyMessageContent> # [<NotifyMessageContent> [html [<Boolean>]]
# (replace <Tag> <UserReplacement>)* # (replace <Tag> <UserReplacement>)*
# (replaceregex <REMatchPattern> <RESubstitution> <Tag> <UserReplacement>)*] # (replaceregex <REMatchPattern> <RESubstitution> <Tag> <UserReplacement>)*]
# [notifypassword <String>]]
# [notifyonupdate [<Boolean>]] # [notifyonupdate [<Boolean>]]
# [logpassword <FileName>] [ignorenullpassword] # [logpassword <FileName>] [ignorenullpassword]
def updateUsers(entityList): def updateUsers(entityList):
@@ -64876,11 +64956,11 @@ def claimOwnership(users):
elif myarg == 'onlyusers': elif myarg == 'onlyusers':
_, userList = getEntityToModify(defaultEntityType=Cmd.ENTITY_USERS) _, userList = getEntityToModify(defaultEntityType=Cmd.ENTITY_USERS)
checkOnly = True checkOnly = True
onlyOwners = set(userList) onlyOwners = {normalizeEmailAddressOrUID(user, noUid=True) for user in userList}
elif myarg == 'skipusers': elif myarg == 'skipusers':
_, userList = getEntityToModify(defaultEntityType=Cmd.ENTITY_USERS) _, userList = getEntityToModify(defaultEntityType=Cmd.ENTITY_USERS)
checkSkip = len(userList) > 0 checkSkip = len(userList) > 0
skipOwners = set(userList) skipOwners = {normalizeEmailAddressOrUID(user, noUid=True) for user in userList}
elif myarg == 'subdomains': elif myarg == 'subdomains':
subdomains = getEntityList(Cmd.OB_DOMAIN_NAME_ENTITY) subdomains = getEntityList(Cmd.OB_DOMAIN_NAME_ENTITY)
elif myarg == 'includetrashed': elif myarg == 'includetrashed':
@@ -73853,14 +73933,58 @@ def printShowMessages(users):
def printShowThreads(users): def printShowThreads(users):
printShowMessagesThreads(users, Ent.THREAD) printShowMessagesThreads(users, Ent.THREAD)
def sendCreateDelegateNotification(user, delegate, basenotify, i=0, count=0, msgFrom=None):
# Substitute for #user#, #delegate#
def _substituteForPattern(field, pattern, value):
if field.find('#') == -1:
return field
return field.replace(pattern, value)
def _makeSubstitutions(field):
notify[field] = _substituteForPattern(notify[field], '#user#', user)
notify[field] = _substituteForPattern(notify[field], '#delegate#', delegate)
notify = basenotify.copy()
if not notify['subject']:
notify['subject'] = Msg.CREATE_DELEGATE_NOTIFY_SUBJECT
_makeSubstitutions('subject')
if not notify['message']:
notify['message'] = Msg.CREATE_DELEGATE_NOTIFY_MESSAGE
elif notify['html']:
notify['message'] = notify['message'].replace('\r', '').replace('\\n', '<br/>')
else:
notify['message'] = notify['message'].replace('\r', '').replace('\\n', '\n')
_makeSubstitutions('message')
if 'from' in notify:
msgFrom = notify['from']
msgReplyTo = notify.get('replyto', None)
mailBox = notify.get('mailbox', None)
send_email(notify['subject'], notify['message'], delegate, i, count,
msgFrom=msgFrom, msgReplyTo=msgReplyTo, html=notify['html'], charset=notify['charset'], mailBox=mailBox)
# gam <UserTypeEntity> create delegate|delegates [convertalias] <UserEntity> # gam <UserTypeEntity> create delegate|delegates [convertalias] <UserEntity>
# [notify [<Boolean>]
# [subject <String>]
# [from <EmailAaddress>] [mailbox <EmailAddress>]
# [replyto <EmailAaddress>]
# [<NotifyMessageContent>] [html [<Boolean>]]
# ]
# gam <UserTypeEntity> delete delegate|delegates [convertalias] <UserEntity> # gam <UserTypeEntity> delete delegate|delegates [convertalias] <UserEntity>
def processDelegates(users): def processDelegates(users):
cd = buildGAPIObject(API.DIRECTORY) cd = buildGAPIObject(API.DIRECTORY)
function = 'delete' if Act.Get() == Act.DELETE else 'create' createCmd = Act.Get() != Act.DELETE
aliasAllowed = not checkArgumentPresent(['convertalias']) aliasAllowed = not checkArgumentPresent(['convertalias'])
delegateEntity = getUserObjectEntity(Cmd.OB_USER_ENTITY, Ent.DELEGATE) delegateEntity = getUserObjectEntity(Cmd.OB_USER_ENTITY, Ent.DELEGATE)
checkForExtraneousArguments() notify = {'notify': False, 'subject': '', 'message': '', 'html': False, 'charset': UTF8}
if createCmd:
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if getNotifyArguments(myarg, notify, False):
pass
else:
unknownArgumentExit()
else:
checkForExtraneousArguments()
i, count, users = getEntityArgument(users) i, count, users = getEntityArgument(users)
for user in users: for user in users:
i += 1 i += 1
@@ -73872,25 +73996,37 @@ def processDelegates(users):
for delegate in delegates: for delegate in delegates:
j += 1 j += 1
delegateEmail = convertUIDtoEmailAddress(delegate, cd=cd, emailTypes=['user', 'group'], aliasAllowed=aliasAllowed) delegateEmail = convertUIDtoEmailAddress(delegate, cd=cd, emailTypes=['user', 'group'], aliasAllowed=aliasAllowed)
kvList = [Ent.USER, user, Ent.DELEGATE, delegateEmail]
try: try:
if function == 'create': if createCmd:
callGAPI(gmail.users().settings().delegates(), function, callGAPI(gmail.users().settings().delegates(), 'create',
throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.ALREADY_EXISTS, GAPI.FAILED_PRECONDITION, GAPI.INVALID, throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.ALREADY_EXISTS, GAPI.FAILED_PRECONDITION, GAPI.INVALID,
GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED], GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
userId='me', body={'delegateEmail': delegateEmail}) userId='me', body={'delegateEmail': delegateEmail})
entityActionPerformed(kvList, j, jcount)
if notify['notify']:
Ind.Increment()
sendCreateDelegateNotification(user, delegateEmail, notify, j, jcount)
Ind.Decrement()
else: else:
callGAPI(gmail.users().settings().delegates(), function, callGAPI(gmail.users().settings().delegates(), 'delete',
throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.NOT_FOUND, GAPI.INVALID_INPUT, GAPI.PERMISSION_DENIED], throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.NOT_FOUND, GAPI.INVALID_INPUT, GAPI.PERMISSION_DENIED],
userId='me', delegateEmail=delegateEmail) userId='me', delegateEmail=delegateEmail)
entityActionPerformed([Ent.USER, user, Ent.DELEGATE, delegateEmail], j, jcount) entityActionPerformed(kvList, j, jcount)
except (GAPI.alreadyExists, GAPI.failedPrecondition, GAPI.invalid, except (GAPI.alreadyExists, GAPI.failedPrecondition, GAPI.invalid,
GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e: GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e:
entityActionFailedWarning([Ent.USER, user, Ent.DELEGATE, delegateEmail], str(e), j, jcount) entityActionFailedWarning(kvList, str(e), j, jcount)
except GAPI.serviceNotAvailable: except GAPI.serviceNotAvailable:
userGmailServiceNotEnabledWarning(user, i, count) userGmailServiceNotEnabledWarning(user, i, count)
Ind.Decrement() Ind.Decrement()
# gam <UserTypeEntity> delegate to [convertalias] <UserEntity> # gam <UserTypeEntity> delegate to [convertalias] <UserEntity>
# [notify [<Boolean>]
# [subject <String>]
# [from <EmailAaddress>] [mailbox <EmailAddress>]
# [replyto <EmailAaddress>]
# [<NotifyMessageContent>] [html [<Boolean>]]
# ]
def delegateTo(users): def delegateTo(users):
checkArgumentPresent('to', required=True) checkArgumentPresent('to', required=True)
processDelegates(users) processDelegates(users)

View File

@@ -34,7 +34,12 @@ def main():
# Run from command line # Run from command line
if __name__ == '__main__': if __name__ == '__main__':
if platform.system() != 'Linux': if getattr(sys, 'frozen', False): # we're frozen:
multiprocessing.freeze_support() multiprocessing.freeze_support()
if platform.system() == 'Linux':
# set explictly since it's not default in Python < 3.14, forkserver should
# be safer than fork and less likely to see bulk command hangs.
multiprocessing.set_start_method('forkserver')
else:
multiprocessing.set_start_method('spawn') multiprocessing.set_start_method('spawn')
main() main()

View File

@@ -60,7 +60,6 @@ DIRECTORY = 'directory'
DOCS = 'docs' DOCS = 'docs'
DRIVE2 = 'drive2' DRIVE2 = 'drive2'
DRIVE3 = 'drive3' DRIVE3 = 'drive3'
DRIVECD = 'drivecd'
DRIVETD = 'drivetd' DRIVETD = 'drivetd'
DRIVEACTIVITY = 'driveactivity' DRIVEACTIVITY = 'driveactivity'
DRIVELABELS = 'drivelabels' DRIVELABELS = 'drivelabels'
@@ -92,7 +91,6 @@ SERVICEACCOUNTLOOKUP = 'serviceaccountlookup'
SERVICEMANAGEMENT = 'servicemanagement' SERVICEMANAGEMENT = 'servicemanagement'
SERVICEUSAGE = 'serviceusage' SERVICEUSAGE = 'serviceusage'
SHEETS = 'sheets' SHEETS = 'sheets'
SHEETSCD = 'sheetscd'
SHEETSTD = 'sheetstd' SHEETSTD = 'sheetstd'
SITEVERIFICATION = 'siteVerification' SITEVERIFICATION = 'siteVerification'
STORAGE = 'storage' STORAGE = 'storage'
@@ -107,6 +105,8 @@ YOUTUBE = 'youtube'
BUSINESSACCOUNTMANAGEMENT_SCOPE = 'https://www.googleapis.com/auth/business.manage' BUSINESSACCOUNTMANAGEMENT_SCOPE = 'https://www.googleapis.com/auth/business.manage'
CHROMEVERSIONHISTORY_URL = 'https://versionhistory.googleapis.com/v1/chrome/platforms' CHROMEVERSIONHISTORY_URL = 'https://versionhistory.googleapis.com/v1/chrome/platforms'
DRIVE_SCOPE = 'https://www.googleapis.com/auth/drive' DRIVE_SCOPE = 'https://www.googleapis.com/auth/drive'
DRIVE_FILE_SCOPE = 'https://www.googleapis.com/auth/drive.file'
DRIVE_READONLY_SCOPE = 'https://www.googleapis.com/auth/drive.readonly'
GMAIL_SEND_SCOPE = 'https://www.googleapis.com/auth/gmail.send' GMAIL_SEND_SCOPE = 'https://www.googleapis.com/auth/gmail.send'
GOOGLE_AUTH_PROVIDER_X509_CERT_URL = 'https://www.googleapis.com/oauth2/v1/certs' GOOGLE_AUTH_PROVIDER_X509_CERT_URL = 'https://www.googleapis.com/oauth2/v1/certs'
GOOGLE_OAUTH2_ENDPOINT = 'https://accounts.google.com/o/oauth2/v2/auth' GOOGLE_OAUTH2_ENDPOINT = 'https://accounts.google.com/o/oauth2/v2/auth'
@@ -158,6 +158,7 @@ OAUTH2_TOKEN_ERRORS = [
'access_denied: Account restricted', 'access_denied: Account restricted',
'internal_failure: Backend Error', 'internal_failure: Backend Error',
'internal_failure: None', 'internal_failure: None',
'invalid_account: Forbidden',
'invalid_grant', 'invalid_grant',
'invalid_grant: Bad Request', 'invalid_grant: Bad Request',
'invalid_grant: Invalid email or User ID', 'invalid_grant: Invalid email or User ID',
@@ -255,7 +256,6 @@ _INFO = {
DOCS: {'name': 'Docs API', 'version': 'v1', 'v2discovery': True}, DOCS: {'name': 'Docs API', 'version': 'v1', 'v2discovery': True},
DRIVE2: {'name': 'Drive API v2', 'version': 'v2', 'v2discovery': False, 'mappedAPI': 'drive'}, DRIVE2: {'name': 'Drive API v2', 'version': 'v2', 'v2discovery': False, 'mappedAPI': 'drive'},
DRIVE3: {'name': 'Drive API v3', 'version': 'v3', 'v2discovery': False, 'mappedAPI': 'drive'}, DRIVE3: {'name': 'Drive API v3', 'version': 'v3', 'v2discovery': False, 'mappedAPI': 'drive'},
DRIVECD: {'name': 'Drive API v3 - read command data', 'version': 'v3', 'v2discovery': False, 'mappedAPI': 'drive'},
DRIVETD: {'name': 'Drive API v3 - write todrive data', 'version': 'v3', 'v2discovery': False, 'mappedAPI': 'drive'}, DRIVETD: {'name': 'Drive API v3 - write todrive data', 'version': 'v3', 'v2discovery': False, 'mappedAPI': 'drive'},
DRIVEACTIVITY: {'name': 'Drive Activity API v2', 'version': 'v2', 'v2discovery': True}, DRIVEACTIVITY: {'name': 'Drive Activity API v2', 'version': 'v2', 'v2discovery': True},
DRIVELABELS_ADMIN: {'name': 'Drive Labels API - Admin', 'version': 'v2', 'v2discovery': True, 'mappedAPI': DRIVELABELS}, DRIVELABELS_ADMIN: {'name': 'Drive Labels API - Admin', 'version': 'v2', 'v2discovery': True, 'mappedAPI': DRIVELABELS},
@@ -286,7 +286,6 @@ _INFO = {
SERVICEMANAGEMENT: {'name': 'Service Management API', 'version': 'v1', 'v2discovery': True}, SERVICEMANAGEMENT: {'name': 'Service Management API', 'version': 'v1', 'v2discovery': True},
SERVICEUSAGE: {'name': 'Service Usage API', 'version': 'v1', 'v2discovery': True}, SERVICEUSAGE: {'name': 'Service Usage API', 'version': 'v1', 'v2discovery': True},
SHEETS: {'name': 'Sheets API', 'version': 'v4', 'v2discovery': True}, SHEETS: {'name': 'Sheets API', 'version': 'v4', 'v2discovery': True},
SHEETSCD: {'name': 'Sheets API - read command data', 'version': 'v4', 'v2discovery': True, 'mappedAPI': SHEETS},
SHEETSTD: {'name': 'Sheets API - write todrive data', 'version': 'v4', 'v2discovery': True, 'mappedAPI': SHEETS}, SHEETSTD: {'name': 'Sheets API - write todrive data', 'version': 'v4', 'v2discovery': True, 'mappedAPI': SHEETS},
SITEVERIFICATION: {'name': 'Site Verification API', 'version': 'v1', 'v2discovery': True}, SITEVERIFICATION: {'name': 'Site Verification API', 'version': 'v1', 'v2discovery': True},
STORAGE: {'name': 'Cloud Storage API', 'version': 'v1', 'v2discovery': True}, STORAGE: {'name': 'Cloud Storage API', 'version': 'v1', 'v2discovery': True},
@@ -534,6 +533,17 @@ _CLIENT_SCOPES = [
'scope': 'https://www.googleapis.com/auth/ediscovery'}, 'scope': 'https://www.googleapis.com/auth/ediscovery'},
] ]
_COMMANDDATA_CLIENT_SCOPES = [
{'name': 'Drive API - commanddata_clientaccess',
'api': DRIVE3,
'subscopes': [],
'scope': DRIVE_READONLY_SCOPE},
{'name': 'Sheets API - commanddata_clientaccess',
'api': SHEETS,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/spreadsheets.readonly'},
]
_TODRIVE_CLIENT_SCOPES = [ _TODRIVE_CLIENT_SCOPES = [
{'name': 'Drive API - todrive_clientaccess', {'name': 'Drive API - todrive_clientaccess',
'api': DRIVE3, 'api': DRIVE3,
@@ -542,7 +552,7 @@ _TODRIVE_CLIENT_SCOPES = [
{'name': 'Drive File API - todrive_clientaccess', {'name': 'Drive File API - todrive_clientaccess',
'api': DRIVE3, 'api': DRIVE3,
'subscopes': [], 'subscopes': [],
'scope': 'https://www.googleapis.com/auth/drive.file'}, 'scope': DRIVE_FILE_SCOPE},
{'name': 'Gmail API - todrive_clientaccess', {'name': 'Gmail API - todrive_clientaccess',
'api': GMAIL, 'api': GMAIL,
'subscopes': [], 'subscopes': [],
@@ -647,7 +657,8 @@ _SVCACCT_SCOPES = [
{'name': 'Drive Activity API v2 - must pair with Drive API', {'name': 'Drive Activity API v2 - must pair with Drive API',
'api': DRIVEACTIVITY, 'api': DRIVEACTIVITY,
'subscopes': [], 'subscopes': [],
'scope': 'https://www.googleapis.com/auth/drive.activity'}, 'scope': [DRIVE_READONLY_SCOPE,
'https://www.googleapis.com/auth/drive.activity']},
{'name': 'Drive Labels API - Admin', {'name': 'Drive Labels API - Admin',
'api': DRIVELABELS_ADMIN, 'api': DRIVELABELS_ADMIN,
'subscopes': READONLY, 'subscopes': READONLY,
@@ -660,10 +671,12 @@ _SVCACCT_SCOPES = [
'api': DOCS, 'api': DOCS,
'subscopes': READONLY, 'subscopes': READONLY,
'scope': 'https://www.googleapis.com/auth/documents'}, 'scope': 'https://www.googleapis.com/auth/documents'},
{'name': 'Forms API', {'name': 'Forms API - must pair with Drive API',
'api': FORMS, 'api': FORMS,
'subscopes': [], 'subscopes': [],
'scope': DRIVE_SCOPE}, 'scope': [DRIVE_READONLY_SCOPE,
'https://www.googleapis.com/auth/forms.body',
'https://www.googleapis.com/auth/forms.responses.readonly']},
{'name': 'Gmail API - Full Access (Labels, Messages)', {'name': 'Gmail API - Full Access (Labels, Messages)',
'api': GMAIL, 'api': GMAIL,
'subscopes': [], 'subscopes': [],
@@ -754,12 +767,7 @@ _SVCACCT_SCOPES = [
] ]
_SVCACCT_SPECIAL_SCOPES = [ _SVCACCT_SPECIAL_SCOPES = [
{'name': 'Drive API - read command data', {'name': 'Drive API - write todrive data - has access to all Drive',
'api': DRIVECD,
'subscopes': [],
'offByDefault': True,
'scope': DRIVE_SCOPE+'.readonly'},
{'name': 'Drive API - write todrive data',
'api': DRIVETD, 'api': DRIVETD,
'subscopes': [], 'subscopes': [],
'offByDefault': True, 'offByDefault': True,
@@ -774,12 +782,7 @@ _SVCACCT_SPECIAL_SCOPES = [
'subscopes': [], 'subscopes': [],
'offByDefault': True, 'offByDefault': True,
'scope': GMAIL_SEND_SCOPE}, 'scope': GMAIL_SEND_SCOPE},
{'name': 'Sheets API - read command data', {'name': 'Sheets API - write todrive data - has access to all Sheets',
'api': SHEETSCD,
'offByDefault': True,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/spreadsheets.readonly'},
{'name': 'Sheets API - write todrive data',
'api': SHEETSTD, 'api': SHEETSTD,
'offByDefault': True, 'offByDefault': True,
'subscopes': [], 'subscopes': [],
@@ -805,14 +808,18 @@ def getVersion(api):
def getClientScopesSet(api): def getClientScopesSet(api):
return {scope['scope'] for scope in _CLIENT_SCOPES if scope['api'] == api} return {scope['scope'] for scope in _CLIENT_SCOPES if scope['api'] == api}
def getClientScopesList(todriveClientAccess): def getClientScopesList(commanddataClientAccess, todriveClientAccess):
caScopes = _CLIENT_SCOPES[:] caScopes = _CLIENT_SCOPES[:]
if commanddataClientAccess:
caScopes.extend(_COMMANDDATA_CLIENT_SCOPES)
if todriveClientAccess: if todriveClientAccess:
caScopes.extend(_TODRIVE_CLIENT_SCOPES) caScopes.extend(_TODRIVE_CLIENT_SCOPES)
return sorted(caScopes, key=lambda k: k['name']) return sorted(caScopes, key=lambda k: k['name'])
def getClientScopesURLs(todriveClientAccess): def getClientScopesURLs(commanddataClientAccess, todriveClientAccess):
caScopes = _CLIENT_SCOPES[:] caScopes = _CLIENT_SCOPES[:]
if commanddataClientAccess:
caScopes.extend(_COMMANDDATA_CLIENT_SCOPES)
if todriveClientAccess: if todriveClientAccess:
caScopes.extend(_TODRIVE_CLIENT_SCOPES) caScopes.extend(_TODRIVE_CLIENT_SCOPES)
return sorted({scope['scope'] for scope in _CLIENT_SCOPES}) return sorted({scope['scope'] for scope in _CLIENT_SCOPES})

View File

@@ -85,6 +85,8 @@ CMDLOG_MAX__BACKUPS = 'cmdlog_max__backups'
CMDLOG_MAX_BACKUPS = 'cmdlog_max_backups' CMDLOG_MAX_BACKUPS = 'cmdlog_max_backups'
# Command logging max kilo bytes per log file # Command logging max kilo bytes per log file
CMDLOG_MAX_KILO_BYTES = 'cmdlog_max_kilo_bytes' CMDLOG_MAX_KILO_BYTES = 'cmdlog_max_kilo_bytes'
# Use client access for command data from Google Docs/Sheets
COMMANDDATA_CLIENTACCESS = 'commanddata_clientaccess'
# GAM config directory containing client_secrets.json, oauth2.txt, oauth2service.json, extra_args.txt # GAM config directory containing client_secrets.json, oauth2.txt, oauth2service.json, extra_args.txt
CONFIG_DIR = 'config_dir' CONFIG_DIR = 'config_dir'
# When retrieving lists of Google Contacts from API, how many should be retrieved in each chunk # When retrieving lists of Google Contacts from API, how many should be retrieved in each chunk
@@ -147,6 +149,8 @@ CSV_OUTPUT_USERS_AUDIT = 'csv_output_users_audit'
CUSTOMER_ID = 'customer_id' CUSTOMER_ID = 'customer_id'
# If debug_level > 0: extra_args['prettyPrint'] = True, httplib2.debuglevel = gam_debug_level, appsObj.debug = True # If debug_level > 0: extra_args['prettyPrint'] = True, httplib2.debuglevel = gam_debug_level, appsObj.debug = True
DEBUG_LEVEL = 'debug_level' DEBUG_LEVEL = 'debug_level'
# redact sensitive credentials from debug output
DEBUG_REDACTION = 'debug_redaction'
# Developer Preview API Key # Developer Preview API Key
DEVELOPER_PREVIEW_API_KEY = 'developer_preview_api_key' DEVELOPER_PREVIEW_API_KEY = 'developer_preview_api_key'
# When retrieving lists of ChromeOS devices from API, how many should be retrieved in each chunk # When retrieving lists of ChromeOS devices from API, how many should be retrieved in each chunk
@@ -344,6 +348,7 @@ Defaults = {
CMDLOG: '', CMDLOG: '',
CMDLOG_MAX_BACKUPS: 5, CMDLOG_MAX_BACKUPS: 5,
CMDLOG_MAX_KILO_BYTES: 1000, CMDLOG_MAX_KILO_BYTES: 1000,
COMMANDDATA_CLIENTACCESS: FALSE,
CONFIG_DIR: '', CONFIG_DIR: '',
CONTACT_MAX_RESULTS: '100', CONTACT_MAX_RESULTS: '100',
CSV_INPUT_COLUMN_DELIMITER: ',', CSV_INPUT_COLUMN_DELIMITER: ',',
@@ -375,6 +380,7 @@ Defaults = {
CSV_OUTPUT_USERS_AUDIT: FALSE, CSV_OUTPUT_USERS_AUDIT: FALSE,
CUSTOMER_ID: MY_CUSTOMER, CUSTOMER_ID: MY_CUSTOMER,
DEBUG_LEVEL: '0', DEBUG_LEVEL: '0',
DEBUG_REDACTION: TRUE,
DEVELOPER_PREVIEW_API_KEY: '', DEVELOPER_PREVIEW_API_KEY: '',
DEVICE_MAX_RESULTS: '200', DEVICE_MAX_RESULTS: '200',
DOMAIN: '', DOMAIN: '',
@@ -512,6 +518,7 @@ VAR_INFO = {
CMDLOG: {VAR_TYPE: TYPE_FILE, VAR_ACCESS: os.W_OK}, CMDLOG: {VAR_TYPE: TYPE_FILE, VAR_ACCESS: os.W_OK},
CMDLOG_MAX_BACKUPS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 10)}, CMDLOG_MAX_BACKUPS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 10)},
CMDLOG_MAX_KILO_BYTES: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (100, 10000)}, CMDLOG_MAX_KILO_BYTES: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (100, 10000)},
COMMANDDATA_CLIENTACCESS: {VAR_TYPE: TYPE_BOOLEAN},
CONFIG_DIR: {VAR_TYPE: TYPE_DIRECTORY, VAR_ENVVAR: 'GAMUSERCONFIGDIR'}, CONFIG_DIR: {VAR_TYPE: TYPE_DIRECTORY, VAR_ENVVAR: 'GAMUSERCONFIGDIR'},
CONTACT_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 10000)}, CONTACT_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 10000)},
CSV_INPUT_COLUMN_DELIMITER: {VAR_TYPE: TYPE_CHARACTER}, CSV_INPUT_COLUMN_DELIMITER: {VAR_TYPE: TYPE_CHARACTER},
@@ -543,6 +550,7 @@ VAR_INFO = {
CSV_OUTPUT_USERS_AUDIT: {VAR_TYPE: TYPE_BOOLEAN}, CSV_OUTPUT_USERS_AUDIT: {VAR_TYPE: TYPE_BOOLEAN},
CUSTOMER_ID: {VAR_TYPE: TYPE_STRING, VAR_ENVVAR: 'CUSTOMER_ID', VAR_LIMITS: (0, None)}, CUSTOMER_ID: {VAR_TYPE: TYPE_STRING, VAR_ENVVAR: 'CUSTOMER_ID', VAR_LIMITS: (0, None)},
DEBUG_LEVEL: {VAR_TYPE: TYPE_INTEGER, VAR_SIGFILE: 'debug.gam', VAR_LIMITS: (0, None), VAR_SFFT: ('0', '4')}, DEBUG_LEVEL: {VAR_TYPE: TYPE_INTEGER, VAR_SIGFILE: 'debug.gam', VAR_LIMITS: (0, None), VAR_SFFT: ('0', '4')},
DEBUG_REDACTION: {VAR_TYPE: TYPE_BOOLEAN},
DEVELOPER_PREVIEW_API_KEY: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, DEVELOPER_PREVIEW_API_KEY: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)},
DEVICE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 200)}, DEVICE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 200)},
DOMAIN: {VAR_TYPE: TYPE_STRING, VAR_ENVVAR: 'GA_DOMAIN', VAR_LIMITS: (0, None)}, DOMAIN: {VAR_TYPE: TYPE_STRING, VAR_ENVVAR: 'GA_DOMAIN', VAR_LIMITS: (0, None)},

View File

@@ -107,6 +107,8 @@ CURRENT_SVCACCT_USER = 'csa'
DATETIME_NOW = 'dtno' DATETIME_NOW = 'dtno'
# If debug_level > 0: extra_args['prettyPrint'] = True, httplib2.debuglevel = gam_debug_level, appsObj.debug = True # If debug_level > 0: extra_args['prettyPrint'] = True, httplib2.debuglevel = gam_debug_level, appsObj.debug = True
DEBUG_LEVEL = 'dbgl' DEBUG_LEVEL = 'dbgl'
# Whether debug output should redact sensitive credentials
DEBUG_REDACTION = 'dbrd'
# Decoded ID token # Decoded ID token
DECODED_ID_TOKEN = 'didt' DECODED_ID_TOKEN = 'didt'
# Index of start of <UserTypeEntity> in command line # Index of start of <UserTypeEntity> in command line
@@ -263,6 +265,7 @@ Globals = {
CURRENT_SVCACCT_USER: None, CURRENT_SVCACCT_USER: None,
DATETIME_NOW: None, DATETIME_NOW: None,
DEBUG_LEVEL: 0, DEBUG_LEVEL: 0,
DEBUG_REDACTION: True,
DECODED_ID_TOKEN: None, DECODED_ID_TOKEN: None,
ENTITY_CL_DELAY_START: 1, ENTITY_CL_DELAY_START: 1,
ENTITY_CL_START: 1, ENTITY_CL_START: 1,

View File

@@ -224,6 +224,8 @@ COUNT_N_EXCEEDS_MAX_TO_PROCESS_M = 'Count {0} exceeds maximum to {1} {2}'
CORRUPT_FILE = 'Corrupt file' CORRUPT_FILE = 'Corrupt file'
COULD_NOT_FIND_ANY_YUBIKEY = 'Could not find any YubiKey\n' COULD_NOT_FIND_ANY_YUBIKEY = 'Could not find any YubiKey\n'
COULD_NOT_FIND_YUBIKEY_WITH_SERIAL = 'Could not find YubiKey with serial number {0}\n' COULD_NOT_FIND_YUBIKEY_WITH_SERIAL = 'Could not find YubiKey with serial number {0}\n'
CREATE_DELEGATE_NOTIFY_MESSAGE = '#user# has granted you #delegate# access to read, delete and send mail on their behalf.'
CREATE_DELEGATE_NOTIFY_SUBJECT = '#user# mail delegation to #delegate#'
CREATE_USER_NOTIFY_MESSAGE = 'Hello #givenname# #familyname#,\n\nYou have a new account at #domain#\nAccount details:\nUsername: #user#\nPassword: #password#\nStart using your new account by signing in at\nhttps://www.google.com/accounts/AccountChooser?Email=#user#&continue=https://workspace.google.com/dashboard\n' CREATE_USER_NOTIFY_MESSAGE = 'Hello #givenname# #familyname#,\n\nYou have a new account at #domain#\nAccount details:\nUsername: #user#\nPassword: #password#\nStart using your new account by signing in at\nhttps://www.google.com/accounts/AccountChooser?Email=#user#&continue=https://workspace.google.com/dashboard\n'
CREATE_USER_NOTIFY_SUBJECT = 'Welcome to #domain#' CREATE_USER_NOTIFY_SUBJECT = 'Welcome to #domain#'
CSV_DATA_ALREADY_SAVED = 'CSV data already saved' CSV_DATA_ALREADY_SAVED = 'CSV data already saved'
@@ -516,7 +518,7 @@ To set up Google Chat for your current project, please go to:
and follow the instructions at: and follow the instructions at:
https://github.com/GAM-team/GAM/wiki/Chat-Bot#set-up-a-chat-bot https://github.com/GAM-team/GAM/wiki/Chat-Bot-Setup-Use#set-up-a-chat-bot
You'll use projects/{1}/topics/no-topic in Connection settings Cloud Pub/Sub Topic Name You'll use projects/{1}/topics/no-topic in Connection settings Cloud Pub/Sub Topic Name
""" """

View File

@@ -43,7 +43,7 @@ Even if you're not going to use GAM as a Chat Bot, you have to configure a Chat
* Uncheck "Build this Chat app as a Workspace add-on." * Uncheck "Build this Chat app as a Workspace add-on."
* Enter an App name and Description of your choosing. * Enter an App name and Description of your choosing.
* For the Avatar URL you can use `https://dummyimage.com/384x256/4d4d4d/0011ff.png&text=+GAM` or a public URL to an image of your own choosing. * For the Avatar URL you can use `https://dummyimage.com/384x256/4d4d4d/0011ff.png&text=+GAM` or a public URL to an image of your own choosing.
* In Functionality, uncheck both "Receive 1:1 messages" and "Join spaces and group conversations" * Inƒ Functionality, uncheck both "Receive 1:1 messages" and "Join spaces and group conversations" if present
* In Connection settings, choose "Cloud Pub/Sub" and enter `projects/<ProjectID>/topics/no-topic` for the Topic Name. Replace `<ProjectID>` with your GAM project ID. GAM doesn't yet listen to pub/sub so this option is not used. * In Connection settings, choose "Cloud Pub/Sub" and enter `projects/<ProjectID>/topics/no-topic` for the Topic Name. Replace `<ProjectID>` with your GAM project ID. GAM doesn't yet listen to pub/sub so this option is not used.
* In Visibility, uncheck "Make this Chat app available to specific people and groups in Domain Workspace". * In Visibility, uncheck "Make this Chat app available to specific people and groups in Domain Workspace".
* Click Save. * Click Save.
@@ -288,7 +288,7 @@ gam create chatmessage spaces spaces/AAAADi-pvqc gdoc announcements@domain.com n
Updates and rewrites an existing Chat message. Message will show as edited and no notification will be sent to members. Updates and rewrites an existing Chat message. Message will show as edited and no notification will be sent to members.
``` ```
gam update chatmessage name <ChatMessage> gam update chatmessage name <ChatMessage>
<ChatContent> [<ChatContent>] [clearattachments <String>]
``` ```
Specify the source of the message: Specify the source of the message:
* `text <String>` - The message is `<String>` * `text <String>` - The message is `<String>`
@@ -296,12 +296,22 @@ Specify the source of the message:
* `gdoc <UserGoogleDoc>` - The message is read from a Google Doc. * `gdoc <UserGoogleDoc>` - The message is read from a Google Doc.
* `gcsdoc <StorageBucketObjectName>` - The message is read from a Google Cloud Storage file. * `gcsdoc <StorageBucketObjectName>` - The message is read from a Google Cloud Storage file.
The option `clearattachments <String>` can be used to clear all attachments from a Chat message.
If `<ChatContent>` is not specified, the current message text is retained and `<String>` is appended;
`<String>` must be specified but can be empty in which case the current message test is preserved as-is.
### Example ### Example
This example updates an existing chat message with new text. This example updates an existing chat message with new text.
``` ```
gam update chatmessage name spaces/AAAADi-pvqc/messages/PKJrx90ooIU.PKJrx90ooIU text "HELLO CHAT?" gam update chatmessage name spaces/AAAADi-pvqc/messages/PKJrx90ooIU.PKJrx90ooIU text "HELLO CHAT?"
``` ```
This example clears attachments from a chat message and appends ` - Attachments cleared`
to the current message text.
```
gam update chatmessage name spaces/AAAADi-pvqc/messages/PKJrx90ooIU.PKJrx90ooIU clearattachments " - Attachments cleared"
```
---- ----
## Delete a Chat Message ## Delete a Chat Message

View File

@@ -245,7 +245,7 @@ to set `<GroupAttribute>`.
gam create cigroup <EmailAddress> gam create cigroup <EmailAddress>
[copyfrom <GroupItem>] <GroupAttribute>* [copyfrom <GroupItem>] <GroupAttribute>*
[makeowner] [alias|aliases <CIGroupAliasList>] [makeowner] [alias|aliases <CIGroupAliasList>]
[security|makesecuritygroup] [security|makesecuritygroup] [locked]
[dynamic <QueryDynamicGroup>] [dynamic <QueryDynamicGroup>]
gam update cigroup <GroupEntity> [copyfrom <GroupItem>] <GroupAttribute> gam update cigroup <GroupEntity> [copyfrom <GroupItem>] <GroupAttribute>
[security|makesecuritygroup| [security|makesecuritygroup|

View File

@@ -53,286 +53,7 @@ You must enable access to policies in the GCP cloud console.
These are the supported policies GAM can show today. These are the supported policies GAM can show today.
See: https://cloud.google.com/identity/docs/concepts/supported-policy-api-settings See: https://cloud.google.com/identity/docs/concepts/supported-policy-api-settings
```
user_takeout_status (is takeout enabled for service)
blogger.user_takeout
books.user_takeout
location_history.user_takeout
maps.user_takeout
pay.user_takeout
photos.user_takeout
play.user_takeout
play_console.user_takeout
youtube.user_takeout
service_status (is service enabled)
ad_manager
ads
adsense
alerts
analytics
applied_digital_skills
appsheet
arts_and_culture
beyondcorp_enterprise
blogger
bookmarks
books
calendar
campaign_manager
chat
chrome_canvas
chrome_remote_desktop
chrome_sync
chrome_web_store
classroom
cloud
cloud_search
colab
cs_first
data_studio
developers
domains
drive_and_docs
earth
enterprise_service_restrictions
experimental_apps
feedburner
fi
gmail
groups
groups_for_business
jamboard
keep
location_history
managed_play
maps
material_gallery
meet
merchant_center
messages
migrate
my_business
my_maps
news
partner_dash
pay
pay_for_business
photos
pinpoint
play
play_books_partner_center
play_console
public_data
question_hub
scholar_profiles
search_ads_360
search_and_assistant
search_console
sites
socratic
takeout
tasks
third_party_app_backups
translate
trips
vault
voice
work_insights
youtube
calendar.appointment_schedules
enablePayments
chat.chat_apps_access
enableApps
enableWebhooks
chat.chat_file_sharing
externalFileSharing
internalFileSharing
chat.chat_history
enableChatHistory
historyOnByDefault
allowUserModification
chat.external_chat_restriction
allowExternalChat
chat.space_history
historyState
classroom.api_data_access
enableApiAccess
classroom.class_membership
whoCanJoinClasses
whichClassesCanUsersJoin
classroom.guardian_access
allowAccess
whoCanManageGuardianAccess
classroom.originality_reports
enableOriginalityReportsSchoolMatches
classroom.roster_import
rosterImportOption
classroom.student_unenrollment
whoCanUnenrollStudents
classroom.teacher_permissions
whoCanCreateClasses
cloud_sharing_options.cloud_data_sharing
sharingOptions
detector.regular_expression
displayName
regularExpression
createTime
updateTime
detector.word_list
displayName
wordList
createTime
updateTime
description
drive_and_docs.drive_for_desktop
allowDriveForDesktop
restrictToAuthorizedDevices
showDownloadLink
allowRealTimePresence
drive_and_docs.external_sharing
externalSharingMode
allowReceivingExternalFiles
warnForSharingOutsideAllowlistedDomains
allowReceivingFilesOutsideAllowlistedDomains
allowNonGoogleInvitesInAllowlistedDomains
warnForExternalSharing
allowNonGoogleInvites
allowPublishingFiles
accessCheckerSuggestions
allowedPartiesForDistributingContent
drive_and_docs.file_security_update
securityUpdate
allowUsersToManageUpdate
drive_and_docs.shared_drive_creation
allowSharedDriveCreation
orgUnitForNewSharedDrives
customOrgUnit
allowManagersToOverrideSettings
allowExternalUserAccess
allowNonMemberAccess
allowedPartiesForDownloadPrintCopy
allowContentManagersToShareFolders
gmail.auto_forwarding
enableAutoForwarding
gmail.confidential_mode
enableConfidentialMode
gmail.email_attachment_safety
enableEncryptedAttachmentProtection
encryptedAttachmentProtectionConsequence
enableAttachmentWithScriptsProtection
attachmentWithScriptsProtectionConsequence
enableAnomalousAttachmentProtection
anomalousAttachmentProtectionConsequence
allowedAnomalousAttachmentFiletypes
applyFutureRecommendedSettingsAutomatically
encryptedAttachmentProtectionQuarantineId
attachmentWithScriptsProtectionQuarantineId
anomalousAttachmentProtectionQuarantineId
gmail.email_image_proxy_bypass
imageProxyBypassPattern
enableImageProxy
gmail.enhanced_pre_delivery_message_scanning
enableImprovedSuspiciousContentDetection
gmail.enhanced_smime_encryption
enableSmimeEncryption
allowUserToUploadCertificates
gmail.gmail_name_format
allowCustomDisplayNames
defaultDisplayNameFormat
gmail.imap_access
enableImapAccess
gmail.links_and_external_images
enableShortenerScanning
enableExternalImageScanning
enableAggressiveWarningsOnUntrustedLinks
applyFutureSettingsAutomatically
gmail.per_user_outbound_gateway
allowUsersToUseExternalSmtpServers
gmail.pop_access
enablePopAccess
gmail.spoofing_and_authentication
detectDomainNameSpoofing
detectEmployeeNameSpoofing
detectDomainSpoofingFromUnauthenticatedSenders
detectUnauthenticatedEmails
domainNameSpoofingConsequence
employeeNameSpoofingConsequence
domainSpoofingConsequence
unauthenticatedEmailConsequence
detectGroupsSpoofing
groupsSpoofingVisibilityType
groupsSpoofingConsequence
applyFutureSettingsAutomatically
domainNameSpoofingQuarantineId
employeeNameSpoofingQuarantineId
domainSpoofingQuarantineId
unauthenticatedEmailQuarantineId
groupsSpoofingQuarantineId
gmail.user_email_uploads
enableMailAndContactsImport
gmail.workspace_sync_for_outlook
enableGoogleWorkspaceSyncForMicrosoftOutlook
groups_for_business.groups_sharing
ownersCanAllowIncomingMailFromPublic
collaborationCapability
createGroupsAccessLevel
ownersCanAllowExternalMembers
ownersCanHideGroups
newGroupsAreHidden
viewTopicsDefaultAccessLevel
meet.safety_access
meetingsAllowedToJoin
meet.safety_domain
usersAllowedToJoin
meet.safety_external_participants
enableExternalLabel
meet.safety_host_management
enableHostManagement
meet.video_recording
enableRecording
rule.dlp
displayName
description
triggers
condition
action
state
createTime
updateTime
ruleTypeMetadata
rule.system_defined_alerts
displayName
description
action
state
createTime
updateTime
security.advanced_protection_program
enableAdvancedProtectionSelfEnrollment
securityCodeOption
security.less_secure_apps
allowLessSecureApps
security.login_challenges
enableEmployeeIdChallenge
security.password
allowedStrength
minimumLength
maximumLength
enforceRequirementsAtLogin
allowReuse
expirationDuration
security.session_controls
webSessionDuration
security.super_admin_account_recovery
enableAccountRecovery
security.user_account_recovery
enableAccountRecovery
sites.sites_creation_and_modification
allowSitesCreation
allowSitesModification
workspace_marketplace.apps_allowlist
apps
```
## Display Cloud Identity Policies ## Display Cloud Identity Policies
Display selected policies. Display selected policies.
``` ```

View File

@@ -5,6 +5,7 @@
- [Plain Text](#plain-text) - [Plain Text](#plain-text)
- [HTML](#html) - [HTML](#html)
- [Read data from a Google Sheet](#read-data-from-a-google-sheet) - [Read data from a Google Sheet](#read-data-from-a-google-sheet)
- [Limited Service Account Access](#limited-service-account-access)
- [Read data from a Google Cloud Storage File](#read-data-from-a-google-cloud-storage-file) - [Read data from a Google Cloud Storage File](#read-data-from-a-google-cloud-storage-file)
- [Plain Text](#plain-text) - [Plain Text](#plain-text)
- [CSV](#csv) - [CSV](#csv)
@@ -79,6 +80,25 @@ Example:
``` ```
gam csv gsheet you@exmaple.com <DriveFileIDEntity> "Sheet 1" gam create user firstname "~FirstName" lastname "~lastName" email "~email" gam csv gsheet you@exmaple.com <DriveFileIDEntity> "Sheet 1" gam create user firstname "~FirstName" lastname "~lastName" email "~email"
``` ```
## Limited Service Account Access
If you want to disable a user's service account access to Drive and Sheets but still allow reading command data from Google Docs and Sheets,
issue the following commands. The admin specified in `gam oauth create` can read command data from Docs and Sheets to which it has access.
```
gam config commanddata_clientaccess true save
gam oauth create
Enable the following and proceed to authorization.
[*] 42) Drive API - commanddata_clientaccess
[*] 54) Sheets API - commanddata_clientaccess
```
In these options, the `<EmailAddress> is not used, but for clarity you may want to specify the
email address of the admin specified in `gam oauth create`.
```
gdoc <EmailAddress> <DriveFileIDEntity>|<DriveFileNameEntity>|(<SharedDriveEntity> <SharedDriveFileNameEntity>)
gsheet <EmailAddress> <DriveFileIDEntity>|<DriveFileNameEntity>|(<SharedDriveEntity> <SharedDriveFileNameEntity>) <SheetEntity>
```
## Read data from a Google Cloud Storage File ## Read data from a Google Cloud Storage File
``` ```
<StorageBucketName> ::= <String> <StorageBucketName> ::= <String>

View File

@@ -10,7 +10,7 @@
- [Delete duplicate email addresses from contacts](#delete-duplicate-email-addresses-from-contacts) - [Delete duplicate email addresses from contacts](#delete-duplicate-email-addresses-from-contacts)
- [Manage domain contact photos](#manage-domain-contact-photos) - [Manage domain contact photos](#manage-domain-contact-photos)
- [Display domain shared contacts](#display-domain-shared-contacts) - [Display domain shared contacts](#display-domain-shared-contacts)
- [Display global address list](#Global-Address-List) - [Display global address list](Global-Address-List)
## API documentation ## API documentation
* [Domain Shared Contacts API](https://developers.google.com/admin-sdk/domain-shared-contacts) * [Domain Shared Contacts API](https://developers.google.com/admin-sdk/domain-shared-contacts)

View File

@@ -10,6 +10,103 @@ 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.27.04
Added options to `gam <UserTypeEntity> create delegate` that support
sending email notifications when a user adds a delegate.
* See: https://github.com/GAM-team/GAM/wiki/Users-Gmail-Delegates#delegation-notification
### 7.27.03
Updated `gam <UserTypeEntity> create|update|sync chatmember` role specification to `role member|manager|owner`.
This is the mapping between the Chat UI and Chat API; GAM uses the Chat UI role names.
```
UI: Member, API: ROLE_MEMBER
UI: Manager, API: ROLE_ASSISTANT_MANAGER
UI: Owner, API: ROLE_MANAGER
```
Updated `gam <UserTypeEntity> update chatspace` options for permission settings.
```
[managemembersandgroups owners|managers|members]
[modifyspacedetails owners|managers|members]
[togglehistory owners|managers|members]
[useatmentionall owners|managers|members]
[manageapps owners|managers|members]
[managewebhooks owners|managers|members]
[replymessages owners|managers|members]
```
### 7.27.02
Added option `clearattachments <String>` to `gam [<UserTypeMessage>] update chatmessage`
that clears all attachments from a Chat message. If `<ChatContent>` is not specified,
the current message text is retained and `<String>` is appended; `<String>` must be specified
but can be empty in which case the current message test is preserved as-is.
### 7.27.01
Fixed bug in `gam <UserTypeEntity> claim ownership <DriveFileEntity> ... onlyUsers|skipusers <UserTypeEntity>`
where the email addresses in `onlyUsers|skipusers <UserTypeEntity>` were not normalized.
### 7.27.00
Added `debug_redaction` Boolean variable to `gam.cfg`. When True, the default,
sensitive data like access/refresh tokens, client secret and authorization codes
are redacted from debug output. This allows you to post debug output without
compromising your account information. Even with debug redaction,
anything shared publicly should be double-checked for sensitive content.
### 7.25.01
Fixed bug in `gam config timezone <String>` to handle timezone abbreviations correctly;
they were incorrectly shifted to lowercase.
### 7.25.00
Removed a capabilty added in 7.24.00 that allowed reading command data from Google Docs and Sheets
when a user's service account access to Drive and Sheets had been disabled. Jay was concerned
that this change could be exploited to give access to all user's files.
This capability has been replaced by issuing the following commands. The admin specified in `gam oauth create`
can read command data from Docs and Sheets to which it has access.
```
gam config commanddata_clientaccess true save
gam oauth create
Enable the following and proceed to authorization.
[*] 42) Drive API - commanddata_clientaccess
[*] 54) Sheets API - commanddata_clientaccess
```
* See: https://github.com/GAM-team/GAM/wiki/Command-Data-From-Google-Docs-Sheets-Storage#limited-service-account-access
Fixed in bug in `gam report` that caused a trap with either of the `thismonth` or `previousmonths` options were used.
Upgraded to Python 3.14.0.
### 7.24.01
Updated GAM to handle the following error that occurs when GAM tries to authenticate
as a user that has been disabled by Google.
```
ERROR: Authentication Token Error - invalid_account: Forbidden
```
### 7.24.00
If you want to disable a user's service account access to Drive and Sheets but still allow reading command data from Google Docs and Sheets,
issue the following command and make these settings:
```
gam user user@domain.com update serviceaccount
[ ] 20) Drive API (supports readonly)
[*] 21) Drive API - read command data
[ ] 42) Sheets API (supports readonly)
[*] 43) Sheets API - read command data
```
### 7.23.07 ### 7.23.07
Fixed bug in `gam print|show admins` where all admin assignments were not displayed when Fixed bug in `gam print|show admins` where all admin assignments were not displayed when

View File

@@ -252,9 +252,9 @@ 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.23.07 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.27.04 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.7 64-bit final Python 3.14.0 64-bit final
macOS Tahoe 26.0.1 x86_64 macOS Tahoe 26.0.1 x86_64
Path: /Users/admin/bin/gam7 Path: /Users/admin/bin/gam7
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
@@ -990,9 +990,9 @@ 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.23.07 - https://github.com/GAM-team/GAM - pythonsource GAM 7.27.04 - https://github.com/GAM-team/GAM - pythonsource
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.7 64-bit final Python 3.14.0 64-bit final
Windows-10-10.0.17134 AMD64 Windows-10-10.0.17134 AMD64
Path: C:\GAM7 Path: C:\GAM7
Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com

View File

@@ -330,16 +330,16 @@ you want the updated data copied to `Latest` so you don't have to remember what
gam redirect csv - todrive tdfileid <DriveFileID> tdupdatesheet tdsheet Tuesday tdbackupsheet "Backup Tuesday" tdcopysheet "Latest" ... gam redirect csv - todrive tdfileid <DriveFileID> tdupdatesheet tdsheet Tuesday tdbackupsheet "Backup Tuesday" tdcopysheet "Latest" ...
``` ```
## Limited Service Account Access ## Limited Service Account Access
If you want to limit a user's service account access but still allow `todrive', If you want to limit a user's service account access to Drive, Gmail and Sheets but still allow `todrive`,
issue the following command and authorize the additional service account APIs: issue the following command and make these settings:
``` ```
gam user user@domain.com update serviceaccount` gam user user@domain.com update serviceaccount
Authorize these APIs: [ ] 20) Drive API (supports readonly)
[*] 22) Drive API - write todrive data - has access to all Drive
Drive API - todrive [*] 31) Gmail API - Send Messages - including todrive
Gmail API - Send Messages - including todrive [ ] 42) Sheets API (supports readonly)
Sheets API - todrive [*] 44) Sheets API - write todrive data - has access to all Sheets
``` ```
## No Service Account Access ## No Service Account Access

View File

@@ -7,6 +7,7 @@
- [Chat Space Permissions](#chat-space-permissions) - [Chat Space Permissions](#chat-space-permissions)
- [Manage Chat Spaces](#manage-chat-spaces) - [Manage Chat Spaces](#manage-chat-spaces)
- [Display Chat Spaces](#display-chat-spaces) - [Display Chat Spaces](#display-chat-spaces)
- [UI API member role mapping](#ui-api-mwmber-role-mapping)
- [Manage Chat Members](#manage-chat-members) - [Manage Chat Members](#manage-chat-members)
- [Display Chat Members](#display-chat-members) - [Display Chat Members](#display-chat-members)
- [Manage Chat Messages](#manage-chat-messages) - [Manage Chat Messages](#manage-chat-messages)
@@ -211,7 +212,7 @@ For `type space`, the following apply:
* `description <String>` - Optional * `description <String>` - Optional
* `guidelines <String>` - Optional * `guidelines <String>` - Optional
* `history <Boolean>` - Optional * `history <Boolean>` - Optional
* `announcement|collaboration` - Initial permission settings; default is `collaboration`; this is in Developer Preview * `announcement|collaboration` - Initial permission settings; default is `collaboration`
For `type groupchat`, the following apply: For `type groupchat`, the following apply:
* `members <UserTypeEntity>` - Required, must specify between 2 and 20 users * `members <UserTypeEntity>` - Required, must specify between 2 and 20 users
@@ -244,30 +245,19 @@ gam <UserTypeEntity> update chatspace <ChatSpace>
[type space] [type space]
[description <String>] [guidelines|rules <String>] [description <String>] [guidelines|rules <String>]
[history <Boolean>]) [history <Boolean>])
[managemembersandgroups managers|members] [managemembersandgroups owners|managers|members]
[modifyspacedetails managers|members] [modifyspacedetails owners|managers|members]
[togglehistory managers|members] [togglehistory owners|managers|members]
[useatmentionall managers|members] [useatmentionall owners|managers|members]
[manageapps managers|members] [manageapps owners|managers|members]
[managewebhooks managers|members] [managewebhooks owners|managers|members]
[replymessages managers|members] [replymessages owners|managers|members]
[formatjson] [formatjson]
``` ```
A groupchat space can be upgraded to a space by specifying `type space` and `displayname <String>`. A groupchat space can be upgraded to a space by specifying `type space` and `displayname <String>`.
The `restricted|audience` options can not be combined with options `displayname,type,description,guidelines,history`. The `restricted|audience` options can not be combined with options `displayname,type,description,guidelines,history`.
You can manage permissions for chat spaces with the following options that are available with Developer Preview.
[managemembersandgroups managers|members]
[modifyspacedetails managers|members]
[togglehistory managers|members]
[useatmentionall managers|members]
[manageapps managers|members]
[managewebhooks managers|members]
[postmessages managers|members]
[replymessages managers|members]
By default, Gam displays the information about the created chatspace as an indented list of keys and values. By default, Gam displays the information about the created chatspace as an indented list of keys and values.
* `formatjson` - Display the fields in JSON format. * `formatjson` - Display the fields in JSON format.
@@ -327,7 +317,7 @@ gam <UserTypeEntity> show chatspaces
By default, chat spaces of all types are displayed. By default, chat spaces of all types are displayed.
* `types <ChatSpaceTypeList>` - Display specific types of spaces. * `types <ChatSpaceTypeList>` - Display specific types of spaces.
When listing Chat Spaces, the Chat API does not return the `accessSettings` field; if you need to see this fieldf, When listing Chat Spaces, the Chat API does not return the `accessSettings` field; if you need to see this field,
add `showaccesssettings` to the command. This requires an additional Chat API call per chat space of type `SPACE` add `showaccesssettings` to the command. This requires an additional Chat API call per chat space of type `SPACE`
to get the `accessSettings` field. to get the `accessSettings` field.
@@ -343,7 +333,7 @@ gam <UserTypeEntity> print chatspaces [todrive <ToDriveAttribute>*]
By default, chat spaces of all types are displayed. By default, chat spaces of all types are displayed.
* `types <ChatSpaceTypeList>` - Display specific types of spaces. * `types <ChatSpaceTypeList>` - Display specific types of spaces.
When listing Chat Spaces, the Chat API does not return the `accessSettings` field; if you need to see this fieldf, When listing Chat Spaces, the Chat API does not return the `accessSettings` field; if you need to see this field,
add `showaccesssettings` to the command. This requires an additional Chat API call per chat space of type `SPACE` add `showaccesssettings` to the command. This requires an additional Chat API call per chat space of type `SPACE`
to get the `accessSettings` field. to get the `accessSettings` field.
@@ -401,7 +391,7 @@ By default, all chat spaces of type SPACE are displayed.
* `query <String> [querytime<String> <Time>]` - Display selected chat spaces * `query <String> [querytime<String> <Time>]` - Display selected chat spaces
* See: https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces/search * See: https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces/search
When listing Chat Spaces, the Chat API does not return the `accessSettings` field; if you need to see this fieldf, When listing Chat Spaces, the Chat API does not return the `accessSettings` field; if you need to see this field,
add `showaccesssettings` to the command. This requires an additional Chat API call per chat space of type `SPACE` add `showaccesssettings` to the command. This requires an additional Chat API call per chat space of type `SPACE`
to get the `accessSettings` field. to get the `accessSettings` field.
@@ -419,7 +409,7 @@ By default, all chat spaces of type SPACE are displayed.
* `query <String> [querytime<String> <Time>]` - Display selected chat spaces * `query <String> [querytime<String> <Time>]` - Display selected chat spaces
* See: https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces/search * See: https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces/search
When listing Chat Spaces, the Chat API does not return the `accessSettings` field; if you need to see this fieldf, When listing Chat Spaces, the Chat API does not return the `accessSettings` field; if you need to see this field,
add `showaccesssettings` to the command. This requires an additional Chat API call per chat space of type `SPACE` add `showaccesssettings` to the command. This requires an additional Chat API call per chat space of type `SPACE`
to get the `accessSettings` field. to get the `accessSettings` field.
@@ -432,11 +422,20 @@ When using the `formatjson` option, double quotes are used extensively in the da
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output. The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used. `quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
## UI API member role mapping
GAM uses the Chat UI role names.
| UI setting | API setting |
|------------|------------|
| Member | ROLE_MEMBER |
| Manager | ROLE_ASSISTANT_MANAGER |
| Owner | ROLE_MANAGER |
## Manage Chat Members ## Manage Chat Members
### Add members to a user's chat space ### Add members to a user's chat space
``` ```
gam <UserTypeEntity> create chatmember <ChatSpace> gam <UserTypeEntity> create chatmember <ChatSpace>
[type human|bot] [role member|manager] [type human|bot] [role member|manager|owner]
(user <UserItem>)* (members <UserTypeEntity>)* (user <UserItem>)* (members <UserTypeEntity>)*
(group <GroupItem>)* (groups <GroupEntity>)* (group <GroupItem>)* (groups <GroupEntity>)*
[formatjson|returnidonly] [formatjson|returnidonly]
@@ -462,7 +461,7 @@ gam <UserTypeEntity> remove chatmember members <ChatMemberList>
Creating memberships for users outside the administrator's Google Workspace organization isn't supported using asadmin. Creating memberships for users outside the administrator's Google Workspace organization isn't supported using asadmin.
``` ```
gam <UserItem> create chatmember asadmin <ChatSpace> gam <UserItem> create chatmember asadmin <ChatSpace>
[type human|bot] [role member|manager] [type human|bot] [role member|manager|owner]
(user <UserItem>)* (members <UserTypeEntity>)* (user <UserItem>)* (members <UserTypeEntity>)*
(group <GroupItem>)* (groups <GroupEntity>)* (group <GroupItem>)* (groups <GroupEntity>)*
[formatjson|returnidonly] [formatjson|returnidonly]
@@ -488,13 +487,13 @@ gam <UserItem> remove chatmember asadmin members <ChatMemberList>
Update members by specifying a chat space, user/group email addresses and role. Update members by specifying a chat space, user/group email addresses and role.
``` ```
gam <UserTypeEntity> update chatmember <ChatSpace> gam <UserTypeEntity> update chatmember <ChatSpace>
role member|manager role member|manager|owner
((user <UserItem>)|(members <UserTypeEntity>))+ ((user <UserItem>)|(members <UserTypeEntity>))+
``` ```
Update members by specifying chatmember names and role. Update members by specifying chatmember names and role.
``` ```
gam <UserTypeEntity> modify chatmember gam <UserTypeEntity> modify chatmember
role member|manager role member|manager|owner
members <ChatMemberList> members <ChatMemberList>
``` ```
@@ -502,13 +501,13 @@ gam <UserTypeEntity> modify chatmember
Update members by specifying a chat space, user/group email addresses and role. Update members by specifying a chat space, user/group email addresses and role.
``` ```
gam <UserItem> update chatmember asadmin <ChatSpace> gam <UserItem> update chatmember asadmin <ChatSpace>
role member|manager role member|manager|owner
((user <UserItem>)|(members <UserTypeEntity>))+ ((user <UserItem>)|(members <UserTypeEntity>))+
``` ```
Update members by specifying chatmember names and role. Update members by specifying chatmember names and role.
``` ```
gam <UserItem> modify chatmember asadmin gam <UserItem> modify chatmember asadmin
role member|manager role member|manager|owner
members <ChatMemberList> members <ChatMemberList>
``` ```
@@ -751,7 +750,7 @@ gam user user@domain.com create chatmessage spaces spaces/AAAADi-pvqc gdoc annou
Updates and rewrites an existing Chat message. Message will show as edited and no notification will be sent to members. Updates and rewrites an existing Chat message. Message will show as edited and no notification will be sent to members.
``` ```
gam <UserTypeEntity> update chatmessage name <ChatMessage> gam <UserTypeEntity> update chatmessage name <ChatMessage>
<ChatContent> [<ChatContent>] [clearattachments <String>]
``` ```
Specify the text of the message: `<ChatContent>` Specify the text of the message: `<ChatContent>`
* `text <String>` - The message is `<String>` * `text <String>` - The message is `<String>`
@@ -759,12 +758,22 @@ Specify the text of the message: `<ChatContent>`
* `gdoc <UserGoogleDoc>` - The message is read from a Google Doc. * `gdoc <UserGoogleDoc>` - The message is read from a Google Doc.
* `gcsdoc <StorageBucketObjectName>` - The message is read from a Google Cloud Storage file. * `gcsdoc <StorageBucketObjectName>` - The message is read from a Google Cloud Storage file.
The option `clearattachments <String>` can be used to clear all attachments from a Chat message.
If `<ChatContent>` is not specified, the current message text is retained and `<String>` is appended;
`<String>` must be specified but can be empty in which case the current message test is preserved as-is.
### Example ### Example
This example updates an existing chat message with new text. This example updates an existing chat message with new text.
``` ```
gam user user@domain.com update chatmessage name spaces/AAAADi-pvqc/messages/PKJrx90ooIU.PKJrx90ooIU text "HELLO CHAT?" gam user user@domain.com update chatmessage name spaces/AAAADi-pvqc/messages/PKJrx90ooIU.PKJrx90ooIU text "HELLO CHAT?"
``` ```
This example clears attachments from a chat message and appends ` - Attachments cleared`
to the current message text.
```
gam user user@domain.com update chatmessage name spaces/AAAADi-pvqc/messages/PKJrx90ooIU.PKJrx90ooIU clearattachments " - Attachments cleared"
```
### Delete a Chat Message ### Delete a Chat Message
Deletes the given Chat message. Members will no longer see the message. Deletes the given Chat message. Members will no longer see the message.

View File

@@ -3,6 +3,7 @@
- [API documentation](#api-documentation) - [API documentation](#api-documentation)
- [Definitions](#definitions) - [Definitions](#definitions)
- [Aliases](#aliases) - [Aliases](#aliases)
- [Delegation Notification](#delegation-notification)
- [Create Gmail delegates](#create-gmail-delegates) - [Create Gmail delegates](#create-gmail-delegates)
- [Delete Gmail delegates](#delete-gmail-delegates) - [Delete Gmail delegates](#delete-gmail-delegates)
- [Update Gmail delegates](#update-gmail-delegates) - [Update Gmail delegates](#update-gmail-delegates)
@@ -31,6 +32,23 @@ mail delegation is enabled. In the admin console, go to Apps/Google Workspace/Gm
<UserEntity> ::= <UserEntity> ::=
<UserList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector> <UserList> | <FileSelector> | <CSVkmdSelector> | <CSVDataSelector>
See: https://github.com/GAM-team/GAM/wiki/Collections-of-Users See: https://github.com/GAM-team/GAM/wiki/Collections-of-Users
<StorageBucketName> ::= <String>
<StorageObjectName> ::= <String>
<StorageBucketObjectName> ::=
https://storage.cloud.google.com/<StorageBucketName>/<StorageObjectName>|
https://storage.googleapis.com/<StorageBucketName>/<StorageObjectName>|
gs://<StorageBucketName>/<StorageObjectName>|
<StorageBucketName>/<StorageObjectName>
<UserGoogleDoc> ::=
<EmailAddress> <DriveFileIDEntity>|<DriveFileNameEntity>|(<SharedDriveEntity> <SharedDriveFileNameEntity>)
<NotifyMessageContent> ::=
(message|textmessage|htmlmessage <String>)|
(file|textfile|htmlfile <FileName> [charset <Charset>])|
(gdoc|ghtml <UserGoogleDoc>)|
(gcsdoc|gcshtml <StorageBucketObjectName>)
``` ```
## Aliases ## Aliases
@@ -39,11 +57,61 @@ The `convertalias` option causes GAM to make an extra API call per user in `<Use
to convert aliases to primary email addresses. If you know that all of the email addresses to convert aliases to primary email addresses. If you know that all of the email addresses
in `<UserEntity>` are primary, you can omit `convertalias` and avoid the extra API calls. in `<UserEntity>` are primary, you can omit `convertalias` and avoid the extra API calls.
## Delegation Notification
When creating a delegate, you can send a message to the delegate.
```
[notify [<Boolean>]
[subject <String>]
[from <EmailAaddress>] [mailbox <EmailAddress>]
[replyto <EmailAddress>]
[<NotifyMessageContent>] [html [<Boolean>]]
]
```
* `notify [<Boolean>]` - Should notification be sent
In the subject and message, these strings will be replaced with the specified values:
* `#user#` - user's email address
* `#delegate#` - delegate's email address
If subject is not specified, the following value will be used:
* `#user# mail delegation to #delegate#`
`<NotifyMessageContent>` is the message, there are four ways to specify it:
* `message|textmessage|htmlmessage <String>` - Use `<String>` as the message
* `file|htmlfile <FileName> [charset <Charset>]` - Read the message from `<FileName>`
* `gdoc|ghtml <UserGoogleDoc>` - Read the message from `<UserGoogleDoc>`
* `gcsdoc|gcshtml <StorageBucketObjectName>` - Read the message from the Google Cloud Storage file `<StorageBucketObjectName>`
If `<NotifyMessageContent>`is not specified, the following value will be used:
* `#user# has granted you #delegate# access to read, delete and send mail on their behalf.`
Unless specified in `<NotifyMessageContent>`, messages are sent as plain text,
use `html` or `html true` to indicate that the message is HTML.
Use `\n` in `message <String>` to indicate a line break; no other special characters are recognized.
By default, the email is sent from the admin user identified in oauth2.txt, `gam oauth info` will show the value.
Use `from <EmailAddress>` to specify an alternate from address.
Use `mailbox <EmailAddress>` if `from <EmailAddress>` specifies a group; GAM has to login as a user to be able to send a message.
Gam gets no indication as to the status of the message delivery; the from user will get a non-delivery receipt if the message could not be sent to the delegate.
## Create Gmail delegates ## Create Gmail delegates
These two commands are equivalent. These two commands are equivalent.
``` ```
gam <UserTypeEntity> add delegate|delegates [convertalias] <UserEntity> gam <UserTypeEntity> add delegate|delegates [convertalias] <UserEntity>
[[notify <EmailAddressList>]
[subject <String>]
[from <EmailAaddress>] [mailbox <EmailAddress>]
[replyto <EmailAaddress>]
[<NotifyMessageContent>]
]
gam <UserTypeEntity> delegate|delegates to [convertalias] <UserEntity> gam <UserTypeEntity> delegate|delegates to [convertalias] <UserEntity>
[[notify <EmailAddressList>]
[subject <String>]
[from <EmailAaddress>] [mailbox <EmailAddress>]
[replyto <EmailAaddress>]
[<NotifyMessageContent>]
]
``` ```
### Example ### Example
@@ -51,6 +119,7 @@ To give Bob access to Fred's mailbox as a delegate:
``` ```
gam user fred@domain.com add delegate bob@domain.com gam user fred@domain.com add delegate bob@domain.com
gam user fred@domain.com delegate to bob@domain.com
``` ```
## Delete Gmail delegates ## Delete Gmail delegates

View File

@@ -401,14 +401,13 @@ password "helloworld" nohash
``` ```
## Password Notification ## Password Notification
When creating a user or updating a user's password, you can send a message with details to an email address;' When creating a user or updating a user's password, you can send a message with details to an email address
this might be the user's secondary email address or their recovery email address. or addresses; these might be the user's secondary email address, their recovery email address or a help desk user.
``` ```
[[notify <EmailAddressList>] [notifyrecoveryemail] [[notify <EmailAddressList>] [notifyrecoveryemail]
[subject <String>] [subject <String>]
[notifypassword <String>] [notifypassword <String>]
[from <EmailAaddress>] [from <EmailAaddress>] [mailbox <EmailAddress>]
[mailbox <EmailAddress>]
[replyto <EmailAddress>] [replyto <EmailAddress>]
[<NotifyMessageContent>] [<NotifyMessageContent>]
(replace <Tag> <UserReplacement>)* (replace <Tag> <UserReplacement>)*
@@ -419,6 +418,15 @@ this might be the user's secondary email address or their recovery email address
* `notify <EmailAddressList>` - Specify recipients * `notify <EmailAddressList>` - Specify recipients
* `notifyrecoveryemail` - Use the user's recovery email address (if defined) as a recipient * `notifyrecoveryemail` - Use the user's recovery email address (if defined) as a recipient
In the subject and message, these strings will be replaced with the specified values:
* `#givenname#` - first/given name
* `#familyname#` - last/family name
* `#email#` - user's email address
* `#user#` - user's email address
* `#username#` - portion of user's email address before @
* `#domain#` - portion of user's email after after @
* `#password#` - password
If subject is not specified, the following value will be used: If subject is not specified, the following value will be used:
* create - `Welcome to #domain#` * create - `Welcome to #domain#`
* update - `Account #user# password has been changed` * update - `Account #user# password has been changed`
@@ -434,14 +442,8 @@ If `<NotifyMessageContent>`is not specified, the following value will be used:
Start using your new account by signing in at\nhttps://www.google.com/accounts/AccountChooser?Email=#user#&continue=https://workspace.google.com/dashboard\n` Start using your new account by signing in at\nhttps://www.google.com/accounts/AccountChooser?Email=#user#&continue=https://workspace.google.com/dashboard\n`
* update - `The account password for #givenname# #familyname#, #user# has been changed to: #password#\n` * update - `The account password for #givenname# #familyname#, #user# has been changed to: #password#\n`
In the subject and message, these strings will be replaced with the specified values: Unless specified in `<NotifyMessageContent>`, messages are sent as plain text,
* `#givenname#` - first/given name use `html` or `html true` to indicate that the message is HTML.
* `#familyname#` - last/family name
* `#email#` - user's email address
* `#user#` - user's email address
* `#username#` - portion of user's email address before @
* `#domain#` - portion of user's email after after @
* `#password#` - password
Use `\n` in `message <String>` to indicate a line break; no other special characters are recognized. Use `\n` in `message <String>` to indicate a line break; no other special characters are recognized.
@@ -464,8 +466,6 @@ Use `from <EmailAddress>` to specify an alternate from address.
Use `mailbox <EmailAddress>` if `from <EmailAddress>` specifies a group; GAM has to login as a user to be able to send a message. Use `mailbox <EmailAddress>` if `from <EmailAddress>` specifies a group; GAM has to login as a user to be able to send a message.
Gam gets no indication as to the status of the message delivery; the from user will get a non-delivery receipt if the message could not be sent to the `notify <EmailAddressList>`. Gam gets no indication as to the status of the message delivery; the from user will get a non-delivery receipt if the message could not be sent to the `notify <EmailAddressList>`.
By default, messages are sent as plain text, use `html` or `html true` to indicate that the message is HTML.
## Define schema fields ## Define schema fields
You can set custom schema field values for users; schema fields can be scalar, a single value, or can be multivalued. You can set custom schema field values for users; schema fields can be scalar, a single value, or can be multivalued.
* https://developers.google.com/admin-sdk/directory/reference/rest/v1/schemas * https://developers.google.com/admin-sdk/directory/reference/rest/v1/schemas
@@ -658,8 +658,7 @@ gam update user <UserItem> [ignorenullpassword] <UserAttribute>*
[[notify <EmailAddressList>] [notifyrecoveryemail] [[notify <EmailAddressList>] [notifyrecoveryemail]
[subject <String>] [subject <String>]
[notifypassword <String>] [notifypassword <String>]
[from <EmailAaddress>] [from <EmailAaddress>] [mailbox <EmailAddress>]
[mailbox <EmailAddress>]
[replyto <EmailAddress>] [replyto <EmailAddress>]
[<NotifyMessageContent>] [<NotifyMessageContent>]
(replace <Tag> <UserReplacement>)* (replace <Tag> <UserReplacement>)*
@@ -680,8 +679,7 @@ gam update users <UserTypeEntity> [ignorenullpassword] <UserAttribute>*
[[notify <EmailAddressList>] [notifyrecoveryemail] [[notify <EmailAddressList>] [notifyrecoveryemail]
[subject <String>] [subject <String>]
[notifypassword <String>] [notifypassword <String>]
[from <EmailAddress>] [from <EmailAddress>] [mailbox <EmailAddress>]
[mailbox <EmailAddress>]
[replyto <EmailAaddress>] [replyto <EmailAaddress>]
[<NotifyMessageContent>] [<NotifyMessageContent>]
(replace <Tag> <UserReplacement>)* (replace <Tag> <UserReplacement>)*
@@ -702,8 +700,7 @@ gam <UserTypeEntity> update users [ignorenullpassword] <UserAttribute>*
[[notify <EmailAddressList>] [notifyrecoveryemail] [[notify <EmailAddressList>] [notifyrecoveryemail]
[subject <String>] [subject <String>]
[notifypassword <String>] [notifypassword <String>]
[from <EmailAaddress>] [from <EmailAaddress>] [mailbox <EmailAddress>]
[mailbox <EmailAddress>]
[replyto <EmailAddress>] [replyto <EmailAddress>]
[<NotifyMessageContent>] [<NotifyMessageContent>]
(replace <Tag> <UserReplacement>)* (replace <Tag> <UserReplacement>)*

View File

@@ -3,9 +3,9 @@
Print the current version of Gam with details Print the current version of Gam with details
``` ```
gam version gam version
GAM 7.23.07 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.27.04 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.7 64-bit final Python 3.14.0 64-bit final
macOS Tahoe 26.0.1 x86_64 macOS Tahoe 26.0.1 x86_64
Path: /Users/Admin/bin/gam7 Path: /Users/Admin/bin/gam7
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
@@ -15,9 +15,9 @@ 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.23.07 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.27.04 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.7 64-bit final Python 3.14.0 64-bit final
macOS Tahoe 26.0.1 x86_64 macOS Tahoe 26.0.1 x86_64
Path: /Users/Admin/bin/gam7 Path: /Users/Admin/bin/gam7
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
@@ -27,9 +27,9 @@ 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.23.07 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.27.04 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.7 64-bit final Python 3.14.0 64-bit final
macOS Tahoe 26.0.1 x86_64 macOS Tahoe 26.0.1 x86_64
Path: /Users/Admin/bin/gam7 Path: /Users/Admin/bin/gam7
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
@@ -68,7 +68,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.22.00 Latest: 7.27.04
echo $? echo $?
1 1
``` ```
@@ -76,7 +76,7 @@ echo $?
Print the current version number without details Print the current version number without details
``` ```
gam version simple gam version simple
7.22.00 7.27.04
``` ```
In Linux/MacOS you can do: In Linux/MacOS you can do:
``` ```
@@ -86,9 +86,9 @@ 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.22.00 - https://github.com/GAM-team/GAM GAM 7.27.04 - https://github.com/GAM-team/GAM
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.7 64-bit final Python 3.14.0 64-bit final
macOS Tahoe 26.0.1 x86_64 macOS Tahoe 26.0.1 x86_64
Path: /Users/Admin/bin/gam7 Path: /Users/Admin/bin/gam7
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com

View File

@@ -140,6 +140,11 @@ cmdlog_max_kilo_bytes
Maximum kilobytes per log file Maximum kilobytes per log file
Default: 1000 Default: 1000
Range: 100 - 10000 Range: 100 - 10000
commanddata_clientaccess
Enable/disable use of client access rather than service account access for the
admin specified in `gam oauth create` when reading command data from Docs and Sheets
to which it has access.
Default: False
config_dir config_dir
GAM config directory containing client_secrets.json, oauth2.txt, oauth2service.json GAM config directory containing client_secrets.json, oauth2.txt, oauth2service.json
and extra_args.txt and extra_args.txt
@@ -298,6 +303,9 @@ debug_level
If debug_level > 0, turn on API debugging output. If debug_level > 0, turn on API debugging output.
Default: 0 Default: 0
Signal file: OldGamPath/debug.gam Signal file: OldGamPath/debug.gam
debug_redaction
Enable/disable redaction of sensitive data from API debugging output
Default: True
device_max_results device_max_results
When retrieving lists of ChromeOS devices from API, When retrieving lists of ChromeOS devices from API,
how many should be retrieved in each API call how many should be retrieved in each API call