mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-28 09:51:36 +00:00
Compare commits
143 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2fc8c8d718 | ||
|
|
a3e5f7b504 | ||
|
|
4137b3b77b | ||
|
|
ce47c9bc7c | ||
|
|
d302563045 | ||
|
|
c5f4bb18fa | ||
|
|
0fdcab4c4f | ||
|
|
130a245906 | ||
|
|
d8bf368c92 | ||
|
|
e7b238e85e | ||
|
|
28b909a686 | ||
|
|
ce73c62e81 | ||
|
|
8e71e18aaa | ||
|
|
d78506fa9b | ||
|
|
a2b226a124 | ||
|
|
8412ba78b2 | ||
|
|
9d01e3fa27 | ||
|
|
9a981bf02e | ||
|
|
12667bf898 | ||
|
|
7e664b437d | ||
|
|
ad3d4e9a57 | ||
|
|
4f992f4d41 | ||
|
|
a987ff4eac | ||
|
|
05fd22565d | ||
|
|
8470949e82 | ||
|
|
f56bf838ad | ||
|
|
33d808ff4b | ||
|
|
35fde0e48b | ||
|
|
7c5e79f309 | ||
|
|
71bac7c2eb | ||
|
|
539b91a27e | ||
|
|
d71bf9b6cb | ||
|
|
0c2fdeee6b | ||
|
|
33df3132b8 | ||
|
|
118e1e3ff5 | ||
|
|
2fdab61fc8 | ||
|
|
a883bf721f | ||
|
|
ca20bcbda0 | ||
|
|
a927dda9aa | ||
|
|
a2d80cac46 | ||
|
|
fcf2712f3f | ||
|
|
8dc2b4bd64 | ||
|
|
679019fc3c | ||
|
|
c4da8110a3 | ||
|
|
7bcd0611c2 | ||
|
|
485cbb65bb | ||
|
|
29a2e224bc | ||
|
|
ac25dd6557 | ||
|
|
673effa9f8 | ||
|
|
a936a5fa3d | ||
|
|
a1b073cbdd | ||
|
|
093015c617 | ||
|
|
2bee44f7e9 | ||
|
|
645155a2ea | ||
|
|
da2298ae23 | ||
|
|
02188e9c49 | ||
|
|
28b5ab34c3 | ||
|
|
b338e2da2f | ||
|
|
b1af32e487 | ||
|
|
a32cc146ef | ||
|
|
1ed1d8552b | ||
|
|
4f58f7c967 | ||
|
|
c41b94487e | ||
|
|
7f95020e6f | ||
|
|
9181a35c10 | ||
|
|
c95997e2d5 | ||
|
|
9348f57141 | ||
|
|
dab6272d55 | ||
|
|
f548d49e19 | ||
|
|
081965fa79 | ||
|
|
bcef6f9391 | ||
|
|
dfb4c88b69 | ||
|
|
f10fca04c9 | ||
|
|
096eef3f59 | ||
|
|
f9cd2f56d6 | ||
|
|
91559239ca | ||
|
|
a00256ee9f | ||
|
|
970697ec65 | ||
|
|
06d131ec55 | ||
|
|
094616e482 | ||
|
|
cbfae9226a | ||
|
|
c35cdcf4c3 | ||
|
|
d87ece177d | ||
|
|
41535666b6 | ||
|
|
20d1b18009 | ||
|
|
c27e48dd5c | ||
|
|
44fe8a22e0 | ||
|
|
21df315887 | ||
|
|
3a7c470e6e | ||
|
|
22feec5136 | ||
|
|
a30f8c325f | ||
|
|
0770c20992 | ||
|
|
cc7fb0df7b | ||
|
|
fec061c250 | ||
|
|
aef3b23061 | ||
|
|
3518fc8ad3 | ||
|
|
e5dab74336 | ||
|
|
3aef51781e | ||
|
|
23deb2526c | ||
|
|
1a77bbf706 | ||
|
|
40b8e58266 | ||
|
|
733110120a | ||
|
|
68b8c9108d | ||
|
|
9ddeaba79b | ||
|
|
582c1e4fa2 | ||
|
|
28383c1391 | ||
|
|
7ab959f27c | ||
|
|
a877ca6139 | ||
|
|
33da8016a2 | ||
|
|
36b2849f20 | ||
|
|
377201614b | ||
|
|
ff11bf33d1 | ||
|
|
59463dcc9a | ||
|
|
23b5eb6fd6 | ||
|
|
8f4aa19f13 | ||
|
|
6410691c0e | ||
|
|
1ad1f9b96c | ||
|
|
636e8dd11e | ||
|
|
caeab48dda | ||
|
|
1364991e5d | ||
|
|
6bdea8fa54 | ||
|
|
da24220d87 | ||
|
|
a7d537ebe2 | ||
|
|
74b285959c | ||
|
|
c138bc44f0 | ||
|
|
13f56afcd2 | ||
|
|
ba8242f480 | ||
|
|
01985d4381 | ||
|
|
77511b79c9 | ||
|
|
06f653db8f | ||
|
|
cea2099537 | ||
|
|
67a6d3f4de | ||
|
|
7987a94aab | ||
|
|
e6494b6747 | ||
|
|
401f5095e1 | ||
|
|
93323d12d3 | ||
|
|
c3e23fabf1 | ||
|
|
95eb36c5c2 | ||
|
|
17105d51f1 | ||
|
|
8dbc455407 | ||
|
|
7e7b8416a4 | ||
|
|
ed81501bf2 | ||
|
|
428f8f5987 |
588
.github/workflows/build.yml
vendored
588
.github/workflows/build.yml
vendored
@@ -86,18 +86,23 @@ jobs:
|
|||||||
freethreaded: false
|
freethreaded: false
|
||||||
goal: build
|
goal: build
|
||||||
name: Build x86_64 macOS 15
|
name: Build x86_64 macOS 15
|
||||||
- os: macos-26
|
- os: macos-26-intel
|
||||||
jid: 11
|
jid: 11
|
||||||
freethreaded: false
|
freethreaded: false
|
||||||
goal: build
|
goal: build
|
||||||
|
name: Build x86_64 macOS 26
|
||||||
|
- os: macos-26
|
||||||
|
jid: 12
|
||||||
|
freethreaded: false
|
||||||
|
goal: build
|
||||||
name: Build Arm MacOS 26
|
name: Build Arm MacOS 26
|
||||||
- os: windows-2025-vs2026
|
- os: windows-2025-vs2026
|
||||||
jid: 12
|
jid: 13
|
||||||
freethreaded: false
|
freethreaded: false
|
||||||
goal: build
|
goal: build
|
||||||
name: Build Intel Windows
|
name: Build Intel Windows
|
||||||
- os: windows-11-arm
|
- os: windows-11-arm
|
||||||
jid: 13
|
jid: 14
|
||||||
freethreaded: false
|
freethreaded: false
|
||||||
goal: build
|
goal: build
|
||||||
name: Build Arm Windows
|
name: Build Arm Windows
|
||||||
@@ -105,36 +110,42 @@ jobs:
|
|||||||
goal: test
|
goal: test
|
||||||
python: "3.10"
|
python: "3.10"
|
||||||
freethreaded: false
|
freethreaded: false
|
||||||
jid: 14
|
jid: 15
|
||||||
name: Test Python 3.10
|
name: Test Python 3.10
|
||||||
- os: ubuntu-24.04
|
- os: ubuntu-24.04
|
||||||
goal: test
|
goal: test
|
||||||
python: "3.11"
|
python: "3.11"
|
||||||
freethreaded: false
|
freethreaded: false
|
||||||
jid: 15
|
jid: 16
|
||||||
name: Test Python 3.11
|
name: Test Python 3.11
|
||||||
- os: ubuntu-24.04
|
- os: ubuntu-24.04
|
||||||
goal: test
|
goal: test
|
||||||
python: "3.12"
|
python: "3.12"
|
||||||
freethreaded: false
|
freethreaded: false
|
||||||
jid: 16
|
jid: 17
|
||||||
name: Test Python 3.12
|
name: Test Python 3.12
|
||||||
|
- os: ubuntu-24.04
|
||||||
|
goal: test
|
||||||
|
python: "3.13"
|
||||||
|
freethreaded: false
|
||||||
|
jid: 18
|
||||||
|
name: Test Python 3.13
|
||||||
- os: ubuntu-24.04
|
- os: ubuntu-24.04
|
||||||
goal: test
|
goal: test
|
||||||
python: "3.15-dev"
|
python: "3.15-dev"
|
||||||
freethreaded: false
|
freethreaded: false
|
||||||
jid: 17
|
jid: 19
|
||||||
name: Test Python 3.15-dev
|
name: Test Python 3.15-dev
|
||||||
- os: ubuntu-24.04
|
- os: ubuntu-24.04
|
||||||
goal: test
|
goal: test
|
||||||
python: "3.14"
|
python: "3.14"
|
||||||
freethreaded: true
|
freethreaded: true
|
||||||
jid: 18
|
jid: 20
|
||||||
name: Test Python 3.14 freethread
|
name: Test Python 3.14 freethread
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -148,12 +159,12 @@ jobs:
|
|||||||
|
|
||||||
- name: Cache multiple paths
|
- name: Cache multiple paths
|
||||||
if: matrix.goal == 'build'
|
if: matrix.goal == 'build'
|
||||||
uses: actions/cache@638ed79f9dc94c1de1baef91bcab5edaa19451f4 # v4.2.4
|
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
|
||||||
id: cache-python-ssl
|
id: cache-python-ssl
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
cache.tar.xz
|
cache.tar.xz
|
||||||
key: gam-${{ matrix.jid }}-20260213
|
key: gam-${{ matrix.jid }}-20260227
|
||||||
|
|
||||||
- name: Untar Cache archive
|
- name: Untar Cache archive
|
||||||
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit == 'true'
|
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit == 'true'
|
||||||
@@ -163,7 +174,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Use pre-compiled Python for testing
|
- name: Use pre-compiled Python for testing
|
||||||
if: matrix.python != ''
|
if: matrix.python != ''
|
||||||
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
|
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python }}
|
python-version: ${{ matrix.python }}
|
||||||
allow-prereleases: true
|
allow-prereleases: true
|
||||||
@@ -247,11 +258,11 @@ jobs:
|
|||||||
|
|
||||||
- name: MacOS import developer certificates for signing
|
- name: MacOS import developer certificates for signing
|
||||||
if: runner.os == 'macOS'
|
if: runner.os == 'macOS'
|
||||||
uses: apple-actions/import-codesign-certs@11e1bb2d3771ad8ffa8459dfe527bc26b2dd4b62 # v5.0.3
|
uses: apple-actions/import-codesign-certs@b610f78488812c1e56b20e6df63ec42d833f2d14 # v6.0.0
|
||||||
with:
|
with:
|
||||||
p12-file-base64: ${{ secrets.CERTIFICATES_P12 }}
|
p12-file-base64: ${{ secrets.CERTIFICATES_P12 }}
|
||||||
p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }}
|
p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }}
|
||||||
|
|
||||||
- name: Windows Configure VCode
|
- name: Windows Configure VCode
|
||||||
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
|
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
|
||||||
if: runner.os == 'Windows' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
if: runner.os == 'Windows' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
||||||
@@ -291,8 +302,9 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
PYEXTERNALS_PATH=$(cygpath -u "${PYTHON_SOURCE_PATH}/PCbuild/${PYEXTERNALS_ARCH}")
|
PYEXTERNALS_PATH=$(cygpath -u "${PYTHON_SOURCE_PATH}/PCbuild/${PYEXTERNALS_ARCH}")
|
||||||
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${PYEXTERNALS_PATH}"
|
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${PYEXTERNALS_PATH}"
|
||||||
echo "PYTHON=${PYTHON_SOURCE_PATH}/PCbuild/${PYEXTERNALS_ARCH}/python.exe" >> $GITHUB_ENV
|
echo "PYTHON=${PYTHON_INSTALL_PATH}\python.exe" >> $GITHUB_ENV
|
||||||
echo "WIX_ARCH=${WIX_ARCH}" >> $GITHUB_ENV
|
echo "WIX_ARCH=${WIX_ARCH}" >> $GITHUB_ENV
|
||||||
|
echo "PS_PYTHON_INSTALL_PATH=$(cygpath -w $PYTHON_INSTALL_PATH)" >> $GITHUB_ENV
|
||||||
fi
|
fi
|
||||||
echo "We'll run make with: ${MAKEOPT}"
|
echo "We'll run make with: ${MAKEOPT}"
|
||||||
echo "staticx=${staticx}" >> $GITHUB_ENV
|
echo "staticx=${staticx}" >> $GITHUB_ENV
|
||||||
@@ -435,7 +447,7 @@ jobs:
|
|||||||
pip install --upgrade sphinx
|
pip install --upgrade sphinx
|
||||||
sphinx-build --version
|
sphinx-build --version
|
||||||
|
|
||||||
- name: Windows Config/Build Python
|
- name: Windows Config/Build/Install Python
|
||||||
if: matrix.goal == 'build' && runner.os == 'Windows' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
if: matrix.goal == 'build' && runner.os == 'Windows' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
||||||
shell: powershell
|
shell: powershell
|
||||||
run: |
|
run: |
|
||||||
@@ -444,13 +456,16 @@ jobs:
|
|||||||
Copy-Item -Path "${env:GITHUB_WORKSPACE}\src\tools\openssl.props" -Destination PCBuild\ -Verbose
|
Copy-Item -Path "${env:GITHUB_WORKSPACE}\src\tools\openssl.props" -Destination PCBuild\ -Verbose
|
||||||
if (${env:RUNNER_ARCH} -eq "X64") {
|
if (${env:RUNNER_ARCH} -eq "X64") {
|
||||||
$env:arch = "x64"
|
$env:arch = "x64"
|
||||||
PCBuild\build.bat -c Release -p $env:arch --pgo
|
#PCBuild\build.bat -c Release -p $env:arch --pgo
|
||||||
} elseif (${env:RUNNER_ARCH} -eq "ARM64") {
|
} elseif (${env:RUNNER_ARCH} -eq "ARM64") {
|
||||||
$env:arch = "ARM64"
|
$env:arch = "ARM64"
|
||||||
# TODO: figure out why Windows ARM64 isn't compat with PGO optimiazation
|
# TODO: figure out why Windows ARM64 isn't compat with PGO optimiazation
|
||||||
# causes 10-20% slowdown in Python
|
# causes 10-20% slowdown in Python
|
||||||
PCBuild\build.bat -c Release -p $env:arch
|
#PCBuild\build.bat -c Release -p $env:arch
|
||||||
}
|
}
|
||||||
|
PCBuild\build.bat -c Release -p $env:arch --pgo
|
||||||
|
.\python.bat PC\layout --precompile --preset-default --copy $env:PS_PYTHON_INSTALL_PATH
|
||||||
|
Get-ChildItem -Path $env:PS_PYTHON_INSTALL_PATH -File
|
||||||
|
|
||||||
- name: Mac/Linux Build Python
|
- name: Mac/Linux Build Python
|
||||||
if: matrix.goal == 'build' && runner.os != 'Windows' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
if: matrix.goal == 'build' && runner.os != 'Windows' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
||||||
@@ -471,7 +486,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Run Python
|
- name: Run Python
|
||||||
run: |
|
run: |
|
||||||
"${PYTHON}" -V
|
"${PYTHON}" -VV
|
||||||
"${PYTHON}" -c "import ssl; print(f'Using {ssl.OPENSSL_VERSION}')"
|
"${PYTHON}" -c "import ssl; print(f'Using {ssl.OPENSSL_VERSION}')"
|
||||||
|
|
||||||
- name: Create and use Python venv
|
- name: Create and use Python venv
|
||||||
@@ -656,28 +671,27 @@ jobs:
|
|||||||
echo "GAM Version ${GAMVERSION}"
|
echo "GAM Version ${GAMVERSION}"
|
||||||
echo "GAMVERSION=${GAMVERSION}" >> $GITHUB_ENV
|
echo "GAMVERSION=${GAMVERSION}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Install WinAppDriver
|
- name: Initialize Windows Desktop Shell
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
Write-Host "Checking for Windows Explorer shell..."
|
||||||
|
if (-not (Get-Process -Name explorer -ErrorAction SilentlyContinue)) {
|
||||||
|
Write-Host "Explorer not found. Booting the desktop shell..."
|
||||||
|
Start-Process explorer.exe
|
||||||
|
# Give the desktop a few seconds to fully render the taskbar
|
||||||
|
Start-Sleep -Seconds 10
|
||||||
|
} else {
|
||||||
|
Write-Host "Explorer is already running."
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Install NPM deps
|
||||||
if: runner.os == 'Windows'
|
if: runner.os == 'Windows'
|
||||||
run: |
|
run: |
|
||||||
choco install -y winappdriver
|
#echo "Installing appium..."
|
||||||
|
#npm install -g appium
|
||||||
- name: Enabled dev mode for WinAppDriver
|
|
||||||
if: runner.os == 'Windows'
|
|
||||||
shell: cmd
|
|
||||||
run : |
|
|
||||||
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /t REG_DWORD /f /v "AllowDevelopmentWithoutDevLicense" /d "1"
|
|
||||||
|
|
||||||
- name: Install appium and totp tools
|
|
||||||
if: runner.os == 'Windows'
|
|
||||||
run: |
|
|
||||||
echo "Installing appium..."
|
|
||||||
npm install -g appium
|
|
||||||
echo "Installing totp-generator..."
|
echo "Installing totp-generator..."
|
||||||
npm install "totp-generator"
|
npm install totp-generator
|
||||||
echo "Installing wdio..."
|
|
||||||
npm install @wdio/cli
|
|
||||||
echo "Installing appium win driver..."
|
|
||||||
appium driver install windows
|
|
||||||
|
|
||||||
- name: Install Certum MSI
|
- name: Install Certum MSI
|
||||||
if: runner.os == 'Windows'
|
if: runner.os == 'Windows'
|
||||||
@@ -699,18 +713,21 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
TOTP_SECRET: ${{ secrets.TOTP_SECRET }}
|
TOTP_SECRET: ${{ secrets.TOTP_SECRET }}
|
||||||
run: |
|
run: |
|
||||||
# disable win private firewall that interferes with appium server
|
|
||||||
Set-NetFirewallProfile -Profile Private -Enabled False
|
|
||||||
$appiumCmd = Get-Command appium
|
|
||||||
$appiumPath = $appiumCmd.Path
|
|
||||||
Start-Process -Filepath "powershell.exe" -ArgumentList "-File", $appiumPath, "--address", "127.0.0.1", "--log-level", "error"
|
|
||||||
Start-Sleep -Seconds 10
|
|
||||||
write-host "appium started"
|
|
||||||
write-host "running SimplySignDesktop login..."
|
write-host "running SimplySignDesktop login..."
|
||||||
node tools/ssd.mjs --log-level warn
|
node tools/ssd.mjs --log-level warn
|
||||||
write-host "sleeping during login..."
|
write-host "sleeping during login..."
|
||||||
Start-Sleep 10
|
Start-Sleep 10
|
||||||
|
|
||||||
|
- name: Archive png artifacts
|
||||||
|
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # 7.0.0
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
with:
|
||||||
|
archive: true
|
||||||
|
name: images-${{ matrix.os }}
|
||||||
|
if-no-files-found: ignore
|
||||||
|
path: |
|
||||||
|
*.png
|
||||||
|
|
||||||
- name: Sign gam.exe
|
- name: Sign gam.exe
|
||||||
if: runner.os == 'Windows'
|
if: runner.os == 'Windows'
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
@@ -732,7 +749,7 @@ jobs:
|
|||||||
$gam create signjwtserviceaccount
|
$gam create signjwtserviceaccount
|
||||||
|
|
||||||
- name: Attest gam executable was generated from this Action
|
- name: Attest gam executable was generated from this Action
|
||||||
uses: actions/attest-build-provenance@0b6e9809265278d02c58acf52849a95818a5a306 # v3.0.0
|
uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0
|
||||||
if: matrix.goal == 'build'
|
if: matrix.goal == 'build'
|
||||||
with:
|
with:
|
||||||
subject-path: ${{ env.gam }}
|
subject-path: ${{ env.gam }}
|
||||||
@@ -753,11 +770,6 @@ jobs:
|
|||||||
echo "GAM Archive ${GAM_ARCHIVE}"
|
echo "GAM Archive ${GAM_ARCHIVE}"
|
||||||
tar -C "${gampath}/.." --create --verbose --exclude-from "${GITHUB_WORKSPACE}/.github/actions/package_exclusions.txt" --file $GAM_ARCHIVE --xz gam7
|
tar -C "${gampath}/.." --create --verbose --exclude-from "${GITHUB_WORKSPACE}/.github/actions/package_exclusions.txt" --file $GAM_ARCHIVE --xz gam7
|
||||||
|
|
||||||
- name: Install Wix on Win ARM64
|
|
||||||
if: runner.os == 'Windows' && runner.arch == 'ARM64'
|
|
||||||
run: |
|
|
||||||
choco install wixtoolset
|
|
||||||
|
|
||||||
- name: Windows package zip
|
- name: Windows package zip
|
||||||
if: runner.os == 'Windows' && matrix.goal != 'test'
|
if: runner.os == 'Windows' && matrix.goal != 'test'
|
||||||
run: |
|
run: |
|
||||||
@@ -767,54 +779,52 @@ jobs:
|
|||||||
GAM_ARCHIVE="${GITHUB_WORKSPACE}/gam-${GAMVERSION}-windows-${arch}.zip"
|
GAM_ARCHIVE="${GITHUB_WORKSPACE}/gam-${GAMVERSION}-windows-${arch}.zip"
|
||||||
/c/Program\ Files/7-Zip/7z.exe a -tzip "$GAM_ARCHIVE" gam7 "-xr@${GITHUB_WORKSPACE}/.github/actions/package_exclusions.txt" -bb3
|
/c/Program\ Files/7-Zip/7z.exe a -tzip "$GAM_ARCHIVE" gam7 "-xr@${GITHUB_WORKSPACE}/.github/actions/package_exclusions.txt" -bb3
|
||||||
|
|
||||||
- name: Windows package MSI
|
- name: Windows package exe with Inno Setup
|
||||||
if: runner.os == 'Windows' && matrix.goal != 'test'
|
if: runner.os == 'Windows' && matrix.goal != 'test'
|
||||||
run: |
|
run: |
|
||||||
export MSI_FILENAME="${GITHUB_WORKSPACE}/gam-${GAMVERSION}-windows-${arch}.msi"
|
choco install innosetup
|
||||||
# auto-generate a lib.wxs based on the files PyInstaller created for the lib/ directory
|
export signtool="C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\signtool.exe"
|
||||||
/c/Program\ Files\ \(x86\)/WiX\ Toolset\ v3.14/bin/heat.exe dir "${gampath}/lib" -ke -srd -cg Lib -gg -dr lib -directoryid lib -out lib.wxs
|
iscc \
|
||||||
$PYTHON tools/gen-wix-xml-filelist.py lib.wxs
|
/S"gamsigntool=$signtool sign /sha1 $WINDOWS_CODESIGN_CERT_HASH /tr http://time.certum.pl /td SHA256 /fd SHA256 /v \$f" \
|
||||||
echo "-- begin lib.wxs --"
|
/O"$GITHUB_WORKSPACE" \
|
||||||
cat lib.wxs
|
gam.iss
|
||||||
echo "-- end lib.wxs --"
|
|
||||||
/c/Program\ Files\ \(x86\)/WiX\ Toolset\ v3.14/bin/candle.exe -arch "${WIX_ARCH}" gam.wxs lib.wxs
|
|
||||||
/c/Program\ Files\ \(x86\)/WiX\ Toolset\ v3.14/bin/light.exe -ext /c/Program\ Files\ \(x86\)/WiX\ Toolset\ v3.14/bin/WixUIExtension.dll gam.wixobj lib.wixobj -b "${gampath}/lib" -o "$MSI_FILENAME" || true;
|
|
||||||
rm -v -f *.wixpdb
|
|
||||||
rm -v -f *.wixobj
|
|
||||||
echo "MSI_FILENAME=${MSI_FILENAME}" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Sign GAM MSI
|
|
||||||
if: runner.os == 'Windows'
|
|
||||||
shell: pwsh
|
|
||||||
run: |
|
|
||||||
write-Host "Signing ${env:MSI_FILENAME}...."
|
|
||||||
# Always explicitely use x64 version os signtool.exe, arm64 version apparently can't
|
|
||||||
# see Certum certs since SimplySignDesktop is x64-only today.
|
|
||||||
Start-Process -Wait -NoNewWindow -ErrorAction Continue -FilePath 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\signtool.exe' -ArgumentList "sign", "/sha1", "$env:WINDOWS_CODESIGN_CERT_HASH", "/tr", "http://time.certum.pl", "/td", "SHA256", "/fd", "SHA256", "/v", "$env:MSI_FILENAME"
|
|
||||||
write-Host "Verifying signature of ${env:MSI_FILENAME}...."
|
|
||||||
# verify signature. If we failed to sign we should fail to verify and die.
|
|
||||||
& 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\signtool.exe' verify /pa /v "$env:MSI_FILENAME"
|
|
||||||
|
|
||||||
- name: Attest that gam package files were generated from this Action
|
- name: Attest that gam package files were generated from this Action
|
||||||
uses: actions/attest-build-provenance@0b6e9809265278d02c58acf52849a95818a5a306 # v3.0.0
|
uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0
|
||||||
if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && matrix.goal == 'build'
|
if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && matrix.goal == 'build'
|
||||||
with:
|
with:
|
||||||
subject-path: |
|
subject-path: |
|
||||||
gam*.tar.xz
|
gam*.tar.xz
|
||||||
gam*.zip
|
gam*.zip
|
||||||
gam*.msi
|
gam*.exe
|
||||||
|
# gam*.msi
|
||||||
|
|
||||||
- name: Archive production artifacts
|
- name: Archive tar.xz artifacts
|
||||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # 4.6.2
|
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # 7.0.0
|
||||||
#if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && matrix.goal != 'test'
|
if: runner.os != 'Windows'
|
||||||
if: always()
|
|
||||||
with:
|
with:
|
||||||
name: gam-binaries-${{ env.GAMOS }}-${{ env.arch }}-${{ matrix.jid }}
|
archive: false
|
||||||
|
if-no-files-found: ignore
|
||||||
path: |
|
path: |
|
||||||
gam*.tar.xz
|
gam*.tar.xz
|
||||||
|
|
||||||
|
- name: Archive zip artifacts
|
||||||
|
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # 7.0.0
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
with:
|
||||||
|
archive: false
|
||||||
|
if-no-files-found: ignore
|
||||||
|
path: |
|
||||||
gam*.zip
|
gam*.zip
|
||||||
gam*.msi
|
|
||||||
*.png
|
- name: Archive exe artifacts
|
||||||
|
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # 7.0.0
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
with:
|
||||||
|
archive: false
|
||||||
|
if-no-files-found: ignore
|
||||||
|
path: |
|
||||||
|
gam*.exe
|
||||||
|
|
||||||
- name: Basic Tests build jobs only
|
- name: Basic Tests build jobs only
|
||||||
if: matrix.goal != 'test' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
if: matrix.goal != 'test' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
||||||
@@ -839,19 +849,46 @@ jobs:
|
|||||||
- name: Live API tests
|
- name: Live API tests
|
||||||
if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
|
if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
|
||||||
run: |
|
run: |
|
||||||
|
run_gam() {
|
||||||
|
local allowed_codes="0"
|
||||||
|
if [[ "$1" == "-a" ]]; then
|
||||||
|
allowed_codes="$2"
|
||||||
|
shift 2
|
||||||
|
fi
|
||||||
|
echo "::group::Executing: gam $*"
|
||||||
|
local exit_code=0
|
||||||
|
$gam "$@" || exit_code=$?
|
||||||
|
echo "::endgroup::"
|
||||||
|
allowed_codes="${allowed_codes//,/ }"
|
||||||
|
local passed=false
|
||||||
|
for code in $allowed_codes; do
|
||||||
|
if [ "$exit_code" -eq "$code" ]; then
|
||||||
|
passed=true
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ "$passed" = true ]; then
|
||||||
|
echo "| \`gam $*\` | 🟢 Pass | $exit_code |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
return 0 # Mask the allowed non-zero exit code so GHA continues
|
||||||
|
else
|
||||||
|
echo "| \`gam $*\` | 🔴 Fail | $exit_code |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
exit $exit_code # Hard fail the step for unapproved errors
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
export gam_user="gam-gha-${JID}@pdl.jaylee.us"
|
export gam_user="gam-gha-${JID}@pdl.jaylee.us"
|
||||||
echo "gam_user=${gam_user}" >> $GITHUB_ENV
|
echo "gam_user=${gam_user}" >> $GITHUB_ENV
|
||||||
$gam config customer_id "C03uzfv2s" save
|
run_gam config customer_id "C03uzfv2s" save
|
||||||
$gam config domain "pdl.jaylee.us" save
|
run_gam config domain "pdl.jaylee.us" save
|
||||||
$gam config admin_email "${gam_user}" save
|
run_gam config admin_email "${gam_user}" save
|
||||||
$gam config enable_dasa false save
|
run_gam config enable_dasa false save
|
||||||
$gam oauth info
|
run_gam oauth info
|
||||||
$gam oauth refresh
|
run_gam oauth refresh
|
||||||
$gam config enable_dasa true save
|
run_gam config enable_dasa true save
|
||||||
$gam checkconn
|
run_gam checkconn
|
||||||
$gam user "$gam_user" check serviceaccount
|
run_gam user "$gam_user" check serviceaccount
|
||||||
$gam info domain
|
run_gam info domain
|
||||||
$gam info user
|
run_gam info user
|
||||||
export tstamp=$($PYTHON -c "import time; print(time.time_ns())")
|
export tstamp=$($PYTHON -c "import time; print(time.time_ns())")
|
||||||
export newbase="gha_test_${JID}_${tstamp}"
|
export newbase="gha_test_${JID}_${tstamp}"
|
||||||
export newuser="${newbase}@pdl.jaylee.us"
|
export newuser="${newbase}@pdl.jaylee.us"
|
||||||
@@ -860,24 +897,39 @@ jobs:
|
|||||||
export newbuilding="${newbase}-building"
|
export newbuilding="${newbase}-building"
|
||||||
export newresource="${newbase}-resource"
|
export newresource="${newbase}-resource"
|
||||||
export newou="aaaGithub Actions/${newbase}"
|
export newou="aaaGithub Actions/${newbase}"
|
||||||
|
|
||||||
|
echo "### GAM Execution Report" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Command | Status |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| :--- | :---: |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
# cleanup old runs
|
# cleanup old runs
|
||||||
$gam config enable_dasa false save
|
run_gam config enable_dasa false save
|
||||||
$gam config csv_output_row_filter "name:regex:gha_test_${JID}_" print vaultholds | $gam csv - gam delete vaulthold "id:~~holdId~~" matter "id:~~matterId~~" || if [ $? != 55 ]; then exit $?; fi
|
run_gam config csv_output_row_filter "name:regex:gha_test_${JID}_" redirect csv ./vh.csv print vaultholds
|
||||||
$gam config csv_output_row_filter "name:regex:gha_test_${JID}_" print vaultmatters matterstate OPEN | $gam csv - gam update vaultmatter "id:~~matterId~~" action close
|
run_gam -a "0 55" csv ./vh.csv gam delete vaulthold "id:~~holdId~~" matter "id:~~matterId~~"
|
||||||
$gam config csv_output_row_filter "name:regex:gha_test_${JID}_" print vaultmatters matterstate CLOSED | $gam csv - gam update vaultmatter "id:~~matterId~~" action delete
|
run_gam config csv_output_row_filter "name:regex:gha_test_${JID}_" redirect csv ./vm-open.csv print vaultmatters matterstate OPEN
|
||||||
$gam config csv_output_row_filter "Emails.1.address:regex:^gha_test-${JID}_" print contacts | $gam csv - gam delete contact ~ContactID
|
run_gam csv ./vm-open.csv gam update vaultmatter "id:~~matterId~~" action close
|
||||||
$gam config enable_dasa true save
|
run_gam config csv_output_row_filter "name:regex:gha_test_${JID}_" redirect csv ./vm-closed.csv print vaultmatters matterstate CLOSED
|
||||||
$gam config csv_output_row_filter "name:regex:gha_test_${JID}_" print features | $gam csv - gam delete feature ~name
|
run_gam csv ./vm-closed.csv gam update vaultmatter "id:~~matterId~~" action delete
|
||||||
$gam config csv_output_row_filter "name:regex:^gha_test_${JID}_" user $gam_user print shareddrives asadmin | $gam csv - gam user $gam_user delete shareddrive ~id nukefromorbit
|
run_gam config csv_output_row_filter "Emails.1.address:regex:^gha_test-${JID}_" redirect csv ./contacts.csv print contacts
|
||||||
$gam print users query "gha.jid=$JID" | $gam csv - gam delete user ~primaryEmail
|
run_gam csv ./contacts.csv gam delete contact ~ContactID
|
||||||
$gam config csv_output_row_filter "name:regex:^gha_test_${JID}_" print ous fromparent "aaaGithub Actions" | $gam csv - gam delete ou ~orgUnitId
|
run_gam config enable_dasa true save
|
||||||
$gam config csv_output_row_filter "email:regex:^gha_test_${JID}_" print cigroups | $gam csv - gam delete cigroup ~email
|
run_gam config csv_output_row_filter "name:regex:gha_test_${JID}_" redirect csv ./features.csv print features
|
||||||
$gam config csv_output_row_filter "resourceId:regex:^gha_test_${JID}_" print resources | $gam csv - gam delete resource ~resourceId
|
run_gam csv ./features.csv gam delete feature ~name
|
||||||
$gam config csv_output_row_filter "buildingId:regex:^gha_test_${JID}_" print buildings | $gam csv - gam delete building ~buildingId
|
run_gam config csv_output_row_filter "name:regex:^gha_test_${JID}_" redirect csv ./sd.csv user $gam_user print shareddrives asadmin
|
||||||
|
run_gam csv ./sd.csv gam user $gam_user delete shareddrive ~id nukefromorbit
|
||||||
|
run_gam redirect csv ./users.csv print users query "gha.jid=$JID"
|
||||||
|
run_gam csv ./users.csv gam delete user ~primaryEmail
|
||||||
|
run_gam config csv_output_row_filter "name:regex:^gha_test_${JID}_" redirect csv ./ous.csv print ous fromparent "aaaGithub Actions"
|
||||||
|
run_gam csv ./ous.csv gam delete ou ~orgUnitId
|
||||||
|
run_gam config csv_output_row_filter "email:regex:^gha_test_${JID}_" redirect csv ./cigroups.csv print cigroups
|
||||||
|
run_gam csv ./cigroups.csv gam delete cigroup ~email
|
||||||
|
run_gam config csv_output_row_filter "resourceId:regex:^gha_test_${JID}_" redirect csv ./resources.csv print resources
|
||||||
|
run_gam csv ./resources.csv gam delete resource ~resourceId
|
||||||
|
run_gam config csv_output_row_filter "buildingId:regex:^gha_test_${JID}_" redirect csv ./buildings.csv print buildings
|
||||||
|
run_gam csv ./buildings.csv gam delete building ~buildingId
|
||||||
|
|
||||||
echo "Creating OrgUnit ${newou}"
|
echo "Creating OrgUnit ${newou}"
|
||||||
$gam create ou "${newou}"
|
run_gam create ou "${newou}"
|
||||||
export GAM_THREADS=5
|
export GAM_THREADS=5
|
||||||
echo email > sample.csv;
|
echo email > sample.csv;
|
||||||
for i in {1..10}; do
|
for i in {1..10}; do
|
||||||
@@ -885,187 +937,183 @@ jobs:
|
|||||||
done
|
done
|
||||||
driveid=$($gam user $gam_user add shareddrive "${newbase}" returnidonly)
|
driveid=$($gam user $gam_user add shareddrive "${newbase}" returnidonly)
|
||||||
echo "Created shared drive ${driveid}"
|
echo "Created shared drive ${driveid}"
|
||||||
$gam create user $newuser firstname GHA lastname $JID displayname "Github Actions ${JID}" password random recoveryphone 12125121110 recoveryemail jay0lee@gmail.com gha.jid $JID languages en+,en-GB- ou "${newou}"
|
run_gam create user $newuser firstname GHA lastname $JID displayname "Github Actions ${JID}" password random recoveryphone 12125121110 recoveryemail jay0lee@gmail.com gha.jid $JID languages en+,en-GB- ou "${newou}"
|
||||||
$gam user $newuser add license workspaceenterpriseplus
|
run_gam user $newuser add license workspaceenterpriseplus
|
||||||
$gam user $newuser update photo https://dummyimage.com/98x98/000/fff.jpg
|
run_gam user $newuser update photo https://dummyimage.com/98x98/000/fff.jpg
|
||||||
$gam user $newuser get photo
|
run_gam user $newuser get photo
|
||||||
$gam user $newuser delete photo
|
run_gam user $newuser delete photo
|
||||||
$gam create alias $newalias user $newuser
|
run_gam create alias $newalias user $newuser
|
||||||
$gam create group $newgroup name "GHA $JID group" description "This is a description" isarchived true
|
run_gam create group $newgroup name "GHA $JID group" description "This is a description" isarchived true
|
||||||
$gam user $gam_user sendemail recipient dev-null@pdl.jaylee.us subject "test message $newbase" message "GHA test message"
|
run_gam user $gam_user sendemail recipient dev-null@pdl.jaylee.us subject "test message $newbase" message "GHA test message"
|
||||||
$gam config enable_dasa false save
|
run_gam config enable_dasa false save
|
||||||
# don't expose policy output
|
# don't expose policy output
|
||||||
$gam show policies > policies.csv
|
run_gam show policies > policies.csv
|
||||||
$gam create contact firstname GHA lastname "$JID" email work "${newbase}@example.com" primary
|
run_gam create contact firstname GHA lastname "$JID" email work "${newbase}@example.com" primary
|
||||||
$gam print contacts
|
run_gam print contacts
|
||||||
$gam print privileges
|
run_gam print privileges
|
||||||
$gam config enable_dasa true save
|
run_gam config enable_dasa true save
|
||||||
$gam update cigroup $newgroup security memberrestriction 'member.type == 1 || member.customer_id == groupCustomerId()'
|
run_gam update cigroup $newgroup security memberrestriction 'member.type == 1 || member.customer_id == groupCustomerId()'
|
||||||
$gam info cigroup $newgroup
|
run_gam info cigroup $newgroup
|
||||||
$gam update group $newgroup add owner $gam_user
|
run_gam update group $newgroup add owner $gam_user
|
||||||
$gam update group $newgroup add member $newuser
|
run_gam update group $newgroup add member $newuser
|
||||||
$gam config enable_dasa false save
|
run_gam config enable_dasa false save
|
||||||
# 9/17/24 temp disable due to Google API sluggishness to see new users for admin commands
|
# 9/17/24 temp disable due to Google API sluggishness to see new users for admin commands
|
||||||
# $gam create admin $newuser _GROUPS_EDITOR_ROLE CUSTOMER # condition nonsecuritygroup
|
# run_gam create admin $newuser _GROUPS_EDITOR_ROLE CUSTOMER # condition nonsecuritygroup
|
||||||
# 9/13/25 temp disable due to hangs
|
# 9/13/25 temp disable due to hangs
|
||||||
# $gam create admin $newgroup _HELP_DESK_ADMIN_ROLE org_unit "${newou}"
|
# run_gam create admin $newgroup _HELP_DESK_ADMIN_ROLE org_unit "${newou}"
|
||||||
# $gam config csv_output_row_filter "assignedToUser:regex:${newuser}" print admins | $gam csv - gam delete admin "~roleAssignmentId"
|
# run_gam config csv_output_row_filter "assignedToUser:regex:${newuser}" print admins | run_gam csv - gam delete admin "~roleAssignmentId"
|
||||||
# $gam config csv_output_row_filter "assignedToGroup:regex:${newgroup}" print admins | $gam csv - gam delete admin "~roleAssignmentId"
|
# run_gam config csv_output_row_filter "assignedToGroup:regex:${newgroup}" print admins | run_gam csv - gam delete admin "~roleAssignmentId"
|
||||||
$gam config enable_dasa false save
|
run_gam config enable_dasa false save
|
||||||
$gam csv sample.csv gam create user ~~email~~ firstname "GHA Bulk" lastname ~~email~~ gha.jid $JID ou "${newou}"
|
run_gam csv sample.csv gam create user ~~email~~ firstname "GHA Bulk" lastname ~~email~~ gha.jid $JID ou "${newou}"
|
||||||
$gam csv sample.csv gam update user ~~email~~ recoveryphone 12125121110 recoveryemail jay0lee@gmail.com password random displayname "GitHub Actions Bulk ${JID}"
|
run_gam csv sample.csv gam update user ~~email~~ recoveryphone 12125121110 recoveryemail jay0lee@gmail.com password random displayname "GitHub Actions Bulk ${JID}"
|
||||||
$gam csv sample.csv gam update user ~~email~~ recoveryphone "" recoveryemail ""
|
run_gam csv sample.csv gam update user ~~email~~ recoveryphone "" recoveryemail ""
|
||||||
$gam config enable_dasa false save
|
run_gam config enable_dasa false save
|
||||||
$gam csv sample.csv gam user ~email add license workspaceenterpriseplus
|
run_gam csv sample.csv gam user ~email add license workspaceenterpriseplus
|
||||||
#$gam user $newuser add contactdelegate "${newbase}-bulkuser-1"
|
#run_gam user $newuser add contactdelegate "${newbase}-bulkuser-1"
|
||||||
#$gam user $newuser print contactdelegates
|
#run_gam user $newuser print contactdelegates
|
||||||
$gam config enable_dasa true save
|
run_gam config enable_dasa true save
|
||||||
$gam csv sample.csv gam user $gam_user sendemail recipient ~~email~~@pdl.jaylee.us subject "test message $newbase" message "GHA test message"
|
run_gam csv sample.csv gam user $gam_user sendemail recipient ~~email~~@pdl.jaylee.us subject "test message $newbase" message "GHA test message"
|
||||||
$gam csv sample.csv gam update group $newgroup add member ~email
|
run_gam csv sample.csv gam update group $newgroup add member ~email
|
||||||
$gam info group $newgroup
|
run_gam info group $newgroup
|
||||||
$gam info cigroup $newgroup membertree
|
run_gam info cigroup $newgroup membertree
|
||||||
# confirm mailbox is provisoned before continuing
|
# confirm mailbox is provisoned before continuing
|
||||||
$gam user $newuser waitformailbox retries 50
|
run_gam user $newuser waitformailbox retries 50
|
||||||
$gam user $newuser imap on
|
run_gam user $newuser imap on
|
||||||
$gam user $newuser show imap
|
run_gam user $newuser show imap
|
||||||
$gam user $newuser show delegates
|
run_gam user $newuser show delegates
|
||||||
export biohazard=$(echo -e '\xe2\x98\xa3')
|
export biohazard=$(echo -e '\xe2\x98\xa3')
|
||||||
$gam user $newuser label "$biohazard unicode biohazard $biohazard"
|
run_gam user $newuser label "$biohazard unicode biohazard $biohazard"
|
||||||
$gam user $newuser show labels
|
run_gam user $newuser show labels
|
||||||
$gam user $newuser show labels > labels.txt
|
run_gam user $newuser show labels > labels.txt
|
||||||
$gam user $gam_user importemail subject "GHA import $newbase" message "This is a test import" labels IMPORTANT,UNREAD,INBOX,STARRED
|
run_gam user $gam_user importemail subject "GHA import $newbase" message "This is a test import" labels IMPORTANT,UNREAD,INBOX,STARRED
|
||||||
$gam user $gam_user insertemail subject "GHA insert $newbase" file gam.py labels INBOX,UNREAD # yep body is gam code
|
run_gam user $gam_user insertemail subject "GHA insert $newbase" file gam.py labels INBOX,UNREAD # yep body is gam code
|
||||||
$gam user $gam_user sendemail recipient admin@pdl.jaylee.us subject "GHA send $gam_user $newbase" file gam.py
|
run_gam user $gam_user sendemail recipient admin@pdl.jaylee.us subject "GHA send $gam_user $newbase" file gam.py
|
||||||
$gam user $gam_user draftemail subject "GHA draft $newbase" message "Draft message test"
|
run_gam user $gam_user draftemail subject "GHA draft $newbase" message "Draft message test"
|
||||||
$gam csvfile sample.csv:email waitformailbox retries 20
|
run_gam csvfile sample.csv:email waitformailbox retries 20
|
||||||
$gam user $newuser delegate to "${newbase}-bulkuser-1" || if [ $? != 50 ]; then exit $?; fi # expect a 50 return code (delegation failed)
|
run_gam user $newuser delegate to "${newbase}-bulkuser-1" || if [ $? != 50 ]; then exit $?; fi # expect a 50 return code (delegation failed)
|
||||||
$gam users "$gam_user $newbase-bulkuser-1 $newbase-bulkuser-2 $newbase-bulkuser-3" delete messages query in:anywhere maxtodelete 99999 doit || if [ $? != 60 ]; then exit $?; fi # expect a 60 return code (no messages)
|
run_gam -a "0 60" users "$gam_user $newbase-bulkuser-1 $newbase-bulkuser-2 $newbase-bulkuser-3" delete messages query in:anywhere maxtodelete 99999 doit
|
||||||
$gam users "$newbase-bulkuser-4 $newbase-bulkuser-5 $newbase-bulkuser-6" trash messages query in:anywhere maxtotrash 99999 doit || if [ $? != 60 ]; then exit $?; fi # expect a 60 return code (no messages)
|
run_gam -a "0 60" users "$newbase-bulkuser-4 $newbase-bulkuser-5 $newbase-bulkuser-6" trash messages query in:anywhere maxtotrash 99999 doit
|
||||||
$gam users "$newbase-bulkuser-7 $newbase-bulkuser-8 $newbase-bulkuser-9" modify messages query in:anywhere maxtomodify 99999 addlabel IMPORTANT addlabel STARRED doit || if [ $? != 60 ]; then exit $?; fi # expect a 60 return code (no messages)
|
run_gam -a "0 60" users "$newbase-bulkuser-7 $newbase-bulkuser-8 $newbase-bulkuser-9" modify messages query in:anywhere maxtomodify 99999 addlabel IMPORTANT addlabel STARRED doit
|
||||||
$gam user $newuser delete label --ALL_LABELS--
|
run_gam user $newuser delete label --ALL_LABELS--
|
||||||
$gam config csv_output_row_filter "name:regex:gha-test-${JID}" print features | $gam csv - gam delete feature ~name
|
run_gam config csv_output_row_filter "name:regex:gha-test-${JID}" redirect csv ./features.csv print features
|
||||||
$gam create feature name VC-$newbase
|
run_gam csv ./features.csv gam delete feature ~name
|
||||||
$gam create feature name Whiteboard-$newbase
|
run_gam create feature name VC-$newbase
|
||||||
$gam create building "My Building - $newbase" id $newbuilding floors 1,2,3,4,5,6,7,8,9,10,11,12,14,15 description "No 13th floor here..."
|
run_gam create feature name Whiteboard-$newbase
|
||||||
$gam create resource $newresource "Resource Calendar $tstamp" capacity 25 features Whiteboard-$newbase,VC-$newbase building $newbuilding floor 15 type Room
|
run_gam create building "My Building - $newbase" id $newbuilding floors 1,2,3,4,5,6,7,8,9,10,11,12,14,15 description "No 13th floor here..."
|
||||||
$gam info resource $newresource
|
run_gam create resource $newresource "Resource Calendar $tstamp" capacity 25 features Whiteboard-$newbase,VC-$newbase building $newbuilding floor 15 type Room
|
||||||
$gam user $newuser add drivefile drivefilename "TPS Reports" mimetype gfolder
|
run_gam info resource $newresource
|
||||||
$gam user $newuser show filelist
|
run_gam user $newuser add drivefile drivefilename "TPS Reports" mimetype gfolder
|
||||||
$gam calendar $gam_user printacl | $gam csv - gam calendar $gam_user delete ~id # clear ACLs
|
run_gam user $newuser show filelist
|
||||||
$gam calendar $gam_user add read domain
|
run_gam redirect csv ./cal-acl.csv calendar $gam_user printacl
|
||||||
$gam calendar $gam_user add freebusy default
|
run_gam csv ./cal-acl.csv gam calendar $gam_user delete ~id # clear ACLs
|
||||||
$gam calendar $gam_user add editor $newuser
|
run_gam calendar $gam_user add read domain
|
||||||
$gam calendar $gam_user showacl
|
run_gam calendar $gam_user add freebusy default
|
||||||
$gam calendar $gam_user printacl | $gam csv - gam calendar $gam_user delete ~id
|
run_gam calendar $gam_user add editor $newuser
|
||||||
$gam calendar $gam_user addevent summary "GHA test event" start +1h end +2h attendee $newgroup hangoutsmeet guestscanmodify true sendupdates all
|
run_gam calendar $gam_user showacl
|
||||||
$gam calendar $gam_user printevents after -0d
|
run_gam redirect csv ./cal-acl.csv calendar $gam_user printacl
|
||||||
$gam config enable_dasa false save
|
run_gam csv ./cal-acl.csv gam calendar $gam_user delete ~id
|
||||||
|
run_gam calendar $gam_user addevent summary "GHA test event" start +1h end +2h attendee $newgroup hangoutsmeet guestscanmodify true sendupdates all
|
||||||
|
run_gam calendar $gam_user printevents after -0d
|
||||||
|
run_gam config enable_dasa false save
|
||||||
matterid=uid:$($gam create vaultmatter name "GHA matter $newbase" description "test matter" returnidonly)
|
matterid=uid:$($gam create vaultmatter name "GHA matter $newbase" description "test matter" returnidonly)
|
||||||
$gam create vaulthold matter $matterid name "GHA hold ${newbase}" corpus mail ou "$newou"
|
run_gam create vaulthold matter "$matterid" name "GHA hold ${newbase}" corpus mail ou "$newou"
|
||||||
$gam print vaultmatters matterstate open
|
run_gam print vaultmatters matterstate open
|
||||||
$gam print vaultholds matter $matterid
|
run_gam print vaultholds matter $matterid
|
||||||
$gam print vaultcount matter $matterid corpus mail everyone todrive tdnobrowser
|
run_gam print vaultcount matter $matterid corpus mail everyone todrive tdnobrowser
|
||||||
$gam create vaultexport matter $matterid name "GHA export $newbase" corpus mail ou "$newou"
|
run_gam create vaultexport matter $matterid name "GHA export $newbase" corpus mail ou "$newou"
|
||||||
$gam print exports matter $matterid | $gam csv - gam info export $matterid id:~~id~~
|
run_gam redirect csv ./exports.csv print exports matter $matterid
|
||||||
$gam config enable_dasa true save
|
run_gam csv ./exports.csv gam info export $matterid id:~~id~~
|
||||||
$gam csv sample.csv gam user ~email add calendar id:$newresource
|
run_gam config enable_dasa true save
|
||||||
$gam delete resource $newresource
|
run_gam csv sample.csv gam user ~email add calendar id:$newresource
|
||||||
$gam delete feature Whiteboard-$newbase
|
run_gam delete resource $newresource
|
||||||
$gam delete feature VC-$newbase
|
run_gam delete feature Whiteboard-$newbase
|
||||||
$gam delete building $newbuilding
|
run_gam delete feature VC-$newbase
|
||||||
$gam delete group $newgroup
|
run_gam delete building $newbuilding
|
||||||
$gam config enable_dasa false save
|
run_gam delete group $newgroup
|
||||||
|
run_gam config enable_dasa false save
|
||||||
echo start
|
echo start
|
||||||
$gam user $newuser delete license workspaceenterpriseplus
|
run_gam user $newuser delete license workspaceenterpriseplus
|
||||||
echo finish
|
echo finish
|
||||||
$gam config enable_dasa true save
|
run_gam config enable_dasa true save
|
||||||
$gam whatis $newuser || if [ $? != 20 ]; then exit $?; fi # expect a 20 return code (is a user)
|
run_gam -a "0 20" whatis $newuser
|
||||||
$gam user $gam_user show tokens
|
run_gam user $gam_user show tokens
|
||||||
$gam config enable_dasa false save
|
run_gam config enable_dasa false save
|
||||||
download_dir="${RUNNER_TEMP}/TEMP_DELETE_ME"
|
download_dir="${RUNNER_TEMP}/TEMP_DELETE_ME"
|
||||||
mkdir -v "$download_dir"
|
mkdir -v "$download_dir"
|
||||||
$gam print exports matter $matterid | $gam csv - gam download export $matterid id:~~id~~ targetfolder "$download_dir"
|
run_gam redirect csv ./exports.csv print exports matter $matterid
|
||||||
|
run_gam csv ./exports.csv gam download export $matterid id:~~id~~ targetfolder "$download_dir"
|
||||||
rm -rvf "$download_dir"
|
rm -rvf "$download_dir"
|
||||||
$gam delete hold "GHA hold $newbase" matter $matterid
|
run_gam delete hold "GHA hold $newbase" matter $matterid
|
||||||
$gam update matter $matterid action close
|
run_gam update matter $matterid action close
|
||||||
$gam update matter $matterid action delete
|
run_gam update matter $matterid action delete
|
||||||
# shakes off vault hold on user so we can delete
|
# shakes off vault hold on user so we can delete
|
||||||
$gam print users query "email:${newuser}" orgunitpath | $gam csv - gam update user ~primaryEmail ou ~orgUnitPath
|
run_gam redirect csv ./users.csv print users query "email:${newuser}" orgunitpath
|
||||||
$gam user $newuser show holds || if [ $? != 55 ]; then exit $?; fi # expect a 55 return code
|
run_gam csv ./users.csv gam update user ~primaryEmail ou ~orgUnitPath
|
||||||
|
run_gam user $newuser show holds || if [ $? != 55 ]; then exit $?; fi # expect a 55 return code
|
||||||
export sn="$JID$JID$JID$JID-$(openssl rand -base64 32 | sed 's/[^a-zA-Z0-9]//g')"
|
export sn="$JID$JID$JID$JID-$(openssl rand -base64 32 | sed 's/[^a-zA-Z0-9]//g')"
|
||||||
$gam create device serialnumber $sn devicetype android
|
run_gam create device serialnumber $sn devicetype android
|
||||||
$gam delete contacts emailmatchpattern "^${newbase}@example.com$"
|
run_gam delete contacts emailmatchpattern "^${newbase}@example.com$"
|
||||||
$gam config enable_dasa true save
|
run_gam config enable_dasa true save
|
||||||
$gam print users query "gha.jid=$JID" | $gam csv - gam delete user ~primaryEmail || if [ $? != 50 ]; then exit $?; fi # expect a 50 return code (vault hold on user)
|
run_gam redirect csv ./users.csv print users query "gha.jid=$JID"
|
||||||
$gam print mobile
|
run_gam -a "0 50" csv ./users.csv gam delete user ~primaryEmail
|
||||||
$gam print devices clientstates
|
run_gam print mobile
|
||||||
$gam print browsers
|
run_gam print devices clientstates
|
||||||
$gam print cros allfields orderby serialnumber
|
run_gam print browsers
|
||||||
$gam show crostelemetry storagepercentonly
|
run_gam print cros allfields orderby serialnumber
|
||||||
$gam report usageparameters customer
|
run_gam show crostelemetry storagepercentonly
|
||||||
$gam report usage customer parameters gmail:num_emails_sent,accounts:num_1day_logins
|
run_gam report usageparameters customer
|
||||||
$gam report customer todrive tdnobrowser
|
run_gam report usage customer parameters gmail:num_emails_sent,accounts:num_1day_logins
|
||||||
#$gam report users fields accounts:is_less_secure_apps_access_allowed,gmail:last_imap_time,gmail:last_pop_time filters "accounts:last_login_time>2025-01-01T00:00:00.000Z" todrive tdnobrowser
|
run_gam report customer todrive tdnobrowser
|
||||||
$gam report users todrive tdnobrowser
|
#run_gam report users fields accounts:is_less_secure_apps_access_allowed,gmail:last_imap_time,gmail:last_pop_time filters "accounts:last_login_time>2025-01-01T00:00:00.000Z" todrive tdnobrowser
|
||||||
$gam report admin start -3d todrive tdnobrowser
|
run_gam report users todrive tdnobrowser
|
||||||
$gam print devices nopersonaldevices nodeviceusers filter "serial:$JID$JID$JID$JID-" | $gam csv - gam delete device id ~name
|
run_gam report admin start -3d todrive tdnobrowser
|
||||||
$gam config enable_dasa false save
|
run_gam redirect csv ./devices.csv print devices nopersonaldevices nodeviceusers filter "serial:$JID$JID$JID$JID-"
|
||||||
$gam print userinvitations
|
run_gam csv ./devices.csv gam delete device id ~name
|
||||||
$gam print userinvitations | $gam csv - gam send userinvitation ~name
|
run_gam config enable_dasa false save
|
||||||
$gam config enable_dasa false save
|
run_gam print userinvitations
|
||||||
$gam create caalevel "zzz_${newbase}" basic condition ipsubnetworks 1.1.1.1/32,2.2.2.2/32 endcondition
|
run_gam redirect csv ./invitations.csv print userinvitations
|
||||||
$gam print caalevels
|
run_gam csv ./invitations.csv gam send userinvitation ~name
|
||||||
$gam delete caalevel "zzz_${newbase}"
|
run_gam config enable_dasa false save
|
||||||
$gam user $gam_user add drivefile localfile gam.py parentid "${driveid}"
|
run_gam create caalevel "zzz_${newbase}" basic condition ipsubnetworks 1.1.1.1/32,2.2.2.2/32 endcondition
|
||||||
$gam user $gam_user update shareddrive "${driveid}" ou "${newou}"
|
run_gam print caalevels
|
||||||
$gam user $gam_user show shareddrives asadmin
|
run_gam delete caalevel "zzz_${newbase}"
|
||||||
$gam user $gam_user update shareddrive "${driveid}" ou "aaaGithub Actions" # so we can delete our OU...
|
run_gam user $gam_user add drivefile localfile gam.py parentid "${driveid}"
|
||||||
$gam user $gam_user delete shareddrive "${driveid}" nukefromorbit
|
run_gam user $gam_user update shareddrive "${driveid}" ou "${newou}"
|
||||||
ssoprofile=$($gam config debug_level 1 create inboundssoprofile name "El Goog ${newbase}" loginurl https://www.google.com logouturl https://www.google.com changepasswordurl https://www.google.com entityid ElGoog return_name_only)
|
run_gam user $gam_user show shareddrives asadmin
|
||||||
|
run_gam user $gam_user update shareddrive "${driveid}" ou "aaaGithub Actions" # so we can delete our OU...
|
||||||
|
run_gam user $gam_user delete shareddrive "${driveid}" nukefromorbit
|
||||||
|
ssoprofile=$(run_gam config debug_level 1 create inboundssoprofile name "El Goog ${newbase}" loginurl https://www.google.com logouturl https://www.google.com changepasswordurl https://www.google.com entityid ElGoog return_name_only)
|
||||||
if [ ${ssoprofile} != 'inProgress' ]; then
|
if [ ${ssoprofile} != 'inProgress' ]; then
|
||||||
$gam create inboundssocredential profile "id:${ssoprofile}" generate_key
|
run_gam create inboundssocredential profile "id:${ssoprofile}" generate_key
|
||||||
#$gam create inboundssoassignment profile "id:${ssoprofile}" orgunit "${newou}" mode SAML_SSO
|
#run_gam create inboundssoassignment profile "id:${ssoprofile}" orgunit "${newou}" mode SAML_SSO
|
||||||
#$gam delete inboundssoassignment "orgunit:${newou}"
|
#run_gam delete inboundssoassignment "orgunit:${newou}"
|
||||||
$gam delete inboundssoprofile "id:${ssoprofile}"
|
run_gam delete inboundssoprofile "id:${ssoprofile}"
|
||||||
fi
|
fi
|
||||||
echo "printer model count:"
|
echo "printer model count:"
|
||||||
$gam print printermodels | wc -l
|
run_gam print printermodels | wc -l
|
||||||
$gam print printers
|
run_gam print printers
|
||||||
printerid=$($gam create printer displayname "${newbase}" uri ipp://localhost:631 driverless description "made by ${gam_user}" ou "${newou}" nodetails | awk '{print substr($2, 1, length($2)-1)}')
|
printerid=$($gam create printer displayname "${newbase}" uri ipp://localhost:631 driverless description "made by ${gam_user}" ou "${newou}" returnIdOnly)
|
||||||
$gam info printer "$printerid"
|
run_gam info printer "$printerid"
|
||||||
$gam delete printer "$printerid"
|
run_gam delete printer "$printerid"
|
||||||
$gam delete ou "${newou}"
|
run_gam delete ou "${newou}"
|
||||||
|
|
||||||
- name: Tar Cache archive
|
- name: Tar Cache archive
|
||||||
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
||||||
working-directory: ${{ github.workspace }}
|
working-directory: ${{ github.workspace }}
|
||||||
run: |
|
run: |
|
||||||
if [[ "${RUNNER_OS}" == "Windows" ]]; then
|
#if [[ "${RUNNER_OS}" == "Windows" ]]; then
|
||||||
tar_folders="src/cpython/ bin/ssl"
|
# tar_folders="src/cpython/ bin/ssl"
|
||||||
else
|
#else
|
||||||
tar_folders="bin/"
|
# tar_folders="bin/"
|
||||||
fi
|
#fi
|
||||||
|
tar_folders="bin/"
|
||||||
echo '.git*' > ./excludes.txt
|
echo '.git*' > ./excludes.txt
|
||||||
tar cJvvf cache.tar.xz --exclude-from=excludes.txt $tar_folders
|
tar cJvvf cache.tar.xz --exclude-from=excludes.txt $tar_folders
|
||||||
|
|
||||||
merge:
|
|
||||||
if: (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
|
|
||||||
runs-on: ubuntu-24.04
|
|
||||||
needs: build
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
packages: write
|
|
||||||
steps:
|
|
||||||
- name: Merge Artifacts
|
|
||||||
uses: actions/upload-artifact/merge@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
||||||
with:
|
|
||||||
name: gam-binaries
|
|
||||||
pattern: gam-binaries-*
|
|
||||||
|
|
||||||
publish:
|
publish:
|
||||||
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
|
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
needs: merge
|
needs: build
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
packages: write
|
packages: write
|
||||||
@@ -1073,13 +1121,17 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Download artifacts
|
- name: Download artifacts
|
||||||
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # 5.0.0
|
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
|
||||||
|
with:
|
||||||
|
path: gam-binaries/
|
||||||
|
merge-multiple: true
|
||||||
|
skip-decompress: true
|
||||||
|
|
||||||
- name: VirusTotal Scan
|
- name: VirusTotal Scan
|
||||||
uses: crazy-max/ghaction-virustotal@d34968c958ae283fe976efed637081b9f9dcf74f # 4.2.0
|
uses: crazy-max/ghaction-virustotal@d34968c958ae283fe976efed637081b9f9dcf74f # 4.2.0
|
||||||
@@ -1096,7 +1148,7 @@ jobs:
|
|||||||
echo "dateversion=${dateversion}" >> $GITHUB_OUTPUT
|
echo "dateversion=${dateversion}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Publish draft release
|
- name: Publish draft release
|
||||||
uses: softprops/action-gh-release@6cbd405e2c4e67a21c47fa9e383d020e4e28b836 # v2.3.3
|
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
|
||||||
with:
|
with:
|
||||||
draft: true
|
draft: true
|
||||||
prerelease: false
|
prerelease: false
|
||||||
|
|||||||
59
.github/workflows/get-cacerts.yml
vendored
59
.github/workflows/get-cacerts.yml
vendored
@@ -1,14 +1,9 @@
|
|||||||
name: Check for Google Root CA Updates
|
name: Check for Google Root CA Updates
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
|
||||||
paths-ignore:
|
|
||||||
- 'wiki/**'
|
|
||||||
pull_request:
|
|
||||||
paths-ignore:
|
|
||||||
- 'wiki/**'
|
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '23 23 * * *'
|
- cron: '23 23 * * *'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
@@ -17,9 +12,9 @@ defaults:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-certs:
|
check-certs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-slim
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v5.0.0
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||||
with:
|
with:
|
||||||
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token
|
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token
|
||||||
fetch-depth: 0 # otherwise, you will failed to push refs to dest repo
|
fetch-depth: 0 # otherwise, you will failed to push refs to dest repo
|
||||||
@@ -30,9 +25,51 @@ jobs:
|
|||||||
echo "Current hash is: ${CURRENT_HASH}"
|
echo "Current hash is: ${CURRENT_HASH}"
|
||||||
echo "CURRENT_HASH=${CURRENT_HASH}" >> $GITHUB_ENV
|
echo "CURRENT_HASH=${CURRENT_HASH}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Get latest cacerts.pem file from Google
|
- name: Generate GAM-specific bundle with LE + Google roots
|
||||||
run: |
|
run: |
|
||||||
curl -o ./cacerts.pem -vvvv https://pki.goog/roots.pem
|
OUTPUT_FILE="cacerts.pem"
|
||||||
|
> "$OUTPUT_FILE"
|
||||||
|
|
||||||
|
process_cert() {
|
||||||
|
local url="$1"
|
||||||
|
local op_ca="$2"
|
||||||
|
local label="$3"
|
||||||
|
local tmp_cert=$(mktemp)
|
||||||
|
curl "$url" > "$tmp_cert"
|
||||||
|
local issuer=$(openssl x509 -noout -issuer -in "$tmp_cert" | sed -e 's/^issuer= *//')
|
||||||
|
local subject=$(openssl x509 -noout -subject -in "$tmp_cert" | sed -e 's/^subject= *//')
|
||||||
|
local serial_hex=$(openssl x509 -noout -serial -in "$tmp_cert" | sed -e 's/^serial=//')
|
||||||
|
local serial_dec=$(python3 -c "print(int('$serial_hex', 16))")
|
||||||
|
local md5=$(openssl x509 -noout -fingerprint -md5 -in "$tmp_cert" | sed -e 's/.*=//' | tr '[:upper:]' '[:lower:]')
|
||||||
|
local sha1=$(openssl x509 -noout -fingerprint -sha1 -in "$tmp_cert" | sed -e 's/.*=//' | tr '[:upper:]' '[:lower:]')
|
||||||
|
local sha256=$(openssl x509 -noout -fingerprint -sha256 -in "$tmp_cert" | sed -e 's/.*=//' | tr '[:upper:]' '[:lower:]')
|
||||||
|
echo "# Operating CA: $op_ca" >> "$OUTPUT_FILE"
|
||||||
|
echo "# Issuer: $issuer" >> "$OUTPUT_FILE"
|
||||||
|
echo "# Subject: $subject" >> "$OUTPUT_FILE"
|
||||||
|
echo "# Label: \"$label\"" >> "$OUTPUT_FILE"
|
||||||
|
echo "# Serial: $serial_dec" >> "$OUTPUT_FILE"
|
||||||
|
echo "# MD5 Fingerprint: $md5" >> "$OUTPUT_FILE"
|
||||||
|
echo "# SHA1 Fingerprint: $sha1" >> "$OUTPUT_FILE"
|
||||||
|
echo "# SHA256 Fingerprint: $sha256" >> "$OUTPUT_FILE"
|
||||||
|
cat "$tmp_cert" >> "$OUTPUT_FILE"
|
||||||
|
echo "" >> "$OUTPUT_FILE"
|
||||||
|
rm "$tmp_cert"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "#" >> "$OUTPUT_FILE"
|
||||||
|
echo "# This is a custom certificate authority bundle for GAM" >> "$OUTPUT_FILE"
|
||||||
|
echo "# It's composed of Let's Encrypt Root CAs and Google's" >> "$OUTPUT_FILE"
|
||||||
|
echo "# certificate bundle. This should be the minimal list of" >> "$OUTPUT_FILE"
|
||||||
|
echo "# CAs required to talk to Google and Github." >> "$OUTPUT_FILE"
|
||||||
|
echo"" >> "$OUTPUT_FILE"
|
||||||
|
echo "Processing Let's Encrypt ISRG Root X1..."
|
||||||
|
process_cert "https://letsencrypt.org/certs/isrgrootx1.pem" "Let's Encrypt" "ISRG Root X1"
|
||||||
|
echo "Processing Let's Encrypt ISRG Root X2..."
|
||||||
|
process_cert "https://letsencrypt.org/certs/isrg-root-x2.pem" "Let's Encrypt" "ISRG Root X2"
|
||||||
|
|
||||||
|
echo "Appending Google's roots.pem..."
|
||||||
|
curl -s https://pki.goog/roots.pem >> "$OUTPUT_FILE"
|
||||||
|
echo "Done! The new bundle has been saved to $OUTPUT_FILE."
|
||||||
|
|
||||||
- name: Compare hashes
|
- name: Compare hashes
|
||||||
run: |
|
run: |
|
||||||
@@ -51,6 +88,6 @@ jobs:
|
|||||||
git diff --quiet && git diff --staged --quiet || git commit -am '[ci skip] Updated cacerts.pem'
|
git diff --quiet && git diff --staged --quiet || git commit -am '[ci skip] Updated cacerts.pem'
|
||||||
|
|
||||||
- name: Push changes
|
- name: Push changes
|
||||||
uses: ad-m/github-push-action@master
|
uses: ad-m/github-push-action@77c5b412c50b723d2a4fbc6d71fb5723bcd439aa
|
||||||
with:
|
with:
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ authors = [
|
|||||||
#significant compile dependencies.
|
#significant compile dependencies.
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrow>=1.3.0",
|
"arrow>=1.3.0",
|
||||||
"chardet>=5.2.0",
|
"chardet==5.2.0",
|
||||||
"cryptography>=46.0.5",
|
"cryptography>=46.0.5",
|
||||||
"distro; sys_platform=='linux'",
|
"distro; sys_platform=='linux'",
|
||||||
"filelock>=3.18.0",
|
"filelock>=3.18.0",
|
||||||
@@ -31,11 +31,11 @@ requires-python = ">=3.10"
|
|||||||
classifiers = [
|
classifiers = [
|
||||||
"Programming Language :: Python :: 3",
|
"Programming Language :: Python :: 3",
|
||||||
"Programming Language :: Python :: 3 :: Only",
|
"Programming Language :: Python :: 3 :: Only",
|
||||||
"Programming Language :: Python :: 3.9",
|
|
||||||
"Programming Language :: Python :: 3.10",
|
"Programming Language :: Python :: 3.10",
|
||||||
"Programming Language :: Python :: 3.11",
|
"Programming Language :: Python :: 3.11",
|
||||||
"Programming Language :: Python :: 3.12",
|
"Programming Language :: Python :: 3.12",
|
||||||
"Programming Language :: Python :: 3.13",
|
"Programming Language :: Python :: 3.13",
|
||||||
|
"Programming Language :: Python :: 3.14",
|
||||||
"Operating System :: OS Independent",
|
"Operating System :: OS Independent",
|
||||||
]
|
]
|
||||||
license = {text = "Apache License (2.0)"}
|
license = {text = "Apache License (2.0)"}
|
||||||
|
|||||||
@@ -4335,14 +4335,14 @@ gam update deviceuserstate <DeviceUserEntity> [clientid <String>]
|
|||||||
# Cloud Identity Policies
|
# Cloud Identity Policies
|
||||||
|
|
||||||
gam info policies <CIPolicyNameEntity>
|
gam info policies <CIPolicyNameEntity>
|
||||||
[nowarnings] [noappnames]
|
[nowarnings] [noappnames] [noidmappimg]
|
||||||
[formatjson]
|
[formatjson]
|
||||||
gam print policies [todrive <ToDriveAttribute>*]
|
gam print policies [todrive <ToDriveAttribute>*]
|
||||||
[filter <String>] [nowarnings] [noappnames]
|
[filter <String>] [nowarnings] [noappnames] [noidmappimg]
|
||||||
[group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
|
[group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
|
||||||
[formatjson [quotechar <Character>]]
|
[formatjson [quotechar <Character>]]
|
||||||
gam show policies
|
gam show policies
|
||||||
[filter <String>] [nowarnings] [noappnames]
|
[filter <String>] [nowarnings] [noappnames] [noidmappimg]
|
||||||
[group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
|
[group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
|
||||||
[formatjson]
|
[formatjson]
|
||||||
|
|
||||||
@@ -4568,8 +4568,8 @@ gam check ou|org <OrgUnitItem> [todrive <ToDriveAttribute>*]
|
|||||||
usedriverlessconfig|
|
usedriverlessconfig|
|
||||||
<PrinterFieldNameList> ::= "<PrinterFieldName>(,<PrinterFieldName>)*"
|
<PrinterFieldNameList> ::= "<PrinterFieldName>(,<PrinterFieldName>)*"
|
||||||
|
|
||||||
gam create printer <PrinterAttribute>+
|
gam create printer <PrinterAttribute>+ [nodetails|returnidonly]
|
||||||
gam update printer <PrinterID> <PrinterAttribute>+
|
gam update printer <PrinterID> <PrinterAttribute>+ [nodetails|returnidonly]
|
||||||
gam delete printer
|
gam delete printer
|
||||||
<PrinterIDList>|
|
<PrinterIDList>|
|
||||||
<FileSelector>|
|
<FileSelector>|
|
||||||
@@ -4926,36 +4926,43 @@ gam print schema|schemas [todrive <ToDriveAttribute>*]
|
|||||||
gam sendemail [recipient|to] <RecipientEntity>
|
gam sendemail [recipient|to] <RecipientEntity>
|
||||||
[from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>]
|
[from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>]
|
||||||
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
[subject <String>]
|
[subject <String>] [<MessageContent>] [html [<Boolean>]]
|
||||||
[<MessageContent>]
|
|
||||||
(replace <Tag> <String>)*
|
(replace <Tag> <String>)*
|
||||||
(replaceregex <RESearchPattern> <RESubstitution> <Tag> <String>)*
|
(replaceregex <RESearchPattern> <RESubstitution> <Tag> <String>)*
|
||||||
[html [<Boolean>]] (attach <FileName> [charset <Charset>])*
|
(attach <FileName> [charset <Charset>])*
|
||||||
(embedimage <FileName> <String>)*
|
(embedimage <FileName> <String>)*
|
||||||
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
|
[threadid <String>]
|
||||||
gam <UserTypeEntity> sendemail recipient|to <RecipientEntity>
|
gam <UserTypeEntity> sendemail recipient|to <RecipientEntity>
|
||||||
[replyto <EmailAddress>]
|
[replyto <EmailAddress>]
|
||||||
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
[subject <String>]
|
[subject <String>] [<MessageContent>] [html [<Boolean>]]
|
||||||
[<MessageContent>]
|
|
||||||
(replace <Tag> <String>)*
|
(replace <Tag> <String>)*
|
||||||
(replaceregex <RESearchPattern> <RESubstitution> <Tag> <String>)*
|
(replaceregex <RESearchPattern> <RESubstitution> <Tag> <String>)*
|
||||||
[html [<Boolean>]] (attach <FileName> [charset <Charset>])*
|
(attach <FileName> [charset <Charset>])*
|
||||||
(embedimage <FileName> <String>)*
|
(embedimage <FileName> <String>)*
|
||||||
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
|
[threadid <String>]
|
||||||
gam <UserTypeEntity> sendemail from <EmailAddress>
|
gam <UserTypeEntity> sendemail from <EmailAddress>
|
||||||
[replyto <EmailAddress>]
|
[replyto <EmailAddress>]
|
||||||
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
[subject <String>]
|
[subject <String>] [<MessageContent>] [html [<Boolean>]]
|
||||||
[<MessageContent>]
|
|
||||||
(replace <Tag> <String>)*
|
(replace <Tag> <String>)*
|
||||||
(replaceregex <RESearchPattern> <RESubstitution> <Tag> <String>)*
|
(replaceregex <RESearchPattern> <RESubstitution> <Tag> <String>)*
|
||||||
[html [<Boolean>]] (attach <FileName> [charset <Charset>])*
|
(attach <FileName> [charset <Charset>])*
|
||||||
(embedimage <FileName> <String>)*
|
(embedimage <FileName> <String>)*
|
||||||
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
|
[threadid <String>]
|
||||||
|
gam <UserTypeEntity> sendreply
|
||||||
|
(((query <QueryGmail> [querytime<String> <Date>]*) [or|and])+) | (ids <MessageIDEntity>)
|
||||||
|
[replyto <EmailAddress>]
|
||||||
|
[subject <String>] [<MessageContent>] [html [<Boolean>]]
|
||||||
|
(attach <FileName> [charset <CharSet>])*
|
||||||
|
(embedimage <FileName> <String>)*
|
||||||
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
|
|
||||||
# Shared Drives - Administrator
|
# Shared Drives - Administrator
|
||||||
|
|
||||||
@@ -5693,6 +5700,7 @@ gam download storagefile <StorageBucketObjectName>
|
|||||||
fullname|
|
fullname|
|
||||||
gender|
|
gender|
|
||||||
givenname|firstname|
|
givenname|firstname|
|
||||||
|
guestaccountinfo|
|
||||||
id|
|
id|
|
||||||
ims|im|
|
ims|im|
|
||||||
includeinglobaladdresslist|gal|
|
includeinglobaladdresslist|gal|
|
||||||
@@ -5700,6 +5708,7 @@ gam download storagefile <StorageBucketObjectName>
|
|||||||
isdelegatedadmin|admin|isadmin|
|
isdelegatedadmin|admin|isadmin|
|
||||||
isenforcedin2sv|is2svenforced|
|
isenforcedin2sv|is2svenforced|
|
||||||
isenrolledin2sv|is2svenrolled|
|
isenrolledin2sv|is2svenrolled|
|
||||||
|
isguestuser|
|
||||||
ismailboxsetup|
|
ismailboxsetup|
|
||||||
keyword|keywords|
|
keyword|keywords|
|
||||||
language|languages|
|
language|languages|
|
||||||
@@ -5801,12 +5810,12 @@ gam download storagefile <StorageBucketObjectName>
|
|||||||
|
|
||||||
<UserClearAttribute> ::=
|
<UserClearAttribute> ::=
|
||||||
(address clear)|
|
(address clear)|
|
||||||
(otheremail clear)|
|
|
||||||
(externalid clear)|
|
(externalid clear)|
|
||||||
(im clear)|
|
(im clear)|
|
||||||
(keyword clear)|
|
(keyword clear)|
|
||||||
(location clear)|
|
(location clear)|
|
||||||
(organization clear)|
|
(organization clear)|
|
||||||
|
(otheremail clear)|
|
||||||
(phone clear)|
|
(phone clear)|
|
||||||
(posix clear)|
|
(posix clear)|
|
||||||
(relation clear)|
|
(relation clear)|
|
||||||
@@ -5819,6 +5828,18 @@ gam download storagefile <StorageBucketObjectName>
|
|||||||
<UserMultiAttribute>|
|
<UserMultiAttribute>|
|
||||||
<UserClearAttribute>
|
<UserClearAttribute>
|
||||||
|
|
||||||
|
<UserMultiAttributeFilterName> ::=
|
||||||
|
address|addresses|
|
||||||
|
externalid|externalids|
|
||||||
|
im|ims|
|
||||||
|
keyword|keywords|
|
||||||
|
location|locations|
|
||||||
|
orgainzation|organizations|
|
||||||
|
otheremail|otheremails|
|
||||||
|
phone|phones|
|
||||||
|
relation|relations|
|
||||||
|
website|websites
|
||||||
|
|
||||||
gam create|add user <EmailAddress> [ignorenullpassword] <UserAttribute>*
|
gam create|add user <EmailAddress> [ignorenullpassword] <UserAttribute>*
|
||||||
[verifynotinvitable|alwaysevict]
|
[verifynotinvitable|alwaysevict]
|
||||||
(groups [<GroupRole>] [[delivery] <DeliverySetting>] <GroupEntity>)*
|
(groups [<GroupRole>] [[delivery] <DeliverySetting>] <GroupEntity>)*
|
||||||
@@ -5873,6 +5894,8 @@ gam info user [<UserItem>]
|
|||||||
[nolicenses|nolicences|licenses|licences]
|
[nolicenses|nolicences|licenses|licences]
|
||||||
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
|
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
|
||||||
[userview] <UserFieldName>* [fields <UserFieldNameList>]
|
[userview] <UserFieldName>* [fields <UserFieldNameList>]
|
||||||
|
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
|
||||||
|
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
|
||||||
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
||||||
[formatjson]
|
[formatjson]
|
||||||
|
|
||||||
@@ -5909,6 +5932,8 @@ gam info users <UserTypeEntity>
|
|||||||
[nolicenses|nolicences|licenses|licences]
|
[nolicenses|nolicences|licenses|licences]
|
||||||
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
|
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
|
||||||
[userview] <UserFieldName>* [fields <UserFieldNameList>]
|
[userview] <UserFieldName>* [fields <UserFieldNameList>]
|
||||||
|
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
|
||||||
|
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
|
||||||
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
||||||
[formatjson]
|
[formatjson]
|
||||||
|
|
||||||
@@ -5945,6 +5970,8 @@ gam <UserTypeEntity> info users
|
|||||||
[nolicenses|nolicences|licenses|licences]
|
[nolicenses|nolicences|licenses|licences]
|
||||||
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
|
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
|
||||||
[userview] <UserFieldName>* [fields <UserFieldNameList>]
|
[userview] <UserFieldName>* [fields <UserFieldNameList>]
|
||||||
|
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
|
||||||
|
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
|
||||||
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
||||||
[formatjson]
|
[formatjson]
|
||||||
|
|
||||||
@@ -5964,6 +5991,8 @@ gam print users [todrive <ToDriveAttribute>*]
|
|||||||
[schemas|custom|customschemas all|<SchemaNameList>]
|
[schemas|custom|customschemas all|<SchemaNameList>]
|
||||||
[emailpart|emailparts|username]
|
[emailpart|emailparts|username]
|
||||||
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||||
|
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
|
||||||
|
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
|
||||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||||
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
|
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
|
||||||
@@ -5981,6 +6010,8 @@ gam print users [todrive <ToDriveAttribute>*] select <UserTypeEntity>
|
|||||||
[schemas|custom|customschemas all|<SchemaNameList>]
|
[schemas|custom|customschemas all|<SchemaNameList>]
|
||||||
[emailpart|emailparts|username]
|
[emailpart|emailparts|username]
|
||||||
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||||
|
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
|
||||||
|
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
|
||||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||||
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
|
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
|
||||||
@@ -5996,6 +6027,8 @@ gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
|||||||
[schemas|custom|customschemas all|<SchemaNameList>]
|
[schemas|custom|customschemas all|<SchemaNameList>]
|
||||||
[emailpart|emailparts|username]
|
[emailpart|emailparts|username]
|
||||||
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||||
|
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
|
||||||
|
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
|
||||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||||
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
|
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
|
||||||
@@ -7496,7 +7529,7 @@ gam <UserTypeEntity> print filecounts [todrive <ToDriveAttribute>*]
|
|||||||
[filenamematchpattern <REMatchPattern>]
|
[filenamematchpattern <REMatchPattern>]
|
||||||
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
||||||
[excludetrashed]
|
[excludetrashed]
|
||||||
[showsize] [showmimetypesize]
|
[showsize] [showsizeunits] [showmimetypesize]
|
||||||
[showlastmodification] [pathdelimiter <Character>]
|
[showlastmodification] [pathdelimiter <Character>]
|
||||||
(addcsvdata <FieldName> <String>)*
|
(addcsvdata <FieldName> <String>)*
|
||||||
[summary none|only|plus] [summaryuser <String>]
|
[summary none|only|plus] [summaryuser <String>]
|
||||||
@@ -7512,7 +7545,7 @@ gam <UserTypeEntity> show filecounts
|
|||||||
[filenamematchpattern <REMatchPattern>]
|
[filenamematchpattern <REMatchPattern>]
|
||||||
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
||||||
[excludetrashed]
|
[excludetrashed]
|
||||||
[showsize] [showmimetypesize]
|
[showsize] [showsizeunits] [showmimetypesize]
|
||||||
[showlastmodification] [pathdelimiter <Character>]
|
[showlastmodification] [pathdelimiter <Character>]
|
||||||
[summary none|only|plus] [summaryuser <String>]
|
[summary none|only|plus] [summaryuser <String>]
|
||||||
|
|
||||||
@@ -7582,7 +7615,7 @@ gam <UserTypeEntity> print filelist [todrive <ToDriveAttribute>*]
|
|||||||
[excludetrashed]
|
[excludetrashed]
|
||||||
[maxfiles <Integer>] [nodataheaders <String>]
|
[maxfiles <Integer>] [nodataheaders <String>]
|
||||||
[countsonly [summary none|only|plus] [summaryuser <String>]
|
[countsonly [summary none|only|plus] [summaryuser <String>]
|
||||||
[showsource] [showsize] [showmimetypesize]]
|
[showsource] [showsize] [showsizeunits] [showmimetypesize]]
|
||||||
[countsrowfilter]
|
[countsrowfilter]
|
||||||
[filepath|fullpath [folderpathonly [<Boolean>]] [pathdelimiter <Character>] [addpathstojson] [showdepth]] [buildtree]
|
[filepath|fullpath [folderpathonly [<Boolean>]] [pathdelimiter <Character>] [addpathstojson] [showdepth]] [buildtree]
|
||||||
[allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)]
|
[allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)]
|
||||||
@@ -8881,17 +8914,17 @@ gam <UserTypeEntity> delete tokens clientid <ClientID>
|
|||||||
|
|
||||||
gam <UserTypeEntity> print tokens|token [todrive <ToDriveAttribute>*] [clientid <ClientID>]
|
gam <UserTypeEntity> print tokens|token [todrive <ToDriveAttribute>*] [clientid <ClientID>]
|
||||||
[usertokencounts|(aggregateusersby|orderby clientid|id|appname|displaytext)]
|
[usertokencounts|(aggregateusersby|orderby clientid|id|appname|displaytext)]
|
||||||
[delimiter <Character>]
|
[delimiter <Character>] [gcpdetails]
|
||||||
gam <UserTypeEntity> show tokens|token|3lo|oauth [clientid <ClientID>]
|
gam <UserTypeEntity> show tokens|token|3lo|oauth [clientid <ClientID>]
|
||||||
[usertokencounts|(aggregateusersby|orderby clientid|id|appname|displaytext)]
|
[usertokencounts|(aggregateusersby|orderby clientid|id|appname|displaytext)]
|
||||||
[delimiter <Character>]
|
[delimiter <Character>] [gcpdetails]
|
||||||
gam print tokens|token [todrive <ToDriveAttribute>*] [clientid <ClientID>]
|
gam print tokens|token [todrive <ToDriveAttribute>*] [clientid <ClientID>]
|
||||||
[usertokencounts|(aggregateusersby|orderby clientid|id|appname|displaytext)]
|
[usertokencounts|(aggregateusersby|orderby clientid|id|appname|displaytext)]
|
||||||
[delimiter <Character>]
|
[delimiter <Character>] [gcpdetails]
|
||||||
[<UserTypeEntity>]
|
[<UserTypeEntity>]
|
||||||
gam show tokens|token [clientid <ClientID>]
|
gam show tokens|token [clientid <ClientID>]
|
||||||
[usertokencounts|(aggregateusersby|orderby clientid|id|appname|displaytext)]
|
[usertokencounts|(aggregateusersby|orderby clientid|id|appname|displaytext)]
|
||||||
[delimiter <Character>]
|
[delimiter <Character>] [gcpdetails]
|
||||||
[<UserTypeEntity>]
|
[<UserTypeEntity>]
|
||||||
|
|
||||||
# Users - YouTube
|
# Users - YouTube
|
||||||
|
|||||||
@@ -1,3 +1,158 @@
|
|||||||
|
7.37.00
|
||||||
|
|
||||||
|
Added new client access scopes used by `gam print tokens`.
|
||||||
|
```
|
||||||
|
[*] 52) Resource Manager API - Organizations readonly
|
||||||
|
[*] 53) Resource Manager API - Projects readonly
|
||||||
|
```
|
||||||
|
|
||||||
|
Added option `gcpdetails` to `gam print tokens` that uses these scopes to get additional project information.
|
||||||
|
|
||||||
|
7.36.03
|
||||||
|
|
||||||
|
Added command to send email replies that causes Gmail to recognize the message
|
||||||
|
in conversation mode for the user sending the reply and the user receiving the reply;
|
||||||
|
GAM supplies the necessary headers and options.
|
||||||
|
```
|
||||||
|
gam <UserTypeEntity> sendreply
|
||||||
|
(((query <QueryGmail> [querytime<String> <Date>]*) [or|and])+) | (ids <MessageIDEntity>)
|
||||||
|
[replyto <EmailAddress>]
|
||||||
|
[subject <String>] [<MessageContent>] [html [<Boolean>]]
|
||||||
|
(attach <FileName> [charset <CharSet>])*
|
||||||
|
(embedimage <FileName> <String>)*
|
||||||
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
|
|
||||||
|
gam user user@domain.com sendreply query "rfc822MsgId:<CAAMmEdqj43...1OsQ@mail.gmail.com>" textmessage "Thanks for the information"
|
||||||
|
gam user user@domain.com sendreply ids 19cfc3506c02c22b textmessage "Thanks for the information"
|
||||||
|
```
|
||||||
|
|
||||||
|
* See: https://github.com/GAM-team/GAM/wiki/Send-Email#conversation-mode
|
||||||
|
|
||||||
|
7.36.02
|
||||||
|
|
||||||
|
Added option `threadid <String>` to `gam [<UserTypeEntity>] sendemail` that causes Gmail to recognize the message
|
||||||
|
in conversation mode in for the user sending the message.
|
||||||
|
|
||||||
|
* See: https://github.com/GAM-team/GAM/wiki/Send-Email#conversation-mode
|
||||||
|
|
||||||
|
7.36.01
|
||||||
|
|
||||||
|
Fixed bug in `gam info|print|show policies` where the `policyQuery/query` field was not displayed.
|
||||||
|
|
||||||
|
Added option `noidmapping` to `gam info|print|show policies` to suppress adding the `policyQuery/groupEmail` and
|
||||||
|
`policyQuery/orgUnitPath` name fields that are mapped from the `policyQuery/group` and `policyQuery/orgInit` id fields.
|
||||||
|
|
||||||
|
7.36.00
|
||||||
|
|
||||||
|
Added options `filtermultiattrtype` and filtermultiattrcustom` to `gam info user` and
|
||||||
|
`gam print users` that support filtering `<UserMultiAttribute>` display based on `type` or `customType`.
|
||||||
|
|
||||||
|
```
|
||||||
|
<UserMultiAttributeFilterName> ::=
|
||||||
|
address|addresses|
|
||||||
|
externalid|externalids|
|
||||||
|
im|ims|
|
||||||
|
keyword|keywords|
|
||||||
|
location|locations|
|
||||||
|
orgainzation|organizations|
|
||||||
|
otheremail|otheremails|
|
||||||
|
phone|phones|
|
||||||
|
relation|relations|
|
||||||
|
website|websites
|
||||||
|
```
|
||||||
|
|
||||||
|
* `filtermultiattrtype <UserMultiAttributeFilterName> <String>` - Display `<UserMultiAttributeFilterName>` if its `type` is `<String>`
|
||||||
|
* `filtermultiattrcustom <UserMultiAttributeFilterName> <String>` - Display `<UserMultiAttributeFilterName>` if its `customType` is `<String>`
|
||||||
|
|
||||||
|
```
|
||||||
|
gam info user user@domain.com quick filtermultiattrtype organizations work filtermultiattrcustom phones private
|
||||||
|
```
|
||||||
|
|
||||||
|
7.35.03
|
||||||
|
|
||||||
|
Updated `gam <UserTypeEntity> print filelist|filecounts` to handle options `showsize` and `showsizeunits` as independent options.
|
||||||
|
* `showsize` - Display a column `Size` with a byte count
|
||||||
|
* `showsizeunits` - Display a column `SizeUnits` with a formatted size with units
|
||||||
|
|
||||||
|
If you select both options, you can sort multiple rows using the `Size` column.
|
||||||
|
|
||||||
|
7.35.02
|
||||||
|
|
||||||
|
Added option `showsizeunits` to `gam gam <UserTypeEntity> print filelist|filecounts` as an alternative to option `showsize`.
|
||||||
|
* `showsize` - 31549200951 - This is a byte count
|
||||||
|
* `showsizeunits` - 31.55 GB - This is as shown in the Admin console
|
||||||
|
|
||||||
|
7.35.01
|
||||||
|
|
||||||
|
The following commands have been updated to not verify the existence of `gam.cfg` credentials files
|
||||||
|
as the WARNING messages about the missing files can be confusing to new users setting up GAM.
|
||||||
|
```
|
||||||
|
gam checkconn
|
||||||
|
gam oauth|oauth2
|
||||||
|
gam version
|
||||||
|
```
|
||||||
|
|
||||||
|
7.35.00
|
||||||
|
|
||||||
|
Windows `gam-7.wx.yz-x86_64.msi` has been replaced with `gam-7.wx.yz-x86_64.exe`.
|
||||||
|
|
||||||
|
Windows `gam-7.wx.yz-arm64.msi` has been replaced with `gam-7.wx.yz-arm64.exe`.
|
||||||
|
|
||||||
|
Updated cacerts.pem to avoid to following error in `gam checkconn`.
|
||||||
|
```
|
||||||
|
Checking raw.githubusercontent.com (185.199.110.133) (2)... ERROR
|
||||||
|
Certificate verification failed. If you are behind a firewall / proxy server that does TLS / SSL inspection you may need to point GAM at your certificate authority file by setting cacerts_pem = /path/to/your/certauth.pem in gam.cfg.
|
||||||
|
```
|
||||||
|
|
||||||
|
If you have customized cacerts.pem, update your version with the `Operating CA: Let's Encrypt` values from the GAM default version.
|
||||||
|
|
||||||
|
7.34.13
|
||||||
|
|
||||||
|
Fixed bug in `gam info policies <CIPolicyNameEntity> ... formatjson` where extraneous line
|
||||||
|
`Show Info 1 Policy` was displayed.
|
||||||
|
|
||||||
|
7.34.12
|
||||||
|
|
||||||
|
Fixed build errors that prevented Windows zip files from being created.
|
||||||
|
|
||||||
|
Added option `returnidonly` to `gam create|update printer` that causes GAM to return just the ID
|
||||||
|
of the printer.
|
||||||
|
|
||||||
|
7.34.11
|
||||||
|
|
||||||
|
Updated gam-install.sh script for macOS/Linux to properly config GAM when the answer to the following question is No.
|
||||||
|
```
|
||||||
|
Can you run a full browser on this machine? (usually Y for macOS, N for Linux if you SSH into this machine)
|
||||||
|
```
|
||||||
|
|
||||||
|
7.34.10
|
||||||
|
|
||||||
|
Fixed bug where `formatjson quotechar <Character>` on the command line did not override `redirect csv <FileName> multiprocess quotechar <Character>`.
|
||||||
|
|
||||||
|
7.34.09
|
||||||
|
|
||||||
|
Updated `gam <UserTypeEntity> update photo` to delete the user's existing photo
|
||||||
|
before performing the update as the API update will succeed but not replace a user's existing self-set photo.
|
||||||
|
|
||||||
|
7.34.08
|
||||||
|
|
||||||
|
Rebuild to avoid the following error:
|
||||||
|
```
|
||||||
|
requests/__init__.py:113: RequestsDependencyWarning: urllib3 (2.6.3) or chardet (6.0.0.post1)/charset_normalizer (3.4.4) doesn't match a supported version!
|
||||||
|
```
|
||||||
|
|
||||||
|
7.34.07
|
||||||
|
|
||||||
|
Added the following command to create a guest user.
|
||||||
|
* See: https://support.google.com/a/answer/16558545
|
||||||
|
```
|
||||||
|
gam create guestuser <EmailAddress>
|
||||||
|
```
|
||||||
|
|
||||||
|
Added the following items to `<UserFieldName>`:
|
||||||
|
* `guestaccountinfo` - Additional guest-related metadata fields
|
||||||
|
* `isguestuser` - Indicates if the inserted user is a guest
|
||||||
|
|
||||||
7.34.06
|
7.34.06
|
||||||
|
|
||||||
Added option `copyfolderpermissions [<Boolean>]` to `gam <UserTypeEntity> copy|move drivefile`.
|
Added option `copyfolderpermissions [<Boolean>]` to `gam <UserTypeEntity> copy|move drivefile`.
|
||||||
@@ -1499,7 +1654,7 @@ Re-run the command specify a new service account name with: saname <ServiceAccou
|
|||||||
|
|
||||||
Native support for Windows 11 Arm-based devices.
|
Native support for Windows 11 Arm-based devices.
|
||||||
|
|
||||||
Renamed some MacOS and Linux binary installer files to align on terminology. Everything is "arm64" now, no "aarch64".
|
Renamed some macOS and Linux binary installer files to align on terminology. Everything is "arm64" now, no "aarch64".
|
||||||
|
|
||||||
7.06.05
|
7.06.05
|
||||||
|
|
||||||
@@ -2108,7 +2263,7 @@ for `[R] 35) Meet API (supports readonly)` as it is a special case.
|
|||||||
|
|
||||||
7.00.39
|
7.00.39
|
||||||
|
|
||||||
Supported MacOS versions are now in the download filename.
|
Supported macOS versions are now in the download filename.
|
||||||
|
|
||||||
Minor code fixes.
|
Minor code fixes.
|
||||||
|
|
||||||
@@ -3911,11 +4066,11 @@ See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-Drive-Files-Display#fil
|
|||||||
|
|
||||||
6.65.12
|
6.65.12
|
||||||
|
|
||||||
Additional updates on MacOS when a `gam csv` command is interrupted with a contol-C.
|
Additional updates on macOS when a `gam csv` command is interrupted with a contol-C.
|
||||||
|
|
||||||
6.65.11
|
6.65.11
|
||||||
|
|
||||||
Updated multiprocessing to handle the following error that occurs on MacOS when a `gam csv` command
|
Updated multiprocessing to handle the following error that occurs on macOS when a `gam csv` command
|
||||||
is interrupted with a contol-C.
|
is interrupted with a contol-C.
|
||||||
```
|
```
|
||||||
multiprocessing/resource_tracker.py:224: UserWarning: resource_tracker: There appear to be N leaked semaphore objects to clean up at shutdown
|
multiprocessing/resource_tracker.py:224: UserWarning: resource_tracker: There appear to be N leaked semaphore objects to clean up at shutdown
|
||||||
@@ -6076,7 +6231,7 @@ Improved code for `gam [<UserTypeEntity>] create teamdrive <Name> ou <OrgUnitIte
|
|||||||
|
|
||||||
6.29.04
|
6.29.04
|
||||||
|
|
||||||
Updated multiprocessing on MacOS to use `spawn` instead of `fork` when starting subprocesses
|
Updated multiprocessing on macOS to use `spawn` instead of `fork` when starting subprocesses
|
||||||
as `fork` was unreliable when large numbers (>20) of threads were used; subprocesses would
|
as `fork` was unreliable when large numbers (>20) of threads were used; subprocesses would
|
||||||
hang and never complete.
|
hang and never complete.
|
||||||
|
|
||||||
@@ -6198,7 +6353,7 @@ then filters the list to only those in `<PeopleContactGroupItem>`; quota limits
|
|||||||
|
|
||||||
6.28.03
|
6.28.03
|
||||||
|
|
||||||
Build MacOS x86_64 and arm64 executables.
|
Build macOS x86_64 and arm64 executables.
|
||||||
|
|
||||||
6.28.02
|
6.28.02
|
||||||
|
|
||||||
@@ -6436,7 +6591,7 @@ This addresses the following issue:
|
|||||||
Updated `gam <UserTypeEntity> add|delete|update|print|show datastudiopermissions` to display an appropriate
|
Updated `gam <UserTypeEntity> add|delete|update|print|show datastudiopermissions` to display an appropriate
|
||||||
error message, `The caller does not have permission`, when the user doesn't have permission to execute the command.
|
error message, `The caller does not have permission`, when the user doesn't have permission to execute the command.
|
||||||
Previously, the following incorrect error message was displayed:
|
Previously, the following incorrect error message was displayed:
|
||||||
`ERROR: Data Studio API not enabled. Please run "gam update project" and "gam user user@domain.com check serviceaccount"`
|
`ERROR: Data Studio API not enabled. Please run "gam update project" and "gam user user@domain.com update serviceaccount"`
|
||||||
|
|
||||||
6.26.14
|
6.26.14
|
||||||
|
|
||||||
@@ -6545,7 +6700,7 @@ Added command that allows checking if a user is a member of specific groups and
|
|||||||
|
|
||||||
6.26.00
|
6.26.00
|
||||||
|
|
||||||
Build MacOS universal version.
|
Build macOS universal version.
|
||||||
|
|
||||||
* Upgraded to OpenSSL 3.0.5 where possible.
|
* Upgraded to OpenSSL 3.0.5 where possible.
|
||||||
|
|
||||||
@@ -6718,7 +6873,7 @@ and display drive labels on files. Please test/experiment and report any issues.
|
|||||||
To use these commands you must add the 'Drive Labels API' to your project and update your service account authorization.
|
To use these commands you must add the 'Drive Labels API' to your project and update your service account authorization.
|
||||||
```
|
```
|
||||||
gam update project
|
gam update project
|
||||||
gam user user@domain.com check serviceaccount
|
gam user user@domain.com update serviceaccount
|
||||||
```
|
```
|
||||||
Supported editions for this feature: Business Standard and Business Plus; Enterprise; Education Standard and Education Plus; G Suite Business; Essentials.
|
Supported editions for this feature: Business Standard and Business Plus; Enterprise; Education Standard and Education Plus; G Suite Business; Essentials.
|
||||||
|
|
||||||
@@ -6916,7 +7071,7 @@ ERROR: 403: permissionDenied - Google Forms API has not been used in project XXX
|
|||||||
```
|
```
|
||||||
is replaced with
|
is replaced with
|
||||||
```
|
```
|
||||||
ERROR: Forms API not enabled. Please run "gam update project" and "gam user user@domain.com check serviceaccount"
|
ERROR: Forms API not enabled. Please run "gam update project" and "gam user user@domain.com update serviceaccount"
|
||||||
```
|
```
|
||||||
|
|
||||||
6.23.00
|
6.23.00
|
||||||
@@ -9274,7 +9429,7 @@ To use this feature you must add the `People API` to your project and authorize
|
|||||||
* `People API - Other Contacts - read only`: https://www.googleapis.com/auth/contacts.other.readonly
|
* `People API - Other Contacts - read only`: https://www.googleapis.com/auth/contacts.other.readonly
|
||||||
```
|
```
|
||||||
gam update project
|
gam update project
|
||||||
gam user user@domain.com check serviceaccount
|
gam user user@domain.com update serviceaccount
|
||||||
```
|
```
|
||||||
|
|
||||||
Added commands to display user's contact groups using the People API.
|
Added commands to display user's contact groups using the People API.
|
||||||
@@ -9315,7 +9470,7 @@ To use these features you must add the `People API` to your project and authoriz
|
|||||||
```
|
```
|
||||||
gam update project
|
gam update project
|
||||||
gam oauth create
|
gam oauth create
|
||||||
gam user user@domain.com check serviceaccount
|
gam user user@domain.com update serviceaccount
|
||||||
```
|
```
|
||||||
|
|
||||||
Following Jay's lead, added new license SKU `Cloud Search`.
|
Following Jay's lead, added new license SKU `Cloud Search`.
|
||||||
@@ -9354,7 +9509,7 @@ Added commands to display Data Studio assets and display/manage Data Studio perm
|
|||||||
To use these commands you must add the `Data Studio API` to your project and update your service account authorization.
|
To use these commands you must add the `Data Studio API` to your project and update your service account authorization.
|
||||||
```
|
```
|
||||||
gam update project
|
gam update project
|
||||||
gam user user@domain.com check serviceaccount
|
gam user user@domain.com update serviceaccount
|
||||||
```
|
```
|
||||||
This is a first release from me, experiment and use with caution.
|
This is a first release from me, experiment and use with caution.
|
||||||
|
|
||||||
@@ -10397,7 +10552,7 @@ Added commands to support the new Device Management API.
|
|||||||
|
|
||||||
To use these commands you must update your service account authorization.
|
To use these commands you must update your service account authorization.
|
||||||
```
|
```
|
||||||
gam user user@domain.com check serviceaccount
|
gam user user@domain.com update serviceaccount
|
||||||
```
|
```
|
||||||
|
|
||||||
In the following places a Google Admin email address is required; by default the admin email address in `oauth2.txt` is used.
|
In the following places a Google Admin email address is required; by default the admin email address in `oauth2.txt` is used.
|
||||||
@@ -11387,7 +11542,7 @@ ID of the created Team Drive as output. This will be useful in scripts that crea
|
|||||||
want to perform subsequent GAM command on the Team Drive. This ID will only be valid when the return code
|
want to perform subsequent GAM command on the Team Drive. This ID will only be valid when the return code
|
||||||
of the command is 0; program accordingly.
|
of the command is 0; program accordingly.
|
||||||
```
|
```
|
||||||
Linux/MacOS
|
Linux/macOS
|
||||||
teamDriveId=`gam user user@domain.com create teamdrive ... returnidonly`
|
teamDriveId=`gam user user@domain.com create teamdrive ... returnidonly`
|
||||||
Windows PowerShell
|
Windows PowerShell
|
||||||
$teamDriveId = & gam user user@domain.com create teamdrive ... returnidonly`
|
$teamDriveId = & gam user user@domain.com create teamdrive ... returnidonly`
|
||||||
@@ -11479,7 +11634,7 @@ file ID of the created file as output. This will be useful in scripts that creat
|
|||||||
want to perform subsequent GAM command on the file. This file ID will only be valid when the return code
|
want to perform subsequent GAM command on the file. This file ID will only be valid when the return code
|
||||||
of the command is 0; program accordingly.
|
of the command is 0; program accordingly.
|
||||||
```
|
```
|
||||||
Linux/MacOS
|
Linux/macOS
|
||||||
fileId=`gam user user@domain.com create drivefile ... returnidonly`
|
fileId=`gam user user@domain.com create drivefile ... returnidonly`
|
||||||
Windows PowerShell
|
Windows PowerShell
|
||||||
$fileId = & gam user user@domain.com create drivefile ... returnidonly`
|
$fileId = & gam user user@domain.com create drivefile ... returnidonly`
|
||||||
@@ -15562,7 +15717,7 @@ gam print group-members [todrive [<ToDriveAttribute>]]
|
|||||||
|
|
||||||
4.55.44
|
4.55.44
|
||||||
|
|
||||||
Improve MacOS version of GAM's use of OpenSSL 1.0.2n.
|
Improve macOS version of GAM's use of OpenSSL 1.0.2n.
|
||||||
Recode pyinstaller .spec files.
|
Recode pyinstaller .spec files.
|
||||||
|
|
||||||
4.55.43
|
4.55.43
|
||||||
@@ -15589,7 +15744,7 @@ Fixed bug that made some gam print commands throw an exception.
|
|||||||
|
|
||||||
4.55.40
|
4.55.40
|
||||||
|
|
||||||
Update MacOS version of GAM to use OpenSSL 1.0.2n.
|
Update macOS version of GAM to use OpenSSL 1.0.2n.
|
||||||
|
|
||||||
4.55.39
|
4.55.39
|
||||||
|
|
||||||
@@ -18415,7 +18570,7 @@ Changed gam info user formatjson to show licenses in SKU ID (SKU Display Name) f
|
|||||||
4.42.00
|
4.42.00
|
||||||
|
|
||||||
Fixed problem where control-C was not recognized when multiple processes were running via gam batch/csv.
|
Fixed problem where control-C was not recognized when multiple processes were running via gam batch/csv.
|
||||||
Gam terminates cleanly on Linux/MacOS when you hit control-C in this situation; on Windows exceptions are
|
Gam terminates cleanly on Linux/macOS when you hit control-C in this situation; on Windows exceptions are
|
||||||
thrown but Gam does terminate.
|
thrown but Gam does terminate.
|
||||||
|
|
||||||
4.41.08
|
4.41.08
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ OPTIONS:
|
|||||||
-d Directory where gam folder will be installed. Default is \$HOME/bin/
|
-d Directory where gam folder will be installed. Default is \$HOME/bin/
|
||||||
-a Architecture to install (x86_64, arm64). Default is to detect your arch with "uname -m".
|
-a Architecture to install (x86_64, arm64). Default is to detect your arch with "uname -m".
|
||||||
-o OS we are running (linux, macos). Default is to detect your OS with "uname -s".
|
-o OS we are running (linux, macos). Default is to detect your OS with "uname -s".
|
||||||
-b OS version. Default is to detect on MacOS and Linux.
|
-b OS version. Default is to detect on macOS and Linux.
|
||||||
-l Just upgrade GAM to latest version. Skips project creation and auth.
|
-l Just upgrade GAM to latest version. Skips project creation and auth.
|
||||||
-p Profile update (true, false). Should script add gam command to environment. Default is true.
|
-p Profile update (true, false). Should script add gam command to environment. Default is true.
|
||||||
-u Admin user email address to use with GAM. Default is to prompt.
|
-u Admin user email address to use with GAM. Default is to prompt.
|
||||||
@@ -247,7 +247,7 @@ case $gamos in
|
|||||||
archgrep="-arm64\|-aarch64"
|
archgrep="-arm64\|-aarch64"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo_red "ERROR: this installer currently only supports x86_64 and arm64 MacOS. Looks like you're running on ${gamarch}. Exiting."
|
echo_red "ERROR: this installer currently only supports x86_64 and arm64 macOS. Looks like you're running on ${gamarch}. Exiting."
|
||||||
exit
|
exit
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@@ -256,19 +256,19 @@ case $gamos in
|
|||||||
versionless_urls=$(echo -e "$gam_macos_urls" | \
|
versionless_urls=$(echo -e "$gam_macos_urls" | \
|
||||||
grep -e "-macos-")
|
grep -e "-macos-")
|
||||||
if [ "$versionless_urls" == "" ]; then
|
if [ "$versionless_urls" == "" ]; then
|
||||||
# versions after 7.00.38 include MacOS version info
|
# versions after 7.00.38 include macOS version info
|
||||||
gam_macos_vers=$(echo -e "$gam_macos_urls" | \
|
gam_macos_vers=$(echo -e "$gam_macos_urls" | \
|
||||||
grep --only-matching -e '-macos[0-9\.]*' | \
|
grep --only-matching -e '-macos[0-9\.]*' | \
|
||||||
cut -c 7-10)
|
cut -c 7-10)
|
||||||
for gam_mac_ver in $gam_macos_vers; do
|
for gam_mac_ver in $gam_macos_vers; do
|
||||||
if version_gt $currentversion $gam_mac_ver; then
|
if version_gt $currentversion $gam_mac_ver; then
|
||||||
download_url=$(echo -e "$gam_macos_urls" | grep "$gam_mac_ver")
|
download_url=$(echo -e "$gam_macos_urls" | grep "$gam_mac_ver")
|
||||||
echo_green "You are running MacOS ${currentversion} Using GAM compiled against ${gam_mac_ver}"
|
echo_green "You are running macOS ${currentversion} Using GAM compiled against ${gam_mac_ver}"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
if [ -z ${download_url+x} ]; then
|
if [ -z ${download_url+x} ]; then
|
||||||
echo_red "Sorry, you are running MacOS ${osversion} but GAM on ${gamarch} requires MacOS ${gam_mac_ver} or newer. Exiting."
|
echo_red "Sorry, you are running macOS ${osversion} but GAM on ${gamarch} requires macOS ${gam_mac_ver} or newer. Exiting."
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
@@ -283,13 +283,13 @@ case $gamos in
|
|||||||
esac
|
esac
|
||||||
download_url=$(echo -e "$download_urls" | grep -e $archgrep)
|
download_url=$(echo -e "$download_urls" | grep -e $archgrep)
|
||||||
if version_gt "$osversion" "$minimum_version"; then
|
if version_gt "$osversion" "$minimum_version"; then
|
||||||
echo_green "You are running MacOS ${osversion}, good. Downloading GAM from ${download_url}."
|
echo_green "You are running macOS ${osversion}, good. Downloading GAM from ${download_url}."
|
||||||
else
|
else
|
||||||
echo_red "Sorry, you are running MacOS ${osversion} but GAM on ${gamarch} requires MacOS ${minimum_version}. Exiting."
|
echo_red "Sorry, you are running macOS ${osversion} but GAM on ${gamarch} requires macOS ${minimum_version}. Exiting."
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
if [ -z ${download_url+x} ]; then
|
if [ -z ${download_url+x} ]; then
|
||||||
echo_red "Sorry, you are running MacOS ${currentversion} but GAM on ${gamarch} requires MacOS ${minimum_version}. Exiting."
|
echo_red "Sorry, you are running macOS ${currentversion} but GAM on ${gamarch} requires macOS ${minimum_version}. Exiting."
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -302,7 +302,7 @@ case $gamos in
|
|||||||
grep ".zip")
|
grep ".zip")
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo_red "Sorry, this installer currently only supports Linux and MacOS. Looks like you're running on ${gamos}. Exiting."
|
echo_red "Sorry, this installer currently only supports Linux and macOS. Looks like you're running on ${gamos}. Exiting."
|
||||||
exit
|
exit
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@@ -368,18 +368,15 @@ if [ "$upgrade_only" = true ]; then
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Set config command
|
|
||||||
#config_cmd="config no_browser false"
|
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
read -p "Can you run a full browser on this machine? (usually Y for MacOS, N for Linux if you SSH into this machine) " yn
|
read -p "Can you run a full browser on this machine? (usually Y for macOS, N for Linux if you SSH into this machine) " yn
|
||||||
case $yn in
|
case $yn in
|
||||||
[Yy]*)
|
[Yy]*)
|
||||||
|
"$target_gam" config no_browser false save
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
[Nn]*)
|
[Nn]*)
|
||||||
# config_cmd="config no_browser true"
|
"$target_gam" config no_browser true save
|
||||||
touch "$target_folder/nobrowser.txt" > /dev/null 2>&1
|
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
@@ -397,7 +394,6 @@ while true; do
|
|||||||
if [ "$adminuser" == "" ]; then
|
if [ "$adminuser" == "" ]; then
|
||||||
read -p "Please enter your Google Workspace admin email address: " adminuser
|
read -p "Please enter your Google Workspace admin email address: " adminuser
|
||||||
fi
|
fi
|
||||||
# "$target_gam" $config_cmd create project $adminuser
|
|
||||||
"$target_gam" create project $adminuser
|
"$target_gam" create project $adminuser
|
||||||
rc=$?
|
rc=$?
|
||||||
if (( $rc == 0 )); then
|
if (( $rc == 0 )); then
|
||||||
@@ -423,7 +419,6 @@ 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
|
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
|
case $yn in
|
||||||
[Yy]*)
|
[Yy]*)
|
||||||
# "$target_gam" $config_cmd oauth create $adminuser
|
|
||||||
"$target_gam" oauth create $adminuser
|
"$target_gam" oauth create $adminuser
|
||||||
rc=$?
|
rc=$?
|
||||||
if (( $rc == 0 )); then
|
if (( $rc == 0 )); then
|
||||||
@@ -453,7 +448,6 @@ while $admin_authorized; do
|
|||||||
read -p "Please enter the email address of a regular Google Workspace user: " regularuser
|
read -p "Please enter the email address of a regular Google Workspace user: " regularuser
|
||||||
fi
|
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."
|
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_gam" $config_cmd user $regularuser check serviceaccount
|
|
||||||
"$target_gam" user $regularuser check serviceaccount
|
"$target_gam" user $regularuser check serviceaccount
|
||||||
rc=$?
|
rc=$?
|
||||||
if (( $rc == 0 )); then
|
if (( $rc == 0 )); then
|
||||||
@@ -475,7 +469,6 @@ while $admin_authorized; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
echo_green "Here's information about your new GAM installation:"
|
echo_green "Here's information about your new GAM installation:"
|
||||||
#"$target_gam" $config_cmd save version extended
|
|
||||||
"$target_gam" version extended
|
"$target_gam" version extended
|
||||||
rc=$?
|
rc=$?
|
||||||
if (( $rc != 0 )); then
|
if (( $rc != 0 )); then
|
||||||
|
|||||||
116
src/gam.iss
Normal file
116
src/gam.iss
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
; --- 1. PREPROCESSOR DEFINITIONS ---
|
||||||
|
#define AppVersion GetEnv("GAMVERSION")
|
||||||
|
#if AppVersion == ""
|
||||||
|
#define AppVersion "7.0.0"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
; Pull architecture directly from GitHub Actions environment variable
|
||||||
|
#define RunnerArch GetEnv("RUNNER_ARCH")
|
||||||
|
|
||||||
|
[Setup]
|
||||||
|
; --- 2. CORE APPLICATION INFO ---
|
||||||
|
AppId={{D86B52B2-EFE9-4F9D-8BA3-9D84B9B2D319}
|
||||||
|
AppName=GAM7
|
||||||
|
AppVersion={#AppVersion}
|
||||||
|
AppPublisher=GAM Team - google-apps-manager@googlegroups.com
|
||||||
|
DefaultDirName={sd}\GAM7
|
||||||
|
LicenseFile=dist\gam\gam7\LICENSE
|
||||||
|
PrivilegesRequired=admin
|
||||||
|
ChangesEnvironment=yes
|
||||||
|
|
||||||
|
; Tell Inno Setup to use a custom signtool defined via the command line
|
||||||
|
SignTool=gamsigntool
|
||||||
|
|
||||||
|
; --- 3. COMPRESSION & OPTIMIZATION ---
|
||||||
|
Compression=lzma2/ultra64
|
||||||
|
SolidCompression=yes
|
||||||
|
|
||||||
|
; --- 4. DYNAMIC ARCHITECTURE CONFIGURATION ---
|
||||||
|
; GitHub Actions RUNNER_ARCH is typically uppercase "ARM64" or "X64"
|
||||||
|
#if RunnerArch == "ARM64" || RunnerArch == "arm64"
|
||||||
|
ArchitecturesAllowed=arm64
|
||||||
|
ArchitecturesInstallIn64BitMode=arm64
|
||||||
|
OutputBaseFilename=gam-{#AppVersion}-windows-arm64
|
||||||
|
#else
|
||||||
|
ArchitecturesAllowed=x64compatible
|
||||||
|
ArchitecturesInstallIn64BitMode=x64compatible
|
||||||
|
OutputBaseFilename=gam-{#AppVersion}-windows-x86_64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
[Messages]
|
||||||
|
; Custom error if an admin tries to run the ARM64 installer on an Intel machine
|
||||||
|
#if RunnerArch == "ARM64" || RunnerArch == "arm64"
|
||||||
|
WindowsVersionNotSupported=You downloaded the ARM64 version of GAM, but this computer has an Intel or AMD processor.%n%nPlease go back to the release page and download the x86_64 installer instead.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
[Files]
|
||||||
|
; --- 5. DYNAMIC FILE INCLUSION ---
|
||||||
|
Source: "dist\gam\gam7\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||||
|
|
||||||
|
[Registry]
|
||||||
|
; --- 6. PATH ENVIRONMENT VARIABLE ---
|
||||||
|
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; \
|
||||||
|
ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};{app}"; \
|
||||||
|
Check: NeedsAddPath(ExpandConstant('{app}'))
|
||||||
|
|
||||||
|
[Code]
|
||||||
|
const
|
||||||
|
ERROR_SUCCESS = 0;
|
||||||
|
|
||||||
|
function MsiEnumRelatedProducts(lpUpgradeCode: string; dwReserved: Integer; iProductIndex: Integer; lpProductBuf: string): Integer;
|
||||||
|
external 'MsiEnumRelatedProductsW@msi.dll stdcall';
|
||||||
|
|
||||||
|
function UninstallWixMSI(): Boolean;
|
||||||
|
var
|
||||||
|
UpgradeCode: string;
|
||||||
|
ProductCode: string;
|
||||||
|
ResultCode: Integer;
|
||||||
|
begin
|
||||||
|
UpgradeCode := '{D86B52B2-EFE9-4F9D-8BA3-9D84B9B2D319}';
|
||||||
|
ProductCode := StringOfChar(' ', 39);
|
||||||
|
|
||||||
|
ResultCode := MsiEnumRelatedProducts(UpgradeCode, 0, 0, ProductCode);
|
||||||
|
|
||||||
|
if ResultCode = ERROR_SUCCESS then
|
||||||
|
begin
|
||||||
|
ProductCode := Trim(ProductCode);
|
||||||
|
Exec('msiexec.exe', '/x ' + ProductCode + ' /qn /norestart', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function InitializeSetup(): Boolean;
|
||||||
|
begin
|
||||||
|
// --- Architecture Warning for Emulation ---
|
||||||
|
#if RunnerArch != "ARM64" && RunnerArch != "arm64"
|
||||||
|
if IsArm64() then
|
||||||
|
begin
|
||||||
|
if MsgBox('Notice: You are installing the Intel (x86_64) build of GAM on an ARM processor.' + #13#10#13#10 +
|
||||||
|
'While this will work via Windows emulation, it will perform worse than the native ARM64 version.' + #13#10#13#10 +
|
||||||
|
'Do you want to continue with the installation anyway?',
|
||||||
|
mbConfirmation, MB_YESNO) = idNo then
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
UninstallWixMSI();
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function NeedsAddPath(Param: string): boolean;
|
||||||
|
var
|
||||||
|
OrigPath: string;
|
||||||
|
begin
|
||||||
|
if not RegQueryStringValue(HKEY_LOCAL_MACHINE,
|
||||||
|
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
|
||||||
|
'Path', OrigPath)
|
||||||
|
then begin
|
||||||
|
Result := True;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
Result := Pos(';' + Param + ';', ';' + OrigPath + ';') = 0;
|
||||||
|
end;
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
Manufacturer="GAM Team - google-apps-manager@googlegroups.com"
|
Manufacturer="GAM Team - google-apps-manager@googlegroups.com"
|
||||||
UpgradeCode="D86B52B2-EFE9-4F9D-8BA3-9D84B9B2D319">
|
UpgradeCode="D86B52B2-EFE9-4F9D-8BA3-9D84B9B2D319">
|
||||||
<Package
|
<Package
|
||||||
InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
|
InstallerVersion="500" Compressed="yes" InstallScope="perMachine" />
|
||||||
|
|
||||||
<MajorUpgrade
|
<MajorUpgrade
|
||||||
DowngradeErrorMessage=
|
DowngradeErrorMessage=
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,72 @@
|
|||||||
|
#
|
||||||
|
# This is a custom certificate authority bundle for GAM
|
||||||
|
# It's composed of Let's Encrypt Root CAs and Google's
|
||||||
|
# certificate bundle. This should be the minimal list of
|
||||||
|
# CAs required to talk to Google and Github.
|
||||||
|
|
||||||
|
# Operating CA: Let's Encrypt
|
||||||
|
# Issuer: C = US, O = Internet Security Research Group, CN = ISRG Root X1
|
||||||
|
# Subject: C = US, O = Internet Security Research Group, CN = ISRG Root X1
|
||||||
|
# Label: "ISRG Root X1"
|
||||||
|
# Serial: 172886928669790476064670243504169061120
|
||||||
|
# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e
|
||||||
|
# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8
|
||||||
|
# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
|
||||||
|
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
|
||||||
|
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
|
||||||
|
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
|
||||||
|
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
|
||||||
|
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
|
||||||
|
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
|
||||||
|
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
|
||||||
|
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
|
||||||
|
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
|
||||||
|
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
|
||||||
|
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
|
||||||
|
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
|
||||||
|
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
|
||||||
|
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
|
||||||
|
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
|
||||||
|
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
|
||||||
|
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
|
||||||
|
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
|
||||||
|
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
|
||||||
|
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
|
||||||
|
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
|
||||||
|
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
|
||||||
|
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
|
||||||
|
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
|
||||||
|
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
|
||||||
|
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
|
||||||
|
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
|
||||||
|
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
# Operating CA: Let's Encrypt
|
||||||
|
# Issuer: C = US, O = Internet Security Research Group, CN = ISRG Root X2
|
||||||
|
# Subject: C = US, O = Internet Security Research Group, CN = ISRG Root X2
|
||||||
|
# Label: "ISRG Root X2"
|
||||||
|
# Serial: 87493402998870891108772069816698636114
|
||||||
|
# MD5 Fingerprint: d3:9e:c4:1e:23:3c:a6:df:cf:a3:7e:6d:e0:14:e6:e5
|
||||||
|
# SHA1 Fingerprint: bd:b1:b9:3c:d5:97:8d:45:c6:26:14:55:f8:db:95:c7:5a:d1:53:af
|
||||||
|
# SHA256 Fingerprint: 69:72:9b:8e:15:a8:6e:fc:17:7a:57:af:b7:17:1d:fc:64:ad:d2:8c:2f:ca:8c:f1:50:7e:34:45:3c:cb:14:70
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw
|
||||||
|
CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
|
||||||
|
R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00
|
||||||
|
MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT
|
||||||
|
ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw
|
||||||
|
EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW
|
||||||
|
+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9
|
||||||
|
ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
|
||||||
|
AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI
|
||||||
|
zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW
|
||||||
|
tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1
|
||||||
|
/q4AaOeMSQ+2b1tbFfLn
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
# Operating CA: DigiCert
|
# Operating CA: DigiCert
|
||||||
# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
|
# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
|
||||||
# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
|
# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Copyright (C) 2024 Ross Scroggs All Rights Reserved.
|
# Copyright (C) 2026 Ross Scroggs All Rights Reserved.
|
||||||
#
|
#
|
||||||
# All Rights Reserved.
|
# All Rights Reserved.
|
||||||
#
|
#
|
||||||
@@ -107,6 +107,7 @@ class GamAction():
|
|||||||
SAVE = 'save'
|
SAVE = 'save'
|
||||||
SEND = 'send'
|
SEND = 'send'
|
||||||
SENDEMAIL = 'snem'
|
SENDEMAIL = 'snem'
|
||||||
|
SENDREPLY = 'sner'
|
||||||
SET = 'set '
|
SET = 'set '
|
||||||
SETUP = 'setu'
|
SETUP = 'setu'
|
||||||
SHARE = 'shar'
|
SHARE = 'shar'
|
||||||
@@ -225,6 +226,7 @@ class GamAction():
|
|||||||
SAVE: ['Saved', 'Save'],
|
SAVE: ['Saved', 'Save'],
|
||||||
SEND: ['Sent', 'Send'],
|
SEND: ['Sent', 'Send'],
|
||||||
SENDEMAIL: ['Email Sent', 'Send Email'],
|
SENDEMAIL: ['Email Sent', 'Send Email'],
|
||||||
|
SENDREPLY: ['Reply Sent', 'Send Reply'],
|
||||||
SET: ['Set', 'Set'],
|
SET: ['Set', 'Set'],
|
||||||
SETUP: ['Set Up', 'Set Up'],
|
SETUP: ['Set Up', 'Set Up'],
|
||||||
SHARE: ['Shared', 'Share'],
|
SHARE: ['Shared', 'Share'],
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ CLOUDIDENTITY_POLICY = 'cloudidentitypolicy'
|
|||||||
CLOUDIDENTITY_POLICY_BETA = 'cloudidentitypolicybeta'
|
CLOUDIDENTITY_POLICY_BETA = 'cloudidentitypolicybeta'
|
||||||
CLOUDIDENTITY_USERINVITATIONS = 'cloudidentityuserinvitations'
|
CLOUDIDENTITY_USERINVITATIONS = 'cloudidentityuserinvitations'
|
||||||
CLOUDRESOURCEMANAGER = 'cloudresourcemanager'
|
CLOUDRESOURCEMANAGER = 'cloudresourcemanager'
|
||||||
|
CLOUDRESOURCEMANAGERV1 = 'cloudresourcemanagerv1'
|
||||||
CONTACTS = 'contacts'
|
CONTACTS = 'contacts'
|
||||||
CONTACTDELEGATION = 'contactdelegation'
|
CONTACTDELEGATION = 'contactdelegation'
|
||||||
DATATRANSFER = 'datatransfer'
|
DATATRANSFER = 'datatransfer'
|
||||||
@@ -103,7 +104,6 @@ TASKS = 'tasks'
|
|||||||
VAULT = 'vault'
|
VAULT = 'vault'
|
||||||
YOUTUBE = 'youtube'
|
YOUTUBE = 'youtube'
|
||||||
#
|
#
|
||||||
BUSINESSACCOUNTMANAGEMENT_SCOPE = 'https://www.googleapis.com/auth/business.manage'
|
|
||||||
CHROMEVERSIONHISTORY_URL = 'https://versionhistory.googleapis.com/v1/chrome/platforms'
|
CHROMEVERSIONHISTORY_URL = 'https://versionhistory.googleapis.com/v1/chrome/platforms'
|
||||||
DRIVE_SCOPE = 'https://www.googleapis.com/auth/drive'
|
DRIVE_SCOPE = 'https://www.googleapis.com/auth/drive'
|
||||||
DRIVE_FILE_SCOPE = 'https://www.googleapis.com/auth/drive.file'
|
DRIVE_FILE_SCOPE = 'https://www.googleapis.com/auth/drive.file'
|
||||||
@@ -119,7 +119,6 @@ STORAGE_READONLY_SCOPE = 'https://www.googleapis.com/auth/devstorage.read_only'
|
|||||||
STORAGE_READWRITE_SCOPE = 'https://www.googleapis.com/auth/devstorage.read_write'
|
STORAGE_READWRITE_SCOPE = 'https://www.googleapis.com/auth/devstorage.read_write'
|
||||||
USERINFO_EMAIL_SCOPE = 'https://www.googleapis.com/auth/userinfo.email' # email
|
USERINFO_EMAIL_SCOPE = 'https://www.googleapis.com/auth/userinfo.email' # email
|
||||||
USERINFO_PROFILE_SCOPE = 'https://www.googleapis.com/auth/userinfo.profile' # profile
|
USERINFO_PROFILE_SCOPE = 'https://www.googleapis.com/auth/userinfo.profile' # profile
|
||||||
VAULT_SCOPES = ['https://www.googleapis.com/auth/ediscovery', 'https://www.googleapis.com/auth/ediscovery.readonly']
|
|
||||||
REQUIRED_SCOPES = [USERINFO_EMAIL_SCOPE, USERINFO_PROFILE_SCOPE]
|
REQUIRED_SCOPES = [USERINFO_EMAIL_SCOPE, USERINFO_PROFILE_SCOPE]
|
||||||
REQUIRED_SCOPES_SET = set(REQUIRED_SCOPES)
|
REQUIRED_SCOPES_SET = set(REQUIRED_SCOPES)
|
||||||
NUM_CLIENT_SCOPES_ERROR_LIMIT = 48
|
NUM_CLIENT_SCOPES_ERROR_LIMIT = 48
|
||||||
@@ -138,6 +137,21 @@ SCOPELESS_APIS = {
|
|||||||
SERVICEACCOUNTLOOKUP,
|
SERVICEACCOUNTLOOKUP,
|
||||||
}
|
}
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# Scopes not in the discovery doc that are still valid for the API.
|
||||||
|
EXTRA_SCOPES = {
|
||||||
|
BUSINESSACCOUNTMANAGEMENT: ['https://www.googleapis.com/auth/business.manage'],
|
||||||
|
CLOUDRESOURCEMANAGER: ['https://www.googleapis.com/auth/cloudplatformfolders',
|
||||||
|
'https://www.googleapis.com/auth/cloudplatformfolders.readonly',
|
||||||
|
'https://www.googleapis.com/auth/cloudplatformprojects',
|
||||||
|
'https://www.googleapis.com/auth/cloudplatformprojects.readonly',
|
||||||
|
'https://www.googleapis.com/auth/cloudplatformorganizations',
|
||||||
|
'https://www.googleapis.com/auth/cloudplatformorganizations.readonly',
|
||||||
|
],
|
||||||
|
VAULT: ['https://www.googleapis.com/auth/ediscovery', 'https://www.googleapis.com/auth/ediscovery.readonly'],
|
||||||
|
}
|
||||||
|
EXTRA_SCOPES[CLOUDRESOURCEMANAGERV1] = EXTRA_SCOPES[CLOUDRESOURCEMANAGER]
|
||||||
|
|
||||||
APIS_NEEDING_ACCESS_TOKEN = {
|
APIS_NEEDING_ACCESS_TOKEN = {
|
||||||
CBCM: ['https://www.googleapis.com/auth/admin.directory.device.chromebrowsers']
|
CBCM: ['https://www.googleapis.com/auth/admin.directory.device.chromebrowsers']
|
||||||
}
|
}
|
||||||
@@ -250,7 +264,8 @@ _INFO = {
|
|||||||
CLOUDIDENTITY_POLICY: {'name': 'Cloud Identity API - Policy', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
|
CLOUDIDENTITY_POLICY: {'name': 'Cloud Identity API - Policy', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
|
||||||
CLOUDIDENTITY_POLICY_BETA: {'name': 'Cloud Identity API - Policy Beta', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
|
CLOUDIDENTITY_POLICY_BETA: {'name': 'Cloud Identity API - Policy Beta', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
|
||||||
CLOUDIDENTITY_USERINVITATIONS: {'name': 'Cloud Identity API - User Invitations', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
|
CLOUDIDENTITY_USERINVITATIONS: {'name': 'Cloud Identity API - User Invitations', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
|
||||||
CLOUDRESOURCEMANAGER: {'name': 'Cloud Resource Manager API v3', 'version': 'v3', 'v2discovery': True},
|
CLOUDRESOURCEMANAGER: {'name': 'Resource Manager API v3', 'version': 'v3', 'v2discovery': True},
|
||||||
|
CLOUDRESOURCEMANAGERV1: {'name': 'Resource Manager API v1', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudresourcemanager'},
|
||||||
CONTACTS: {'name': 'Contacts API', 'version': 'v3', 'v2discovery': False},
|
CONTACTS: {'name': 'Contacts API', 'version': 'v3', 'v2discovery': False},
|
||||||
CONTACTDELEGATION: {'name': 'Contact Delegation API', 'version': 'v1', 'v2discovery': True, 'localjson': True},
|
CONTACTDELEGATION: {'name': 'Contact Delegation API', 'version': 'v1', 'v2discovery': True, 'localjson': True},
|
||||||
DATATRANSFER: {'name': 'Data Transfer API', 'version': 'datatransfer_v1', 'v2discovery': True, 'mappedAPI': 'admin'},
|
DATATRANSFER: {'name': 'Data Transfer API', 'version': 'datatransfer_v1', 'v2discovery': True, 'mappedAPI': 'admin'},
|
||||||
@@ -305,9 +320,8 @@ READONLY = ['readonly',]
|
|||||||
_CLIENT_SCOPES = [
|
_CLIENT_SCOPES = [
|
||||||
{'name': 'Business Account Management API',
|
{'name': 'Business Account Management API',
|
||||||
'api': BUSINESSACCOUNTMANAGEMENT,
|
'api': BUSINESSACCOUNTMANAGEMENT,
|
||||||
'subscopes': [],
|
|
||||||
'offByDefault': True,
|
'offByDefault': True,
|
||||||
'scope': BUSINESSACCOUNTMANAGEMENT_SCOPE},
|
'scope': EXTRA_SCOPES[BUSINESSACCOUNTMANAGEMENT]},
|
||||||
{'name': 'Calendar API',
|
{'name': 'Calendar API',
|
||||||
'api': CALENDAR,
|
'api': CALENDAR,
|
||||||
'subscopes': READONLY,
|
'subscopes': READONLY,
|
||||||
@@ -316,21 +330,18 @@ _CLIENT_SCOPES = [
|
|||||||
'api': CBCM,
|
'api': CBCM,
|
||||||
'subscopes': READONLY,
|
'subscopes': READONLY,
|
||||||
'scope': 'https://www.googleapis.com/auth/admin.directory.device.chromebrowsers'},
|
'scope': 'https://www.googleapis.com/auth/admin.directory.device.chromebrowsers'},
|
||||||
{'name': 'Chrome Management API - read only',
|
{'name': 'Chrome Management API - readonly',
|
||||||
'api': CHROMEMANAGEMENT,
|
'api': CHROMEMANAGEMENT,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/chrome.management.reports.readonly'},
|
'scope': 'https://www.googleapis.com/auth/chrome.management.reports.readonly'},
|
||||||
{'name': 'Chrome Management API - AppDetails read only',
|
{'name': 'Chrome Management API - AppDetails readonly',
|
||||||
'api': CHROMEMANAGEMENT_APPDETAILS,
|
'api': CHROMEMANAGEMENT_APPDETAILS,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/chrome.management.appdetails.readonly'},
|
'scope': 'https://www.googleapis.com/auth/chrome.management.appdetails.readonly'},
|
||||||
{'name': 'Chrome Management API - Profiles',
|
{'name': 'Chrome Management API - Profiles',
|
||||||
'api': CHROMEMANAGEMENT_CHROMEPROFILES,
|
'api': CHROMEMANAGEMENT_CHROMEPROFILES,
|
||||||
'subscopes': READONLY,
|
'subscopes': READONLY,
|
||||||
'scope': 'https://www.googleapis.com/auth/chrome.management.profiles'},
|
'scope': 'https://www.googleapis.com/auth/chrome.management.profiles'},
|
||||||
{'name': 'Chrome Management API - Telemetry read only',
|
{'name': 'Chrome Management API - Telemetry readonly',
|
||||||
'api': CHROMEMANAGEMENT_TELEMETRY,
|
'api': CHROMEMANAGEMENT_TELEMETRY,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/chrome.management.telemetry.readonly'},
|
'scope': 'https://www.googleapis.com/auth/chrome.management.telemetry.readonly'},
|
||||||
{'name': 'Chrome Policy API',
|
{'name': 'Chrome Policy API',
|
||||||
'api': CHROMEPOLICY,
|
'api': CHROMEPOLICY,
|
||||||
@@ -342,7 +353,6 @@ _CLIENT_SCOPES = [
|
|||||||
'scope': 'https://www.googleapis.com/auth/admin.chrome.printers'},
|
'scope': 'https://www.googleapis.com/auth/admin.chrome.printers'},
|
||||||
{'name': 'Chrome Version History API',
|
{'name': 'Chrome Version History API',
|
||||||
'api': CHROMEVERSIONHISTORY,
|
'api': CHROMEVERSIONHISTORY,
|
||||||
'subscopes': [],
|
|
||||||
'scope': ''},
|
'scope': ''},
|
||||||
{'name': 'Classroom API - Courses',
|
{'name': 'Classroom API - Courses',
|
||||||
'api': CLASSROOM,
|
'api': CLASSROOM,
|
||||||
@@ -370,11 +380,9 @@ _CLIENT_SCOPES = [
|
|||||||
'scope': 'https://www.googleapis.com/auth/classroom.guardianlinks.students'},
|
'scope': 'https://www.googleapis.com/auth/classroom.guardianlinks.students'},
|
||||||
{'name': 'Classroom API - Profile Emails',
|
{'name': 'Classroom API - Profile Emails',
|
||||||
'api': CLASSROOM,
|
'api': CLASSROOM,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/classroom.profile.emails'},
|
'scope': 'https://www.googleapis.com/auth/classroom.profile.emails'},
|
||||||
{'name': 'Classroom API - Profile Photos',
|
{'name': 'Classroom API - Profile Photos',
|
||||||
'api': CLASSROOM,
|
'api': CLASSROOM,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/classroom.profile.photos'},
|
'scope': 'https://www.googleapis.com/auth/classroom.profile.photos'},
|
||||||
{'name': 'Classroom API - Rosters',
|
{'name': 'Classroom API - Rosters',
|
||||||
'api': CLASSROOM,
|
'api': CLASSROOM,
|
||||||
@@ -404,7 +412,6 @@ _CLIENT_SCOPES = [
|
|||||||
'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'},
|
'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'},
|
||||||
{'name': 'Cloud Identity API - Policy Beta',
|
{'name': 'Cloud Identity API - Policy Beta',
|
||||||
'api': CLOUDIDENTITY_POLICY_BETA,
|
'api': CLOUDIDENTITY_POLICY_BETA,
|
||||||
'subscopes': [],
|
|
||||||
'offByDefault': True,
|
'offByDefault': True,
|
||||||
'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'},
|
'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'},
|
||||||
{'name': 'Cloud Identity API - User Invitations',
|
{'name': 'Cloud Identity API - User Invitations',
|
||||||
@@ -413,17 +420,14 @@ _CLIENT_SCOPES = [
|
|||||||
'scope': 'https://www.googleapis.com/auth/cloud-identity.userinvitations'},
|
'scope': 'https://www.googleapis.com/auth/cloud-identity.userinvitations'},
|
||||||
{'name': 'Cloud Storage API (Read Only, Vault/Takeout Download, Cloud Storage)',
|
{'name': 'Cloud Storage API (Read Only, Vault/Takeout Download, Cloud Storage)',
|
||||||
'api': STORAGEREAD,
|
'api': STORAGEREAD,
|
||||||
'subscopes': [],
|
|
||||||
'offByDefault': True,
|
'offByDefault': True,
|
||||||
'scope': STORAGE_READONLY_SCOPE},
|
'scope': STORAGE_READONLY_SCOPE},
|
||||||
{'name': 'Cloud Storage API (Read/Write, Vault/Takeout Copy/Download, Cloud Storage)',
|
{'name': 'Cloud Storage API (Read/Write, Vault/Takeout Copy/Download, Cloud Storage)',
|
||||||
'api': STORAGEWRITE,
|
'api': STORAGEWRITE,
|
||||||
'subscopes': [],
|
|
||||||
'offByDefault': True,
|
'offByDefault': True,
|
||||||
'scope': STORAGE_READWRITE_SCOPE},
|
'scope': STORAGE_READWRITE_SCOPE},
|
||||||
{'name': 'Contacts API - Domain Shared Contacts',
|
{'name': 'Contacts API - Domain Shared Contacts',
|
||||||
'api': CONTACTS,
|
'api': CONTACTS,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.google.com/m8/feeds'},
|
'scope': 'https://www.google.com/m8/feeds'},
|
||||||
{'name': 'Contact Delegation API',
|
{'name': 'Contact Delegation API',
|
||||||
'api': CONTACTDELEGATION,
|
'api': CONTACTDELEGATION,
|
||||||
@@ -451,7 +455,7 @@ _CLIENT_SCOPES = [
|
|||||||
'scope': 'https://www.googleapis.com/auth/admin.directory.group'},
|
'scope': 'https://www.googleapis.com/auth/admin.directory.group'},
|
||||||
{'name': 'Directory API - Mobile Devices Directory',
|
{'name': 'Directory API - Mobile Devices Directory',
|
||||||
'api': DIRECTORY,
|
'api': DIRECTORY,
|
||||||
'subscopes': ['readonly', 'action'],
|
'subscopes': ['readonly', 'actiononly'],
|
||||||
'scope': 'https://www.googleapis.com/auth/admin.directory.device.mobile'},
|
'scope': 'https://www.googleapis.com/auth/admin.directory.device.mobile'},
|
||||||
{'name': 'Directory API - Organizational Units',
|
{'name': 'Directory API - Organizational Units',
|
||||||
'api': DIRECTORY,
|
'api': DIRECTORY,
|
||||||
@@ -471,7 +475,6 @@ _CLIENT_SCOPES = [
|
|||||||
'scope': 'https://www.googleapis.com/auth/admin.directory.userschema'},
|
'scope': 'https://www.googleapis.com/auth/admin.directory.userschema'},
|
||||||
{'name': 'Directory API - User Security',
|
{'name': 'Directory API - User Security',
|
||||||
'api': DIRECTORY,
|
'api': DIRECTORY,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/admin.directory.user.security'},
|
'scope': 'https://www.googleapis.com/auth/admin.directory.user.security'},
|
||||||
{'name': 'Directory API - Users',
|
{'name': 'Directory API - Users',
|
||||||
'api': DIRECTORY,
|
'api': DIRECTORY,
|
||||||
@@ -479,24 +482,19 @@ _CLIENT_SCOPES = [
|
|||||||
'scope': 'https://www.googleapis.com/auth/admin.directory.user'},
|
'scope': 'https://www.googleapis.com/auth/admin.directory.user'},
|
||||||
{'name': 'Email Audit API',
|
{'name': 'Email Audit API',
|
||||||
'api': EMAIL_AUDIT,
|
'api': EMAIL_AUDIT,
|
||||||
'subscopes': [],
|
|
||||||
'offByDefault': True,
|
'offByDefault': True,
|
||||||
'scope': 'https://apps-apis.google.com/a/feeds/compliance/audit/'},
|
'scope': 'https://apps-apis.google.com/a/feeds/compliance/audit/'},
|
||||||
{'name': 'Groups Migration API',
|
{'name': 'Groups Migration API',
|
||||||
'api': GROUPSMIGRATION,
|
'api': GROUPSMIGRATION,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/apps.groups.migration'},
|
'scope': 'https://www.googleapis.com/auth/apps.groups.migration'},
|
||||||
{'name': 'Groups Settings API',
|
{'name': 'Groups Settings API',
|
||||||
'api': GROUPSSETTINGS,
|
'api': GROUPSSETTINGS,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/apps.groups.settings'},
|
'scope': 'https://www.googleapis.com/auth/apps.groups.settings'},
|
||||||
{'name': 'License Manager API',
|
{'name': 'License Manager API',
|
||||||
'api': LICENSING,
|
'api': LICENSING,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/apps.licensing'},
|
'scope': 'https://www.googleapis.com/auth/apps.licensing'},
|
||||||
{'name': 'People Directory API - read only',
|
{'name': 'People Directory API - readonly',
|
||||||
'api': PEOPLE_DIRECTORY,
|
'api': PEOPLE_DIRECTORY,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/directory.readonly'},
|
'scope': 'https://www.googleapis.com/auth/directory.readonly'},
|
||||||
{'name': 'People API',
|
{'name': 'People API',
|
||||||
'api': PEOPLE,
|
'api': PEOPLE,
|
||||||
@@ -504,29 +502,31 @@ _CLIENT_SCOPES = [
|
|||||||
'scope': PEOPLE_SCOPE},
|
'scope': PEOPLE_SCOPE},
|
||||||
{'name': 'Pub / Sub API',
|
{'name': 'Pub / Sub API',
|
||||||
'api': PUBSUB,
|
'api': PUBSUB,
|
||||||
'subscopes': [],
|
|
||||||
'offByDefault': True,
|
'offByDefault': True,
|
||||||
'scope': 'https://www.googleapis.com/auth/pubsub'},
|
'scope': 'https://www.googleapis.com/auth/pubsub'},
|
||||||
{'name': 'Reports API - Audit Reports',
|
{'name': 'Reports API - Audit Reports readonly',
|
||||||
'api': REPORTS,
|
'api': REPORTS,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/admin.reports.audit.readonly'},
|
'scope': 'https://www.googleapis.com/auth/admin.reports.audit.readonly'},
|
||||||
{'name': 'Reports API - Usage Reports',
|
{'name': 'Reports API - Usage Reports readonly',
|
||||||
'api': REPORTS,
|
'api': REPORTS,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/admin.reports.usage.readonly'},
|
'scope': 'https://www.googleapis.com/auth/admin.reports.usage.readonly'},
|
||||||
{'name': 'Reseller API',
|
{'name': 'Reseller API',
|
||||||
'api': RESELLER,
|
'api': RESELLER,
|
||||||
'subscopes': [],
|
|
||||||
'offByDefault': True,
|
'offByDefault': True,
|
||||||
'scope': 'https://www.googleapis.com/auth/apps.order'},
|
'scope': 'https://www.googleapis.com/auth/apps.order'},
|
||||||
|
{'name': 'Resource Manager API - Organizations readonly',
|
||||||
|
'api': CLOUDRESOURCEMANAGER,
|
||||||
|
'offByDefault': True,
|
||||||
|
'scope': 'https://www.googleapis.com/auth/cloudplatformorganizations.readonly'},
|
||||||
|
{'name': 'Resource Manager API - Projects readonly',
|
||||||
|
'api': CLOUDRESOURCEMANAGER,
|
||||||
|
'offByDefault': True,
|
||||||
|
'scope': 'https://www.googleapis.com/auth/cloudplatformprojects.readonly'},
|
||||||
{'name': 'Service Account Lookup pseudo-API',
|
{'name': 'Service Account Lookup pseudo-API',
|
||||||
'api': SERVICEACCOUNTLOOKUP,
|
'api': SERVICEACCOUNTLOOKUP,
|
||||||
'subscopes': [],
|
|
||||||
'scope': ''},
|
'scope': ''},
|
||||||
{'name': 'Site Verification API',
|
{'name': 'Site Verification API',
|
||||||
'api': SITEVERIFICATION,
|
'api': SITEVERIFICATION,
|
||||||
'subscopes': [],
|
|
||||||
'offByDefault': True,
|
'offByDefault': True,
|
||||||
'scope': 'https://www.googleapis.com/auth/siteverification'},
|
'scope': 'https://www.googleapis.com/auth/siteverification'},
|
||||||
{'name': 'Vault API',
|
{'name': 'Vault API',
|
||||||
@@ -538,30 +538,24 @@ _CLIENT_SCOPES = [
|
|||||||
_COMMANDDATA_CLIENT_SCOPES = [
|
_COMMANDDATA_CLIENT_SCOPES = [
|
||||||
{'name': 'Drive API - commanddata_clientaccess',
|
{'name': 'Drive API - commanddata_clientaccess',
|
||||||
'api': DRIVE3,
|
'api': DRIVE3,
|
||||||
'subscopes': [],
|
|
||||||
'scope': DRIVE_READONLY_SCOPE},
|
'scope': DRIVE_READONLY_SCOPE},
|
||||||
{'name': 'Sheets API - commanddata_clientaccess',
|
{'name': 'Sheets API - commanddata_clientaccess readonly',
|
||||||
'api': SHEETS,
|
'api': SHEETS,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/spreadsheets.readonly'},
|
'scope': 'https://www.googleapis.com/auth/spreadsheets.readonly'},
|
||||||
]
|
]
|
||||||
|
|
||||||
_TODRIVE_CLIENT_SCOPES = [
|
_TODRIVE_CLIENT_SCOPES = [
|
||||||
{'name': 'Drive API - todrive_clientaccess',
|
{'name': 'Drive API - todrive_clientaccess',
|
||||||
'api': DRIVE3,
|
'api': DRIVE3,
|
||||||
'subscopes': [],
|
|
||||||
'scope': DRIVE_SCOPE},
|
'scope': DRIVE_SCOPE},
|
||||||
{'name': 'Drive File API - todrive_clientaccess',
|
{'name': 'Drive File API - todrive_clientaccess',
|
||||||
'api': DRIVE3,
|
'api': DRIVE3,
|
||||||
'subscopes': [],
|
|
||||||
'scope': DRIVE_FILE_SCOPE},
|
'scope': DRIVE_FILE_SCOPE},
|
||||||
{'name': 'Gmail API - todrive_clientaccess',
|
{'name': 'Gmail API - todrive_clientaccess',
|
||||||
'api': GMAIL,
|
'api': GMAIL,
|
||||||
'subscopes': [],
|
|
||||||
'scope': GMAIL_SEND_SCOPE},
|
'scope': GMAIL_SEND_SCOPE},
|
||||||
{'name': 'Sheets API - todrive_clientaccess',
|
{'name': 'Sheets API - todrive_clientaccess',
|
||||||
'api': SHEETS,
|
'api': SHEETS,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/spreadsheets'},
|
'scope': 'https://www.googleapis.com/auth/spreadsheets'},
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -570,11 +564,9 @@ OAUTH2SA_SCOPES = 'us_scopes'
|
|||||||
_SVCACCT_SCOPES = [
|
_SVCACCT_SCOPES = [
|
||||||
{'name': 'AlertCenter API',
|
{'name': 'AlertCenter API',
|
||||||
'api': ALERTCENTER,
|
'api': ALERTCENTER,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/apps.alerts'},
|
'scope': 'https://www.googleapis.com/auth/apps.alerts'},
|
||||||
{'name': 'Analytics Admin API - read only',
|
{'name': 'Analytics Admin API - readonly',
|
||||||
'api': ANALYTICS_ADMIN,
|
'api': ANALYTICS_ADMIN,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/analytics.readonly'},
|
'scope': 'https://www.googleapis.com/auth/analytics.readonly'},
|
||||||
{'name': 'Calendar API',
|
{'name': 'Calendar API',
|
||||||
'api': CALENDAR,
|
'api': CALENDAR,
|
||||||
@@ -611,11 +603,9 @@ _SVCACCT_SCOPES = [
|
|||||||
'scope': 'https://www.googleapis.com/auth/chat.admin.spaces'},
|
'scope': 'https://www.googleapis.com/auth/chat.admin.spaces'},
|
||||||
{'name': 'Chat API - Spaces Delete',
|
{'name': 'Chat API - Spaces Delete',
|
||||||
'api': CHAT_SPACES_DELETE,
|
'api': CHAT_SPACES_DELETE,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/chat.delete'},
|
'scope': 'https://www.googleapis.com/auth/chat.delete'},
|
||||||
{'name': 'Chat API - Spaces Delete Admin',
|
{'name': 'Chat API - Spaces Delete Admin',
|
||||||
'api': CHAT_SPACES_DELETE_ADMIN,
|
'api': CHAT_SPACES_DELETE_ADMIN,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/chat.admin.delete'},
|
'scope': 'https://www.googleapis.com/auth/chat.admin.delete'},
|
||||||
{'name': 'Classroom API - Course Announcements',
|
{'name': 'Classroom API - Course Announcements',
|
||||||
'api': CLASSROOM,
|
'api': CLASSROOM,
|
||||||
@@ -635,11 +625,9 @@ _SVCACCT_SCOPES = [
|
|||||||
'scope': 'https://www.googleapis.com/auth/classroom.coursework.students'},
|
'scope': 'https://www.googleapis.com/auth/classroom.coursework.students'},
|
||||||
{'name': 'Classroom API - Profile Emails',
|
{'name': 'Classroom API - Profile Emails',
|
||||||
'api': CLASSROOM,
|
'api': CLASSROOM,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/classroom.profile.emails'},
|
'scope': 'https://www.googleapis.com/auth/classroom.profile.emails'},
|
||||||
{'name': 'Classroom API - Profile Photos',
|
{'name': 'Classroom API - Profile Photos',
|
||||||
'api': CLASSROOM,
|
'api': CLASSROOM,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/classroom.profile.photos'},
|
'scope': 'https://www.googleapis.com/auth/classroom.profile.photos'},
|
||||||
{'name': 'Classroom API - Rosters',
|
{'name': 'Classroom API - Rosters',
|
||||||
'api': CLASSROOM,
|
'api': CLASSROOM,
|
||||||
@@ -656,7 +644,6 @@ _SVCACCT_SCOPES = [
|
|||||||
# 'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'},
|
# 'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'},
|
||||||
# {'name': 'Cloud Identity API - Policy Beta',
|
# {'name': 'Cloud Identity API - Policy Beta',
|
||||||
# 'api': CLOUDIDENTITY_POLICY_BETA,
|
# 'api': CLOUDIDENTITY_POLICY_BETA,
|
||||||
# 'subscopes': [],
|
|
||||||
# 'offByDefault': True,
|
# 'offByDefault': True,
|
||||||
# 'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'},
|
# 'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'},
|
||||||
# {'name': 'Cloud Identity User Invitations API',
|
# {'name': 'Cloud Identity User Invitations API',
|
||||||
@@ -665,7 +652,6 @@ _SVCACCT_SCOPES = [
|
|||||||
# 'scope': 'https://www.googleapis.com/auth/cloud-identity'},
|
# 'scope': 'https://www.googleapis.com/auth/cloud-identity'},
|
||||||
# {'name': 'Contacts API - Users',
|
# {'name': 'Contacts API - Users',
|
||||||
# 'api': CONTACTS,
|
# 'api': CONTACTS,
|
||||||
# 'subscopes': [],
|
|
||||||
# 'scope': 'https://www.google.com/m8/feeds'},
|
# 'scope': 'https://www.google.com/m8/feeds'},
|
||||||
{'name': 'Drive API',
|
{'name': 'Drive API',
|
||||||
'api': DRIVE3,
|
'api': DRIVE3,
|
||||||
@@ -673,7 +659,6 @@ _SVCACCT_SCOPES = [
|
|||||||
'scope': DRIVE_SCOPE},
|
'scope': DRIVE_SCOPE},
|
||||||
{'name': 'Drive Activity API v2 - must pair with Drive API',
|
{'name': 'Drive Activity API v2 - must pair with Drive API',
|
||||||
'api': DRIVEACTIVITY,
|
'api': DRIVEACTIVITY,
|
||||||
'subscopes': [],
|
|
||||||
'scope': [DRIVE_READONLY_SCOPE,
|
'scope': [DRIVE_READONLY_SCOPE,
|
||||||
'https://www.googleapis.com/auth/drive.activity']},
|
'https://www.googleapis.com/auth/drive.activity']},
|
||||||
{'name': 'Drive Labels API - Admin',
|
{'name': 'Drive Labels API - Admin',
|
||||||
@@ -690,30 +675,24 @@ _SVCACCT_SCOPES = [
|
|||||||
'scope': 'https://www.googleapis.com/auth/documents'},
|
'scope': 'https://www.googleapis.com/auth/documents'},
|
||||||
{'name': 'Forms API - must pair with Drive API',
|
{'name': 'Forms API - must pair with Drive API',
|
||||||
'api': FORMS,
|
'api': FORMS,
|
||||||
'subscopes': [],
|
|
||||||
'scope': [DRIVE_READONLY_SCOPE,
|
'scope': [DRIVE_READONLY_SCOPE,
|
||||||
'https://www.googleapis.com/auth/forms.body',
|
'https://www.googleapis.com/auth/forms.body',
|
||||||
'https://www.googleapis.com/auth/forms.responses.readonly']},
|
'https://www.googleapis.com/auth/forms.responses.readonly']},
|
||||||
{'name': 'Gmail API - Full Access (Labels, Messages)',
|
{'name': 'Gmail API - Full Access (Labels, Messages)',
|
||||||
'api': GMAIL,
|
'api': GMAIL,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://mail.google.com/'},
|
'scope': 'https://mail.google.com/'},
|
||||||
{'name': 'Gmail API - Full Access (Labels, Messages) except delete message',
|
{'name': 'Gmail API - Full Access (Labels, Messages) except delete message',
|
||||||
'api': GMAIL,
|
'api': GMAIL,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/gmail.modify'},
|
'scope': 'https://www.googleapis.com/auth/gmail.modify'},
|
||||||
{'name': 'Gmail API - Basic Settings (Filters, IMAP, Language, POP, Vacation) - read/write, Sharing Settings (Delegates, Forwarding, SendAs) - read',
|
{'name': 'Gmail API - Basic Settings (Filters, IMAP, Language, POP, Vacation) - read/write, Sharing Settings (Delegates, Forwarding, SendAs) - read',
|
||||||
'api': GMAIL,
|
'api': GMAIL,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/gmail.settings.basic'},
|
'scope': 'https://www.googleapis.com/auth/gmail.settings.basic'},
|
||||||
{'name': 'Gmail API - Sharing Settings (Delegates, Forwarding, SendAs) - write',
|
{'name': 'Gmail API - Sharing Settings (Delegates, Forwarding, SendAs) - write',
|
||||||
'api': GMAIL,
|
'api': GMAIL,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/gmail.settings.sharing'},
|
'scope': 'https://www.googleapis.com/auth/gmail.settings.sharing'},
|
||||||
# {'name': 'Identity and Access Management API',
|
# {'name': 'Identity and Access Management API',
|
||||||
# 'api': IAM,
|
# 'api': IAM,
|
||||||
# 'offByDefault': True,
|
# 'offByDefault': True,
|
||||||
# 'subscopes': [],
|
|
||||||
# 'scope': CLOUD_PLATFORM_SCOPE},
|
# 'scope': CLOUD_PLATFORM_SCOPE},
|
||||||
{'name': 'Keep API',
|
{'name': 'Keep API',
|
||||||
'api': KEEP,
|
'api': KEEP,
|
||||||
@@ -725,32 +704,26 @@ _SVCACCT_SCOPES = [
|
|||||||
'scope': 'https://www.googleapis.com/auth/datastudio'},
|
'scope': 'https://www.googleapis.com/auth/datastudio'},
|
||||||
{'name': 'Meet API - Manage/Display Meeting Spaces',
|
{'name': 'Meet API - Manage/Display Meeting Spaces',
|
||||||
'api': MEET_SPACES,
|
'api': MEET_SPACES,
|
||||||
'subscopes': [],
|
|
||||||
'scope': ['https://www.googleapis.com/auth/meetings.space.created',
|
'scope': ['https://www.googleapis.com/auth/meetings.space.created',
|
||||||
'https://www.googleapis.com/auth/meetings.space.settings']},
|
'https://www.googleapis.com/auth/meetings.space.settings']},
|
||||||
{'name': 'Meet API - Read Meeting Spaces metadata',
|
{'name': 'Meet API - Read Meeting Spaces metadata readonly',
|
||||||
'api': MEET_READONLY,
|
'api': MEET_READONLY,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/meetings.space.readonly'},
|
'scope': 'https://www.googleapis.com/auth/meetings.space.readonly'},
|
||||||
{'name': 'OAuth2 API',
|
{'name': 'OAuth2 API',
|
||||||
'api': OAUTH2,
|
'api': OAUTH2,
|
||||||
'subscopes': [],
|
|
||||||
'scope': USERINFO_PROFILE_SCOPE},
|
'scope': USERINFO_PROFILE_SCOPE},
|
||||||
{'name': 'People API',
|
{'name': 'People API',
|
||||||
'api': PEOPLE,
|
'api': PEOPLE,
|
||||||
'subscopes': READONLY,
|
'subscopes': READONLY,
|
||||||
'scope': PEOPLE_SCOPE},
|
'scope': PEOPLE_SCOPE},
|
||||||
{'name': 'People Directory API - read only',
|
{'name': 'People Directory API - readonly',
|
||||||
'api': PEOPLE_DIRECTORY,
|
'api': PEOPLE_DIRECTORY,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/directory.readonly'},
|
'scope': 'https://www.googleapis.com/auth/directory.readonly'},
|
||||||
{'name': 'People API - Other Contacts - read only',
|
{'name': 'People API - Other Contacts - readonly',
|
||||||
'api': PEOPLE_OTHERCONTACTS,
|
'api': PEOPLE_OTHERCONTACTS,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/contacts.other.readonly'},
|
'scope': 'https://www.googleapis.com/auth/contacts.other.readonly'},
|
||||||
{'name': 'Search Console API - read only',
|
{'name': 'Search Console API - readonly',
|
||||||
'api': SEARCHCONSOLE,
|
'api': SEARCHCONSOLE,
|
||||||
'subscopes': [],
|
|
||||||
'offByDefault': True,
|
'offByDefault': True,
|
||||||
'scope': 'https://www.googleapis.com/auth/webmasters.readonly'},
|
'scope': 'https://www.googleapis.com/auth/webmasters.readonly'},
|
||||||
{'name': 'Sheets API',
|
{'name': 'Sheets API',
|
||||||
@@ -759,26 +732,22 @@ _SVCACCT_SCOPES = [
|
|||||||
'scope': 'https://www.googleapis.com/auth/spreadsheets'},
|
'scope': 'https://www.googleapis.com/auth/spreadsheets'},
|
||||||
{'name': 'Site Verification API',
|
{'name': 'Site Verification API',
|
||||||
'api': SITEVERIFICATION,
|
'api': SITEVERIFICATION,
|
||||||
'subscopes': [],
|
|
||||||
'offByDefault': True,
|
'offByDefault': True,
|
||||||
'scope': 'https://www.googleapis.com/auth/siteverification'},
|
'scope': 'https://www.googleapis.com/auth/siteverification'},
|
||||||
{'name': 'Tag Manager API - Accounts, Containers, Workspaces, Tags - read only',
|
{'name': 'Tag Manager API - Accounts, Containers, Workspaces, Tags - readonly',
|
||||||
'api': TAGMANAGER,
|
'api': TAGMANAGER,
|
||||||
'subscopes': [],
|
|
||||||
'offByDefault': True,
|
'offByDefault': True,
|
||||||
'scope': 'https://www.googleapis.com/auth/tagmanager.readonly'},
|
'scope': 'https://www.googleapis.com/auth/tagmanager.readonly'},
|
||||||
{'name': 'Tag Manager API - Users',
|
{'name': 'Tag Manager API - Users',
|
||||||
'api': TAGMANAGER_USERS,
|
'api': TAGMANAGER_USERS,
|
||||||
'subscopes': [],
|
|
||||||
'offByDefault': True,
|
'offByDefault': True,
|
||||||
'scope': 'https://www.googleapis.com/auth/tagmanager.manage.users'},
|
'scope': 'https://www.googleapis.com/auth/tagmanager.manage.users'},
|
||||||
{'name': 'Tasks API',
|
{'name': 'Tasks API',
|
||||||
'api': TASKS,
|
'api': TASKS,
|
||||||
'subscopes': READONLY,
|
'subscopes': READONLY,
|
||||||
'scope': 'https://www.googleapis.com/auth/tasks'},
|
'scope': 'https://www.googleapis.com/auth/tasks'},
|
||||||
{'name': 'Youtube API - read only',
|
{'name': 'Youtube API - readonly',
|
||||||
'api': YOUTUBE,
|
'api': YOUTUBE,
|
||||||
'subscopes': [],
|
|
||||||
'offByDefault': True,
|
'offByDefault': True,
|
||||||
'scope': 'https://www.googleapis.com/auth/youtube.readonly'},
|
'scope': 'https://www.googleapis.com/auth/youtube.readonly'},
|
||||||
]
|
]
|
||||||
@@ -786,30 +755,25 @@ _SVCACCT_SCOPES = [
|
|||||||
_SVCACCT_SPECIAL_SCOPES = [
|
_SVCACCT_SPECIAL_SCOPES = [
|
||||||
{'name': 'Drive API - write todrive data - has access to all Drive',
|
{'name': 'Drive API - write todrive data - has access to all Drive',
|
||||||
'api': DRIVETD,
|
'api': DRIVETD,
|
||||||
'subscopes': [],
|
|
||||||
'offByDefault': True,
|
'offByDefault': True,
|
||||||
'scope': DRIVE_SCOPE},
|
'scope': DRIVE_SCOPE},
|
||||||
{'name': 'Gmail API - Full Access - read only',
|
{'name': 'Gmail API - Full Access - readonly',
|
||||||
'api': GMAIL,
|
'api': GMAIL,
|
||||||
'subscopes': [],
|
|
||||||
'offByDefault': True,
|
'offByDefault': True,
|
||||||
'scope': 'https://www.googleapis.com/auth/gmail.readonly'},
|
'scope': 'https://www.googleapis.com/auth/gmail.readonly'},
|
||||||
{'name': 'Gmail API - Send Messages - including todrive',
|
{'name': 'Gmail API - Send Messages - including todrive',
|
||||||
'api': GMAIL,
|
'api': GMAIL,
|
||||||
'subscopes': [],
|
|
||||||
'offByDefault': True,
|
'offByDefault': True,
|
||||||
'scope': GMAIL_SEND_SCOPE},
|
'scope': GMAIL_SEND_SCOPE},
|
||||||
{'name': 'Sheets API - write todrive data - has access to all Sheets',
|
{'name': 'Sheets API - write todrive data - has access to all Sheets',
|
||||||
'api': SHEETSTD,
|
'api': SHEETSTD,
|
||||||
'offByDefault': True,
|
'offByDefault': True,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/spreadsheets'},
|
'scope': 'https://www.googleapis.com/auth/spreadsheets'},
|
||||||
]
|
]
|
||||||
|
|
||||||
_USER_SVCACCT_ONLY_SCOPES = [
|
_USER_SVCACCT_ONLY_SCOPES = [
|
||||||
{'name': 'Groups Migration API',
|
{'name': 'Groups Migration API',
|
||||||
'api': GROUPSMIGRATION,
|
'api': GROUPSMIGRATION,
|
||||||
'subscopes': [],
|
|
||||||
'scope': 'https://www.googleapis.com/auth/apps.groups.migration'},
|
'scope': 'https://www.googleapis.com/auth/apps.groups.migration'},
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -849,7 +813,7 @@ def getClientScopesURLs(commanddataClientAccess, todriveClientAccess):
|
|||||||
|
|
||||||
def getSvcAcctScopeAPI(uscope):
|
def getSvcAcctScopeAPI(uscope):
|
||||||
for scope in _SVCACCT_SCOPES:
|
for scope in _SVCACCT_SCOPES:
|
||||||
if uscope == scope['scope'] or (uscope.endswith('.readonly') and 'readonly' in scope['subscopes']):
|
if uscope == scope['scope'] or (uscope.endswith('.readonly') and 'readonly' in scope.get('subscopes', [])):
|
||||||
return scope['api']
|
return scope['api']
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -877,11 +841,11 @@ def findAPIforScope(scopesList):
|
|||||||
if cscope['scope'] == scope:
|
if cscope['scope'] == scope:
|
||||||
requiredAPIs.append(cscope['name'])
|
requiredAPIs.append(cscope['name'])
|
||||||
return True
|
return True
|
||||||
if cscope['subscopes'] == READONLY and cscope['scope']+'.readonly' == scope:
|
if 'readonly' in cscope.get('subscopes', []) and cscope['scope']+'.readonly' == scope:
|
||||||
requiredAPIs.append(cscope['name']+' (supports readonly)')
|
requiredAPIs.append(cscope['name']+' (supports readonly)')
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
requiredAPIs = []
|
requiredAPIs = []
|
||||||
for scope in scopesList:
|
for scope in scopesList:
|
||||||
for cscope in _CLIENT_SCOPES:
|
for cscope in _CLIENT_SCOPES:
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
\deftab720
|
\deftab720
|
||||||
\pard\pardeftab720\sl276\slmult1\sa200\qc\partightenfactor0
|
\pard\pardeftab720\sl276\slmult1\sa200\qc\partightenfactor0
|
||||||
|
|
||||||
\f0\fs22 \cf0 Copyright 2025 Jay Lee\
|
\f0\fs22 \cf0 Copyright 2026 Jay Lee\
|
||||||
\pard\pardeftab720\sa200\qc\partightenfactor0
|
\pard\pardeftab720\sa200\qc\partightenfactor0
|
||||||
|
|
||||||
\f1\b \cf0 Licensed under the Apache License, Version 2.0 (the "License");\
|
\f1\b \cf0 Licensed under the Apache License, Version 2.0 (the "License");\
|
||||||
|
|||||||
@@ -1,128 +1,147 @@
|
|||||||
// Node.js script that implements an Appium client which will launch
|
// Node.js script to launch Simply Sign Desktop app and log a user in
|
||||||
// Simply Sign Desktop app and log a user in. Once logged in it should
|
// using native Windows keystrokes and screenshot-desktop for reliable CI imaging.
|
||||||
// be possible to use tools like signtool.exe to sign Windows EXE/MSI files
|
|
||||||
// with the Certum certificate.
|
|
||||||
|
|
||||||
import { Key, remote } from 'webdriverio';
|
import { execSync, spawn } from 'child_process';
|
||||||
import { exec } from 'child_process';
|
|
||||||
import { TOTP } from 'totp-generator';
|
import { TOTP } from 'totp-generator';
|
||||||
|
import path from 'path';
|
||||||
async function screenshot(driver, filename) {
|
import fs from 'fs';
|
||||||
// uncomment to save .png screenshots
|
|
||||||
await driver.saveScreenshot(filename);
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
function sleep(ms) {
|
function sleep(ms) {
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function executeCommand(command) {
|
// Native PowerShell Keystroke Sender
|
||||||
|
function sendKeys(keys) {
|
||||||
|
const script = `$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('${keys}')`;
|
||||||
|
execSync(`powershell -Command "${script}"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Native PowerShell Desktop Clear
|
||||||
|
function minimizeAllWindows() {
|
||||||
|
console.log('Minimizing all rogue background windows...');
|
||||||
|
const script = `$shell = New-Object -ComObject "Shell.Application"; $shell.MinimizeAll()`;
|
||||||
try {
|
try {
|
||||||
let { stdout, stderr } = await exec(command);
|
execSync(`powershell -Command "${script}"`);
|
||||||
return stdout;
|
} catch (err) {
|
||||||
} catch (error) {
|
console.log('Minimize command failed silently.');
|
||||||
console.error(`Error executing command: ${command}`);
|
|
||||||
console.error(`Error details: ${error}`);
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runSSD() {
|
async function takeScreenshot(filename) {
|
||||||
const opts = {
|
const workspace = process.env.GITHUB_WORKSPACE || process.cwd();
|
||||||
port: 4723,
|
const fullPath = path.join(workspace, filename);
|
||||||
logLevel: "silent",
|
|
||||||
capabilities: {
|
|
||||||
platformName: "Windows",
|
|
||||||
"appium:app": "C:\\Program Files\\Certum\\SimplySign Desktop\\SimplySignDesktop.exe",
|
|
||||||
"appium:automationName": "Windows",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let driver;
|
const psScript = `
|
||||||
try {
|
Add-Type -AssemblyName System.Windows.Forms;
|
||||||
driver = await remote(opts);
|
Add-Type -AssemblyName System.Drawing;
|
||||||
|
$Screen = [System.Windows.Forms.SystemInformation]::VirtualScreen;
|
||||||
// Github Actions Win ARM64 is stuck on a OOB screen that steals focus
|
|
||||||
// These enter / escapes should dismiss it.
|
if ($Screen.Width -eq 0 -or $Screen.Height -eq 0) {
|
||||||
const runner_arch = process.env.RUNNER_ARCH;
|
Write-Error "Screen dimensions are 0x0. Desktop not fully initialized.";
|
||||||
if ( runner_arch === "ARM64" ) {
|
exit 1;
|
||||||
console.log('Running on ARM64...');
|
|
||||||
await sleep(3000); // Pause execution for 3 seconds
|
|
||||||
await screenshot(driver, 'oob1.png');
|
|
||||||
await driver.sendKeys([Key.Enter]);
|
|
||||||
await sleep(3000); // Pause execution for 3 seconds
|
|
||||||
await screenshot(driver, 'oob2.png');
|
|
||||||
await driver.sendKeys([Key.Enter]);
|
|
||||||
await sleep(3000); // Pause execution for 3 seconds
|
|
||||||
await screenshot(driver, 'oob3.png');
|
|
||||||
await driver.sendKeys([Key.Escape]);
|
|
||||||
await screenshot(driver, 'oob6.png');
|
|
||||||
} else {
|
|
||||||
console.log('NOT running on ARM64');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute SSD again to open login dialog
|
|
||||||
exec('"C:\\Program Files\\Certum\\SimplySign Desktop\\SimplySignDesktop.exe"', (error, stdout, stderr) => {
|
|
||||||
if (error) {
|
|
||||||
console.error(`exec error: ${error}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
await sleep(3000);
|
|
||||||
|
|
||||||
// Login
|
|
||||||
const windows = await driver.getWindowHandles();
|
|
||||||
const login_window = windows[0]
|
|
||||||
await driver.switchWindow(login_window);
|
|
||||||
await screenshot(driver, 'login01.png');
|
|
||||||
const id_value = 'jay0lee@gmail.com';
|
|
||||||
const id_arr = [...id_value];
|
|
||||||
await driver.sendKeys(id_arr);
|
|
||||||
await screenshot(driver, 'login02.png');
|
|
||||||
await driver.sendKeys([Key.Tab]);
|
|
||||||
console.log('Our secret is ' + process.env.TOTP_SECRET.length + ' characters.');
|
|
||||||
// We wait until the last possible second to generate
|
|
||||||
// our TOTP to ensure it's still valid.
|
|
||||||
const { otp } = await TOTP.generate(process.env.TOTP_SECRET, {algorithm: 'SHA-256'});
|
|
||||||
console.log('Our token is ' + otp.length + ' characters.');
|
|
||||||
const otp_arr = [...otp];
|
|
||||||
await driver.sendKeys(otp_arr);
|
|
||||||
await screenshot(driver, 'login03.png');
|
|
||||||
await driver.sendKeys([Key.Enter]);
|
|
||||||
|
|
||||||
// TODO: it's expected that on successful login the window
|
|
||||||
// will close and these screenshots will error out. Figure
|
|
||||||
// out how to handle that gracefully.
|
|
||||||
await screenshot(driver, 'login04.png');
|
|
||||||
await sleep(500);
|
|
||||||
await screenshot(driver, 'login05.png');
|
|
||||||
await sleep(500);
|
|
||||||
await screenshot(driver, 'login06.png');
|
|
||||||
await sleep(500);
|
|
||||||
await screenshot(driver, 'login07.png');
|
|
||||||
await sleep(500);
|
|
||||||
await screenshot(driver, 'login08.png');
|
|
||||||
await sleep(500);
|
|
||||||
await screenshot(driver, 'login09.png');
|
|
||||||
await sleep(500);
|
|
||||||
await screenshot(driver, 'login10.png');
|
|
||||||
await sleep(500);
|
|
||||||
await screenshot(driver, 'login11.png');
|
|
||||||
await sleep(500);
|
|
||||||
await screenshot(driver, 'login12.png');
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
//console.error("Error during Appium run:");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$bitmap = New-Object System.Drawing.Bitmap $Screen.Width, $Screen.Height;
|
||||||
|
$graphic = [System.Drawing.Graphics]::FromImage($bitmap);
|
||||||
|
$graphic.CopyFromScreen($Screen.Left, $Screen.Top, 0, 0, $bitmap.Size);
|
||||||
|
$bitmap.Save('${fullPath}');
|
||||||
|
`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
execSync(`powershell -Command "${psScript}"`);
|
||||||
|
console.log(`Saved screenshot: ${fullPath}`);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Failed to save screenshot ${fullPath}:`, err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// INTENTIONAL Keep driver open so tray icon for Certum doesn't close
|
// Fire and forget application launcher
|
||||||
// finally {
|
function launchSSD() {
|
||||||
// if (driver) {
|
const child = spawn('C:\\Program Files\\Certum\\SimplySign Desktop\\SimplySignDesktop.exe', [], {
|
||||||
// await driver.deleteSession(); // Close the Appium session
|
detached: true,
|
||||||
// }
|
stdio: 'ignore'
|
||||||
//}
|
});
|
||||||
|
child.unref();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function runSSD() {
|
||||||
|
await takeScreenshot('001.png');
|
||||||
|
minimizeAllWindows();
|
||||||
|
await sleep(2000);
|
||||||
|
await takeScreenshot('002.png');
|
||||||
|
sendKeys('{ESC}');
|
||||||
|
await sleep(2000);
|
||||||
|
await takeScreenshot('003.png');
|
||||||
|
//sendKeys('{ESC}');
|
||||||
|
//await sleep(2000);
|
||||||
|
//await takeScreenshot('004.png');
|
||||||
|
//sendKeys('{ESC}');
|
||||||
|
//await sleep(2000);
|
||||||
|
//await takeScreenshot('005.png');
|
||||||
|
//sendKeys('%{F4}');
|
||||||
|
//await sleep(2000);
|
||||||
|
//await takeScreenshot('006.png');
|
||||||
|
//sendKeys('%{F4}');
|
||||||
|
//await sleep(2000);
|
||||||
|
//await takeScreenshot('007.png');
|
||||||
|
|
||||||
|
// Re-execute SSD to open login dialog
|
||||||
|
launchSSD();
|
||||||
|
await sleep(3000);
|
||||||
|
await takeScreenshot('008.png');
|
||||||
|
launchSSD();
|
||||||
|
await sleep(3000);
|
||||||
|
await takeScreenshot('009.png');
|
||||||
|
|
||||||
|
// 2. Login Flow
|
||||||
|
console.log('Typing credentials...');
|
||||||
|
|
||||||
|
// Type Email
|
||||||
|
sendKeys('jay0lee@gmail.com');
|
||||||
|
await sleep(500);
|
||||||
|
await takeScreenshot('010.png');
|
||||||
|
|
||||||
|
// Tab to next field
|
||||||
|
sendKeys('{TAB}');
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
// Generate and type TOTP
|
||||||
|
console.log(`Our secret is ${process.env.TOTP_SECRET.length} characters.`);
|
||||||
|
const { otp } = await TOTP.generate(process.env.TOTP_SECRET, {algorithm: 'SHA-256'});
|
||||||
|
console.log(`Our token is ${otp.length} characters.`);
|
||||||
|
|
||||||
|
sendKeys(otp);
|
||||||
|
await sleep(500);
|
||||||
|
await takeScreenshot('011.png');
|
||||||
|
|
||||||
|
// Submit
|
||||||
|
sendKeys('{ENTER}');
|
||||||
|
console.log('Login sequence complete.');
|
||||||
|
|
||||||
|
// Screenshot cascade to monitor the window closing
|
||||||
|
await takeScreenshot('012.png');
|
||||||
|
await sleep(500);
|
||||||
|
await takeScreenshot('013.png');
|
||||||
|
await sleep(500);
|
||||||
|
await takeScreenshot('014.png');
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
|
||||||
|
console.log('Exiting script, leaving SimplySign running in background.');
|
||||||
|
|
||||||
|
// Verification block to list all PNGs in the workspace
|
||||||
|
console.log('\n--- Screenshot Verification ---');
|
||||||
|
const workspace = process.env.GITHUB_WORKSPACE || process.cwd();
|
||||||
|
try {
|
||||||
|
const files = fs.readdirSync(workspace);
|
||||||
|
const pngFiles = files.filter(f => f.endsWith('.png'));
|
||||||
|
console.log(`Target Directory: ${workspace}`);
|
||||||
|
console.log(`Found ${pngFiles.length} .png files:`);
|
||||||
|
pngFiles.forEach(f => console.log(` - ${f}`));
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Error reading directory ${workspace}:`, err.message);
|
||||||
|
}
|
||||||
|
console.log('-------------------------------\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
runSSD();
|
runSSD();
|
||||||
|
|||||||
@@ -99,14 +99,25 @@ Typically, you will enclose the entire list in double quotes and quote each item
|
|||||||
## Manage printers
|
## Manage printers
|
||||||
When creating a printer you must specify: `displayname`, `ou`, `uri` and `makeandmodel` or `driverless`.
|
When creating a printer you must specify: `displayname`, `ou`, `uri` and `makeandmodel` or `driverless`.
|
||||||
```
|
```
|
||||||
gam create printer <PrinterAttribute>+ [nodetails]
|
gam create printer <PrinterAttribute>+ [nodetails|returnidonly]
|
||||||
gam update printer <PrinterID> <PrinterAttribute>+ [nodetails]
|
gam update printer <PrinterID> <PrinterAttribute>+ [nodetails|returnidonly]
|
||||||
gam delete printer
|
gam delete printer
|
||||||
<PrinterIDList>|
|
<PrinterIDList>|
|
||||||
<FileSelector>|
|
<FileSelector>|
|
||||||
<CSVFileSelector>
|
<CSVFileSelector>
|
||||||
```
|
```
|
||||||
By default, when a printer is created/updated, GAM outputs details of the printer; the `nodetails` option suppresses this output.
|
By default, when a printer is created/updated, GAM outputs details of the printer.
|
||||||
|
* `nodetails` - Suppress the datails output.
|
||||||
|
* `returnidonly` - Display just the printer ID of the created printer as output
|
||||||
|
|
||||||
|
To retrieve the printer ID with `returnidonly`:
|
||||||
|
```
|
||||||
|
Linux/MacOS
|
||||||
|
printerId=$(gam create printer ... returnidonly)
|
||||||
|
Windows PowerShell
|
||||||
|
$printerId = & gam create printer ... returnidonly
|
||||||
|
```
|
||||||
|
The printer ID will only be valid when the return code of the command is 0; program accordingly.
|
||||||
|
|
||||||
## Display printers
|
## Display printers
|
||||||
Display information about a single printer.
|
Display information about a single printer.
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ See: https://cloud.google.com/identity/docs/concepts/supported-policy-api-settin
|
|||||||
Display selected policies.
|
Display selected policies.
|
||||||
```
|
```
|
||||||
gam info policies <CIPolicyEntity>
|
gam info policies <CIPolicyEntity>
|
||||||
[nowarnings] [noappnames]
|
[nowarnings] [noappnames] [noidmappimg]
|
||||||
[formatjson]
|
[formatjson]
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -69,16 +69,20 @@ Select policies::
|
|||||||
|
|
||||||
By default, policy warnings are displayed, use the 'nowarnings` option to suppress their display.
|
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`
|
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.
|
to get the application name for the application ID. Use option `noappnames` to suppress these calls.
|
||||||
|
|
||||||
|
By default, additional API calls are made to add the `policyQuery/groupEmail` and `policyQuery/orgUnitPath` fields
|
||||||
|
that are mapped from the `policyQuery/group` and `policyQuery/orgUnit` fields. Use option `noidmapping'
|
||||||
|
to suppress these calls and not add the additional fields.
|
||||||
|
|
||||||
By default, Gam displays the information as an indented list of keys and values.
|
By default, Gam displays the information as an indented list of keys and values.
|
||||||
* `formatjson` - Display the fields in JSON format.
|
* `formatjson` - Display the fields in JSON format.
|
||||||
|
|
||||||
Display all or filtered policies.
|
Display all or filtered policies.
|
||||||
```
|
```
|
||||||
gam show policies
|
gam show policies
|
||||||
[filter <String>] [nowarnings] [noappnames]
|
[filter <String>] [nowarnings] [noappnames] [noidmappimg]
|
||||||
[group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
|
[group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
|
||||||
[formatjson]
|
[formatjson]
|
||||||
```
|
```
|
||||||
@@ -92,12 +96,16 @@ By default, policy warnings are displayed, use the `nowarnings` option to suppre
|
|||||||
By default, additional API calls are made for `settings/workspace_marketplace.apps_allowlist`
|
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.
|
to get the application name for the application ID. Use option `noappnames` to suppress these calls.
|
||||||
|
|
||||||
|
By default, additional API calls are made to add the `policyQuery/groupEmail` and `policyQuery/orgUnitPath` fields
|
||||||
|
that are mapped from the `policyQuery/group` and `policyQuery/orgUnit` fields. Use option `noidmapping'
|
||||||
|
to suppress these calls and not add the additional fields.
|
||||||
|
|
||||||
By default, Gam displays the information as an indented list of keys and values.
|
By default, Gam displays the information as an indented list of keys and values.
|
||||||
* `formatjson` - Display the fields in JSON format.
|
* `formatjson` - Display the fields in JSON format.
|
||||||
|
|
||||||
```
|
```
|
||||||
gam print policies [todrive <ToDriveAttribute>*]
|
gam print policies [todrive <ToDriveAttribute>*]
|
||||||
[filter <String>] [nowarnings] [noappnames]
|
[filter <String>] [nowarnings] [noappnames] [noidmappimg]
|
||||||
[group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
|
[group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
|
||||||
[formatjson [quotechar <Character>]]
|
[formatjson [quotechar <Character>]]
|
||||||
```
|
```
|
||||||
@@ -108,6 +116,10 @@ By default, all policies are displayed:
|
|||||||
|
|
||||||
By default, policy warnings are displayed, use the `nowarnings` option to suppress their display.
|
By default, policy warnings are displayed, use the `nowarnings` option to suppress their display.
|
||||||
|
|
||||||
|
By default, additional API calls are made to add the `policyQuery/groupEmail` and `policyQuery/orgUnitPath` fields
|
||||||
|
that are mapped from the `policyQuery/group` and `policyQuery/orgUnit` fields. Use option `noidmapping'
|
||||||
|
to suppress these calls and not add the additional fields.
|
||||||
|
|
||||||
By default, additional API calls are made for `settings/workspace_marketplace.apps_allowlist`
|
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.
|
to get the application name for the application ID. Use option `noappnames` to suppress these calls.
|
||||||
|
|
||||||
|
|||||||
@@ -25,41 +25,41 @@ start a new terminal session and reissue the command from above.
|
|||||||
## Executable, Manual
|
## Executable, Manual
|
||||||
|
|
||||||
* Executable Archive, Manual, Linux/Google Cloud Shell
|
* Executable Archive, Manual, Linux/Google Cloud Shell
|
||||||
- `gam-7.wx.yz-linux-x86_64-glibc2.36.tar.xz`
|
- `gam-7.wx.yz-linux-x86_64-glibc2.35.tar.xz`
|
||||||
- `gam-7.wx.yz-linux-x86_64-glibc2.39.tar.xz`
|
- `gam-7.wx.yz-linux-x86_64-glibc2.39.tar.xz`
|
||||||
- `gam-7.wx.yz-linux-x86_64-legacy.tar.xz`
|
- `gam-7.wx.yz-linux-x86_64-legacy.tar.xz`
|
||||||
- Download the archive, extract the contents into some directory.
|
- Download the archive, extract the contents into some directory.
|
||||||
- Start a terminal session.
|
- Start a terminal session.
|
||||||
|
|
||||||
* Executable Archive, Manual, Raspberry Pi/ChromeOS ARM devices
|
* Executable Archive, Manual, Raspberry Pi/ChromeOS ARM devices
|
||||||
- `gam-7.wx.yz-linux-arm64-glibc2.36.tar.xz`
|
- `gam-7.wx.yz-linux-arm64-glibc2.35.tar.xz`
|
||||||
- `gam-7.wx.yz-linux-arm64-glibc2.39.tar.xz`
|
- `gam-7.wx.yz-linux-arm64-glibc2.39.tar.xz`
|
||||||
- `gam-7.wx.yz-linux-arm64-legacy.tar.xz`
|
- `gam-7.wx.yz-linux-arm64-legacy.tar.xz`
|
||||||
- Download the archive, extract the contents into some directory.
|
- Download the archive, extract the contents into some directory.
|
||||||
- Start a terminal session.
|
- Start a terminal session.
|
||||||
|
|
||||||
* Executable Archive, Manual, Mac OS versions Sonoma, Sequoia - M1/M2
|
* Executable Archive, Manual, Mac OS versions Sonoma, Sequoia - M1/M2
|
||||||
- `gam-7.wx.yz-macos14.7-arm64.tar.xz`
|
- `gam-7.wx.yz-macos14.8-arm64.tar.xz`
|
||||||
- Download the archive, extract the contents into some directory.
|
- Download the archive, extract the contents into some directory.
|
||||||
- Start a terminal session.
|
- Start a terminal session.
|
||||||
|
|
||||||
* Executable Archive, Manual, Mac OS versions Sequoia - M2/M3
|
* Executable Archive, Manual, Mac OS versions Sequoia - M2/M3
|
||||||
- `gam-7.wx.yz-macos15.6-arm64.tar.xz`
|
- `gam-7.wx.yz-macos15.7-arm64.tar.xz`
|
||||||
- Download the archive, extract the contents into some directory.
|
|
||||||
- Start a terminal session.
|
|
||||||
|
|
||||||
* Executable Archive, Manual, Mac OS versions Tahoe - M2/M3/M4
|
|
||||||
- `gam-7.wx.yz-macos26.0-arm64.tar.xz`
|
|
||||||
- Download the archive, extract the contents into some directory.
|
|
||||||
- Start a terminal session.
|
|
||||||
|
|
||||||
* Executable Archive, Manual, Mac OS, versions Ventura, Sonoma - Intel
|
|
||||||
- `gam-7.wx.yz-macos13.7-x86_64.tar.xz`
|
|
||||||
- Download the archive, extract the contents into some directory.
|
- Download the archive, extract the contents into some directory.
|
||||||
- Start a terminal session.
|
- Start a terminal session.
|
||||||
|
|
||||||
* Executable Archive, Manual, Mac OS, versions Sequoia, Tahoe - Intel
|
* Executable Archive, Manual, Mac OS, versions Sequoia, Tahoe - Intel
|
||||||
- `gam-7.wx.yz-macos15.6-x86_64.tar.xz`
|
- `gam-7.wx.yz-macos15.7-x86_64.tar.xz`
|
||||||
|
- Download the archive, extract the contents into some directory.
|
||||||
|
- Start a terminal session.
|
||||||
|
|
||||||
|
* Executable Archive, Manual, Mac OS versions Tahoe - M2/M3/M4
|
||||||
|
- `gam-7.wx.yz-macos26.3-arm64.tar.xz`
|
||||||
|
- Download the archive, extract the contents into some directory.
|
||||||
|
- Start a terminal session.
|
||||||
|
|
||||||
|
* Executable Archive, Manual, Mac OS versions Tahoe - Intel
|
||||||
|
- `gam-7.wx.yz-macos26.3-x86_64.tar.xz`
|
||||||
- Download the archive, extract the contents into some directory.
|
- Download the archive, extract the contents into some directory.
|
||||||
- Start a terminal session.
|
- Start a terminal session.
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ start a new terminal session and reissue the command from above.
|
|||||||
- Start a Command Prompt/PowerShell session.
|
- Start a Command Prompt/PowerShell session.
|
||||||
|
|
||||||
* Executable Installer, Manual, Windows 64 bit
|
* Executable Installer, Manual, Windows 64 bit
|
||||||
- `gam-7.wx.yz-windows-x86_64.msi`
|
- `gam-7.wx.yz-windows-x86_64.exe`
|
||||||
- Download the installer and run it.
|
- Download the installer and run it.
|
||||||
- Start a Command Prompt/PowerShell session.
|
- Start a Command Prompt/PowerShell session.
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ start a new terminal session and reissue the command from above.
|
|||||||
- Start a Command Prompt/PowerShell session.
|
- Start a Command Prompt/PowerShell session.
|
||||||
|
|
||||||
* Executable Installer, Manual, Windows 11 ARM
|
* Executable Installer, Manual, Windows 11 ARM
|
||||||
- `gam-7.wx.yz-windows-arm64.msi`
|
- `gam-7.wx.yz-windows-arm64.exe`
|
||||||
- Download the installer and run it.
|
- Download the installer and run it.
|
||||||
- Start a Command Prompt/PowerShell session.
|
- Start a Command Prompt/PowerShell session.
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,171 @@ 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
|
See [Downloads-Installs-GAM7](https://github.com/GAM-team/GAM/wiki/Downloads-Installs) for Windows or other options, including manual installation
|
||||||
|
|
||||||
|
### 7.36.03
|
||||||
|
|
||||||
|
Added command to send email replies that causes Gmail to recognize the message
|
||||||
|
in conversation mode for the user sending the reply and the user receiving the reply;
|
||||||
|
GAM supplies the necessary headers and options.
|
||||||
|
```
|
||||||
|
gam <UserTypeEntity> sendreply
|
||||||
|
(((query <QueryGmail> [querytime<String> <Date>]*) [or|and])+) | (ids <MessageIDEntity>)
|
||||||
|
[replyto <EmailAddress>]
|
||||||
|
[subject <String>] [<MessageContent>] [html [<Boolean>]]
|
||||||
|
(attach <FileName> [charset <CharSet>])*
|
||||||
|
(embedimage <FileName> <String>)*
|
||||||
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
|
|
||||||
|
gam user user@domain.com sendreply query "rfc822MsgId:<CAAMmEdqj43...1OsQ@mail.gmail.com>" textmessage "Thanks for the information"
|
||||||
|
gam user user@domain.com sendreply ids 19cfc3506c02c22b textmessage "Thanks for the information"
|
||||||
|
```
|
||||||
|
|
||||||
|
* See: https://github.com/GAM-team/GAM/wiki/Send-Email#conversation-mode
|
||||||
|
|
||||||
|
### 7.36.02
|
||||||
|
|
||||||
|
Added option `threadid <String>` to `gam [<UserTypeEntity>] sendemail` that causes Gmail to recognize the message
|
||||||
|
in conversation mode in for the user sending the message.
|
||||||
|
|
||||||
|
* See: https://github.com/GAM-team/GAM/wiki/Send-Email#conversation-mode
|
||||||
|
|
||||||
|
### 7.36.01
|
||||||
|
|
||||||
|
Fixed bug in `gam info|print|show policies` where the `policyQuery/query` field was not displayed.
|
||||||
|
|
||||||
|
Added option `noidmapping` to `gam info|print|show policies` to suppress adding the `policyQuery/groupEmail` and
|
||||||
|
`policyQuery/orgUnitPath` name fields that are mapped from the `policyQuery/group` and `policyQuery/orgInit` id fields.
|
||||||
|
|
||||||
|
### 7.36.00
|
||||||
|
|
||||||
|
Added options `filtermultiattrtype` and filtermultiattrcustom` to `gam info user` and
|
||||||
|
`gam print users` that support filtering `<UserMultiAttribute>` display based on `type` or `customType`.
|
||||||
|
|
||||||
|
```
|
||||||
|
<UserMultiAttributeFilterName> ::=
|
||||||
|
address|addresses|
|
||||||
|
externalid|externalids|
|
||||||
|
im|ims|
|
||||||
|
keyword|keywords|
|
||||||
|
location|locations|
|
||||||
|
orgainzation|organizations|
|
||||||
|
otheremail|otheremails|
|
||||||
|
phone|phones|
|
||||||
|
relation|relations|
|
||||||
|
website|websites
|
||||||
|
```
|
||||||
|
|
||||||
|
* `filtermultiattrtype <UserMultiAttributeFilterName> <String>` - Display `<UserMultiAttributeFilterName>` if its `type` is `<String>`
|
||||||
|
* `filtermultiattrcustom <UserMultiAttributeFilterName> <String>` - Display `<UserMultiAttributeFilterName>` if its `customType` is `<String>`
|
||||||
|
|
||||||
|
```
|
||||||
|
gam info user user@domain.com quick filtermultiattrtype organizations work filtermultiattrcustom phones private
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.35.03
|
||||||
|
|
||||||
|
Updated `gam <UserTypeEntity> print filelist|filecounts` to handle options `showsize` and `showsizeunits` as independent options.
|
||||||
|
* `showsize` - Display a column `Size` with a byte count
|
||||||
|
* `showsizeunits` - Display a column `SizeUnits` with a formatted size with units
|
||||||
|
|
||||||
|
If you select both options, you can sort multiple rows using the `Size` column.
|
||||||
|
|
||||||
|
### 7.35.02
|
||||||
|
|
||||||
|
Added option `showsizeunits` to `gam gam <UserTypeEntity> print filelist|filecounts` as an alternative to option `showsize`.
|
||||||
|
* `showsize` - 31549200951 - This is a byte count
|
||||||
|
* `showsizeunits` - 31.55 GB - This is as shown in the Admin console
|
||||||
|
|
||||||
|
### 7.35.01
|
||||||
|
|
||||||
|
The following commands have been updated to not verify the existence of `gam.cfg` credentials files
|
||||||
|
as the WARNING messages about the missing files can be confusing to new users setting up GAM.
|
||||||
|
```
|
||||||
|
gam checkconn
|
||||||
|
gam oauth|oauth2
|
||||||
|
gam version
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.35.00
|
||||||
|
|
||||||
|
Windows `gam-7.wx.yz-x86_64.msi` has been replaced with `gam-7.wx.yz-x86_64.exe`.
|
||||||
|
|
||||||
|
Windows `gam-7.wx.yz-arm64.msi` has been replaced with `gam-7.wx.yz-arm64.exe`.
|
||||||
|
|
||||||
|
Updated cacerts.pem to avoid to following error in `gam checkconn`.
|
||||||
|
```
|
||||||
|
Checking raw.githubusercontent.com (185.199.110.133) (2)... ERROR
|
||||||
|
Certificate verification failed. If you are behind a firewall / proxy server that does TLS / SSL inspection you may need to point GAM at your certificate authority file by setting cacerts_pem = /path/to/your/certauth.pem in gam.cfg.
|
||||||
|
```
|
||||||
|
|
||||||
|
If you have customized cacerts.pem, update your version with the `Operating CA: Let's Encrypt` values from the GAM default version.
|
||||||
|
|
||||||
|
### 7.34.13
|
||||||
|
|
||||||
|
Fixed bug in `gam info policies <CIPolicyNameEntity> ... formatjson` where extraneous line
|
||||||
|
`Show Info 1 Policy` was displayed.
|
||||||
|
|
||||||
|
### 7.34.12
|
||||||
|
|
||||||
|
Fixed build errors that prevented Windows zip files from being created.
|
||||||
|
|
||||||
|
Added option `returnidonly` to `gam create|update printer` that causes GAM to return just the ID
|
||||||
|
of the printer.
|
||||||
|
|
||||||
|
### 7.34.11
|
||||||
|
|
||||||
|
Updated gam-install.sh script for macOS/Linux to properly config GAM when the answer to the following question is No.
|
||||||
|
```
|
||||||
|
Can you run a full browser on this machine? (usually Y for macOS, N for Linux if you SSH into this machine)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.34.10
|
||||||
|
|
||||||
|
Fixed bug where `formatjson quotechar <Character>` on the command line did not override `redirect csv <FileName> multiprocess quotechar <Character>`.
|
||||||
|
|
||||||
|
### 7.34.09
|
||||||
|
|
||||||
|
Updated `gam <UserTypeEntity> update photo` to delete the user's existing photo
|
||||||
|
before performing the update as the API update will succeed but not replace a user's existing self-set photo.
|
||||||
|
|
||||||
|
### 7.34.08
|
||||||
|
|
||||||
|
Rebuild to avoid the following error:
|
||||||
|
```
|
||||||
|
requests/__init__.py:113: RequestsDependencyWarning: urllib3 (2.6.3) or chardet (6.0.0.post1)/charset_normalizer (3.4.4) doesn't match a supported version!
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.34.07
|
||||||
|
|
||||||
|
Added the following command to create a guest user.
|
||||||
|
* See: https://support.google.com/a/answer/16558545
|
||||||
|
```
|
||||||
|
gam create guestuser <EmailAddress>
|
||||||
|
```
|
||||||
|
|
||||||
|
Added the following items to `<UserFieldName>`:
|
||||||
|
* `guestaccountinfo` - Additional guest-related metadata fields
|
||||||
|
* `isguestuser` - Indicates if the inserted user is a guest
|
||||||
|
|
||||||
|
### 7.34.06
|
||||||
|
|
||||||
|
Added option `copyfolderpermissions [<Boolean>]` to `gam <UserTypeEntity> copy|move drivefile`.
|
||||||
|
|
||||||
|
When `copyfolderpermissions false` is specified, no folder permissions are copied; this simplifies
|
||||||
|
disabling all folder permission copying.
|
||||||
|
|
||||||
|
When not specified or `copyfolderpermissions [true]` is specified, folder permissions are copied based on the following options:
|
||||||
|
```
|
||||||
|
copymergewithparentfolderpermissions [<Boolean>]
|
||||||
|
copymergedtopfolderpermissions [<Boolean>]
|
||||||
|
copytopfolderpermissions [<Boolean>]
|
||||||
|
copytopfolderiheritedpermissions [<Boolean>]
|
||||||
|
copytopfoldernoniheritedpermissions never|always|syncallfolders|syncupdatedfolders
|
||||||
|
copymergedsubfolderpermissions [<Boolean>]
|
||||||
|
copysubfolderpermissions [<Boolean>]
|
||||||
|
copysubfolderinheritedpermissions [<Boolean>]
|
||||||
|
copysubfoldernoniheritedpermissions never|always|syncallfolders|syncupdatedfolders
|
||||||
|
```
|
||||||
|
|
||||||
### 7.34.05
|
### 7.34.05
|
||||||
|
|
||||||
Updated `gam report <ActivityApplictionName>` to perform a reverse chronological sort
|
Updated `gam report <ActivityApplictionName>` to perform a reverse chronological sort
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ See: [Downloads-Installs-GAM7](Downloads-Installs-GAM7)
|
|||||||
### Update to latest version, use current path `C:\GAMADV-XTD3`.
|
### Update to latest version, use current path `C:\GAMADV-XTD3`.
|
||||||
You don't have to update path or scripts.
|
You don't have to update path or scripts.
|
||||||
* Executable Installer, Manual, Windows 64 bit
|
* Executable Installer, Manual, Windows 64 bit
|
||||||
- `gam-7.wx.yz-windows-x86_64.msi`
|
- `gam-7.wx.yz-windows-x86_64.exe`
|
||||||
- Download the installer and run it. When prompted for the Destination Foler, enter `C:\GAMADV-XTD3`.
|
- Download the installer and run it. When prompted for the Destination Foler, enter `C:\GAMADV-XTD3`.
|
||||||
* Executable Archive, Manual, Windows 64 bit
|
* Executable Archive, Manual, Windows 64 bit
|
||||||
- `gam-7.wx.yz-windows-x86_64.zip`
|
- `gam-7.wx.yz-windows-x86_64.zip`
|
||||||
@@ -139,7 +139,7 @@ Your update is complete.
|
|||||||
|
|
||||||
### Update to latest version, use new path `C:\GAM7`.
|
### Update to latest version, use new path `C:\GAM7`.
|
||||||
* Executable Installer, Manual, Windows 64 bit
|
* Executable Installer, Manual, Windows 64 bit
|
||||||
- `gam-7.wx.yz-windows-x86_64.msi`
|
- `gam-7.wx.yz-windows-x86_64.exe`
|
||||||
- Download the installer and run it.
|
- Download the installer and run it.
|
||||||
- Start a Command Prompt/PowerShell session.
|
- Start a Command Prompt/PowerShell session.
|
||||||
* Executable Archive, Manual, Windows 64 bit
|
* Executable Archive, Manual, Windows 64 bit
|
||||||
|
|||||||
@@ -251,11 +251,10 @@ writes the credentials into the file oauth2.txt.
|
|||||||
```
|
```
|
||||||
gamteam@server:/Users/gamteam$ rm -f /Users/gamteam/GAMConfig/oauth2.txt
|
gamteam@server:/Users/gamteam$ rm -f /Users/gamteam/GAMConfig/oauth2.txt
|
||||||
gamteam@server:/Users/gamteam$ gam version
|
gamteam@server:/Users/gamteam$ gam version
|
||||||
WARNING: Config File: /Users/gamteam/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/gamteam/GAMConfig/oauth2.txt, Not Found
|
GAM 7.36.03 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM 7.34.05 - https://github.com/GAM-team/GAM - pyinstaller
|
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.14.3 64-bit final
|
Python 3.14.3 64-bit final
|
||||||
macOS Tahoe 26.3 arm64
|
macOS Tahoe 26.3.1 arm64
|
||||||
Path: /Users/gamteam/bin/gam7
|
Path: /Users/gamteam/bin/gam7
|
||||||
Config File: /Users/gamteam/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/gamteam/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
|
|
||||||
@@ -1035,8 +1034,7 @@ writes the credentials into the file oauth2.txt.
|
|||||||
```
|
```
|
||||||
C:\>del C:\GAMConfig\oauth2.txt
|
C:\>del C:\GAMConfig\oauth2.txt
|
||||||
C:\>gam version
|
C:\>gam version
|
||||||
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
|
GAM 7.36.03 - https://github.com/GAM-team/GAM - pythonsource
|
||||||
GAM 7.34.05 - https://github.com/GAM-team/GAM - pythonsource
|
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.14.3 64-bit final
|
Python 3.14.3 64-bit final
|
||||||
Windows 11 10.0.26200 AMD64
|
Windows 11 10.0.26200 AMD64
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Organizational Units
|
# Organizational Units
|
||||||
- [API documentation](#api-documentation)
|
- [API documentation](#api-documentation)
|
||||||
- [Definitions](#definitions)
|
- [Definitions](#definitions)
|
||||||
|
- [Special character issues](#special-character-issues)
|
||||||
- [Special quoting](#special-quoting)
|
- [Special quoting](#special-quoting)
|
||||||
- [Manage organizational units](#manage-organizational-units)
|
- [Manage organizational units](#manage-organizational-units)
|
||||||
- [Add users to an organizational unit](#add-users-to-an-organizational-unit)
|
- [Add users to an organizational unit](#add-users-to-an-organizational-unit)
|
||||||
@@ -50,6 +51,15 @@ For `<UserTypeEntity>`, see: [Collections of Users](Collections-Of-Users)
|
|||||||
|
|
||||||
For `<CrOSTypeEntity>`, see: [Collections of ChromeOS Devices](Collections-of-ChromeOS-Devices)
|
For `<CrOSTypeEntity>`, see: [Collections of ChromeOS Devices](Collections-of-ChromeOS-Devices)
|
||||||
|
|
||||||
|
## Special character issues
|
||||||
|
If an organizational unit name contains a `#` or a `+`, these commands will not work due to a bug
|
||||||
|
that Google does not plan to fix.
|
||||||
|
```
|
||||||
|
gam update org|ou <OrgUnitPath>
|
||||||
|
gam delete org|ou <OrgUnitPath>
|
||||||
|
gam info org|ou <OrgUnitPath>
|
||||||
|
```
|
||||||
|
|
||||||
## Special quoting
|
## Special quoting
|
||||||
You specify a single organizational unit with `org <OrgUnitPath>` and a list of organizationsl units with `orgs <OrgUnitList>`.
|
You specify a single organizational unit with `org <OrgUnitPath>` and a list of organizationsl units with `orgs <OrgUnitList>`.
|
||||||
As organizational unit paths can contain spaces, some care must be used when entering `<OrgUnitPath>` and `<OrgUnitList>`.
|
As organizational unit paths can contain spaces, some care must be used when entering `<OrgUnitPath>` and `<OrgUnitList>`.
|
||||||
|
|||||||
@@ -377,6 +377,9 @@ features "CameraSet"
|
|||||||
features "'Laptop Cart'"
|
features "'Laptop Cart'"
|
||||||
features "CameraSet,'Laptop Cart'"
|
features "CameraSet,'Laptop Cart'"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
For quoting rules, see: [List Quoting Rules](Command-Line-Parsing)
|
||||||
|
|
||||||
## Manage buildings
|
## Manage buildings
|
||||||
When creating a building, at a minimum you must enter `address|addresslines` and `country|regioncode`.
|
When creating a building, at a minimum you must enter `address|addresslines` and `country|regioncode`.
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
- [Send an email to users](#send-an-email-to-users)
|
- [Send an email to users](#send-an-email-to-users)
|
||||||
- [Simple `replace <Tag> <String>` processing](Tag-Replace)
|
- [Simple `replace <Tag> <String>` processing](Tag-Replace)
|
||||||
- [Example](#example)
|
- [Example](#example)
|
||||||
|
- [Conversation mode](#conversation-mode)
|
||||||
|
|
||||||
## Note
|
## Note
|
||||||
Thanks to @bousquf for the following enhancement. You want to send a message from an authorized group
|
Thanks to @bousquf for the following enhancement. You want to send a message from an authorized group
|
||||||
@@ -214,14 +215,14 @@ Configure it at Admin Console > Apps > Google Workspace > Gmail > Routing > SMTP
|
|||||||
gam sendemail [recipient|to] <RecipientEntity>
|
gam sendemail [recipient|to] <RecipientEntity>
|
||||||
[from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>]
|
[from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>]
|
||||||
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
[subject <String>]
|
[subject <String>] [<MessageContent>]
|
||||||
[<MessageContent>]
|
|
||||||
(replace <Tag> <String>)*
|
(replace <Tag> <String>)*
|
||||||
(replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
|
(replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
|
||||||
[html [<Boolean>]] (attach <FileName> [charset <Charset>])*
|
[html [<Boolean>]] (attach <FileName> [charset <Charset>])*
|
||||||
(embedimage <FileName> <String>)*
|
(embedimage <FileName> <String>)*
|
||||||
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
|
[threadid <String>]
|
||||||
```
|
```
|
||||||
By default, emails will be sent from the admin user named in oauth2.txt, override this with the `from <EmailAddress>` option.
|
By default, emails will be sent from the admin user named in oauth2.txt, override this with the `from <EmailAddress>` option.
|
||||||
|
|
||||||
@@ -272,14 +273,14 @@ You can specify additional recipients, e.g., help desk personnel.
|
|||||||
gam sendemail [recipient|to] <RecipientEntity> [from <EmailAddress>]
|
gam sendemail [recipient|to] <RecipientEntity> [from <EmailAddress>]
|
||||||
[replyto <EmailAddress>]
|
[replyto <EmailAddress>]
|
||||||
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
[subject <String>]
|
[subject <String>] [<MessageContent>]
|
||||||
[<MessageContent>]
|
|
||||||
(replace <Tag> <String>)*
|
(replace <Tag> <String>)*
|
||||||
(replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
|
(replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
|
||||||
[html [<Boolean>]] (attach <FileName> [charset <Charset>])*
|
[html [<Boolean>]] (attach <FileName> [charset <Charset>])*
|
||||||
(embedimage <FileName> <String>)*
|
(embedimage <FileName> <String>)*
|
||||||
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
|
[threadid <String>]
|
||||||
```
|
```
|
||||||
|
|
||||||
By default, emails will be sent from the admin user named in oauth2.txt, override this with the `from <EmailAddress>` option.
|
By default, emails will be sent from the admin user named in oauth2.txt, override this with the `from <EmailAddress>` option.
|
||||||
@@ -353,14 +354,14 @@ gam csv Users.csv gam sendemail "~personal" subject "Your new #domain# account`
|
|||||||
gam <UserTypeEntity> sendemail recipient|to <RecipientEntity>
|
gam <UserTypeEntity> sendemail recipient|to <RecipientEntity>
|
||||||
[replyto <EmailAddress>]
|
[replyto <EmailAddress>]
|
||||||
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
[subject <String>]
|
[subject <String>] [<MessageContent>]
|
||||||
[<MessageContent>]
|
|
||||||
(replace <Tag> <String>)*
|
(replace <Tag> <String>)*
|
||||||
(replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
|
(replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
|
||||||
[html [<Boolean>]] (attach <FileName> [charset <Charset>])*
|
[html [<Boolean>]] (attach <FileName> [charset <Charset>])*
|
||||||
(embedimage <FileName> <String>)*
|
(embedimage <FileName> <String>)*
|
||||||
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
|
[threadid <String>]
|
||||||
```
|
```
|
||||||
Emails will be sent from the users in `<UserTypeEntity>` to the recipients in `<RecipientEntity>`.
|
Emails will be sent from the users in `<UserTypeEntity>` to the recipients in `<RecipientEntity>`.
|
||||||
|
|
||||||
@@ -395,14 +396,14 @@ Your command line will have: `embedimage file1.jpg image1 embedimage file2.jpg i
|
|||||||
gam <UserTypeEntity> sendemail from <EmailAddress>
|
gam <UserTypeEntity> sendemail from <EmailAddress>
|
||||||
[replyto <EmailAddress>]
|
[replyto <EmailAddress>]
|
||||||
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
[cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
[subject <String>]
|
[subject <String>] [<MessageContent>]
|
||||||
[<MessageContent>]
|
|
||||||
(replace <Tag> <String>)*
|
(replace <Tag> <String>)*
|
||||||
(replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
|
(replaceregex <REMatchPattern> <RESubstitution> <Tag> <String>)*
|
||||||
[html [<Boolean>]] (attach <FileName> [charset <Charset>])*
|
[html [<Boolean>]] (attach <FileName> [charset <Charset>])*
|
||||||
(embedimage <FileName> <String>)*
|
(embedimage <FileName> <String>)*
|
||||||
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
[newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
|
[threadid <String>]
|
||||||
```
|
```
|
||||||
Emails will be sent to the users in `<UserTypeEntity>`.
|
Emails will be sent to the users in `<UserTypeEntity>`.
|
||||||
|
|
||||||
@@ -451,3 +452,42 @@ $ gam csv UserEmail.csv gam user "~User" sendemail to "~To" subject "~Subject" t
|
|||||||
User: user1@domain.com, Send Email to 1 Recipient
|
User: user1@domain.com, Send Email to 1 Recipient
|
||||||
Recipient: user2@domain.com, Message: Test, Email Sent: 17677cdfbe1146f4
|
Recipient: user2@domain.com, Message: Test, Email Sent: 17677cdfbe1146f4
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Conversation mode
|
||||||
|
|
||||||
|
To reply to an email and have Gmail recognize it in conversation mode for the original sender, you have to specify the
|
||||||
|
`References` and `In-Reply-to` headers with the `RFC822 Message ID` from the original message
|
||||||
|
and the `subject` from the original message.
|
||||||
|
```
|
||||||
|
gam user recipient@domain.com sendemail to sender@domain.com references "<CAAMabc...XYZQ@mail.gmail.com>" in-reply-to "<CAAMabc...XYZQ@mail.gmail.com>" subject "Re: Original subject" textmessage "Reply text"
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to have Gmail recognize the reply in conversation mode in the Sent folder of the original recipient,
|
||||||
|
you must include `threadid <String>`; you can get the 'threadId` with:
|
||||||
|
```
|
||||||
|
gam user recipient@domain.com show threads query "rfc822MsgId:<CAAMabc...XYZQ@mail.gmail.com>"
|
||||||
|
Getting all Messages that match query ((rfc822MsgId:<CAAMabc...XYZQ@mail.gmail.com>)) for recipient@domain.com
|
||||||
|
Got 1 Message that matched query ((rfc822MsgId:<CAAMabc...XYZQ@mail.gmail.com>)) for recipient@domain.com...
|
||||||
|
User: recipient@domain.com, Show 1 Thread
|
||||||
|
Thread: 19cfd414fe48430d
|
||||||
|
Message: 19cfd414fe48430d
|
||||||
|
...
|
||||||
|
|
||||||
|
gam user recipient@domain.com sendemail to sender@domain.com references "<CAAMabc...XYZQ@mail.gmail.com>" in-reply-to "<CAAMabc...XYZQ@mail.gmail.com>" subject "Re: Original subject" textmessage "Reply text" threadid 19cfd414fe48430d
|
||||||
|
```
|
||||||
|
As of version 7.36.03, GAM has a command to simplify this process.
|
||||||
|
```
|
||||||
|
gam <UserTypeEntity> sendreply
|
||||||
|
(((query <QueryGmail> [querytime<String> <Date>]*) [or|and])+) | (ids <MessageIDEntity>)
|
||||||
|
[replyto <EmailAddress>]
|
||||||
|
[subject <String>] [<MessageContent>] [html [<Boolean>]]
|
||||||
|
(attach <FileName> [charset <CharSet>])*
|
||||||
|
(embedimage <FileName> <String>)*
|
||||||
|
(<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
|
|
||||||
|
gam user recipient@domain.com sendreply query "rfc822MsgId:<CAAMabc...XYZQ@mail.gmail.com>" textmessage "Reply text"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
- [Change Shared Drive visibility](#change-shared-drive-visibility)
|
- [Change Shared Drive visibility](#change-shared-drive-visibility)
|
||||||
- [Display Shared Drives](#display-shared-drives)
|
- [Display Shared Drives](#display-shared-drives)
|
||||||
- [Display Shared Drive Counts](#display-shared-drive-counts)
|
- [Display Shared Drive Counts](#display-shared-drive-counts)
|
||||||
|
- [Display Shared Drive Storage Info](#display-shared-drive-storage-info)
|
||||||
- [Display List of Shared Drives in an Organizational Unit](#display-list-of-shared-drives-in-an-organizational-unit)
|
- [Display List of Shared Drives in an Organizational Unit](#display-list-of-shared-drives-in-an-organizational-unit)
|
||||||
- [Display Count of Shared Drives in an Organizational Unit](#display-count-of-shared-drives-in-an-organizational-unit)
|
- [Display Count of Shared Drives in an Organizational Unit](#display-count-of-shared-drives-in-an-organizational-unit)
|
||||||
- [Display Shared Drive Organizers](#display-shared-drive-organizers)
|
- [Display Shared Drive Organizers](#display-shared-drive-organizers)
|
||||||
@@ -563,6 +564,21 @@ Windows Command Prompt
|
|||||||
for /f "delims=" %a in ('gam print shareddrives showitemcountonly') do set count=%a
|
for /f "delims=" %a in ('gam print shareddrives showitemcountonly') do set count=%a
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Display Shared Drive Storage Info
|
||||||
|
|
||||||
|
Get a list of Shared Drives/organizers.
|
||||||
|
```
|
||||||
|
gam redirect csv ./SharedDriveOrganizers.csv print shareddriveorganizers includefileorganizers
|
||||||
|
```
|
||||||
|
Get SharedDrive Drive file count and storage info; use one of the following for size information:
|
||||||
|
* `showsize` - 31549200951 - This is a byte count; include `Size` in `csv_output_header_filter`
|
||||||
|
* `showsizeunits` - 31.55 GB - This is as shown in the Admin console; include `SizeUnits` in csv_output_header_filter
|
||||||
|
```
|
||||||
|
gam config csv_output_header_filter "id,name,Total,Size,SizeUnits,Item cap" csv_input_row_filter "organizers:regex:^.+$"
|
||||||
|
redirect csv ./SharedDriveStorageInfo.csv multiprocess redirect stderr - multiprocess
|
||||||
|
csv ./SharedDriveOrganizers.csv gam user "~organizers" print filecounts select shareddriveid "~id" showsize showsizeunits
|
||||||
|
```
|
||||||
|
|
||||||
## Display all Shared Drives with a specific organizer
|
## Display all Shared Drives with a specific organizer
|
||||||
Substitute actual email address for `organizer@domain.com`.
|
Substitute actual email address for `organizer@domain.com`.
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ gam <UserTypeEntity> copy drivefile <DriveFileEntity>
|
|||||||
[copyfilepermissions [<Boolean>]]
|
[copyfilepermissions [<Boolean>]]
|
||||||
[copyfileinheritedpermissions [<Boolean>]
|
[copyfileinheritedpermissions [<Boolean>]
|
||||||
[copyfilenoninheritedpermissions [<Boolean>]
|
[copyfilenoninheritedpermissions [<Boolean>]
|
||||||
|
[copyfolderpermissions [<Boolean>]]
|
||||||
[copymergewithparentfolderpermissions [<Boolean>]]
|
[copymergewithparentfolderpermissions [<Boolean>]]
|
||||||
[copymergedtopfolderpermissions [<Boolean>]]
|
[copymergedtopfolderpermissions [<Boolean>]]
|
||||||
[copytopfolderpermissions [<Boolean>]]
|
[copytopfolderpermissions [<Boolean>]]
|
||||||
@@ -294,6 +295,8 @@ When a folder is copied, its permissions are not copied; these options control c
|
|||||||
of the form `option [<Boolean>]`; if `<Boolean>` is omitted, `true` is assumed.
|
of the form `option [<Boolean>]`; if `<Boolean>` is omitted, `true` is assumed.
|
||||||
|
|
||||||
When copied, a target folder inherits the permissions of its parent folder; these options control whether/how GAM copies the existing source folder permissions.
|
When copied, a target folder inherits the permissions of its parent folder; these options control whether/how GAM copies the existing source folder permissions.
|
||||||
|
* `copyfolderpermissions false` - The permissions of the source folders are not copied to the target folder.
|
||||||
|
* `copyfolderpermissions true` - The permissions of the source folders are copied to the target folder based on the following options; this is the default action.
|
||||||
|
|
||||||
When `mergewithparent` is `true`:
|
When `mergewithparent` is `true`:
|
||||||
* `copymergewithparentfolderpermissions false` - The permissions of the source top folder are not not copied to the target folder; this is the default action.
|
* `copymergewithparentfolderpermissions false` - The permissions of the source top folder are not not copied to the target folder; this is the default action.
|
||||||
@@ -571,6 +574,7 @@ gam <UserTypeEntity> move drivefile <DriveFileEntity> [newfilename <DriveFileNam
|
|||||||
[createshortcutsfornonmovablefiles [<Boolean>]]
|
[createshortcutsfornonmovablefiles [<Boolean>]]
|
||||||
[duplicatefiles overwriteolder|overwriteall|duplicatename|uniquename|skip]
|
[duplicatefiles overwriteolder|overwriteall|duplicatename|uniquename|skip]
|
||||||
[duplicatefolders merge|duplicatename|uniquename|skip]
|
[duplicatefolders merge|duplicatename|uniquename|skip]
|
||||||
|
[copyfolderpermissions [<Boolean>]]
|
||||||
[copymergewithparentfolderpermissions [<Boolean>]]
|
[copymergewithparentfolderpermissions [<Boolean>]]
|
||||||
[copymergedtopfolderpermissions [<Boolean>]]
|
[copymergedtopfolderpermissions [<Boolean>]]
|
||||||
[copytopfolderpermissions [<Boolean>]]
|
[copytopfolderpermissions [<Boolean>]]
|
||||||
@@ -660,6 +664,8 @@ When a folder is moved by recreating it, its permissions are not copied by the D
|
|||||||
For options of the form `option [<Boolean>]`; if `<Boolean>` is omitted, `true` is assumed.
|
For options of the form `option [<Boolean>]`; if `<Boolean>` is omitted, `true` is assumed.
|
||||||
|
|
||||||
When recreated, a target folder inherits the permissions of its parent folder; these options control whether/how GAM copies the existing source folder permissions;
|
When recreated, a target folder inherits the permissions of its parent folder; these options control whether/how GAM copies the existing source folder permissions;
|
||||||
|
* `copyfolderpermissions false` - The permissions of the source folders are not copied to the target folder.
|
||||||
|
* `copyfolderpermissions true` - The permissions of the source folders are copied to the target folder based on the following options; this is the default action.
|
||||||
|
|
||||||
When `mergewithparent` is `true`:
|
When `mergewithparent` is `true`:
|
||||||
* `copymergewithparentfolderpermissions false` - The permissions of the source top folder are not not copied to the target folder; this is the default action.
|
* `copymergewithparentfolderpermissions false` - The permissions of the source top folder are not not copied to the target folder; this is the default action.
|
||||||
|
|||||||
@@ -405,7 +405,7 @@ quotaBytesUsed - The number of storage quota bytes used by the file.
|
|||||||
size - Size in bytes of blobs and first party editor files.
|
size - Size in bytes of blobs and first party editor files.
|
||||||
```
|
```
|
||||||
Previously, GAM used the `size` field when totaling file sizes, it now uses the `quotaBytesUsed` field.
|
Previously, GAM used the `size` field when totaling file sizes, it now uses the `quotaBytesUsed` field.
|
||||||
The option `sizefield quotabytesused|size` allows you to select which field to use.
|
The option `sizefield quotabytesused|size` allows you to select which field to use; `quotabytesused` is the default.
|
||||||
|
|
||||||
For most MIME types, the values are the same; for the following MIME types, `quotabytesused` is larger.
|
For most MIME types, the values are the same; for the following MIME types, `quotabytesused` is larger.
|
||||||
```
|
```
|
||||||
@@ -719,7 +719,7 @@ gam <UserTypeEntity> print filecounts [todrive <ToDriveAttribute>*]
|
|||||||
[filenamematchpattern <REMatchPattern>]
|
[filenamematchpattern <REMatchPattern>]
|
||||||
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
||||||
[excludetrashed]
|
[excludetrashed]
|
||||||
[showsize] [showmimetypesize]
|
[showsize] [showsizeunits] [showmimetypesize]
|
||||||
[showlastmodification] [pathdelimiter <Character>]
|
[showlastmodification] [pathdelimiter <Character>]
|
||||||
(addcsvdata <FieldName> <String>)*
|
(addcsvdata <FieldName> <String>)*
|
||||||
[summary none|only|plus] [summaryuser <String>]
|
[summary none|only|plus] [summaryuser <String>]
|
||||||
@@ -735,7 +735,7 @@ gam <UserTypeEntity> show filecounts
|
|||||||
[filenamematchpattern <REMatchPattern>]
|
[filenamematchpattern <REMatchPattern>]
|
||||||
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
||||||
[excludetrashed]
|
[excludetrashed]
|
||||||
[showsize] [showmimetypesize]
|
[showsize] [showsizeunits] [showmimetypesize]
|
||||||
[showlastmodification] [pathdelimiter <Character>]
|
[showlastmodification] [pathdelimiter <Character>]
|
||||||
[summary none|only|plus] [summaryuser <String>]
|
[summary none|only|plus] [summaryuser <String>]
|
||||||
```
|
```
|
||||||
@@ -748,7 +748,11 @@ saying that the query is invalid when, in fact, it is but the user does not have
|
|||||||
When `continueoninvalidquery` is true, GAM prints an error message and proceeds to the next user rather that terminating
|
When `continueoninvalidquery` is true, GAM prints an error message and proceeds to the next user rather that terminating
|
||||||
as it does now. Of course, if the query really is invalid, you will get the message for every user.
|
as it does now. Of course, if the query really is invalid, you will get the message for every user.
|
||||||
|
|
||||||
The `showsize` option displays the total size (in bytes) of the files counted.
|
The `showsize` option displays the total size (in bytes) of the files counted; e.g., `31549200951`.
|
||||||
|
With `print filecounts`, this will be in a column labelled `Size`.
|
||||||
|
|
||||||
|
The `showsizeunits` option displays the total size of the files counted with two decimal places and units; e.g., `31.55 GB`.
|
||||||
|
With `print filecounts`, this will be in a column labelled `SizeUnits`.
|
||||||
|
|
||||||
The `showmimetypesize` option displays the total size (in bytes) of each MIME type counted.
|
The `showmimetypesize` option displays the total size (in bytes) of each MIME type counted.
|
||||||
|
|
||||||
@@ -1100,7 +1104,7 @@ gam <UserTypeEntity> print|show filelist [todrive <ToDriveAttribute>*]
|
|||||||
[excludetrashed]
|
[excludetrashed]
|
||||||
[maxfiles <Integer>] [nodataheaders <String>]
|
[maxfiles <Integer>] [nodataheaders <String>]
|
||||||
[countsonly [summary none|only|plus] [summaryuser <String>]
|
[countsonly [summary none|only|plus] [summaryuser <String>]
|
||||||
[showsource] [showsize] [showmimetypesize]]
|
[showsource] [showsize] [showsizeunits] [showmimetypesize]]
|
||||||
[countsrowfilter]
|
[countsrowfilter]
|
||||||
[filepath|fullpath [folderpathonly [<Boolean>]] [pathdelimiter <Character>] [addpathstojson] [showdepth]] [buildtree]
|
[filepath|fullpath [folderpathonly [<Boolean>]] [pathdelimiter <Character>] [addpathstojson] [showdepth]] [buildtree]
|
||||||
[allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)]
|
[allfields|<DriveFieldName>*|(fields <DriveFieldNameList>)]
|
||||||
@@ -1304,7 +1308,9 @@ The `summaryuser <String>` option replaces the default summary user `Summary` w
|
|||||||
|
|
||||||
The `countsonly` suboption `showsource` adds additional columns `Source` and `Name` that identify the top level folder ID and Name from which the counts are derived.
|
The `countsonly` suboption `showsource` adds additional columns `Source` and `Name` that identify the top level folder ID and Name from which the counts are derived.
|
||||||
|
|
||||||
The `countsonly` suboption `showsize` adds an additional column `Size` that indicates the total size (in bytes) of the files represented on the row.
|
The `countsonly` suboption `showsize` adds an additional column `Size` that indicates the total size (in bytes) of the files represented on the row; e.g., `31549200951`.
|
||||||
|
|
||||||
|
The `countsonly` suboption `showsizeunits` adds an additional column `SizeUnits` that indicates the total size of the files represented on the row with two decimal places and units; e.g., `31.55 GB`.
|
||||||
|
|
||||||
The `countsonly` suboption `showmimetypesize` adds additional columns `<MimeType>:Size` that indicate the total size (in bytes) of each MIME type.
|
The `countsonly` suboption `showmimetypesize` adds additional columns `<MimeType>:Size` that indicate the total size (in bytes) of each MIME type.
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
# Users - Photo
|
# Users - Photo
|
||||||
- [API documentation](#api-documentation)
|
- [API documentation](#api-documentation)
|
||||||
|
- [Notes](#notes)
|
||||||
- [Definitions](#definitions)
|
- [Definitions](#definitions)
|
||||||
- [Upload a user's photo from a default file](#upload-a-users-photo-from-a-default-file)
|
- [Upload a user's photo from a default file](#upload-a-users-photo-from-a-default-file)
|
||||||
- [Upload a user's photo specifying file name](#upload-a-users-photo-specifying-file-name)
|
- [Upload a user's photo specifying file name](#upload-a-users-photo-specifying-file-name)
|
||||||
@@ -7,11 +8,16 @@
|
|||||||
- [Upload a user's photo specifying a Google Drive owner and file name](#upload-a-users-photo-specifying-a-google-drive-owner-and-file-name)
|
- [Upload a user's photo specifying a Google Drive owner and file name](#upload-a-users-photo-specifying-a-google-drive-owner-and-file-name)
|
||||||
- [Download a user's photo](#download-a-users-photo)
|
- [Download a user's photo](#download-a-users-photo)
|
||||||
- [Delete a user's photo](#delete-a-users-photo)
|
- [Delete a user's photo](#delete-a-users-photo)
|
||||||
|
- [Update photo fails to change user's photo](#update-photo-fails-to-change-users-photo)
|
||||||
- [Download a user's profile photo](Users-Profile-Photo)
|
- [Download a user's profile photo](Users-Profile-Photo)
|
||||||
|
|
||||||
## API documentation
|
## API documentation
|
||||||
* [Directory API - Users Photos](https://developers.google.com/admin-sdk/directory/reference/rest/v1/users.photos)
|
* [Directory API - Users Photos](https://developers.google.com/admin-sdk/directory/reference/rest/v1/users.photos)
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
As of version 7.34.09, `gam <UserTypeEntity> update photo` was updated to delete the user's existing photo
|
||||||
|
before performing the update as the API update will succeed but not replace a user's existing self-set photo.
|
||||||
|
|
||||||
## Definitions
|
## Definitions
|
||||||
* [`<DriveFileEntity>`](Drive-File-Selection)
|
* [`<DriveFileEntity>`](Drive-File-Selection)
|
||||||
* [`<UserTypeEntity>`](Collections-of-Users)
|
* [`<UserTypeEntity>`](Collections-of-Users)
|
||||||
@@ -81,3 +87,7 @@ By default, the Base64 encoded data is dumped to stdout.
|
|||||||
```
|
```
|
||||||
gam <UserTypeEntity> delete|del photo
|
gam <UserTypeEntity> delete|del photo
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Update photo fails to change user's photo
|
||||||
|
If you use `gam <UserTypeEntity> update photo ...` to change a user's photo and the command succeeds
|
||||||
|
but the photo doesn't change, use `gam <UserTypeEntity> delete photo` first and then do the update.
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
- [Print user list](#print-user-list)
|
- [Print user list](#print-user-list)
|
||||||
- [Display user counts](#display-user-counts)
|
- [Display user counts](#display-user-counts)
|
||||||
- [Verify domain membership](#verify-domain-membership)
|
- [Verify domain membership](#verify-domain-membership)
|
||||||
|
- [Guest Users](#guest-users)
|
||||||
|
|
||||||
## API documentation
|
## API documentation
|
||||||
* [Directory API - Users](https://developers.google.com/admin-sdk/directory/reference/rest/v1/users)
|
* [Directory API - Users](https://developers.google.com/admin-sdk/directory/reference/rest/v1/users)
|
||||||
@@ -169,6 +170,7 @@ queries "`"orgUnitPath=\'/Students/Lower\ School/2027\'`",`"orgUnitPath=\'/Stude
|
|||||||
fullname|
|
fullname|
|
||||||
gender|
|
gender|
|
||||||
givenname|firstname|
|
givenname|firstname|
|
||||||
|
guestaccountinfo|
|
||||||
id|
|
id|
|
||||||
ims|im|
|
ims|im|
|
||||||
includeinglobaladdresslist|gal|
|
includeinglobaladdresslist|gal|
|
||||||
@@ -176,6 +178,7 @@ queries "`"orgUnitPath=\'/Students/Lower\ School/2027\'`",`"orgUnitPath=\'/Stude
|
|||||||
isdelegatedadmin|admin|isadmin|
|
isdelegatedadmin|admin|isadmin|
|
||||||
isenforcedin2sv|is2svenforced|
|
isenforcedin2sv|is2svenforced|
|
||||||
isenrolledin2sv|is2svenrolled|
|
isenrolledin2sv|is2svenrolled|
|
||||||
|
isguestuser|
|
||||||
ismailboxsetup|
|
ismailboxsetup|
|
||||||
keyword|keywords|
|
keyword|keywords|
|
||||||
language|languages|
|
language|languages|
|
||||||
@@ -326,6 +329,20 @@ You can remove all instances of a `<UserMultiAttribute>` with `<UserClearAttribu
|
|||||||
<UserMultiAttribute>|
|
<UserMultiAttribute>|
|
||||||
<UserClearAttribute>
|
<UserClearAttribute>
|
||||||
```
|
```
|
||||||
|
```
|
||||||
|
<UserMultiAttributeFilterName> ::=
|
||||||
|
address|addresses|
|
||||||
|
externalid|externalids|
|
||||||
|
im|ims|
|
||||||
|
keyword|keywords|
|
||||||
|
location|locations|
|
||||||
|
orgainzation|organizations|
|
||||||
|
otheremail|otheremails|
|
||||||
|
phone|phones|
|
||||||
|
relation|relations|
|
||||||
|
website|websites
|
||||||
|
```
|
||||||
|
|
||||||
## Admin Console User Info
|
## Admin Console User Info
|
||||||
When defining a user in the admin console, there is a section labelled `Employee information` with the following items:
|
When defining a user in the admin console, there is a section labelled `Employee information` with the following items:
|
||||||
* `Employee ID`
|
* `Employee ID`
|
||||||
@@ -968,6 +985,8 @@ gam info user [<UserItem>]
|
|||||||
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
||||||
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
|
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
|
||||||
[userview] <UserFieldName>* [fields <UserFieldNameList>]
|
[userview] <UserFieldName>* [fields <UserFieldNameList>]
|
||||||
|
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
|
||||||
|
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
|
||||||
[formatjson]
|
[formatjson]
|
||||||
```
|
```
|
||||||
### Display information about multiple users
|
### Display information about multiple users
|
||||||
@@ -981,6 +1000,8 @@ gam info users <UserTypeEntity>
|
|||||||
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
||||||
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
|
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
|
||||||
[userview] <UserFieldName>* [fields <UserFieldNameList>]
|
[userview] <UserFieldName>* [fields <UserFieldNameList>]
|
||||||
|
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
|
||||||
|
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
|
||||||
[formatjson]
|
[formatjson]
|
||||||
gam <UserTypeEntity> info users
|
gam <UserTypeEntity> info users
|
||||||
[quick]
|
[quick]
|
||||||
@@ -991,6 +1012,8 @@ gam <UserTypeEntity> info users
|
|||||||
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
||||||
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
|
[noschemas|allschemas|(schemas|custom|customschemas <SchemaNameList>)]
|
||||||
[userview] <UserFieldName>* [fields <UserFieldNameList>]
|
[userview] <UserFieldName>* [fields <UserFieldNameList>]
|
||||||
|
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
|
||||||
|
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
|
||||||
[formatjson]
|
[formatjson]
|
||||||
```
|
```
|
||||||
For `info users`, unlike all other GAM commands, a `<UserTypeEntity>` value of `all users` is actually `all users_ns_susp` not `all users_ns`.
|
For `info users`, unlike all other GAM commands, a `<UserTypeEntity>` value of `all users` is actually `all users_ns_susp` not `all users_ns`.
|
||||||
@@ -1028,6 +1051,11 @@ By default, Gam displays fields that only an adminstrator can view.
|
|||||||
By default, Gam displays all fields for a user.
|
By default, Gam displays all fields for a user.
|
||||||
* `<UserFieldName>* [fields <UserFieldNameList>]` - Only display selected fields.
|
* `<UserFieldName>* [fields <UserFieldNameList>]` - Only display selected fields.
|
||||||
|
|
||||||
|
By default, all instances of `<UserMultiAttribute>` are displayed, use these options to only display instances
|
||||||
|
of a specified `type` or `customType`.
|
||||||
|
* `filtermultiattrtype <UserMultiAttributeFilterName> <String>` - Display `<UserMultiAttributeFilterName>` if its `type` is `<String>`
|
||||||
|
* `filtermultiattrcustom <UserMultiAttributeFilterName> <String>` - Display `<UserMultiAttributeFilterName>` if its `customType` is `<String>`
|
||||||
|
|
||||||
By default, Gam displays the information as an indented list of keys and values.
|
By default, Gam displays the information as an indented list of keys and values.
|
||||||
* `formatjson` - Display the fields in JSON format.
|
* `formatjson` - Display the fields in JSON format.
|
||||||
|
|
||||||
@@ -1059,6 +1087,8 @@ gam print users [todrive <ToDriveAttribute>*]
|
|||||||
[schemas|custom|customschemas all|<SchemaNameList>]
|
[schemas|custom|customschemas all|<SchemaNameList>]
|
||||||
[emailpart|emailparts|username]
|
[emailpart|emailparts|username]
|
||||||
[userview] [allfields|basic|full|(<UserFieldName>*|fields <UserFieldNameList>)]
|
[userview] [allfields|basic|full|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||||
|
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
|
||||||
|
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
|
||||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||||
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
|
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
|
||||||
@@ -1085,6 +1115,8 @@ gam print users [todrive <ToDriveAttribute>*] select <UserTypeEntity>
|
|||||||
[schemas|custom|customschemas all|<SchemaNameList>]
|
[schemas|custom|customschemas all|<SchemaNameList>]
|
||||||
[emailpart|emailparts|username]
|
[emailpart|emailparts|username]
|
||||||
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||||
|
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
|
||||||
|
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
|
||||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||||
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
|
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
|
||||||
@@ -1099,6 +1131,8 @@ gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
|||||||
[schemas|custom|customschemas all|<SchemaNameList>]
|
[schemas|custom|customschemas all|<SchemaNameList>]
|
||||||
[emailpart|emailparts|username]
|
[emailpart|emailparts|username]
|
||||||
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||||
|
(filtermultiattrtype <UserMultiAttributeFilterName> <String>)*
|
||||||
|
(filtermultiattrcustom <UserMultiAttributeFilterName> <String>)*
|
||||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||||
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
|
[issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
|
||||||
@@ -1134,6 +1168,11 @@ By default, Gam displays only the primary email address for each user.
|
|||||||
* `schemas|custom all` - Display custom schema information for all schemas.
|
* `schemas|custom all` - Display custom schema information for all schemas.
|
||||||
* `schemas|custom <SchemaNameList>` - Display all fields or selected fields of the specified custom schemas
|
* `schemas|custom <SchemaNameList>` - Display all fields or selected fields of the specified custom schemas
|
||||||
|
|
||||||
|
By default, all instances of `<UserMultiAttribute>` are displayed, use these options to only display instances
|
||||||
|
of a specified `type` or `customType`.
|
||||||
|
* `filtermultiattrtype <UserMultiAttributeFilterName> <String>` - Display `<UserMultiAttributeFilterName>` if its `type` is `<String>`
|
||||||
|
* `filtermultiattrcustom <UserMultiAttributeFilterName> <String>` - Display `<UserMultiAttributeFilterName>` if its `customType` is `<String>`
|
||||||
|
|
||||||
By default, when aliases are displayed, all aliases are displayed. Use `aliasmatchpattern <REMatchPattern>`
|
By default, when aliases are displayed, all aliases are displayed. Use `aliasmatchpattern <REMatchPattern>`
|
||||||
to limit the display of aliases to those that match `<REMatchPattern>`.
|
to limit the display of aliases to those that match `<REMatchPattern>`.
|
||||||
|
|
||||||
@@ -1384,3 +1423,11 @@ testuser1@domain.com,118080758787650801331,True,Test User 1
|
|||||||
testuserxxx@domain.com,,False,Test User XXX
|
testuserxxx@domain.com,,False,Test User XXX
|
||||||
testuser2@domain.com,107344800159717682514,True,Test User 2
|
testuser2@domain.com,107344800159717682514,True,Test User 2
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Guest Users
|
||||||
|
* See: https://support.google.com/a/answer/16558545
|
||||||
|
```
|
||||||
|
gam create guestuser <EmailAddress>
|
||||||
|
```
|
||||||
|
|
||||||
|
Guest users are in the OU "/Workspace guests".
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ It's important to confirm you are always running an official GAM7 release. The f
|
|||||||
# GitHub Attestation (Linux/MacOS/Windows)
|
# GitHub Attestation (Linux/MacOS/Windows)
|
||||||
GitHub offers [artifict attestations](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds) which prove if a given GAM binary or archive was built by the [GAM-team/GAM](https://gitHub.com/GAM-team/GAM) project and links to the build job. This offers you certainty that the GAM executable you are running or the GAM package you downloaded were officially generated by the [GAM-team/GAM](https://gitHub.com/GAM-team/GAM) project.
|
GitHub offers [artifict attestations](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds) which prove if a given GAM binary or archive was built by the [GAM-team/GAM](https://gitHub.com/GAM-team/GAM) project and links to the build job. This offers you certainty that the GAM executable you are running or the GAM package you downloaded were officially generated by the [GAM-team/GAM](https://gitHub.com/GAM-team/GAM) project.
|
||||||
|
|
||||||
To verify a given GAM executable file or package (.zip, .msi or .tar.xz) is legitimate, use the following steps:
|
To verify a given GAM executable file or package (.zip, .exe or .tar.xz) is legitimate, use the following steps:
|
||||||
1. Install the [GitHub CLI command line tool](https://github.com/cli/cli#installation).
|
1. Install the [GitHub CLI command line tool](https://github.com/cli/cli#installation).
|
||||||
2. Login to the tool with the command. You need a [free GitHub account](https://gitHub.com/join) for this.
|
2. Login to the tool with the command. You need a [free GitHub account](https://gitHub.com/join) for this.
|
||||||
```
|
```
|
||||||
@@ -27,7 +27,7 @@ gh attestation verify --repo GAM-team/GAM --format=json \
|
|||||||
|
|
||||||
4. If the GAM file or package is legit you'll see output like:
|
4. If the GAM file or package is legit you'll see output like:
|
||||||
```
|
```
|
||||||
Loaded digest sha256:a63dc5e71c0b3335865877fc7dc9248bbf7481d22995c18253a2ae71fcb9793a for file://gam-7.00.00-windows-x86_64.msi
|
Loaded digest sha256:a63dc5e71c0b3335865877fc7dc9248bbf7481d22995c18253a2ae71fcb9793a for file://gam-7.00.00-windows-x86_64.exe
|
||||||
Loaded 1 attestation from GitHub API
|
Loaded 1 attestation from GitHub API
|
||||||
✓ Verification succeeded!
|
✓ Verification succeeded!
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ origin=Developer ID Application: Jay Lee (GZ85H2DRLM)
|
|||||||
If you do not see "accepted" and "Jay Lee" as the developer ID, there may be a problem. Please report any suspicious files or concerns to the [GAM Group](https://groups.google.com/g/google-apps-manager) or the [GAM Chat Space](https://git.io/gam-chat).
|
If you do not see "accepted" and "Jay Lee" as the developer ID, there may be a problem. Please report any suspicious files or concerns to the [GAM Group](https://groups.google.com/g/google-apps-manager) or the [GAM Chat Space](https://git.io/gam-chat).
|
||||||
|
|
||||||
# Windows Code Sign
|
# Windows Code Sign
|
||||||
On Windows, Official gam.exe files and MSI installer packages are signed by a [Certum Open Source code signing certificate](https://shop.certum.eu/open-source-code-signing.html). You can validate the signature and thus be sure you are running official GAM7 from the command line and GUI:
|
On Windows, Official gam.exe files and EXE installer packages are signed by a [Certum Open Source code signing certificate](https://shop.certum.eu/open-source-code-signing.html). You can validate the signature and thus be sure you are running official GAM7 from the command line and GUI:
|
||||||
|
|
||||||
# Command Line
|
# Command Line
|
||||||
From PowerShell, run the following command:
|
From PowerShell, run the following command:
|
||||||
@@ -113,6 +113,6 @@ SignerCertificate : [Subject]
|
|||||||
confirm that status is "Valid" and the SignerCertificate says "Open Source Developer, James Lee" (yes, James is Jay's legal name, now you know).
|
confirm that status is "Valid" and the SignerCertificate says "Open Source Developer, James Lee" (yes, James is Jay's legal name, now you know).
|
||||||
|
|
||||||
## GUI
|
## GUI
|
||||||
From File Manager, you can right click on gam.exe or the MSI package and go to the Digital Signatures tab. From there you'll see the signing certificate which should show "Open Source Developer, James Lee".
|
From File Manager, you can right click on gam.exe or the EXE installer package and go to the Digital Signatures tab. From there you'll see the signing certificate which should show "Open Source Developer, James Lee".
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
Print the current version of Gam with details
|
Print the current version of Gam with details
|
||||||
```
|
```
|
||||||
gam version
|
gam version
|
||||||
GAM 7.34.05 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.36.03 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.14.3 64-bit final
|
Python 3.14.3 64-bit final
|
||||||
macOS Tahoe 26.3 arm64
|
macOS Tahoe 26.3.1 arm64
|
||||||
Path: /Users/gamteam/bin/gam7
|
Path: /Users/gamteam/bin/gam7
|
||||||
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
Time: 2026-02-15T07:51:00-08:00
|
Time: 2026-02-15T07:51:00-08:00
|
||||||
@@ -15,10 +15,10 @@ Time: 2026-02-15T07:51:00-08:00
|
|||||||
Print the current version of Gam with details and time offset information
|
Print the current version of Gam with details and time offset information
|
||||||
```
|
```
|
||||||
gam version timeoffset
|
gam version timeoffset
|
||||||
GAM 7.34.05 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.36.03 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.14.3 64-bit final
|
Python 3.14.3 64-bit final
|
||||||
macOS Tahoe 26.3 arm64
|
macOS Tahoe 26.3.1 arm64
|
||||||
Path: /Users/gamteam/bin/gam7
|
Path: /Users/gamteam/bin/gam7
|
||||||
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
Your system time differs from www.googleapis.com by less than 1 second
|
Your system time differs from www.googleapis.com by less than 1 second
|
||||||
@@ -27,10 +27,10 @@ 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
|
Print the current version of Gam with extended details and SSL information
|
||||||
```
|
```
|
||||||
gam version extended
|
gam version extended
|
||||||
GAM 7.34.05 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.36.03 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.14.3 64-bit final
|
Python 3.14.3 64-bit final
|
||||||
macOS Tahoe 26.3 arm64
|
macOS Tahoe 26.3.1 arm64
|
||||||
Path: /Users/gamteam/bin/gam7
|
Path: /Users/gamteam/bin/gam7
|
||||||
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
Time: 2026-02-15T07:51:00-08:00
|
Time: 2026-02-15T07:51:00-08:00
|
||||||
@@ -68,7 +68,7 @@ MacOS High Sierra 10.13.6 x86_64
|
|||||||
Path: /Users/gamteam/bin/gam7
|
Path: /Users/gamteam/bin/gam7
|
||||||
Version Check:
|
Version Check:
|
||||||
Current: 5.35.08
|
Current: 5.35.08
|
||||||
Latest: 7.34.05
|
Latest: 7.36.03
|
||||||
echo $?
|
echo $?
|
||||||
1
|
1
|
||||||
```
|
```
|
||||||
@@ -76,7 +76,7 @@ echo $?
|
|||||||
Print the current version number without details
|
Print the current version number without details
|
||||||
```
|
```
|
||||||
gam version simple
|
gam version simple
|
||||||
7.34.05
|
7.36.03
|
||||||
```
|
```
|
||||||
In Linux/MacOS you can do:
|
In Linux/MacOS you can do:
|
||||||
```
|
```
|
||||||
@@ -86,10 +86,10 @@ echo $VER
|
|||||||
Print the current version of Gam and address of this Wiki
|
Print the current version of Gam and address of this Wiki
|
||||||
```
|
```
|
||||||
gam help
|
gam help
|
||||||
GAM 7.34.05 - https://github.com/GAM-team/GAM
|
GAM 7.36.03 - https://github.com/GAM-team/GAM
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.14.3 64-bit final
|
Python 3.14.3 64-bit final
|
||||||
macOS Tahoe 26.3 arm64
|
macOS Tahoe 26.3.1 arm64
|
||||||
Path: /Users/gamteam/bin/gam7
|
Path: /Users/gamteam/bin/gam7
|
||||||
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
Time: 2026-02-15T07:51:00-08:00
|
Time: 2026-02-15T07:51:00-08:00
|
||||||
|
|||||||
Reference in New Issue
Block a user