mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-28 18:01:36 +00:00
Added support for Gmail Client Side Encryption
This commit is contained in:
@@ -10,6 +10,19 @@ Add the `-s` option to the end of the above commands to suppress creating the `g
|
||||
|
||||
See [Downloads](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads) for Windows or other options, including manual installation
|
||||
|
||||
### 6.70.01
|
||||
|
||||
Added `gmail_cse_incert_dir` and `gmail_cse_inkey_dir` path variables to `gam.cfg` that provide
|
||||
default values for the `incertdir <FilePath>` and `inkeydir <FilePath>` options in `gam <UserTypeEntity> create csekeypair`.
|
||||
|
||||
### 6.70.00
|
||||
|
||||
Added support for Gmail Client Side Encryption.
|
||||
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-Gmail-CSE
|
||||
|
||||
This is an initial, minimally tested release; proceed with care and report all issues.
|
||||
|
||||
### 6.69.00
|
||||
|
||||
Added `use_classroom_owner_access` Boolean variable to `gam.cfg` that controls how GAM gets
|
||||
|
||||
@@ -334,7 +334,7 @@ writes the credentials into the file oauth2.txt.
|
||||
admin@server:/Users/admin/bin/gamadv-xtd3$ rm -f /Users/admin/GAMConfig/oauth2.txt
|
||||
admin@server:/Users/admin/bin/gamadv-xtd3$ ./gam version
|
||||
WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
|
||||
GAMADV-XTD3 6.69.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.70.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.2 64-bit final
|
||||
MacOS Sonoma 14.2.1 x86_64
|
||||
@@ -1002,7 +1002,7 @@ writes the credentials into the file oauth2.txt.
|
||||
C:\GAMADV-XTD3>del C:\GAMConfig\oauth2.txt
|
||||
C:\GAMADV-XTD3>gam version
|
||||
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
|
||||
GAMADV-XTD3 6.69.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.70.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.2 64-bit final
|
||||
Windows-10-10.0.17134 AMD64
|
||||
|
||||
@@ -573,7 +573,7 @@ The `querytime<String> <Time>` value replaces the string `#querytime<String>#` i
|
||||
The characters following `querytime` can be any combination of lowercase letters and numbers. This is most useful in scripts
|
||||
where you can specify a relative date without having to change the script.
|
||||
|
||||
For example, query for files last modified me than 5 years ago:
|
||||
For example, query for files last modified more than 5 years ago:
|
||||
```
|
||||
querytime5years -5y query "modifiedTime<'#querytime5years#'"
|
||||
```
|
||||
|
||||
197
docs/Users-Gmail-CSE.md
Normal file
197
docs/Users-Gmail-CSE.md
Normal file
@@ -0,0 +1,197 @@
|
||||
# Users - Gmail - Client Side Encryption
|
||||
- [API documentation](#api-documentation)
|
||||
- [Notes](#notes)
|
||||
- [Definitions](#definitions)
|
||||
- [Create Gmail CSE Identity](#create-gmail-cse-identity)
|
||||
- [Update Gmail CSE Identity](#update-gmail-cse-identity)
|
||||
- [Delete Gmail CSE Identity](#delete-gmail-cse-identity)
|
||||
- [Display Gmail CSE Identities](#display-gmail-cse-identities)
|
||||
- [Create Gmail CSE Key Pair](#create-gmail-cse-key-pair)
|
||||
- [Action Gmail CSE Key Pairs](#action-gmail-cse-key-pairs)
|
||||
- [Display Gmail CSE Key Pairs](#display-gmail-cse-key-pairs)
|
||||
|
||||
## API documentation
|
||||
* https://developers.google.com/gmail/api/reference/rest/v1/users.settings.cse.identities
|
||||
* https://developers.google.com/gmail/api/reference/rest/v1/users.settings.cse.keypairs
|
||||
|
||||
## Notes
|
||||
|
||||
This is an initial, minimally tested release; proceed with care and report all issues.
|
||||
|
||||
Setting up Client Side Encryption is not for the faint of heart; here is a start.
|
||||
* https://support.google.com/a/answer/10741897?hl=en&ref_topic=10742486&sjid=10342493441460488213-NA
|
||||
|
||||
Do I personally understand what's going on here? No, I just added the API calls to GAM.
|
||||
|
||||
Two sets of files are required for Gmail CSE, these two variables in `gam.cfg` control where GAM looks for these files.
|
||||
You must edit `gam.cfg` to set the paths you currently use.
|
||||
```
|
||||
gmail_cse_incert_dir
|
||||
Directory for the S/MIME certificate files used by Gmail Client Side Encryption.
|
||||
Default: Blank
|
||||
gmail_cse_inkey_dir
|
||||
Directory for the Key Access Control List (KACL) wrapped private key data files used by Gmail Client Side Encryption.
|
||||
Default: Blank
|
||||
```
|
||||
|
||||
## Definitions
|
||||
* [`<UserTypeEntity>`](Collections-of-Users)
|
||||
|
||||
```
|
||||
<DomainName> ::= <String>(.<String>)+
|
||||
<EmailAddress> ::= <String>@<DomainName>
|
||||
<FilePath> ::= <String>
|
||||
<Password> ::= <String>
|
||||
<KeyPairID> ::= <String>
|
||||
```
|
||||
## Create Gmail CSE Identity
|
||||
Creates and configures a client-side encryption identity that's authorized to send mail from the user account.
|
||||
Google publishes the S/MIME certificate to a shared domain-wide directory so that people within a Google Workspace organization can encrypt and send mail to the identity.
|
||||
|
||||
```
|
||||
gam <UserTypeEntity> create cseidentity <KeyPairID> [kpemail <EmailAddress>]
|
||||
[formatjson]
|
||||
```
|
||||
If `kpemail <EmailAddress>` is not specified, the user's primary email address is used for the identity.
|
||||
|
||||
By default, Gam displays the identity as an indented list of keys and values; the following option causes the output to be in JSON format:
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
|
||||
## Update Gmail CSE Identity
|
||||
Associates a different key pair with an existing client-side encryption identity. The updated key pair must validate against Google's S/MIME certificate profiles.
|
||||
```
|
||||
gam <UserTypeEntity> update cseidentity <KeyPairID> [kpemail <EmailAddress>]
|
||||
[formatjson]
|
||||
```
|
||||
If `kpemail <EmailAddress>` is not specified, the key pair for the user's primary email address is identity updated.
|
||||
|
||||
By default, Gam displays the identity as an indented list of keys and values; the following option causes the output to be in JSON format:
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
|
||||
## Delete Gmail CSE Identity
|
||||
Deletes a client-side encryption identity. The authenticated user can no longer use the identity to send encrypted messages.
|
||||
You cannot restore the identity after you delete it. Instead, use the `create cseidentity` to create another identity with the same configuration.
|
||||
|
||||
```
|
||||
gam <UserTypeEntity> delete cseidentity [kpemail <EmailAddress>]
|
||||
```
|
||||
If `kpemail <EmailAddress>` is not specified, the identity for the user's primary email address is deleted.
|
||||
|
||||
## Display Gmail CSE Identities
|
||||
### Display a client-side encryption identity configuration.
|
||||
```
|
||||
gam <UserTypeEntity> info cseidentity [kpemail <EmailAddress>]
|
||||
[formatjson]
|
||||
```
|
||||
If `kpemail <EmailAddress>` is not specified, the user's primary email address is used for the identity.
|
||||
|
||||
|
||||
### Display all of the client-side encrypted identities for an authenticated user.
|
||||
```
|
||||
gam <UserTypeEntity> show cseidentities
|
||||
[formatjson]
|
||||
```
|
||||
By default, Gam displays the identity as an indented list of keys and values; the following option causes the output to be in JSON format:
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
|
||||
```
|
||||
gam <UserTypeEntity> print cseidentities [todrive <ToDriveAttribute>*]
|
||||
[formatjson [quotechar <Character>]]
|
||||
```
|
||||
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format:
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
|
||||
By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain
|
||||
the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled.
|
||||
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
|
||||
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
|
||||
|
||||
## Create Gmail CSE Key Pair
|
||||
Create a CSE Key Pair for the primary address of a user.
|
||||
```
|
||||
gam <UserTypeEntity> create csekeypair
|
||||
[incertdir <FilePath>] [inkeydir <FilePath>]
|
||||
[addidentity [<Boolean>]] [kpemail <EmailAddress>]
|
||||
[formatjson|returnidonly]
|
||||
```
|
||||
* The S/MIME certificate files for the users are in the `incertdir <FilePath>` folder/directory.
|
||||
* If this option is not specified, the directory is taken from `gam.cfg/gmail_cse_incert_dir`.
|
||||
* The files must be named `user@domain.com.p7pem`.
|
||||
* The certificate contains the public key and its certificate chain. The chain must be in PKCS#7 format and use PEM encoding and ASCII armor.
|
||||
|
||||
* The Key Access Control List (KACL) wrapped private key data files are in the `inkeydir <FilePath>` folder/directory.
|
||||
* If this option is not specified, the directory is taken from `gam.cfg/gmail_cse_inkey_dir`.
|
||||
* The files must be named `user@domain.com.wrap`.
|
||||
* The files are in JSON format with two keys:
|
||||
* `kacls_url` - The URI of the key access control list service that manages the private key.
|
||||
* `wrapped_private_key` - Opaque data generated and used by the key access control list service.
|
||||
|
||||
By default, Gam displays the new key pair as an indented list of keys and values; the following options cause the output to be displayed in alternate forms.
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
* `returnidonly` - Display just the new `<KeyPairID>`.
|
||||
|
||||
If 'addidentity` or `addidentity true` is specified, a client-side encryption identity is created with the new key pair.
|
||||
If `kpemail <EmailAddress>` is not specified, the user's primary email address is used for the identity.
|
||||
|
||||
By default, Gam displays the identity as an indented list of keys and values; the following option causes the output to be in JSON format:
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
* `returnidonly` - Display just the new `<KeyPairID>-<EmailAddress>`.
|
||||
|
||||
|
||||
## Action Gmail CSE Key Pairs
|
||||
### Disable
|
||||
Turns off a client-side encryption key pair. The authenticated user can no longer use the key pair to decrypt incoming CSE message texts or sign outgoing CSE mail.
|
||||
```
|
||||
gam <UserTypeEntity> disable csekeypair <KeyPairID>
|
||||
[formatjson]
|
||||
```
|
||||
By default, Gam displays the disabled key pair as an indented list of keys and values; the following option causes the output to be displayed in alternate forms.
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
|
||||
### Enable
|
||||
Turn on a client-side encryption key pair that was turned off. The key pair becomes active again for any associated client-side encryption identities.
|
||||
```
|
||||
gam <UserTypeEntity> ensable csekeypair <KeyPairID>
|
||||
[formatjson]
|
||||
```
|
||||
By default, Gam displays the enabled key pair as an indented list of keys and values; the following option causes the output to be displayed in alternate forms.
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
|
||||
### Obliterate
|
||||
Delete a client-side encryption key pair permanently and immediately. You can only permanently delete key pairs that have been turned off for more than 30 days.
|
||||
To turn off a key pair, use `disable csekeypair`.
|
||||
```
|
||||
gam <UserTypeEntity> obliterate csekeypair <KeyPairID>
|
||||
```
|
||||
|
||||
Gmail can't restore or decrypt any messages that were encrypted by an obliterated key. Authenticated users and Google Workspace administrators lose access to reading the encrypted messages.
|
||||
|
||||
## Display Gmail CSE Key Pairs
|
||||
### Display an existing client-side encryption key pair.
|
||||
```
|
||||
gam <UserTypeEntity> info csekeypair <KeyPairID>
|
||||
[formatjson]
|
||||
```
|
||||
By default, Gam displays the key pairs as an indented list of keys and values; the following option causes the output to be in JSON format:
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
|
||||
|
||||
### Display all client-side encryption key pairs for an authenticated user.
|
||||
```
|
||||
gam <UserTypeEntity> show csekeypairs
|
||||
[formatjson]
|
||||
```
|
||||
By default, Gam displays the key pairs as an indented list of keys and values; the following option causes the output to be in JSON format:
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
|
||||
```
|
||||
gam <UserTypeEntity> print csekeypairs [todrive <ToDriveAttribute>*]
|
||||
[formatjson [quotechar <Character>]]
|
||||
```
|
||||
By default, Gam displays the key pairs as columns of fields; the following option causes the output to be in JSON format:
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
|
||||
By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain
|
||||
the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled.
|
||||
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
|
||||
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
|
||||
@@ -3,7 +3,7 @@
|
||||
Print the current version of Gam with details
|
||||
```
|
||||
gam version
|
||||
GAMADV-XTD3 6.69.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.70.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.2 64-bit final
|
||||
MacOS Sonoma 14.2.1 x86_64
|
||||
@@ -15,7 +15,7 @@ Time: 2023-06-02T21:10:00-07:00
|
||||
Print the current version of Gam with details and time offset information
|
||||
```
|
||||
gam version timeoffset
|
||||
GAMADV-XTD3 6.69.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.70.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.2 64-bit final
|
||||
MacOS Sonoma 14.2.1 x86_64
|
||||
@@ -27,7 +27,7 @@ Your system time differs from www.googleapis.com by less than 1 second
|
||||
Print the current version of Gam with extended details and SSL information
|
||||
```
|
||||
gam version extended
|
||||
GAMADV-XTD3 6.69.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.70.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.2 64-bit final
|
||||
MacOS Sonoma 14.2.1 x86_64
|
||||
@@ -64,7 +64,7 @@ MacOS High Sierra 10.13.6 x86_64
|
||||
Path: /Users/Admin/bin/gamadv-xtd3
|
||||
Version Check:
|
||||
Current: 5.35.08
|
||||
Latest: 6.69.00
|
||||
Latest: 6.70.00
|
||||
echo $?
|
||||
1
|
||||
```
|
||||
@@ -72,7 +72,7 @@ echo $?
|
||||
Print the current version number without details
|
||||
```
|
||||
gam version simple
|
||||
6.69.00
|
||||
6.70.00
|
||||
```
|
||||
In Linux/MacOS you can do:
|
||||
```
|
||||
@@ -82,7 +82,7 @@ echo $VER
|
||||
Print the current version of Gam and address of this Wiki
|
||||
```
|
||||
gam help
|
||||
GAM 6.69.00 - https://github.com/taers232c/GAMADV-XTD3
|
||||
GAM 6.70.00 - https://github.com/taers232c/GAMADV-XTD3
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.2 64-bit final
|
||||
MacOS Sonoma 14.2.1 x86_64
|
||||
|
||||
@@ -141,6 +141,7 @@ Service Account Access
|
||||
* [Users - Drive - Shortcuts](Users-Drive-Shortcuts)
|
||||
* [Users - Drive - Transfer](Users-Drive-Transfer)
|
||||
* [Users - Forms](Users-Forms)
|
||||
* [Users - Gmail - Client Side Encryption](Users-Gmail-CSE)
|
||||
* [Users - Gmail - Delegates](Users-Gmail-Delegates)
|
||||
* [Users - Gmail - Filters](Users-Gmail-Filters)
|
||||
* [Users - Gmail - Forwarding](Users-Gmail-Forwarding)
|
||||
|
||||
@@ -322,6 +322,12 @@ extra_args
|
||||
Path to extra_args.txt
|
||||
Default: Blank
|
||||
Data file: extra_args.txt
|
||||
gmail_cse_incert_dir
|
||||
Directory for the S/MIME certificate files used by Gmail Client Side Encryption.
|
||||
Default: Blank
|
||||
gmail_cse_inkey_dir
|
||||
Directory for the Key Access Control List (KACL) wrapped private key data files used by Gmail Client Side Encryption.
|
||||
Default: Blank
|
||||
inter_batch_wait
|
||||
When processing items in batches, how many seconds should GAM wait between batches
|
||||
Default: 0
|
||||
|
||||
@@ -7126,6 +7126,15 @@ gam <UserTypeEntity> show signature|sig [compact|format|html]
|
||||
gam <UserTypeEntity> print signature [compact]
|
||||
[primary|default] [verifyonly] [todrive <ToDriveAttribute>*]
|
||||
|
||||
gam <UserTypeEntity> vacation <Boolean> subject <String>
|
||||
[<VacationMessageContent> (replace <Tag> <UserReplacement>)*]
|
||||
[html [<Boolean>]] [contactsonly [<Boolean>]] [domainonly [<Boolean>]]
|
||||
[start|startdate <Date>|Started] [end|enddate <Date>|NotSpecified]
|
||||
gam <UserTypeEntity> show vacation [compact|format|html] [enabledonly]
|
||||
gam <UserTypeEntity> print vacation [compact] [enabledonly] [todrive <ToDriveAttribute>*]
|
||||
|
||||
# Users - Gmail - S/MIME
|
||||
|
||||
gam <UserTypeEntity> create|add smime file <FileName> [password <Password>]
|
||||
[sendas|sendasemail <EmailAddress>] [default]
|
||||
gam <UserTypeEntity> update smime default
|
||||
@@ -7137,12 +7146,37 @@ gam <UserTypeEntity> show smimes
|
||||
gam <UserTypeEntity> print smimes [todrive <ToDriveAttribute>*]
|
||||
[primary|default|(sendas|sendasemail <EmailAddress>)]
|
||||
|
||||
gam <UserTypeEntity> vacation <Boolean> subject <String>
|
||||
[<VacationMessageContent> (replace <Tag> <UserReplacement>)*]
|
||||
[html [<Boolean>]] [contactsonly [<Boolean>]] [domainonly [<Boolean>]]
|
||||
[start|startdate <Date>|Started] [end|enddate <Date>|NotSpecified]
|
||||
gam <UserTypeEntity> show vacation [compact|format|html] [enabledonly]
|
||||
gam <UserTypeEntity> print vacation [compact] [enabledonly] [todrive <ToDriveAttribute>*]
|
||||
# Users - Gmail Client Side Encryption
|
||||
|
||||
gam <UserTypeEntity> create cseidentity <KeyPairID> [kpemail <EmailAddress>]
|
||||
[formatjson]
|
||||
gam <UserTypeEntity> update cseidentity <KeyPairID> [kpemail <EmailAddress>]
|
||||
[formatjson]
|
||||
gam <UserTypeEntity> delete cseidentity [kpemail <EmailAddress>]
|
||||
|
||||
gam <UserTypeEntity> info cseidentity [kpemail <EmailAddress>]
|
||||
[formatjson]
|
||||
gam <UserTypeEntity> show cseidentities
|
||||
[formatjson]
|
||||
gam <UserTypeEntity> print cseidentities [todrive <ToDriveAttribute>*]
|
||||
[formatjson [quotechar <Character>]]
|
||||
|
||||
gam <UserTypeEntity> create csekeypair
|
||||
[incertdir <FilePath>] [inkeydir <FilePath>]
|
||||
[addidentity [<Boolean>]] [kpemail <EmailAddress>]
|
||||
[formatjson|returnidonly]
|
||||
gam <UserTypeEntity> disable csekeypair <KeyPairID>
|
||||
[formatjson]
|
||||
gam <UserTypeEntity> enable csekeypair <KeyPairID>
|
||||
[formatjson]
|
||||
gam <UserTypeEntity> obliterate csekeypair <KeyPairID>
|
||||
|
||||
gam <UserTypeEntity> info csekeypair <KeyPairID>
|
||||
[formatjson]
|
||||
gam <UserTypeEntity> show csekeypairs
|
||||
[formatjson]
|
||||
gam <UserTypeEntity> print csekeypairs [todrive <ToDriveAttribute>*]
|
||||
[formatjson [quotechar <Character>]]
|
||||
|
||||
# Users - Gmail - Settings
|
||||
|
||||
|
||||
@@ -2,7 +2,20 @@
|
||||
|
||||
Merged GAM-Team version
|
||||
|
||||
6.69.00
|
||||
6.70.01
|
||||
|
||||
Added `gmail_cse_incert_dir` and `gmail_cse_inkey_dir` path variables to `gam.cfg` that provide
|
||||
default values for the `incertdir <FilePath>` and `inkeydir <FilePath>` options in `gam <UserTypeEntity> create csekeypair`.
|
||||
|
||||
6.70.00
|
||||
|
||||
Added support for Gmail Client Side Encryption.
|
||||
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-Gmail-CSE
|
||||
|
||||
This is an initial, minimally tested release; proceed with care and report all issues.
|
||||
|
||||
c6.69.00
|
||||
|
||||
Added `use_classroom_owner_access` Boolean variable to `gam.cfg` that controls how GAM gets
|
||||
classroom member information and removes students/teachers. Client access does not provide
|
||||
|
||||
@@ -2210,7 +2210,7 @@ def getJSON(deleteFields):
|
||||
jsonData = json.loads(readFile(filename, encoding=encoding))
|
||||
except (IndexError, KeyError, SyntaxError, TypeError, ValueError) as e:
|
||||
Cmd.Backup()
|
||||
usageErrorExit(f'{str(e)}: {filename}')
|
||||
usageErrorExit(Msg.JSON_ERROR.format(str(e), filename))
|
||||
for field in deleteFields:
|
||||
jsonData.pop(field, None)
|
||||
return jsonData
|
||||
@@ -3630,6 +3630,8 @@ def SetGlobalVariables():
|
||||
|
||||
def _getCfgDirectory(sectionName, itemName):
|
||||
dirPath = os.path.expanduser(_stripStringQuotes(GM.Globals[GM.PARSER].get(sectionName, itemName)))
|
||||
if (not dirPath) and (itemName in {GC.GMAIL_CSE_INCERT_DIR, GC.GMAIL_CSE_INKEY_DIR}):
|
||||
return dirPath
|
||||
if (not dirPath) or (not os.path.isabs(dirPath)):
|
||||
if (sectionName != configparser.DEFAULTSECT) and (GM.Globals[GM.PARSER].has_option(sectionName, itemName)):
|
||||
dirPath = os.path.join(os.path.expanduser(_stripStringQuotes(GM.Globals[GM.PARSER].get(configparser.DEFAULTSECT, itemName))), dirPath)
|
||||
@@ -3707,6 +3709,8 @@ def SetGlobalVariables():
|
||||
for itemName, itemEntry in iter(GC.VAR_INFO.items()):
|
||||
if itemEntry[GC.VAR_TYPE] == GC.TYPE_DIRECTORY:
|
||||
dirPath = GC.Values[itemName]
|
||||
if (not dirPath) and (itemName in {GC.GMAIL_CSE_INCERT_DIR, GC.GMAIL_CSE_INKEY_DIR}):
|
||||
return
|
||||
if (itemName != GC.CACHE_DIR or not GC.Values[GC.NO_CACHE]) and not os.path.isdir(dirPath):
|
||||
writeStderr(formatKeyValueList(WARNING_PREFIX,
|
||||
[Ent.Singular(Ent.CONFIG_FILE), GM.Globals[GM.GAM_CFG_FILE],
|
||||
@@ -69610,6 +69614,283 @@ def printShowSmimes(users):
|
||||
if csvPF:
|
||||
csvPF.writeCSVfile('S/MIME')
|
||||
|
||||
def _showCSEItem(result, entityType, keyField, timeObjects, i, count, FJQC):
|
||||
if FJQC.formatJSON:
|
||||
printLine(json.dumps(cleanJSON(result, timeObjects=timeObjects), ensure_ascii=False, sort_keys=True))
|
||||
return
|
||||
Ind.Increment()
|
||||
printEntity([entityType, result[keyField]], i, count)
|
||||
Ind.Increment()
|
||||
showJSON(None, result, timeObjects=timeObjects)
|
||||
Ind.Decrement()
|
||||
Ind.Decrement()
|
||||
|
||||
CSE_IDENTITY_TIME_OBJECTS = {}
|
||||
CSE_KEYPAIR_TIME_OBJECTS = {'disableTime'}
|
||||
|
||||
def _printShowCSEItems(users, entityType, keyField, timeObjects):
|
||||
csvPF = CSVPrintFile(['User', keyField]) if Act.csvFormat() else None
|
||||
FJQC = FormatJSONQuoteChar(csvPF)
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if csvPF and myarg == 'todrive':
|
||||
csvPF.GetTodriveParameters()
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, True)
|
||||
i, count, users = getEntityArgument(users)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, gmail = buildGAPIServiceObject(API.GMAIL, user, i, count)
|
||||
if not gmail:
|
||||
continue
|
||||
printGettingAllEntityItemsForWhom(entityType, user, i, count)
|
||||
kvList = [Ent.USER, user, entityType, None]
|
||||
try:
|
||||
if entityType == Ent.CSE_IDENTITY:
|
||||
results = callGAPIpages(gmail.users().settings().cse().identities(), 'list', 'cseIdentities',
|
||||
throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.PERMISSION_DENIED],
|
||||
userId='me', fields='nextPageToken,cseIdentities')
|
||||
else:
|
||||
results = callGAPIpages(gmail.users().settings().cse().keypairs(), 'list', 'cseKeyPairs',
|
||||
throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.PERMISSION_DENIED],
|
||||
userId='me', fields='nextPageToken,cseKeyPairs')
|
||||
|
||||
except GAPI.permissionDenied as e:
|
||||
entityActionFailedWarning(kvList, str(e), i, count)
|
||||
continue
|
||||
except (GAPI.serviceNotAvailable, GAPI.badRequest):
|
||||
entityServiceNotApplicableWarning(Ent.USER, user, i, count)
|
||||
continue
|
||||
jcount = len(results)
|
||||
if not csvPF:
|
||||
if not FJQC.formatJSON:
|
||||
entityPerformActionNumItems([Ent.USER, user], jcount, entityType, i, count)
|
||||
j = 0
|
||||
for result in results:
|
||||
j += 1
|
||||
_showCSEItem(result, entityType, keyField, timeObjects, j, jcount, FJQC)
|
||||
else:
|
||||
for result in results:
|
||||
row = flattenJSON(result, flattened={'User': user})
|
||||
if not FJQC.formatJSON:
|
||||
csvPF.WriteRowTitles(row)
|
||||
elif csvPF.CheckRowTitles(row):
|
||||
csvPF.WriteRowNoFilter({'User': user, keyField: result[keyField],
|
||||
'JSON': json.dumps(cleanJSON(result, timeObjects=timeObjects), ensure_ascii=False, sort_keys=True)})
|
||||
if csvPF:
|
||||
csvPF.writeCSVfile(Ent.Plural(entityType))
|
||||
|
||||
CSE_IDENTITY_ACTION_FUNCTION_MAP = {
|
||||
Act.CREATE: 'create',
|
||||
Act.UPDATE: 'patch',
|
||||
Act.DELETE: 'delete',
|
||||
Act.INFO: 'get',
|
||||
}
|
||||
|
||||
# gam <UserTypeEntity> create cseidentity <KeyPairID> [kpemail <EmailAddress>]
|
||||
# [formatjson]
|
||||
# gam <UserTypeEntity> update cseidentity <KeyPairID> [kpemail <EmailAddress>]
|
||||
# [formatjson]
|
||||
# gam <UserTypeEntity> delete cseidentity [kpemail <EmailAddress>]
|
||||
# gam <UserTypeEntity> info cseidentity [kpemail <EmailAddress>]
|
||||
# [formatjson]
|
||||
def processCSEIdentity(users):
|
||||
function = CSE_IDENTITY_ACTION_FUNCTION_MAP[Act.Get()]
|
||||
keyPairId = getString(Cmd.OB_CSE_KEYPAIR_ID) if function in {'create', 'patch'} else None
|
||||
FJQC = FormatJSONQuoteChar()
|
||||
kpEmail = None
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if myarg == 'kpemail':
|
||||
kpEmail = getEmailAddress(noUid=True)
|
||||
else:
|
||||
FJQC.GetFormatJSON(myarg)
|
||||
i, count, users = getEntityArgument(users)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, gmail = buildGAPIServiceObject(API.GMAIL, user, i, count)
|
||||
if not gmail:
|
||||
continue
|
||||
if keyPairId:
|
||||
identity = {'keyPairId': keyPairId, 'emailAddress': user if not kpEmail else kpEmail}
|
||||
kwargs = {'body': identity}
|
||||
if function == 'patch':
|
||||
kwargs['emailAddress'] = identity['emailAddress']
|
||||
kvList = [Ent.USER, user, Ent.CSE_IDENTITY, identity['emailAddress'], Ent.CSE_KEYPAIR, keyPairId]
|
||||
else:
|
||||
kwargs = {'cseEmailAddress': user if not kpEmail else kpEmail}
|
||||
kvList = [Ent.USER, user, Ent.CSE_IDENTITY, kwargs['cseEmailAddress']]
|
||||
try:
|
||||
result = callGAPI(gmail.users().settings().cse().identities(), function,
|
||||
throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.PERMISSION_DENIED],
|
||||
userId='me', **kwargs)
|
||||
if not FJQC.formatJSON:
|
||||
entityActionPerformed(kvList, i, count)
|
||||
if function != 'delete':
|
||||
_showCSEItem(result, Ent.CSE_IDENTITY, 'emailAddress', CSE_IDENTITY_TIME_OBJECTS, i, count, FJQC)
|
||||
except GAPI.permissionDenied as e:
|
||||
entityActionFailedWarning(kvList, str(e), i, count)
|
||||
except (GAPI.serviceNotAvailable, GAPI.badRequest):
|
||||
entityServiceNotApplicableWarning(Ent.USER, user, i, count)
|
||||
|
||||
# gam <UserTypeEntity> show cseidentities
|
||||
# [formatjson]
|
||||
# gam <UserTypeEntity> print cseidentities [todrive <ToDriveAttribute>*]
|
||||
# [formatjson [quotechar <Character>]]
|
||||
def printShowCSEIdentities(users):
|
||||
_printShowCSEItems(users, Ent.CSE_IDENTITY, 'emailAddress', CSE_IDENTITY_TIME_OBJECTS)
|
||||
|
||||
# gam <UserTypeEntity> create csekeypair [incertdir <FilePath>] [inkeydir <FilePath>]
|
||||
# [addidentity [<Boolean>]] [kpemail <EmailAddress>]
|
||||
# [formatjson|returnidonly]
|
||||
def createCSEKeyPair(users):
|
||||
def _getFolderPath(myarg):
|
||||
filepath = os.path.expanduser(getString(Cmd.OB_FILE_PATH))
|
||||
if not os.path.isdir(filepath):
|
||||
entityDoesNotExistExit(Ent.DIRECTORY, f'{myarg} {filepath}')
|
||||
return filepath
|
||||
|
||||
FJQC = FormatJSONQuoteChar()
|
||||
incertdir = GC.Values[GC.GMAIL_CSE_INCERT_DIR]
|
||||
inkeydir = GC.Values[GC.GMAIL_CSE_INKEY_DIR]
|
||||
addIdentity = returnIdOnly = False
|
||||
kpEmail = None
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if myarg == 'incertdir':
|
||||
incertdir = _getFolderPath(myarg)
|
||||
elif myarg == 'inkeydir':
|
||||
inkeydir = _getFolderPath(myarg)
|
||||
elif myarg == 'addidentity':
|
||||
addIdentity = getBoolean()
|
||||
elif myarg == 'kpemail':
|
||||
kpEmail = getEmailAddress(noUid=True)
|
||||
elif myarg == 'returnidonly':
|
||||
returnIdOnly = True
|
||||
else:
|
||||
FJQC.GetFormatJSON(myarg)
|
||||
if not incertdir:
|
||||
missingArgumentExit('incertdir <FilePath>')
|
||||
if not inkeydir:
|
||||
missingArgumentExit('inkeydir <FilePath>')
|
||||
i, count, users = getEntityArgument(users)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, gmail = buildGAPIServiceObject(API.GMAIL, user, i, count)
|
||||
if not gmail:
|
||||
continue
|
||||
smimeFilename = os.path.join(incertdir, user+'.p7pem')
|
||||
if not os.path.isfile(smimeFilename):
|
||||
entityActionNotPerformedWarning([Ent.USER, user, Ent.CSE_KEYPAIR, None],
|
||||
Msg.FILE_NOT_FOUND.format(smimeFilename), i, count)
|
||||
continue
|
||||
smimeData = readFile(smimeFilename, mode='rb', continueOnError=True)
|
||||
if smimeData is None:
|
||||
continue
|
||||
kaclFilename = os.path.join(inkeydir, user+'.wrap')
|
||||
if not os.path.isfile(kaclFilename):
|
||||
entityActionNotPerformedWarning([Ent.USER, user, Ent.CSE_KEYPAIR, None],
|
||||
Msg.FILE_NOT_FOUND.format(kaclFilename), i, count)
|
||||
continue
|
||||
jsonData = readFile(kaclFilename, mode='r', encoding=UTF8, continueOnError=True)
|
||||
if jsonData is None:
|
||||
continue
|
||||
try:
|
||||
keyData = json.loads(jsonData)
|
||||
key = 'kacls_url'
|
||||
kaclsUri = keyData[key]
|
||||
key = 'wrapped_private_key'
|
||||
kaclsData = keyData[key]
|
||||
cseKeyPair = {
|
||||
'pkcs7': smimeData.decode(UTF8),
|
||||
'privateKeyMetadata': [{'kaclsKeyMetadata': {'kaclsUri': kaclsUri, 'kaclsData': kaclsData}}]
|
||||
}
|
||||
except KeyError:
|
||||
entityActionNotPerformedWarning([Ent.USER, user, Ent.CSE_KEYPAIR, None],
|
||||
Msg.JSON_KEY_NOT_FOUND.format(key, kaclFilename), i, count)
|
||||
continue
|
||||
except (IndexError, SyntaxError, TypeError, ValueError) as e:
|
||||
entityActionNotPerformedWarning([Ent.USER, user, Ent.CSE_KEYPAIR, None],
|
||||
Msg.JSON_ERROR.format(str(e), kaclFilename) , i, count)
|
||||
continue
|
||||
kvList = [Ent.USER, user, Ent.CSE_KEYPAIR, None]
|
||||
try:
|
||||
result = callGAPI(gmail.users().settings().cse().keypairs(), 'create',
|
||||
throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.PERMISSION_DENIED],
|
||||
userId='me', body=cseKeyPair)
|
||||
|
||||
keyPairId = result['keyPairId']
|
||||
if not returnIdOnly:
|
||||
kvList[-1] = keyPairId
|
||||
if not FJQC.formatJSON:
|
||||
entityActionPerformed(kvList, i, count)
|
||||
_showCSEItem(result, Ent.CSE_KEYPAIR, 'keyPairId', CSE_KEYPAIR_TIME_OBJECTS, i, count, FJQC)
|
||||
elif not addIdentity:
|
||||
writeStdout(f'{keyPairId}\n')
|
||||
if addIdentity:
|
||||
identity = {'keyPairId': keyPairId, 'emailAddress': user if not kpEmail else kpEmail}
|
||||
kvList = [Ent.USER, user, Ent.CSE_IDENTITY, identity['emailAddress'], Ent.CSE_KEYPAIR, keyPairId]
|
||||
result = callGAPI(gmail.users().settings().cse().identities(), 'create',
|
||||
throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.PERMISSION_DENIED],
|
||||
userId='me', body=identity)
|
||||
if not returnIdOnly:
|
||||
if not FJQC.formatJSON:
|
||||
entityActionPerformed(kvList, i, count)
|
||||
_showCSEItem(result, Ent.CSE_IDENTITY, 'emailAddress', CSE_IDENTITY_TIME_OBJECTS, i, count, FJQC)
|
||||
else:
|
||||
writeStdout(f'{keyPairId}-{user}\n')
|
||||
except GAPI.permissionDenied as e:
|
||||
entityActionFailedWarning(kvList, str(e), i, count)
|
||||
except (GAPI.serviceNotAvailable, GAPI.badRequest):
|
||||
entityServiceNotApplicableWarning(Ent.USER, user, i, count)
|
||||
|
||||
CSE_KEYPAIR_ACTION_FUNCTION_MAP = {
|
||||
Act.DISABLE: 'disable',
|
||||
Act.ENABLE: 'enable',
|
||||
Act.OBLITERATE: 'obliterate',
|
||||
Act.INFO: 'get',
|
||||
}
|
||||
|
||||
# gam <UserTypeEntity> disable csekeypair <KeyPairID>
|
||||
# [formatjson]
|
||||
# gam <UserTypeEntity> enable csekeypair <KeyPairID>
|
||||
# [formatjson]
|
||||
# gam <UserTypeEntity> obliterate csekeypair <KeyPairID>
|
||||
# gam <UserTypeEntity> info csekeypair <KeyPairID>
|
||||
# [formatjson]
|
||||
def processCSEKeyPair(users):
|
||||
function = CSE_KEYPAIR_ACTION_FUNCTION_MAP[Act.Get()]
|
||||
keyPairId = getString(Cmd.OB_CSE_KEYPAIR_ID)
|
||||
FJQC = FormatJSONQuoteChar(formatJSONOnly=True)
|
||||
i, count, users = getEntityArgument(users)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, gmail = buildGAPIServiceObject(API.GMAIL, user, i, count)
|
||||
if not gmail:
|
||||
continue
|
||||
kvList = [Ent.USER, user, Ent.CSE_KEYPAIR, keyPairId]
|
||||
try:
|
||||
result = callGAPI(gmail.users().settings().cse().keypairs(), function,
|
||||
throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.PERMISSION_DENIED],
|
||||
userId='me', keyPairId=keyPairId)
|
||||
if function != 'obliterate':
|
||||
if not FJQC.formatJSON:
|
||||
entityActionPerformed(kvList, i, count)
|
||||
_showCSEItem(result, Ent.CSE_KEYPAIR, 'keyPairId', CSE_KEYPAIR_TIME_OBJECTS, i, count, FJQC)
|
||||
else:
|
||||
entityActionPerformed(kvList, i, count)
|
||||
except GAPI.permissionDenied as e:
|
||||
entityActionFailedWarning(kvList, str(e), i, count)
|
||||
except (GAPI.serviceNotAvailable, GAPI.badRequest):
|
||||
entityServiceNotApplicableWarning(Ent.USER, user, i, count)
|
||||
|
||||
# gam <UserTypeEntity> show csekeypairs
|
||||
# [formatjson]
|
||||
# gam <UserTypeEntity> print csekeypairs [todrive <ToDriveAttribute>*]
|
||||
# [formatjson [quotechar <Character>]]
|
||||
def printShowCSEKeyPairs(users):
|
||||
_printShowCSEItems(users, Ent.CSE_KEYPAIR, 'keyPairId', CSE_KEYPAIR_TIME_OBJECTS)
|
||||
|
||||
# gam <UserTypeEntity> signature|sig
|
||||
# <SignatureContent>
|
||||
# (replace <Tag> <String>)*
|
||||
@@ -71044,7 +71325,7 @@ def importTasklist(users):
|
||||
jsonData = json.loads(readFile(filename, encoding=encoding))
|
||||
except (IndexError, KeyError, SyntaxError, TypeError, ValueError) as e:
|
||||
Cmd.Backup()
|
||||
usageErrorExit(f'{str(e)}: {filename}')
|
||||
usageErrorExit(Msg.JSON_ERROR.format(str(e), filename))
|
||||
if jsonData.get('kind', '') != 'tasks#taskLists':
|
||||
Cmd.Backup()
|
||||
usageErrorExit(f'{"Not a Tasks takeout JSON file"}: {filename}')
|
||||
@@ -72417,6 +72698,8 @@ USER_ADD_CREATE_FUNCTIONS = {
|
||||
Cmd.ARG_CHATSPACE: createChatSpace,
|
||||
Cmd.ARG_CLASSROOMINVITATION: createClassroomInvitations,
|
||||
Cmd.ARG_CONTACTDELEGATE: processContactDelegates,
|
||||
Cmd.ARG_CSEIDENTITY: processCSEIdentity,
|
||||
Cmd.ARG_CSEKEYPAIR: createCSEKeyPair,
|
||||
Cmd.ARG_LOOKERSTUDIOPERMISSION: processLookerStudioPermissions,
|
||||
Cmd.ARG_DELEGATE: processDelegates,
|
||||
Cmd.ARG_DRIVEFILE: createDriveFile,
|
||||
@@ -72529,6 +72812,7 @@ USER_COMMANDS_WITH_OBJECTS = {
|
||||
Cmd.ARG_CHATSPACE: deleteChatSpace,
|
||||
Cmd.ARG_CLASSROOMINVITATION: deleteClassroomInvitations,
|
||||
Cmd.ARG_CONTACTDELEGATE: processContactDelegates,
|
||||
Cmd.ARG_CSEIDENTITY: processCSEIdentity,
|
||||
Cmd.ARG_LOOKERSTUDIOPERMISSION: processLookerStudioPermissions,
|
||||
Cmd.ARG_DELEGATE: processDelegates,
|
||||
Cmd.ARG_DRIVEFILE: deleteDriveFile,
|
||||
@@ -72568,6 +72852,11 @@ USER_COMMANDS_WITH_OBJECTS = {
|
||||
Cmd.ARG_WORKINGLOCATION: deleteWorkingLocation,
|
||||
}
|
||||
),
|
||||
'disable':
|
||||
(Act.DISABLE,
|
||||
{Cmd.ARG_CSEKEYPAIR: processCSEKeyPair,
|
||||
}
|
||||
),
|
||||
'draft':
|
||||
(Act.DRAFT,
|
||||
{Cmd.ARG_MESSAGE: draftMessage,
|
||||
@@ -72579,6 +72868,11 @@ USER_COMMANDS_WITH_OBJECTS = {
|
||||
Cmd.ARG_DRIVETRASH: emptyDriveTrash,
|
||||
}
|
||||
),
|
||||
'enable':
|
||||
(Act.ENABLE,
|
||||
{Cmd.ARG_CSEKEYPAIR: processCSEKeyPair,
|
||||
}
|
||||
),
|
||||
'export':
|
||||
(Act.EXPORT,
|
||||
{Cmd.ARG_MESSAGE: exportMessages,
|
||||
@@ -72616,6 +72910,8 @@ USER_COMMANDS_WITH_OBJECTS = {
|
||||
Cmd.ARG_CHATSPACE: infoChatSpace,
|
||||
Cmd.ARG_CHATSPACEDM: infoChatSpaceDM,
|
||||
Cmd.ARG_CIGROUPMEMBERS: infoCIGroupMembers,
|
||||
Cmd.ARG_CSEIDENTITY: processCSEIdentity,
|
||||
Cmd.ARG_CSEKEYPAIR: processCSEKeyPair,
|
||||
Cmd.ARG_DRIVEFILE: showFileInfo,
|
||||
Cmd.ARG_DRIVEFILEACL: infoDriveFileACLs,
|
||||
Cmd.ARG_DRIVELABEL: infoDriveLabels,
|
||||
@@ -72657,6 +72953,11 @@ USER_COMMANDS_WITH_OBJECTS = {
|
||||
Cmd.ARG_TASK: processTasks,
|
||||
}
|
||||
),
|
||||
'obliterate':
|
||||
(Act.OBLITERATE,
|
||||
{Cmd.ARG_CSEKEYPAIR: processCSEKeyPair,
|
||||
}
|
||||
),
|
||||
'purge':
|
||||
(Act.PURGE,
|
||||
{Cmd.ARG_DRIVEFILE: purgeDriveFile,
|
||||
@@ -72681,6 +72982,8 @@ USER_COMMANDS_WITH_OBJECTS = {
|
||||
Cmd.ARG_CLASSROOMINVITATION: printShowClassroomInvitations,
|
||||
Cmd.ARG_CLASSROOMPROFILE: printShowClassroomProfile,
|
||||
Cmd.ARG_CONTACTDELEGATE: printShowContactDelegates,
|
||||
Cmd.ARG_CSEIDENTITY: printShowCSEIdentities,
|
||||
Cmd.ARG_CSEKEYPAIR: printShowCSEKeyPairs,
|
||||
Cmd.ARG_LOOKERSTUDIOASSET: printShowLookerStudioAssets,
|
||||
Cmd.ARG_LOOKERSTUDIOPERMISSION: printShowLookerStudioPermissions,
|
||||
Cmd.ARG_DELEGATE: printShowDelegates,
|
||||
@@ -72778,6 +73081,8 @@ USER_COMMANDS_WITH_OBJECTS = {
|
||||
Cmd.ARG_CLASSROOMPROFILE: printShowClassroomProfile,
|
||||
Cmd.ARG_CONTACTDELEGATE: printShowContactDelegates,
|
||||
Cmd.ARG_COUNT: showCountUser,
|
||||
Cmd.ARG_CSEIDENTITY: printShowCSEIdentities,
|
||||
Cmd.ARG_CSEKEYPAIR: printShowCSEKeyPairs,
|
||||
Cmd.ARG_LOOKERSTUDIOASSET: printShowLookerStudioAssets,
|
||||
Cmd.ARG_LOOKERSTUDIOPERMISSION: printShowLookerStudioPermissions,
|
||||
Cmd.ARG_DELEGATE: printShowDelegates,
|
||||
@@ -72902,6 +73207,7 @@ USER_COMMANDS_WITH_OBJECTS = {
|
||||
Cmd.ARG_CHATMEMBER: deleteUpdateChatMember,
|
||||
Cmd.ARG_CHATMESSAGE: updateChatMessage,
|
||||
Cmd.ARG_CHATSPACE: updateChatSpace,
|
||||
Cmd.ARG_CSEIDENTITY: processCSEIdentity,
|
||||
Cmd.ARG_LOOKERSTUDIOPERMISSION: processLookerStudioPermissions,
|
||||
Cmd.ARG_DELEGATE: updateDelegates,
|
||||
Cmd.ARG_DRIVEFILE: updateDriveFile,
|
||||
@@ -72982,6 +73288,8 @@ USER_COMMANDS_OBJ_ALIASES = {
|
||||
Cmd.ARG_CONTACTGROUPS: Cmd.ARG_PEOPLECONTACTGROUP,
|
||||
Cmd.ARG_CONTACTPHOTO: Cmd.ARG_PEOPLECONTACTPHOTO,
|
||||
Cmd.ARG_CONTACTPHOTOS: Cmd.ARG_PEOPLECONTACTPHOTO,
|
||||
Cmd.ARG_CSEIDENTITIES: Cmd.ARG_CSEIDENTITY,
|
||||
Cmd.ARG_CSEKEYPAIRS: Cmd.ARG_CSEKEYPAIR,
|
||||
Cmd.ARG_COUNTS: Cmd.ARG_COUNT,
|
||||
Cmd.ARG_DATASTUDIOASSET: Cmd.ARG_LOOKERSTUDIOASSET,
|
||||
Cmd.ARG_DATASTUDIOPERMISSION: Cmd.ARG_LOOKERSTUDIOPERMISSION,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2023 Ross Scroggs All Rights Reserved.
|
||||
# Copyright (C) 2024 Ross Scroggs All Rights Reserved.
|
||||
#
|
||||
# All Rights Reserved.
|
||||
#
|
||||
@@ -77,6 +77,7 @@ class GamAction():
|
||||
MOVE_MERGE = 'movm'
|
||||
NOACTION = 'noac'
|
||||
NOACTION_PREVIEW = 'noap'
|
||||
OBLITERATE = 'obli'
|
||||
PERFORM = 'perf'
|
||||
PRE_PROVISIONED_DISABLE ='ppdi'
|
||||
PRE_PROVISIONED_REENABLE ='ppre'
|
||||
@@ -193,6 +194,7 @@ class GamAction():
|
||||
MOVE_MERGE: ['Moved(Merge)', 'Move(Merge)'],
|
||||
NOACTION: ['No Action', 'No Action'],
|
||||
NOACTION_PREVIEW: ['No Action (Preview)', 'No Action (Preview)'],
|
||||
OBLITERATE: ['Obliterated', 'Obliterate'],
|
||||
PERFORM: ['Action Performed', 'Perform Action'],
|
||||
PRE_PROVISIONED_DISABLE: ['PreProvisioned Disabled', 'PreProvisioned Disable'],
|
||||
PRE_PROVISIONED_REENABLE: ['PreProvisioned Reenabled', 'PreProvisioned Reenable'],
|
||||
|
||||
@@ -161,6 +161,10 @@ ENABLE_GCLOUD_REAUTH = 'enable_gcloud_reauth'
|
||||
EVENT_MAX_RESULTS = 'event_max_results'
|
||||
# Path to extra_args.txt
|
||||
EXTRA_ARGS = 'extra_args'
|
||||
# Gmail CSE certificates directory
|
||||
GMAIL_CSE_INCERT_DIR = 'gmail_cse_incert_dir'
|
||||
# Gmail CSE KACL wrapped key files
|
||||
GMAIL_CSE_INKEY_DIR = 'gmail_cse_inkey_dir'
|
||||
# When processing items in batches, how many seconds should GAM wait between batches
|
||||
INTER_BATCH_WAIT = 'inter_batch_wait'
|
||||
# When retrieving lists of licenses from API, how many should be retrieved in each chunk
|
||||
@@ -284,6 +288,8 @@ TODRIVE_UPLOAD_NODATA = 'todrive_upload_nodata'
|
||||
TODRIVE_USER = 'todrive_user'
|
||||
# Update CrOS org unit with orgUnitId
|
||||
UPDATE_CROS_OU_WITH_ID = 'update_cros_ou_with_id'
|
||||
# Use course owner for course access
|
||||
USE_COURSE_OWNER_ACCESS = 'use_course_owner_access'
|
||||
# Use Project ID as Project Name and App Name
|
||||
USE_PROJECTID_AS_NAME = 'use_projectid_as_name'
|
||||
# When retrieving lists of Users from API, how many should be retrieved in each chunk
|
||||
@@ -359,6 +365,8 @@ Defaults = {
|
||||
ENABLE_GCLOUD_REAUTH: FALSE,
|
||||
EVENT_MAX_RESULTS: '250',
|
||||
EXTRA_ARGS: '',
|
||||
GMAIL_CSE_INCERT_DIR: '',
|
||||
GMAIL_CSE_INKEY_DIR: '',
|
||||
INTER_BATCH_WAIT: '0',
|
||||
LICENSE_MAX_RESULTS: '100',
|
||||
LICENSE_SKUS: '',
|
||||
@@ -420,6 +428,7 @@ Defaults = {
|
||||
TODRIVE_UPLOAD_NODATA: TRUE,
|
||||
TODRIVE_USER: '',
|
||||
UPDATE_CROS_OU_WITH_ID: FALSE,
|
||||
USE_COURSE_OWNER_ACCESS: FALSE,
|
||||
USE_PROJECTID_AS_NAME: FALSE,
|
||||
USER_MAX_RESULTS: '500',
|
||||
USER_SERVICE_ACCOUNT_ACCESS_ONLY: FALSE,
|
||||
@@ -514,6 +523,8 @@ VAR_INFO = {
|
||||
ENABLE_GCLOUD_REAUTH: {VAR_TYPE: TYPE_BOOLEAN},
|
||||
EVENT_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 2500)},
|
||||
EXTRA_ARGS: {VAR_TYPE: TYPE_FILE, VAR_SIGFILE: FN_EXTRA_ARGS_TXT, VAR_SFFT: ('', FN_EXTRA_ARGS_TXT), VAR_ACCESS: os.R_OK},
|
||||
GMAIL_CSE_INCERT_DIR: {VAR_TYPE: TYPE_DIRECTORY},
|
||||
GMAIL_CSE_INKEY_DIR: {VAR_TYPE: TYPE_DIRECTORY},
|
||||
INTER_BATCH_WAIT: {VAR_TYPE: TYPE_FLOAT, VAR_LIMITS: (0.0, 60.0)},
|
||||
LICENSE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (10, 1000)},
|
||||
LICENSE_SKUS: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)},
|
||||
@@ -575,6 +586,7 @@ VAR_INFO = {
|
||||
TODRIVE_UPLOAD_NODATA: {VAR_TYPE: TYPE_BOOLEAN},
|
||||
TODRIVE_USER: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)},
|
||||
UPDATE_CROS_OU_WITH_ID: {VAR_TYPE: TYPE_BOOLEAN},
|
||||
USE_COURSE_OWNER_ACCESS: {VAR_TYPE: TYPE_BOOLEAN},
|
||||
USE_PROJECTID_AS_NAME: {VAR_TYPE: TYPE_BOOLEAN},
|
||||
USER_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 500)},
|
||||
USER_SERVICE_ACCOUNT_ACCESS_ONLY: {VAR_TYPE: TYPE_BOOLEAN},
|
||||
|
||||
@@ -520,6 +520,10 @@ class GamCLArgs():
|
||||
ARG_CROSES = 'croses'
|
||||
ARG_CROSACTIVITY = 'crosactivity'
|
||||
ARG_CROSTELEMETRY = 'crostelemetry'
|
||||
ARG_CSEIDENTITY = 'cseidentity'
|
||||
ARG_CSEIDENTITIES = 'cseidentities'
|
||||
ARG_CSEKEYPAIR = 'csekeypair'
|
||||
ARG_CSEKEYPAIRS = 'csekeypairs'
|
||||
ARG_CURRENTPROJECTID = 'currentprojectid'
|
||||
ARG_CUSTOMER = 'customer'
|
||||
ARG_DATASTUDIOASSET = 'datastudioasset'
|
||||
@@ -846,6 +850,7 @@ class GamCLArgs():
|
||||
OB_COURSE_WORK_STATE_LIST = "CourseWorkStateList"
|
||||
OB_CROS_DEVICE_ENTITY = 'CrOSDeviceEntity'
|
||||
OB_CROS_ENTITY = 'CrOSEntity'
|
||||
OB_CSE_KEYPAIR_ID = 'CSEKeyPairID'
|
||||
OB_CUSTOMER_ID = 'CustomerID'
|
||||
OB_CUSTOMER_AUTH_TOKEN = 'CustomerAuthToken'
|
||||
OB_DEVICE_FILE_ENTITY = 'DeviceFileEntity'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2023 Ross Scroggs All Rights Reserved.
|
||||
# Copyright (C) 2024 Ross Scroggs All Rights Reserved.
|
||||
#
|
||||
# All Rights Reserved.
|
||||
#
|
||||
@@ -150,12 +150,14 @@ class GamEntity():
|
||||
CRITERIA = 'crit'
|
||||
CROS_DEVICE = 'cros'
|
||||
CROS_SERIAL_NUMBER = 'crsn'
|
||||
CSE_IDENTITY = 'csei'
|
||||
CSE_KEYPAIR = 'csek'
|
||||
CUSTOMER_DOMAIN = 'cudo'
|
||||
CUSTOMER_ID = 'cuid'
|
||||
DATE = 'date'
|
||||
DEFAULT_LANGUAGE = 'dfla'
|
||||
DELEGATE = 'dele'
|
||||
DELETED_USER = 'del'
|
||||
DELETED_USER = 'delu'
|
||||
DELIVERY = 'deli'
|
||||
DEVICE = 'devi'
|
||||
DEVICE_FILE = 'devf'
|
||||
@@ -163,7 +165,7 @@ class GamEntity():
|
||||
DEVICE_USER = 'devu'
|
||||
DEVICE_USER_CLIENT_STATE = 'ducs'
|
||||
DISCOVERY_JSON_FILE = 'disc'
|
||||
DOCUMENT = 'doc '
|
||||
DOCUMENT = 'docu'
|
||||
DOMAIN = 'doma'
|
||||
DOMAIN_ALIAS = 'doal'
|
||||
DOMAIN_CONTACT = 'doco'
|
||||
@@ -483,6 +485,8 @@ class GamEntity():
|
||||
CRITERIA: ['Criteria', 'Criteria'],
|
||||
CROS_DEVICE: ['CrOS Devices', 'CrOS Device'],
|
||||
CROS_SERIAL_NUMBER: ['CrOS Serial Numbers', 'CrOS Serial Numbers'],
|
||||
CSE_IDENTITY: ['CSE Identities', 'CSE Identity'],
|
||||
CSE_KEYPAIR: ['CSE KeyPairs', 'CSE KeyPair'],
|
||||
CUSTOMER_DOMAIN: ['Customer Domains', 'Customer Domain'],
|
||||
CUSTOMER_ID: ['Customer IDs', 'Customer ID'],
|
||||
DATE: ['Dates', 'Date'],
|
||||
|
||||
@@ -232,6 +232,7 @@ FAILED_PRECONDITION = 'Failed precondition'
|
||||
FAILED_TO_PARSE_AS_JSON = 'Failed to parse as JSON'
|
||||
FAILED_TO_PARSE_AS_LIST = 'Failed to parse as list'
|
||||
FIELD_NOT_FOUND_IN_SCHEMA = 'Field {0} not found in schema {1}'
|
||||
FILE_NOT_FOUND = 'File {0} not found'
|
||||
FINISHED = 'Finished'
|
||||
FILTER_CAN_ONLY_CONTAIN_ONE_CATEGORY_LABEL = 'Filter can only contain one CATEGORY label'
|
||||
FILTER_CAN_ONLY_CONTAIN_ONE_USER_LABEL = 'Filter can only contain one USER label'
|
||||
@@ -300,6 +301,8 @@ IS_NOT_UNIQUE = 'Is not unique, {0}: {1}'
|
||||
IS_REQD_TO_CHG_PWD_NO_DELEGATION = 'Is required to change password at next login. You must change password or clear changepassword flag for delegation.'
|
||||
IS_SUSPENDED_NO_BACKUPCODES = 'User is suspended. You must unsuspend to process backupcodes'
|
||||
IS_SUSPENDED_NO_DELEGATION = 'Is suspended. You must unsuspend for delegation.'
|
||||
JSON_ERROR = 'JSON error "{0}" in file {1}'
|
||||
JSON_KEY_NOT_FOUND = 'JSON key "{0}" not found in file {1}'
|
||||
KIOSK_MODE_REQUIRED = ' This command ({0}) requires that the ChromeOS device be in Kiosk mode.'
|
||||
LESS_THAN_1_SECOND = 'less than 1 second'
|
||||
LIST_CHROMEOS_INVALID_INPUT_PAGE_TOKEN_RETRY = 'List ChromeOSdevices Invalid Input: pageToken retry'
|
||||
|
||||
Reference in New Issue
Block a user