Compare commits

..

28 Commits
v6.08 ... v6.11

Author SHA1 Message Date
Jay Lee
b75ad006f1 Update build.yml 2021-11-22 08:26:33 -05:00
Jay Lee
dbc3f0cd83 Update var.py 2021-11-22 08:16:32 -05:00
Jay Lee
ea2750f970 Merge branch 'main' of https://github.com/jay0lee/GAM into main 2021-11-22 08:08:33 -05:00
Jay Lee
a2eb5a2483 Correct certificate not before value to UTC-1h. Fixes #1453 2021-11-22 08:08:20 -05:00
Ross Scroggs
54178543d6 Fix Row Filtering Part 3 (#1450)
Graak! Why I can't get my code translated into yours is beyond me; this time for sure.
2021-11-21 20:25:09 -05:00
Jay Lee
5436f21bc0 Use OpenSSL 3.0.0 in builds 2021-10-29 18:12:30 -04:00
Ross Scroggs
839768a2a5 Fix error handling (#1447) 2021-10-29 13:04:59 -04:00
Jay Lee
2e195d5aa1 Update build.yml 2021-10-29 11:05:57 -04:00
Ross Scroggs
66811f8eb5 Fix Row Filtering Part 2 (#1446)
```
Row Filtering
There can be multiple filters, a filter can match multiple columns (wildcard).
The semantics should be:
For row keep filters, if all filters match, the row is kept.
For row drop filters, if any filter matches, the row is dropped.

For an individual filter that specifies multiple columns, there is a match if any column matches.

Prior to PR 1433, the semantics for keep/drop were reversed; the semantics for multiple columns was correct.

PR 1433 corrected the semantics for keep/drop but broke the semantics for multiple columns.

This PR corrects the semantics for multiple columns.
```
2021-10-29 10:24:12 -04:00
Jay Lee
a92326790d Update build.yml 2021-10-29 10:19:09 -04:00
Ross Scroggs
d405767fb0 Update requirements.txt to get latest library versions (#1444)
* Update requirements.txt

* Revert "Update requirements.txt"

This reverts commit f89f66d44c.

* Update to fixed google oauth library
2021-10-26 14:45:34 -04:00
Ross Scroggs
8d7c6d3835 MacOS codesign fix no longer needed; MacOS 12 = Monterey (#1441)
* Updated 3.9 to 3.10, is this still needed?

* Fix no longer required

* MacOS 12 is Monterey
2021-10-26 12:56:47 -04:00
Jay Lee
e362591b7a pin google-auth to 2.0.2
Need https://github.com/googleapis/google-auth-library-python/issues/889 fixed.
2021-10-21 19:32:39 -04:00
Jay Lee
ee5f4b73e8 Update var.py 2021-10-21 18:43:34 -04:00
Jay Lee
0d15eb2898 Workaround Python 3.10.0 CSV escape issue. Fixes #1437 2021-10-21 10:41:20 -04:00
Jay Lee
4af50206ad need lists to repro 2021-10-21 08:19:32 -04:00
Jay Lee
c596937006 Update build.yml 2021-10-21 08:13:17 -04:00
Jay Lee
17eb61e1eb Merge branch 'main' of https://github.com/jay0lee/GAM into main 2021-10-21 08:06:39 -04:00
Jay Lee
a333185e84 repro issue #1438 2021-10-21 08:06:26 -04:00
Jay Lee
f6863ae2d6 Update var.py 2021-10-20 13:57:11 -04:00
Ross Scroggs
36830250b5 Handle spurious Google error when enabling project APIs (#1436) 2021-10-20 13:48:41 -04:00
Jay Lee
4ca1c3537b Merge branch 'main' of https://github.com/jay0lee/GAM into main 2021-10-18 08:50:25 -04:00
Jay Lee
eeab09eacb fix deprecated package in a_atleast_b.py 2021-10-18 08:50:13 -04:00
Ross Scroggs
af16967257 Fix Row Filtering (#1433)
When multiple filter expressions are defined:
GAM_CSV_ROW_FILTER - should match only if all expressions match
GAM_CSV_ROW_DROP_FILTER - should match if any expression matches

Currently, the opposite is true
2021-10-14 20:12:51 -04:00
Jay Lee
75e2bf5a9a Update build.yml 2021-10-14 19:22:57 -04:00
Ross Scroggs
4db3bc409b Document member restrictions; fix print users (#1430)
* Document member restrictions

* Fix gam print users allfields custom all to include primaryEmail

If you really want everything say: gam print users full
2021-10-06 14:22:27 -04:00
Jay Lee
32ccf414ea Update gam-install.sh 2021-10-06 08:01:29 -04:00
Jay Lee
615e48fffc Update gam-install.sh 2021-10-05 20:18:07 -04:00
13 changed files with 85 additions and 47 deletions

View File

@@ -55,7 +55,7 @@ else
tar xf openssl-$BUILD_OPENSSL_VERSION.tar.gz
cd openssl-$BUILD_OPENSSL_VERSION
echo "Compiling OpenSSL $BUILD_OPENSSL_VERSION..."
./config shared --prefix=$HOME/ssl
./Configure --libdir=lib --prefix=$HOME/ssl
echo "Running make for OpenSSL..."
make -j$cpucount -s
echo "Running make install for OpenSSL..."
@@ -70,7 +70,7 @@ else
cd Python-$BUILD_PYTHON_VERSION
echo "Compiling Python $BUILD_PYTHON_VERSION..."
safe_flags="--with-openssl=$HOME/ssl --enable-shared --prefix=$HOME/python --with-ensurepip=upgrade"
unsafe_flags="--enable-optimizations --with-lto"
unsafe_flags="--enable-optimizations --with-lto --with-openssl=~/ssl --with-openssl-rpath=~~/ssl/lib"
if [ ! -e Makefile ]; then
echo "running configure with safe and unsafe"
./configure $safe_flags $unsafe_flags > /dev/null

View File

@@ -29,7 +29,7 @@ echo "installing Python $BUILD_PYTHON_VERSION..."
sudo installer -pkg ./$pyfile -target /
# This fixes https://github.com/pyinstaller/pyinstaller/issues/5062
codesign --remove-signature /Library/Frameworks/Python.framework/Versions/3.9/Python
#codesign --remove-signature /Library/Frameworks/Python.framework/Versions/3.10/Python
#if [ ! -f python-$MIN_PYTHON_VERSION-macosx10.9.pkg ]; then
# wget --quiet https://www.python.org/ftp/python/$MIN_PYTHON_VERSION/python-$MIN_PYTHON_VERSION-macosx10.9.pkg

View File

@@ -12,13 +12,13 @@ defaults:
working-directory: src
env:
BUILD_PYTHON_VERSION: "3.9.7"
MIN_PYTHON_VERSION: "3.9.7"
BUILD_OPENSSL_VERSION: "1.1.1l"
BUILD_PYTHON_VERSION: "3.10.0"
MIN_PYTHON_VERSION: "3.10.0"
BUILD_OPENSSL_VERSION: "3.0.0"
MIN_OPENSSL_VERSION: "1.1.1l"
PATCHELF_VERSION: "0.13"
# PYINSTALLER_VERSION can be full commit hash or version like v4.20
PYINSTALLER_VERSION: "ae7ed8ed044f210288b27f0c84ad670ff573822b"
PYINSTALLER_VERSION: "6eae2c7cf93a968ddc054339e0cb3063f90d0e64"
jobs:
build:
@@ -73,7 +73,7 @@ jobs:
platform: "x86_64"
- os: ubuntu-20.04
goal: test
python: "3.10.0"
python: "3.9"
jid: 9
gamos: linux
platform: x86_64
@@ -92,7 +92,7 @@ jobs:
path: |
~/python
~/ssl
key: ${{ matrix.os }}-${{ matrix.jid }}-20211004
key: ${{ matrix.os }}-${{ matrix.jid }}-20211122
- name: Set env variables
env:
@@ -215,6 +215,7 @@ jobs:
- name: Basic Tests build jobs only
if: matrix.goal != 'test'
run: |
$pip install packaging
export vline=$($gam version | grep "Python ")
export python_line=($vline)
export this_python=${python_line[1]}
@@ -332,7 +333,7 @@ jobs:
$gam print browsers
export sn="$JID$JID$JID$JID-$(openssl rand -base64 32 | sed 's/[^a-zA-Z0-9]//g')"
$gam create device serialnumber $sn devicetype android
$gam print cros allfields nolists
$gam print cros allfields orderby serialnumber
$gam report usageparameters customer
$gam report usage customer parameters gmail:num_emails_sent,accounts:num_1day_logins
$gam report customer todrive

View File

@@ -222,8 +222,10 @@ If an item contains spaces, it should be surrounded by ".
<QueryContact> ::= <String> See: https://developers.google.com/google-apps/contacts/v3/reference#contacts-query-parameters-reference
<QueryCrOS> ::= <String> See: https://support.google.com/chrome/a/answer/1698333?hl=en
<QueryDriveFile> ::= <String> See: https://developers.google.com/drive/v2/web/search-parameters
<QueryDynamicGroup> ::= <String> See: https://cloud.google.com/identity/docs/reference/rest/v1beta1/groups#dynamicgroupquery
<QueryGmail> ::= <String> See: https://support.google.com/mail/answer/7190
<QueryGroup> ::= <String> See: https://developers.google.com/admin-sdk/directory/v1/guides/search-groups
<QueryMemberRestrictions> ::= <String> See: https://cloud.google.com/identity/docs/reference/rest/v1beta1/SecuritySettings#MemberRestriction
<QueryMobile> ::= <String> See: https://support.google.com/a/answer/7549103
<QueryTeamDrive> ::= <String> See: https://developers.google.com/drive/api/v3/search-shareddrives
<QueryUser> ::= <String> See: https://developers.google.com/admin-sdk/directory/v1/guides/search-users
@@ -1384,18 +1386,21 @@ gam print printermodels [todrive] [filter <String>]
gam create cigroup <EmailAddress> <CIGroupAttribute>*
[makeowner] [alias|aliases <AliasList>] [dynamic <QueryDynamicGroup>]
gam update cigroup <GroupItem> [email <EmailAddress>] <CIGroupAttribute>* [security]
gam update cigroup <GroupItem> [email <EmailAddress>] <CIGroupAttribute>*
[security] [dynamic <QueryDynamicGroup>]
[memberrestrictions <QueryMemberRestrictions>]
gam update cigroup <GroupItem> add [owner|manager|member] [notsuspended|suspended] [expires never|<Time>] <UserTypeEntity>
gam update cigroup <GroupItem> delete|remove [owner|manager|member] [notsuspended|suspended] <UserTypeEntity>
gam update cigroup <GroupItem> sync [owner|manager|member] [notsuspended|suspended] [expires never|<Time>] <UserTypeEntity>
gam update cigroup <GroupItem> update [owner|manager|member] [notsuspended|suspended] [expires never|<Time>] <UserTypeEntity>
gam update cigroup <GroupItem> clear [member] [manager] [owner] [notsuspended|suspended]
gam delete cigroup <GroupItem>
gam info cigroup <GroupItem> [nousers] [nojoindate] [showupdatedate] [membertree]
gam info cigroup <GroupItem> [nousers] [nojoindate] [showupdatedate] [membertree] [nosecurity|nosecuritysettings]
gam print cigroups [todrive]
[enterprisemember <UserItem>]
[members|memberscount] [managers|managerscount] [owners|ownerscount]
[memberrestrictions]
[delimiter <Character>] [sortheaders]
gam info cimember <UserItem> <GroupItem>

View File

@@ -28,7 +28,7 @@ upgrade_only=false
gamversion="latest"
adminuser=""
regularuser=""
gam_glibc_vers="2.31 2.27 2.23"
gam_glibc_vers="2.31 2.27"
#gam_macos_vers="10.15.6 10.14.6 10.13.6"
while getopts "hd:a:o:b:lp:u:r:v:" OPTION
@@ -128,7 +128,7 @@ case $gamos in
this_macos_ver=$osversion
fi
echo "You are running MacOS $this_macos_ver"
gamfile="macos-x86_64.tar.xz"
gamfile="macos-universal2.tar.xz"
;;
MINGW64_NT*)
gamos="windows"

View File

@@ -7244,6 +7244,7 @@ def enableGAMProjectAPIs(GAMProjectAPIs,
gapi_errors.ErrorReason.FORBIDDEN,
gapi_errors.ErrorReason.PERMISSION_DENIED
],
retry_reasons=[gapi_errors.ErrorReason.INTERNAL_SERVER_ERROR],
name=service_name)
print(f' API: {api}, Enabled{currentCount(j, jcount)}')
break
@@ -7764,7 +7765,9 @@ def _generatePrivateKeyAndPublicCert(client_id, key_size):
x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, client_id)]))
builder = builder.issuer_name(
x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, client_id)]))
builder = builder.not_valid_before(datetime.datetime.today())
# Gooogle seems to enforce the not before date strictly. Set the not before
# date to be UTC one hour ago should cover any clock skew.
builder = builder.not_valid_before(datetime.datetime.utcnow() - datetime.timedelta(hours=1))
# Google uses 12/31/9999 date for end time
builder = builder.not_valid_after(datetime.datetime(9999, 12, 31, 23, 59))
builder = builder.serial_number(x509.random_serial_number())
@@ -9680,6 +9683,8 @@ def doPrintUsers():
sortHeaders = True
i += 1
elif myarg in ['custom', 'schemas']:
if not fieldsList:
fieldsList = ['primaryEmail']
fieldsList.append('customSchemas')
if sys.argv[i + 1].lower() == 'all':
projection = 'full'

