Compare commits

...

66 Commits

Author SHA1 Message Date
Ross Scroggs
b818002202 Update gam info user <UserItem> to eliminate 5 second delay when getting license info.
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2025) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-08-27 19:38:24 -07:00
Ross Scroggs
33065438d8 Update gam info user <UserItem> to eliminate 5 second delay when getting license info. 2025-08-27 19:38:09 -07:00
Jay Lee
e4880a3814 [no ci] actions: Use Windows 2025 2025-08-27 12:46:20 -04:00
Jay Lee
a2bd409d51 [no ci] actions: verbose cert verification output 2025-08-27 12:24:28 -04:00
Jay Lee
352f09fad8 actions: add env: prefix powershell wants 2025-08-27 11:04:09 -04:00
Jay Lee
221a18fc51 [no ci] actions: fix job name 2025-08-27 11:02:12 -04:00
Jay Lee
158138f344 [no ci] actions: fix job name 2025-08-27 10:59:17 -04:00
Jay Lee
0d32e451e9 actions: fix path to ssd.mjs 2025-08-27 10:54:46 -04:00
Jay Lee
38780e2ba9 actions: use new local win code signing #1824 2025-08-27 10:53:06 -04:00
Jay Lee
f3e6afbca4 Create ssd.mjs #1824
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
2025-08-27 08:12:11 -04:00
Ross Scroggs
cb1c7ad6fe Update Vault-Takeout.md
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
2025-08-26 17:30:33 -07:00
Ross Scroggs
3ee8bf2841 Updated gam <UserTypeEntity> print|show signature
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
2025-08-25 14:23:11 -07:00
Ross Scroggs
71d82f0f87 Merge branch 'main' of https://github.com/GAM-team/GAM
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-08-23 08:22:55 -07:00
Ross Scroggs
398a91b987 Updated gam <UserTypeEntity> print|show signature
to handle the following error that occurs when an alias is specified.
```
ERROR: 404: notFound - Requested entity was not found.
2025-08-23 08:22:52 -07:00
Jay Lee
0cf17be7ca Update Chrome-Policies.md
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
2025-08-22 15:29:43 -04:00
Ross Scroggs
28d76c5aee Meet API fixes #1822
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-08-21 16:42:09 -07:00
Ross Scroggs
04371eee53 Meet API fixes #1822 2025-08-21 12:40:58 -07:00
Ross Scroggs
70cf32f6ed Additional Meet API changes #1822 2025-08-21 05:33:38 -07:00
Ross Scroggs
d2495f0ed8 Additional Meet API changes #1822
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2025-08-21 05:32:58 -07:00
Ross Scroggs
2d3c1e5aa8 Merge branch 'main' of https://github.com/GAM-team/GAM 2025-08-21 05:29:21 -07:00
GitHub Action
7855447014 [ci skip] Updated cacerts.pem 2025-08-20 23:29:50 +00:00
Ross Scroggs
0028955412 #1822 2025-08-19 20:04:56 -07:00
Ross Scroggs
c3b59a9c10 #1822
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-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-08-19 20:04:36 -07:00
Ross Scroggs
fbe1bb69c3 Eliminated drive_v3_beta and meet_v2_beta from gam.cfg
Updated `Meet API` scopes.
[*] 34)  Meet API - Read Only
[*] 35)  Meet API - Read Write

`Meet API - Read Only` - Allow apps to read metadata about any meeting space the user has access to.
`Meet API - Read Write` - Allow apps to create, modify, and read metadata about meeting spaces *created by your app*.
2025-08-19 16:43:47 -07:00
Ross Scroggs
b2573b465b Eliminated drive_v3_beta and meet_v2_beta from gam.cfg
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-certs (push) Has been cancelled
Updated `Meet API` scopes.
[*] 34)  Meet API - Read Only
[*] 35)  Meet API - Read Write

`Meet API - Read Only` - Allow apps to read metadata about any meeting space the user has access to.
`Meet API - Read Write` - Allow apps to create, modify, and read metadata about meeting spaces *created by your app*.
2025-08-19 16:43:01 -07:00
Jay Lee
6171e3c2ef actions: upgrade actions and always use commit hash for security reasons 2025-08-19 14:35:40 -04:00
Jay Lee
19e13a9052 actions: remove overwrite_files which isn't supported or necessary 2025-08-19 14:18:50 -04:00
Jay Lee
b349d80be5 Update get-cacerts.yml 2025-08-19 14:15:26 -04:00
Ross Scroggs
c5c4553ae0 Updated gam <UserTypeEntity> print drivelastmodification
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
to put `addcsvdata` columns
after `User,id,name` rather than after the last column.
2025-08-18 12:21:58 -07:00
Ross Scroggs
ef77e6f7e9 Updated gam <UserTypeEntity> print drivelastmodification
to put `addcsvdata` columns after  `User,id,name` rather than after the last column.
2025-08-18 12:21:31 -07:00
Jay Lee
66816863e0 actions: upgrade apple codesign action version
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
2025-08-18 10:01:30 -04:00
Ross Scroggs
7d67cd08f6 Updated `gam <UserTypeEntity> delete|modify messages
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
to improve the handling of the following error.
```
quotaExceeded - User-rate limit exceeded
```
2025-08-15 15:05:07 -07:00
Ross Scroggs
0d1b622831 Merge branch 'main' of https://github.com/GAM-team/GAM 2025-08-15 15:03:51 -07:00
Ross Scroggs
a1000f7778 Updated gam <UserTypeEntity> delete|modify messages
to improve the handling
of the following error.
```
quotaExceeded - User-rate limit exceeded
```
2025-08-15 14:55:38 -07:00
Jay Lee
30fea18f93 Add more reasons why user info license errored
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
2025-08-15 14:50:53 +00:00
Ross Scroggs
8bbb9b6e85 Update ChromeOS-Devices.md
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2025-08-14 20:14:39 -07:00
Ross Scroggs
4b5390f6cf Update ChromeOS-Devices.md 2025-08-14 20:12:02 -07:00
Ross Scroggs
941abe608a Updated to Python 3.13.7. 2025-08-14 19:27:51 -07:00
Ross Scroggs
0d23175216 Update GamUpdates.md 2025-08-14 19:22:00 -07:00
Ross Scroggs
c9c9fbd604 #1813 #1816 2025-08-14 17:34:24 -07:00
Ross Scroggs
9d0d7c5aa8 Merge branch 'main' of https://github.com/GAM-team/GAM 2025-08-14 17:32:31 -07:00
Ross Scroggs
65b23113a9 #1813 #1816 2025-08-14 17:32:27 -07:00
Jay Lee
4d3edf7203 actions: rebuild for Python 3.13.7
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
2025-08-14 16:30:11 -04:00
Jay Lee
3c5d3fc569 retry license errors on "info user". Fixes #1817 2025-08-14 18:57:07 +00:00
Ross Scroggs
f0d984c693 Update Inbound-SSO.md
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
2025-08-14 07:43:16 -07:00
Ross Scroggs
6efe1a596f Update Inbound-SSO.md 2025-08-14 07:39:22 -07:00
Ross Scroggs
598e5cf315 Update Inbound-SSO.md
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
2025-08-13 08:32:14 -07:00
Ross Scroggs
3fb0b840a1 Merge branch 'main' of https://github.com/GAM-team/GAM
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-08-13 07:43:53 -07:00
Ross Scroggs
ee3fa9715c Wiki cleanup 2025-08-13 07:43:51 -07:00
Jay Lee
3369a7a506 Update build.yml 2025-08-13 10:11:14 -04:00
Jay Lee
a6d176c033 actions: move to maintained action for publish. Fixes #1782 2025-08-13 10:08:23 -04:00
Ross Scroggs
120d72e67a Alert Center Pub/Sub notifications
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
2025-08-12 09:23:49 -07:00
Ross Scroggs
0082a5a0b9 Alert Center Pub/Sub notifications 2025-08-12 09:21:45 -07:00
Ross Scroggs
9971cdbfb3 Alert Center notifications 2025-08-12 09:01:44 -07:00
GitHub Action
837bb9f84f [ci skip] Updated cacerts.pem 2025-08-11 23:32:05 +00:00
Ross Scroggs
805b196532 Update Users-Drive-Copy-Move.md
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
Push wiki / pushwiki (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
2025-08-11 08:13:38 -07:00
Ross Scroggs
a23238f97f Update Users-Chat.md
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2025-08-10 06:21:12 -07:00
Ross Scroggs
e88e2f0d7f Doc updates
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
2025-08-08 17:29:43 -07:00
Ross Scroggs
13ed3fe80c Update Users-Drive-Permissions.md 2025-08-08 09:18:56 -07:00
Ross Scroggs
37bfcc1251 Updated gam oauth create to warn about too many scopes 2025-08-07 20:43:02 -07:00
Ross Scroggs
cb7e70ce31 Merge branch 'main' of https://github.com/GAM-team/GAM
Some checks failed
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-08-07 20:41:35 -07:00
Ross Scroggs
25006765de Updated gam oauth create to warn about too many scopes 2025-08-07 20:41:33 -07:00
GitHub Action
594164944e [ci skip] Updated cacerts.pem 2025-08-07 23:34:51 +00:00
Ross Scroggs
56ed6e8a81 Update Version-and-Help.md
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
2025-08-07 12:04:19 -07:00
Ross Scroggs
159184be73 Update Users-Drive-Permissions.md
Some checks failed
Push wiki / pushwiki (push) Has been cancelled
Build and test GAM / build (build, 1, Build Intel Ubuntu Jammy, ubuntu-22.04) (push) Has been cancelled
Build and test GAM / build (build, 10, Build Intel Windows, windows-2022) (push) Has been cancelled
Build and test GAM / build (build, 11, Build Arm Windows, windows-11-arm) (push) Has been cancelled
Build and test GAM / build (build, 2, Build Intel Ubuntu Noble, ubuntu-24.04) (push) Has been cancelled
Build and test GAM / build (build, 3, Build Arm Ubuntu Noble, ubuntu-24.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 4, Build Arm Ubuntu Jammy, ubuntu-22.04-arm) (push) Has been cancelled
Build and test GAM / build (build, 5, Build Intel StaticX Legacy, ubuntu-22.04, yes) (push) Has been cancelled
Build and test GAM / build (build, 6, Build Arm StaticX Legacy, ubuntu-22.04-arm, yes) (push) Has been cancelled
Build and test GAM / build (build, 7, Build Intel MacOS, macos-13) (push) Has been cancelled
Build and test GAM / build (build, 8, Build Arm MacOS 14, macos-14) (push) Has been cancelled
Build and test GAM / build (build, 9, Build Arm MacOS 15, macos-15) (push) Has been cancelled
Build and test GAM / build (test, 12, Test Python 3.10, ubuntu-24.04, 3.10) (push) Has been cancelled
Build and test GAM / build (test, 13, Test Python 3.11, ubuntu-24.04, 3.11) (push) Has been cancelled
Build and test GAM / build (test, 14, Test Python 3.12, ubuntu-24.04, 3.12) (push) Has been cancelled
Build and test GAM / build (test, 15, Test Python 3.14-dev, ubuntu-24.04, 3.14-dev) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled
2025-08-06 11:34:52 -07:00
Ross Scroggs
51f4f3c401 Upgraded to OpenSSL 3.5.2. 2025-08-06 11:27:07 -07:00
31 changed files with 966 additions and 523 deletions

View File

@@ -30,6 +30,7 @@ env:
PYTHON_SOURCE_PATH: ${{ github.workspace }}/src/cpython PYTHON_SOURCE_PATH: ${{ github.workspace }}/src/cpython
CRYPTOGRAPHY_BUILD_OPENSSL_NO_LEGACY: 1 CRYPTOGRAPHY_BUILD_OPENSSL_NO_LEGACY: 1
CRYPTOGRAPHY_OPENSSL_NO_LEGACY: 1 CRYPTOGRAPHY_OPENSSL_NO_LEGACY: 1
WINDOWS_CODESIGN_CERT_HASH: 590dc5bb10dfb31dbff38c0e2f9c35ef0f6d0e9e
jobs: jobs:
build: build:
@@ -76,7 +77,7 @@ jobs:
jid: 9 jid: 9
goal: build goal: build
name: Build Arm MacOS 15 name: Build Arm MacOS 15
- os: windows-2022 - os: windows-2025
jid: 10 jid: 10
goal: build goal: build
name: Build Intel Windows name: Build Intel Windows
@@ -107,26 +108,26 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # 5.0.0
with: with:
persist-credentials: false persist-credentials: false
fetch-depth: 0 fetch-depth: 0
- id: auth - id: auth
name: Authenticate to Google Cloud name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2 uses: google-github-actions/auth@6fc4af4b145ae7821d527454aa9bd537d1f2dc5f # 2.1.12
with: with:
workload_identity_provider: projects/297925809119/locations/global/workloadIdentityPools/gha-pool/providers/gha-provider workload_identity_provider: projects/297925809119/locations/global/workloadIdentityPools/gha-pool/providers/gha-provider
service_account: github-actions-testing-for-gam@gam-project-wyo-lub-ivl.iam.gserviceaccount.com service_account: github-actions-testing-for-gam@gam-project-wyo-lub-ivl.iam.gserviceaccount.com
- name: Cache multiple paths - name: Cache multiple paths
if: matrix.goal == 'build' if: matrix.goal == 'build'
uses: actions/cache@v4 uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # 4.2.4
id: cache-python-ssl id: cache-python-ssl
with: with:
path: | path: |
cache.tar.xz cache.tar.xz
key: gam-${{ matrix.jid }}-20250805 key: gam-${{ matrix.jid }}-20250814
- 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'
@@ -136,7 +137,7 @@ jobs:
- name: Use pre-compiled Python for testing - name: Use pre-compiled Python for testing
if: matrix.python != '' if: matrix.python != ''
uses: actions/setup-python@v5 uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # 5.6.0
with: with:
python-version: ${{ matrix.python }} python-version: ${{ matrix.python }}
allow-prereleases: true allow-prereleases: true
@@ -216,14 +217,13 @@ jobs:
- name: MacOS import developer certificates for signing - name: MacOS import developer certificates for signing
if: runner.os == 'macOS' if: runner.os == 'macOS'
uses: apple-actions/import-codesign-certs@v3 uses: apple-actions/import-codesign-certs@95e84a1a18f2bdbc5c6ab9b7f4429372e4b13a8b # 5.0.3
with: with:
keychain: signing_temp
p12-file-base64: ${{ secrets.CERTIFICATES_P12 }} p12-file-base64: ${{ secrets.CERTIFICATES_P12 }}
p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }} p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }}
- name: Windows Configure VCode - name: Windows Configure VCode
uses: ilammy/msvc-dev-cmd@v1 uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # 1.13.0
if: runner.os == 'Windows' && steps.cache-python-ssl.outputs.cache-hit != 'true' if: runner.os == 'Windows' && steps.cache-python-ssl.outputs.cache-hit != 'true'
with: with:
arch: ${{ runner.arch }} arch: ${{ runner.arch }}
@@ -285,7 +285,7 @@ jobs:
echo "COMPILED_OPENSSL_VERSION=${COMPILED_OPENSSL_VERSION}" >> $GITHUB_ENV echo "COMPILED_OPENSSL_VERSION=${COMPILED_OPENSSL_VERSION}" >> $GITHUB_ENV
- name: Windows NASM Install - name: Windows NASM Install
uses: ilammy/setup-nasm@v1 uses: ilammy/setup-nasm@72793074d3c8cdda771dba85f6deafe00623038b # 1.5.2
if: matrix.goal == 'build' && runner.os == 'Windows' && runner.arch == 'X64' && steps.cache-python-ssl.outputs.cache-hit != 'true' if: matrix.goal == 'build' && runner.os == 'Windows' && runner.arch == 'X64' && steps.cache-python-ssl.outputs.cache-hit != 'true'
- name: Config OpenSSL - name: Config OpenSSL
@@ -462,13 +462,6 @@ jobs:
curl -O -L "$latest_crypt_whl" curl -O -L "$latest_crypt_whl"
"$PYTHON" -m pip install cryptography*.whl "$PYTHON" -m pip install cryptography*.whl
#- uses: actions-rust-lang/setup-rust-toolchain@v1
# - name: Compile cryptography from source (no legacy)
# if: runner.os != 'Windows' || runner.arch != 'ARM64'
# run: |
# pip install --no-binary ":all:" --force cryptography
- name: Install pip requirements - name: Install pip requirements
run: | run: |
echo "before anything..." echo "before anything..."
@@ -601,6 +594,72 @@ jobs:
echo "GAM Version ${GAMVERSION}" echo "GAM Version ${GAMVERSION}"
echo "GAMVERSION=${GAMVERSION}" >> $GITHUB_ENV echo "GAMVERSION=${GAMVERSION}" >> $GITHUB_ENV
- name: Install WinAppDriver
if: runner.os == 'Windows'
run: |
choco install -y winappdriver
- name: Enabled dev mode for WinAppDriver
if: runner.os == 'Windows'
shell: cmd
run : |
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /t REG_DWORD /f /v "AllowDevelopmentWithoutDevLicense" /d "1"
- name: Install appium and totp tools
if: runner.os == 'Windows'
run: |
echo "Installing appium..."
npm install -g appium
echo "Installing totp-generator..."
npm install "totp-generator"
echo "Installing wdio..."
npm install @wdio/cli
echo "Installing appium win driver..."
appium driver install windows
- name: Install Certum MSI
if: runner.os == 'Windows'
shell: pwsh
run: |
$url = "https://files.certum.eu/software/SimplySignDesktop/Windows/9.3.2.67/SimplySignDesktop-9.3.2.67-64-bit-en.msi"
$file = "SimplySignDesktop-9.3.2.67-64-bit-en.msi"
Invoke-WebRequest $url -OutFile $file
$log = "install.log"
$procMain = Start-Process "msiexec" "/i `"$file`" /qn /l*! `"$log`"" -NoNewWindow -PassThru
$procLog = Start-Process "powershell" "Get-Content -Path `"$log`" -Wait" -NoNewWindow -PassThru
$procMain.WaitForExit()
$procLog.Kill()
- name: Login to Certum
if: runner.os == 'Windows'
shell: pwsh
env:
TOTP_SECRET: ${{ secrets.TOTP_SECRET }}
run: |
# disable win private firewall that interferes with appium server
Set-NetFirewallProfile -Profile Private -Enabled False
$appiumCmd = Get-Command appium
$appiumPath = $appiumCmd.Path
Start-Process -Filepath "powershell.exe" -ArgumentList "-File", $appiumPath, "--address", "127.0.0.1", "--log-level", "error"
Start-Sleep -Seconds 10
write-host "appium started"
write-host "running SimplySignDesktop login..."
node tools/ssd.mjs --log-level warn
write-host "sleeping during login..."
Start-Sleep 10
- name: Sign gam.exe
if: runner.os == 'Windows'
shell: pwsh
run: |
write-Host "Signing ${env:gam}...."
# Always explicitely use x64 version os signtool.exe, arm64 version apparently can't
# see Certum certs since SimplySignDesktop is x64-only today.
Start-Process -Wait -NoNewWindow -ErrorAction Continue -FilePath 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\signtool.exe' -ArgumentList "sign", "/sha1", "590dc5bb10dfb31dbff38c0e2f9c35ef0f6d0e9e", "/tr", "http://time.certum.pl", "/td", "SHA256", "/fd", "SHA256", "/v", "$env:gam"
write-Host "Verifying signature of ${env:gam}...."
# verify signature. If we failed to sign we should fail to verify and die.
& 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\signtool.exe' verify /pa /v "$env:gam"
- name: Configure user and service account auth - name: Configure user and service account auth
id: configserviceaccount id: configserviceaccount
env: env:
@@ -609,36 +668,8 @@ jobs:
../.github/actions/decrypt.sh "${GAMCFGDIR}" ../.github/actions/decrypt.sh "${GAMCFGDIR}"
$gam create signjwtserviceaccount $gam create signjwtserviceaccount
- name: Upload gam.exe Windows for signing
if: runner.os == 'Windows' && matrix.goal != 'test'
run: |
export folder_number=$(date +%s)
export folder_id=$($gam user gam-win-signer@pdl.jaylee.us add drivefile drivefilename "UPLOADING_FOR_SIGN ${folder_number}" parentid "1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp" mimetype gfolder returnidonly)
$gam user gam-win-signer@pdl.jaylee.us add drivefile localfile "$gam" parentid "$folder_id"
$gam user gam-win-signer@pdl.jaylee.us update drivefile "$folder_id" newfilename "READYTOSIGN ${folder_number}"
export signed_folder="SIGNED ${folder_number}"
zero_results="gam-win-signer@pdl.jaylee.us,0"
while true; do
result_counts=$($gam user gam-win-signer@pdl.jaylee.us print filelist query "name = '${signed_folder}' and '1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp' in parents and mimeType = 'application/vnd.google-apps.folder'" countsonly)
echo "$result_counts"
if [[ ! "$result_counts" =~ "$zero_results" ]]; then
echo "looks like we have results"
break
fi
echo "no results, sleeping 10..."
sleep 10
done
# download signed gam.exe
$gam user gam-win-signer@pdl.jaylee.us print filelist query "name = '${signed_folder}' and '1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp' in parents and mimeType = 'application/vnd.google-apps.folder'" id | $gam csv - gam user gam-win-signer@pdl.jaylee.us print filelist query "'~~id~~' in parents and name = 'gam.exe'" id | $gam csv - gam user gam-win-signer@pdl.jaylee.us get drivefile ~id targetfolder "$gampath" targetname "signed-gam.exe" overwrite true acknowledgeabuse true
# delete signed folder on drive
$gam user gam-win-signer@pdl.jaylee.us print filelist query "name = '${signed_folder}' and '1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp' in parents and mimeType = 'application/vnd.google-apps.folder'" id | $gam csv - gam user gam-win-signer@pdl.jaylee.us trash drivefile "~id"
# remove unsigned gam.exe and rename signed-gam.exe
rm -v -f "${gampath}/gam.exe"
mv -v -f "${gampath}/signed-gam.exe" "${gampath}/gam.exe"
#"/c/Program Files (x86)/Windows Kits/10/bin/10.0.22621.0/x64/signtool.exe" verify /v /pa "$gam"
- name: Attest gam executable was generated from this Action - name: Attest gam executable was generated from this Action
uses: actions/attest-build-provenance@v1 uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # 2.4.0
if: matrix.goal == 'build' if: matrix.goal == 'build'
with: with:
subject-path: ${{ env.gam }} subject-path: ${{ env.gam }}
@@ -689,34 +720,20 @@ jobs:
rm -v -f *.wixobj rm -v -f *.wixobj
echo "MSI_FILENAME=${MSI_FILENAME}" >> $GITHUB_ENV echo "MSI_FILENAME=${MSI_FILENAME}" >> $GITHUB_ENV
- name: Upload gam MSI Windows for signing - name: Sign GAM MSI
if: runner.os == 'Windows' && matrix.goal != 'test' if: runner.os == 'Windows'
shell: pwsh
run: | run: |
export folder_number=$(date +%s) write-Host "Signing ${env:MSI_FILENAME}...."
export folder_id=$($gam user gam-win-signer@pdl.jaylee.us add drivefile drivefilename "UPLOADING_FOR_SIGN ${folder_number}" parentid "1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp" mimetype gfolder returnidonly) # Always explicitely use x64 version os signtool.exe, arm64 version apparently can't
$gam user gam-win-signer@pdl.jaylee.us add drivefile localfile "$MSI_FILENAME" parentid "$folder_id" # see Certum certs since SimplySignDesktop is x64-only today.
rm -f -v "$MSI_FILENAME" Start-Process -Wait -NoNewWindow -ErrorAction Continue -FilePath 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\signtool.exe' -ArgumentList "sign", "/sha1", "590dc5bb10dfb31dbff38c0e2f9c35ef0f6d0e9e", "/tr", "http://time.certum.pl", "/td", "SHA256", "/fd", "SHA256", "/v", "$env:MSI_FILENAME"
$gam user gam-win-signer@pdl.jaylee.us update drivefile "$folder_id" newfilename "READYTOSIGN ${folder_number}" write-Host "Verifying signature of ${env:MSI_FILENAME}...."
export signed_folder="SIGNED ${folder_number}" # verify signature. If we failed to sign we should fail to verify and die.
zero_results="gam-win-signer@pdl.jaylee.us,0" & 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\signtool.exe' verify /pa /v "$env:MSI_FILENAME"
while true; do
result_counts=$($gam user gam-win-signer@pdl.jaylee.us print filelist query "name = '${signed_folder}' and '1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp' in parents and mimeType = 'application/vnd.google-apps.folder'" countsonly)
echo "$result_counts"
if [[ ! "$result_counts" =~ "$zero_results" ]]; then
echo "looks like we have results"
break
fi
echo "no results, sleeping 10..."
sleep 10
done
# download signed package
$gam user gam-win-signer@pdl.jaylee.us print filelist query "name = '${signed_folder}' and '1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp' in parents and mimeType = 'application/vnd.google-apps.folder'" id | $gam csv - gam user gam-win-signer@pdl.jaylee.us print filelist query "'~~id~~' in parents and name contains '.msi'" id | $gam csv - gam user gam-win-signer@pdl.jaylee.us get drivefile ~id targetfolder "$GITHUB_WORKSPACE" targetname "$MSI_FILENAME" overwrite true acknowledgeabuse true
# delete signed folder on drive
$gam user gam-win-signer@pdl.jaylee.us print filelist query "name = '${signed_folder}' and '1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp' in parents and mimeType = 'application/vnd.google-apps.folder'" id | $gam csv - gam user gam-win-signer@pdl.jaylee.us trash drivefile "~id"
#"/c/Program Files (x86)/Windows Kits/10/bin/10.0.22621.0/x64/signtool.exe" verify /v /pa "$MSI_FILENAME"
- name: Attest that gam package files were generated from this Action - name: Attest that gam package files were generated from this Action
uses: actions/attest-build-provenance@v1 uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # 2.4.0
if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && matrix.goal == 'build' if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && matrix.goal == 'build'
with: with:
subject-path: | subject-path: |
@@ -725,7 +742,7 @@ jobs:
gam*.msi gam*.msi
- name: Archive production artifacts - name: Archive production artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # 4.6.2
if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && matrix.goal != 'test' if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && matrix.goal != 'test'
with: with:
name: gam-binaries-${{ env.GAMOS }}-${{ env.arch }}-${{ matrix.jid }} name: gam-binaries-${{ env.GAMOS }}-${{ env.arch }}-${{ matrix.jid }}
@@ -989,16 +1006,16 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # 5.0.0
with: with:
persist-credentials: false persist-credentials: false
fetch-depth: 0 fetch-depth: 0
- name: Download artifacts - name: Download artifacts
uses: actions/download-artifact@v4 uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # 5.0.0
- name: VirusTotal Scan - name: VirusTotal Scan
uses: crazy-max/ghaction-virustotal@v4 uses: crazy-max/ghaction-virustotal@d34968c958ae283fe976efed637081b9f9dcf74f # 4.2.0
with: with:
vt_api_key: ${{ secrets.VT_API_KEY }} vt_api_key: ${{ secrets.VT_API_KEY }}
files: | files: |
@@ -1011,12 +1028,14 @@ jobs:
echo "Date version: ${dateversion}" echo "Date version: ${dateversion}"
echo "dateversion=${dateversion}" >> $GITHUB_OUTPUT echo "dateversion=${dateversion}" >> $GITHUB_OUTPUT
- uses: "marvinpinto/action-automatic-releases@latest" - name: Publish draft release
name: Publish draft release uses: softprops/action-gh-release@72f2c25fcb47643c292f7107632f7a47c1df5cd8 # 2.3.2
with: with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: "${{ steps.dateversion.outputs.dateversion }}"
prerelease: false
draft: true draft: true
prerelease: false
tag_name: "${{ steps.dateversion.outputs.dateversion }}"
fail_on_unmatched_files: true
files: | files: |
gam-binaries/* gam-binaries/*

View File

@@ -16,7 +16,7 @@ defaults:
working-directory: src working-directory: src
jobs: jobs:
check-apis: check-certs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@master - uses: actions/checkout@master

View File

@@ -539,6 +539,7 @@ If an item contains spaces, it should be surrounded by ".
Must match this Python Regular Expression: [a-zA-Z0-9 '"!-]{4,30} Must match this Python Regular Expression: [a-zA-Z0-9 '"!-]{4,30}
<PropertyKey> ::= <String> <PropertyKey> ::= <String>
<PropertyValue> ::= <String> <PropertyValue> ::= <String>
<PubSubTopicName> ::= <String>
<QueryAlert> ::= <String> <QueryAlert> ::= <String>
See: https://developers.google.com/admin-sdk/alertcenter/guides/query-filters See: https://developers.google.com/admin-sdk/alertcenter/guides/query-filters
<QueryBrowser> ::= <String> <QueryBrowser> ::= <String>
@@ -1540,6 +1541,10 @@ gam show admins
# Alert Center # Alert Center
gam show alertsettings
gam update alertsettings <PubsubTopicName>
gam clear alertsettings
gam delete alert <AlertID> gam delete alert <AlertID>
gam undelete alert <AlertID> gam undelete alert <AlertID>
gam info alert <AlertID> [formatjson] gam info alert <AlertID> [formatjson]
@@ -4277,19 +4282,19 @@ gam show policies
<SSOProfileItem> ::= <SSOProfileDisplayName>|<SSOProfileName> <SSOProfileItem> ::= <SSOProfileDisplayName>|<SSOProfileName>
<SSOProfileItemList> ::= "<SSOProfileItem>(,<SSOProfileItem>)*" <SSOProfileItemList> ::= "<SSOProfileItem>(,<SSOProfileItem>)*"
gam create inboundssoprofile [name <SSOProfileDisplayName>] gam create inboundssoprofile [saml|oidc] [name <SSOProfileDisplayName>]
[entityid <String>] [loginurl <URL>] [logouturl <URL>] [changepasswordurl <URL>] [entityid <String>] [loginurl <URL>] [logouturl <URL>] [changepasswordurl <URL>]
[returnnameonly] [returnnameonly]
gam update inboundssoprofile <SSOProfileItem> gam update inboundssoprofile [saml|oidc] <SSOProfileItem>
[entityid <String>] [loginurl <URL>] [logouturl <URL>] [changepasswordurl <URL>] [entityid <String>] [loginurl <URL>] [logouturl <URL>] [changepasswordurl <URL>]
[returnnameonly] [returnnameonly]
gam delete inboundssoprofile <SSOProfileItem> gam delete inboundssoprofile [saml|oidc] <SSOProfileItem>
gam info inboundssoprofile <SSOProfileItem> gam info inboundssoprofile [all|saml|oidc] <SSOProfileItem>
[formatjson] [formatjson]
gam show inboundssoprofiles gam show inboundssoprofiles [all|saml|oidc]
[formatjson] [formatjson]
gam print inboundssoprofiles [todrive <ToDriveAttribute>*] gam print inboundssoprofiles [all|saml|oidc] [todrive <ToDriveAttribute>*]
[[formatjson [quotechar <Character>]] [[formatjson [quotechar <Character>]]
<SSOCredentialsName> ::= [id:]inboundSamlSsoProfiles/<String>/idpCredentials/<String> <SSOCredentialsName> ::= [id:]inboundSamlSsoProfiles/<String>/idpCredentials/<String>
@@ -4313,10 +4318,14 @@ gam print inboundssocredentials [profile|profiles <SSOProfileItemList>]
orgunits/<String> | orgunits/<String> |
orgunit:<OrgUnitPath> orgunit:<OrgUnitPath>
gam create inboundssoassignment (group <GroupItem> rank <Number>)|(ou|org|orgunit <OrgUnitItem>) gam create inboundssoassignment
(mode sso_off)|(mode saml_sso profile <SSOProfileItem>)(mode domain_wide_saml_if_enabled) [neverredirect] (group <GroupItem> rank <Number>)|(ou|org|orgunit <OrgUnitItem>)
gam update inboundssoassignment [(group <GroupItem> rank <Number>)|(ou|org|orgunit <OrgUnitItem>)] (mode sso_off)|(mode saml_sso profile <SSOProfileItem>)|(mode oidc_sso profile <SSOProfileName>}|(mode domain_wide_saml_if_enabled)
[(mode sso_off)|(mode saml_sso profile <SSOProfileItem>)(mode domain_wide_saml_if_enabled)] [neverredirect] [neverredirect]
gam update inboundssoassignment <SSOAssignmentName>
[(group <GroupItem> rank <Number>)|(ou|org|orgunit <OrgUnitItem>)]
(mode sso_off)|(mode saml_sso profile <SSOProfileItem>)|(mode oidc_sso profile <SSOProfileName>}|(mode domain_wide_saml_if_enabled)
[neverredirect]
gam delete inboundssoassignment <SSOAssignmentSelector> gam delete inboundssoassignment <SSOAssignmentSelector>
gam info inboundssoassignment <SSOAssignmentSelector> gam info inboundssoassignment <SSOAssignmentSelector>
@@ -4540,11 +4549,12 @@ gam report usage customer [todrive <ToDriveAttribute>*]
chrome| chrome|
classroom| classroom|
contextawareaccess| contextawareaccess|
gplus|currents|google+|
datastudio| datastudio|
drive|doc|docs| drive|doc|docs|
gcp|cloud| gcp|cloud|
geminiinworkspaceapps|gemini|geminiforworkspace| geminiinworkspaceapps|gemini|geminiforworkspace|
gmail|
gplus|currents|google+|
groups|group| groups|group|
groupsenterprise|enterprisegroups| groupsenterprise|enterprisegroups|
jamboard| jamboard|

View File

@@ -1,3 +1,61 @@
7.19.02
Update `gam info user <UserItem>` to eliminate 5 second delay when getting license info.
Additional information:
* See: https://github.com/GAM-team/GAM/wiki/Licenses#info-user-performance
7.19.01
Updated `gam <UserTypeEntity> print|show signature` to handle the following error
that occurs when an alias is specified.
```
ERROR: 404: notFound - Requested entity was not found.
```
7.19.00
Eliminated `drive_v3_beta` and `meet_v2_beta` from `gam.cfg` as the API betas are no longer used.
Updated `Meet API` scopes so that GAM can read metadata about additional Meet spaces.
```
[*] 34) Meet API - Manage/Display Meeting Spaces
[*] 35) Meet API - Read Meeting Spaces metadata
```
7.18.07
Updated `gam <UserTypeEntity> print drivelastmodification` to put `addcsvdata` columns
after `User,id,name` rather than after the last column.
7.18.06
Updated `gam <UserTypeEntity> delete|modify messages` to improve the handling
of the following error.
```
quotaExceeded - User-rate limit exceeded
```
7.18.05
Added support for Inbound SSO OIDC profiles.
Currently, if you enter `gam select <SectionName>` and nothing else on the command line,
GAM performs no action. Now, it will be treated as if you entered:
`gam select <SectionName> save`
Updated to Python 3.13.7.
7.18.04
Added commands to display/manage Alert Center Pub/Sub notifications.
* See: https://github.com/GAM-team/GAM/wiki/Alert-Center#configuring-settings
7.18.03
Updated `gam oauth create` to give a warning if the number of selected scopes will
probably cause Google to generate a "Something went wrong" error.
7.18.02 7.18.02
Upgraded to OpenSSL 3.5.2. Upgraded to OpenSSL 3.5.2.

View File

@@ -433,106 +433,6 @@ pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
-----END CERTIFICATE----- -----END CERTIFICATE-----
# Operating CA: GoDaddy
# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority
# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority
# Label: "Starfield Class 2 CA"
# Serial: 0
# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24
# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a
# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58
-----BEGIN CERTIFICATE-----
MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
-----END CERTIFICATE-----
# Operating CA: GoDaddy
# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority
# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority
# Label: "Go Daddy Class 2 CA"
# Serial: 0
# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67
# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4
# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
ReYNnyicsbkqWletNw+vHX/bvZ8=
-----END CERTIFICATE-----
# Operating CA: Sectigo
# Issuer: CN=AAA Certificate Services O=Comodo CA Limited
# Subject: CN=AAA Certificate Services O=Comodo CA Limited
# Label: "Comodo AAA Services root"
# Serial: 1
# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0
# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49
# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4
-----BEGIN CERTIFICATE-----
MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
-----END CERTIFICATE-----
# Operating CA: Sectigo # Operating CA: Sectigo
# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited # Issuer: CN=COMODO Certification Authority O=COMODO CA Limited
# Subject: CN=COMODO Certification Authority O=COMODO CA Limited # Subject: CN=COMODO Certification Authority O=COMODO CA Limited

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.18.02' __version__ = '7.19.02'
__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
@@ -3952,14 +3952,20 @@ def SetGlobalVariables():
if checkArgumentPresent(Cmd.SELECT_CMD): if checkArgumentPresent(Cmd.SELECT_CMD):
sectionName = _selectSection() sectionName = _selectSection()
GM.Globals[GM.SECTION] = sectionName # Save section for inner gams GM.Globals[GM.SECTION] = sectionName # Save section for inner gams
while Cmd.ArgumentsRemaining(): # If command line is simply: gam select <SectionName>
if checkArgumentPresent('save'): # assume save
GM.Globals[GM.PARSER].set(configparser.DEFAULTSECT, GC.SECTION, sectionName) if not Cmd.ArgumentsRemaining():
_writeGamCfgFile(GM.Globals[GM.PARSER], GM.Globals[GM.GAM_CFG_FILE], Act.SAVE) GM.Globals[GM.PARSER].set(configparser.DEFAULTSECT, GC.SECTION, sectionName)
elif checkArgumentPresent('verify'): _writeGamCfgFile(GM.Globals[GM.PARSER], GM.Globals[GM.GAM_CFG_FILE], Act.SAVE)
_verifyValues(sectionName, inputFilterSectionName, outputFilterSectionName) else:
else: while Cmd.ArgumentsRemaining():
break if checkArgumentPresent('save'):
GM.Globals[GM.PARSER].set(configparser.DEFAULTSECT, GC.SECTION, sectionName)
_writeGamCfgFile(GM.Globals[GM.PARSER], GM.Globals[GM.GAM_CFG_FILE], Act.SAVE)
elif checkArgumentPresent('verify'):
_verifyValues(sectionName, inputFilterSectionName, outputFilterSectionName)
else:
break
GM.Globals[GM.GAM_CFG_SECTION_NAME] = sectionName GM.Globals[GM.GAM_CFG_SECTION_NAME] = sectionName
# showsections # showsections
if checkArgumentPresent(Cmd.SHOWSECTIONS_CMD): if checkArgumentPresent(Cmd.SHOWSECTIONS_CMD):
@@ -4733,8 +4739,6 @@ def getAPIService(api, httpObj):
discoveryServiceUrl=DISCOVERY_URIS[v2discovery], static_discovery=False) discoveryServiceUrl=DISCOVERY_URIS[v2discovery], static_discovery=False)
def getService(api, httpObj): def getService(api, httpObj):
### Drive v3beta
# mapDriveURL = api == API.DRIVE3 and GC.Values[GC.DRIVE_V3_BETA]
hasLocalJSON = API.hasLocalJSON(api) hasLocalJSON = API.hasLocalJSON(api)
api, version, v2discovery = API.getVersion(api) api, version, v2discovery = API.getVersion(api)
if api in GM.Globals[GM.CURRENT_API_SERVICES] and version in GM.Globals[GM.CURRENT_API_SERVICES][api]: if api in GM.Globals[GM.CURRENT_API_SERVICES] and version in GM.Globals[GM.CURRENT_API_SERVICES][api]:
@@ -4750,9 +4754,6 @@ def getService(api, httpObj):
discoveryServiceUrl=DISCOVERY_URIS[v2discovery], static_discovery=False) discoveryServiceUrl=DISCOVERY_URIS[v2discovery], static_discovery=False)
GM.Globals[GM.CURRENT_API_SERVICES].setdefault(api, {}) GM.Globals[GM.CURRENT_API_SERVICES].setdefault(api, {})
GM.Globals[GM.CURRENT_API_SERVICES][api][version] = service._rootDesc.copy() GM.Globals[GM.CURRENT_API_SERVICES][api][version] = service._rootDesc.copy()
### Drive v3beta
# if mapDriveURL:
# setattr(service, '_baseUrl', getattr(service, '_baseUrl').replace('/v3/', '/v3beta/'))
if GM.Globals[GM.CACHE_DISCOVERY_ONLY]: if GM.Globals[GM.CACHE_DISCOVERY_ONLY]:
clearServiceCache(service) clearServiceCache(service)
return service return service
@@ -4794,7 +4795,10 @@ def defaultSvcAcctScopes():
for scope in scopesList: for scope in scopesList:
if not scope.get('offByDefault'): if not scope.get('offByDefault'):
saScopes.setdefault(scope['api'], []) saScopes.setdefault(scope['api'], [])
saScopes[scope['api']].append(scope['scope']) if not isinstance(scope['scope'], list):
saScopes[scope['api']].append(scope['scope'])
else:
saScopes[scope['api']].extend(scope['scope'])
saScopes[API.DRIVEACTIVITY].append(API.DRIVE_SCOPE) saScopes[API.DRIVEACTIVITY].append(API.DRIVE_SCOPE)
saScopes[API.DRIVE2] = saScopes[API.DRIVE3] saScopes[API.DRIVE2] = saScopes[API.DRIVE3]
saScopes[API.DRIVETD] = saScopes[API.DRIVE3] saScopes[API.DRIVETD] = saScopes[API.DRIVE3]
@@ -5609,8 +5613,6 @@ def buildGAPIServiceObject(api, user, i=0, count=0, displayError=True):
userEmail = getSaUser(user) userEmail = getSaUser(user)
httpObj = getHttpObj(cache=GM.Globals[GM.CACHE_DIR]) httpObj = getHttpObj(cache=GM.Globals[GM.CACHE_DIR])
service = getService(api, httpObj) service = getService(api, httpObj)
if api == API.MEET_BETA:
api = API.MEET
credentials = getSvcAcctCredentials(api, userEmail) credentials = getSvcAcctCredentials(api, userEmail)
request = transportCreateRequest(httpObj) request = transportCreateRequest(httpObj)
triesLimit = 3 triesLimit = 3
@@ -10672,9 +10674,6 @@ Select all default scopes by entering an 's'; yields [*] for default scopes, [ ]
Unselect all scopes by entering a 'u'; yields [ ] for all scopes Unselect all scopes by entering a 'u'; yields [ ] for all scopes
Exit without changes/authorization by entering an 'e' Exit without changes/authorization by entering an 'e'
Continue to authorization by entering a 'c' Continue to authorization by entering a 'c'
'''
if clientAccess:
oauth2_menu += ''' Note, if all scopes are selected, Google will probably generate an authorization error
''' '''
menu = oauth2_menu % tuple(range(numScopes)) menu = oauth2_menu % tuple(range(numScopes))
selectedScopes = ['*'] * numScopes selectedScopes = ['*'] * numScopes
@@ -10710,14 +10709,21 @@ Continue to authorization by entering a 'c'
api = a_scope['api'] api = a_scope['api']
possibleScope = a_scope['scope'] possibleScope = a_scope['scope']
if api in currentScopes: if api in currentScopes:
for scope in currentScopes[api]: if not isinstance(possibleScope, list):
if scope == possibleScope: for scope in currentScopes[api]:
selectedScopes[i] = '*' if scope == possibleScope:
break selectedScopes[i] = '*'
if 'readonly' in a_scope['subscopes']:
if (scope == possibleScope+'.readonly') or (scope == a_scope.get('roscope')):
selectedScopes[i] = 'R'
break break
if 'readonly' in a_scope['subscopes']:
if (scope == possibleScope+'.readonly') or (scope == a_scope.get('roscope')):
selectedScopes[i] = 'R'
break
else:
for scope in possibleScope:
if scope not in currentScopes[api]:
break
else:
selectedScopes[i] = '*'
i += 1 i += 1
else: else:
i = 0 i = 0
@@ -10776,7 +10782,25 @@ Continue to authorization by entering a 'c'
break break
sys.stdout.write(f'{ERROR_PREFIX}Invalid input "{choice}"\n') sys.stdout.write(f'{ERROR_PREFIX}Invalid input "{choice}"\n')
if selection == 'c': if selection == 'c':
break if clientAccess:
numSelectedScopes = 0
i = 0
for a_scope in scopesList:
if selectedScopes[i] == '*':
if a_scope['scope']:
numSelectedScopes += 1
elif selectedScopes[i] != ' ':
numSelectedScopes += 1
i += 1
if numSelectedScopes <= API.NUM_CLIENT_SCOPES_ERROR_LIMIT:
break
# If number of scopes is > 48 we'll probably get an error
writeStdout(Msg.NUM_SELECTED_CLIENT_SCOPES.format(numSelectedScopes, API.NUM_CLIENT_SCOPES_ERROR_LIMIT))
choice = readStdin('\nPlease enter c to continue to authorization or any other key to amend selection: ')
if choice and choice.lower() == 'c':
break
else:
break
return selectedScopes return selectedScopes
def _localhost_to_ip(): def _localhost_to_ip():
@@ -11467,13 +11491,14 @@ def _createOauth2serviceJSON(httpObj, projectInfo, svcAcctInfo, create_key=True)
iam = getAPIService(API.IAM, httpObj) iam = getAPIService(API.IAM, httpObj)
try: try:
service_account = callGAPI(iam.projects().serviceAccounts(), 'create', service_account = callGAPI(iam.projects().serviceAccounts(), 'create',
throwReasons=[GAPI.NOT_FOUND, GAPI.PERMISSION_DENIED, GAPI.ALREADY_EXISTS], throwReasons=[GAPI.FAILED_PRECONDITION, GAPI.NOT_FOUND,
GAPI.PERMISSION_DENIED, GAPI.ALREADY_EXISTS],
name=f'projects/{projectInfo["projectId"]}', name=f'projects/{projectInfo["projectId"]}',
body={'accountId': svcAcctInfo['name'], body={'accountId': svcAcctInfo['name'],
'serviceAccount': {'displayName': svcAcctInfo['displayName'], 'serviceAccount': {'displayName': svcAcctInfo['displayName'],
'description': svcAcctInfo['description']}}) 'description': svcAcctInfo['description']}})
entityActionPerformed([Ent.PROJECT, projectInfo['projectId'], Ent.SVCACCT, service_account['name'].rsplit('/', 1)[-1]]) entityActionPerformed([Ent.PROJECT, projectInfo['projectId'], Ent.SVCACCT, service_account['name'].rsplit('/', 1)[-1]])
except (GAPI.notFound, GAPI.permissionDenied) as e: except (GAPI.failedPrecondition, GAPI.notFound, GAPI.permissionDenied) as e:
entityActionFailedWarning([Ent.PROJECT, projectInfo['projectId']], str(e)) entityActionFailedWarning([Ent.PROJECT, projectInfo['projectId']], str(e))
return False return False
except GAPI.alreadyExists as e: except GAPI.alreadyExists as e:
@@ -12309,8 +12334,12 @@ def checkServiceAccount(users):
for scope in scopesList: for scope in scopesList:
if selectedScopes[i] == '*': if selectedScopes[i] == '*':
saScopes.setdefault(scope['api'], []) saScopes.setdefault(scope['api'], [])
saScopes[scope['api']].append(scope['scope']) if not isinstance(scope['scope'], list):
checkScopesSet.add(scope['scope']) saScopes[scope['api']].append(scope['scope'])
checkScopesSet.add(scope['scope'])
else:
saScopes[scope['api']].extend(scope['scope'])
checkScopesSet.update(scope['scope'])
elif selectedScopes[i] == 'R': elif selectedScopes[i] == 'R':
saScopes.setdefault(scope['api'], []) saScopes.setdefault(scope['api'], [])
if 'roscope' not in scope: if 'roscope' not in scope:
@@ -13606,6 +13635,7 @@ REPORT_CHOICE_MAP = {
'drive': 'drive', 'drive': 'drive',
'gcp': 'gcp', 'gcp': 'gcp',
'geminiinworkspaceapps': 'gemini_in_workspace_apps', 'geminiinworkspaceapps': 'gemini_in_workspace_apps',
'gmail': 'gmail',
'gplus': 'gplus', 'gplus': 'gplus',
'groups': 'groups', 'groups': 'groups',
'groupsenterprise': 'groups_enterprise', 'groupsenterprise': 'groups_enterprise',
@@ -27066,6 +27096,8 @@ def _getChatMemberEmail(cd, member):
if member['member']['type'] == 'HUMAN': if member['member']['type'] == 'HUMAN':
_, memberUid = member['member']['name'].split('/') _, memberUid = member['member']['name'].split('/')
member['member']['email'], _ = convertUIDtoEmailAddressWithType(f'uid:{memberUid}', cd, None, emailTypes=['user']) member['member']['email'], _ = convertUIDtoEmailAddressWithType(f'uid:{memberUid}', cd, None, emailTypes=['user'])
if member['member']['email'].find('@') == -1:
member['member']['email'] = 'id:'+member['member']['email']
elif 'groupMember' in member: elif 'groupMember' in member:
_, memberUid = member['groupMember']['name'].split('/') _, memberUid = member['groupMember']['name'].split('/')
member['groupMember']['email'], _ = convertUIDtoEmailAddressWithType(f'uid:{memberUid}', cd, None, emailTypes=['group']) member['groupMember']['email'], _ = convertUIDtoEmailAddressWithType(f'uid:{memberUid}', cd, None, emailTypes=['group'])
@@ -28215,9 +28247,7 @@ def printShowChatEvents(users):
if csvPF: if csvPF:
csvPF.writeCSVfile('Chat Events') csvPF.writeCSVfile('Chat Events')
def buildMeetServiceObject(api=API.MEET, user=None, i=0, count=0, entityTypeList=None): def buildMeetServiceObject(api, user=None, i=0, count=0, entityTypeList=None):
if GC.Values[GC.MEET_V2_BETA]:
api = API.MEET_BETA
user, meet = buildGAPIServiceObject(api, user, i, count) user, meet = buildGAPIServiceObject(api, user, i, count)
kvList = [Ent.USER, user] kvList = [Ent.USER, user]
if entityTypeList is not None: if entityTypeList is not None:
@@ -28326,7 +28356,7 @@ def createMeetSpace(users):
i, count, users = getEntityArgument(users) i, count, users = getEntityArgument(users)
for user in users: for user in users:
i += 1 i += 1
user, meet, kvList = buildMeetServiceObject(API.MEET, user, i, count, [Ent.MEET_SPACE, None]) user, meet, kvList = buildMeetServiceObject(API.MEET_SPACES, user, i, count, [Ent.MEET_SPACE, None])
if not meet: if not meet:
continue continue
try: try:
@@ -28365,7 +28395,7 @@ def updateMeetSpace(users):
i, count, users = getEntityArgument(users) i, count, users = getEntityArgument(users)
for user in users: for user in users:
i += 1 i += 1
user, meet, kvList = buildMeetServiceObject(API.MEET, user, i, count, [Ent.MEET_SPACE, name]) user, meet, kvList = buildMeetServiceObject(API.MEET_SPACES, user, i, count, [Ent.MEET_SPACE, name])
if not meet: if not meet:
continue continue
try: try:
@@ -28396,7 +28426,7 @@ def infoMeetSpace(users):
i, count, users = getEntityArgument(users) i, count, users = getEntityArgument(users)
for user in users: for user in users:
i += 1 i += 1
user, meet, kvList = buildMeetServiceObject(API.MEET, user, i, count, [Ent.MEET_SPACE, name]) user, meet, kvList = buildMeetServiceObject(API.MEET_SPACES, user, i, count, [Ent.MEET_SPACE, name])
if not meet: if not meet:
continue continue
try: try:
@@ -28425,7 +28455,7 @@ def endMeetConference(users):
i, count, users = getEntityArgument(users) i, count, users = getEntityArgument(users)
for user in users: for user in users:
i += 1 i += 1
user, meet, kvList = buildMeetServiceObject(API.MEET, user, i, count, [Ent.MEET_SPACE, name, Ent.MEET_CONFERENCE, None]) user, meet, kvList = buildMeetServiceObject(API.MEET_SPACES, user, i, count, [Ent.MEET_SPACE, name, Ent.MEET_CONFERENCE, None])
if not meet: if not meet:
continue continue
try: try:
@@ -28506,7 +28536,7 @@ def printShowMeetConferences(users):
i, count, users = getEntityArgument(users) i, count, users = getEntityArgument(users)
for user in users: for user in users:
i += 1 i += 1
user, meet, kvList = buildMeetServiceObject(API.MEET, user, i, count, [Ent.MEET_CONFERENCE, None]) user, meet, kvList = buildMeetServiceObject(API.MEET_READONLY, user, i, count, [Ent.MEET_CONFERENCE, None])
if not meet: if not meet:
continue continue
try: try:
@@ -28582,7 +28612,7 @@ def _printShowMeetItems(users, entityType):
i, count, users = getEntityArgument(users) i, count, users = getEntityArgument(users)
for user in users: for user in users:
i += 1 i += 1
user, meet, kvList = buildMeetServiceObject(API.MEET, user, i, count, [Ent.MEET_CONFERENCE, parent]) user, meet, kvList = buildMeetServiceObject(API.MEET_READONLY, user, i, count, [Ent.MEET_CONFERENCE, parent])
if not meet: if not meet:
continue continue
if entityType == Ent.MEET_PARTICIPANT: if entityType == Ent.MEET_PARTICIPANT:
@@ -32198,9 +32228,9 @@ def doUpdateMobileDevices():
[Msg.ACTION_APPLIED, body['action']], i, count) [Msg.ACTION_APPLIED, body['action']], i, count)
except GAPI.internalError: except GAPI.internalError:
entityActionFailedWarning([Ent.MOBILE_DEVICE, resourceId], Msg.DOES_NOT_EXIST, i, count) entityActionFailedWarning([Ent.MOBILE_DEVICE, resourceId], Msg.DOES_NOT_EXIST, i, count)
except (GAPI.resourceIdNotFound, GAPI.badRequest, GAPI.resourceNotFound) as e: except (GAPI.resourceIdNotFound, GAPI.badRequest, GAPI.resourceNotFound, GAPI.forbidden) as e:
entityActionFailedWarning([Ent.MOBILE_DEVICE, resourceId], str(e), i, count) entityActionFailedWarning([Ent.MOBILE_DEVICE, resourceId], str(e), i, count)
except (GAPI.forbidden, GAPI.permissionDenied) as e: except GAPI.permissionDenied as e:
ClientAPIAccessDeniedExit(str(e)) ClientAPIAccessDeniedExit(str(e))
# gam delete mobile|mobiles <MobileDeviceEntity> # gam delete mobile|mobiles <MobileDeviceEntity>
@@ -37783,6 +37813,54 @@ def doDeleteOrUndeleteAlert():
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.permissionDenied): except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.permissionDenied):
userAlertsServiceNotEnabledWarning(user) userAlertsServiceNotEnabledWarning(user)
def _showAlertSettings(settings):
notifications = settings.get('notifications', [])
count = len(notifications)
entityPerformAction([Ent.ALERT_SETTINGS, None])
i = 0
for notification in notifications:
i += 1
printEntity([Ent.NOTIFICATION, None], i, count)
Ind.Increment()
showJSON(None, notification)
Ind.Decrement()
# gam show alertsettings
def doShowAlertSettings():
checkForExtraneousArguments()
user, ac = buildGAPIServiceObject(API.ALERTCENTER, _getAdminEmail())
if not ac:
return
try:
settings = callGAPI(ac.v1beta1(), 'getSettings',
throwReasons=GAPI.ALERT_THROW_REASONS)
_showAlertSettings(settings)
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.permissionDenied):
userAlertsServiceNotEnabledWarning(user)
# gam update alertsettings <PubsubTopicName>
def doUpdateAlertSettings(clear=False):
if not clear:
body = {'notifications':
[{'cloudPubsubTopic': {'topicName': getString(Cmd.OB_PUBSUB_TOPIC_NAME)}}]}
else:
body = {'notifications': []}
checkForExtraneousArguments()
user, ac = buildGAPIServiceObject(API.ALERTCENTER, _getAdminEmail())
if not ac:
return
try:
settings = callGAPI(ac.v1beta1(), 'updateSettings',
throwReasons=GAPI.ALERT_THROW_REASONS,
body=body)
_showAlertSettings(settings)
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.permissionDenied):
userAlertsServiceNotEnabledWarning(user)
# gam clear alertsettings
def doClearAlertSettings():
doUpdateAlertSettings(clear=True)
ALERT_TIME_OBJECTS = {'createTime', 'startTime', 'endTime'} ALERT_TIME_OBJECTS = {'createTime', 'startTime', 'endTime'}
def _showAlert(alert, FJQC, i=0, count=0): def _showAlert(alert, FJQC, i=0, count=0):
@@ -44829,21 +44907,44 @@ def waitForMailbox(entityList):
Ind.Decrement() Ind.Decrement()
def getUserLicenses(lic, user, skus): def getUserLicenses(lic, user, skus):
def _callbackGetLicense(_, response, exception): reasons_to_quit = [
GAPI.ACCESS_NOT_CONFIGURED, # license API not turned on
GAPI.PERMISSION_DENIED, # Admin doesn't have rights to license assignments
GAPI.NOT_FOUND # API call succeeded, user does not have this license
]
def _callbackGetLicense(request_id, response, exception):
if exception is None: if exception is None:
if response and 'skuId' in response: if response and 'skuId' in response:
licenses.append(response['skuId']) licenses.append(response['skuId'])
del sku_calls[request_id]
else:
_, reason, _ = checkGAPIError(exception, softErrors=True)
if reason in reasons_to_quit:
del sku_calls[request_id]
licenses = [] licenses = []
svcargs = dict([('userId', user['primaryEmail']), ('productId', None), ('skuId', None), ('fields', 'skuId')]+GM.Globals[GM.EXTRA_ARGS_LIST]) svcargs = dict([('userId', user['primaryEmail']), ('productId', None), ('skuId', None), ('fields', 'skuId')]+GM.Globals[GM.EXTRA_ARGS_LIST])
method = getattr(lic.licenseAssignments(), 'get') method = getattr(lic.licenseAssignments(), 'get')
dbatch = lic.new_batch_http_request(callback=_callbackGetLicense) sku_calls = {}
for sku in skus: for sku in skus:
svcparms = svcargs.copy() svcparms = svcargs.copy()
svcparms['productId'] = sku[0] svcparms['productId'] = sku[0]
svcparms['skuId'] = sku[1] sku_id = sku[1]
dbatch.add(method(**svcparms)) svcparms['skuId'] = sku_id
dbatch.execute() sku_calls[sku_id] = method(**svcparms)
try_count = 0
while sku_calls:
try_count += 1
dbatch = lic.new_batch_http_request(callback=_callbackGetLicense)
for sku_id, sku_call in sku_calls.items():
dbatch.add(sku_call, request_id=sku_id)
dbatch.execute()
if sku_calls:
if try_count >= 5:
# give up and return what we have
return licenses
time.sleep(5)
return licenses return licenses
USER_NAME_PROPERTY_PRINT_ORDER = [ USER_NAME_PROPERTY_PRINT_ORDER = [
@@ -46328,9 +46429,30 @@ def checkCIUserIsInvitable(users):
return return
csvPF.writeCSVfile('Invitable Users') csvPF.writeCSVfile('Invitable Users')
INBOUNDSSO_INPUT_MODE_CHOICE_MAP = {
'saml': 'saml',
'samlsso': 'saml',
'oidc': 'oidc',
'oidcsso': 'oidc',
}
INBOUNDSSO_OUTPUT_MODE_CHOICE_MAP = {
'all': 'all',
'saml': 'saml',
'samlsso': 'saml',
'oidc': 'oidc',
'oidcsso': 'oidc',
}
INBOUNDSSO_ALL_SAML = {'all', 'saml'}
INBOUNDSSO_ALL_OIDC = {'all', 'oidc'}
INBOUNDSSO_MODE_CHOICE_MAP = { INBOUNDSSO_MODE_CHOICE_MAP = {
'ssooff': 'SSO_OFF', 'ssooff': 'SSO_OFF',
'saml': 'SAML_SSO',
'samlsso': 'SAML_SSO', 'samlsso': 'SAML_SSO',
'oidc': 'OIDC_SSO',
'oidcsso': 'OIDC_SSO',
'domainwidesamlifenabled': 'DOMAIN_WIDE_SAML_IF_ENABLED' 'domainwidesamlifenabled': 'DOMAIN_WIDE_SAML_IF_ENABLED'
} }
@@ -46340,29 +46462,49 @@ def getCIOrgunitID(cd, orgunit):
ou_id = ou_id[3:] ou_id = ou_id[3:]
return f'orgUnits/{ou_id}' return f'orgUnits/{ou_id}'
def _getInboundSSOProfiles(ci): def _getInboundSSOProfiles(ci, mode):
customer = normalizeChannelCustomerID(GC.Values[GC.CUSTOMER_ID]) customer = normalizeChannelCustomerID(GC.Values[GC.CUSTOMER_ID])
try: profiles = []
return callGAPIpages(ci.inboundSamlSsoProfiles(), 'list', 'inboundSamlSsoProfiles', if mode in INBOUNDSSO_ALL_SAML:
throwReasons=GAPI.CISSO_LIST_THROW_REASONS, try:
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS, profiles.extend(callGAPIpages(ci.inboundSamlSsoProfiles(), 'list', 'inboundSamlSsoProfiles',
bailOnInternalError=True, throwReasons=GAPI.CISSO_LIST_THROW_REASONS,
filter=f'customer=="{customer}"') retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
except (GAPI.notFound, GAPI.domainNotFound, GAPI.domainCannotUseApis, bailOnInternalError=True,
GAPI.forbidden, GAPI.badRequest, GAPI.invalid, filter=f'customer=="{customer}"'))
GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e: except (GAPI.notFound, GAPI.domainNotFound, GAPI.domainCannotUseApis,
entityActionFailedWarning([Ent.INBOUND_SSO_PROFILE, customer], str(e)) GAPI.forbidden, GAPI.badRequest, GAPI.invalid,
return [] GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e:
entityActionFailedWarning([Ent.INBOUND_SSO_PROFILE, customer], str(e))
if mode in INBOUNDSSO_ALL_OIDC:
try:
profiles.extend(callGAPIpages(ci.inboundOidcSsoProfiles(), 'list', 'inboundOidcSsoProfiles',
throwReasons=GAPI.CISSO_LIST_THROW_REASONS,
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
bailOnInternalError=True,
filter=f'customer=="{customer}"'))
except (GAPI.notFound, GAPI.domainNotFound, GAPI.domainCannotUseApis,
GAPI.forbidden, GAPI.badRequest, GAPI.invalid,
GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e:
entityActionFailedWarning([Ent.INBOUND_SSO_PROFILE, customer], str(e))
return profiles
def _convertInboundSSOProfileDisplaynameToName(ci=None, displayName=''): def _convertInboundSSOProfileDisplaynameToName(ci, mode, displayName='',
entityType=Ent.INBOUND_SSO_PROFILE):
if displayName.lower().startswith('id:') or displayName.lower().startswith('uid:'): if displayName.lower().startswith('id:') or displayName.lower().startswith('uid:'):
displayName = displayName.split(':', 1)[1] displayName = displayName.split(':', 1)[1]
if not displayName.startswith('inboundSamlSsoProfiles/'): if mode == 'all':
displayName = f'inboundSamlSsoProfiles/{displayName}' if not (displayName.startswith('inboundSamlSsoProfiles/') and
displayName.startswith('inboundOidcSsoProfiles/')):
displayName = f'inboundSamlSsoProfiles/{displayName}'
elif mode == 'saml':
if not displayName.startswith('inboundSamlSsoProfiles/'):
displayName = f'inboundSamlSsoProfiles/{displayName}'
else:
if not displayName.startswith('inboundOidcSsoProfiles/'):
displayName = f'inboundOidcSsoProfiles/{displayName}'
return displayName return displayName
if not ci: profiles = _getInboundSSOProfiles(ci, mode)
ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
profiles = _getInboundSSOProfiles(ci)
matches = [] matches = []
for profile in profiles: for profile in profiles:
if displayName.lower() == profile.get('displayName', '').lower(): if displayName.lower() == profile.get('displayName', '').lower():
@@ -46370,30 +46512,50 @@ def _convertInboundSSOProfileDisplaynameToName(ci=None, displayName=''):
if len(matches) == 1: if len(matches) == 1:
return matches[0]['name'] return matches[0]['name']
if len(matches) == 0: if len(matches) == 0:
usageErrorExit(Msg.NO_SSO_PROFILE_MATCHES.format(displayName)) errMsg = Msg.NO_SSO_PROFILE_MATCHES.format(displayName)
errMsg = Msg.MULTIPLE_SSO_PROFILES_MATCH.format(displayName) else:
for m in matches: errMsg = Msg.MULTIPLE_SSO_PROFILES_MATCH.format(displayName)
errMsg += f' {m["name"]} {m["displayName"]}\n' for m in matches:
usageErrorExit(errMsg) errMsg += f' {m["name"]} {m["displayName"]}\n'
entityActionFailedWarning([entityType, None], errMsg)
return None
def _getInboundSSOProfileArguments(body): def _getInboundSSOProfileArguments(body, mode):
returnNameOnly = False returnNameOnly = False
while Cmd.ArgumentsRemaining(): if mode == 'saml':
myarg = getArgument() while Cmd.ArgumentsRemaining():
if myarg == 'name': myarg = getArgument()
body['displayName'] = getString(Cmd.OB_STRING) if myarg == 'name':
elif myarg == 'entityid': body['displayName'] = getString(Cmd.OB_STRING)
body.setdefault('idpConfig', {})['entityId'] = getString(Cmd.OB_STRING) elif myarg == 'entityid':
elif myarg == 'loginurl': body.setdefault('idpConfig', {})['entityId'] = getString(Cmd.OB_STRING)
body.setdefault('idpConfig', {})['singleSignOnServiceUri'] = getString(Cmd.OB_STRING) elif myarg == 'loginurl':
elif myarg == 'logouturl': body.setdefault('idpConfig', {})['singleSignOnServiceUri'] = getString(Cmd.OB_STRING)
body.setdefault('idpConfig', {})['logoutRedirectUri'] = getString(Cmd.OB_STRING) elif myarg == 'logouturl':
elif myarg == 'changepasswordurl': body.setdefault('idpConfig', {})['logoutRedirectUri'] = getString(Cmd.OB_STRING)
body.setdefault('idpConfig', {})['changePasswordUri'] = getString(Cmd.OB_STRING) elif myarg == 'changepasswordurl':
elif myarg == 'returnnameonly': body.setdefault('idpConfig', {})['changePasswordUri'] = getString(Cmd.OB_STRING)
returnNameOnly = True elif myarg == 'returnnameonly':
else: returnNameOnly = True
unknownArgumentExit() else:
unknownArgumentExit()
else:
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if myarg == 'name':
body['displayName'] = getString(Cmd.OB_STRING)
elif myarg == 'issueruri':
body.setdefault('idpConfig', {})['issuerUri'] = getString(Cmd.OB_STRING)
elif myarg == 'changepasswordurl':
body.setdefault('idpConfig', {})['changePasswordUri'] = getString(Cmd.OB_STRING)
elif myarg == 'clientid':
body.setdefault('rpConfig', {})['clientId'] = getString(Cmd.OB_STRING)
elif myarg == 'clientsecret':
body.setdefault('rpConfig', {})['clientSecret'] = getString(Cmd.OB_STRING)
elif myarg == 'returnnameonly':
returnNameOnly = True
else:
unknownArgumentExit()
return (returnNameOnly, body) return (returnNameOnly, body)
def _showInboundSSOProfile(profile, FJQC, i=0, count=0): def _showInboundSSOProfile(profile, FJQC, i=0, count=0):
@@ -46424,18 +46586,24 @@ def _processInboundSSOProfileResult(result, returnNameOnly, kvlist, function):
else: else:
writeStdout('inProgress\n') writeStdout('inProgress\n')
# gam create inboundssoprofile [name <SSOProfileName>] def _getInboundSSOModeService(ci):
mode = getChoice(INBOUNDSSO_INPUT_MODE_CHOICE_MAP, defaultChoice='saml', mapChoice=True)
service = ci.inboundSamlSsoProfiles() if mode == 'saml' else ci.inboundOidcSsoProfiles()
return (mode, service)
# gam create inboundssoprofile [saml|oidc] [name <SSOProfileName>]
# [entityid <String>] [loginurl <URL>] [logouturl <URL>] [changepasswordurl <URL>] # [entityid <String>] [loginurl <URL>] [logouturl <URL>] [changepasswordurl <URL>]
# [returnnameonly] # [returnnameonly]
def doCreateInboundSSOProfile(): def doCreateInboundSSOProfile():
ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO) ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
mode, service = _getInboundSSOModeService(ci)
body = {'customer': normalizeChannelCustomerID(GC.Values[GC.CUSTOMER_ID]), body = {'customer': normalizeChannelCustomerID(GC.Values[GC.CUSTOMER_ID]),
'displayName': 'SSO Profile' 'displayName': 'SSO Profile'
} }
returnNameOnly, body = _getInboundSSOProfileArguments(body) returnNameOnly, body = _getInboundSSOProfileArguments(body, mode)
kvlist = [Ent.INBOUND_SSO_PROFILE, body['displayName']] kvlist = [Ent.INBOUND_SSO_PROFILE, body['displayName']]
try: try:
result = callGAPI(ci.inboundSamlSsoProfiles(), 'create', result = callGAPI(service, 'create',
throwReasons=GAPI.CISSO_CREATE_THROW_REASONS, throwReasons=GAPI.CISSO_CREATE_THROW_REASONS,
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS, retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
bailOnInternalError=True, bailOnInternalError=True,
@@ -46446,16 +46614,19 @@ def doCreateInboundSSOProfile():
GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e: GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e:
entityActionFailedWarning(kvlist, str(e)) entityActionFailedWarning(kvlist, str(e))
# gam update inboundssoprofile <SSOProfileItem> # gam update inboundssoprofile [saml|oidc] <SSOProfileItem>
# [entityid <String>] [loginurl <URL>] [logouturl <URL>] [changepasswordurl <URL>] # [entityid <String>] [loginurl <URL>] [logouturl <URL>] [changepasswordurl <URL>]
# [returnnameonly] # [returnnameonly]
def doUpdateInboundSSOProfile(): def doUpdateInboundSSOProfile():
ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO) ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
name = _convertInboundSSOProfileDisplaynameToName(ci, getString(Cmd.OB_STRING)) mode, service = _getInboundSSOModeService(ci)
returnNameOnly, body = _getInboundSSOProfileArguments({}) name = _convertInboundSSOProfileDisplaynameToName(ci, mode, getString(Cmd.OB_STRING))
if not name:
return
returnNameOnly, body = _getInboundSSOProfileArguments({}, mode)
kvlist = [Ent.INBOUND_SSO_PROFILE, name] kvlist = [Ent.INBOUND_SSO_PROFILE, name]
try: try:
result = callGAPI(ci.inboundSamlSsoProfiles(), 'patch', result = callGAPI(service, 'patch',
throwReasons=GAPI.CISSO_UPDATE_THROW_REASONS, throwReasons=GAPI.CISSO_UPDATE_THROW_REASONS,
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS, retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
bailOnInternalError=True, bailOnInternalError=True,
@@ -46468,14 +46639,17 @@ def doUpdateInboundSSOProfile():
GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e: GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e:
entityActionFailedWarning(kvlist, str(e)) entityActionFailedWarning(kvlist, str(e))
# gam delete inboundssoprofile <SSOProfileItem> # gam delete inboundssoprofile [saml|oidc] <SSOProfileItem>
def doDeleteInboundSSOProfile(): def doDeleteInboundSSOProfile():
ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO) ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
name = _convertInboundSSOProfileDisplaynameToName(ci, getString(Cmd.OB_STRING)) mode, service = _getInboundSSOModeService(ci)
name = _convertInboundSSOProfileDisplaynameToName(ci, mode, getString(Cmd.OB_STRING))
if not name:
return
checkForExtraneousArguments() checkForExtraneousArguments()
kvlist = [Ent.INBOUND_SSO_PROFILE, name] kvlist = [Ent.INBOUND_SSO_PROFILE, name]
try: try:
result = callGAPI(ci.inboundSamlSsoProfiles(), 'delete', result = callGAPI(service, 'delete',
throwReasons=GAPI.CISSO_UPDATE_THROW_REASONS, throwReasons=GAPI.CISSO_UPDATE_THROW_REASONS,
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS, retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
bailOnInternalError=True, bailOnInternalError=True,
@@ -46488,33 +46662,54 @@ def doDeleteInboundSSOProfile():
GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e: GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e:
entityActionFailedWarning(kvlist, str(e)) entityActionFailedWarning(kvlist, str(e))
def _getInboundSSOProfile(ci, name): def _getInboundSSOProfileByName(ci, mode, name):
notFound = False
kvlist = [Ent.INBOUND_SSO_PROFILE, name] kvlist = [Ent.INBOUND_SSO_PROFILE, name]
try: if mode in INBOUNDSSO_ALL_SAML:
return callGAPI(ci.inboundSamlSsoProfiles(), 'get', try:
throwReasons=GAPI.CISSO_GET_THROW_REASONS, return callGAPI(ci.inboundSamlSsoProfiles(), 'get',
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS, throwReasons=GAPI.CISSO_GET_THROW_REASONS,
bailOnInternalError=True, retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
name=name) bailOnInternalError=True,
except GAPI.notFound: name=name)
except GAPI.notFound:
notFound = True
except (GAPI.domainNotFound, GAPI.domainCannotUseApis, GAPI.forbidden,
GAPI.badRequest, GAPI.invalid, GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e:
entityActionFailedWarning(kvlist, str(e))
if mode in INBOUNDSSO_ALL_OIDC:
try:
return callGAPI(ci.inboundOidcSsoProfiles(), 'get',
throwReasons=GAPI.CISSO_GET_THROW_REASONS,
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
bailOnInternalError=True,
name=name)
except GAPI.notFound:
notFound = True
except (GAPI.domainNotFound, GAPI.domainCannotUseApis, GAPI.forbidden,
GAPI.badRequest, GAPI.invalid, GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e:
entityActionFailedWarning(kvlist, str(e))
if notFound:
entityActionFailedWarning(kvlist, Msg.DOES_NOT_EXIST) entityActionFailedWarning(kvlist, Msg.DOES_NOT_EXIST)
except (GAPI.domainNotFound, GAPI.domainCannotUseApis, GAPI.forbidden,
GAPI.badRequest, GAPI.invalid, GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e:
entityActionFailedWarning(kvlist, str(e))
return None return None
# gam info inboundssoprofile <SSOProfileItem> [formatjson] # gam info inboundssoprofile [all|saml|oidc] <SSOProfileItem> [formatjson]
def doInfoInboundSSOProfile(): def doInfoInboundSSOProfile():
ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO) ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
name = _convertInboundSSOProfileDisplaynameToName(ci, getString(Cmd.OB_STRING)) mode = getChoice(INBOUNDSSO_OUTPUT_MODE_CHOICE_MAP, defaultChoice='all', mapChoice=True)
name = getString(Cmd.OB_STRING)
FJQC = FormatJSONQuoteChar(formatJSONOnly=True) FJQC = FormatJSONQuoteChar(formatJSONOnly=True)
profile = _getInboundSSOProfile(ci, name) name = _convertInboundSSOProfileDisplaynameToName(ci, mode, name)
if not name:
return
mode = 'saml' if name.startswith('inboundSamlSsoProfiles/') else 'oidc'
profile = _getInboundSSOProfileByName(ci, mode, name)
if profile: if profile:
_showInboundSSOProfile(profile, FJQC) _showInboundSSOProfile(profile, FJQC)
# gam show inboundssoprofile # gam show inboundssoprofile [all|saml|oidc]
# [formatjson] # [formatjson]
# gam print inboundssoprofile [todrive <ToDriveAttribute>*] # gam print inboundssoprofile [all|saml|oidc] [todrive <ToDriveAttribute>*]
# [[formatjson [quotechar <Character>]] # [[formatjson [quotechar <Character>]]
def doPrintShowInboundSSOProfiles(): def doPrintShowInboundSSOProfiles():
ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO) ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
@@ -46522,6 +46717,7 @@ def doPrintShowInboundSSOProfiles():
csvPF = CSVPrintFile(['name']) if Act.csvFormat() else None csvPF = CSVPrintFile(['name']) if Act.csvFormat() else None
FJQC = FormatJSONQuoteChar(csvPF) FJQC = FormatJSONQuoteChar(csvPF)
cfilter = f'customer=="{customer}"' cfilter = f'customer=="{customer}"'
mode = getChoice(INBOUNDSSO_OUTPUT_MODE_CHOICE_MAP, defaultChoice='all', mapChoice=True)
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
if csvPF and myarg == 'todrive': if csvPF and myarg == 'todrive':
@@ -46530,7 +46726,7 @@ def doPrintShowInboundSSOProfiles():
FJQC.GetFormatJSONQuoteChar(myarg, True) FJQC.GetFormatJSONQuoteChar(myarg, True)
if csvPF: if csvPF:
printGettingAllAccountEntities(Ent.INBOUND_SSO_PROFILE, cfilter) printGettingAllAccountEntities(Ent.INBOUND_SSO_PROFILE, cfilter)
profiles = _getInboundSSOProfiles(ci) profiles = _getInboundSSOProfiles(ci, mode)
if not csvPF: if not csvPF:
count = len(profiles) count = len(profiles)
if not FJQC.formatJSON: if not FJQC.formatJSON:
@@ -46600,6 +46796,7 @@ def _processInboundSSOCredentialsResult(result, kvlist, function):
# (pemfile <FileName>)|(generatekey [keysize 1024|2048|4096]) [replaceolddest] # (pemfile <FileName>)|(generatekey [keysize 1024|2048|4096]) [replaceolddest]
def doCreateInboundSSOCredential(): def doCreateInboundSSOCredential():
ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO) ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
mode = 'saml'
profile = None profile = None
generateKey = replaceOldest = False generateKey = replaceOldest = False
keySize = 2048 keySize = 2048
@@ -46607,7 +46804,11 @@ def doCreateInboundSSOCredential():
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
if myarg == 'profile': if myarg == 'profile':
profile = _convertInboundSSOProfileDisplaynameToName(ci, getString(Cmd.OB_STRING)) profile = _convertInboundSSOProfileDisplaynameToName(ci, mode,
getString(Cmd.OB_STRING),
Ent.INBOUND_SSO_CREDENTIALS)
if not profile:
return
elif myarg == 'pemfile': elif myarg == 'pemfile':
pemData = readFile(getString(Cmd.OB_FILE_NAME)) pemData = readFile(getString(Cmd.OB_FILE_NAME))
elif myarg == 'generatekey': elif myarg == 'generatekey':
@@ -46711,15 +46912,24 @@ def doPrintShowInboundSSOCredentials():
ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO) ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
csvPF = CSVPrintFile(['name']) if Act.csvFormat() else None csvPF = CSVPrintFile(['name']) if Act.csvFormat() else None
FJQC = FormatJSONQuoteChar(csvPF) FJQC = FormatJSONQuoteChar(csvPF)
mode = 'saml'
profiles = [] profiles = []
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
if myarg in {'profile', 'profiles'}: if myarg in {'profile', 'profiles'}:
profiles = [_convertInboundSSOProfileDisplaynameToName(ci, profile) for profile in getString(Cmd.OB_STRING_LIST).split(',')] errors = 0
for profile in getEntityList(Cmd.OB_STRING_LIST, shlexSplit=True):
name = _convertInboundSSOProfileDisplaynameToName(ci, mode, profile, Ent.INBOUND_SSO_CREDENTIALS)
if name:
profiles.append(name)
else:
errors += 1
if errors:
return
else: else:
FJQC.GetFormatJSONQuoteChar(myarg, True) FJQC.GetFormatJSONQuoteChar(myarg, True)
if not profiles: if not profiles:
profiles = [p['name'] for p in _getInboundSSOProfiles(ci)] profiles = [p['name'] for p in _getInboundSSOProfiles(ci, mode)]
count = len(profiles) count = len(profiles)
i = 0 i = 0
for profile in profiles: for profile in profiles:
@@ -46812,6 +47022,7 @@ def _getInboundSSOAssignmentByTarget(ci, cd, target):
usageErrorExit(Msg.NO_SSO_PROFILE_ASSIGNED.format(targetType, target)) usageErrorExit(Msg.NO_SSO_PROFILE_ASSIGNED.format(targetType, target))
def _getInboundSSOAssignmentArguments(ci, cd, body): def _getInboundSSOAssignmentArguments(ci, cd, body):
mode = None
rank = 0 rank = 0
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
@@ -46819,9 +47030,19 @@ def _getInboundSSOAssignmentArguments(ci, cd, body):
rank = getInteger(minVal=1) rank = getInteger(minVal=1)
elif myarg == 'mode': elif myarg == 'mode':
body['ssoMode'] = getChoice(INBOUNDSSO_MODE_CHOICE_MAP, mapChoice=True) body['ssoMode'] = getChoice(INBOUNDSSO_MODE_CHOICE_MAP, mapChoice=True)
elif myarg == 'profile': if body['ssoMode'] == 'SAML_SSO':
body['samlSsoInfo'] = {'inboundSamlSsoProfile': mode = 'saml'
_convertInboundSSOProfileDisplaynameToName(ci, getString(Cmd.OB_STRING))} profile = 'inboundSamlSsoProfile'
elif body['ssoMode'] == 'OIDC_SSO':
mode = 'oidc'
profile = 'inboundOidcSsoProfile'
elif mode and myarg == 'profile':
name = _convertInboundSSOProfileDisplaynameToName(ci, mode,
getString(Cmd.OB_STRING),
Ent.INBOUND_SSO_ASSIGNMENT)
if not name:
return None
body['samlSsoInfo'] = {profile: name}
elif myarg == 'neverredirect': elif myarg == 'neverredirect':
body['signInBehavior'] = {'redirectCondition': 'NEVER'} body['signInBehavior'] = {'redirectCondition': 'NEVER'}
elif myarg == 'group': elif myarg == 'group':
@@ -46832,7 +47053,7 @@ def _getInboundSSOAssignmentArguments(ci, cd, body):
unknownArgumentExit() unknownArgumentExit()
if 'ssoMode' not in body: if 'ssoMode' not in body:
missingArgumentExit('mode') missingArgumentExit('mode')
if body['ssoMode'] == 'SAML_SSO' and 'samlSsoInfo' not in body: if mode and 'samlSsoInfo' not in body:
missingArgumentExit('profile') missingArgumentExit('profile')
if 'targetGroup' in body: if 'targetGroup' in body:
if 'targetOrgUnit' in body: if 'targetOrgUnit' in body:
@@ -46870,13 +47091,17 @@ def _processInboundSSOAssignmentResult(result, kvlist, ci, cd, function):
else: else:
entityActionPerformedMessage(kvlist, Msg.ACTION_IN_PROGRESS.format(f'{function} inboundssoassignment')) entityActionPerformedMessage(kvlist, Msg.ACTION_IN_PROGRESS.format(f'{function} inboundssoassignment'))
# gam create inboundssoassignment (group <GroupItem> rank <Number>)|(ou|org|orgunit <OrgUnitItem>) # gam create inboundssoassignment
# (mode sso_off)|(mode saml_sso profile <SSOProfileItem>)(mode domain_wide_saml_if_enabled) [neverredirect] # (group <GroupItem> rank <Number>)|(ou|org|orgunit <OrgUnitItem>)
# (mode sso_off)|(mode saml_sso profile <SSOProfileItem>)|(mode oidc_sso profile <SSOProfileName>}|(mode domain_wide_saml_if_enabled)
# [neverredirect]
def doCreateInboundSSOAssignment(): def doCreateInboundSSOAssignment():
cd = buildGAPIObject(API.DIRECTORY) cd = buildGAPIObject(API.DIRECTORY)
ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO) ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
body = {'customer': normalizeChannelCustomerID(GC.Values[GC.CUSTOMER_ID])} body = {'customer': normalizeChannelCustomerID(GC.Values[GC.CUSTOMER_ID])}
body = _getInboundSSOAssignmentArguments(ci, cd, body) body = _getInboundSSOAssignmentArguments(ci, cd, body)
if not body:
return
kvlist = [Ent.INBOUND_SSO_ASSIGNMENT, body['customer']] kvlist = [Ent.INBOUND_SSO_ASSIGNMENT, body['customer']]
try: try:
result = callGAPI(ci.inboundSsoAssignments(), 'create', result = callGAPI(ci.inboundSsoAssignments(), 'create',
@@ -46890,8 +47115,10 @@ def doCreateInboundSSOAssignment():
GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e: GAPI.systemError, GAPI.permissionDenied, GAPI.internalError, GAPI.serviceNotAvailable) as e:
entityActionFailedWarning(kvlist, str(e)) entityActionFailedWarning(kvlist, str(e))
# gam update inboundssoassignment [(group <GroupItem> rank <Number>)|(ou|org|orgunit <OrgUnitItem>)] # gam update inboundssoassignment <SSOAssignmentName>
# [(mode sso_off)|(mode saml_sso profile <SSOProfileItem>)(mode domain_wide_saml_if_enabled)] [neverredirect] # [(group <GroupItem> rank <Number>)|(ou|org|orgunit <OrgUnitItem>)]
# (mode sso_off)|(mode saml_sso profile <SSOProfileItem>)|(mode oidc_sso profile <SSOProfileName>}|(mode domain_wide_saml_if_enabled)
# [neverredirect]
def doUpdateInboundSSOAssignment(): def doUpdateInboundSSOAssignment():
cd = buildGAPIObject(API.DIRECTORY) cd = buildGAPIObject(API.DIRECTORY)
ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO) ci = buildGAPIObject(API.CLOUDIDENTITY_INBOUND_SSO)
@@ -46948,14 +47175,20 @@ def doInfoInboundSSOAssignment():
return return
name = assignment.get('samlSsoInfo', {}).get('inboundSamlSsoProfile') name = assignment.get('samlSsoInfo', {}).get('inboundSamlSsoProfile')
if name: if name:
profile = _getInboundSSOProfile(ci, name) profile = _getInboundSSOProfileByName(ci, 'saml', name)
if profile: if profile:
assignment['samlSsoInfo']['inboundSamlSsoProfile'] = profile assignment['samlSsoInfo']['inboundSamlSsoProfile'] = profile
else:
name = assignment.get('oidcSsoInfo', {}).get('inboundOidcSsoProfile')
if name:
profile = _getInboundSSOProfileByName(ci, 'oidc', name)
if profile:
assignment['oidcSsoInfo']['inboundOidcSsoProfile'] = profile
_showInboundSSOAssignment(assignment, FJQC, ci, cd) _showInboundSSOAssignment(assignment, FJQC, ci, cd)
# gam show inboundssoassignment # gam show inboundssoassignments
# [formatjson] # [formatjson]
# gam print inboundssoassignment [todrive <ToDriveAttribute>*] # gam print inboundssoassignments [todrive <ToDriveAttribute>*]
# [[formatjson [quotechar <Character>]] # [[formatjson [quotechar <Character>]]
def doPrintShowInboundSSOAssignments(): def doPrintShowInboundSSOAssignments():
cd = buildGAPIObject(API.DIRECTORY) cd = buildGAPIObject(API.DIRECTORY)
@@ -58086,11 +58319,11 @@ def printShowDrivelastModifications(users):
DLP.Finalize(fileIdEntity) DLP.Finalize(fileIdEntity)
if csvPF: if csvPF:
sortTitles = ['User', 'id', 'name'] if fileIdEntity.get('shareddrive') else ['User'] sortTitles = ['User', 'id', 'name'] if fileIdEntity.get('shareddrive') else ['User']
if addCSVData:
sortTitles.extend(sorted(addCSVData.keys()))
sortTitles.extend(['lastModifiedFileId', 'lastModifiedFileName', sortTitles.extend(['lastModifiedFileId', 'lastModifiedFileName',
'lastModifiedFileMimeType', 'lastModifiedFilePath', 'lastModifiedFileMimeType', 'lastModifiedFilePath',
'lastModifyingUser', 'lastModifiedTime']) 'lastModifyingUser', 'lastModifiedTime'])
if addCSVData:
sortTitles.extend(sorted(addCSVData.keys()))
csvPF.SetTitles(sortTitles) csvPF.SetTitles(sortTitles)
csvPF.SetSortAllTitles() csvPF.SetSortAllTitles()
pagesFields = getItemFieldsFromFieldsList('files', fieldsList) pagesFields = getItemFieldsFromFieldsList('files', fieldsList)
@@ -71070,7 +71303,7 @@ def _processMessagesThreads(users, entityType):
try: try:
callGAPI(gmail.users().messages(), function, callGAPI(gmail.users().messages(), function,
throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.INVALID_MESSAGE_ID, GAPI.INVALID, GAPI.INVALID_ARGUMENT, throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.INVALID_MESSAGE_ID, GAPI.INVALID, GAPI.INVALID_ARGUMENT,
GAPI.FAILED_PRECONDITION, GAPI.PERMISSION_DENIED], GAPI.FAILED_PRECONDITION, GAPI.PERMISSION_DENIED, GAPI.QUOTA_EXCEEDED],
userId='me', body=body) userId='me', body=body)
for messageId in body['ids']: for messageId in body['ids']:
mcount += 1 mcount += 1
@@ -71080,7 +71313,7 @@ def _processMessagesThreads(users, entityType):
csvPF.WriteRow({'User': user, entityHeader: messageId, 'action': Act.Performed()}) csvPF.WriteRow({'User': user, entityHeader: messageId, 'action': Act.Performed()})
except GAPI.serviceNotAvailable: except GAPI.serviceNotAvailable:
mcount += bcount mcount += bcount
except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied) as e: except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied, GAPI.quotaExceeded) as e:
_processMessageFailed(user, idsList, f'{str(e)} ({mcount+1}-{mcount+bcount}/{jcount})') _processMessageFailed(user, idsList, f'{str(e)} ({mcount+1}-{mcount+bcount}/{jcount})')
mcount += bcount mcount += bcount
except GAPI.invalidMessageId: except GAPI.invalidMessageId:
@@ -71093,7 +71326,8 @@ def _processMessagesThreads(users, entityType):
_GMAIL_ERROR_REASON_TO_MESSAGE_MAP = {GAPI.NOT_FOUND: Msg.DOES_NOT_EXIST, _GMAIL_ERROR_REASON_TO_MESSAGE_MAP = {GAPI.NOT_FOUND: Msg.DOES_NOT_EXIST,
GAPI.INVALID_MESSAGE_ID: Msg.INVALID_MESSAGE_ID, GAPI.INVALID_MESSAGE_ID: Msg.INVALID_MESSAGE_ID,
GAPI.FAILED_PRECONDITION: Msg.FAILED_PRECONDITION} GAPI.FAILED_PRECONDITION: Msg.FAILED_PRECONDITION,
GAPI.QUOTA_EXCEEDED: Msg.QUOTA_EXCEEDED}
def _callbackProcessMessage(request_id, _, exception): def _callbackProcessMessage(request_id, _, exception):
ri = request_id.splitlines() ri = request_id.splitlines()
@@ -71104,7 +71338,9 @@ def _processMessagesThreads(users, entityType):
csvPF.WriteRow({'User': ri[RI_ENTITY], entityHeader: ri[RI_ITEM], 'action': Act.Performed()}) csvPF.WriteRow({'User': ri[RI_ENTITY], entityHeader: ri[RI_ITEM], 'action': Act.Performed()})
else: else:
http_status, reason, message = checkGAPIError(exception) http_status, reason, message = checkGAPIError(exception)
_processMessageFailed(ri[RI_ENTITY], ri[RI_ITEM], getHTTPError(_GMAIL_ERROR_REASON_TO_MESSAGE_MAP, http_status, reason, message), int(ri[RI_J]), int(ri[RI_JCOUNT])) _processMessageFailed(ri[RI_ENTITY], ri[RI_ITEM],
getHTTPError(_GMAIL_ERROR_REASON_TO_MESSAGE_MAP, http_status, reason, message),
int(ri[RI_J]), int(ri[RI_JCOUNT]))
def _batchProcessMessagesThreads(service, function, user, jcount, messageIds, **kwargs): def _batchProcessMessagesThreads(service, function, user, jcount, messageIds, **kwargs):
svcargs = dict([('userId', 'me'), ('id', None), ('fields', '')]+list(kwargs.items())+GM.Globals[GM.EXTRA_ARGS_LIST]) svcargs = dict([('userId', 'me'), ('id', None), ('fields', '')]+list(kwargs.items())+GM.Globals[GM.EXTRA_ARGS_LIST])
@@ -71202,7 +71438,9 @@ def _processMessagesThreads(users, entityType):
continue continue
if parameters['messageEntity'] is None: if parameters['messageEntity'] is None:
if parameters['maxToProcess'] and jcount > parameters['maxToProcess']: if parameters['maxToProcess'] and jcount > parameters['maxToProcess']:
entityNumEntitiesActionNotPerformedWarning([Ent.USER, user], entityType, jcount, Msg.COUNT_N_EXCEEDS_MAX_TO_PROCESS_M.format(jcount, Act.ToPerform(), parameters['maxToProcess']), i, count) entityNumEntitiesActionNotPerformedWarning([Ent.USER, user], entityType, jcount,
Msg.COUNT_N_EXCEEDS_MAX_TO_PROCESS_M.format(jcount, Act.ToPerform(), parameters['maxToProcess']),
i, count)
continue continue
if not parameters['doIt']: if not parameters['doIt']:
entityNumEntitiesActionNotPerformedWarning([Ent.USER, user], entityType, jcount, Msg.USE_DOIT_ARGUMENT_TO_PERFORM_ACTION, i, count) entityNumEntitiesActionNotPerformedWarning([Ent.USER, user], entityType, jcount, Msg.USE_DOIT_ARGUMENT_TO_PERFORM_ACTION, i, count)
@@ -74451,7 +74689,7 @@ def printShowSignature(users):
try: try:
if selection is None: if selection is None:
sendas = callGAPI(gmail.users().settings().sendAs(), 'get', sendas = callGAPI(gmail.users().settings().sendAs(), 'get',
throwReasons=GAPI.GMAIL_THROW_REASONS, throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.NOT_FOUND],
userId='me', sendAsEmail=user) userId='me', sendAsEmail=user)
else: else:
results = callGAPIitems(gmail.users().settings().sendAs(), 'list', 'sendAs', results = callGAPIitems(gmail.users().settings().sendAs(), 'list', 'sendAs',
@@ -74480,6 +74718,8 @@ def printShowSignature(users):
if field in sendas[item]: if field in sendas[item]:
row[f'smtpMsa{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}{field}'] = sendas[item][field] row[f'smtpMsa{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}{field}'] = sendas[item][field]
csvPF.WriteRowTitles(row) csvPF.WriteRowTitles(row)
except GAPI.notFound as e:
entityActionFailedWarning([Ent.USER, user], str(e), i, count)
except GAPI.serviceNotAvailable: except GAPI.serviceNotAvailable:
userGmailServiceNotEnabledWarning(user, i, count) userGmailServiceNotEnabledWarning(user, i, count)
if csvPF: if csvPF:
@@ -77170,7 +77410,8 @@ MAIN_COMMANDS_WITH_OBJECTS = {
), ),
'clear': 'clear':
(Act.CLEAR, (Act.CLEAR,
{Cmd.ARG_CONTACT: doClearDomainContacts, {Cmd.ARG_ALERTSETTINGS: doClearAlertSettings,
Cmd.ARG_CONTACT: doClearDomainContacts,
} }
), ),
'close': 'close':
@@ -77491,6 +77732,7 @@ MAIN_COMMANDS_WITH_OBJECTS = {
Cmd.ARG_ADMIN: doPrintShowAdmins, Cmd.ARG_ADMIN: doPrintShowAdmins,
Cmd.ARG_ALERT: doPrintShowAlerts, Cmd.ARG_ALERT: doPrintShowAlerts,
Cmd.ARG_ALERTFEEDBACK: doPrintShowAlertFeedback, Cmd.ARG_ALERTFEEDBACK: doPrintShowAlertFeedback,
Cmd.ARG_ALERTSETTINGS: doShowAlertSettings,
Cmd.ARG_BROWSER: doPrintShowBrowsers, Cmd.ARG_BROWSER: doPrintShowBrowsers,
Cmd.ARG_BROWSERTOKEN: doPrintShowBrowserTokens, Cmd.ARG_BROWSERTOKEN: doPrintShowBrowserTokens,
Cmd.ARG_BUILDING: doPrintShowBuildings, Cmd.ARG_BUILDING: doPrintShowBuildings,
@@ -77583,6 +77825,7 @@ MAIN_COMMANDS_WITH_OBJECTS = {
'update': 'update':
(Act.UPDATE, (Act.UPDATE,
{Cmd.ARG_ADMINROLE: doCreateUpdateAdminRoles, {Cmd.ARG_ADMINROLE: doCreateUpdateAdminRoles,
Cmd.ARG_ALERTSETTINGS: doUpdateAlertSettings,
Cmd.ARG_ALIAS: doCreateUpdateAliases, Cmd.ARG_ALIAS: doCreateUpdateAliases,
Cmd.ARG_BROWSER: doUpdateBrowsers, Cmd.ARG_BROWSER: doUpdateBrowsers,
Cmd.ARG_BUILDING: doUpdateBuilding, Cmd.ARG_BUILDING: doUpdateBuilding,

View File

@@ -433,106 +433,6 @@ pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
-----END CERTIFICATE----- -----END CERTIFICATE-----
# Operating CA: GoDaddy
# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority
# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority
# Label: "Starfield Class 2 CA"
# Serial: 0
# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24
# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a
# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58
-----BEGIN CERTIFICATE-----
MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
-----END CERTIFICATE-----
# Operating CA: GoDaddy
# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority
# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority
# Label: "Go Daddy Class 2 CA"
# Serial: 0
# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67
# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4
# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
ReYNnyicsbkqWletNw+vHX/bvZ8=
-----END CERTIFICATE-----
# Operating CA: Sectigo
# Issuer: CN=AAA Certificate Services O=Comodo CA Limited
# Subject: CN=AAA Certificate Services O=Comodo CA Limited
# Label: "Comodo AAA Services root"
# Serial: 1
# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0
# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49
# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4
-----BEGIN CERTIFICATE-----
MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
-----END CERTIFICATE-----
# Operating CA: Sectigo # Operating CA: Sectigo
# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited # Issuer: CN=COMODO Certification Authority O=COMODO CA Limited
# Subject: CN=COMODO Certification Authority O=COMODO CA Limited # Subject: CN=COMODO Certification Authority O=COMODO CA Limited

View File

@@ -75,8 +75,8 @@ IAM_CREDENTIALS = 'iamcredentials'
KEEP = 'keep' KEEP = 'keep'
LICENSING = 'licensing' LICENSING = 'licensing'
LOOKERSTUDIO = 'datastudio' LOOKERSTUDIO = 'datastudio'
MEET = 'meet' MEET_SPACES = 'meet'
MEET_BETA = 'meetbeta' MEET_READONLY = 'meetreadonly'
OAUTH2 = 'oauth2' OAUTH2 = 'oauth2'
ORGPOLICY = 'orgpolicy' ORGPOLICY = 'orgpolicy'
PEOPLE = 'people' PEOPLE = 'people'
@@ -119,6 +119,7 @@ USERINFO_PROFILE_SCOPE = 'https://www.googleapis.com/auth/userinfo.profile' # pr
VAULT_SCOPES = ['https://www.googleapis.com/auth/ediscovery', 'https://www.googleapis.com/auth/ediscovery.readonly'] VAULT_SCOPES = ['https://www.googleapis.com/auth/ediscovery', 'https://www.googleapis.com/auth/ediscovery.readonly']
REQUIRED_SCOPES = [USERINFO_EMAIL_SCOPE, USERINFO_PROFILE_SCOPE] REQUIRED_SCOPES = [USERINFO_EMAIL_SCOPE, USERINFO_PROFILE_SCOPE]
REQUIRED_SCOPES_SET = set(REQUIRED_SCOPES) REQUIRED_SCOPES_SET = set(REQUIRED_SCOPES)
NUM_CLIENT_SCOPES_ERROR_LIMIT = 48
# #
JWT_APIS = { JWT_APIS = {
ACCESSCONTEXTMANAGER: [CLOUD_PLATFORM_SCOPE], ACCESSCONTEXTMANAGER: [CLOUD_PLATFORM_SCOPE],
@@ -266,8 +267,8 @@ _INFO = {
KEEP: {'name': 'Keep API', 'version': 'v1', 'v2discovery': True}, KEEP: {'name': 'Keep API', 'version': 'v1', 'v2discovery': True},
LICENSING: {'name': 'License Manager API', 'version': 'v1', 'v2discovery': True}, LICENSING: {'name': 'License Manager API', 'version': 'v1', 'v2discovery': True},
LOOKERSTUDIO: {'name': 'Looker Studio API', 'version': 'v1', 'v2discovery': True, 'localjson': True}, LOOKERSTUDIO: {'name': 'Looker Studio API', 'version': 'v1', 'v2discovery': True, 'localjson': True},
MEET: {'name': 'Meet API', 'version': 'v2', 'v2discovery': True}, MEET_SPACES: {'name': 'Meet API - Manage/Display Meeting Spaces', 'version': 'v2', 'v2discovery': True},
MEET_BETA: {'name': 'Meet API Beta', 'version': 'v2beta', 'v2discovery': True, 'localjson': True, 'mappedAPI': MEET}, MEET_READONLY: {'name': 'Meet API - Read Meeting Spaces metadata', 'version': 'v2', 'v2discovery': True, 'mappedAPI': MEET_SPACES},
OAUTH2: {'name': 'OAuth2 API', 'version': 'v2', 'v2discovery': False}, OAUTH2: {'name': 'OAuth2 API', 'version': 'v2', 'v2discovery': False},
ORGPOLICY: {'name': 'Organization Policy API', 'version': 'v2', 'v2discovery': True}, ORGPOLICY: {'name': 'Organization Policy API', 'version': 'v2', 'v2discovery': True},
PEOPLE: {'name': 'People API', 'version': 'v1', 'v2discovery': True}, PEOPLE: {'name': 'People API', 'version': 'v1', 'v2discovery': True},
@@ -688,11 +689,15 @@ _SVCACCT_SCOPES = [
'api': LOOKERSTUDIO, 'api': LOOKERSTUDIO,
'subscopes': READONLY, 'subscopes': READONLY,
'scope': 'https://www.googleapis.com/auth/datastudio'}, 'scope': 'https://www.googleapis.com/auth/datastudio'},
{'name': 'Meet API', {'name': 'Meet API - Manage/Display Meeting Spaces',
'api': MEET, 'api': MEET_SPACES,
'subscopes': READONLY, 'subscopes': [],
'scope': 'https://www.googleapis.com/auth/meetings.space.created', 'scope': ['https://www.googleapis.com/auth/meetings.space.created',
'roscope': 'https://www.googleapis.com/auth/meetings.space.readonly'}, 'https://www.googleapis.com/auth/meetings.space.settings']},
{'name': 'Meet API - Read Meeting Spaces metadata',
'api': MEET_READONLY,
'subscopes': [],
'scope': 'https://www.googleapis.com/auth/meetings.space.readonly'},
{'name': 'OAuth2 API', {'name': 'OAuth2 API',
'api': OAUTH2, 'api': OAUTH2,
'subscopes': [], 'subscopes': [],
@@ -843,4 +848,3 @@ def findAPIforScope(scopesList):
if not requiredAPIs: if not requiredAPIs:
requiredAPIs = scopesList requiredAPIs = scopesList
return ' or '.join(requiredAPIs) return ' or '.join(requiredAPIs)

View File

@@ -153,8 +153,6 @@ DOMAIN = 'domain'
DRIVE_DIR = 'drive_dir' DRIVE_DIR = 'drive_dir'
# When retrieving lists of Drive files/folders from API, how many should be retrieved in each chunk # When retrieving lists of Drive files/folders from API, how many should be retrieved in each chunk
DRIVE_MAX_RESULTS = 'drive_max_results' DRIVE_MAX_RESULTS = 'drive_max_results'
# Use Drive V3 beta
DRIVE_V3_BETA = 'drive_v3_beta'
# When processing email messages in batches, how many should be processed in each batch # When processing email messages in batches, how many should be processed in each batch
EMAIL_BATCH_SIZE = 'email_batch_size' EMAIL_BATCH_SIZE = 'email_batch_size'
# Enable Delegated Admin Service Account # Enable Delegated Admin Service Account
@@ -177,8 +175,6 @@ INTER_BATCH_WAIT = 'inter_batch_wait'
LICENSE_MAX_RESULTS = 'license_max_results' LICENSE_MAX_RESULTS = 'license_max_results'
# License SKUs to process # License SKUs to process
LICENSE_SKUS = 'license_skus' LICENSE_SKUS = 'license_skus'
# Use Meet V2 beta
MEET_V2_BETA = 'meet_v2_beta'
# When retrieving lists of Google Group members from API, how many should be retrieved in each chunk # When retrieving lists of Google Group members from API, how many should be retrieved in each chunk
MEMBER_MAX_RESULTS = 'member_max_results' MEMBER_MAX_RESULTS = 'member_max_results'
# CI API Group members max page size when view=BASIC # CI API Group members max page size when view=BASIC
@@ -379,7 +375,6 @@ Defaults = {
DRIVE_DIR: '', DRIVE_DIR: '',
ENFORCE_EXPANSIVE_ACCESS: TRUE, ENFORCE_EXPANSIVE_ACCESS: TRUE,
DRIVE_MAX_RESULTS: '1000', DRIVE_MAX_RESULTS: '1000',
DRIVE_V3_BETA: FALSE,
EMAIL_BATCH_SIZE: '50', EMAIL_BATCH_SIZE: '50',
ENABLE_DASA: FALSE, ENABLE_DASA: FALSE,
ENABLE_GCLOUD_REAUTH: FALSE, ENABLE_GCLOUD_REAUTH: FALSE,
@@ -390,7 +385,6 @@ Defaults = {
INTER_BATCH_WAIT: '0', INTER_BATCH_WAIT: '0',
LICENSE_MAX_RESULTS: '100', LICENSE_MAX_RESULTS: '100',
LICENSE_SKUS: '', LICENSE_SKUS: '',
MEET_V2_BETA: FALSE,
MEMBER_MAX_RESULTS: '200', MEMBER_MAX_RESULTS: '200',
MEMBER_MAX_RESULTS_CI_BASIC: '1000', MEMBER_MAX_RESULTS_CI_BASIC: '1000',
MEMBER_MAX_RESULTS_CI_FULL: '500', MEMBER_MAX_RESULTS_CI_FULL: '500',
@@ -547,7 +541,6 @@ VAR_INFO = {
DRIVE_DIR: {VAR_TYPE: TYPE_DIRECTORY, VAR_ENVVAR: 'GAMDRIVEDIR'}, DRIVE_DIR: {VAR_TYPE: TYPE_DIRECTORY, VAR_ENVVAR: 'GAMDRIVEDIR'},
ENFORCE_EXPANSIVE_ACCESS: {VAR_TYPE: TYPE_BOOLEAN}, ENFORCE_EXPANSIVE_ACCESS: {VAR_TYPE: TYPE_BOOLEAN},
DRIVE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 1000)}, DRIVE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 1000)},
DRIVE_V3_BETA: {VAR_TYPE: TYPE_BOOLEAN},
EMAIL_BATCH_SIZE: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 100)}, EMAIL_BATCH_SIZE: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 100)},
ENABLE_DASA: {VAR_TYPE: TYPE_BOOLEAN, VAR_SIGFILE: 'enabledasa.txt', VAR_SFFT: (FALSE, TRUE)}, ENABLE_DASA: {VAR_TYPE: TYPE_BOOLEAN, VAR_SIGFILE: 'enabledasa.txt', VAR_SFFT: (FALSE, TRUE)},
ENABLE_GCLOUD_REAUTH: {VAR_TYPE: TYPE_BOOLEAN}, ENABLE_GCLOUD_REAUTH: {VAR_TYPE: TYPE_BOOLEAN},
@@ -558,7 +551,6 @@ VAR_INFO = {
INTER_BATCH_WAIT: {VAR_TYPE: TYPE_FLOAT, VAR_LIMITS: (0.0, 60.0)}, INTER_BATCH_WAIT: {VAR_TYPE: TYPE_FLOAT, VAR_LIMITS: (0.0, 60.0)},
LICENSE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (10, 1000)}, LICENSE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (10, 1000)},
LICENSE_SKUS: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, LICENSE_SKUS: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)},
MEET_V2_BETA: {VAR_TYPE: TYPE_BOOLEAN},
MEMBER_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 200)}, MEMBER_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 200)},
MEMBER_MAX_RESULTS_CI_BASIC: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 1000)}, MEMBER_MAX_RESULTS_CI_BASIC: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 1000)},
MEMBER_MAX_RESULTS_CI_FULL: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 500)}, MEMBER_MAX_RESULTS_CI_FULL: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 500)},

View File

@@ -411,6 +411,7 @@ class GamCLArgs():
ARG_ALERTFEEDBACK = 'alertfeedback' ARG_ALERTFEEDBACK = 'alertfeedback'
ARG_ALERTFEEDBACKS = 'alertfeedbacks' ARG_ALERTFEEDBACKS = 'alertfeedbacks'
ARG_ALERTSFEEDBACK = 'alertsfeedback' ARG_ALERTSFEEDBACK = 'alertsfeedback'
ARG_ALERTSETTINGS = 'alertsettings'
ARG_ALIAS = 'alias' ARG_ALIAS = 'alias'
ARG_ALIASES = 'aliases' ARG_ALIASES = 'aliases'
ARG_ALIASDOMAIN = 'aliasdomain' ARG_ALIASDOMAIN = 'aliasdomain'
@@ -1013,6 +1014,7 @@ class GamCLArgs():
OB_PROJECT_ID_ENTITY = 'ProjectIDEntity' OB_PROJECT_ID_ENTITY = 'ProjectIDEntity'
OB_PROPERTY_KEY = 'PropertyKey' OB_PROPERTY_KEY = 'PropertyKey'
OB_PROPERTY_VALUE = 'PropertyValue' OB_PROPERTY_VALUE = 'PropertyValue'
OB_PUBSUB_TOPIC_NAME = 'PubSubTopicName'
OB_QUERY = 'Query' OB_QUERY = 'Query'
OB_QUERY_ITEM = 'QueryItem' OB_QUERY_ITEM = 'QueryItem'
OB_QUERY_LIST = 'QueryList' OB_QUERY_LIST = 'QueryList'

View File

@@ -54,6 +54,7 @@ class GamEntity():
ALERT_ID = 'alri' ALERT_ID = 'alri'
ALERT_FEEDBACK = 'alfb' ALERT_FEEDBACK = 'alfb'
ALERT_FEEDBACK_ID = 'alfi' ALERT_FEEDBACK_ID = 'alfi'
ALERT_SETTINGS = 'alrs'
ALIAS = 'alia' ALIAS = 'alia'
ALIAS_EMAIL = 'alie' ALIAS_EMAIL = 'alie'
ALIAS_TARGET = 'alit' ALIAS_TARGET = 'alit'
@@ -285,10 +286,11 @@ class GamEntity():
MIMETYPE = 'mime' MIMETYPE = 'mime'
MOBILE_DEVICE = 'mobi' MOBILE_DEVICE = 'mobi'
NAME = 'name' NAME = 'name'
NONEDITABLE_ALIAS = 'neal'
NOTE = 'note' NOTE = 'note'
NOTE_ACL = 'nota' NOTE_ACL = 'nota'
NOTES_ACLS = 'naac' NOTES_ACLS = 'naac'
NONEDITABLE_ALIAS = 'neal' NOTIFICATION = 'noti'
OAUTH2_TXT_FILE = 'oaut' OAUTH2_TXT_FILE = 'oaut'
OAUTH2SERVICE_JSON_FILE = 'oau2' OAUTH2SERVICE_JSON_FILE = 'oau2'
ORGANIZATIONAL_UNIT = 'orgu' ORGANIZATIONAL_UNIT = 'orgu'
@@ -414,6 +416,7 @@ class GamEntity():
ALERT_ID: ['Alert IDs', 'Alert ID'], ALERT_ID: ['Alert IDs', 'Alert ID'],
ALERT_FEEDBACK: ['Alert Feedbacks', 'Alert Feedback'], ALERT_FEEDBACK: ['Alert Feedbacks', 'Alert Feedback'],
ALERT_FEEDBACK_ID: ['Alert Feedback IDs', 'Alert Feedback ID'], ALERT_FEEDBACK_ID: ['Alert Feedback IDs', 'Alert Feedback ID'],
ALERT_SETTINGS: ['Alert Settings', 'Alert Settings'],
ALIAS: ['Aliases', 'Alias'], ALIAS: ['Aliases', 'Alias'],
ALIAS_EMAIL: ['Alias Emails', 'Alias Email'], ALIAS_EMAIL: ['Alias Emails', 'Alias Email'],
ALIAS_TARGET: ['Alias Targets', 'Alias Target'], ALIAS_TARGET: ['Alias Targets', 'Alias Target'],
@@ -645,10 +648,11 @@ class GamEntity():
MIMETYPE: ['MIME Types', 'MIME Type'], MIMETYPE: ['MIME Types', 'MIME Type'],
MOBILE_DEVICE: ['Mobile Devices', 'Mobile Device'], MOBILE_DEVICE: ['Mobile Devices', 'Mobile Device'],
NAME: ['Names', 'Name'], NAME: ['Names', 'Name'],
NONEDITABLE_ALIAS: ['Non-Editable Aliases', 'Non-Editable Alias'],
NOTE: ['Notes', 'Note'], NOTE: ['Notes', 'Note'],
NOTE_ACL: ['Note ACLs', 'Note ACL'], NOTE_ACL: ['Note ACLs', 'Note ACL'],
NOTES_ACLS: ["'Note's ACLs", "Note's ACLs"], NOTES_ACLS: ["'Note's ACLs", "Note's ACLs"],
NONEDITABLE_ALIAS: ['Non-Editable Aliases', 'Non-Editable Alias'], NOTIFICATION: ['Notifications', 'Notification'],
OAUTH2_TXT_FILE: ['Client OAuth2 File', 'Client OAuth2 File'], OAUTH2_TXT_FILE: ['Client OAuth2 File', 'Client OAuth2 File'],
OAUTH2SERVICE_JSON_FILE: ['Service Account OAuth2 File', 'Service Account OAuth2 File'], OAUTH2SERVICE_JSON_FILE: ['Service Account OAuth2 File', 'Service Account OAuth2 File'],
ORGANIZATIONAL_UNIT: ['Organizational Units', 'Organizational Unit'], ORGANIZATIONAL_UNIT: ['Organizational Units', 'Organizational Unit'],

View File

@@ -433,6 +433,7 @@ NO_SVCACCT_ACCESS_ALLOWED = 'No Service Account Access allowed'
NO_TRANSFER_LACK_OF_DISK_SPACE = 'Transfer not performed due to lack of target drive space.' NO_TRANSFER_LACK_OF_DISK_SPACE = 'Transfer not performed due to lack of target drive space.'
NO_USAGE_PARAMETERS_DATA_AVAILABLE = 'No usage parameters data available.' NO_USAGE_PARAMETERS_DATA_AVAILABLE = 'No usage parameters data available.'
NO_USER_COUNTS_DATA_AVAILABLE = 'No User counts data available.' NO_USER_COUNTS_DATA_AVAILABLE = 'No User counts data available.'
NUM_SELECTED_CLIENT_SCOPES = '\n{0} scopes are selected, if more than {1} scopes are selected, Google will probably generate a "Something went wrong" error\n'
OAUTH2_GO_TO_LINK_MESSAGE = """ OAUTH2_GO_TO_LINK_MESSAGE = """
Go to the following link in a browser on this computer or on another computer: Go to the following link in a browser on this computer or on another computer:
@@ -464,6 +465,7 @@ PROCESSING_ITEM_N = '{0},0,Processing item {1}\n'
PROCESSING_ITEM_N_OF_M = '{0},0,Processing item {1}/{2}\n' PROCESSING_ITEM_N_OF_M = '{0},0,Processing item {1}/{2}\n'
PROFILE_PHOTO_NOT_FOUND = 'Profile photo not found' PROFILE_PHOTO_NOT_FOUND = 'Profile photo not found'
PROFILE_PHOTO_IS_DEFAULT = 'Profile photo is default' PROFILE_PHOTO_IS_DEFAULT = 'Profile photo is default'
QUOTA_EXCEEDED = 'Quota exceeded'
REASON_ONLY_VALID_WITH_CONTENTRESTRICTIONS_READONLY_TRUE = 'reason only valid with contentrestrictions readonly true' REASON_ONLY_VALID_WITH_CONTENTRESTRICTIONS_READONLY_TRUE = 'reason only valid with contentrestrictions readonly true'
REAUTHENTICATION_IS_NEEDED = 'Reauthentication is needed, please run\n\ngam oauth create' REAUTHENTICATION_IS_NEEDED = 'Reauthentication is needed, please run\n\ngam oauth create'
RECOMMEND_RUNNING_GAM_ROTATE_SAKEY = 'Recommend running "gam rotate sakey" to get a new key\n' RECOMMEND_RUNNING_GAM_ROTATE_SAKEY = 'Recommend running "gam rotate sakey" to get a new key\n'

125
src/tools/ssd.mjs Normal file
View File

@@ -0,0 +1,125 @@
// Node.js script that implements an Appium client which will launch
// Simply Sign Desktop app and log a user in. Once logged in it should
// be possible to use tools like signtool.exe to sign Windows EXE/MSI files
// with the Certum certificate.
import { Key, remote } from 'webdriverio';
import { exec } from 'child_process';
import { TOTP } from 'totp-generator';
async function screenshot(driver, filename) {
// uncomment to save .png screenshots
//await driver.saveScreenshot(filename);
return
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function executeCommand(command) {
try {
let { stdout, stderr } = await exec(command);
return stdout;
} catch (error) {
console.error(`Error executing command: ${command}`);
console.error(`Error details: ${error}`);
throw error;
}
}
async function runSSD() {
const opts = {
port: 4723,
logLevel: "silent",
capabilities: {
platformName: "Windows",
"appium:app": "C:\\Program Files\\Certum\\SimplySign Desktop\\SimplySignDesktop.exe",
"appium:automationName": "Windows",
},
};
let driver;
try {
driver = await remote(opts);
// Github Actions Win ARM64 is stuck on a OOB screen that steals focus
// These enter / escapes should dismiss it.
const runner_arch = process.env.RUNNER_ARCH;
if ( runner_arch === "ARM64" ) {
console.log('Running on ARM64...');
await sleep(3000); // Pause execution for 3 seconds
await screenshot(driver, 'oob1.png');
await driver.sendKeys([Key.Enter]);
await sleep(3000); // Pause execution for 3 seconds
await screenshot(driver, 'oob2.png');
await driver.sendKeys([Key.Enter]);
await sleep(3000); // Pause execution for 3 seconds
await screenshot(driver, 'oob3.png');
await driver.sendKeys([Key.Escape]);
await screenshot(driver, 'oob6.png');
} else {
console.log('NOT running on ARM64');
}
// Execute SSD again to open login dialog
exec('"C:\\Program Files\\Certum\\SimplySign Desktop\\SimplySignDesktop.exe"', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
});
await sleep(3000);
// Login
const windows = await driver.getWindowHandles();
const login_window = windows[0]
await driver.switchWindow(login_window);
await screenshot(driver, 'login01.png');
const id_value = 'jay0lee@gmail.com';
const id_arr = [...id_value];
await driver.sendKeys(id_arr);
await screenshot(driver, 'login02.png');
await driver.sendKeys([Key.Tab]);
// We wait until the last possible second to generate
// our TOTP to ensure it's still valid.
const token_value = TOTP.generate(process.env.TOTP_SECRET, {algorithm: 'SHA-256'}).otp;
const token_arr = [...token_value];
await driver.sendKeys(token_arr);
await screenshot(driver, 'login03.png');
await driver.sendKeys([Key.Enter]);
// TODO: it's expected that on successful login the window
// will close and these screenshots will error out. Figure
// out how to handle that gracefully.
await screenshot(driver, 'login04.png');
await sleep(500);
await screenshot(driver, 'login05.png');
await sleep(500);
await screenshot(driver, 'login06.png');
await sleep(500);
await screenshot(driver, 'login07.png');
await sleep(500);
await screenshot(driver, 'login08.png');
await sleep(500);
await screenshot(driver, 'login09.png');
await sleep(500);
await screenshot(driver, 'login10.png');
await sleep(500);
await screenshot(driver, 'login11.png');
await sleep(500);
await screenshot(driver, 'login12.png');
} catch (error) {
console.error("Error during Appium run:", error.name);
}
// INTENTIONAL Keep driver open so tray icon for Certum doesn't close
// finally {
// if (driver) {
// await driver.deleteSession(); // Close the Appium session
// }
//}
}
runSSD();

View File

@@ -7,6 +7,7 @@
- [Display alerts](#display-alerts) - [Display alerts](#display-alerts)
- [Manage alert feedback](#manage-alert-feedback) - [Manage alert feedback](#manage-alert-feedback)
- [Display alert feedback](#display-alert-feedback) - [Display alert feedback](#display-alert-feedback)
- [Configuring settings](#configuring-settings)
## API documentation ## API documentation
* [Alert Center API](https://developers.google.com/admin-sdk/alertcenter/reference/rest/) * [Alert Center API](https://developers.google.com/admin-sdk/alertcenter/reference/rest/)
@@ -18,6 +19,7 @@
## Definitions ## Definitions
``` ```
<AlertID> ::= <String> <AlertID> ::= <String>
<PubSubTopicName> ::= <String>
<QueryAlert> ::= <String> See: https://developers.google.com/admin-sdk/alertcenter/guides/query-filters <QueryAlert> ::= <String> See: https://developers.google.com/admin-sdk/alertcenter/guides/query-filters
``` ```
## Introduction ## Introduction
@@ -95,3 +97,15 @@ the quote character itself, the column delimiter (comma by default) and new-line
When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output. When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output.
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output. 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.
## Configuring settings
Alert Center can be configured to send notifications to a Google Cloud Pub/Sub topic, but it first requires configuration.
* See https://developers.google.com/workspace/admin/alertcenter/guides/notifications for information.
Gam can be used to display or modify the settings:
```
gam show alertsettings
gam update alertsettings <PubSubTopicName>
gam clear alertsettings
```

View File

@@ -436,6 +436,7 @@
Must match this Python Regular Expression: [a-zA-Z0-9 '"!-]{4,30} Must match this Python Regular Expression: [a-zA-Z0-9 '"!-]{4,30}
<PropertyKey> ::= <String> <PropertyKey> ::= <String>
<PropertyValue> ::= <String> <PropertyValue> ::= <String>
<PubSubTopicName> ::= <String>
<QueryAlert> ::= <String> <QueryAlert> ::= <String>
See: https://developers.google.com/admin-sdk/alertcenter/guides/query-filters See: https://developers.google.com/admin-sdk/alertcenter/guides/query-filters
<QueryBrowser> ::= <String> <QueryBrowser> ::= <String>

View File

@@ -239,6 +239,10 @@ bookmarks.json
gam update chromepolicy chrome.users.ManagedBookmarksSetting json file bookmarks.json orgunit "/Students/ gam update chromepolicy chrome.users.ManagedBookmarksSetting json file bookmarks.json orgunit "/Students/
``` ```
Allowlist the Google Translate extension for the Students OrgUnit
```
gam update chromepolicy chrome.users.apps.InstallType appInstallType ALLOWED app_id chrome:aapbdbdomjkkjkaonfhkkikfgjllcleb ou "/Students"
```
## Delete Chrome policy ## Delete Chrome policy
You can delete a policy for all devices/users within an OU, users with a group or for a specific printer or application within an OU. You can delete a policy for all devices/users within an OU, users with a group or for a specific printer or application within an OU.
@@ -9946,4 +9950,4 @@ chrome.users.ZstdContentEncodingEnabled: Zstd compression.
false: Do not allow zstd-compressed web content. false: Do not allow zstd-compressed web content.
``` ```

View File

@@ -62,15 +62,6 @@ To use the `crostelemetry` commands you must authorize an additional scope:
gam oauth create gam oauth create
``` ```
Many commands come in two forms:
```
gam <CrOSTypeEntity> <Command> ...
gam <Command> cros <CrOSEntity> ...
```
The first form allows more powerful selection of devices with `<CrOSTypeEntity>`.
The second form is backwards compatible with Legacy GAM and selection with `<CrOSEntity>` is limited.
## Definitions ## Definitions
* [`<CrOSTypeEntity>`](Collections-of-ChromeOS-Devices) * [`<CrOSTypeEntity>`](Collections-of-ChromeOS-Devices)
@@ -332,7 +323,6 @@ gam select default config update_cros_ou_with_id true save
``` ```
gam <CrOSTypeEntity> update <CrOSAttribute>+ [quickcrosmove [<Boolean>]] [nobatchupdate] gam <CrOSTypeEntity> update <CrOSAttribute>+ [quickcrosmove [<Boolean>]] [nobatchupdate]
gam update cros <CrOSEntity> <CrOSAttribute>+ [quickcrosmove [<Boolean>]] [nobatchupdate]
``` ```
Google has introduced a new, faster method for moving CrOS devices to a new OU. The `quickcrosmove` option controls which method Gam uses. Google has introduced a new, faster method for moving CrOS devices to a new OU. The `quickcrosmove` option controls which method Gam uses.
@@ -419,8 +409,6 @@ gam update ou csvkmd cros.csv keyfield OU datafield deviceId add croscsvdata dev
gam <CrOSTypeEntity> update action <CrOSAction> [acknowledge_device_touch_requirement] gam <CrOSTypeEntity> update action <CrOSAction> [acknowledge_device_touch_requirement]
[actionbatchsize <Integer>] [actionbatchsize <Integer>]
gam update cros <CrOSEntity> action <CrOSAction> [acknowledge_device_touch_requirement]
[actionbatchsize <Integer>]
``` ```
As of GAM version `6.67.00`, the new API function `batchChangeStatus` replaces the old API function `action`; ChromeOS devices are now processed in batches. As of GAM version `6.67.00`, the new API function `batchChangeStatus` replaces the old API function `action`; ChromeOS devices are now processed in batches.
The batch size defaults to 10, the `actionbatchsize <Integer>` option can be used to set a batch size between 10 and 250. The batch size defaults to 10, the `actionbatchsize <Integer>` option can be used to set a batch size between 10 and 250.
@@ -457,21 +445,18 @@ is configurable from 0 to some large number. If the status reaches `EXPIRED`, `C
wipe_users| wipe_users|
take_a_screenshot take_a_screenshot
gam cros <CrOSTypeEntity> issuecommand command <CrOSCommand> [times_to_check_status <Integer>] [doit] gam <CrOSTypeEntity> issuecommand command <CrOSCommand> [times_to_check_status <Integer>] [doit]
gam issuecommand cros <CrOSEntity> command <CrOSCommand> [times_to_check_status <Integer>] [doit]
``` ```
If the final status is not reached before GAM exits, you can issue the following commands to continue checking the status. If the final status is not reached before GAM exits, you can issue the following commands to continue checking the status.
``` ```
gam cros <CrOSTypeEntity> getcommand commandid <CommandID> [times_to_check_status <Integer>] gam <CrOSTypeEntity> getcommand commandid <CommandID> [times_to_check_status <Integer>]
gam getcommand cros <CrOSEntity> commandid <CommandID> [times_to_check_status <Integer>]
``` ```
### Action Examples ### Action Examples
Remove user profile data from the device; the device will remain enrolled and connected. Remove user profile data from the device; the device will remain enrolled and connected.
User data not synced to the Cloud including Downloads, Android app data and Crostini Linux VMs will be permanently lost. User data not synced to the Cloud including Downloads, Android app data and Crostini Linux VMs will be permanently lost.
Commands with issuecommand directly after gam will work with Legacy GAM & GAM7, whereas commands where the issuecommand is after the cros <CrOSTypeEntity> will work only with GAM7.
``` ```
gam issuecommand cros dd1d659a-0ea4-4e94-905e-4726c7a5f1e9 command wipe_users doit gam cros dd1d659a-0ea4-4e94-905e-4726c7a5f1e9 issuecommand command wipe_users doit
``` ```
Remove profiles using the annotatedAssetID, which is a user editable field, in this example the device has an asset ID of CB1234. Remove profiles using the annotatedAssetID, which is a user editable field, in this example the device has an asset ID of CB1234.
``` ```
@@ -483,14 +468,12 @@ gam cros_queries "asset_id:CB1234,asset_id:CB5678" issuecommand command wipe_use
``` ```
Powerwash the device with serial number 143040348. Powerwash the device with serial number 143040348.
``` ```
gam issuecommand cros query:id:143040348 command remote_powerwash times_to_check_status 10 doit
gam cros_sn 143040348 issuecommand command remote_powerwash times_to_check_status 10 doit gam cros_sn 143040348 issuecommand command remote_powerwash times_to_check_status 10 doit
``` ```
Powerwash all devices in the /StudentCarts OrgUnit. Devices will need to be manually reconnected to WiFi which may mean entering a PSK. Powerwash all devices in the /StudentCarts OrgUnit. Devices will need to be manually reconnected to WiFi which may mean entering a PSK.
Use `wipe_users` if that's going to create too much work for you. Use `wipe_users` if that's going to create too much work for you.
``` ```
gam issuecommand cros "query:orgunitpath:/StudentCarts" command remote_powerwash times_to_check_status 0 doit
gam cros_ou /StudentCarts issuecommand command remote_powerwash times_to_check_status 0 doit gam cros_ou /StudentCarts issuecommand command remote_powerwash times_to_check_status 0 doit
``` ```
## ChromeOS device lists ## ChromeOS device lists
@@ -829,7 +812,6 @@ The `quotechar <Character>` option allows you to choose an alternate quote chara
``` ```
gam <CrOSTypeEntity> info downloadfile latest|<Time> [targetfolder <FilePath>] gam <CrOSTypeEntity> info downloadfile latest|<Time> [targetfolder <FilePath>]
gam info cros <CrOSEntity> downloadfile latest|<Time> [targetfolder <FilePath>]
``` ```
Select the device file to download by its timestamp. Select the device file to download by its timestamp.

