mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-18 05:01:37 +00:00
Compare commits
4 Commits
20240221.2
...
20240225.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96aa4f3bd2 | ||
|
|
883979f5f5 | ||
|
|
b03a43777d | ||
|
|
a0e4be4b50 |
@@ -89,15 +89,6 @@ If you run a Google Workspace Education SKU, verify that the super admin you'll
|
||||
* Choose "All users are 18 or older"
|
||||
* Click "SAVE"
|
||||
|
||||
Verify whether the super admin you'll be using is in an OU where reauthentication is required.
|
||||
* Access the admin console and go to Security -> Overview
|
||||
* Scroll down and open Google Cloud session control section
|
||||
* Select the OU containing the super admin
|
||||
* If Require reauthentication is selected and Exempt Trusted apps is not checked, you'll have to do `gam oauth create` at whatever frequency is specified
|
||||
* If that sounds unappealing, check Exempt Trusted apps
|
||||
* Click "OVERRIDE"
|
||||
* Follow the steps below to mark GAM as a trusted app
|
||||
|
||||
Based on your domain policies, you may have to mark GAM as a trusted app. These steps are performed after a project is created.
|
||||
* Access the admin console and go to Security -> Access and data control -> API controls
|
||||
* Check Trust internal, domain-owned apps
|
||||
@@ -114,6 +105,15 @@ Based on your domain policies, you may have to mark GAM as a trusted app. These
|
||||
* Click Next/Continue
|
||||
* Click Finish
|
||||
|
||||
Verify whether the super admin you'll be using is in an OU where reauthentication is required.
|
||||
* Access the admin console and go to Security -> Overview
|
||||
* Scroll down and open Google Cloud session control section
|
||||
* Select the OU containing the super admin
|
||||
* If Require reauthentication is selected and Exempt Trusted apps is not checked, you'll have to do `gam oauth create` at whatever frequency is specified
|
||||
* If that sounds unappealing, check Exempt Trusted apps
|
||||
* Click "OVERRIDE"
|
||||
* Follow the steps below to mark GAM as a trusted app
|
||||
|
||||
## Headless computers and Cloud Shells
|
||||
With many thanks to Jay, `gam oauth create` now uses a new client access authentication flow
|
||||
as required by Google for headless computers/cloud shells; this is required as of February 28, 2022.
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
#7a4706|#8a1c0a|#994a64|#ffffff
|
||||
<LanguageCode> ::=
|
||||
ach|af|ag|ak|am|ar|az|be|bem|bg|bn|br|bs|ca|chr|ckb|co|crs|cs|cy|da|de|
|
||||
ee|el|en|en-gb|en-us|eo|es|es-419|et|eu|fa|fi|fil|fo|fr|fr-ca|fy|
|
||||
ee|el|en|en-ca|en-gb|en-us|eo|es|es-419|et|eu|fa|fi|fil|fo|fr|fr-ca|fy|
|
||||
ga|gaa|gd|gl|gn|gu|ha|haw|he|hi|hr|ht|hu|hy|ia|id|ig|in|is|it|iw|ja|jw|
|
||||
ka|kg|kk|km|kn|ko|kri|ku|ky|la|lg|ln|lo|loz|lt|lua|lv|
|
||||
mfe|mg|mi|mk|ml|mn|mo|mr|ms|mt|my|ne|nl|nn|no|nso|ny|nyn|oc|om|or|
|
||||
@@ -232,8 +232,11 @@
|
||||
101035 |
|
||||
101036 |
|
||||
101037 |
|
||||
101038 |
|
||||
101039 |
|
||||
101040 |
|
||||
101043 |
|
||||
101047 |
|
||||
Google-Apps |
|
||||
Google-Chrome-Device-Management |
|
||||
Google-Drive-storage |
|
||||
@@ -249,12 +252,17 @@
|
||||
4tb | drive4tb | googledrivestorage4tb | Google-Drive-storage-4TB |
|
||||
8tb | drive8tb | googledrivestorage8tb | Google-Drive-storage-8TB |
|
||||
16tb | drive16tb | googledrivestorage16tb | Google-Drive-storage-16TB |
|
||||
appsheetcore | 1010380001 |
|
||||
appsheetstandard | appsheetenterprisestandard | 1010380002 |
|
||||
appsheetplus | appsheetenterpriseplus | 1010380003 |
|
||||
assuredcontrols | 1010390001 |
|
||||
bce | beyondcorp | beyondcorpenterprise | 1010400001 |
|
||||
cdm | chrome | googlechromedevicemanagement | Google-Chrome-Device-Management |
|
||||
cloudidentity | identity | 1010010001 |
|
||||
cloudidentitypremium | identitypremium | 1010050001 |
|
||||
cloudsearch | 1010350001 |
|
||||
geminibiz | 1010470003 |
|
||||
geminient| duetai | 1010470001 |
|
||||
gsuitebasic | gafb | gafw | basic | Google-Apps-For-Business |
|
||||
gsuitebusiness | gau | gsb | unlimited | Google-Apps-Unlimited |
|
||||
gsuitebusinessarchived | gsbau | businessarchived | 1010340002 |
|
||||
@@ -270,6 +278,7 @@
|
||||
gwesstaff | workspaceeducationstandardstaff | 1010310006 |
|
||||
gwesstudent | workspaceeducationstandardstudent | 1010310007 |
|
||||
gwetlu | workspaceeducationupgrade | 1010370001 |
|
||||
gwlabs | workspacelabs | 1010470002
|
||||
meetdialing | googlemeetglobaldialing | 1010360001 |
|
||||
postini | gams | gsuitegams | gsuitepostini | gsuitemessagesecurity | Google-Apps-For-Postini |
|
||||
standard | free | Google-Apps |
|
||||
@@ -278,16 +287,22 @@
|
||||
voicepremier | gvpremier | googlevoicepremier | 1010330002 |
|
||||
voicestandard | gvstandard | googlevoicestandard | 1010330004 |
|
||||
voicestarter | gvstarter | googlevoicestarter | 1010330003 |
|
||||
wsas | plusstorage | 1010430001 |
|
||||
wsbizplus | workspacebusinessplus | 1010020025 |
|
||||
wsbizplusarchived | workspacebusinessplusarchived | 1010340003 |
|
||||
wsbizstan | workspacebusinessstandard | 1010020028 |
|
||||
wsbizstanarchived | workspacebusinessstandardarchived | 1010340006 |
|
||||
wsbizstarter | workspacebusinessstarter | wsbizstart | 1010020027 |
|
||||
wsbizstarterarchived | workspacebusinessstarterarchived | 1010340005 |
|
||||
wsentess | workspaceenterpriseessentials | 1010060003 |
|
||||
wsentplus | workspaceenterpriseplus | gae | gse | enterprise | gsuiteenterprise | 1010020020 |
|
||||
wsentstan | workspaceenterprisestandard | 1010020026 |
|
||||
wsentstanarchived | workspaceenterprisestandardarchived | 1010340004 |
|
||||
wsentstarter | workspaceenterprisestarter | 1010020029 | wes |
|
||||
wsess | workspaceesentials | gsuiteessentials | essentials | d4e | driveenterprise | drive4enterprise | 1010060001 |
|
||||
wsflw | workspacefrontline | workspacefrontlineworker | 1010020030
|
||||
wsessplus | workspaceessentialsplus | 1010060005 |
|
||||
wsflw | workspacefrontline | workspacefrontlineworker | 1010020030 |
|
||||
wsflwstan | workspacefrontlinestan | workspacefrontlineworkerstan | 1010020031
|
||||
```
|
||||
## Items built from primitives
|
||||
```
|
||||
@@ -346,7 +361,7 @@
|
||||
<ChannelCustomerID> ::= <String>
|
||||
<ChatMember> ::= spaces/<String>/members/<String>
|
||||
<ChatMessage> ::= spaces/<String>/messages/<String>
|
||||
<ChatSpace> ::= spaces/<String> | <String>
|
||||
<ChatSpace> ::= spaces/<String> | space <String> | space spaces/<String>
|
||||
<ChatThread> ::= spaces/<String>/threads/<String>
|
||||
<ClassroomInvitationID> ::= <String>
|
||||
<ClientID> ::= <String>
|
||||
@@ -421,6 +436,7 @@
|
||||
<DriveLabelFieldID> ::= <String>
|
||||
<DriveLabelSelectionID> ::= <String>
|
||||
<DriveLabelName> ::= labels/<DriveLabelID>[@latest|@published|@<Number>]
|
||||
<DriveLabelPermissionName> ::= labels/<DriveLabelID>[@latest|@published|@<Number>]/permissions/(audiences|groups|people)/<String>
|
||||
<EmailAddress> ::= <String>@<DomainName>
|
||||
<EmailItem> ::= <EmailAddress>|<UniqueID>|<String>
|
||||
<EmailReplacement> ::= <String>
|
||||
@@ -456,6 +472,11 @@
|
||||
<Marker> ::= <String>
|
||||
<MatterItem> ::= <UniqueID>|<String>
|
||||
<MatterState> ::= open|closed|deleted
|
||||
<MessageContent> ::=
|
||||
(message|textmessage|htmlmessage <String>)|
|
||||
(file|textfile|htmlfile <FileName> [charset <Charset>])|
|
||||
(gdoc|ghtml <UserGoogleDoc>)|
|
||||
(gcsdoc|gcshtml <StorageBucketObjectName>)
|
||||
<MessageID> ::= <String>
|
||||
<Namespace> ::= <String>
|
||||
<NotesName> ::= notes/<String>
|
||||
@@ -529,7 +550,7 @@
|
||||
<ServiceAccountDisplayName> ::= <String>
|
||||
Maximum of 100 characters
|
||||
<ServiceAccountDescrition> ::= <String>
|
||||
Maximumof 256 chcracters
|
||||
Maximum of 256 chcracters
|
||||
<ServiceAccountEmail> ::= <ServiceAccountName>@<ProjectID>.iam.gserviceaccount.com
|
||||
<ServiceAccountUniqueID> ::= <Number>
|
||||
<ServiceAccountKey> ::= <String>
|
||||
@@ -584,8 +605,10 @@
|
||||
(tdlocale <Locale>)|
|
||||
(tdnobrowser [<Boolean>])|
|
||||
(tdnoemail [<Boolean>])|
|
||||
(tdnoescapechar [<Boolean>])|
|
||||
(tdparent (id:<DriveFolderID>)|<DriveFolderName>)|
|
||||
(tdshare <EmailAddress> commenter|reader|writer)|
|
||||
(tdretaintitle [<Boolean>])|
|
||||
(tdshare <EmailAddress> commenter|reader|writer)*|
|
||||
(tdsheet (id:<Number>)|<String>)|
|
||||
(tdsheettimestamp [<Boolean>] [tdsheettimeformat <String>])
|
||||
(tdsheettitle <String>)|
|
||||
|
||||
@@ -262,6 +262,8 @@ Data fields identified in a `csvkmd` argument.
|
||||
<FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
|
||||
<DriveLabelNameEntity> ::=
|
||||
<DriveLabelNameList> | <FileSelector> | <CSVFileSelector> | <CSVDataSelector>
|
||||
<DriveLabelPermissionNameEntity> ::=
|
||||
<DriveLabelPermissionNameList> | <FileSelector> | <CSVFileSelector> | <CSVDataSelector>
|
||||
<EmailAddressEntity> ::=
|
||||
<EmailAddressList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
|
||||
<FilterIDEntity> ::=
|
||||
|
||||
@@ -10,6 +10,43 @@ 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.05
|
||||
|
||||
Added commands to create|delete|display Drive Label permissions.
|
||||
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-Drive-Labels
|
||||
|
||||
### 6.70.04
|
||||
|
||||
Added option `showvalidcolumn` to `gam print users` that can be used to identify whether
|
||||
users are defined in the domain. Typically, you would read CSV file of email addresses
|
||||
to verify as domain members.
|
||||
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users#verify-domain-membership
|
||||
|
||||
Added option `addcsvdata <FieldName> <String>` to `gam print users` that adds
|
||||
additional columns of data to the CSV file output. Typically, you would read CSV file of email addresses
|
||||
to generate a CSV file of results and copy data from the input CSV to the outout CSV.
|
||||
|
||||
### 6.70.03
|
||||
|
||||
Renamed license product DuetAI to Gemini
|
||||
* ProductID - 101047
|
||||
|
||||
Renamed license SKU DuetAI for Google Workspace to Gemini Enterprise
|
||||
* ProductID - 101047
|
||||
* SKUID - 1010470001 | geminient | duetai
|
||||
|
||||
Added support for license SKU Gemini Business
|
||||
* ProductID - 101047
|
||||
* SKUID - 1010470003 | geminibiz
|
||||
|
||||
### 6.70.02
|
||||
|
||||
In 6.69.00, GAM starting using course owner access when using `copyfrom` in `gam create|update course`
|
||||
regardless of the value of `gam.cfg/use_course_owner_access`. This prevents copying from courses
|
||||
with a deleted user. GAM now uses the value of `gam.cfg/use_course_owner_access` when `copyfrom` is used.o
|
||||
|
||||
### 6.70.01
|
||||
|
||||
Added `gmail_cse_incert_dir` and `gmail_cse_inkey_dir` path variables to `gam.cfg` that provide
|
||||
@@ -25,10 +62,10 @@ This is an initial, minimally tested release; proceed with care and report all i
|
||||
|
||||
### 6.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
|
||||
Added `use_course_owner_access` Boolean variable to `gam.cfg` that controls how GAM gets
|
||||
classroom member information and removes students/teachers. Client/admin access does not provide
|
||||
complete information about non-domain students/teachers.
|
||||
* `False` - Use client access; this is the default. Use if you don't have non-domain members in your courses.
|
||||
* `False` - Use client/admin access; this is the default. Use if you don't have non-domain members in your courses.
|
||||
* `True` - Use service account access as the classroom owner. An extra API call is required per course to authenticate the owner; this will affect performance
|
||||
|
||||
Added the following command which must be used to delete classroom invitations for non-domain students/teachers.
|
||||
|
||||
@@ -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.70.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.70.05 - 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.70.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.70.05 - 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
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
| Cloud Identity Free | 101001 |
|
||||
| Cloud Identity Premium | 101005 |
|
||||
| Cloud Search | 101035 |
|
||||
| Duet AI | 101047 |
|
||||
| Gemini | 101047 |
|
||||
| Google Chrome Device Management | Google-Chrome-Device-Management |
|
||||
| Google Drive Storage | Google-Drive-storage |
|
||||
| Google Meet Global Dialing | 101036 |
|
||||
@@ -46,11 +46,12 @@
|
||||
| Cloud Identity Free | 1010010001 | cloudidentity |
|
||||
| Cloud Identity Premium | 1010050001 | cloudidentitypremium |
|
||||
| Cloud Search | 1010350001 | cloudsearch |
|
||||
| Duet AI | 1010470001 | duetai |
|
||||
| G Suite Basic | Google-Apps-For-Business | gsuitebasic |
|
||||
| G Suite Business | Google-Apps-Unlimited | gsuitebusiness |
|
||||
| G Suite Legacy | Google-Apps | standard |
|
||||
| G Suite Lite | Google-Apps-Lite | gsuitelite |
|
||||
| Gemini Business | 1010470003 | geminibiz
|
||||
| Gemini Enterprise | 1010470001 | geminient | duetai |
|
||||
| Google Apps Message Security | Google-Apps-For-Postini | postini |
|
||||
| Google Chrome Device Management | Google-Chrome-Device-Management | cdm |
|
||||
| Google Drive Storage 16TB | Google-Drive-storage-16TB | 16tb |
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
<DriveFolderNameList> ::= "<DriveFolderName>(,<DriveFolderName>)*"
|
||||
<DriveLabelIDList> ::= "<DriveLabelID>(,<DriveLabelID>)*"
|
||||
<DriveLabelNameList> ::= "<DriveLabelName>(,<DriveLabelName>)*"
|
||||
<DriveLabelPermissionNameList> ::= "<DriveLabelPermissionName>(,<DriveLabelPermissionName>)*"
|
||||
<DriveLabelFieldIDList> ::= "<DriveLabelFieldID>(,<DriveLabelFieldID>)*"
|
||||
<DriveLabelSelectionIDList> ::= "<DriveLabelSelectionID>(,<DriveLabelSelectionID>)*"
|
||||
<EmailAddressList> ::= "<EmailAddress>(,<EmailAddress>)*"
|
||||
|
||||
@@ -6,12 +6,15 @@
|
||||
- [Introduction](#introduction)
|
||||
- [Display Drive Labels](#display-drive-labels)
|
||||
- [Process File Drive Labels](#process-file-drive-labels)
|
||||
- [Manage Drive Label Permissions](#manage-drive-label-permissions)
|
||||
- [Display Drive Label Permissions](#display-drive-label-permissions)
|
||||
|
||||
## API documentation
|
||||
* https://support.google.com/a/answer/9292382
|
||||
* https://developers.google.com/drive/labels/guides/overview
|
||||
* https://developers.google.com/drive/labels/guides/authorize
|
||||
* https://developers.google.com/drive/labels/reference/rest/v2beta/labels
|
||||
* https://developers.google.com/drive/labels/reference/rest/v2beta/labels.permissions
|
||||
* https://developers.google.com/drive/api/guides/about-labels
|
||||
* https://developers.google.com/drive/api/v3/reference/files
|
||||
|
||||
@@ -19,13 +22,15 @@
|
||||
To use these commands you must add the 'Drive Labels API' to your project and update your service account authorization.
|
||||
```
|
||||
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.
|
||||
|
||||
## Definitions
|
||||
* [`<DriveFileEntity>`](Drive-File-Selection)
|
||||
* [`<UserTypeEntity>`](Collections-of-Users)
|
||||
* [`<DriveLabelNameEntity>`, `<DriveLabelPermissionNameEntity'](Collections-of-Items)
|
||||
* [`<UserTypeEntity>`](Collections-of-Items)
|
||||
|
||||
```
|
||||
<DriveLabelID> ::= <String>
|
||||
@@ -35,7 +40,11 @@ Supported editions for this feature: Business Standard and Business Plus; Enterp
|
||||
<DriveLabelNameList> ::= "<DriveLabelName>(,<DriveLabelName)*"
|
||||
<DriveLabelNameEntity> ::=
|
||||
<DriveLabelNameList> | <FileSelector> | <CSVFileSelector> | <CSVDataSelector>
|
||||
See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items
|
||||
|
||||
<DriveLabelPermissionName> ::= labels/<DriveLabelID>[@latest|@published|@<Number>]/permissions/(audiences|groups|people)/<String>
|
||||
<DriveLabelPermissionNameList> ::= "<DriveLabelPermissionName>(,<DriveLabelPermissionName>)*"
|
||||
<DriveLabelPermissionNameEntity> ::=
|
||||
<DriveLabelPermissionNameList> | <FileSelector> | <CSVFileSelector> | <CSVDataSelector>
|
||||
|
||||
<DriveLabelFieldID> ::= <String>
|
||||
<DriveLabelSelectionID> ::= <String>
|
||||
@@ -86,9 +95,9 @@ A domain administrator with the Drive and Docs administrator privilege can searc
|
||||
owned by their organization, regardless of the admin's membership in any given Shared Drive.
|
||||
|
||||
Three forms of the commands are available:
|
||||
* `gam action ...` - The administrator named in oauth2.txt is used, domain administrator access implied and labels of type `SHARED` and `ADMIN`can be written
|
||||
* `gam <UserTypeEntity> action ... adminaccess` - The user named in `<UserTypeEntty>` is used, adminaccess indicates that labels of type `SHARED` and `ADMIN`can be written
|
||||
* `gam <UserTypeEntity> action ...` - The user named in `<UserTypeEntty>` is used, access is limited, onlylabels of type `SHARED` can be written
|
||||
* `gam action ...` - The administrator named in oauth2.txt is used, domain administrator access implied and labels of type `SHARED` and `ADMIN`can be processed
|
||||
* `gam <UserTypeEntity> action ... adminaccess` - The user named in `<UserTypeEntty>` is used, adminaccess indicates that labels of type `SHARED` and `ADMIN`can be processed
|
||||
* `gam <UserTypeEntity> action ...` - The user named in `<UserTypeEntty>` is used, access is limited, onlylabels of type `SHARED` can be processed
|
||||
|
||||
## Display Drive Labels
|
||||
|
||||
@@ -156,3 +165,51 @@ gam <UserTypeEntity> process filedrivelabels <DriveFileEntity>
|
||||
|
||||
By default, details of the process labels are displayed, use `nodetails` to suppress this display.
|
||||
|
||||
## Manage Drive Label Permissions
|
||||
Create a permission for a Drive Label by specifying the label name and the principal.
|
||||
```
|
||||
gam [<UserTypeEntity>] create drivelabelpermission <DriveLabelNameEntity>
|
||||
(user <UserItem>) | (group <GroupItem) | (audience <String>)
|
||||
role applier|editor|organizer|reader
|
||||
[nodetails|formatjson] [adminaccess|asadmin]
|
||||
```
|
||||
|
||||
By default, when a permission is created, GAM outputs details of the permission as indented keywords and values.
|
||||
* `nodetails` - Suppress the details output.
|
||||
* `formatjson` - Output the details in JSON format.
|
||||
|
||||
Delete a Drive Label permission by specifying the label name and the principal.
|
||||
```
|
||||
gam [<UserTypeEntity>] delete drivelabelpermission <DriveLabelNameEntity>
|
||||
(user <UserItem>) | (group <GroupItem) | (audience <String>)
|
||||
[adminaccess|asadmin]
|
||||
```
|
||||
|
||||
Delete a Drive Label permission by specifying the label permission name.
|
||||
```
|
||||
gam [<UserTypeEntity>] remove drivelabelpermission <DriveLabelPermissionNameEntity>
|
||||
[adminaccess|asadmin]
|
||||
```
|
||||
## Display Drive Label Permissions
|
||||
Display permissions for a collection of Drive Label permission names.
|
||||
```
|
||||
gam [<UserTypeEntity>] show drivelabelpermissions <DriveLabelNameEntity>
|
||||
[formatjson] [adminaccess|asadmin]
|
||||
```
|
||||
|
||||
By default, Gam displays the information as an indented list of keys and values.
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
|
||||
```
|
||||
gam [<UserTypeEntity>] print drivelabelpermissions <DriveLabelNameEntity> [todrive <ToDriveAttribute>*]
|
||||
[formatjson [quotechar <Character>]] [adminaccess|asadmin]
|
||||
```
|
||||
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.
|
||||
When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output.
|
||||
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.
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
- [Print domain counts for users specified by `<UserTypeEntity>`](#print-domain-counts-for-users-specified-by-usertypeentity)
|
||||
- [Print user list](#print-user-list)
|
||||
- [Display user counts](#display-user-counts)
|
||||
- [Verify domain membership]($verify-domain-membership)
|
||||
|
||||
## API documentation
|
||||
* https://developers.google.com/admin-sdk/directory/reference/rest/v1/users
|
||||
@@ -981,14 +982,16 @@ gam print users [todrive <ToDriveAttribute>*]
|
||||
[limittoou <OrgUnitItem>] [deleted_only|only_deleted])
|
||||
[orderby <UserOrderByFieldName> [ascending|descending]]
|
||||
[groups|groupsincolumns]
|
||||
[license|licenses|licence|licences]
|
||||
[license|licenses|licence|licences|licensebyuser|licensesbyuser|licencebyuser|licencesbyuser]
|
||||
[onelicenseperrow|onelicenceperrow]
|
||||
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
||||
[schemas|custom|customschemas all|<SchemaNameList>]
|
||||
[emailpart|emailparts|username]
|
||||
[userview] [allfields|basic|full|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||
[showvalidcolumn] (addcsvdata <FieldName> <String>)*
|
||||
```
|
||||
|
||||
By default, users in all domains in the account are selected; these options allow selection of subsets of users:
|
||||
@@ -1008,11 +1011,13 @@ gam print users [todrive <ToDriveAttribute>*] select <UserTypeEntity>
|
||||
[onelicenseperrow|onelicenceperrow]
|
||||
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
||||
[schemas|custom|customschemas all|<SchemaNameList>]
|
||||
[emailpart|emailparts|username][schemas|custom all|<SchemaNameList>]
|
||||
[userview] [allfields|basic|full|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||
[emailpart|emailparts|username]
|
||||
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||
[showvalidcolumn] (addcsvdata <FieldName> <String>)*
|
||||
|
||||
gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
||||
[orderby <UserOrderByFieldName> [ascending|descending]]
|
||||
[groups|groupsincolumns]
|
||||
@@ -1021,10 +1026,11 @@ gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
||||
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
||||
[schemas|custom|customschemas all|<SchemaNameList>]
|
||||
[emailpart|emailparts|username]
|
||||
[userview] [allfields|basic|full|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||
[showvalidcolumn] (addcsvdata <FieldName> <String>)*
|
||||
```
|
||||
|
||||
By default, Gam gets no group membership information for each user. The `groups` and `groupsincolumns`
|
||||
@@ -1079,6 +1085,17 @@ In the output, primaryEmail is the always the first column; these options contro
|
||||
* `<UserFieldName>*|fields <UserFieldNameList>` - The columns appear in the order that the fields are specified.
|
||||
* `scalarsfirst [true]` - When columns are sorted by name, scalar fields appear before repeating fields.
|
||||
|
||||
By default, if `<UserTypeEntity>` includes an email address the is not a user member of the domain,
|
||||
an error message is generated.
|
||||
```
|
||||
User: testuserxxx@domain.com, Does not exist
|
||||
```
|
||||
|
||||
Using option `showvalidcolumn`, a new column `Found` indicates domain membership; no errors are generated
|
||||
|
||||
Add additional columns of data from the command line to the output
|
||||
* `addcsvdata <FieldName> <String>`
|
||||
|
||||
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.
|
||||
|
||||
@@ -1249,3 +1266,34 @@ count=$(gam print users query "orgUnitPath='/Students/Middle School'" showitemco
|
||||
Windows PowerShell
|
||||
count = & gam print users query "orgUnitPath='/Students/Middle School'" showitemcountonly
|
||||
```
|
||||
## Verify domain membership
|
||||
You have a CSV file of email addresses and want to verify of the addresses are valid users in your domain.
|
||||
```
|
||||
# Users.csv
|
||||
$ more Users.csv
|
||||
primaryEmail,name
|
||||
testuser1@domain.com,Test User 1
|
||||
testuserxxx@domain.com,Test User XXX
|
||||
testuser2@domain.com,Test User 2
|
||||
|
||||
# Without showvalidcolumn, non-domain users generate an error
|
||||
$ gam redirect csv - multiprocess csv Users.csv gam user "~primaryEmail" print users fields primaryemail,id addcsvdata name "~name"
|
||||
2024-02-23T11:29:00.407-08:00,0/3,Using 3 processes...
|
||||
2024-02-23T11:29:00.410-08:00,0,Processing item 3/3
|
||||
User: testuserxxx@domain.com, Does not exist
|
||||
2024-02-23T11:29:06.511-08:00,0/3,Processing complete
|
||||
primaryEmail,id,name
|
||||
testuser1@domain.com,118080758787650801331,Test User 1
|
||||
testuser2@domain.com,107344800159717682514,Test User 2
|
||||
|
||||
# Using showvalidcolumn, a new column `Valid` indicates domain membership; no errors are generated
|
||||
$ gam redirect csv - multiprocess csv Users.csv gam user "~primaryEmail" print users fields primaryemail,id addcsvdata name "~name" showvalidcolumn
|
||||
2024-02-23T11:29:22.287-08:00,0/3,Using 3 processes...
|
||||
2024-02-23T11:29:22.292-08:00,0,Processing item 3/3
|
||||
2024-02-23T11:29:23.366-08:00,0/3,Processing complete
|
||||
primaryEmail,id,Valid,name
|
||||
testuser1@domain.com,118080758787650801331,True,Test User 1
|
||||
testuserxxx@domain.com,,False,Test User XXX
|
||||
testuser2@domain.com,107344800159717682514,True,Test User 2
|
||||
```
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Print the current version of Gam with details
|
||||
```
|
||||
gam version
|
||||
GAMADV-XTD3 6.70.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.70.05 - 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.70.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.70.05 - 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.70.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.70.05 - 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.70.00
|
||||
Latest: 6.70.05
|
||||
echo $?
|
||||
1
|
||||
```
|
||||
@@ -72,7 +72,7 @@ echo $?
|
||||
Print the current version number without details
|
||||
```
|
||||
gam version simple
|
||||
6.70.00
|
||||
6.70.05
|
||||
```
|
||||
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.70.00 - https://github.com/taers232c/GAMADV-XTD3
|
||||
GAM 6.70.05 - 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
|
||||
|
||||
@@ -22,43 +22,6 @@ If an item contains spaces, it should be surrounded by ".
|
||||
<FalseValues>= false|off|no|disabled|0
|
||||
<TrueValues> ::= true|on|yes|enabled|1
|
||||
|
||||
<Charset> ::= ascii|latin1|mbcs|utf-8|utf-8-sig|utf-16|<String>
|
||||
<CalendarColorIndex> ::= <Number in range 1-24>
|
||||
<CalendarColorName> ::=
|
||||
amethyst|avocado|banana|basil|birch|blueberry|
|
||||
cherryblossom|citron|cobalt|cocoa|eucalyptus|flamingo|
|
||||
grape|graphite|lavender|mango|peacock|pistachio|
|
||||
pumpkin|radicchio|sage|tangerine|tomato|wisteria|
|
||||
<ColorHex> ::= "#<Hex><Hex><Hex><Hex><Hex><Hex>"
|
||||
<ColorNameGoogle> ::=
|
||||
asparagus|bluevelvet|bubblegum|cardinal|chocolateicecream|denim|desertsand|
|
||||
earthworm|macaroni|marsorange|mountaingray|mountaingrey|mouse|oldbrickred|
|
||||
pool|purpledino|purplerain|rainysky|seafoam|slimegreen|spearmint|
|
||||
toyeggplant|vernfern|wildstrawberries|yellowcab
|
||||
<ColorNameWeb> ::=
|
||||
aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|
|
||||
blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|
|
||||
cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|
|
||||
darkgrey|darkgreen|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|
|
||||
darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|
|
||||
darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|
|
||||
firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|
|
||||
gray|grey|green|greenyellow|honeydew|hotpink|indianred|indigo|ivory|khaki|
|
||||
lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|
|
||||
lightgoldenrodyellow|lightgray|lightgrey|lightgreen|lightpink|lightsalmon|
|
||||
lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|
|
||||
lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|
|
||||
mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|
|
||||
mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|
|
||||
navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|
|
||||
palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|
|
||||
peru|pink|plum|powderblue|purple|red|rosybrown|royalblue|saddlebrown|salmon|
|
||||
sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|
|
||||
slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|
|
||||
wheat|white|whitesmoke|yellow|yellowgreen
|
||||
<ColorName> ::= <ColorNameGoogle>|<ColorNameWeb>
|
||||
<ColorValue> ::= <ColorName>|<ColorHex>
|
||||
<DayOfWeek> ::= mon|tue|wed|thu|fri|sat|sun
|
||||
<BCP47LanguageCode> ::=
|
||||
ar-sa| # Arabic Saudi Arabia
|
||||
cs-cz| # Czech Czech Republic
|
||||
@@ -97,6 +60,43 @@ If an item contains spaces, it should be surrounded by ".
|
||||
zh-cn| # Chinese China
|
||||
zh-hk| # Chinese Hong Kong
|
||||
zh-tw # Chinese Taiwan
|
||||
<Charset> ::= ascii|latin1|mbcs|utf-8|utf-8-sig|utf-16|<String>
|
||||
<CalendarColorIndex> ::= <Number in range 1-24>
|
||||
<CalendarColorName> ::=
|
||||
amethyst|avocado|banana|basil|birch|blueberry|
|
||||
cherryblossom|citron|cobalt|cocoa|eucalyptus|flamingo|
|
||||
grape|graphite|lavender|mango|peacock|pistachio|
|
||||
pumpkin|radicchio|sage|tangerine|tomato|wisteria|
|
||||
<ColorHex> ::= "#<Hex><Hex><Hex><Hex><Hex><Hex>"
|
||||
<ColorNameGoogle> ::=
|
||||
asparagus|bluevelvet|bubblegum|cardinal|chocolateicecream|denim|desertsand|
|
||||
earthworm|macaroni|marsorange|mountaingray|mountaingrey|mouse|oldbrickred|
|
||||
pool|purpledino|purplerain|rainysky|seafoam|slimegreen|spearmint|
|
||||
toyeggplant|vernfern|wildstrawberries|yellowcab
|
||||
<ColorNameWeb> ::=
|
||||
aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|
|
||||
blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|
|
||||
cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|
|
||||
darkgrey|darkgreen|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|
|
||||
darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|
|
||||
darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|
|
||||
firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|
|
||||
gray|grey|green|greenyellow|honeydew|hotpink|indianred|indigo|ivory|khaki|
|
||||
lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|
|
||||
lightgoldenrodyellow|lightgray|lightgrey|lightgreen|lightpink|lightsalmon|
|
||||
lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|
|
||||
lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|
|
||||
mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|
|
||||
mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|
|
||||
navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|
|
||||
palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|
|
||||
peru|pink|plum|powderblue|purple|red|rosybrown|royalblue|saddlebrown|salmon|
|
||||
sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|
|
||||
slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|
|
||||
wheat|white|whitesmoke|yellow|yellowgreen
|
||||
<ColorName> ::= <ColorNameGoogle>|<ColorNameWeb>
|
||||
<ColorValue> ::= <ColorName>|<ColorHex>
|
||||
<DayOfWeek> ::= mon|tue|wed|thu|fri|sat|sun
|
||||
<EventColorIndex> ::= <Number in range 1-11>
|
||||
<EventColorName> ::=
|
||||
banana|basil|blueberry|flamingo|graphite|grape|
|
||||
@@ -267,7 +267,8 @@ If an item contains spaces, it should be surrounded by ".
|
||||
cloudidentity | identity | 1010010001 |
|
||||
cloudidentitypremium | identitypremium | 1010050001 |
|
||||
cloudsearch | 1010350001 |
|
||||
duetai | 1010470001 |
|
||||
geminibiz | 1010470003 |
|
||||
geminient| duetai | 1010470001 |
|
||||
gsuitebasic | gafb | gafw | basic | Google-Apps-For-Business |
|
||||
gsuitebusiness | gau | gsb | unlimited | Google-Apps-Unlimited |
|
||||
gsuitebusinessarchived | gsbau | businessarchived | 1010340002 |
|
||||
@@ -441,6 +442,7 @@ If an item contains spaces, it should be surrounded by ".
|
||||
<DriveLabelFieldID> ::= <String>
|
||||
<DriveLabelSelectionID> ::= <String>
|
||||
<DriveLabelName> ::= labels/<DriveLabelID>[@latest|@published|@<Number>]
|
||||
<DriveLabelPermissionName> ::= labels/<DriveLabelID>[@latest|@published|@<Number>]/permissions/(audiences|groups|people)/<String>
|
||||
<EmailAddress> ::= <String>@<DomainName>
|
||||
<EmailItem> ::= <EmailAddress>|<UniqueID>|<String>
|
||||
<EmailReplacement> ::= <String>
|
||||
@@ -583,6 +585,7 @@ If an item contains spaces, it should be surrounded by ".
|
||||
<StorageObjectName> ::= <String>
|
||||
<StorageBucketObjectName> ::=
|
||||
https://storage.cloud.google.com/<StorageBucketName>/<StorageObjectName>|
|
||||
https://storage.googleapis.com/<StorageBucketName>/<StorageObjectName>|
|
||||
gs://<StorageBucketName>/<StorageObjectName>|
|
||||
<StorageBucketName>/<StorageObjectName>
|
||||
<Tag> ::= <String>
|
||||
@@ -641,6 +644,7 @@ If an item contains spaces, it should be surrounded by ".
|
||||
<AssetTagList> ::= "<AssetTag>(,<AssetTag>)*"
|
||||
<CalendarACLScopeList> ::= "<CalendarACLScope>(,<CalendarACLScope>)*"
|
||||
<CalendarList> ::= "<CalendarItem>(,<CalendarItem>)*"
|
||||
<ChatSpaceList> ::= "<ChatSpace>(,<ChatSpace>)*"
|
||||
<CIGroupAliasList> ::= "<CIGroupAlias>(,<CIGroupAlias>)*"
|
||||
<CIGroupTypeList> ::= "<CIGroupType>(,<CIGroupType>)*"
|
||||
<ClassroomInvitationIDList> ::= "<ClassroomInvitationID>(,<ClassroomInvitationID>)*"
|
||||
@@ -673,6 +677,7 @@ If an item contains spaces, it should be surrounded by ".
|
||||
<DriveFolderNameList> ::= "<DriveFolderName>(,<DriveFolderName>)*"
|
||||
<DriveLabelIDList> ::= "<DriveLabelID>(,<DriveLabelID>)*"
|
||||
<DriveLabelNameList> ::= "<DriveLabelName>(,<DriveLabelName>)*"
|
||||
<DriveLabelPermissionNameList> ::= "<DriveLabelPermissionName>(,<DriveLabelPermissionName>)*"
|
||||
<DriveLabelFieldIDList> ::= "<DriveLabelFieldID>(,<DriveLabelFieldID>)*"
|
||||
<DriveLabelSelectionIDList> ::= "<DriveLabelSelectionID>(,<DriveLabelSelectionID>)*"
|
||||
<EmailAddressList> ::= "<EmailAddress>(,<EmailAddress>)*"
|
||||
@@ -1095,6 +1100,8 @@ Specify a collection of items by directly specifying them; the item type is dete
|
||||
<FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
|
||||
<DriveLabelNameEntity> ::=
|
||||
<DriveLabelNameList> | <FileSelector> | <CSVFileSelector> | <CSVDataSelector>
|
||||
<DriveLabelPermissionNameEntity> ::=
|
||||
<DriveLabelPermissionNameList> | <FileSelector> | <CSVFileSelector> | <CSVDataSelector>
|
||||
<EmailAddressEntity> ::=
|
||||
<EmailAddressList> | <FileSelector> | <CSVFileSelector> | <CSVkmdSelector> | <CSVDataSelector>
|
||||
<FilterIDEntity> ::=
|
||||
@@ -3395,6 +3402,21 @@ gam [<UserTypeEntity>] show drivelabels
|
||||
[basic|full] [languagecode <LanguageCode>]
|
||||
[publishedonly [<Boolean>]] [minimumrole applier|editor|organizer|reader]
|
||||
[formatjson] [adminaccess|asadmin]
|
||||
`
|
||||
gam [<UserTypeEntity>] create drivelabelpermission <DriveLabelNameEntity>
|
||||
(user <UserItem>) | (group <GroupItem) | (audience <String>)
|
||||
role applier|editor|organizer|reader
|
||||
[formatjson] [adminaccess|asadmin]
|
||||
gam [<UserTypeEntity>] delete drivelabelpermission <DriveLabelNameEntity>
|
||||
(user <UserItem>) | (group <GroupItem) | (audience <String>)
|
||||
[adminaccess|asadmin]
|
||||
gam [<UserTypeEntity>] remove drivelabelpermission <DriveLabelPermissionNameEntity>
|
||||
[adminaccess|asadmin]
|
||||
|
||||
gam [<UserTypeEntity>] print drivelabelpermissions <DriveLabelNameEntity> [todrive <ToDriveAttribute>*]
|
||||
[formatjson [quotechar <Character>]] [adminaccess|asadmin]
|
||||
gam [<UserTypeEntity>] show drivelabelpermissions <DriveLabelNameEntity>
|
||||
[formatjson] [adminaccess|asadmin]
|
||||
|
||||
# Email Audit Monitor
|
||||
|
||||
@@ -5413,10 +5435,11 @@ gam print users [todrive <ToDriveAttribute>*]
|
||||
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
||||
[schemas|custom|customschemas all|<SchemaNameList>]
|
||||
[emailpart|emailparts|username]
|
||||
[userview] [basic|full|allfields | <UserFieldName>* | fields <UserFieldNameList>]
|
||||
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||
[showvalidcolumn] (addcsvdata <FieldName> <String>)*
|
||||
[showitemcountonly]
|
||||
|
||||
Print fields for specified users.
|
||||
@@ -5429,10 +5452,11 @@ gam print users [todrive <ToDriveAttribute>*] select <UserTypeEntity>
|
||||
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
||||
[schemas|custom|customschemas all|<SchemaNameList>]
|
||||
[emailpart|emailparts|username]
|
||||
[userview] [basic|full|allfields | <UserFieldName>* | fields <UserFieldNameList>]
|
||||
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||
[showvalidcolumn] (addcsvdata <FieldName> <String>)*
|
||||
[showitemcountonly]
|
||||
|
||||
gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
||||
@@ -5443,10 +5467,11 @@ gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
||||
[(products|product <ProductIDList>)|(skus|sku <SKUIDList>)]
|
||||
[schemas|custom|customschemas all|<SchemaNameList>]
|
||||
[emailpart|emailparts|username]
|
||||
[userview] [basic|full|allfields | <UserFieldName>* | fields <UserFieldNameList>]
|
||||
[userview] [basic|full|allfields|(<UserFieldName>*|fields <UserFieldNameList>)]
|
||||
[delimiter <Character>] [sortheaders [<Boolean>]] [scalarsfirst [<Boolean>]]
|
||||
[formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||
[issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||
[showvalidcolumn] (addcsvdata <FieldName> <String>)*
|
||||
[showitemcountonly]
|
||||
|
||||
The first column will always be primaryEmail; the remaining field names will be sorted if allfields, basic, full or sortheaders is specified;
|
||||
|
||||
@@ -2,6 +2,43 @@
|
||||
|
||||
Merged GAM-Team version
|
||||
|
||||
6.70.05
|
||||
|
||||
Added commands to create|delete|display Drive Label permissions.
|
||||
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-Drive-Labels
|
||||
|
||||
6.70.04
|
||||
|
||||
Added option `showvalidcolumn` to `gam print users` that can be used to identify whether
|
||||
users are defined in the domain. Typically, you would read CSV file of email addresses
|
||||
to verify as domain members.
|
||||
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users#verify-domain-membership
|
||||
|
||||
Added option `addcsvdata <FieldName> <String>` to `gam print users` that adds
|
||||
additional columns of data to the CSV file output. Typically, you would read CSV file of email addresses
|
||||
to generate a CSV file of results and copy data from the input CSV to the outout CSV.
|
||||
|
||||
6.70.03
|
||||
|
||||
Renamed license product DuetAI to Gemini
|
||||
* ProductID - 101047
|
||||
|
||||
Renamed license SKU DuetAI for Google Workspace to Gemini Enterprise
|
||||
* ProductID - 101047
|
||||
* SKUID - 1010470001 | geminient | duetai
|
||||
|
||||
Added support for license SKU Gemini Business
|
||||
* ProductID - 101047
|
||||
* SKUID - 1010470003 | geminibiz
|
||||
|
||||
6.70.02
|
||||
|
||||
In 6.69.00, GAM starting using course owner access when using `copyfrom` in `gam create|update course`
|
||||
regardless of the value of `gam.cfg/use_course_owner_access`. This prevents copying from courses
|
||||
with a deleted user. GAM now uses the value of `gam.cfg/use_course_owner_access` when `copyfrom` is used.
|
||||
|
||||
6.70.01
|
||||
|
||||
Added `gmail_cse_incert_dir` and `gmail_cse_inkey_dir` path variables to `gam.cfg` that provide
|
||||
|
||||
@@ -42672,6 +42672,7 @@ USERS_INDEXED_TITLES = ['addresses', 'aliases', 'nonEditableAliases', 'emails',
|
||||
# [delimiter <Character>] [sortheaders] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||
# [issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||
# [showitemcountonly]
|
||||
# [showvalidcolumn] (addcsvdata <FieldName> <String>)*
|
||||
#
|
||||
# gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
||||
# [groups|groupsincolumns]
|
||||
@@ -42683,6 +42684,7 @@ USERS_INDEXED_TITLES = ['addresses', 'aliases', 'nonEditableAliases', 'emails',
|
||||
# [delimiter <Character>] [sortheaders] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
|
||||
# [issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||
# [showitemcountonly]
|
||||
# [showvalidcolumn] (addcsvdata <FieldName> <String>)*
|
||||
#
|
||||
# gam print users [todrive <ToDriveAttribute>*]
|
||||
# ([domain <DomainName>] [(query <QueryUser>)|(queries <QueryUserList>)]
|
||||
@@ -42690,6 +42692,7 @@ USERS_INDEXED_TITLES = ['addresses', 'aliases', 'nonEditableAliases', 'emails',
|
||||
# [formatjson [quotechar <Character>]] [countonly]
|
||||
# [issuspended <Boolean>] [aliasmatchpattern <RegularExpression>]
|
||||
# [showitemcountonly]
|
||||
# [showvalidcolumn] (addcsvdata <FieldName> <String>)*
|
||||
#
|
||||
# gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
||||
# [formatjson [quotechar <Character>]] [countonly]
|
||||
@@ -42697,16 +42700,23 @@ USERS_INDEXED_TITLES = ['addresses', 'aliases', 'nonEditableAliases', 'emails',
|
||||
# [showitemcountonly]
|
||||
def doPrintUsers(entityList=None):
|
||||
def _writeUserEntity(userEntity):
|
||||
if addCSVData:
|
||||
userEntity.update(addCSVData)
|
||||
row = flattenJSON(userEntity, skipObjects=USER_SKIP_OBJECTS, timeObjects=USER_TIME_OBJECTS)
|
||||
if not FJQC.formatJSON:
|
||||
csvPF.WriteRowTitles(row)
|
||||
elif csvPF.CheckRowTitles(row):
|
||||
csvPF.WriteRowNoFilter({'primaryEmail': userEntity['primaryEmail'],
|
||||
'JSON': json.dumps(cleanJSON(userEntity, skipObjects=USER_SKIP_OBJECTS, timeObjects=USER_TIME_OBJECTS),
|
||||
ensure_ascii=False, sort_keys=True)})
|
||||
row = {'primaryEmail': userEntity['primaryEmail']}
|
||||
if showValidColumn:
|
||||
row[showValidColumn] = userEntity[showValidColumn]
|
||||
row['JSON'] = json.dumps(cleanJSON(userEntity, skipObjects=USER_SKIP_OBJECTS, timeObjects=USER_TIME_OBJECTS),
|
||||
ensure_ascii=False, sort_keys=True)
|
||||
csvPF.WriteRowNoFilter(row)
|
||||
|
||||
def _printUser(userEntity, i, count):
|
||||
if isSuspended is None or isSuspended == userEntity.get('suspended', isSuspended):
|
||||
if showValidColumn:
|
||||
userEntity[showValidColumn] = True
|
||||
userEmail = userEntity['primaryEmail']
|
||||
if printOptions['emailParts']:
|
||||
if userEmail.find('@') != -1:
|
||||
@@ -42785,7 +42795,10 @@ def doPrintUsers(entityList=None):
|
||||
else:
|
||||
http_status, reason, message = checkGAPIError(exception)
|
||||
if reason in GAPI.USER_GET_THROW_REASONS:
|
||||
entityUnknownWarning(Ent.USER, ri[RI_ITEM], int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
||||
if not showValidColumn:
|
||||
entityUnknownWarning(Ent.USER, ri[RI_ITEM], int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
||||
else:
|
||||
_writeUserEntity({'primaryEmail': ri[RI_ITEM], showValidColumn: False})
|
||||
elif (reason == GAPI.INVALID_INPUT) and customFieldMask:
|
||||
entityActionFailedWarning([Ent.USER, ri[RI_ITEM]], invalidUserSchema(customFieldMask), int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
||||
elif reason not in GAPI.DEFAULT_RETRY_REASONS:
|
||||
@@ -42799,7 +42812,10 @@ def doPrintUsers(entityList=None):
|
||||
userKey=ri[RI_ITEM], projection=projection, customFieldMask=customFieldMask, viewType=viewType, fields=fields)
|
||||
_printUser(user, int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
||||
except (GAPI.userNotFound, GAPI.resourceNotFound):
|
||||
entityUnknownWarning(Ent.USER, ri[RI_ITEM], int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
||||
if not showValidColumn:
|
||||
entityUnknownWarning(Ent.USER, ri[RI_ITEM], int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
||||
else:
|
||||
_writeUserEntity({'primaryEmail': ri[RI_ITEM], showValidColumn: False})
|
||||
except (GAPI.domainNotFound, GAPI.domainCannotUseApis, GAPI.forbidden,
|
||||
GAPI.badRequest, GAPI.backendError, GAPI.systemError, GAPI.rateLimitExceeded) as e:
|
||||
entityActionFailedWarning([Ent.USER, ri[RI_ITEM]], str(e), int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
||||
@@ -42836,7 +42852,9 @@ def doPrintUsers(entityList=None):
|
||||
aliasMatchPattern = isSuspended = orgUnitPath = orgUnitPathLower = orderBy = sortOrder = None
|
||||
viewType = 'admin_view'
|
||||
delimiter = GC.Values[GC.CSV_OUTPUT_FIELD_DELIMITER]
|
||||
showValidColumn = ''
|
||||
showItemCountOnly = False
|
||||
addCSVData = {}
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if myarg == 'todrive':
|
||||
@@ -42913,6 +42931,11 @@ def doPrintUsers(entityList=None):
|
||||
quotePlusPhoneNumbers = True
|
||||
elif myarg == 'showitemcountonly':
|
||||
showItemCountOnly = True
|
||||
elif myarg == 'showvalidcolumn':
|
||||
showValidColumn = 'Valid'
|
||||
elif myarg == 'addcsvdata':
|
||||
k = getString(Cmd.OB_STRING)
|
||||
addCSVData[k] = getString(Cmd.OB_STRING, minLen=0)
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, False)
|
||||
_, _, entityList = getEntityArgument(entityList)
|
||||
@@ -42926,8 +42949,16 @@ def doPrintUsers(entityList=None):
|
||||
else:
|
||||
if FJQC.formatJSON:
|
||||
printOptions['sortHeaders'] = False
|
||||
csvPF.SetJSONTitles(['primaryEmail', 'JSON'])
|
||||
titles = ['primaryEmail']
|
||||
if showValidColumn:
|
||||
titles.append(showValidColumn)
|
||||
titles.append('JSON')
|
||||
csvPF.SetJSONTitles(titles)
|
||||
else:
|
||||
if showValidColumn:
|
||||
csvPF.AddTitles([showValidColumn])
|
||||
if addCSVData:
|
||||
csvPF.AddTitles(sorted(addCSVData.keys()))
|
||||
if printOptions['getGroupFeed']:
|
||||
if not printOptions['groupsInColumns']:
|
||||
csvPF.AddTitles(['GroupsCount', 'Groups'])
|
||||
@@ -43013,7 +43044,7 @@ def doPrintUsers(entityList=None):
|
||||
# If no individual fields were specified (allfields, basic, full) or individual fields other than primaryEmail were specified, look up each user
|
||||
if isSuspended is not None:
|
||||
fieldsList.append('suspended')
|
||||
if projectionSet or len(set(fieldsList)) > 1:
|
||||
if projectionSet or len(set(fieldsList)) > 1 or showValidColumn:
|
||||
jcount = len(entityList)
|
||||
fields = getFieldsFromFieldsList(fieldsList)
|
||||
if GC.Values[GC.BATCH_SIZE] > 1 and jcount > 1:
|
||||
@@ -43045,7 +43076,10 @@ def doPrintUsers(entityList=None):
|
||||
userKey=userEmail, projection=projection, customFieldMask=customFieldMask, viewType=viewType, fields=fields)
|
||||
_printUser(user, j, jcount)
|
||||
except (GAPI.userNotFound, GAPI.resourceNotFound):
|
||||
entityUnknownWarning(Ent.USER, userEmail, j, jcount)
|
||||
if not showValidColumn:
|
||||
entityUnknownWarning(Ent.USER, userEmail, j, jcount)
|
||||
else:
|
||||
_writeUserEntity({'primaryEmail': userEmail, showValidColumn: False})
|
||||
except (GAPI.domainNotFound, GAPI.domainCannotUseApis, GAPI.forbidden,
|
||||
GAPI.badRequest, GAPI.backendError, GAPI.systemError, GAPI.rateLimitExceeded) as e:
|
||||
entityActionFailedWarning([Ent.USER, userEmail], str(e), j, jcount)
|
||||
@@ -44381,10 +44415,12 @@ class CourseAttributes():
|
||||
else:
|
||||
return True
|
||||
# ocroom - copyfrom course owner
|
||||
if self.announcementStates or self.materialStates or self.workStates or self.copyTopics or self.members != 'none':
|
||||
_, self.ocroom = buildGAPIServiceObject(API.CLASSROOM, f'uid:{self.ownerId}')
|
||||
if self.ocroom is None:
|
||||
return False
|
||||
self.ocroom = self.croom
|
||||
if GC.Values[GC.USE_COURSE_OWNER_ACCESS]:
|
||||
if self.announcementStates or self.materialStates or self.workStates or self.copyTopics or self.members != 'none':
|
||||
_, self.ocroom = buildGAPIServiceObject(API.CLASSROOM, f'uid:{self.ownerId}')
|
||||
if self.ocroom is None:
|
||||
return False
|
||||
if self.members != 'none':
|
||||
_, self.teachers, self.students = _getCourseAliasesMembers(self.croom, self.ocroom, self.courseId, {'members': self.members},
|
||||
'nextPageToken,teachers(profile(emailAddress,id))',
|
||||
@@ -61141,7 +61177,7 @@ def doPrintShowDriveFileACLs():
|
||||
printShowDriveFileACLs([_getAdminEmail()], True)
|
||||
|
||||
DRIVELABELS_PROJECTION_CHOICE_MAP = {'basic': 'LABEL_VIEW_BASIC', 'full': 'LABEL_VIEW_FULL'}
|
||||
DRIVELABELS_MINIMUM_ROLE_MAP = {
|
||||
DRIVELABELS_PERMISSION_ROLE_MAP = {
|
||||
'applier': 'APPLIER',
|
||||
'editor': 'EDITOR',
|
||||
'organizer': 'ORGANIZER',
|
||||
@@ -61160,7 +61196,7 @@ def _getDisplayDriveLabelsParameters(myarg, parameters):
|
||||
elif myarg == 'publishedonly':
|
||||
parameters['publishedOnly'] = getBoolean()
|
||||
elif myarg == 'minimumrole':
|
||||
parameters['minimumRole'] = getChoice(DRIVELABELS_MINIMUM_ROLE_MAP, mapChoice=True)
|
||||
parameters['minimumRole'] = getChoice(DRIVELABELS_PERMISSION_ROLE_MAP, mapChoice=True)
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
@@ -61178,6 +61214,22 @@ def normalizeDriveLabelName(driveLabelName):
|
||||
return driveLabelName
|
||||
return f'labels/{driveLabelName}'
|
||||
|
||||
def validateDriveLabelName(name, kvList, j, jcount, permName=False):
|
||||
name = normalizeDriveLabelName(name)
|
||||
# Label name
|
||||
if not permName:
|
||||
mg = re.match(r'^(labels/[^/]+)$', name)
|
||||
if not mg:
|
||||
entityActionNotPerformedWarning(kvList, 'Expected labels/<String>', j, jcount)
|
||||
return None
|
||||
return name
|
||||
# Label permission name
|
||||
mg = re.match(r'^(labels/[^/]+)/permissions/(?:audiences|groups|people)/.+$', name)
|
||||
if not mg:
|
||||
entityActionNotPerformedWarning(kvList, 'Expected labels/<String>/permissions/(audiences|groups|people)/<String>', j, jcount)
|
||||
return (None, None)
|
||||
return (name, mg.group(1))
|
||||
|
||||
def _showDriveLabel(label, j, jcount, FJQC):
|
||||
if FJQC.formatJSON:
|
||||
printLine(json.dumps(cleanJSON(label, timeObjects=DRIVELABELS_TIME_OBJECTS), ensure_ascii=False, sort_keys=True))
|
||||
@@ -61191,7 +61243,7 @@ def _showDriveLabel(label, j, jcount, FJQC):
|
||||
# [[basic|full] [languagecode <BCP47LanguageCode>]
|
||||
# [formatjson] [adminaccess|asadmin]
|
||||
def infoDriveLabels(users, useAdminAccess=False):
|
||||
driveLabelNameEntity = getUserObjectEntity(Cmd.OB_DRIVE_LABEL_NAME, Ent.DRIVE_LABEL_NAME, shlexSplit=True)
|
||||
driveLabelNameEntity = getUserObjectEntity(Cmd.OB_DRIVE_LABEL_NAME, Ent.DRIVE_LABEL, shlexSplit=True)
|
||||
FJQC = FormatJSONQuoteChar()
|
||||
parameters = {'useAdminAccess': useAdminAccess}
|
||||
while Cmd.ArgumentsRemaining():
|
||||
@@ -61204,15 +61256,18 @@ def infoDriveLabels(users, useAdminAccess=False):
|
||||
i, count, users = getEntityArgument(users)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, drive, noteNames, jcount = _validateUserGetObjectList(user, i, count, driveLabelNameEntity,
|
||||
api=api, showAction=FJQC is None or not FJQC.formatJSON)
|
||||
user, drive, labelNames, jcount = _validateUserGetObjectList(user, i, count, driveLabelNameEntity,
|
||||
api=api, showAction=not FJQC.formatJSON)
|
||||
if jcount == 0:
|
||||
continue
|
||||
Ind.Increment()
|
||||
j = 0
|
||||
for name in noteNames:
|
||||
for name in labelNames:
|
||||
j += 1
|
||||
name = normalizeDriveLabelName(name)
|
||||
kvList = [Ent.USER, user, Ent.DRIVE_LABEL_NAME, name]
|
||||
name = validateDriveLabelName(name, kvList, j, jcount, False)
|
||||
if name is None:
|
||||
continue
|
||||
try:
|
||||
label = callGAPI(drive.labels(), 'get',
|
||||
bailOnInternalError=True,
|
||||
@@ -61221,13 +61276,14 @@ def infoDriveLabels(users, useAdminAccess=False):
|
||||
name=name, **parameters)
|
||||
_showDriveLabel(label, j, jcount, FJQC)
|
||||
except GAPI.notFound as e:
|
||||
entityActionFailedWarning([Ent.USER, user, Ent.DRIVE_LABEL_NAME, name], str(e), j, jcount)
|
||||
entityActionFailedWarning(kvList, str(e), j, jcount)
|
||||
except (GAPI.permissionDenied, GAPI.invalidArgument, GAPI.internalError) as e:
|
||||
entityActionFailedWarning([Ent.USER, user, Ent.DRIVE_LABEL_NAME, name], str(e), j, jcount)
|
||||
entityActionFailedWarning(kvList, str(e), j, jcount)
|
||||
break
|
||||
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||
userSvcNotApplicableOrDriveDisabled(user, str(e), i, count)
|
||||
break
|
||||
Ind.Decrement()
|
||||
|
||||
def doInfoDriveLabels():
|
||||
infoDriveLabels([_getAdminEmail()], True)
|
||||
@@ -61270,7 +61326,7 @@ def printShowDriveLabels(users, useAdminAccess=False):
|
||||
labels = callGAPIpages(drive.labels(), 'list', 'labels',
|
||||
pageMessage=pageMessage,
|
||||
throwReasons=GAPI.DRIVE_USER_THROW_REASONS+[GAPI.PERMISSION_DENIED],
|
||||
**parameters, fields='nextPageToken,labels', pageSize=GC.Values[GC.DRIVE_MAX_RESULTS])
|
||||
**parameters, fields='nextPageToken,labels', pageSize=200)
|
||||
if not csvPF:
|
||||
jcount = len(labels)
|
||||
if not FJQC.formatJSON:
|
||||
@@ -61301,6 +61357,234 @@ def printShowDriveLabels(users, useAdminAccess=False):
|
||||
def doPrintShowDriveLabels():
|
||||
printShowDriveLabels([_getAdminEmail()], True)
|
||||
|
||||
def _showDriveLabelPermission(labelperm, j, jcount, FJQC):
|
||||
if FJQC.formatJSON:
|
||||
printLine(json.dumps(cleanJSON(labelperm), ensure_ascii=False, sort_keys=True))
|
||||
return
|
||||
printEntity([Ent.DRIVE_LABEL_PERMISSION_NAME, f'{labelperm["name"]}'], j, jcount)
|
||||
Ind.Increment()
|
||||
showJSON(None, labelperm)
|
||||
Ind.Decrement()
|
||||
|
||||
# gam [<UserTypeEntity>] create drivelabelpermission <DriveLabelNameEntity>
|
||||
# (user <UserItem>) | (group <GroupItem) | (audience <String>)
|
||||
# role applier|editor|organizer|reader
|
||||
# [nodetails|formatjson] [adminaccess|asadmin]
|
||||
def createDriveLabelPermissions(users, useAdminAccess=False):
|
||||
driveLabelNameEntity = getUserObjectEntity(Cmd.OB_DRIVE_LABEL_NAME, Ent.DRIVE_LABEL_PERMISSION, shlexSplit=True)
|
||||
FJQC = FormatJSONQuoteChar()
|
||||
parameters = {'useAdminAccess': useAdminAccess}
|
||||
body = {}
|
||||
showDetails = True
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if myarg in ADMIN_ACCESS_OPTIONS:
|
||||
parameters['useAdminAccess'] = True
|
||||
elif myarg == 'role':
|
||||
body['role'] = getChoice(DRIVELABELS_PERMISSION_ROLE_MAP, mapChoice=True)
|
||||
elif myarg in {'user', 'group'}:
|
||||
email = getEmailAddress(returnUIDprefix='id:')
|
||||
body['email'], status = convertUIDtoEmailAddressWithType(email, emailTypes=[myarg])
|
||||
if status == 'unknown':
|
||||
Cmd.Backup()
|
||||
usageErrorExit(Msg.ENTITY_DOES_NOT_EXIST.format(email))
|
||||
elif myarg == 'audience':
|
||||
audience = getString(Cmd.OB_STRING)
|
||||
if not audience.startswith('audiences/'):
|
||||
audience = 'audiences/'+audience
|
||||
body['audience'] = audience
|
||||
elif myarg == 'nodetails':
|
||||
showDetails = False
|
||||
else:
|
||||
FJQC.GetFormatJSON(myarg)
|
||||
if 'role' not in body:
|
||||
missingArgumentExit(f'role {"|".join(DRIVELABELS_PERMISSION_ROLE_MAP.keys())}')
|
||||
if 'email' not in body and 'audience' not in body:
|
||||
missingArgumentExit('(user <UserItem>) | (group <GroupItem) | (audience <String>)')
|
||||
api = API.DRIVELABELS_ADMIN if parameters['useAdminAccess'] else API.DRIVELABELS_USER
|
||||
i, count, users = getEntityArgument(users)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, drive, labelNames, jcount = _validateUserGetObjectList(user, i, count, driveLabelNameEntity,
|
||||
api=api, showAction=not FJQC.formatJSON)
|
||||
if jcount == 0:
|
||||
continue
|
||||
Ind.Increment()
|
||||
j = 0
|
||||
for name in labelNames:
|
||||
j += 1
|
||||
kvList = [Ent.USER, user, Ent.DRIVE_LABEL_NAME, name, Ent.DRIVE_LABEL_PERMISSION, None]
|
||||
name = validateDriveLabelName(name, kvList, j, jcount, False)
|
||||
if name is None:
|
||||
continue
|
||||
try:
|
||||
labelperm = callGAPI(drive.labels().permissions(), 'create',
|
||||
bailOnInternalError=True,
|
||||
throwReasons=GAPI.DRIVE_USER_THROW_REASONS+[GAPI.PERMISSION_DENIED, GAPI.NOT_FOUND,
|
||||
GAPI.INVALID, GAPI.INTERNAL_ERROR],
|
||||
parent=name, body=body, **parameters)
|
||||
kvList = [Ent.USER, user, Ent.DRIVE_LABEL_PERMISSION, labelperm['name']]
|
||||
if not FJQC.formatJSON:
|
||||
entityActionPerformed(kvList, j, jcount)
|
||||
if showDetails:
|
||||
Ind.Increment()
|
||||
_showDriveLabelPermission(labelperm, j, jcount, FJQC)
|
||||
Ind.Decrement()
|
||||
except (GAPI.permissionDenied, GAPI.notFound, GAPI.invalid, GAPI.internalError) as e:
|
||||
entityActionFailedWarning(kvList, str(e), j, jcount)
|
||||
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||
userSvcNotApplicableOrDriveDisabled(user, str(e), i, count)
|
||||
break
|
||||
Ind.Decrement()
|
||||
|
||||
def doCreateDriveLabelPermissions():
|
||||
createDriveLabelPermissions([_getAdminEmail()], True)
|
||||
|
||||
# gam [<UserTypeEntity>] delete drivelabelpermission <DriveLabelNameEntity>
|
||||
# (user <UserItem>) | (group <GroupItem) | (audience <String>)
|
||||
# [adminaccess|asadmin]
|
||||
# gam [<UserTypeEntity>] remove drivelabelpermission <DriveLabelPermissionNameEntity>
|
||||
# [adminaccess|asadmin]
|
||||
def deleteDriveLabelPermissions(users, useAdminAccess=False):
|
||||
doDelete = Act.Get() == Act.DELETE
|
||||
if doDelete:
|
||||
driveLabelNameEntity = getUserObjectEntity(Cmd.OB_DRIVE_LABEL_NAME, Ent.DRIVE_LABEL, shlexSplit=True)
|
||||
else:
|
||||
driveLabelNameEntity = getUserObjectEntity(Cmd.OB_DRIVE_LABEL_PERMISSION_NAME, Ent.DRIVE_LABEL_PERMISSION, shlexSplit=True)
|
||||
parameters = {'useAdminAccess': useAdminAccess, 'requests': [None]}
|
||||
labelperm = ''
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if myarg in ADMIN_ACCESS_OPTIONS:
|
||||
parameters['useAdminAccess'] = True
|
||||
elif doDelete and myarg in {'user', 'group'}:
|
||||
labelperm = ['people/', 'groups/'][myarg == 'group']+convertEmailAddressToUID(getEmailAddress(), cd=None, emailType=myarg, savedLocation=None)
|
||||
elif doDelete and myarg == 'audience':
|
||||
audience = getString(Cmd.OB_STRING)
|
||||
if not audience.startswith('audiences/'):
|
||||
audience = 'audiences/'+audience
|
||||
labelperm = audience
|
||||
else:
|
||||
unknownArgumentExit()
|
||||
if doDelete and not labelperm:
|
||||
missingArgumentExit('(user <UserItem>) | (group <GroupItem) | (audience <String>)')
|
||||
api = API.DRIVELABELS_ADMIN if parameters['useAdminAccess'] else API.DRIVELABELS_USER
|
||||
i, count, users = getEntityArgument(users)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, drive, labelPermNames, jcount = _validateUserGetObjectList(user, i, count, driveLabelNameEntity,
|
||||
api=api, showAction=True)
|
||||
if jcount == 0:
|
||||
continue
|
||||
Ind.Increment()
|
||||
j = 0
|
||||
for name in labelPermNames:
|
||||
j += 1
|
||||
kvList = [Ent.USER, user, Ent.DRIVE_LABEL_PERMISSION_NAME, name]
|
||||
if doDelete:
|
||||
parent = validateDriveLabelName(name, kvList, j, jcount, False)
|
||||
if parent is None:
|
||||
continue
|
||||
name = parent+'/permissions/'+labelperm
|
||||
else:
|
||||
name, parent = validateDriveLabelName(name, kvList, j, jcount, True)
|
||||
if name is None:
|
||||
continue
|
||||
kvList[-1] = name
|
||||
parameters['requests'][0] = {'name': name}
|
||||
try:
|
||||
callGAPI(drive.labels().permissions(), 'batchDelete',
|
||||
throwReasons=GAPI.DRIVE_USER_THROW_REASONS+[GAPI.PERMISSION_DENIED, GAPI.INVALID, GAPI.NOT_FOUND],
|
||||
parent=parent, body=parameters)
|
||||
entityActionPerformed(kvList, j, jcount)
|
||||
except (GAPI.permissionDenied, GAPI.invalid, GAPI.notFound) as e:
|
||||
entityActionFailedWarning(kvList, str(e), j, jcount)
|
||||
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||
userSvcNotApplicableOrDriveDisabled(user, str(e), i, count)
|
||||
break
|
||||
Ind.Decrement()
|
||||
|
||||
def doDeleteDriveLabelPermissions():
|
||||
deleteDriveLabelPermissions([_getAdminEmail()], True)
|
||||
|
||||
# gam [<UserTypeEntity>] print drivelabelpermissions <DriveLabelNameEntity> [todrive <ToDriveAttribute>*]
|
||||
# [formatjson [quotechar <Character>]] [adminaccess|asadmin]
|
||||
# gam [<UserTypeEntity>] show drivelabelpermissions <DriveLabelNameEntity>
|
||||
# [formatjson] [adminaccess|asadmin]
|
||||
def printShowDriveLabelPermissions(users, useAdminAccess=False):
|
||||
csvPF = CSVPrintFile(['User', 'name', 'email', 'role', 'person', 'group', 'audience'], 'sortall') if Act.csvFormat() else None
|
||||
driveLabelNameEntity = getUserObjectEntity(Cmd.OB_DRIVE_LABEL_NAME, Ent.DRIVE_LABEL_PERMISSION, shlexSplit=True)
|
||||
FJQC = FormatJSONQuoteChar(csvPF)
|
||||
parameters = {'useAdminAccess': useAdminAccess}
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = getArgument()
|
||||
if csvPF and myarg == 'todrive':
|
||||
csvPF.GetTodriveParameters()
|
||||
elif myarg in ADMIN_ACCESS_OPTIONS:
|
||||
parameters['useAdminAccess'] = True
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, True)
|
||||
if csvPF and FJQC.formatJSON:
|
||||
csvPF.SetJSONTitles(['User', 'name', 'JSON'])
|
||||
api = API.DRIVELABELS_ADMIN if parameters['useAdminAccess'] else API.DRIVELABELS_USER
|
||||
i, count, users = getEntityArgument(users)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, drive, labelNames, jcount = _validateUserGetObjectList(user, i, count, driveLabelNameEntity,
|
||||
api=api, showAction=FJQC is None or not FJQC.formatJSON)
|
||||
if jcount == 0:
|
||||
continue
|
||||
Ind.Increment()
|
||||
j = 0
|
||||
for name in labelNames:
|
||||
j += 1
|
||||
kvList = [Ent.USER, user, Ent.DRIVE_LABEL_NAME, name, Ent.DRIVE_LABEL_PERMISSION, None]
|
||||
name = validateDriveLabelName(name, kvList, j, jcount, False)
|
||||
if name is None:
|
||||
continue
|
||||
kvList = [Ent.USER, user, Ent.DRIVE_LABEL_NAME, name]
|
||||
if csvPF:
|
||||
printGettingAllEntityItemsForWhom(Ent.DRIVE_LABEL_PERMISSION, name, j, jcount)
|
||||
pageMessage = getPageMessageForWhom()
|
||||
else:
|
||||
pageMessage = None
|
||||
try:
|
||||
labelperms = callGAPIpages(drive.labels().permissions(), 'list', 'labelPermissions',
|
||||
pageMessage=pageMessage,
|
||||
throwReasons=GAPI.DRIVE_USER_THROW_REASONS+[GAPI.PERMISSION_DENIED, GAPI.NOT_FOUND],
|
||||
parent=name, **parameters, fields='nextPageToken,labelPermissions', pageSize=200)
|
||||
if not csvPF:
|
||||
jcount = len(labelperms)
|
||||
if not FJQC.formatJSON:
|
||||
entityPerformActionNumItems(kvList, jcount, Ent.DRIVE_LABEL_PERMISSION, i, count)
|
||||
Ind.Increment()
|
||||
j = 0
|
||||
for labelperm in labelperms:
|
||||
j += 1
|
||||
_showDriveLabelPermission(labelperm, j, jcount, FJQC)
|
||||
Ind.Decrement()
|
||||
else:
|
||||
for labelperm in labelperms:
|
||||
row = flattenJSON(labelperm, flattened={'User': user})
|
||||
if not FJQC.formatJSON:
|
||||
csvPF.WriteRowTitles(row)
|
||||
elif csvPF.CheckRowTitles(row):
|
||||
row = {'User': user, 'name': labelperm['name']}
|
||||
row['JSON'] = json.dumps(cleanJSON(labelperm),
|
||||
ensure_ascii=False, sort_keys=True)
|
||||
csvPF.WriteRowNoFilter(row)
|
||||
except (GAPI.permissionDenied, GAPI.notFound) as e:
|
||||
entityActionFailedWarning(kvList, str(e), j, jcount)
|
||||
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||
userSvcNotApplicableOrDriveDisabled(user, str(e), i, count)
|
||||
break
|
||||
Ind.Decrement()
|
||||
if csvPF:
|
||||
csvPF.writeCSVfile('Drive Label Permissions')
|
||||
|
||||
def doPrintShowDriveLabelPermissions():
|
||||
printShowDriveLabelPermissions([_getAdminEmail()], True)
|
||||
|
||||
DRIVELABEL_FIELD_TYPE_MAP = {
|
||||
'text': 'setTextValues',
|
||||
'selection': 'setSelectionValues',
|
||||
@@ -61404,6 +61688,7 @@ def processFileDriveLabels(users):
|
||||
entityActionFailedWarning(kvList, str(e), j, jcount)
|
||||
break
|
||||
except (GAPI.notFound, GAPI.forbidden, GAPI.internalError,
|
||||
GAPI.fileNeverWritable, GAPI.applyLabelForbidden,
|
||||
GAPI.insufficientFilePermissions, GAPI.unknownError, GAPI.invalidInput, GAPI.badRequest,
|
||||
GAPI.labelMutationUnknownField, GAPI.labelMutationIllegalSelection, GAPI.labelMutationForbidden,
|
||||
GAPI.labelMultipleValuesForSingularField) as e:
|
||||
@@ -71707,6 +71992,7 @@ MAIN_ADD_CREATE_FUNCTIONS = {
|
||||
Cmd.ARG_DOMAIN: doCreateDomain,
|
||||
Cmd.ARG_DOMAINALIAS: doCreateDomainAlias,
|
||||
Cmd.ARG_DRIVEFILEACL: doCreateDriveFileACL,
|
||||
Cmd.ARG_DRIVELABELPERMISSION: doCreateDriveLabelPermissions,
|
||||
Cmd.ARG_FEATURE: doCreateFeature,
|
||||
Cmd.ARG_GCPSERVICEACCOUNT: doCreateGCPServiceAccount,
|
||||
Cmd.ARG_GROUP: doCreateGroup,
|
||||
@@ -71819,6 +72105,7 @@ MAIN_COMMANDS_WITH_OBJECTS = {
|
||||
Cmd.ARG_DOMAINALIAS: doDeleteDomainAlias,
|
||||
Cmd.ARG_DOMAINCONTACT: doDeleteDomainContacts,
|
||||
Cmd.ARG_DRIVEFILEACL: doDeleteDriveFileACLs,
|
||||
Cmd.ARG_DRIVELABELPERMISSION: doDeleteDriveLabelPermissions,
|
||||
Cmd.ARG_FEATURE: doDeleteFeature,
|
||||
Cmd.ARG_GROUP: doDeleteGroups,
|
||||
Cmd.ARG_GUARDIAN: doDeleteGuardian,
|
||||
@@ -71996,6 +72283,7 @@ MAIN_COMMANDS_WITH_OBJECTS = {
|
||||
Cmd.ARG_DOMAINCONTACT: doPrintShowDomainContacts,
|
||||
Cmd.ARG_DRIVEFILEACL: doPrintShowDriveFileACLs,
|
||||
Cmd.ARG_DRIVELABEL: doPrintShowDriveLabels,
|
||||
Cmd.ARG_DRIVELABELPERMISSION: doPrintShowDriveLabelPermissions,
|
||||
Cmd.ARG_FEATURE: doPrintShowFeatures,
|
||||
Cmd.ARG_GAL: doPrintShowGAL,
|
||||
Cmd.ARG_GROUP: doPrintGroups,
|
||||
@@ -72042,6 +72330,7 @@ MAIN_COMMANDS_WITH_OBJECTS = {
|
||||
'remove':
|
||||
(Act.REMOVE,
|
||||
{Cmd.ARG_ALIAS: doRemoveAliases,
|
||||
Cmd.ARG_DRIVELABELPERMISSION: doDeleteDriveLabelPermissions,
|
||||
}
|
||||
),
|
||||
'reopen':
|
||||
@@ -72109,6 +72398,7 @@ MAIN_COMMANDS_WITH_OBJECTS = {
|
||||
Cmd.ARG_DOMAINCONTACT: doPrintShowDomainContacts,
|
||||
Cmd.ARG_DRIVEFILEACL: doPrintShowDriveFileACLs,
|
||||
Cmd.ARG_DRIVELABEL: doPrintShowDriveLabels,
|
||||
Cmd.ARG_DRIVELABELPERMISSION: doPrintShowDriveLabelPermissions,
|
||||
Cmd.ARG_FEATURE: doPrintShowFeatures,
|
||||
Cmd.ARG_GAL: doPrintShowGAL,
|
||||
Cmd.ARG_GROUPMEMBERS: doShowGroupMembers,
|
||||
@@ -72294,6 +72584,7 @@ MAIN_COMMANDS_OBJ_ALIASES = {
|
||||
Cmd.ARG_DOMAINPROFILES: Cmd.ARG_PEOPLEPROFILE,
|
||||
Cmd.ARG_DRIVEFILEACLS: Cmd.ARG_DRIVEFILEACL,
|
||||
Cmd.ARG_DRIVELABELS: Cmd.ARG_DRIVELABEL,
|
||||
Cmd.ARG_DRIVELABELPERMISSIONS: Cmd.ARG_DRIVELABELPERMISSION,
|
||||
Cmd.ARG_EXPORT: Cmd.ARG_VAULTEXPORT,
|
||||
Cmd.ARG_EXPORTS: Cmd.ARG_VAULTEXPORT,
|
||||
Cmd.ARG_FEATURES: Cmd.ARG_FEATURE,
|
||||
@@ -72706,6 +72997,7 @@ USER_ADD_CREATE_FUNCTIONS = {
|
||||
Cmd.ARG_DRIVEFILEACL: createDriveFileACL,
|
||||
Cmd.ARG_DRIVEFILESHORTCUT: createDriveFileShortcut,
|
||||
Cmd.ARG_DRIVEFOLDERPATH: createDriveFolderPath,
|
||||
Cmd.ARG_DRIVELABELPERMISSION: createDriveLabelPermissions,
|
||||
Cmd.ARG_EVENT: createCalendarEvent,
|
||||
Cmd.ARG_FILTER: createFilter,
|
||||
Cmd.ARG_FOCUSTIME: createFocusTime,
|
||||
@@ -72817,6 +73109,7 @@ USER_COMMANDS_WITH_OBJECTS = {
|
||||
Cmd.ARG_DELEGATE: processDelegates,
|
||||
Cmd.ARG_DRIVEFILE: deleteDriveFile,
|
||||
Cmd.ARG_DRIVEFILEACL: deleteDriveFileACLs,
|
||||
Cmd.ARG_DRIVELABELPERMISSION: deleteDriveLabelPermissions,
|
||||
Cmd.ARG_EMPTYDRIVEFOLDERS: deleteEmptyDriveFolders,
|
||||
Cmd.ARG_EVENT: deleteCalendarEvents,
|
||||
Cmd.ARG_FILEREVISION: deleteFileRevisions,
|
||||
@@ -72991,6 +73284,7 @@ USER_COMMANDS_WITH_OBJECTS = {
|
||||
Cmd.ARG_DRIVEACTIVITY: printDriveActivity,
|
||||
Cmd.ARG_DRIVEFILEACL: printShowDriveFileACLs,
|
||||
Cmd.ARG_DRIVELABEL: printShowDriveLabels,
|
||||
Cmd.ARG_DRIVELABELPERMISSION: printShowDriveLabelPermissions,
|
||||
Cmd.ARG_DRIVESETTINGS: printShowDriveSettings,
|
||||
Cmd.ARG_EMPTYDRIVEFOLDERS: printEmptyDriveFolders,
|
||||
Cmd.ARG_EVENT: printShowCalendarEvents,
|
||||
@@ -73055,6 +73349,7 @@ USER_COMMANDS_WITH_OBJECTS = {
|
||||
(Act.REMOVE,
|
||||
{Cmd.ARG_CALENDAR: removeCalendars,
|
||||
Cmd.ARG_CHATMEMBER: deleteUpdateChatMember,
|
||||
Cmd.ARG_DRIVELABELPERMISSION: deleteDriveLabelPermissions,
|
||||
}
|
||||
),
|
||||
'replacedomain':
|
||||
@@ -73090,6 +73385,7 @@ USER_COMMANDS_WITH_OBJECTS = {
|
||||
Cmd.ARG_DRIVEACTIVITY: printDriveActivity,
|
||||
Cmd.ARG_DRIVEFILEACL: printShowDriveFileACLs,
|
||||
Cmd.ARG_DRIVELABEL: printShowDriveLabels,
|
||||
Cmd.ARG_DRIVELABELPERMISSION: printShowDriveLabelPermissions,
|
||||
Cmd.ARG_DRIVESETTINGS: printShowDriveSettings,
|
||||
Cmd.ARG_EVENT: printShowCalendarEvents,
|
||||
Cmd.ARG_FILECOUNT: printShowFileCounts,
|
||||
@@ -73304,6 +73600,7 @@ USER_COMMANDS_OBJ_ALIASES = {
|
||||
Cmd.ARG_FILEDRIVELABELS: Cmd.ARG_FILEDRIVELABEL,
|
||||
Cmd.ARG_DRIVEFILESHORTCUTS: Cmd.ARG_DRIVEFILESHORTCUT,
|
||||
Cmd.ARG_DRIVELABELS: Cmd.ARG_DRIVELABEL,
|
||||
Cmd.ARG_DRIVELABELPERMISSIONS: Cmd.ARG_DRIVELABELPERMISSION,
|
||||
Cmd.ARG_EVENTS: Cmd.ARG_EVENT,
|
||||
Cmd.ARG_FILECOUNTS: Cmd.ARG_FILECOUNT,
|
||||
Cmd.ARG_FILEPATHS: Cmd.ARG_FILEPATH,
|
||||
|
||||
@@ -567,6 +567,8 @@ class GamCLArgs():
|
||||
ARG_DRIVEFOLDERPATH = 'drivefolderpath'
|
||||
ARG_DRIVELABEL = 'drivelabel'
|
||||
ARG_DRIVELABELS = 'drivelabels'
|
||||
ARG_DRIVELABELPERMISSION = 'drivelabelpermission'
|
||||
ARG_DRIVELABELPERMISSIONS = 'drivelabelpermissions'
|
||||
ARG_DRIVESETTINGS = 'drivesettings'
|
||||
ARG_DRIVETRASH = 'drivetrash'
|
||||
ARG_EMPTYDRIVEFOLDERS = 'emptydrivefolders'
|
||||
@@ -877,6 +879,7 @@ class GamCLArgs():
|
||||
OB_DRIVE_FOLDER_PATH = 'DriveFolderPath'
|
||||
OB_DRIVE_LABEL_ID = 'DriveLabelID'
|
||||
OB_DRIVE_LABEL_NAME = 'DriveLabelName'
|
||||
OB_DRIVE_LABEL_PERMISSION_NAME = 'DriveLabelPermissionName'
|
||||
OB_DRIVE_LABEL_FIELD_ID = 'DriveLabelFieldID'
|
||||
OB_DRIVE_LABEL_SELECTION_ID_LIST = 'DriveLabelSelectionIDList'
|
||||
OB_EMAIL_ADDRESS = 'EmailAddress'
|
||||
|
||||
@@ -191,6 +191,8 @@ class GamEntity():
|
||||
DRIVE_LABEL_FIELD_ID = 'dlfi'
|
||||
DRIVE_LABEL_ID = 'dlid'
|
||||
DRIVE_LABEL_NAME = 'dlna'
|
||||
DRIVE_LABEL_PERMISSION = 'dlpe'
|
||||
DRIVE_LABEL_PERMISSION_NAME = 'dlpn'
|
||||
DRIVE_ORPHAN_FILE_OR_FOLDER = 'orph'
|
||||
DRIVE_PARENT_FOLDER = 'fipf'
|
||||
DRIVE_PARENT_FOLDER_ID = 'fipi'
|
||||
@@ -526,6 +528,8 @@ class GamEntity():
|
||||
DRIVE_LABEL_FIELD_ID: ['Drive Label Field IDs', 'Drive Label Field ID'],
|
||||
DRIVE_LABEL_ID: ['Drive Label IDs', 'Drive Label ID'],
|
||||
DRIVE_LABEL_NAME: ['Drive Label Names', 'Drive Label Name'],
|
||||
DRIVE_LABEL_PERMISSION: ['Drive Label Permissions', 'Drive Label Permission'],
|
||||
DRIVE_LABEL_PERMISSION_NAME: ['Drive Label Permission Names', 'Drive Label Permission Name'],
|
||||
DRIVE_ORPHAN_FILE_OR_FOLDER: ['Drive Orphan Files/Folders', 'Drive Orphan File/Folder'],
|
||||
DRIVE_PARENT_FOLDER: ['Drive Parent Folders', 'Drive Parent Folder'],
|
||||
DRIVE_PARENT_FOLDER_ID: ['Drive Parent Folder IDs', 'Drive Parent Folder ID'],
|
||||
|
||||
@@ -24,6 +24,7 @@ ABORTED = 'aborted'
|
||||
ABUSIVE_CONTENT_RESTRICTION = 'abusiveContentRestriction'
|
||||
ACCESS_NOT_CONFIGURED = 'accessNotConfigured'
|
||||
ALREADY_EXISTS = 'alreadyExists'
|
||||
APPLY_LABEL_FORBIDDEN = 'applyLabelForbidden'
|
||||
AUTH_ERROR = 'authError'
|
||||
BACKEND_ERROR = 'backendError'
|
||||
BAD_GATEWAY = 'badGateway'
|
||||
@@ -243,6 +244,7 @@ DRIVE3_DELETE_ACL_THROW_REASONS = [BAD_REQUEST, CANNOT_REMOVE_OWNER,
|
||||
INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, SHARING_RATE_LIMIT_EXCEEDED,
|
||||
NOT_FOUND, PERMISSION_NOT_FOUND]
|
||||
DRIVE3_MODIFY_LABEL_THROW_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, NOT_FOUND, FORBIDDEN, INTERNAL_ERROR,
|
||||
FILE_NEVER_WRITABLE, APPLY_LABEL_FORBIDDEN,
|
||||
INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, INSUFFICIENT_FILE_PERMISSIONS,
|
||||
UNKNOWN_ERROR, INVALID_INPUT, BAD_REQUEST,
|
||||
LABEL_MULTIPLE_VALUES_FOR_SINGULAR_FIELD, LABEL_MUTATION_FORBIDDEN,
|
||||
@@ -349,6 +351,8 @@ class accessNotConfigured(Exception):
|
||||
pass
|
||||
class alreadyExists(Exception):
|
||||
pass
|
||||
class applyLabelForbidden(Exception):
|
||||
pass
|
||||
class authError(Exception):
|
||||
pass
|
||||
class backendError(Exception):
|
||||
@@ -649,6 +653,7 @@ REASON_EXCEPTION_MAP = {
|
||||
ABUSIVE_CONTENT_RESTRICTION: abusiveContentRestriction,
|
||||
ACCESS_NOT_CONFIGURED: accessNotConfigured,
|
||||
ALREADY_EXISTS: alreadyExists,
|
||||
APPLY_LABEL_FORBIDDEN: applyLabelForbidden,
|
||||
AUTH_ERROR: authError,
|
||||
BACKEND_ERROR: backendError,
|
||||
BAD_REQUEST: badRequest,
|
||||
|
||||
@@ -34,7 +34,7 @@ _PRODUCTS = {
|
||||
'101039': 'Assured Controls',
|
||||
'101040': 'Beyond Corp Enterprise',
|
||||
'101043': 'Google Workspace Additional Storage',
|
||||
'101047': 'Duet AI',
|
||||
'101047': 'Gemini',
|
||||
'Google-Apps': 'Google Workspace',
|
||||
'Google-Chrome-Device-Management': 'Google Chrome Device Management',
|
||||
'Google-Drive-storage': 'Google Drive Storage',
|
||||
@@ -86,9 +86,11 @@ _SKUS = {
|
||||
'1010430001': {
|
||||
'product': '101043', 'aliases': ['gwas', 'plusstorage'], 'displayName': 'Google Workspace Additional Storage'},
|
||||
'1010470001': {
|
||||
'product': '101047', 'aliases': ['duetai'], 'displayName': 'Duet AI for Enterprise'},
|
||||
'product': '101047', 'aliases': ['geminient', 'duetai'], 'displayName': 'Gemini Enterprise'},
|
||||
'1010470002': {
|
||||
'product': '101047', 'aliases': ['gwlabs', 'workspacelabs'], 'displayName': 'Google Workspace Labs'},
|
||||
'1010470003': {
|
||||
'product': '101047', 'aliases': ['geminibiz'], 'displayName': 'Gemini Business'},
|
||||
'Google-Apps': {
|
||||
'product': 'Google-Apps', 'aliases': ['standard', 'free'], 'displayName': 'G Suite Legacy'},
|
||||
'Google-Apps-For-Business': {
|
||||
|
||||
Reference in New Issue
Block a user