View File

@@ -395,7 +395,7 @@ class Credentials(google.oauth2.credentials.Credentials):
self.refresh(request)
self._id_token_data = google.oauth2.id_token.verify_oauth2_token(
self.id_token, request)
self.id_token, request, clock_skew_in_seconds=10)
def get_token_value(self, field):
"""Retrieves data from the OAuth ID token.

View File

@@ -154,28 +154,39 @@ def write_csv_file(csvRows, titles, list_type, todrive):
return True
return False
def filterMatch(filterVal, columns, row):
for column in columns:
if filterVal[1] == 'regex':
if filterVal[2].search(str(row.get(column, ''))):
return True
elif filterVal[1] == 'notregex':
if not filterVal[2].search(str(row.get(column, ''))):
return True
elif filterVal[1] in ['date', 'time']:
if rowDateTimeFilterMatch(
filterVal[1] == 'date', row.get(column, ''),
filterVal[2], filterVal[3]):
return True
elif filterVal[1] == 'count':
if rowCountFilterMatch(
row.get(column, 0), filterVal[2], filterVal[3]):
return True
else: #boolean
if rowBooleanFilterMatch(
row.get(column, False), filterVal[2]):
return True
return False
def rowFilterMatch(filters, columns, row):
for c, filterVal in iter(filters.items()):
for column in columns[c]:
if filterVal[1] == 'regex':
if filterVal[2].search(str(row.get(column, ''))):
return True
elif filterVal[1] == 'notregex':
if not filterVal[2].search(str(row.get(column, ''))):
return True
elif filterVal[1] in ['date', 'time']:
if rowDateTimeFilterMatch(
filterVal[1] == 'date', row.get(column, ''),
filterVal[2], filterVal[3]):
return True
elif filterVal[1] == 'count':
if rowCountFilterMatch(
row.get(column, 0), filterVal[2], filterVal[3]):
return True
else: #boolean
if rowBooleanFilterMatch(
row.get(column, False), filterVal[2]):
return True
if not filterMatch(filterVal, columns[c], row):
return False
return True
def rowDropFilterMatch(filters, columns, row):
for c, filterVal in iter(filters.items()):
if filterMatch(filterVal, columns[c], row):
return True
return False
if GC_Values[GC_CSV_ROW_FILTER] or GC_Values[GC_CSV_ROW_DROP_FILTER]:
@@ -210,7 +221,7 @@ def write_csv_file(csvRows, titles, list_type, todrive):
if (((keepColumns is None) or
rowFilterMatch(GC_Values[GC_CSV_ROW_FILTER], keepColumns, row)) and
((dropColumns is None) or
not rowFilterMatch(GC_Values[GC_CSV_ROW_DROP_FILTER], dropColumns, row))):
not rowDropFilterMatch(GC_Values[GC_CSV_ROW_DROP_FILTER], dropColumns, row))):
rows.append(row)
csvRows = rows
@@ -231,7 +242,14 @@ def write_csv_file(csvRows, titles, list_type, todrive):
'No columns selected with GAM_CSV_HEADER_FILTER and GAM_CSV_HEADER_DROP_FILTER\n'
)
return
csv.register_dialect('nixstdout', lineterminator='\n')
nixstdout_dialect = {'lineterminator': '\n',
'quoting': csv.QUOTE_MINIMAL}
# fix issue with Python 3.10.0 and no escape char
# 3.10.1+ may fix this within Python so hopefully
# this is short-lived.
if sys.version_info.minor >= 10:
nixstdout_dialect['escapechar'] = '\\'
csv.register_dialect('nixstdout', **nixstdout_dialect)
if todrive:
write_to = io.StringIO()
else:
@@ -239,8 +257,7 @@ def write_csv_file(csvRows, titles, list_type, todrive):
writer = csv.DictWriter(write_to,
fieldnames=titles,
dialect='nixstdout',
extrasaction='ignore',
quoting=csv.QUOTE_MINIMAL)
extrasaction='ignore')
try:
writer.writerow(dict((item, item) for item in writer.fieldnames))
writer.writerows(csvRows)

View File

@@ -359,7 +359,7 @@ def handle_oauth_token_error(e, soft_errors):
returns to the caller.
"""
token_error = str(e).replace('.', '')
if token_error in errors.OAUTH2_TOKEN_ERRORS or e.startswith(
if token_error in errors.OAUTH2_TOKEN_ERRORS or token_error.startswith(
'Invalid response'):
if soft_errors:
return

View File

@@ -60,6 +60,10 @@ class GapiGroupNotFoundError(Exception):
pass
class GapiInternalServerError(Exception):
pass
class GapiInvalidError(Exception):
pass
@@ -125,6 +129,7 @@ class ErrorReason(Enum):
GATEWAY_TIMEOUT = 'gatewayTimeout'
GROUP_NOT_FOUND = 'groupNotFound'
INTERNAL_ERROR = 'internalError'
INTERNAL_SERVER_ERROR = 'internalServerError'
INVALID = 'invalid'
INVALID_ARGUMENT = 'invalidArgument'
INVALID_MEMBER = 'invalidMember'
@@ -199,6 +204,8 @@ ERROR_REASON_TO_EXCEPTION = {
GapiGatewayTimeoutError,
ErrorReason.GROUP_NOT_FOUND:
GapiGroupNotFoundError,
ErrorReason.INTERNAL_SERVER_ERROR:
GapiInternalServerError,
ErrorReason.INVALID:
GapiInvalidError,
ErrorReason.INVALID_ARGUMENT:
@@ -336,6 +343,10 @@ def get_gapi_error_detail(e,
if 'Requested entity was not found' in message or 'does not exist' in message:
error = _create_http_error_dict(404, ErrorReason.NOT_FOUND.value,
message)
elif http_status == 500:
if 'Failed to convert server response to JSON' in message:
error = _create_http_error_dict(500, ErrorReason.INTERNAL_SERVER_ERROR.value,
message)
else:
if 'error_description' in error:
if error['error_description'] == 'Invalid Value':

View File

@@ -8,7 +8,7 @@ import platform
import re
GAM_AUTHOR = 'Jay Lee <jay0lee@gmail.com>'
GAM_VERSION = '6.08'
GAM_VERSION = '6.11'
GAM_LICENSE = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
GAM_URL = 'https://git.io/gam'
@@ -631,6 +631,7 @@ MACOS_CODENAMES = {
16: 'Big Sur'
},
11: 'Big Sur',
12: 'Monterey',
}
_MICROSOFT_FORMATS_LIST = [{

View File

@@ -4,7 +4,7 @@ filelock
google-api-python-client>=2.1
google-auth-httplib2
google-auth-oauthlib>=0.4.1
google-auth>=1.11.2
google-auth>=2.3.2
httplib2>=0.17.0
importlib.metadata; python_version < '3.8'
passlib>=1.7.2

View File

@@ -1,13 +1,11 @@
#!/usr/bin/env python3
#from packaging import version
from distutils.version import LooseVersion
from packaging import version
import sys
a = sys.argv[1]
b = sys.argv[2]
#result = version.parse(a) >= version.parse(b)
result = LooseVersion(a) >= LooseVersion(b)
result = version.parse(a) >= version.parse(b)
if result:
print('OK: %s is equal or newer than %s' % (a, b))
else: