gam7 7.25.1__py3-none-any.whl → 7.27.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of gam7 might be problematic. Click here for more details.
- gam/__init__.py +38 -5
- gam/gamlib/glcfg.py +4 -0
- gam/gamlib/glglobals.py +3 -0
- {gam7-7.25.1.dist-info → gam7-7.27.0.dist-info}/METADATA +2 -2
- {gam7-7.25.1.dist-info → gam7-7.27.0.dist-info}/RECORD +8 -8
- {gam7-7.25.1.dist-info → gam7-7.27.0.dist-info}/WHEEL +0 -0
- {gam7-7.25.1.dist-info → gam7-7.27.0.dist-info}/entry_points.txt +0 -0
- {gam7-7.25.1.dist-info → gam7-7.27.0.dist-info}/licenses/LICENSE +0 -0
gam/__init__.py
CHANGED
|
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
|
|
|
25
25
|
"""
|
|
26
26
|
|
|
27
27
|
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
|
28
|
-
__version__ = '7.
|
|
28
|
+
__version__ = '7.27.00'
|
|
29
29
|
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
|
30
30
|
|
|
31
31
|
#pylint: disable=wrong-import-position
|
|
@@ -49,7 +49,7 @@ from email.policy import SMTP as policySMTP
|
|
|
49
49
|
import hashlib
|
|
50
50
|
from html.entities import name2codepoint
|
|
51
51
|
from html.parser import HTMLParser
|
|
52
|
-
import http.client
|
|
52
|
+
import http.client
|
|
53
53
|
import importlib
|
|
54
54
|
from importlib.metadata import version as lib_version
|
|
55
55
|
import io
|
|
@@ -375,6 +375,37 @@ YUBIKEY_VALUE_ERROR_RC = 85
|
|
|
375
375
|
YUBIKEY_MULTIPLE_CONNECTED_RC = 86
|
|
376
376
|
YUBIKEY_NOT_FOUND_RC = 87
|
|
377
377
|
|
|
378
|
+
DEBUG_REDACTION_PATTERNS = [
|
|
379
|
+
# Positional patterns that redact sensitive credentials based on their location
|
|
380
|
+
(r'(Bearer\s+)\S+', r'\1*****'), # access tokens and JWTs in auth header
|
|
381
|
+
(r'([?&]refresh_token=)[^&]*', r'\1*****'), # refresh token URL parameter
|
|
382
|
+
(r'([?&]client_secret=)[^&]*', r'\1*****'), # client secret URL parameter
|
|
383
|
+
(r'([?&]key=)[^&]*', r'\1*****'), # API key URL parameter
|
|
384
|
+
(r'([?&]code=)[^&]*', r'\1*****'), # auth code URL parameter
|
|
385
|
+
|
|
386
|
+
# Pattern match patterns that redact sensitive credentials based on known credential pattern
|
|
387
|
+
(r'ya29.[0-9A-Za-z-_]+', '*****'), # Access token
|
|
388
|
+
(r'1%2F%2F[0-9A-Za-z-_]{100}|1%2F%2F[0-9A-Za-z-_]{64}|1%2F%2F[0-9A-Za-z-_]{43}', '*****'), # Refresh token
|
|
389
|
+
(r'4/[0-9A-Za-z-_]+', '*****'), # Auth code
|
|
390
|
+
(r'GOCSPX-[0-9a-zA-Z-_]{28}', '*****'), # Client secret
|
|
391
|
+
(r'AIza[0-9A-Za-z-_]{35}', '*****'), # API key
|
|
392
|
+
(r'eyJ[a-zA-Z0-9\-_]+\.eyJ[a-zA-Z0-9\-_]+\.[a-zA-Z0-9\-_]*', '*****'), # JWT
|
|
393
|
+
]
|
|
394
|
+
|
|
395
|
+
def redactable_debug_print(*args):
|
|
396
|
+
processed_args = []
|
|
397
|
+
for arg in args:
|
|
398
|
+
if arg.startswith('b\''):
|
|
399
|
+
sbytes = arg[2:-1]
|
|
400
|
+
sbytes = bytes(sbytes, 'utf-8')
|
|
401
|
+
arg = sbytes.decode()
|
|
402
|
+
arg = arg.replace('\\r\\n', "\n ")
|
|
403
|
+
if GC.Values[GC.DEBUG_REDACTION]:
|
|
404
|
+
for pattern, replace in DEBUG_REDACTION_PATTERNS:
|
|
405
|
+
arg = re.sub(pattern, replace, arg)
|
|
406
|
+
processed_args.append(arg)
|
|
407
|
+
print(*processed_args)
|
|
408
|
+
|
|
378
409
|
# Multiprocessing lock
|
|
379
410
|
mplock = None
|
|
380
411
|
|
|
@@ -4124,6 +4155,8 @@ def SetGlobalVariables():
|
|
|
4124
4155
|
GM.Globals[GM.OAUTH2_TXT_LOCK] = f'{GC.Values[GC.OAUTH2_TXT]}.lock'
|
|
4125
4156
|
# Override httplib2 settings
|
|
4126
4157
|
httplib2.debuglevel = GC.Values[GC.DEBUG_LEVEL]
|
|
4158
|
+
# Use our own print function for http.client so we can redact and cleanup
|
|
4159
|
+
http.client.print = redactable_debug_print
|
|
4127
4160
|
# Reset global variables if required
|
|
4128
4161
|
if prevExtraArgsTxt != GC.Values[GC.EXTRA_ARGS]:
|
|
4129
4162
|
GM.Globals[GM.EXTRA_ARGS_LIST] = [('prettyPrint', GC.Values[GC.DEBUG_LEVEL] > 0)]
|
|
@@ -4775,7 +4808,7 @@ def getService(api, httpObj):
|
|
|
4775
4808
|
waitOnFailure(n, triesLimit, INVALID_JSON_RC, str(e))
|
|
4776
4809
|
continue
|
|
4777
4810
|
systemErrorExit(INVALID_JSON_RC, str(e))
|
|
4778
|
-
except (
|
|
4811
|
+
except (http.client.ResponseNotReady, OSError, googleapiclient.errors.HttpError) as e:
|
|
4779
4812
|
errMsg = f'Connection error: {str(e) or repr(e)}'
|
|
4780
4813
|
if n != triesLimit:
|
|
4781
4814
|
waitOnFailure(n, triesLimit, SOCKET_ERROR_RC, errMsg)
|
|
@@ -5088,7 +5121,7 @@ def callGData(service, function,
|
|
|
5088
5121
|
e = e.args[0]
|
|
5089
5122
|
handleOAuthTokenError(e, GDATA.SERVICE_NOT_APPLICABLE in throwErrors)
|
|
5090
5123
|
raise GDATA.ERROR_CODE_EXCEPTION_MAP[GDATA.SERVICE_NOT_APPLICABLE](str(e))
|
|
5091
|
-
except (
|
|
5124
|
+
except (http.client.ResponseNotReady, OSError) as e:
|
|
5092
5125
|
errMsg = f'Connection error: {str(e) or repr(e)}'
|
|
5093
5126
|
if n != triesLimit:
|
|
5094
5127
|
waitOnFailure(n, triesLimit, SOCKET_ERROR_RC, errMsg)
|
|
@@ -5398,7 +5431,7 @@ def callGAPI(service, function,
|
|
|
5398
5431
|
e = e.args[0]
|
|
5399
5432
|
handleOAuthTokenError(e, GAPI.SERVICE_NOT_AVAILABLE in throwReasons)
|
|
5400
5433
|
raise GAPI.REASON_EXCEPTION_MAP[GAPI.SERVICE_NOT_AVAILABLE](str(e))
|
|
5401
|
-
except (
|
|
5434
|
+
except (http.client.ResponseNotReady, OSError) as e:
|
|
5402
5435
|
errMsg = f'Connection error: {str(e) or repr(e)}'
|
|
5403
5436
|
if n != triesLimit:
|
|
5404
5437
|
waitOnFailure(n, triesLimit, SOCKET_ERROR_RC, errMsg)
|
gam/gamlib/glcfg.py
CHANGED
|
@@ -149,6 +149,8 @@ CSV_OUTPUT_USERS_AUDIT = 'csv_output_users_audit'
|
|
|
149
149
|
CUSTOMER_ID = 'customer_id'
|
|
150
150
|
# If debug_level > 0: extra_args['prettyPrint'] = True, httplib2.debuglevel = gam_debug_level, appsObj.debug = True
|
|
151
151
|
DEBUG_LEVEL = 'debug_level'
|
|
152
|
+
# redact sensitive credentials from debug output
|
|
153
|
+
DEBUG_REDACTION = 'debug_redaction'
|
|
152
154
|
# Developer Preview API Key
|
|
153
155
|
DEVELOPER_PREVIEW_API_KEY = 'developer_preview_api_key'
|
|
154
156
|
# When retrieving lists of ChromeOS devices from API, how many should be retrieved in each chunk
|
|
@@ -378,6 +380,7 @@ Defaults = {
|
|
|
378
380
|
CSV_OUTPUT_USERS_AUDIT: FALSE,
|
|
379
381
|
CUSTOMER_ID: MY_CUSTOMER,
|
|
380
382
|
DEBUG_LEVEL: '0',
|
|
383
|
+
DEBUG_REDACTION: TRUE,
|
|
381
384
|
DEVELOPER_PREVIEW_API_KEY: '',
|
|
382
385
|
DEVICE_MAX_RESULTS: '200',
|
|
383
386
|
DOMAIN: '',
|
|
@@ -547,6 +550,7 @@ VAR_INFO = {
|
|
|
547
550
|
CSV_OUTPUT_USERS_AUDIT: {VAR_TYPE: TYPE_BOOLEAN},
|
|
548
551
|
CUSTOMER_ID: {VAR_TYPE: TYPE_STRING, VAR_ENVVAR: 'CUSTOMER_ID', VAR_LIMITS: (0, None)},
|
|
549
552
|
DEBUG_LEVEL: {VAR_TYPE: TYPE_INTEGER, VAR_SIGFILE: 'debug.gam', VAR_LIMITS: (0, None), VAR_SFFT: ('0', '4')},
|
|
553
|
+
DEBUG_REDACTION: {VAR_TYPE: TYPE_BOOLEAN},
|
|
550
554
|
DEVELOPER_PREVIEW_API_KEY: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)},
|
|
551
555
|
DEVICE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 200)},
|
|
552
556
|
DOMAIN: {VAR_TYPE: TYPE_STRING, VAR_ENVVAR: 'GA_DOMAIN', VAR_LIMITS: (0, None)},
|
gam/gamlib/glglobals.py
CHANGED
|
@@ -107,6 +107,8 @@ CURRENT_SVCACCT_USER = 'csa'
|
|
|
107
107
|
DATETIME_NOW = 'dtno'
|
|
108
108
|
# If debug_level > 0: extra_args['prettyPrint'] = True, httplib2.debuglevel = gam_debug_level, appsObj.debug = True
|
|
109
109
|
DEBUG_LEVEL = 'dbgl'
|
|
110
|
+
# Whether debug output should redact sensitive credentials
|
|
111
|
+
DEBUG_REDACTION = 'dbrd'
|
|
110
112
|
# Decoded ID token
|
|
111
113
|
DECODED_ID_TOKEN = 'didt'
|
|
112
114
|
# Index of start of <UserTypeEntity> in command line
|
|
@@ -263,6 +265,7 @@ Globals = {
|
|
|
263
265
|
CURRENT_SVCACCT_USER: None,
|
|
264
266
|
DATETIME_NOW: None,
|
|
265
267
|
DEBUG_LEVEL: 0,
|
|
268
|
+
DEBUG_REDACTION: True,
|
|
266
269
|
DECODED_ID_TOKEN: None,
|
|
267
270
|
ENTITY_CL_DELAY_START: 1,
|
|
268
271
|
ENTITY_CL_START: 1,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gam7
|
|
3
|
-
Version: 7.
|
|
3
|
+
Version: 7.27.0
|
|
4
4
|
Summary: CLI tool to manage Google Workspace
|
|
5
5
|
Project-URL: Homepage, https://github.com/GAM-team/GAM
|
|
6
6
|
Project-URL: Issues, https://github.com/GAM-team/GAM/issues
|
|
@@ -17,7 +17,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
-
Requires-Python: >=3.
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
21
|
Requires-Dist: arrow>=1.3.0
|
|
22
22
|
Requires-Dist: chardet>=5.2.0
|
|
23
23
|
Requires-Dist: cryptography>=44.0.2
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
gam/__init__.py,sha256=
|
|
1
|
+
gam/__init__.py,sha256=jGHH20ehVL8twFNTrfYiI7dOm1kcdZLFn31iLERfp-E,3625606
|
|
2
2
|
gam/__main__.py,sha256=VwEYS7a9vYQPbT6iLduMOoVUJ6p4R-HZgerZQmM1NpE,1307
|
|
3
3
|
gam/cacerts.pem,sha256=DUsVo2XlFYwfkhe3gnxa-Km4Z4noz74hSApXwTT-nQE,44344
|
|
4
4
|
gam/cbcm-v1.1beta1.json,sha256=xO5XloCQQULmPbFBx5bckdqmbLFQ7sJ2TImhE1ysDIY,19439
|
|
@@ -23,12 +23,12 @@ gam/atom/url.py,sha256=pxO1TlORxyKQTQ1bkBE1unFzjnv9c8LjJkm-UEORShY,4276
|
|
|
23
23
|
gam/gamlib/__init__.py,sha256=z5mF-y0j8pm-YNFBaiuxB4M_GAUPG-cXWwrhYwrVReM,679
|
|
24
24
|
gam/gamlib/glaction.py,sha256=1Il_HrChVnPkzZwiZs5au4mFQVtq4K1Z42uIuR6qdnI,9419
|
|
25
25
|
gam/gamlib/glapi.py,sha256=g49VStWE64nCdrpNIMl60U06m98d3AGO8-vUDxgcBog,37048
|
|
26
|
-
gam/gamlib/glcfg.py,sha256=
|
|
26
|
+
gam/gamlib/glcfg.py,sha256=do_FR9m9m7Bmh2SgjLPk2pysU-wPHt7PlqPPjX90tpw,28684
|
|
27
27
|
gam/gamlib/glclargs.py,sha256=LlTtwJJHqU48l7SQT4bcZCWlw3Y46g42Bn1ACGW8gIk,53307
|
|
28
28
|
gam/gamlib/glentity.py,sha256=KWFomkoNE6lLE83zVqVIlJ2rkzfLkhEasW1M0TWGieA,35373
|
|
29
29
|
gam/gamlib/glgapi.py,sha256=pdBbwNtnCwFWxJGaP-_3hdTjSNoOCJF2yo76WdQOi1k,40426
|
|
30
30
|
gam/gamlib/glgdata.py,sha256=weRppttWm6uRyqtBoGPKoHiNZ2h28nhfUV4J_mbCszY,2707
|
|
31
|
-
gam/gamlib/glglobals.py,sha256=
|
|
31
|
+
gam/gamlib/glglobals.py,sha256=U1eCXHOkWAtwVXG8-0HL4ZzQP0YcbeFlhJxbOa_x1QI,9804
|
|
32
32
|
gam/gamlib/glindent.py,sha256=RfBa2LDfLIqPLL5vMfC689TCVmqn8xf-qulSzkiatrc,1228
|
|
33
33
|
gam/gamlib/glmsgs.py,sha256=ODq-KS3jhXH5DB5DEo6eCX1DHhy4OGv_jeQjiLVPOHM,34049
|
|
34
34
|
gam/gamlib/glskus.py,sha256=29vlBLBJCL4u9GawCt3eNeZq9HQG3hGFZk9-EainNng,15384
|
|
@@ -47,8 +47,8 @@ gam/gdata/apps/audit/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrK
|
|
|
47
47
|
gam/gdata/apps/audit/service.py,sha256=Z1eueThcNeVUMWP1DRWc_DGHrJCiJI8W_xj6L-cqu-Q,9658
|
|
48
48
|
gam/gdata/apps/contacts/__init__.py,sha256=Um6zgIkiahZns7yAEuC3pxHSMD8iciZ_EoynSLoYPfU,30463
|
|
49
49
|
gam/gdata/apps/contacts/service.py,sha256=5lNb-Ii1Gyek6ePFji3kyoYtCBc8CuJTwagx2BL2o14,15684
|
|
50
|
-
gam7-7.
|
|
51
|
-
gam7-7.
|
|
52
|
-
gam7-7.
|
|
53
|
-
gam7-7.
|
|
54
|
-
gam7-7.
|
|
50
|
+
gam7-7.27.0.dist-info/METADATA,sha256=tQM_yG7zU9QVIzkevtF7YQq79yRcs90PsjdlHeDnufs,3093
|
|
51
|
+
gam7-7.27.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
52
|
+
gam7-7.27.0.dist-info/entry_points.txt,sha256=HVUM5J7dA8YwvJfG30jiLefR19ExMs387TWugWd9sf4,42
|
|
53
|
+
gam7-7.27.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
54
|
+
gam7-7.27.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|