View File

@@ -10,6 +10,68 @@ 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.19.02
Update `gam info user <UserItem>` to eliminate 5 second delay when getting license info.
Additional information:
* See: https://github.com/GAM-team/GAM/wiki/Licenses#info-user-performance
### 7.19.01
Updated `gam <UserTypeEntity> print|show signature` to handle the following error
that occurs when an alias is specified.
```
ERROR: 404: notFound - Requested entity was not found.
```
### 7.19.00
Eliminated `drive_v3_beta` and `meet_v2_beta` from `gam.cfg` as the API betas are no longer used.
Updated `Meet API` scopes so that GAM can read metadata about additional Meet spaces.
```
[*] 34) Meet API - Manage/Display Meeting Spaces
[*] 35) Meet API - Read Meeting Spaces metadata
```
### 7.18.07
Updated `gam <UserTypeEntity> print drivelastmodification` to put `addcsvdata` columns
after `User,id,name` rather than after the last column.
### 7.18.06
Updated `gam <UserTypeEntity> delete|modify messages` to improve the handling
of the following error.
```
quotaExceeded - User-rate limit exceeded
```
### 7.18.05
Added support for Inbound SSO OIDC profiles.
Currently, if you enter `gam select <SectionName>` and nothing else on the command line,
GAM performs no action. Now, it will be treated as if you entered:
`gam select <SectionName> save`
Updated to Python 3.13.7.
### 7.18.04
Added commands to display/manage Alert Center Pub/Sub notifications.
* See: https://github.com/GAM-team/GAM/wiki/Alert-Center#configuring-settings
### 7.18.03
Updated `gam oauth create` to give a warning if the number of selected scopes will
probably cause Google to generate a "Something went wrong" error.
### 7.18.02
Upgraded to OpenSSL 3.5.2.
### 7.18.01 ### 7.18.01
Added option `nosystemroles` to `gam print|show adminroles` that causes GAM Added option `nosystemroles` to `gam print|show adminroles` that causes GAM

View File

@@ -252,10 +252,10 @@ 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.18.01 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.19.02 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.5 64-bit final Python 3.13.7 64-bit final
MacOS Sequoia 15.6 x86_64 MacOS Sequoia 15.6.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.18.01 - https://github.com/GAM-team/GAM - pythonsource GAM 7.19.02 - https://github.com/GAM-team/GAM - pythonsource
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.5 64-bit final Python 3.13.7 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

@@ -1,7 +1,9 @@
# Inbound SSO # Inbound SSO
- [Admin Console](#admin-console) - [Setup SSO](https://support.google.com/a/answer/12032922)
- [Admin Console](https://admin.google.com/ac/security/sso)
- [API documentation](#api-documentation) - [API documentation](#api-documentation)
- [Definitions](#definitions) - [Definitions](#definitions)
- [Setup SSO](#setupsso)
- [Manage profiles](#manage-profiles) - [Manage profiles](#manage-profiles)
- [Display profiles](#display-profiles) - [Display profiles](#display-profiles)
- [Manage credentials](#manage-credentials) - [Manage credentials](#manage-credentials)
@@ -9,12 +11,10 @@
- [Manage assignments](#manage-assignments) - [Manage assignments](#manage-assignments)
- [Display assignments](#display-assignments) - [Display assignments](#display-assignments)
## Admin Console
* https://admin.google.com/ac/security/sso
## API documentation ## API documentation
* [Cloud Identity API - Inbound SAML SSO Profiles](https://cloud.google.com/identity/docs/reference/rest/v1beta1/inboundSamlSsoProfiles) * [Cloud Identity API - Inbound SAML SSO Profiles](https://cloud.google.com/identity/docs/reference/rest/v1beta1/inboundSamlSsoProfiles)
* [Cloud Identity API - Inbound SAML SSO Profiles idp Credentials](https://cloud.google.com/identity/docs/reference/rest/v1beta1/inboundSamlSsoProfiles.idpCredentials) * [Cloud Identity API - Inbound SAML SSO Profiles idp Credentials](https://cloud.google.com/identity/docs/reference/rest/v1beta1/inboundSamlSsoProfiles.idpCredentials)
* [Cloud Identity API - Inbound OIDC SSO Profiles](https://cloud.google.com/identity/docs/reference/rest/v1beta1/inboundOidcSsoProfiles)
* [Cloud Identity API - Inbound SSO Assignments](https://cloud.google.com/identity/docs/reference/rest/v1beta1/inboundSsoAssignments) * [Cloud Identity API - Inbound SSO Assignments](https://cloud.google.com/identity/docs/reference/rest/v1beta1/inboundSsoAssignments)
## Definitions ## Definitions
@@ -41,46 +41,68 @@
``` ```
## Manage profiles ## Manage profiles
``` ```
gam create inboundssoprofile [name <SSOProfileDisplayName>] gam create inboundssoprofile [saml|oidc] [name <SSOProfileDisplayName>]
[entityid <String>] [loginurl <URL>] [logouturl <URL>] [changepasswordurl <URL>] [entityid <String>] [loginurl <URL>] [logouturl <URL>] [changepasswordurl <URL>]
[returnnameonly] [returnnameonly]
gam update inboundssoprofile <SSOProfileItem> gam update inboundssoprofile [saml|oidc] <SSOProfileItem>
[entityid <String>] [loginurl <URL>] [logouturl <URL>] [changepasswordurl <URL>] [entityid <String>] [loginurl <URL>] [logouturl <URL>] [changepasswordurl <URL>]
[returnnameonly] [returnnameonly]
``` ```
Select type of profile:
* `saml` - SAML profile; this is the default
* `oidc` - OIDC profile
By default, all fields of the created|updated profile are displayed; By default, all fields of the created|updated profile are displayed;
use the `returnnameonly` option to have GAM display just the profile name of the created|updated profile. use the `returnnameonly` option to have GAM display just the profile name of the created|updated profile.
This will be useful in scripts that create|update a profile and then want to perform subsequent GAM commands that This will be useful in scripts that create|update a profile and then want to perform subsequent GAM commands that
reference the profile. reference the profile.
If `returnnameonly is specified, `inProgress` is returned if the API does not return a complete result. If `returnnameonly` is specified, `inProgress` is returned if the API does not return a complete result.
``` ```
gam delete inboundssoprofile <SSOProfileItem> gam delete inboundssoprofile [saml|oidc] <SSOProfileItem>
``` ```
Select type of profile:
* `saml` - SAML profile; this is the default
* `oidc` - OIDC profile
## Display profiles ## Display profiles
Display a specific profile. Display a specific profile.
``` ```
gam info inboundssoprofile <SSOProfileItem> gam info inboundssoprofile [all|saml|oidc] <SSOProfileItem>
[formatjson] [formatjson]
``` ```
Select type of profile:
* `all` - All profiles are displayed; this is the default
* `saml` - SAML profile
* `oidc` - OIDC profile
By default, Gam displays the information as an indented list of keys and values. By default, Gam displays the information as an indented list of keys and values.
* `formatjson` - Display the fields in JSON format. * `formatjson` - Display the fields in JSON format.
Display all profiles. Display profiles.
``` ```
gam show inboundssoprofiles gam show inboundssoprofiles [all|saml|oidc]
[formatjson] [formatjson]
``` ```
Select profiles to display:
* `all` - All profiles are displayed; this is the default
* `saml` - Display SAML profiles
* `oidc` - Display OIDC profiles
By default, Gam displays the information as an indented list of keys and values. By default, Gam displays the information as an indented list of keys and values.
* `formatjson` - Display the fields in JSON format. * `formatjson` - Display the fields in JSON format.
Display all profiles in a CSV file. Display profiles in a CSV file.
``` ```
gam print inboundssoprofiles [todrive <ToDriveAttribute>*] gam print inboundssoprofiles [all|saml|oidc] [todrive <ToDriveAttribute>*]
[[formatjson [quotechar <Character>]] [[formatjson [quotechar <Character>]]
``` ```
Select profiles to display:
* `all` - All profiles are displayed; this is the default
* `saml` - Display SAML profiles
* `oidc` - Display OIDC profiles
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format, By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format,
* `formatjson` - Display the fields in JSON format. * `formatjson` - Display the fields in JSON format.
@@ -130,10 +152,14 @@ The `quotechar <Character>` option allows you to choose an alternate quote chara
## Manage assignments ## Manage assignments
``` ```
gam create inboundssoassignment (group <GroupItem> rank <Number>)|(ou|org|orgunit <OrgUnitItem>) gam create inboundssoassignment
(mode sso_off)|(mode saml_sso profile <SSOProfileItem>)(mode domain_wide_saml_if_enabled) [neverredirect] (group <GroupItem> rank <Number>)|(ou|org|orgunit <OrgUnitItem>)
gam update inboundssoassignment [(group <GroupItem> rank <Number>)|(ou|org|orgunit <OrgUnitItem>)] (mode sso_off)|(mode saml_sso profile <SSOProfileItem>)(mode domain_wide_saml_if_enabled)
[(mode sso_off)|(mode saml_sso profile <SSOProfileItem>)(mode domain_wide_saml_if_enabled)] [neverredirect] [neverredirect]
gam update inboundssoassignment <SSOAssignmentName>
[(group <GroupItem> rank <Number>)|(ou|org|orgunit <OrgUnitItem>)]
[(mode sso_off)|(mode saml_sso profile <SSOProfileItem>)(mode domain_wide_saml_if_enabled)]
[neverredirect]
gam delete inboundssoassignment <SSOAssignmentSelector> gam delete inboundssoassignment <SSOAssignmentSelector>
``` ```

View File

@@ -3,6 +3,7 @@
- [License Products and SKUs](#license-products-and-skus) - [License Products and SKUs](#license-products-and-skus)
- [Definitions](#definitions) - [Definitions](#definitions)
- [Notes](#Notes) - [Notes](#Notes)
- [Info User Performance](#info-user-performance)
- [Display license counts](#display-license-counts) - [Display license counts](#display-license-counts)
- [Display licenses](#display-licenses) - [Display licenses](#display-licenses)
- [Add licenses](#add-licenses) - [Add licenses](#add-licenses)
@@ -233,6 +234,27 @@ nv:<String>:<String>
``` ```
The first `<String>` is a Product and the second `<String>` is a SKU. The first `<String>` is a Product and the second `<String>` is a SKU.
## Info User Performance
In GAM versions prior 7.18.05, when you did `gam info user`, GAM would make one attempt to get the user's licenses.
If something went wrong, you might not get the complete list.
The License Manager API doesn't have a call that returns the list of licenses that a user has; you have to ask:
```
Does user have license SKU 1?
Does user have license SKU 2?
Does user have license SKU 3?
...
Does user have license SKU 73?
```
If you do a couple of info user commands back to back, you start to run into quota issues.
You can help yourself in the following way: generate a list of all of the SKUs that exist in your workspace.
Then do (example, use actual list): gam config license_skus 1010020028,1010070001, ... save
Now, rather that asking 73 questions per user, GAM will only ask about the license SKUs in the list.
It is much less likely that quota issues will occur,
## Display license counts ## Display license counts
``` ```
gam show licenses gam show licenses

View File

@@ -35,6 +35,9 @@ Select a section from gam.cfg and process a GAM command using values from that s
- Print the variable values for the selected section - Print the variable values for the selected section
- Values are determined in this order: Selected section, DEFAULT section, Program default - Values are determined in this order: Selected section, DEFAULT section, Program default
If you enter `gam select <SectionName>` and nothing else on the command line,
it will be treated as if you entered: `gam select <SectionName> save`
### Display sections ### Display sections
Display all of the sections in gam.cfg and mark the currently selected section with a *. Display all of the sections in gam.cfg and mark the currently selected section with a *.
``` ```

View File

@@ -392,7 +392,7 @@ Your command line will have: `embedimage file1.jpg image1 embedimage file2.jpg i
## Send an email to users ## Send an email to users
``` ```
gam <UserTypeEntity> sendemail [from <EmailAddress>] gam <UserTypeEntity> sendemail from <EmailAddress>
[replyto <EmailAddress>] [replyto <EmailAddress>]
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage] [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
[subject <String>] [subject <String>]
@@ -406,8 +406,6 @@ gam <UserTypeEntity> sendemail [from <EmailAddress>]
``` ```
Emails will be sent to the users in `<UserTypeEntity>`. Emails will be sent to the users in `<UserTypeEntity>`.
By default, emails will be sent from the admin user named in oauth2.txt, override this with the `from <EmailAddress>` option.
When using the Gmail API/SMTP, GAM gets no/little indication as to the status of the message delivery; the from user will get a non-delivery receipt if the message When using the Gmail API/SMTP, GAM gets no/little 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 specified recipients. could not be sent to the specified recipients.

View File

@@ -125,7 +125,7 @@
(foregroundcolor <ColorValue>)| (foregroundcolor <ColorValue>)|
(hidden <Boolean>)| (hidden <Boolean>)|
(notification clear|(email <CalendarEmailNotificatonEventTypeList>))| (notification clear|(email <CalendarEmailNotificatonEventTypeList>))|
(reminder clear|(email|popup <Number>)|(<Number> email|popup))| (reminder clear|(email|popup <Number>)|(<Number> email|popup))*|
(selected <Boolean>)| (selected <Boolean>)|
(summary <String>) (summary <String>)

View File

@@ -464,7 +464,7 @@ gam <UserItem> delete chatmember asadmin <ChatSpace>
Delete members from a chat space by specifying chatmember names, asadmin Delete members from a chat space by specifying chatmember names, asadmin
``` ```
gam <UserItem> remove chatmember members asadmin <ChatMemberList> gam <UserItem> remove chatmember asadmin members <ChatMemberList>
``` ```
### Update a members role in a user's chat space ### Update a members role in a user's chat space

View File

@@ -13,6 +13,7 @@
- [Move with ownership change](#move-with-ownership-change) - [Move with ownership change](#move-with-ownership-change)
- [Complex moves](#complex-moves) - [Complex moves](#complex-moves)
- [Move content of a Shared Drive to another Shared Drive](#move-content-of-a-shared-drive-to-another-shared-drive) - [Move content of a Shared Drive to another Shared Drive](#move-content-of-a-shared-drive-to-another-shared-drive)
- [Move content of a Shared Drive to a My Drive](#move-content-of-a-shared-drive-to-a-my-drive)
## API documentation ## API documentation
* [Drive API - Files](https://developers.google.com/drive/api/v3/reference/files) * [Drive API - Files](https://developers.google.com/drive/api/v3/reference/files)
@@ -673,8 +674,10 @@ gam user user@domain.com move drivefile teamdriveid 0AC_1AB teamdriveparentid 0A
``` ```
If you want the source Shared Drive with ID 0AC_1AB to be contained in a top level folder of the target Shared Drive with ID 0AE_9ZX, omit the `mergewithparent` argument. If you want the source Shared Drive with ID 0AC_1AB to be contained in a top level folder of the target Shared Drive with ID 0AE_9ZX, omit the `mergewithparent` argument.
The folder on the target Shared Drive will have the same name as the name of the source Shared Drive; use the `newfilename <DriveFileName>` to use a different name.
``` ```
gam user user@domain.com move drivefile teamdriveid 0AC_1AB teamdriveparentid 0AE_9ZX gam user user@domain.com move drivefile teamdriveid 0AC_1AB teamdriveparentid 0AE_9ZX
gam user user@domain.com move drivefile teamdriveid 0AC_1AB teamdriveparentid 0AE_9ZX newfilename "Copy of source Shared Drive"
``` ```
### Inter-workspace moves ### Inter-workspace moves
@@ -692,3 +695,21 @@ User: user@domaina.com, Move 1 Drive File/Folder
User: user@domaina.com, Drive Folder: Shared Drive A(<SharedDriveAID>), Retained User: user@domaina.com, Drive Folder: Shared Drive A(<SharedDriveAID>), Retained
``` ```
To get this to work, you must check `Allow people outside of Domain A to access files` on Shared Drive A in domaina.com To get this to work, you must check `Allow people outside of Domain A to access files` on Shared Drive A in domaina.com
## Move content of a Shared Drive to a My Drive
Suppose you have a Shared Drive with ID 0AC_1AB with multiple files and folders, and want to move all of its content to the root of a My Drive.
The following command will change the parents of the top level files and folders from 0AC_1AB to the root of the My Drive; the sub files and folders will move along with their top level folder.
* No permissions are processed.
```
gam user user@domain.com move drivefile teamdriveid 0AC_1AB parentid root mergewithparent
```
If you want the contents of Shared Drive with ID 0AC_1AB to be contained in a top level folder of the My Drive, omit the `mergewithparent` argument.
The folder on the My Drive will have the same name as the name of the Shared Drive; use the `newfilename <DriveFileName>` to use a different name.
```
gam user user@domain.com move drivefile teamdriveid 0AC_1AB parentid root
gam user user@domain.com move drivefile teamdriveid 0AC_1AB parentid root newfilename "Copy of Shared Drive"
```

View File

@@ -11,6 +11,7 @@
- [Change shares to User1 to shares to User2](#change-shares-to-user1-to-shares-to-user2) - [Change shares to User1 to shares to User2](#change-shares-to-user1-to-shares-to-user2)
- [Map All ACLs from an old domain to a new domain](#map-all-acls-from-an-old-domain-to-a-new-domain) - [Map All ACLs from an old domain to a new domain](#map-all-acls-from-an-old-domain-to-a-new-domain)
- [Remove all ACLs for a specific user or group email address](#remove-all-ACLs-for-a-specific-user-or-group-email-address) - [Remove all ACLs for a specific user or group email address](#remove-all-ACLs-for-a-specific-user-or-group-email-address)
- [Remove anyone-anyoneWithLink ACLs](#remove-anyone-anyonewithlink-acls)
## API documentation ## API documentation
* [Drive API - Permissions](https://developers.google.com/drive/api/v3/reference/permissions) * [Drive API - Permissions](https://developers.google.com/drive/api/v3/reference/permissions)
@@ -391,15 +392,15 @@ gam config csv_input_row_filter "permission.type:regex:domain" redirect stdout .
### My Drives ### My Drives
Get My Drive ACLs sharing to that email address: Get My Drive ACLs sharing to that email address:
* Replace <Type> with user or group * Replace `<Type>` with user or group
* Replace email@domain.com with actual address * Replace `email@domain.com` with actual email address
``` ```
gam config auto_batch_min 1 num_threads 20 redirect csv ./MyDriveShares.csv multiprocess redirect stderr - multiprocess all users print filelist fields id,name,mimetype,basicpermissions query "'email@domain.com' in readers or 'email@domain.com' in writers" pm notrole owner type <Type> emailaddress email@domain.com em pmfilter oneitemperrow gam config auto_batch_min 1 num_threads 20 redirect csv ./MyDriveShares.csv multiprocess redirect stderr - multiprocess all users print filelist fields id,name,mimetype,basicpermissions query "'email@domain.com' in readers or 'email@domain.com' in writers" pm notrole owner type <Type> emailaddress email@domain.com em pmfilter oneitemperrow
``` ```
Delete those My Drive ACLs. Delete those My Drive ACLs.
``` ```
gam config num_threads 20 redirect stdout ./DeleteMyDriveShares.txt multiprocess redirect stderr stdout csv MyDriveShares.csv gam user "~Owner" delete drivefleacl "~id" "id:~~permissions.id~~" gam config num_threads 20 redirect stdout ./DeleteMyDriveShares.txt multiprocess redirect stderr stdout csv MyDriveShares.csv gam user "~Owner" delete drivefleacl "~id" "id:~~permission.id~~"
``` ```
Add My Drive ACLs with a different email address and the same role. Add My Drive ACLs with a different email address and the same role.
@@ -411,17 +412,18 @@ gam config num_threads 20 redirect stdout ./AddMyDriveShares.txt multiprocess re
Get an organizer for each Shared Drive Get an organizer for each Shared Drive
``` ```
gam redirect csv ./SharedDriveOrganizers.csv print shareddriveorganizers gam redirect csv ./SharedDriveOrganizers.csv print shareddriveorganizers
```
Get Shared Drive ACLs explicitly sharing to that email address: Get Shared Drive ACLs explicitly sharing to that email address:
* Replace <Type> with user or group * Replace `<Type>` with user or group
* Replace email@domain.com with actual address * Replace `email@domain.com` with actual email address
``` ```
gam config num_threads 20 csv_input_row_filter "organizers:regex:^.+$" redirect csv ./SharedDriveShares.csv multiprocess redirect stderr - multiprocess csv SharedDriveOrganizers.csv gam user "~organizers" print filelist select shareddriveid "~id" fields id,name,mimetype,basicpermissions,driveid showdrivename query "'email@domain.com' in readers or 'email@domain.com' in writers" pm type <Type> emailaddress email@domain.com inherited false em pmfilter oneitemperrow gam config num_threads 20 csv_input_row_filter "organizers:regex:^.+$" redirect csv ./SharedDriveShares.csv multiprocess redirect stderr - multiprocess csv SharedDriveOrganizers.csv gam user "~organizers" print filelist select shareddriveid "~id" fields id,name,mimetype,basicpermissions,driveid showdrivename query "'email@domain.com' in readers or 'email@domain.com' in writers" pm type <Type> emailaddress email@domain.com inherited false em pmfilter oneitemperrow
``` ```
Delete those Shared Drive ACLs. Delete those Shared Drive ACLs.
``` ```
gam config num_threads 20 redirect stdout ./DeleteSharedDriveShares.txt multiprocess redirect stderr stdout csv SharedDriveShares.csv gam user "~Owner" delete drivefleacl "~id" "id:~~permissions.id~~" gam config num_threads 20 redirect stdout ./DeleteSharedDriveShares.txt multiprocess redirect stderr stdout csv SharedDriveShares.csv gam user "~Owner" delete drivefleacl "~id" "id:~~permission.id~~"
``` ```
Add Shared Drive ACLs with a different email address and the same role. Add Shared Drive ACLs with a different email address and the same role.
@@ -429,4 +431,39 @@ Add Shared Drive ACLs with a different email address and the same role.
gam config num_threads 20 redirect stdout ./ReplaceSharedDriveShares.txt multiprocess redirect stderr stdout csv SharedDriveShares.csv gam user "~Owner" add drivefleacl "~id" "~permission.type" newemail@domain.rom role "~permission.role" gam config num_threads 20 redirect stdout ./ReplaceSharedDriveShares.txt multiprocess redirect stderr stdout csv SharedDriveShares.csv gam user "~Owner" add drivefleacl "~id" "~permission.type" newemail@domain.rom role "~permission.role"
``` ```
## Remove anyone-anyoneWithLink ACLs
Here are the queries that will be used in these commands:
* anyone - query "visibility='anyoneCanFind'"
* anyoneWithLink - query "visibility='anyoneWithLink'"
* both - query "(visibility='anyoneCanFind' or visibility='anyoneWithLink')"
### My Drives
Get My Drive anyone/anyoneWithLink ACLs
```
gam config auto_batch_min 1 num_threads 20 redirect csv ./MyDriveShares.csv multiprocess redirect stderr - multiprocess all users print filelist fields id,name,mimetype,basicpermissions <Query> pm type anyone em pmfilter oneitemperrow
```
Delete those My Drive ACLs.
```
gam config num_threads 20 redirect stdout ./DeleteMyDriveShares.txt multiprocess redirect stderr stdout csv MyDriveShares.csv gam user "~Owner" delete drivefleacl "~id" "id:~~permission.id~~"
```
### Shared Drives
Get an organizer for each Shared Drive
```
gam redirect csv ./SharedDriveOrganizers.csv print shareddriveorganizers
```
Get Shared Drive anyone/anyoneWithLink ACLs
```
gam config num_threads 20 csv_input_row_filter "organizers:regex:^.+$" redirect csv ./SharedDriveShares.csv multiprocess redirect stderr - multiprocess csv SharedDriveOrganizers.csv gam user "~organizers" print filelist select shareddriveid "~id" fields id,name,mimetype,basicpermissions,driveid showdrivename <Query> pm type anyone inherited false em pmfilter oneitemperrow
```
Delete those Shared Drive ACLs.
```
gam config num_threads 20 redirect stdout ./DeleteSharedDriveShares.txt multiprocess redirect stderr stdout csv SharedDriveShares.csv gam user "~Owner" delete drivefleacl "~id" "id:~~permission.id~~"
```

View File

@@ -29,9 +29,10 @@ To use these commands you must add the 'Meet API' to your project and update you
gam update project gam update project
gam user user@domain.com update serviceaccount gam user user@domain.com update serviceaccount
... ...
[*] 36) Meet API (supports readonly) [*] 34) Meet API - Manage/Display Meeting Spaces
[*] 35) Meet API - Read Meeting Spaces metadata
``` ```
## Definitions ## Definitions
* [`<UserTypeEntity>`](Collections-of-Users) * [`<UserTypeEntity>`](Collections-of-Users)
``` ```

View File

@@ -16,7 +16,10 @@ Delegated admin service accounts (DASA) are regular [GCP service accounts](https
## Disadvantages ## Disadvantages
* DASA accounts can only be delegated admins. [If a task requires super admin rights to perform](https://support.google.com/a/answer/2405986#:~:text=Only%20super%20administrators%20can...), DASA accounts wont be able to do it. * DASA accounts can only be delegated admins. [If a task requires super admin rights to perform](https://support.google.com/a/answer/2405986#:~:text=Only%20super%20administrators%20can...), DASA accounts wont be able to do it.
Not all Google Admin APIs work with DASA right now. For example, Google Vault API calls will fail with a DASA account; Classroom API calls do not return data. Not all Google Admin APIs work with DASA right no:
* Google Vault API calls will fail with a DASA account
* Classroom API calls do not return data
* Cloud Identity Policies are not available
* DASA is a delegated admin and can make Workspace / Cloud Identity admin API calls, it does not replace domain-wide delegation (DwD) when using GAM7 commands that interact with Gmail, Drive and Calendar user data. * DASA is a delegated admin and can make Workspace / Cloud Identity admin API calls, it does not replace domain-wide delegation (DwD) when using GAM7 commands that interact with Gmail, Drive and Calendar user data.
* GAM7 support for DASA is still experimental and some things may fail. Please report your findings to the [GAM group](https://groups.google.com/g/google-apps-manager). * GAM7 support for DASA is still experimental and some things may fail. Please report your findings to the [GAM group](https://groups.google.com/g/google-apps-manager).

View File

@@ -39,6 +39,16 @@
[Collections of Items](Collections-of-Items) [Collections of Items](Collections-of-Items)
``` ```
<AttendeeStatus> ::= accepted|declined|needsaction|tentative <AttendeeStatus> ::= accepted|declined|needsaction|tentative
<Date> ::=
<Year>-<Month>-<Day> |
(+|-)<Number>(d|w|y) |
never|
today
<Time> ::=
<Year>-<Month>-<Day>(<Space>|T)<Hour>:<Minute>:<Second>[.<MilliSeconds>](Z|(+|-(<Hour>:<Minute>))) |
(+|-)<Number>(m|h|d|w|y) |
never|
now|today
<EmailItem> ::= <EmailAddress>|<UniqueID>|<String> <EmailItem> ::= <EmailAddress>|<UniqueID>|<String>
<EmailItemList> ::= "<EmailItem>(,<EmailItem>)*" <EmailItemList> ::= "<EmailItem>(,<EmailItem>)*"
<EmailAddressList> ::= "<EmailAddess>(,<EmailAddress>)*" <EmailAddressList> ::= "<EmailAddess>(,<EmailAddress>)*"

View File

@@ -3,10 +3,10 @@
Print the current version of Gam with details Print the current version of Gam with details
``` ```
gam version gam version
GAM 7.18.01 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.19.02 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.5 64-bit final Python 3.13.7 64-bit final
MacOS Sequoia 15.6 x86_64 MacOS Sequoia 15.6.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
Time: 2023-06-02T21:10:00-07:00 Time: 2023-06-02T21:10:00-07:00
@@ -15,10 +15,10 @@ 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.18.01 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.19.02 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.5 64-bit final Python 3.13.7 64-bit final
MacOS Sequoia 15.6 x86_64 MacOS Sequoia 15.6.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
Your system time differs from www.googleapis.com by less than 1 second Your system time differs from www.googleapis.com by less than 1 second
@@ -27,15 +27,15 @@ 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.18.01 - https://github.com/GAM-team/GAM - pyinstaller GAM 7.19.02 - https://github.com/GAM-team/GAM - pyinstaller
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.5 64-bit final Python 3.13.7 64-bit final
MacOS Sequoia 15.6 x86_64 MacOS Sequoia 15.6.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
Time: 2023-06-02T21:10:00-07:00 Time: 2023-06-02T21:10:00-07:00
Your system time differs from admin.googleapis.com by less than 1 second Your system time differs from admin.googleapis.com by less than 1 second
OpenSSL 3.4.0 22 Oct Sep 2024 OpenSSL 3.5.2 5 ASug 2025
cryptography 43.0.3 cryptography 43.0.3
filelock 3.16.1 filelock 3.16.1
google-api-python-client 2.149.0 google-api-python-client 2.149.0
@@ -64,7 +64,7 @@ MacOS High Sierra 10.13.6 x86_64
Path: /Users/Admin/bin/gam7 Path: /Users/Admin/bin/gam7
Version Check: Version Check:
Current: 5.35.08 Current: 5.35.08
Latest: 7.18.01 Latest: 7.19.02
echo $? echo $?
1 1
``` ```
@@ -72,7 +72,7 @@ echo $?
Print the current version number without details Print the current version number without details
``` ```
gam version simple gam version simple
7.18.01 7.19.02
``` ```
In Linux/MacOS you can do: In Linux/MacOS you can do:
``` ```
@@ -82,10 +82,10 @@ 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.18.01 - https://github.com/GAM-team/GAM GAM 7.19.02 - https://github.com/GAM-team/GAM
GAM Team <google-apps-manager@googlegroups.com> GAM Team <google-apps-manager@googlegroups.com>
Python 3.13.5 64-bit final Python 3.13.7 64-bit final
MacOS Sequoia 15.6 x86_64 MacOS Sequoia 15.6.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
Time: 2023-06-02T21:10:00-07:00 Time: 2023-06-02T21:10:00-07:00