mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-22 15:11:37 +00:00
Compare commits
10 Commits
20250624.2
...
20250626.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4fd7172f7a | ||
|
|
e670cf3e6a | ||
|
|
e305cc0789 | ||
|
|
d7b9d43c63 | ||
|
|
75e3ae8144 | ||
|
|
130a483e4d | ||
|
|
cbd04bcec4 | ||
|
|
a51b245015 | ||
|
|
64356a9736 | ||
|
|
c18375abb7 |
8
.github/workflows/build.yml
vendored
8
.github/workflows/build.yml
vendored
@@ -457,10 +457,6 @@ jobs:
|
||||
- name: Custom wheels for Win arm64
|
||||
if: runner.os == 'Windows' && runner.arch == 'ARM64'
|
||||
run: |
|
||||
latest_lxml_whl=$(curl https://api.github.com/repos/GAM-team/lxml-wheel/releases/latest -s | jq -r .assets.[0].browser_download_url)
|
||||
echo "Downloading ${latest_lxml_whl}..."
|
||||
curl -O -L "$latest_lxml_whl"
|
||||
"$PYTHON" -m pip install lxml*.whl
|
||||
latest_crypt_whl=$(curl https://api.github.com/repos/jay0lee/cryptography/releases/latest -s | jq -r .assets.[0].browser_download_url)
|
||||
echo "Downloading ${latest_crypt_whl}..."
|
||||
curl -O -L "$latest_crypt_whl"
|
||||
@@ -810,7 +806,7 @@ jobs:
|
||||
echo "Created shared drive ${driveid}"
|
||||
$gam create user $newuser firstname GHA lastname $JID displayname "Github Actions ${JID}" password random recoveryphone 12125121110 recoveryemail jay0lee@gmail.com gha.jid $JID languages en+,en-GB- ou "${newou}"
|
||||
$gam user $newuser add license workspaceenterpriseplus
|
||||
$gam user $newuser update photo https://dummyimage.com/400x600/000/fff
|
||||
$gam user $newuser update photo https://dummyimage.com/98x98/000/fff.jpg
|
||||
$gam user $newuser get photo
|
||||
$gam user $newuser delete photo
|
||||
$gam create alias $newalias user $newuser
|
||||
@@ -920,7 +916,7 @@ jobs:
|
||||
$gam config enable_dasa true save
|
||||
$gam print users query "gha.jid=$JID" | $gam csv - gam delete user ~primaryEmail || if [ $? != 50 ]; then exit $?; fi # expect a 50 return code (vault hold on user)
|
||||
$gam print mobile
|
||||
$gam print devices
|
||||
$gam print devices clientstates
|
||||
$gam print browsers
|
||||
$gam print cros allfields orderby serialnumber
|
||||
$gam show crostelemetry storagepercentonly
|
||||
|
||||
@@ -4124,6 +4124,7 @@ gam print devices [todrive <ToDriveAttribute>*]
|
||||
[orderby <DeviceOrderByFieldName> [ascending|descending]]
|
||||
[all|company|personal|nocompanydevices|nopersonaldevices]
|
||||
[nodeviceusers|oneuserperrow]
|
||||
[clientstates]
|
||||
[formatjson [quotechar <Character>]]
|
||||
[showitemcountonly]
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
7.10.06
|
||||
|
||||
"gam print devices clientstates" to include client states in device output
|
||||
|
||||
7.10.05
|
||||
|
||||
Google renamed an error: cannotModifyInheritedTeamDrivePermission became cannotModifyInheritedPermission.
|
||||
|
||||
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
|
||||
"""
|
||||
|
||||
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
||||
__version__ = '7.10.05'
|
||||
__version__ = '7.10.06'
|
||||
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
||||
|
||||
#pylint: disable=wrong-import-position
|
||||
@@ -29508,6 +29508,7 @@ def getCIDeviceEntity():
|
||||
return ([], ci, customer, False)
|
||||
|
||||
DEVICE_USERNAME_PATTERN = re.compile(r'^(devices/.+)/(deviceUsers/.+)$')
|
||||
DEVICE_USERNAME_CLIENT_STATE_PATTERN = re.compile(r'^(devices/.+/deviceUsers/.+)/clientStates/(.+)$')
|
||||
DEVICE_USERNAME_FORMAT_REQUIRED = 'devices/<String>/deviceUsers/<String>'
|
||||
def getCIDeviceUserEntity():
|
||||
ci = buildGAPICIDeviceServiceObject()
|
||||
@@ -29956,6 +29957,7 @@ DEVICE_ORDERBY_CHOICE_MAP = {
|
||||
# [orderby <DeviceOrderByFieldName> [ascending|descending]]
|
||||
# [all|company|personal|nocompanydevices|nopersonaldevices]
|
||||
# [nodeviceusers|oneuserperrow]
|
||||
# [clientstates]
|
||||
# [formatjson [quotechar <Character>]]
|
||||
# [showitemcountonly]
|
||||
def doPrintCIDevices():
|
||||
@@ -29971,6 +29973,7 @@ def doPrintCIDevices():
|
||||
queries = [None]
|
||||
view, entityType = DEVICE_VIEW_CHOICE_MAP['all']
|
||||
getDeviceUsers = True
|
||||
getClientStates = False
|
||||
oneUserPerRow = showItemCountOnly = False
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
@@ -29986,6 +29989,8 @@ def doPrintCIDevices():
|
||||
view, entityType = DEVICE_VIEW_CHOICE_MAP[myarg]
|
||||
elif myarg == 'nodeviceusers':
|
||||
getDeviceUsers = False
|
||||
elif myarg == 'clientstates':
|
||||
getClientStates = True
|
||||
elif myarg in {'oneuserperrow', 'oneitemperrow'}:
|
||||
getDeviceUsers = oneUserPerRow = True
|
||||
elif getFieldsList(myarg, DEVICE_FIELDS_CHOICE_MAP, fieldsList, initialField='name'):
|
||||
@@ -30004,14 +30009,16 @@ def doPrintCIDevices():
|
||||
if FJQC.formatJSON and oneUserPerRow:
|
||||
csvPF.SetJSONTitles(['name', 'user.name', 'JSON'])
|
||||
itemCount = 0
|
||||
throwReasons = [GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED]
|
||||
retryReasons = GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS
|
||||
for query in queries:
|
||||
printGettingAllAccountEntities(entityType, query)
|
||||
pageMessage = getPageMessage()
|
||||
try:
|
||||
devices = callGAPIpages(ci.devices(), 'list', 'devices',
|
||||
pageMessage=pageMessage,
|
||||
throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
throwReasons=throwReasons,
|
||||
retryReasons=retryReasons,
|
||||
customer=customer, filter=query,
|
||||
orderBy=OBY.orderBy, view=view, fields=fields, pageSize=100)
|
||||
if showItemCountOnly:
|
||||
@@ -30030,10 +30037,27 @@ def doPrintCIDevices():
|
||||
try:
|
||||
deviceUsers = callGAPIpages(ci.devices().deviceUsers(), 'list', 'deviceUsers',
|
||||
pageMessage=pageMessage,
|
||||
throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
throwReasons=throwReasons,
|
||||
retryReasons=retryReasons,
|
||||
customer=customer, filter=query, parent=parent,
|
||||
orderBy=OBY.orderBy, fields=userFields, pageSize=20)
|
||||
if getClientStates:
|
||||
printGettingAllAccountEntities(Ent.DEVICE_USER_CLIENT_STATE, None)
|
||||
states = callGAPIpages(ci.devices().deviceUsers().clientStates(), 'list', 'clientStates',
|
||||
pageMessage=pageMessage,
|
||||
throwReasons=throwReasons,
|
||||
retryReasons=retryReasons,
|
||||
customer=customer, filter=query, parent='devices/-/deviceUsers/-')
|
||||
for state in states:
|
||||
mg = DEVICE_USERNAME_CLIENT_STATE_PATTERN.match(state['name'])
|
||||
if mg:
|
||||
du = mg.group(1)
|
||||
state_name = mg.group(2)
|
||||
for i in range(len(deviceUsers)):
|
||||
if deviceUsers[i]['name'] == du:
|
||||
deviceUsers[i].setdefault('clientstates', {})
|
||||
deviceUsers[i]['clientstates'][state_name] = state
|
||||
break
|
||||
for deviceUser in deviceUsers:
|
||||
mg = DEVICE_USERNAME_PATTERN.match(deviceUser['name'])
|
||||
if mg:
|
||||
|
||||
@@ -107,6 +107,8 @@ _SKUS = {
|
||||
'product': '101047', 'aliases': ['aisecurity'], 'displayName': 'AI Security'},
|
||||
'1010470007': {
|
||||
'product': '101047', 'aliases': ['aimeetingsandmessaging'], 'displayName': 'AI Meetings and Messaging'},
|
||||
'1010470008': {
|
||||
'product': '101047', 'aliases': ['geminiultra', ], 'displayName': 'Google AI Ultra for Business'},
|
||||
'1010490001': {
|
||||
'product': '101049', 'aliases': ['eeu'], 'displayName': 'Endpoint Education Upgrade'},
|
||||
'1010500001': {
|
||||
|
||||
@@ -211,6 +211,7 @@ gam print devices [todrive <ToDriveAttribute>*]
|
||||
[orderby <DeviceOrderByFieldName> [ascending|descending]]
|
||||
[all|company|personal|nocompanydevices|nopersonaldevices]
|
||||
[nodeviceusers|oneuserperrow]
|
||||
[clientstates]
|
||||
[formatjson [quotechar <Character>]]
|
||||
```
|
||||
By default, all devices are displayed; use the query options to limit the display.
|
||||
|
||||
@@ -10,6 +10,15 @@ 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
|
||||
|
||||
### 7.10.06
|
||||
|
||||
Added option `clientstates` to `gam print devices` to include client states in device output.
|
||||
|
||||
### 7.10.05
|
||||
|
||||
Google renamed an error: cannotModifyInheritedTeamDrivePermission became cannotModifyInheritedPermission.
|
||||
GAM will now handle the new error.
|
||||
|
||||
### 7.10.04
|
||||
|
||||
Updated `gam report <ActivityApplicationName>` to accept accept application names as defined
|
||||
|
||||
@@ -251,7 +251,7 @@ writes the credentials into the file oauth2.txt.
|
||||
admin@server:/Users/admin$ rm -f /Users/admin/GAMConfig/oauth2.txt
|
||||
admin@server:/Users/admin$ gam version
|
||||
WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
|
||||
GAM 7.10.04 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM 7.10.06 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.13.5 64-bit final
|
||||
MacOS Sequoia 15.5 x86_64
|
||||
@@ -989,7 +989,7 @@ writes the credentials into the file oauth2.txt.
|
||||
C:\>del C:\GAMConfig\oauth2.txt
|
||||
C:\>gam version
|
||||
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
|
||||
GAM 7.10.04 - https://github.com/GAM-team/GAM - pythonsource
|
||||
GAM 7.10.06 - https://github.com/GAM-team/GAM - pythonsource
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.13.5 64-bit final
|
||||
Windows-10-10.0.17134 AMD64
|
||||
|
||||
@@ -1,19 +1,12 @@
|
||||
# Using GAM7 with a delegated admin service account
|
||||
- [Thanks](#thanks)
|
||||
- [Introduction](#introduction)
|
||||
- [Advantages](#advantages)
|
||||
- [Disadvantages](#disadvantages)
|
||||
- [Setup Steps](#setup-steps)
|
||||
|
||||
## Thanks
|
||||
|
||||
Thanks to Jay Lee for the original version of this document.
|
||||
|
||||
## Introduction
|
||||
Delegated admin service accounts (DASA) are regular [GCP service accounts](https://cloud.google.com/iam/docs/service-accounts#what_are_service_accounts) that are granted a Workspace [delegated admin role](https://support.google.com/a/answer/33325). Service accounts have an email address like `gam-project-xuw-sp1-c4b@gam-project-xuw-sp1-c4b.iam.gserviceaccount.com` and are not part of a Workspace or Cloud Identity domain even if they are owned by a project in the domain’s organization. Service accounts cannot login to Google web services interactively, they are only able to call Google APIs.
|
||||
|
||||
GAM7 version 6.50.00 or higher is required.
|
||||
|
||||
## Advantages
|
||||
* DASA accounts don’t require a Workspace or Cloud Identity license.
|
||||
* DASA accounts don’t have a password login that can be phished or captured, they use [RSA private keys](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) to sign authentication requests which makes them very secure. You should however [rotate the key](https://jaylee.us/qwm) on a regular basis and keep it safe and secured!
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Print the current version of Gam with details
|
||||
```
|
||||
gam version
|
||||
GAM 7.10.04 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM 7.10.06 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.13.5 64-bit final
|
||||
MacOS Sequoia 15.5 x86_64
|
||||
@@ -15,7 +15,7 @@ Time: 2023-06-02T21:10:00-07:00
|
||||
Print the current version of Gam with details and time offset information
|
||||
```
|
||||
gam version timeoffset
|
||||
GAM 7.10.04 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM 7.10.06 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.13.5 64-bit final
|
||||
MacOS Sequoia 15.5 x86_64
|
||||
@@ -27,7 +27,7 @@ Your system time differs from www.googleapis.com by less than 1 second
|
||||
Print the current version of Gam with extended details and SSL information
|
||||
```
|
||||
gam version extended
|
||||
GAM 7.10.04 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM 7.10.06 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.13.5 64-bit final
|
||||
MacOS Sequoia 15.5 x86_64
|
||||
@@ -64,7 +64,7 @@ MacOS High Sierra 10.13.6 x86_64
|
||||
Path: /Users/Admin/bin/gam7
|
||||
Version Check:
|
||||
Current: 5.35.08
|
||||
Latest: 7.10.04
|
||||
Latest: 7.10.06
|
||||
echo $?
|
||||
1
|
||||
```
|
||||
@@ -72,7 +72,7 @@ echo $?
|
||||
Print the current version number without details
|
||||
```
|
||||
gam version simple
|
||||
7.10.04
|
||||
7.10.06
|
||||
```
|
||||
In Linux/MacOS you can do:
|
||||
```
|
||||
@@ -82,7 +82,7 @@ echo $VER
|
||||
Print the current version of Gam and address of this Wiki
|
||||
```
|
||||
gam help
|
||||
GAM 7.10.04 - https://github.com/GAM-team/GAM
|
||||
GAM 7.10.06 - https://github.com/GAM-team/GAM
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.13.5 64-bit final
|
||||
MacOS Sequoia 15.5 x86_64
|
||||
|
||||
Reference in New Issue
Block a user