mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-20 22:21:37 +00:00
Compare commits
2 Commits
20241026.0
...
20241027.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4e3f25c1e | ||
|
|
bb198c8c1a |
@@ -282,7 +282,7 @@
|
||||
<GIGroupAlias> ::= <EmailAddress>
|
||||
<GIGroupItem> ::= <EmailAddress>|<UniqueID>|groups/<String>
|
||||
<CIGroupType> ::= customer|group|other|serviceaccount|user
|
||||
<CIPolicyName> ::= policies/<String>
|
||||
<CIPolicyName> ::= policies/<String>|settings/<String>|<String>
|
||||
<ClassroomInvitationID> ::= <String>
|
||||
<ClientID> ::= <String>
|
||||
<CommandID> ::= <String>
|
||||
|
||||
@@ -19,7 +19,7 @@ gam oauth create
|
||||
|
||||
## Definitions
|
||||
```
|
||||
<CIPolicyName> ::= policies/<String>
|
||||
<CIPolicyName> ::= policies/<String>|settings/<String>|<String>
|
||||
<CIPolicyNameList> ::= "<CIPolicyName>(,<CIPolicyName>)*"
|
||||
<CIPolicyNameEntity> ::=
|
||||
<CIPolicyNameList> | <FileSelector> | <CSVFileSelector>
|
||||
@@ -27,17 +27,19 @@ gam oauth create
|
||||
|
||||
## Policies
|
||||
These are the supported policies GAM can show today.
|
||||
|
||||
See: https://cloud.google.com/identity/docs/concepts/supported-policy-api-settings
|
||||
```
|
||||
user_takeout_status (is takeout enabled for service)
|
||||
blogger
|
||||
books
|
||||
location_history
|
||||
maps
|
||||
pay
|
||||
photos
|
||||
play
|
||||
play_console
|
||||
youtube
|
||||
blogger.user_takeout
|
||||
books.user_takeout
|
||||
location_history.user_takeout
|
||||
maps.user_takeout
|
||||
pay.user_takeout
|
||||
photos.user_takeout
|
||||
play.user_takeout
|
||||
play_console.user_takeout
|
||||
youtube.user_takeout
|
||||
service_status (is service enabled)
|
||||
ad_manager
|
||||
ads
|
||||
@@ -311,39 +313,53 @@ workspace_marketplace.apps_allowlist
|
||||
Display selected policies.
|
||||
```
|
||||
gam info policies <CIPolicyEntity>
|
||||
[nowarnings]
|
||||
[nowarnings] [noappnames]
|
||||
[formatjson]
|
||||
```
|
||||
|
||||
Select policies::
|
||||
* `polices/<String>` - A policy name, `policies/ahv4hg7qc24kvaghb7zihwf4riid4`
|
||||
* `settings/<String>` - A policy setting type, `settings/workspace_marketplace.apps_allowlist'
|
||||
* `<String>` - A policy setting type, `workspace_marketplace.apps_allowlist'
|
||||
|
||||
By default, policy warnings are displayed, use the 'nowarnings` option to suppress their display.
|
||||
|
||||
By default, additional API calls are made for `settings/workspace_marketplace.apps_allowlist`
|
||||
to get the application name for the application ID. Use option `noappnames` to suppress these calls.
|
||||
|
||||
By default, Gam displays the information as an indented list of keys and values.
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
|
||||
Display all or filtered policies.
|
||||
```
|
||||
gam show policies
|
||||
[filter <String>] [nowarnings]
|
||||
[filter <String>] [nowarnings] [noappnames]
|
||||
[formatjson]
|
||||
```
|
||||
By default, all policies are displayed.
|
||||
* `filter <String>` - Display filtered policies, See https://github.com/taers232c/GAMADV-XTD3/wiki/Cloud-Identity-Policies
|
||||
* `filter <String>` - Display filtered policies, See https://cloud.google.com/identity/docs/reference/rest/v1beta1/policies/list
|
||||
|
||||
By default, policy warnings are displayed, use the 'nowarnings` option to suppress their display.
|
||||
|
||||
By default, additional API calls are made for `settings/workspace_marketplace.apps_allowlist`
|
||||
to get the application name for the application ID. Use option `noappnames` to suppress these calls.
|
||||
|
||||
By default, Gam displays the information as an indented list of keys and values.
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
|
||||
```
|
||||
gam print policies [todrive <ToDriveAttribute>*]
|
||||
[filter <String>] [nowarnings]
|
||||
[filter <String>] [nowarnings] [noappnames]
|
||||
[formatjson [quotechar <Character>]]
|
||||
```
|
||||
By default, all policies are displayed:
|
||||
* `filter <String>` - Display filtered policies, See https://github.com/taers232c/GAMADV-XTD3/wiki/Cloud-Identity-Policies
|
||||
* `filter <String>` - Display filtered policies, See https://cloud.google.com/identity/docs/reference/rest/v1beta1/policies/list
|
||||
|
||||
By default, policy warnings are displayed, use the 'nowarnings` option to suppress their display.
|
||||
|
||||
By default, additional API calls are made for `settings/workspace_marketplace.apps_allowlist`
|
||||
to get the application name for the application ID. Use option `noappnames` to suppress these calls.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
@@ -10,6 +10,18 @@ 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.00.32
|
||||
|
||||
Updated `gam info policies` to accept different policy specifications:
|
||||
* `polices/<String>` - A policy name, `policies/ahv4hg7qc24kvaghb7zihwf4riid4`
|
||||
* `settings/<String>` - A policy setting type, `settings/workspace_marketplace.apps_allowlist'
|
||||
* `<String>` - A policy setting type, `workspace_marketplace.apps_allowlist'
|
||||
|
||||
### 7.00.31
|
||||
|
||||
Updated `gam info|print|show policies` to make additional API calls for `settings/workspace_marketplace.apps_allowlist`
|
||||
to get the application name for the application ID. Use option `noappnames` to suppress these calls.
|
||||
|
||||
### 7.00.30
|
||||
|
||||
Added command to display selected Cloud Identity policies.
|
||||
|
||||
@@ -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.00.30 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM 7.00.32 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.13.0 64-bit final
|
||||
MacOS Sonoma 14.5 x86_64
|
||||
@@ -923,7 +923,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
|
||||
GAM7 7.00.30 - https://github.com/GAM-team/GAM - pythonsource
|
||||
GAM7 7.00.32 - https://github.com/GAM-team/GAM - pythonsource
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.13.0 64-bit final
|
||||
Windows-10-10.0.17134 AMD64
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Print the current version of Gam with details
|
||||
```
|
||||
gam version
|
||||
GAM 7.00.30 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM 7.00.32 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.13.0 64-bit final
|
||||
MacOS Sonoma 14.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.00.30 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM 7.00.32 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.13.0 64-bit final
|
||||
MacOS Sonoma 14.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.00.30 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM 7.00.32 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.13.0 64-bit final
|
||||
MacOS Sonoma 14.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.00.30
|
||||
Latest: 7.00.32
|
||||
echo $?
|
||||
1
|
||||
```
|
||||
@@ -72,7 +72,7 @@ echo $?
|
||||
Print the current version number without details
|
||||
```
|
||||
gam version simple
|
||||
7.00.30
|
||||
7.00.32
|
||||
```
|
||||
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.00.30 - https://github.com/GAM-team/GAM
|
||||
GAM 7.00.32 - https://github.com/GAM-team/GAM
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.13.0 64-bit final
|
||||
MacOS Sonoma 14.5 x86_64
|
||||
|
||||
@@ -378,7 +378,7 @@ If an item contains spaces, it should be surrounded by ".
|
||||
<GIGroupAlias> ::= <EmailAddress>
|
||||
<GIGroupItem> ::= <EmailAddress>|<UniqueID>|groups/<String>
|
||||
<CIGroupType> ::= customer|group|other|serviceaccount|user
|
||||
<CIPolicyName> ::= policies/<String>
|
||||
<CIPolicyName> ::= policies/<String>|settings/<String>|<String>
|
||||
<ClassroomInvitationID> ::= <String>
|
||||
<ClientID> ::= <String>
|
||||
<CommandID> ::= <String>
|
||||
@@ -4076,14 +4076,13 @@ gam update deviceuserstate <DeviceUserEntity> [clientid <String>]
|
||||
# Cloud Identity Policies
|
||||
|
||||
gam info policies <CIPolicyNameEntity>
|
||||
[nowarnings]
|
||||
[nowarnings] [noappnames]
|
||||
[formatjson]
|
||||
|
||||
gam print policies [todrive <ToDriveAttribute>*]
|
||||
[filter <String>] [nowarnings]
|
||||
[filter <String>] [nowarnings] [noappnames]
|
||||
[formatjson [quotechar <Character>]]
|
||||
gam show policies
|
||||
[filter <String>] [nowarnings]
|
||||
[filter <String>] [nowarnings] [noappnames]
|
||||
[formatjson]
|
||||
|
||||
# Inbound SSO
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
7.00.32
|
||||
|
||||
Updated `gam info policies` to accept different policy specifications:
|
||||
* `polices/<String>` - A policy name, `policies/ahv4hg7qc24kvaghb7zihwf4riid4`
|
||||
* `settings/<String>` - A policy setting type, `settings/workspace_marketplace.apps_allowlist'
|
||||
* `<String>` - A policy setting type, `workspace_marketplace.apps_allowlist'
|
||||
|
||||
7.00.31
|
||||
|
||||
Updated `gam info|print|show policies` to make additional API calls for `settings/workspace_marketplace.apps_allowlist`
|
||||
to get the application name for the application ID. Use option `noappnames` to suppress these calls.
|
||||
|
||||
7.00.30
|
||||
|
||||
Added command to display selected Cloud Identity policies.
|
||||
|
||||
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
|
||||
"""
|
||||
|
||||
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
||||
__version__ = '7.00.30'
|
||||
__version__ = '7.00.32'
|
||||
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
||||
|
||||
#pylint: disable=wrong-import-position
|
||||
@@ -9253,6 +9253,7 @@ def doCheckConnection():
|
||||
hosts = ['api.github.com',
|
||||
'raw.githubusercontent.com',
|
||||
'accounts.google.com',
|
||||
'workspace.google.com',
|
||||
'oauth2.googleapis.com',
|
||||
'www.googleapis.com']
|
||||
fix_hosts = {'calendar-json.googleapis.com': 'www.googleapis.com',
|
||||
@@ -35089,6 +35090,20 @@ def updateFieldsForCIGroupMatchPatterns(matchPatterns, fieldsList, csvPF=None):
|
||||
|
||||
CIPOLICY_TIME_OBJECTS = {'createTime', 'updateTime'}
|
||||
|
||||
def _filterPolicies(ci, pageMessage, ifilter):
|
||||
try:
|
||||
policies = callGAPIpages(ci.policies(), 'list', 'policies',
|
||||
pageMessage=pageMessage,
|
||||
throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
|
||||
filter=ifilter,
|
||||
fields='nextPageToken,policies(name,policyQuery(group,orgUnit,sortOrder),type,setting)',
|
||||
pageSize=100)
|
||||
# Google returns unordered results, sort them by setting type
|
||||
return sorted(policies, key=lambda p: p.get('setting', {}).get('type', ''))
|
||||
except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied) as e:
|
||||
entityActionFailedWarning([Ent.POLICY, ifilter], str(e))
|
||||
return []
|
||||
|
||||
# Policies where GAM should offer additional guidance and information
|
||||
CIPOLICY_ADDITIONAL_WARNINGS = {
|
||||
'settings/drive_and_docs.external_sharing': {
|
||||
@@ -35097,10 +35112,32 @@ CIPOLICY_ADDITIONAL_WARNINGS = {
|
||||
}
|
||||
}
|
||||
|
||||
def _cleanPolicy(policy, add_warnings, cd, groups_ci):
|
||||
def _getPolicyAppNameFromId(httpObj, app):
|
||||
app['applicationName'] = UNKNOWN
|
||||
appId = app['applicationId']
|
||||
url = f'https://workspace.google.com/marketplace/app/_/{appId}'
|
||||
try:
|
||||
resp, content = httpObj.request(url, 'GET')
|
||||
except:
|
||||
return
|
||||
if resp.status != 200:
|
||||
return
|
||||
if isinstance(content, bytes):
|
||||
content = content.decode()
|
||||
pattern = f'https://workspace.google.com/marketplace/app/(.+?)/{appId}'
|
||||
a = re.search(pattern, content)
|
||||
if a:
|
||||
app['applicationName'] = a.group(1)
|
||||
|
||||
def _cleanPolicy(policy, add_warnings, no_appnames, cd, groups_ci):
|
||||
# convert any wordlists into spaced strings to reduce output complexity
|
||||
if policy['setting']['type'] == 'settings/detector.word_list':
|
||||
policy['setting']['value']['wordList'] = ' '.join(policy['setting']['value']['wordList']['words'])
|
||||
# get application name for application id
|
||||
if policy['setting']['type'] == 'settings/workspace_marketplace.apps_allowlist' and not no_appnames:
|
||||
httpObj = getHttpObj(timeout=10)
|
||||
for app in policy['setting']['value'].get('apps', []):
|
||||
_getPolicyAppNameFromId(httpObj, app)
|
||||
# add any warnings to applicable policies
|
||||
if add_warnings and policy['setting']['type'] in CIPOLICY_ADDITIONAL_WARNINGS:
|
||||
policy['warning'] = CIPOLICY_ADDITIONAL_WARNINGS[policy['setting']['type']]
|
||||
@@ -35124,8 +35161,20 @@ def _showPolicy(policy, FJQC, i=0, count=0):
|
||||
printBlankLine()
|
||||
Ind.Decrement()
|
||||
|
||||
def _showPolicies(policies, FJQC, add_warnings, no_appnames, cd, groups_ci):
|
||||
count = len(policies)
|
||||
performActionNumItems(count, Ent.POLICY)
|
||||
Ind.Increment()
|
||||
i = 0
|
||||
for policy in policies:
|
||||
i += 1
|
||||
_cleanPolicy(policy, add_warnings, no_appnames, cd, groups_ci)
|
||||
_showPolicy(policy, FJQC, i, count)
|
||||
Ind.Decrement()
|
||||
|
||||
# gam info policies <CIPolicyNameEntity>
|
||||
# [nowarnings] [formatjson]
|
||||
# [nowarnings] [noappnames]
|
||||
# [formatjson]
|
||||
def doInfoCIPolicies():
|
||||
groups_ci = buildGAPIObject(API.CLOUDIDENTITY_GROUPS)
|
||||
ci = buildGAPIObject(API.CLOUDIDENTITY_POLICY)
|
||||
@@ -35133,35 +35182,42 @@ def doInfoCIPolicies():
|
||||
entityList = getEntityList(Cmd.OB_CIPOLICY_NAME_ENTITY)
|
||||
FJQC = FormatJSONQuoteChar()
|
||||
add_warnings = True
|
||||
no_appnames = False
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if myarg == 'nowarnings':
|
||||
add_warnings = False
|
||||
elif myarg == 'noappnames':
|
||||
no_appnames=True
|
||||
else:
|
||||
FJQC.GetFormatJSON(myarg)
|
||||
i = 0
|
||||
count = len(entityList)
|
||||
for pname in entityList:
|
||||
i += 1
|
||||
if not pname.startswith('policies/'):
|
||||
pname = 'policies/'+pname
|
||||
try:
|
||||
policy = callGAPI(ci.policies(), 'get',
|
||||
bailOnInternalError=True,
|
||||
throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
|
||||
name=pname,
|
||||
fields='name,policyQuery(group,orgUnit,sortOrder),type,setting')
|
||||
_cleanPolicy(policy, add_warnings, cd, groups_ci)
|
||||
_showPolicy(policy, FJQC, i, count)
|
||||
except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied, GAPI.internalError) as e:
|
||||
entityActionFailedWarning([Ent.POLICY, pname], str(e), i, count)
|
||||
continue
|
||||
|
||||
if pname.startswith('policies/'):
|
||||
try:
|
||||
policies = [callGAPI(ci.policies(), 'get',
|
||||
bailOnInternalError=True,
|
||||
throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
|
||||
name=pname,
|
||||
fields='name,policyQuery(group,orgUnit,sortOrder),type,setting')]
|
||||
except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied, GAPI.internalError) as e:
|
||||
entityActionFailedWarning([Ent.POLICY, pname], str(e), i, count)
|
||||
continue
|
||||
else:
|
||||
if pname.startswith('settings/'):
|
||||
pname = pname.split('/')[1]
|
||||
ifilter = f"setting.type.matches('{pname}')"
|
||||
printGettingAllAccountEntities(Ent.POLICY, ifilter)
|
||||
policies = _filterPolicies(ci, getPageMessage(), ifilter)
|
||||
_showPolicies(policies, FJQC, add_warnings, no_appnames, cd, groups_ci)
|
||||
|
||||
# gam print policies [todrive <ToDriveAttribute>*]
|
||||
# [filter <String>] [nowarnings]
|
||||
# [filter <String>] [nowarnings] [noappnames]
|
||||
# [formatjson [quotechar <Character>]]
|
||||
# gam show policies
|
||||
# [filter <String>] [nowarnings]
|
||||
# [filter <String>] [nowarnings] [noappnames]
|
||||
# [formatjson]
|
||||
def doPrintShowCIPolicies():
|
||||
|
||||
@@ -35182,6 +35238,7 @@ def doPrintShowCIPolicies():
|
||||
FJQC = FormatJSONQuoteChar(csvPF)
|
||||
ifilter = None
|
||||
add_warnings = True
|
||||
no_appnames = False
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if csvPF and myarg == 'todrive':
|
||||
@@ -35190,34 +35247,17 @@ def doPrintShowCIPolicies():
|
||||
ifilter = getString(Cmd.OB_STRING)
|
||||
elif myarg == 'nowarnings':
|
||||
add_warnings = False
|
||||
elif myarg == 'noappnames':
|
||||
no_appnames=True
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, True)
|
||||
printGettingAllAccountEntities(Ent.POLICY, ifilter)
|
||||
pageMessage = getPageMessage()
|
||||
try:
|
||||
policies = callGAPIpages(ci.policies(), 'list', 'policies',
|
||||
pageMessage=pageMessage,
|
||||
throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
|
||||
filter=ifilter,
|
||||
fields='nextPageToken,policies(name,policyQuery(group,orgUnit,sortOrder),type,setting)',
|
||||
pageSize=100)
|
||||
except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied) as e:
|
||||
entityActionFailedExit([Ent.POLICY, None], str(e))
|
||||
# Google returns unordered results, sort them by setting type
|
||||
policies = sorted(policies, key=lambda p: p.get('setting', {}).get('type', ''))
|
||||
policies = _filterPolicies(ci, getPageMessage(), ifilter)
|
||||
if not csvPF:
|
||||
count = len(policies)
|
||||
performActionNumItems(count, Ent.POLICY)
|
||||
Ind.Increment()
|
||||
i = 0
|
||||
for policy in policies:
|
||||
i += 1
|
||||
_cleanPolicy(policy, add_warnings, cd, groups_ci)
|
||||
_showPolicy(policy, FJQC, i, count)
|
||||
Ind.Decrement()
|
||||
_showPolicies(policies, FJQC, add_warnings, no_appnames, cd, groups_ci)
|
||||
else:
|
||||
for policy in policies:
|
||||
_cleanPolicy(policy, add_warnings, cd, groups_ci)
|
||||
_cleanPolicy(policy, add_warnings, no_appnames, cd, groups_ci)
|
||||
_printPolicy(policy)
|
||||
if csvPF:
|
||||
csvPF.writeCSVfile('Policies')
|
||||
|
||||
Reference in New Issue
Block a user