mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-16 20:21:37 +00:00
Compare commits
17 Commits
20250305.1
...
20250330.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d308ad1271 | ||
|
|
09be8b08f7 | ||
|
|
10a91091f2 | ||
|
|
16cef20094 | ||
|
|
e588c8851a | ||
|
|
d14cd1ad56 | ||
|
|
0e82964068 | ||
|
|
6394207c2f | ||
|
|
f12b367019 | ||
|
|
9b130ac8bf | ||
|
|
f35bde4f8b | ||
|
|
9ffabc15ff | ||
|
|
212460b636 | ||
|
|
be0dcbc8d4 | ||
|
|
b9ca2ba9a1 | ||
|
|
c4dea95f08 | ||
|
|
7b59b648c7 |
@@ -102,7 +102,7 @@ If an item contains spaces, it should be surrounded by ".
|
||||
banana|basil|blueberry|flamingo|graphite|grape|
|
||||
lavender|peacock|sage|tangerine|tomato
|
||||
<FileFormat> ::=
|
||||
csv|doc|dot|docx|dotx|epub|html|jpeg|jpg|mht|odp|ods|odt|
|
||||
csv|doc|dot|docx|dotx|epub|html|jpeg|jpg|json|mht|odp|ods|odt|
|
||||
pdf|png|ppt|pot|potx|pptx|rtf|svg|tsv|txt|xls|xlt|xlsx|xltx|zip|
|
||||
ms|microsoft|openoffice|
|
||||
<LabelColorHex> ::=
|
||||
@@ -266,6 +266,7 @@ If an item contains spaces, it should be surrounded by ".
|
||||
appsheetstandard | appsheetenterprisestandard | 1010380002 | AppSheet Enterprise Standard |
|
||||
appsheetplus | appsheetenterpriseplus | 1010380003 | AppSheet Enterprise Plus |
|
||||
assuredcontrols | 1010390001 | Assured Controls |
|
||||
assuredcontrolsplus | 1010390002 | Assured Controls Plus |
|
||||
bce | beyondcorp | beyondcorpenterprise | cep | chromeenterprisepremium | 1010400001 | Chrome Enterprise Premium |
|
||||
cdm | chrome | googlechromedevicemanagement | Google-Chrome-Device-Management |
|
||||
cloudidentity | identity | 1010010001 | Cloud Identity |
|
||||
@@ -281,11 +282,15 @@ If an item contains spaces, it should be surrounded by ".
|
||||
gsuitebasic | gafb | gafw | basic | Google-Apps-For-Business |
|
||||
gsuitebusiness | gau | gsb | unlimited | Google-Apps-Unlimited |
|
||||
gsuitebusinessarchived | gsbau | businessarchived | 1010340002 | Google Workspace Business - Archived User |
|
||||
gsuiteedu | gafe | gsuiteeducation | Google-Apps-For-Education |
|
||||
gsuiteenterprisearchived | gseau | enterprisearchived | 1010340001 | Google Workspace Enterprise Plus - Archived User |
|
||||
gsuiteenterpriseeducation | gsefe | e4e | 1010310002 | Google Workspace for Education Plus - Legacy |
|
||||
gsuiteenterpriseeducationstudent | gsefes | e4es | 1010310003 | Google Workspace for Education Plus - Legacy (Student) |
|
||||
gsuitegov | gafg | gsuitegovernment | Google-Apps-For-Government |
|
||||
gsuitelite | gal | gsl | lite | Google-Apps-Lite |
|
||||
gwef | workspaceeducationfundamentals | 1010070001 | Google Workspace for Education Fundamentals |
|
||||
gwefau | gwefarchived | workspaceeducationfundamentalsarchived | 1010340007 | Google Workspace for Education Fundamentals - Archived User |
|
||||
gwegmo | workspaceeducationgmailonly | 1010070004 | Google Workspace for Education Gmail Only |
|
||||
gwep | workspaceeducationplus | 1010310008 | Google Workspace for Education Plus |
|
||||
gwepstaff | workspaceeducationplusstaff | 1010310009 | Google Workspace for Education Plus (Staff) |
|
||||
gwepstudent | workspaceeducationplusstudent | 1010310010 | Google Workspace for Education Plus (Extra Student)|
|
||||
@@ -1271,8 +1276,8 @@ If the pattern {{Section}} appears in <FileName>, it will be replaced with the n
|
||||
For redirect csv, the optional arguments must appear in the order shown.
|
||||
<Redirect> ::=
|
||||
redirect csv <FileName> [multiprocess] [append] [noheader] [charset <Charset>]
|
||||
[columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>]
|
||||
[sortheaders <StringList>] [timestampcolumn <String>]
|
||||
[columndelimiter <Character>] [quotechar <Character>] [noescapechar [<Boolean>]]
|
||||
[sortheaders <StringList>] [timestampcolumn <String>] [transpose [<Bopolean>]]
|
||||
[todrive <ToDriveAttribute>*] |
|
||||
redirect stdout <FileName> [multiprocess] [append] |
|
||||
redirect stdout null [multiprocess] |
|
||||
@@ -3921,6 +3926,10 @@ gam print group-members [todrive <ToDriveAttribute>*]
|
||||
|
||||
# Cloud Identity Groups
|
||||
|
||||
<CBCMBrowser> ::= id:cbcm-browser.<DeviceId>
|
||||
<ChromeOSDevice> ::= id:chrome-os-device.<DeviceId>
|
||||
<BrowserDeviceList> ::= "(<CBCMBrowser>|<ChromeOSDevice>)(,(<CBCMBrowser>|<ChromeOSDevice>))*"
|
||||
|
||||
<CIGroupFieldsName> ::=
|
||||
additionalgroupkeys|
|
||||
createtime|
|
||||
@@ -3950,12 +3959,12 @@ gam update cigroups <GroupEntity> create|add [<GroupRole>]
|
||||
[usersonly|groupsonly]
|
||||
[notsuspended|suspended] [notarchived|archived]
|
||||
[expire|expires <Time>] [preview] [actioncsv]
|
||||
<UserTypeEntity>
|
||||
<UserTypeEntity>|<BrowserDeviceList>
|
||||
gam update cigroups <GroupEntity> delete|remove [<GroupRole>]
|
||||
[usersonly|groupsonly]
|
||||
[notsuspended|suspended] [notarchived|archived]
|
||||
[preview] [actioncsv]
|
||||
<UserTypeEntity>
|
||||
<UserTypeEntity>|<BrowserDeviceList>
|
||||
gam update cigroups <GroupEntity> sync [<GroupRole>|ignorerole]
|
||||
[usersonly|groupsonly] [addonly|removeonly]
|
||||
[notsuspended|suspended] [notarchived|archived]
|
||||
|
||||
@@ -1,3 +1,86 @@
|
||||
7.05.18
|
||||
|
||||
Updated `gam calendars <CalendarEntity> show events` and `gam <UserTypeEntity> show events`
|
||||
to display the event description according to `show_convert_cr_nl` in `gam.cfg`;
|
||||
previously, GAM assumed `show_convert_cr_nl = true`.
|
||||
```
|
||||
show_convert_cr_nl = false
|
||||
description:
|
||||
Line 1
|
||||
Line 2
|
||||
Line 3
|
||||
|
||||
show_convert_cr_nl = true
|
||||
description: Line 1\nLine 2\nLine 3\n
|
||||
```
|
||||
|
||||
7.05.17
|
||||
|
||||
Updated commands that delete drive ACLs to handle the following error:
|
||||
```
|
||||
ERROR: 403: cannotDeletePermission - The authenticated user does not have the required access to delete the permission.
|
||||
```
|
||||
|
||||
7.05.16
|
||||
|
||||
Added option `transpose [<Boolean>]` to `redirect csv` that causes
|
||||
GAM to transpose CSV output rows and columns. This will most useful
|
||||
when a `countsonly` option is used in a `print` or `report` command.
|
||||
|
||||
7.05.15
|
||||
|
||||
Updated `gam <UserTypeEntity> get drivefile` and `gam <UserTypeEntity> create drivefile`
|
||||
to allow downloading and uploading of Google Apps Scripts.
|
||||
```
|
||||
$ gam user user1@domain.com get drivefile 1ZY-YkS3E0OKipALra_XzfIh9cvxoILSbb8TRdHBFCpyB_mXI_J8FmjHv format json
|
||||
User: user1@domain.com, Download 1 Drive File
|
||||
User: user1@domain.com, Drive File: Test Project, Downloaded to: /Users/gamteam/GamWork/Test Project.json, Type: Google Doc
|
||||
$ gam user user2@domain.com create drivefile localfile "Test Project.json" mimetype application/vnd.google-apps.script+json drivefilename "Test Project"
|
||||
User: user2@domain.com, Drive File: Test Project(1Ok_svw55VTreZ5CzcViJDLfEzVRi-Un8D9eG6I5pIeVyRl2YsmNiy3C_), Created with content from: Test Project.json
|
||||
```
|
||||
|
||||
7.05.14
|
||||
|
||||
Added the following License SKU:
|
||||
```
|
||||
ProductId SKUId Display Name
|
||||
101039 1010390002 Assured Controls Plus
|
||||
```
|
||||
|
||||
7.05.13
|
||||
|
||||
Updated license product names to match Google.
|
||||
|
||||
7.05.12
|
||||
|
||||
Fixed bug in `gam update chromepolicy` where `appid` was misinterpreted for `chrome.devices.kiosk` policies
|
||||
and an error was generated.
|
||||
```
|
||||
ERROR: Chrome Policy Schema: customers/C123abc456/policySchemas/<Field>, Does not exist
|
||||
```
|
||||
|
||||
7.05.11
|
||||
|
||||
Added the following License SKUs:
|
||||
```
|
||||
ProductId SKUId Display Name
|
||||
Google-Apps 1010070001 Google Workspace for Education Fundamentals
|
||||
Google-Apps 1010070004 Google Workspace for Education Gmail Only
|
||||
101034 1010340007 Google Workspace for Education Fundamentals - Archived User
|
||||
```
|
||||
|
||||
7.05.10
|
||||
|
||||
Updated various chat space commands to handle the following error:
|
||||
```
|
||||
ERROR: 503: serviceNotAvailable - The service is currently unavailable
|
||||
```
|
||||
|
||||
7.05.09
|
||||
|
||||
Fixed bug in `gam calendars <CalendarEntity> print events matchfield attendeesstatus required accepted resource_calendar@resource.calendar.google.com`
|
||||
that caused a trap.
|
||||
|
||||
7.05.08
|
||||
|
||||
Added error message to `gam report` commands to indicate forbidden access;
|
||||
|
||||
@@ -21,7 +21,7 @@ EOF
|
||||
}
|
||||
|
||||
target_dir="$HOME/bin"
|
||||
target_gam="gam7/gam"
|
||||
target_folder="$target_dir/gam7"
|
||||
gamarch=$(uname -m)
|
||||
gamos=$(uname -s)
|
||||
osversion=""
|
||||
@@ -36,7 +36,7 @@ while getopts "hd:a:o:b:lp:u:r:v:s" OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
h) usage; exit;;
|
||||
d) target_dir="$OPTARG";;
|
||||
d) target_dir="${OPTARG%/}"; target_folder="$target_dir/gam7";;
|
||||
a) gamarch="$OPTARG";;
|
||||
o) gamos="$OPTARG";;
|
||||
b) osversion="$OPTARG";;
|
||||
@@ -45,13 +45,11 @@ do
|
||||
u) adminuser="$OPTARG";;
|
||||
r) regularuser="$OPTARG";;
|
||||
v) gamversion="$OPTARG";;
|
||||
s) strip_gam="--strip-components 1"; target_gam="gam";;
|
||||
s) strip_gam="--strip-components 1"; target_folder="$target_dir";;
|
||||
?) usage; exit;;
|
||||
esac
|
||||
done
|
||||
|
||||
# remove possible / from end of target_dir
|
||||
target_dir=${target_dir%/}
|
||||
target_gam="$target_folder/gam"
|
||||
|
||||
update_profile() {
|
||||
[ "$2" -eq 1 ] || [ -f "$1" ] || return 1
|
||||
@@ -328,9 +326,9 @@ echo_yellow "Downloading ${download_url} to $temp_archive_dir ($check_type)..."
|
||||
# Save archive to temp w/o losing our path
|
||||
(cd "$temp_archive_dir" && curl -O -L -s "${curl_opts[@]}" "$download_url")
|
||||
|
||||
mkdir -p "$target_dir"
|
||||
echo_yellow "Deleting contents of $target_dir/gam7/lib"
|
||||
rm -frv "$target_dir/gam7/lib"
|
||||
mkdir -p "$target_folder"
|
||||
echo_yellow "Deleting contents of $target_folder/lib"
|
||||
rm -frv "$target_folder/lib"
|
||||
|
||||
echo_yellow "Extracting archive to $target_dir"
|
||||
if [[ "$name" =~ tar.xz|tar.gz|tar ]]; then
|
||||
@@ -351,7 +349,7 @@ fi
|
||||
|
||||
# Update profile to add gam command
|
||||
if [ "$update_profile" = true ]; then
|
||||
alias_line="alias gam=\"${target_dir// /\\ }/$target_gam\""
|
||||
alias_line="alias gam=\"$target_gam\""
|
||||
if [ "$gamos" == "linux" ]; then
|
||||
update_profile "$HOME/.bash_aliases" 0 || update_profile "$HOME/.bash_profile" 0 || update_profile "$HOME/.bashrc" 0
|
||||
update_profile "$HOME/.zshrc" 0
|
||||
@@ -365,7 +363,7 @@ fi
|
||||
|
||||
if [ "$upgrade_only" = true ]; then
|
||||
echo_green "Here's information about your GAM upgrade:"
|
||||
"$target_dir/$target_gam" version extended
|
||||
"$target_gam" version extended
|
||||
rc=$?
|
||||
if (( $rc != 0 )); then
|
||||
echo_red "ERROR: Failed running GAM for the first time with return code $rc. Please report this error to GAM mailing list. Exiting."
|
||||
@@ -387,7 +385,7 @@ while true; do
|
||||
;;
|
||||
[Nn]*)
|
||||
# config_cmd="config no_browser true"
|
||||
touch "$target_dir/gam7/nobrowser.txt" > /dev/null 2>&1
|
||||
touch "$target_folder/nobrowser.txt" > /dev/null 2>&1
|
||||
break
|
||||
;;
|
||||
*)
|
||||
@@ -405,8 +403,8 @@ while true; do
|
||||
if [ "$adminuser" == "" ]; then
|
||||
read -p "Please enter your Google Workspace admin email address: " adminuser
|
||||
fi
|
||||
# "$target_dir/$target_gam" $config_cmd create project $adminuser
|
||||
"$target_dir/$target_gam" create project $adminuser
|
||||
# "$target_gam" $config_cmd create project $adminuser
|
||||
"$target_gam" create project $adminuser
|
||||
rc=$?
|
||||
if (( $rc == 0 )); then
|
||||
echo_green "Project creation complete."
|
||||
@@ -431,8 +429,8 @@ while $project_created; do
|
||||
read -p "Are you ready to authorize GAM to perform Google Workspace management operations as your admin account? (yes or no) " yn
|
||||
case $yn in
|
||||
[Yy]*)
|
||||
# "$target_dir/$target_gam" $config_cmd oauth create $adminuser
|
||||
"$target_dir/$target_gam" oauth create $adminuser
|
||||
# "$target_gam" $config_cmd oauth create $adminuser
|
||||
"$target_gam" oauth create $adminuser
|
||||
rc=$?
|
||||
if (( $rc == 0 )); then
|
||||
echo_green "Admin authorization complete."
|
||||
@@ -461,8 +459,8 @@ while $admin_authorized; do
|
||||
read -p "Please enter the email address of a regular Google Workspace user: " regularuser
|
||||
fi
|
||||
echo_yellow "Great! Checking service account scopes.This will fail the first time. Follow the steps to authorize and retry. It can take a few minutes for scopes to PASS after they've been authorized in the admin console."
|
||||
# "$target_dir/$target_gam" $config_cmd user $regularuser check serviceaccount
|
||||
"$target_dir/$target_gam" user $regularuser check serviceaccount
|
||||
# "$target_gam" $config_cmd user $regularuser check serviceaccount
|
||||
"$target_gam" user $regularuser check serviceaccount
|
||||
rc=$?
|
||||
if (( $rc == 0 )); then
|
||||
echo_green "Service account authorization complete."
|
||||
@@ -483,8 +481,8 @@ while $admin_authorized; do
|
||||
done
|
||||
|
||||
echo_green "Here's information about your new GAM installation:"
|
||||
#"$target_dir/$target_gam" $config_cmd save version extended
|
||||
"$target_dir/$target_gam" version extended
|
||||
#"$target_gam" $config_cmd save version extended
|
||||
"$target_gam" version extended
|
||||
rc=$?
|
||||
if (( $rc != 0 )); then
|
||||
echo_red "ERROR: Failed running GAM for the first time with $rc. Please report this error to GAM mailing list. Exiting."
|
||||
|
||||
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
|
||||
"""
|
||||
|
||||
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
||||
__version__ = '7.05.08'
|
||||
__version__ = '7.05.18'
|
||||
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
||||
|
||||
#pylint: disable=wrong-import-position
|
||||
@@ -262,6 +262,7 @@ MIMETYPE_GA_JAM = f'{APPLICATION_VND_GOOGLE_APPS}jam'
|
||||
MIMETYPE_GA_MAP = f'{APPLICATION_VND_GOOGLE_APPS}map'
|
||||
MIMETYPE_GA_PRESENTATION = f'{APPLICATION_VND_GOOGLE_APPS}presentation'
|
||||
MIMETYPE_GA_SCRIPT = f'{APPLICATION_VND_GOOGLE_APPS}script'
|
||||
MIMETYPE_GA_SCRIPT_JSON = f'{APPLICATION_VND_GOOGLE_APPS}script+json'
|
||||
MIMETYPE_GA_SHORTCUT = f'{APPLICATION_VND_GOOGLE_APPS}shortcut'
|
||||
MIMETYPE_GA_3P_SHORTCUT = f'{APPLICATION_VND_GOOGLE_APPS}drive-sdk'
|
||||
MIMETYPE_GA_SITE = f'{APPLICATION_VND_GOOGLE_APPS}site'
|
||||
@@ -909,6 +910,8 @@ def getBoolean(defaultValue=True):
|
||||
Cmd.Advance()
|
||||
return False
|
||||
if defaultValue is not None:
|
||||
if not Cmd.Current().strip(): # If current argument is empty, skip over it
|
||||
Cmd.Advance()
|
||||
return defaultValue
|
||||
invalidChoiceExit(boolean, TRUE_FALSE, False)
|
||||
if defaultValue is not None:
|
||||
@@ -1482,6 +1485,8 @@ def getInteger(minVal=None, maxVal=None, default=None):
|
||||
return number
|
||||
except ValueError:
|
||||
if default is not None:
|
||||
if not Cmd.Current().strip(): # If current argument is empty, skip over it
|
||||
Cmd.Advance()
|
||||
return default
|
||||
invalidArgumentExit(integerLimits(minVal, maxVal))
|
||||
elif default is not None:
|
||||
@@ -4083,13 +4088,8 @@ def SetGlobalVariables():
|
||||
GC.Values[GC.OUTPUT_DATEFORMAT] = GM.Globals[GM.OUTPUT_DATEFORMAT]
|
||||
if not GC.Values[GC.OUTPUT_TIMEFORMAT]:
|
||||
GC.Values[GC.OUTPUT_TIMEFORMAT] = GM.Globals[GM.OUTPUT_TIMEFORMAT]
|
||||
# Create/set mode for oauth2.txt.lock
|
||||
if not GM.Globals[GM.OAUTH2_TXT_LOCK]:
|
||||
fileName = f'{GC.Values[GC.OAUTH2_TXT]}.lock'
|
||||
if not os.path.isfile(fileName):
|
||||
closeFile(openFile(fileName, mode=DEFAULT_FILE_APPEND_MODE))
|
||||
os.chmod(fileName, 0o666)
|
||||
GM.Globals[GM.OAUTH2_TXT_LOCK] = fileName
|
||||
# Define lockfile: oauth2.txt.lock
|
||||
GM.Globals[GM.OAUTH2_TXT_LOCK] = f'{GC.Values[GC.OAUTH2_TXT]}.lock'
|
||||
# Override httplib2 settings
|
||||
httplib2.debuglevel = GC.Values[GC.DEBUG_LEVEL]
|
||||
# Reset global variables if required
|
||||
@@ -4108,8 +4108,8 @@ def SetGlobalVariables():
|
||||
if checkArgumentPresent(Cmd.MULTIPROCESSEXIT_CMD):
|
||||
_setMultiprocessExit()
|
||||
# redirect csv <FileName> [multiprocess] [append] [noheader] [charset <CharSet>]
|
||||
# [columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>]]
|
||||
# [sortheaders <StringList>] [timestampcolumn <String>]
|
||||
# [columndelimiter <Character>] [quotechar <Character>]] [noescapechar [<Boolean>]]
|
||||
# [sortheaders <StringList>] [timestampcolumn <String>] [transpose [<Boolean>]]
|
||||
# [todrive <ToDriveAttribute>*]
|
||||
# redirect stdout <FileName> [multiprocess] [append]
|
||||
# redirect stdout null
|
||||
@@ -4134,6 +4134,8 @@ def SetGlobalVariables():
|
||||
GM.Globals[GM.CSV_OUTPUT_SORT_HEADERS] = GC.Values[GC.CSV_OUTPUT_SORT_HEADERS] = getString(Cmd.OB_STRING_LIST, minLen=0).replace(',', ' ').split()
|
||||
if checkArgumentPresent('timestampcolumn'):
|
||||
GM.Globals[GM.CSV_OUTPUT_TIMESTAMP_COLUMN] = GC.Values[GC.CSV_OUTPUT_TIMESTAMP_COLUMN] = getString(Cmd.OB_STRING, minLen=0)
|
||||
if checkArgumentPresent('transpose'):
|
||||
GM.Globals[GM.CSV_OUTPUT_TRANSPOSE] = getBoolean()
|
||||
_setCSVFile(filename, mode, encoding, writeHeader, multi)
|
||||
GM.Globals[GM.CSVFILE][GM.REDIRECT_QUEUE_CSVPF] = CSVPrintFile()
|
||||
if checkArgumentPresent('todrive'):
|
||||
@@ -4442,7 +4444,7 @@ def handleOAuthTokenError(e, softErrors, displayError=False, i=0, count=0):
|
||||
if not GM.Globals[GM.CURRENT_SVCACCT_USER]:
|
||||
ClientAPIAccessDeniedExit()
|
||||
if softErrors:
|
||||
entityDoesNotExistWarning(Ent.USER, GM.Globals[GM.CURRENT_SVCACCT_USER], i, count)
|
||||
entityActionFailedWarning([Ent.USER, GM.Globals[GM.CURRENT_SVCACCT_USER], Ent.USER, None], errMsg, i, count)
|
||||
return None
|
||||
systemErrorExit(SERVICE_NOT_APPLICABLE_RC, Msg.SERVICE_NOT_APPLICABLE_THIS_ADDRESS.format(GM.Globals[GM.CURRENT_SVCACCT_USER]))
|
||||
if errMsg in API.OAUTH2_UNAUTHORIZED_ERRORS:
|
||||
@@ -7789,6 +7791,7 @@ class CSVPrintFile():
|
||||
def __init__(self, titles=None, sortTitles=None, indexedTitles=None):
|
||||
self.rows = []
|
||||
self.rowCount = 0
|
||||
self.outputTranspose = GM.Globals[GM.CSV_OUTPUT_TRANSPOSE]
|
||||
self.todrive = GM.Globals[GM.CSV_TODRIVE]
|
||||
self.titlesSet = set()
|
||||
self.titlesList = []
|
||||
@@ -8988,6 +8991,22 @@ class CSVPrintFile():
|
||||
self.JSONtitlesList = self.orderHeaders(self.JSONtitlesList)
|
||||
titlesList = self.JSONtitlesList
|
||||
normalizeSortHeaders()
|
||||
if self.outputTranspose:
|
||||
newRows = []
|
||||
pivotKey = titlesList[0]
|
||||
newTitlesList = [pivotKey]
|
||||
newTitlesSet = set(newTitlesList)
|
||||
for title in titlesList[1:]:
|
||||
newRow = {pivotKey: title}
|
||||
for row in self.rows:
|
||||
pivotValue = row[pivotKey]
|
||||
if pivotValue not in newTitlesSet:
|
||||
newTitlesSet.add(pivotValue)
|
||||
newTitlesList.append(pivotValue)
|
||||
newRow[pivotValue] = row.get(title)
|
||||
newRows.append(newRow)
|
||||
titlesList = newTitlesList
|
||||
self.rows = newRows
|
||||
if (not self.todrive) or self.todrive['localcopy']:
|
||||
if GM.Globals[GM.CSVFILE][GM.REDIRECT_NAME] == '-':
|
||||
if GM.Globals[GM.STDOUT][GM.REDIRECT_MULTI_FD]:
|
||||
@@ -11842,7 +11861,7 @@ def doCreateProject():
|
||||
# Try to set policy on project to allow Service Account Key Upload
|
||||
# orgp = getAPIService(API.ORGPOLICY, httpObj)
|
||||
# projectParent = f"projects/{projectInfo['projectId']}"
|
||||
# policyName = f'{projectParent}/policies/iam.disableServiceAccountKeyUpload'
|
||||
# policyName = f'{projectParent}/policies/iam.managed.disableServiceAccountKeyUpload'
|
||||
# try:
|
||||
# result = callGAPI(orgp.projects().policies(), 'get',
|
||||
# throwReasons=[GAPI.NOT_FOUND, GAPI.FAILED_PRECONDITION, GAPI.PERMISSION_DENIED],
|
||||
@@ -12646,7 +12665,7 @@ def doProcessSvcAcctKeys(mode=None, iam=None, projectId=None, clientEmail=None,
|
||||
return False
|
||||
except GAPI.failedPrecondition as e:
|
||||
entityActionFailedWarning([Ent.PROJECT, projectId, Ent.SVCACCT, clientEmail], str(e))
|
||||
if 'iam.disableServiceAccountKeyUpload' not in str(e):
|
||||
if 'iam.disableServiceAccountKeyUpload' not in str(e) and 'iam.managed.disableServiceAccountKeyUpload' not in str(e):
|
||||
return False
|
||||
if retry == maxRetries or mode != 'upload':
|
||||
sys.stdout.write(Msg.ENABLE_SERVICE_ACCOUNT_PRIVATE_KEY_UPLOAD.format(projectId))
|
||||
@@ -26380,6 +26399,7 @@ def printShowChatSpaces(users):
|
||||
bailOnInternalError=True,
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.INTERNAL_ERROR,
|
||||
GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
fields=fields, pageSize=CHAT_PAGE_SIZE, **kwargsCS)
|
||||
except (GAPI.notFound, GAPI.invalidArgument, GAPI.internalError, GAPI.permissionDenied) as e:
|
||||
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
||||
@@ -26798,6 +26818,7 @@ def syncChatMembers(users):
|
||||
members = callGAPIpages(chat.spaces().members(), 'list', 'memberships',
|
||||
pageMessage=_getChatPageMessage(Ent.CHAT_MEMBER, user, i, count, qfilter),
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
parent=parent, showGroups=groupsSpecified, pageSize=CHAT_PAGE_SIZE, **kwargs, **kwargsUAA)
|
||||
for member in members:
|
||||
if 'member' in member:
|
||||
@@ -26995,6 +27016,7 @@ def printShowChatMembers(users):
|
||||
bailOnInternalError=True,
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.INTERNAL_ERROR,
|
||||
GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
fields="nextPageToken,spaces(name,displayName,spaceType,membershipCount)", pageSize=CHAT_PAGE_SIZE,
|
||||
**kwargsCS)
|
||||
for space in spaces:
|
||||
@@ -27011,6 +27033,7 @@ def printShowChatMembers(users):
|
||||
bailOnInternalError=True,
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.INTERNAL_ERROR,
|
||||
GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
fields="nextPageToken,spaces(name,displayName,spaceType,membershipCount)", pageSize=CHAT_PAGE_SIZE,
|
||||
**kwargsCS)
|
||||
for space in spaces:
|
||||
@@ -27355,6 +27378,7 @@ def printShowChatMessages(users):
|
||||
messages = callGAPIpages(chat.spaces().messages(), 'list', 'messages',
|
||||
pageMessage=_getChatPageMessage(Ent.CHAT_MESSAGE, user, i, count, qfilter),
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
pageSize=CHAT_PAGE_SIZE, parent=parentName, filter=pfilter, showDeleted=showDeleted,
|
||||
fields=fields)
|
||||
for message in messages:
|
||||
@@ -27472,6 +27496,7 @@ def printShowChatEvents(users):
|
||||
events = callGAPIpages(chat.spaces().spaceEvents(), 'list', 'spaceEvents',
|
||||
pageMessage=_getChatPageMessage(Ent.CHAT_EVENT, user, i, count, qfilter),
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
pageSize=CHAT_PAGE_SIZE, parent=parentName, filter=pfilter)
|
||||
except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e:
|
||||
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
||||
@@ -28192,6 +28217,7 @@ def doUpdateChromePolicy():
|
||||
schemaName, schema = simplifyChromeSchema(_getChromePolicySchema(cp, Cmd.Previous(), '*'))
|
||||
body['requests'].append({'policyValue': {'policySchema': schemaName, 'value': {}},
|
||||
'updateMask': ''})
|
||||
schemaNameList.append(schemaName)
|
||||
while Cmd.ArgumentsRemaining():
|
||||
field = getArgumentEmptyAllowed()
|
||||
# Allow an empty field/value pair which makes processing an input CSV file with schemas with different numbers of fields easy
|
||||
@@ -28200,8 +28226,9 @@ def doUpdateChromePolicy():
|
||||
Cmd.Advance()
|
||||
continue
|
||||
if field in {'ou', 'org', 'orgunit', 'group', 'printerid', 'appid'} or '.' in field:
|
||||
Cmd.Backup()
|
||||
break # field is actually a new policy name or orgunit
|
||||
if field != 'appid' or not schemaName.startswith('chrome.devices.kiosk'):
|
||||
Cmd.Backup()
|
||||
break # field is actually a new policy name or orgunit
|
||||
# JSON
|
||||
if field == 'json':
|
||||
jsonData = getJSON(['direct', 'name', 'orgUnitPath', 'parentOrgUnitPath', 'group'])
|
||||
@@ -28212,7 +28239,7 @@ def doUpdateChromePolicy():
|
||||
body['requests'][-1]['policyTargetKey']['additionalTargetKeys'] = {atk['name']: atk['value']}
|
||||
if atk['name'] == 'app_id':
|
||||
schemaNameAppId += f"({atk['value']})"
|
||||
schemaNameList.append(schemaNameAppId)
|
||||
schemaNameList[-1] = schemaNameAppId
|
||||
for field in jsonData.get('fields', []):
|
||||
casedField = field['name']
|
||||
lowerField = casedField.lower()
|
||||
@@ -28253,7 +28280,6 @@ def doUpdateChromePolicy():
|
||||
body['requests'][-1]['policyValue']['value'][casedField] = value
|
||||
body['requests'][-1]['updateMask'] += f'{casedField},'
|
||||
break
|
||||
schemaNameList.append(schemaName)
|
||||
# Handle TYPE_MESSAGE fields with durations, values, counts and timeOfDay as special cases
|
||||
tmschema = CHROME_SCHEMA_TYPE_MESSAGE.get(schemaName, {}).get(field)
|
||||
if tmschema:
|
||||
@@ -38688,7 +38714,7 @@ def _getEventMatchFields(calendarEventEntity, fieldsList):
|
||||
else:
|
||||
fieldsList.append('attendees/email')
|
||||
if match[0][1] == 'status':
|
||||
fieldsList.extend('attendees/optional', 'attendees/responseStatus')
|
||||
fieldsList.extend(['attendees/optional', 'attendees/responseStatus'])
|
||||
|
||||
def _eventMatches(event, match):
|
||||
if match[0][0] != 'attendees':
|
||||
@@ -39379,7 +39405,10 @@ def _showCalendarEvent(primaryEmail, calId, eventEntityType, event, k, kcount, F
|
||||
Ind.Increment()
|
||||
for field in EVENT_SHOW_ORDER:
|
||||
if field in event:
|
||||
showJSON(field, event[field], skipObjects, EVENT_TIME_OBJECTS)
|
||||
if field != 'description':
|
||||
showJSON(field, event[field], skipObjects, EVENT_TIME_OBJECTS)
|
||||
else:
|
||||
printKeyValueWithCRsNLs(field, event[field])
|
||||
skipObjects.add(field)
|
||||
showJSON(None, event, skipObjects)
|
||||
Ind.Decrement()
|
||||
@@ -42466,16 +42495,16 @@ class PasswordOptions():
|
||||
up = 'password'
|
||||
password = self.GetPassword()
|
||||
if password:
|
||||
notFoundBody[up] = password
|
||||
if notFoundBody[up].lower() in {'blocklogin'}:
|
||||
if password.lower() == 'blocklogin':
|
||||
self.makeCleanPassword = False
|
||||
notFoundBody[up] = self.CreateRandomPassword()
|
||||
self.notFoundPassword = notFoundBody[up]
|
||||
elif notFoundBody[up].lower() in {'random', 'uniquerandom'}:
|
||||
elif password.lower() in {'random', 'uniquerandom'}:
|
||||
self.SetCleanPasswordLen()
|
||||
self.makeCleanPassword = True
|
||||
notFoundBody[up] = self.CreateRandomPassword()
|
||||
self.notFoundPassword = notFoundBody[up]
|
||||
else:
|
||||
notFoundBody[up] = password
|
||||
self.notFoundPassword = notFoundBody[up]
|
||||
elif myarg in {'lograndompassword', 'logpassword'}:
|
||||
self.filename = getString(Cmd.OB_FILE_NAME)
|
||||
else:
|
||||
@@ -42518,6 +42547,8 @@ class PasswordOptions():
|
||||
self.promptForUniquePassword = True
|
||||
else:
|
||||
self.promptForPassword = True
|
||||
else:
|
||||
self.password = password
|
||||
elif up == 'hashFunction':
|
||||
body[up] = self.HASH_FUNCTION_MAP[myarg]
|
||||
self.clearPassword = self.hashPassword = False
|
||||
@@ -43027,7 +43058,7 @@ def getUserAttributes(cd, updateCmd, noUid=False):
|
||||
if value:
|
||||
entry[argument] = value
|
||||
else:
|
||||
entry[argument] = getInteger(minVal=0, maxVal=100000)
|
||||
entry[argument] = getInteger(minVal=0, maxVal=100000, default=0)
|
||||
elif primaryNotPrimary(argument, entry):
|
||||
break
|
||||
else:
|
||||
@@ -43230,9 +43261,7 @@ def doCreateUser():
|
||||
cd = buildGAPIObject(API.DIRECTORY)
|
||||
body, notify, tagReplacements, addGroups, addAliases, PwdOpts, \
|
||||
_, _, _, \
|
||||
parameters, resolveConflictAccount = getUserAttributes(cd,
|
||||
False,
|
||||
noUid=True)
|
||||
parameters, resolveConflictAccount = getUserAttributes(cd, False, noUid=True)
|
||||
suffix = 0
|
||||
originalEmail = body['primaryEmail']
|
||||
atLoc = originalEmail.find('@')
|
||||
@@ -43340,8 +43369,7 @@ def updateUsers(entityList):
|
||||
updateRetryDelay = 5
|
||||
body, notify, tagReplacements, addGroups, addAliases, PwdOpts, \
|
||||
updatePrimaryEmail, notFoundBody, groupOrgUnitMap, \
|
||||
parameters, resolveConflictAccount = getUserAttributes(cd,
|
||||
True)
|
||||
parameters, resolveConflictAccount = getUserAttributes(cd, True)
|
||||
vfe = 'primaryEmail' in body and body['primaryEmail'][:4].lower() == 'vfe@'
|
||||
if body.get('orgUnitPath', '') and parameters['immutableOUs']:
|
||||
ubody = body.copy()
|
||||
@@ -57392,6 +57420,8 @@ def createDriveFile(users):
|
||||
if parameters[DFA_LOCALFILEPATH]:
|
||||
if parameters[DFA_LOCALFILEPATH] != '-' and parameters[DFA_PRESERVE_FILE_TIMES]:
|
||||
setPreservedFileTimes(body, parameters, False)
|
||||
if body.get('mimeType') == MIMETYPE_GA_SCRIPT_JSON:
|
||||
parameters[DFA_LOCALMIMETYPE] = body['mimeType']
|
||||
media_body = getMediaBody(parameters)
|
||||
elif parameters[DFA_URL]:
|
||||
media_body = getMediaBody(parameters)
|
||||
@@ -58713,7 +58743,7 @@ def _copyPermissions(drive, user, i, count, j, jcount,
|
||||
except (GAPI.notFound, GAPI.permissionNotFound,
|
||||
GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission,
|
||||
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded) as e:
|
||||
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e:
|
||||
entityActionFailedWarning(kvList, str(e), k, kcount)
|
||||
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||
userDriveServiceNotEnabledWarning(user, str(e), i, count)
|
||||
@@ -59744,7 +59774,7 @@ def _updateMoveFilePermissions(drive, user, i, count,
|
||||
except (GAPI.notFound, GAPI.permissionNotFound,
|
||||
GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission,
|
||||
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded) as e:
|
||||
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e:
|
||||
entityActionFailedWarning(kvList, str(e), k, kcount)
|
||||
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||
userDriveServiceNotEnabledWarning(user, str(e), i, count)
|
||||
@@ -60429,6 +60459,7 @@ GOOGLEDOC_VALID_EXTENSIONS_MAP = {
|
||||
MIMETYPE_GA_DOCUMENT: ['.docx', '.epub', '.html', '.odt', '.pdf', '.rtf', '.txt', '.zip'],
|
||||
MIMETYPE_GA_JAM: ['.pdf'],
|
||||
MIMETYPE_GA_PRESENTATION: ['.pdf', '.pptx', '.odp', '.txt'],
|
||||
MIMETYPE_GA_SCRIPT: ['.json'],
|
||||
MIMETYPE_GA_SPREADSHEET: ['.csv', '.ods', '.pdf', '.tsv', '.xlsx', '.zip'],
|
||||
}
|
||||
|
||||
@@ -60464,6 +60495,7 @@ DOCUMENT_FORMATS_MAP = {
|
||||
'html': [{'mime': 'text/html', 'ext': '.html'}],
|
||||
'jpeg': [{'mime': 'image/jpeg', 'ext': '.jpeg'}],
|
||||
'jpg': [{'mime': 'image/jpeg', 'ext': '.jpg'}],
|
||||
'json': [{'mime': MIMETYPE_GA_SCRIPT_JSON, 'ext': '.json'}],
|
||||
'mht': [{'mime': 'message/rfc822', 'ext': 'mht'}],
|
||||
'odp': [{'mime': 'application/vnd.oasis.opendocument.presentation', 'ext': '.odp'}],
|
||||
'ods': [{'mime': 'application/x-vnd.oasis.opendocument.spreadsheet', 'ext': '.ods'},
|
||||
@@ -61445,7 +61477,7 @@ def transferDrive(users):
|
||||
if showRetentionMessages:
|
||||
entityActionPerformed([Ent.USER, sourceUser, childFileType, childFileName, Ent.ROLE, ownerRetainRoleBody['role']], j, jcount)
|
||||
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||
GAPI.badRequest, GAPI.sharingRateLimitExceeded, GAPI.cannotRemoveOwner) as e:
|
||||
GAPI.badRequest, GAPI.sharingRateLimitExceeded, GAPI.cannotRemoveOwner, GAPI.cannotDeletePermission) as e:
|
||||
entityActionFailedWarning([Ent.USER, sourceUser, childFileType, childFileName], str(e), j, jcount)
|
||||
except GAPI.permissionNotFound:
|
||||
entityDoesNotHaveItemWarning([Ent.USER, sourceUser, childFileType, childFileName, Ent.PERMISSION_ID, sourcePermissionId], j, jcount)
|
||||
@@ -61498,7 +61530,7 @@ def transferDrive(users):
|
||||
if showRetentionMessages:
|
||||
entityActionPerformed([Ent.USER, sourceUser, childFileType, childFileName, Ent.ROLE, sourceUpdateRole['role']], j, jcount)
|
||||
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||
GAPI.badRequest, GAPI.sharingRateLimitExceeded, GAPI.cannotRemoveOwner) as e:
|
||||
GAPI.badRequest, GAPI.sharingRateLimitExceeded, GAPI.cannotRemoveOwner, GAPI.cannotDeletePermission) as e:
|
||||
entityActionFailedWarning([Ent.USER, ownerUser, childFileType, childFileName], str(e), j, jcount)
|
||||
except GAPI.permissionNotFound:
|
||||
entityDoesNotHaveItemWarning([Ent.USER, ownerUser, childFileType, childFileName, Ent.PERMISSION_ID, sourcePermissionId], j, jcount)
|
||||
@@ -61522,7 +61554,7 @@ def transferDrive(users):
|
||||
if showRetentionMessages:
|
||||
entityActionPerformed([Ent.USER, targetUser, childFileType, childFileName, Ent.ROLE, targetInsertBody['role']], j, jcount)
|
||||
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||
GAPI.badRequest, GAPI.sharingRateLimitExceeded) as e:
|
||||
GAPI.badRequest, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e:
|
||||
entityActionFailedWarning([Ent.USER, ownerUser, childFileType, childFileName], str(e), j, jcount)
|
||||
except GAPI.invalidSharingRequest as e:
|
||||
entityActionFailedWarning([Ent.USER, ownerUser, childFileType, childFileName], Ent.TypeNameMessage(Ent.PERMISSION_ID, targetPermissionId, str(e)), j, jcount)
|
||||
@@ -62265,7 +62297,7 @@ def claimOwnership(users):
|
||||
entityActionPerformed([Ent.USER, oldOwner, entityType, fileDesc, Ent.ROLE, sourceRetainRoleBody['role']], l, lcount)
|
||||
except GAPI.permissionNotFound:
|
||||
entityDoesNotHaveItemWarning([Ent.USER, oldOwner, entityType, fileDesc, Ent.PERMISSION_ID, oldOwnerPermissionId], l, lcount)
|
||||
except (GAPI.badRequest, GAPI.insufficientFilePermissions) as e:
|
||||
except (GAPI.badRequest, GAPI.insufficientFilePermissions, GAPI.cannotDeletePermission) as e:
|
||||
entityActionFailedWarning([Ent.USER, oldOwner, entityType, fileDesc], str(e), l, lcount)
|
||||
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||
userDriveServiceNotEnabledWarning(user, str(e), i, count)
|
||||
@@ -63437,7 +63469,7 @@ def deleteDriveFileACLs(users, useDomainAdminAccess=False):
|
||||
_updateSheetProtectedRangesACLchange(sheet, user, i, count, j, jcount, fileId, fileName, False, permission)
|
||||
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||
GAPI.fileNeverWritable, GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission,
|
||||
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded) as e:
|
||||
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.cannotDeletePermission) as e:
|
||||
entityActionFailedWarning([Ent.USER, user, entityType, fileName], str(e), j, jcount)
|
||||
except GAPI.notFound as e:
|
||||
entityActionFailedWarning([Ent.USER, user, Ent.SHAREDDRIVE, fileName], str(e), j, jcount)
|
||||
@@ -63493,7 +63525,7 @@ def deletePermissions(users, useDomainAdminAccess=False):
|
||||
entityActionPerformed([Ent.DRIVE_FILE_OR_FOLDER_ID, ri[RI_ENTITY], Ent.PERMISSION_ID, ri[RI_ITEM]], int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
||||
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||
GAPI.badRequest, GAPI.cannotRemoveOwner, GAPI.cannotModifyInheritedTeamDrivePermission,
|
||||
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.permissionNotFound,
|
||||
GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded, GAPI.permissionNotFound, GAPI.cannotDeletePermission,
|
||||
GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||
entityActionFailedWarning([Ent.DRIVE_FILE_OR_FOLDER_ID, ri[RI_ENTITY], Ent.PERMISSION_ID, ri[RI_ITEM]], str(e), int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
||||
if int(ri[RI_J]) == int(ri[RI_JCOUNT]):
|
||||
|
||||
@@ -108,7 +108,7 @@ class MockHttpClient(atom.http_interface.GenericHttpClient):
|
||||
for recording in self.recordings:
|
||||
if recording[0].operation == operation and recording[0].url == url:
|
||||
return recording[1]
|
||||
raise NoRecordingFound('No recodings found for %s %s' % (
|
||||
raise NoRecordingFound('No recordings found for %s %s' % (
|
||||
operation, url))
|
||||
else:
|
||||
# There is a real HTTP client, so make the request, and record the
|
||||
|
||||
@@ -37,6 +37,7 @@ CANNOT_CHANGE_OWNER_ACL = 'cannotChangeOwnerAcl'
|
||||
CANNOT_CHANGE_OWN_PRIMARY_SUBSCRIPTION = 'cannotChangeOwnPrimarySubscription'
|
||||
CANNOT_COPY_FILE = 'cannotCopyFile'
|
||||
CANNOT_DELETE_ONLY_REVISION = 'cannotDeleteOnlyRevision'
|
||||
CANNOT_DELETE_PERMISSION = 'cannotDeletePermission'
|
||||
CANNOT_DELETE_PRIMARY_CALENDAR = 'cannotDeletePrimaryCalendar'
|
||||
CANNOT_DELETE_PRIMARY_SENDAS = 'cannotDeletePrimarySendAs'
|
||||
CANNOT_DELETE_RESOURCE_WITH_CHILDREN = 'cannotDeleteResourceWithChildren'
|
||||
@@ -246,7 +247,7 @@ DRIVE3_UPDATE_ACL_THROW_REASONS = [BAD_REQUEST, INVALID_OWNERSHIP_TRANSFER, CANN
|
||||
DRIVE3_DELETE_ACL_THROW_REASONS = [BAD_REQUEST, CANNOT_REMOVE_OWNER,
|
||||
CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION,
|
||||
INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, SHARING_RATE_LIMIT_EXCEEDED,
|
||||
NOT_FOUND, PERMISSION_NOT_FOUND]
|
||||
NOT_FOUND, PERMISSION_NOT_FOUND, CANNOT_DELETE_PERMISSION]
|
||||
DRIVE3_MODIFY_LABEL_THROW_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, NOT_FOUND, FORBIDDEN, INTERNAL_ERROR,
|
||||
FILE_NEVER_WRITABLE, APPLY_LABEL_FORBIDDEN,
|
||||
INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, INSUFFICIENT_FILE_PERMISSIONS,
|
||||
@@ -382,6 +383,8 @@ class cannotCopyFile(Exception):
|
||||
pass
|
||||
class cannotDeleteOnlyRevision(Exception):
|
||||
pass
|
||||
class cannotDeletePermission(Exception):
|
||||
pass
|
||||
class cannotDeletePrimaryCalendar(Exception):
|
||||
pass
|
||||
class cannotDeletePrimarySendAs(Exception):
|
||||
@@ -676,6 +679,7 @@ REASON_EXCEPTION_MAP = {
|
||||
CANNOT_CHANGE_OWN_PRIMARY_SUBSCRIPTION: cannotChangeOwnPrimarySubscription,
|
||||
CANNOT_COPY_FILE: cannotCopyFile,
|
||||
CANNOT_DELETE_ONLY_REVISION: cannotDeleteOnlyRevision,
|
||||
CANNOT_DELETE_PERMISSION: cannotDeletePermission,
|
||||
CANNOT_DELETE_PRIMARY_CALENDAR: cannotDeletePrimaryCalendar,
|
||||
CANNOT_DELETE_PRIMARY_SENDAS: cannotDeletePrimarySendAs,
|
||||
CANNOT_DELETE_RESOURCE_WITH_CHILDREN: cannotDeleteResourceWithChildren,
|
||||
|
||||
@@ -85,6 +85,8 @@ CSV_OUTPUT_ROW_FILTER_MODE = 'corm'
|
||||
CSV_OUTPUT_ROW_LIMIT = 'corl'
|
||||
# Add timestamp column to CSV output file
|
||||
CSV_OUTPUT_TIMESTAMP_COLUMN = 'cotc'
|
||||
# Transpose output rows/columns
|
||||
CSV_OUTPUT_TRANSPOSE = 'cotr'
|
||||
# Output sort headers
|
||||
CSV_OUTPUT_SORT_HEADERS = 'cosh'
|
||||
# CSV todrive options
|
||||
@@ -250,6 +252,7 @@ Globals = {
|
||||
CSV_OUTPUT_ROW_LIMIT: 0,
|
||||
CSV_OUTPUT_SORT_HEADERS: [],
|
||||
CSV_OUTPUT_TIMESTAMP_COLUMN: None,
|
||||
CSV_OUTPUT_TRANSPOSE: False,
|
||||
CSV_TODRIVE: {},
|
||||
CURRENT_API_SERVICES: {},
|
||||
CURRENT_CLIENT_API: None,
|
||||
|
||||
@@ -118,7 +118,7 @@ Your workspace is configured to disable service account private key uploads.
|
||||
|
||||
Please go to:
|
||||
|
||||
https://github.com/taers232c/GAMADV-XTD3/wiki/Authorization#authorize-service-account-key-uploads
|
||||
https://github.com/GAM-team/GAM/wiki/Authorization#authorize-service-account-key-uploads
|
||||
|
||||
Follow the steps to allow a service account private key upload for the project ({0}) just created.
|
||||
Once those steps are completed, you can continue with your project authentication.
|
||||
@@ -322,7 +322,7 @@ INVALID_NUMBER_OF_CHAT_SPACE_MEMBERS = '{0} type {1} number of members, {2}, mus
|
||||
INVALID_ORGUNIT = 'Invalid Organizational Unit'
|
||||
INVALID_PATH = 'Invalid Path'
|
||||
INVALID_PERMISSION_ATTRIBUTE_TYPE = 'permission attribute {0} not allowed with type {1}'
|
||||
INVALID_REGION = 'See: https://github.com/taers232c/GAMADV-XTD3/wiki/Context-Aware-Access-Levels#caa-region-codes'
|
||||
INVALID_REGION = 'See: https://github.com/GAM-team/GAM/wiki/Context-Aware-Access-Levels#caa-region-codes'
|
||||
INVALID_QUERY = 'Invalid Query'
|
||||
INVALID_RE = 'Invalid RE'
|
||||
INVALID_REQUEST = 'Invalid Request'
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
# Products/SKUs
|
||||
_PRODUCTS = {
|
||||
'101001': 'Cloud Identity Free',
|
||||
'101001': 'Cloud Identity',
|
||||
'101005': 'Cloud Identity Premium',
|
||||
'101031': 'Google Workspace for Education',
|
||||
'101033': 'Google Voice',
|
||||
@@ -47,6 +47,10 @@ _SKUS = {
|
||||
'product': '101001', 'aliases': ['identity', 'cloudidentity'], 'displayName': 'Cloud Identity'},
|
||||
'1010050001': {
|
||||
'product': '101005', 'aliases': ['identitypremium', 'cloudidentitypremium'], 'displayName': 'Cloud Identity Premium'},
|
||||
'1010070001': {
|
||||
'product': 'Google-Apps', 'aliases': ['gwef', 'workspaceeducationfundamentals'], 'displayName': 'Google Workspace for Education Fundamentals'},
|
||||
'1010070004': {
|
||||
'product': 'Google-Apps', 'aliases': ['gwegmo', 'workspaceeducationgmailonly'], 'displayName': 'Google Workspace for Education Gmail Only'},
|
||||
'1010310002': {
|
||||
'product': '101031', 'aliases': ['gsefe', 'e4e', 'gsuiteenterpriseeducation'], 'displayName': 'Google Workspace for Education Plus - Legacy'},
|
||||
'1010310003': {
|
||||
@@ -83,6 +87,8 @@ _SKUS = {
|
||||
'product': '101038', 'aliases': ['appsheetplus', 'appsheetenterpriseplus'], 'displayName': 'AppSheet Enterprise Plus'},
|
||||
'1010390001': {
|
||||
'product': '101039', 'aliases': ['assuredcontrols'], 'displayName': 'Assured Controls'},
|
||||
'1010390002': {
|
||||
'product': '101039', 'aliases': ['assuredcontrolsplus'], 'displayName': 'Assured Controls Plus'},
|
||||
'1010400001': {
|
||||
'product': '101040', 'aliases': ['beyondcorp', 'beyondcorpenterprise', 'bce', 'cep', 'chromeenterprisepremium'], 'displayName': 'Chrome Enterprise Premium'},
|
||||
'1010430001': {
|
||||
@@ -111,6 +117,8 @@ _SKUS = {
|
||||
'product': 'Google-Apps', 'aliases': ['standard', 'free'], 'displayName': 'G Suite Legacy'},
|
||||
'Google-Apps-For-Business': {
|
||||
'product': 'Google-Apps', 'aliases': ['gafb', 'gafw', 'basic', 'gsuitebasic'], 'displayName': 'G Suite Basic'},
|
||||
'Google-Apps-For-Education': {
|
||||
'product': 'Google-Apps', 'aliases': ['gafe', 'gsuiteeducation', 'gsuiteedu'], 'displayName': 'Google Workspace for Education - Fundamentals'},
|
||||
'Google-Apps-For-Government': {
|
||||
'product': 'Google-Apps', 'aliases': ['gafg', 'gsuitegovernment', 'gsuitegov'], 'displayName': 'Google Workspace Government'},
|
||||
'Google-Apps-For-Postini': {
|
||||
@@ -121,7 +129,7 @@ _SKUS = {
|
||||
'product': 'Google-Apps', 'aliases': ['gau', 'gsb', 'unlimited', 'gsuitebusiness'], 'displayName': 'G Suite Business'},
|
||||
'1010020020': {
|
||||
'product': 'Google-Apps', 'aliases': ['gae', 'gse', 'enterprise', 'gsuiteenterprise',
|
||||
'wsentplus', 'workspaceenterpriseplus'], 'displayName': 'Google Workspace Enterprise Plus'},
|
||||
'wsentplus', 'workspaceenterpriseplus'], 'displayName': 'Google Workspace Enterprise Plus (formerly G Suite Enterprise)'},
|
||||
'1010020025': {
|
||||
'product': 'Google-Apps', 'aliases': ['wsbizplus', 'workspacebusinessplus'], 'displayName': 'Google Workspace Business Plus'},
|
||||
'1010020026': {
|
||||
@@ -148,14 +156,16 @@ _SKUS = {
|
||||
'product': '101034', 'aliases': ['wsbizstarterarchived', 'workspacebusinessstarterarchived'], 'displayName': 'Google Workspace Business Starter - Archived User'},
|
||||
'1010340006': {
|
||||
'product': '101034', 'aliases': ['wsbizstanarchived', 'workspacebusinessstanarchived'], 'displayName': 'Google Workspace Business Standard - Archived User'},
|
||||
'1010340007': {
|
||||
'product': '101034', 'aliases': ['gwefau', 'gwefarchived', 'workspaceeducationfundamentalsarchived'], 'displayName': 'Google Workspace for Education Fundamentals - Archived User'},
|
||||
'1010060001': {
|
||||
'product': '101006', 'aliases': ['gsuiteessentials', 'essentials',
|
||||
'd4e', 'driveenterprise', 'drive4enterprise',
|
||||
'wsess', 'workspaceesentials'], 'displayName': 'Google Workspace Essentials'},
|
||||
'wsess', 'workspaceesentials'], 'displayName': 'Google Workspace Essentials (formerly G Suite Essentials)'},
|
||||
'1010060003': {
|
||||
'product': 'Google-Apps', 'aliases': ['wsentess', 'workspaceenterpriseessentials'], 'displayName': 'Google Workspace Enterprise Essentials'},
|
||||
'1010060005': {
|
||||
'product': 'Google-Apps', 'aliases': ['wsessplus', 'workspaceessentialsplus'], 'displayName': 'Google Workspace Essentials Plus'},
|
||||
'product': 'Google-Apps', 'aliases': ['wsessplus', 'workspaceessentialsplus'], 'displayName': 'Google Workspace Enterprise Essentials Plus'},
|
||||
'Google-Drive-storage-20GB': {
|
||||
'product': 'Google-Drive-storage', 'aliases': ['drive20gb', '20gb', 'googledrivestorage20gb'], 'displayName': 'Google Drive Storage 20GB'},
|
||||
'Google-Drive-storage-50GB': {
|
||||
|
||||
@@ -12,4 +12,4 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
__version__ = "2.156.0"
|
||||
__version__ = "2.164.0"
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
accesscontextmanager.googleapis.com
|
||||
admin.googleapis.com
|
||||
alertcenter.googleapis.com
|
||||
calendar-json.googleapis.com
|
||||
chat.googleapis.com
|
||||
chromemanagement.googleapis.com
|
||||
chromepolicy.googleapis.com
|
||||
classroom.googleapis.com
|
||||
cloudidentity.googleapis.com
|
||||
cloudresourcemanager.googleapis.com
|
||||
contacts.googleapis.com
|
||||
drive.googleapis.com
|
||||
driveactivity.googleapis.com
|
||||
iap.googleapis.com
|
||||
gmail.googleapis.com
|
||||
groupssettings.googleapis.com
|
||||
iam.googleapis.com
|
||||
licensing.googleapis.com
|
||||
reseller.googleapis.com
|
||||
sheets.googleapis.com
|
||||
siteverification.googleapis.com
|
||||
storage-api.googleapis.com
|
||||
vault.googleapis.com
|
||||
Reference in New Issue
Block a user