mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-20 22:21:37 +00:00
Compare commits
14 Commits
20240417.2
...
20240501.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42d33786a1 | ||
|
|
683435cfb8 | ||
|
|
6b8170dd2f | ||
|
|
941fe97785 | ||
|
|
f87e013ec4 | ||
|
|
fc792bf454 | ||
|
|
b4b9bd2436 | ||
|
|
0e455a2e40 | ||
|
|
b384bdb503 | ||
|
|
10a6348ddd | ||
|
|
74be07a9ef | ||
|
|
5607d659fb | ||
|
|
da1ef497a1 | ||
|
|
ac4fef0e4b |
@@ -7,6 +7,7 @@
|
||||
- [Definitions](#definitions)
|
||||
- [Manage Projects](#manage-projects)
|
||||
- [Authorize a super admin to create projects](#authorize-a-super-admin-to-create-projects)
|
||||
- [Authorize Service Account Key Uploads](#authorize-service-account-key-uploads)
|
||||
- [Authorize GAM to create projects](#authorize-gam-to-create-projects)
|
||||
- [Create a new GCP project folder](#create-a-new-gcp-project-folder)
|
||||
- [Create a new project for GAM authorization](#create-a-new-project-for-gam-authorization)
|
||||
@@ -30,6 +31,7 @@
|
||||
- [Update an existing Service Account key](#update-an-existing-service-account-key)
|
||||
- [Replace all existing Service Account keys](#replace-all-existing-service-account-keys)
|
||||
- [Delete Service Account keys](#delete-service-account-keys)
|
||||
- [Upload a Service Account key to a service account with no keys](#upload-a-service-account-key-to-a-service-account-with-no-keys)
|
||||
- [Display Service Account keys](#display-service-account-keys)
|
||||
- [Manage Service Account access](#manage-service-account-access)
|
||||
- [Full Service Account access](#full-service-account-access)
|
||||
@@ -116,6 +118,7 @@ Verify whether the super admin you'll be using is in an OU where reauthenticatio
|
||||
|
||||
Additional steps may be required if errors are encountered.
|
||||
* [Authorize a super admin to create projects](#authorize-a-super-admin-to-create-projects)
|
||||
* [Authorize Service Account Key Uploads](#authorize-service-account-key-uploads)
|
||||
* [Authorize GAM to create projects](#authorize-gam-to-create-projects)
|
||||
|
||||
## Headless computers and Cloud Shells
|
||||
@@ -203,8 +206,51 @@ perform these steps and then retry the create project command.
|
||||
* Click in the Select a role box
|
||||
* Type project creator in the Filter box
|
||||
* Click Project Creator
|
||||
* Click + Add Another Role
|
||||
* Type organization policy administrator in the Filter box
|
||||
* Click Orgainzation Policy Administrator
|
||||
* Click Save
|
||||
|
||||
## Authorize Service Account Key Uploads
|
||||
|
||||
If you try to create a project and get an error saying that Constraint `constraints/iam.disableServiceAccountKeyUpload violated for service account projects/gam-project-xxx`,
|
||||
perform these steps and then you should be able to authorize and use your project.
|
||||
|
||||
* Login as an existing super admin at console.cloud.google.com
|
||||
* In the upper left click the three lines to the left of Google Cloud and select IAM & Admin
|
||||
* Under IAM & Admin select IAM
|
||||
* Click the down arrow in the box to the right of Google Cloud
|
||||
* Click the three dots at the right and select IAM/Permissions
|
||||
* Now you should be at "Permissions for organization ..."
|
||||
* Click on Grant Access
|
||||
* Enter the new admin address in Principals
|
||||
* Click in the Select a role box
|
||||
* Type orgpolicy.policies.update in the Filter box
|
||||
* Click Organization Policy Administrator
|
||||
* Click Save
|
||||
* In the upper left click the three lines to the left of Google Cloud and select IAM & Admin
|
||||
* Under IAM & Admin select IAM
|
||||
* Click the down arrow in the box to the right of Google Cloud
|
||||
* Click the three dots at the right and select Manage Resources
|
||||
* Click the three dots and the end of the line for the GAM project just created
|
||||
* Click Settings
|
||||
* Click Organization Policies in the left column
|
||||
* Now you should be at "Policies for Gam Project"
|
||||
* Click in the Filter box
|
||||
* Enter iam.disableServiceAccountKeyUpload
|
||||
* Click the three dots at the end of the Disable Service Account Key Upload
|
||||
* Choose Edit policy
|
||||
* Click Override parent's policy
|
||||
* Click Add A Rule
|
||||
* Select Enforcement/Off
|
||||
* Click Done
|
||||
* Click Set Policy
|
||||
|
||||
Wait a couple of minutes for the policy updates to complete and then do the following to upload the service account key:
|
||||
```
|
||||
gam upload sakey [admin <EmailAddress>]
|
||||
```
|
||||
|
||||
## Authorize GAM to create projects
|
||||
If you try to create a project and get an error saying "This app has been blocked on your domain for either being
|
||||
insecure or non-edutational"; you'll have to mark the GAM Project Creation app as trusted.
|
||||
@@ -814,10 +860,26 @@ delete a service account key for a distributed copy of an `oauth2service.json` f
|
||||
that user's service account access.
|
||||
|
||||
You can disable your current Service Account key if you specify the `doit` argument. This is your
|
||||
acknowledgement that you will have to manually create a new Service Account key in the Developer's Console.
|
||||
acknowledgement that you will have to manually create a new Service Account key in the Developer's Console
|
||||
or upload a new key with the `gam upload sakey` command.
|
||||
```
|
||||
gam delete sakeys <ServiceAccountKeyList>+ [doit]
|
||||
```
|
||||
## Upload a Service Account key to a service account with no keys
|
||||
There are two cases where you will use this command:
|
||||
* Your workspace is configured to disable service account private key uploads and you are creating a project.
|
||||
* All of your service account keys have been deleted, either manually or with the `gam delete sakeys` command.
|
||||
|
||||
The `oauth2service.json` file is updated with the new private key. If you had previously distributed
|
||||
any `oauth2service.json` file to other users, you must redistribute the updated file with the new key.
|
||||
```
|
||||
gam upload sakey [admin <EmailAddress>]
|
||||
(algorithm KEY_ALG_RSA_1024|KEY_ALG_RSA_2048)|
|
||||
((localkeysize 1024|2048|4096 [validityhours <Number>])|
|
||||
(yubikey yubikey_pin yubikey_slot AUTHENTICATION
|
||||
yubikey_serialnumber <Number>
|
||||
[localkeysize 1024|2048|4096])
|
||||
```
|
||||
## Display Service Account keys
|
||||
There are system keys and user keys; user keys are what Gam uses; GCP uses system keys.
|
||||
|
||||
|
||||
@@ -10,6 +10,64 @@ 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.75.02
|
||||
|
||||
Updated `gam report <ActivityApplictionName>` to retry/handle the following error:
|
||||
```
|
||||
ERROR: 503: serviceNotAvailable - The service is currently unavailable.
|
||||
```
|
||||
|
||||
### 6.75.01
|
||||
|
||||
Added option `admin <EmailAddress>` to `gam upload sakey`.
|
||||
|
||||
### 6.75.00
|
||||
|
||||
Updated `gam create project` to simplify handling the situation where your workspace is configured to disable service account private key uploads.
|
||||
|
||||
Added command `gam upload sakey` to aid in this process.
|
||||
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Authorization#upload-a-service-account-key-to-a-service-account-with-no-keys
|
||||
|
||||
### 6.74.02
|
||||
|
||||
Fixed bug in `gam <UserTypeEntity> print shareddrives ... formatjson` that caused a trap.
|
||||
|
||||
### 6.74.01
|
||||
|
||||
Updated `gam create|update drivefileacl <DriveFileEntity> ... expiration <Time>` to handle
|
||||
the following error caused by tryig to add an expiration time to a member of a Shared Drive.
|
||||
```
|
||||
ERROR: 403: expirationDateNotAllowedForSharedDriveMembers - Expiration dates are not allowed for shared drive members.
|
||||
```
|
||||
|
||||
### 6.74.00
|
||||
|
||||
Added `truncate_client_id` Boolean variable to `gam.cfg`. Prior to version 6.74.00, GAM stripped
|
||||
'.apps.googleusercontent.com' from `client_id` in `oauth2.txt` and passed the truncated value in API calls.
|
||||
At Jay's suggestion this is no longer performed by default; setting `truncate_client_id = true` restores the previous behavior.
|
||||
|
||||
Do `gam oauth delete` and `gam oauth create` to set the untruncated value of `client_id` in `oauth2.txt`.
|
||||
|
||||
### 6.73.00
|
||||
|
||||
The Google Chat API has been updated so that chat members can now have their role set to manager.
|
||||
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-Chat#manage-chat-members
|
||||
|
||||
### 6.72.16
|
||||
|
||||
Updated `emailaddressList <EmailAddressList>` and `domainlist|notdomainlist <DomainNameList>`
|
||||
in `<PermissionMatch>` to perform case-insensitive matches as the API is returning mixed case
|
||||
ACL email addresses in some cases.
|
||||
|
||||
### 6.75.15
|
||||
|
||||
Updated all commands that display tasks to display the due date in GMT as the time portion
|
||||
is not supported by the API and converting the due date to local time may display the wrong date.
|
||||
|
||||
Renamed license SKU `1010400001` from `Beyond Corp Enterprise` to `Chrome Enterprise Premium`.
|
||||
|
||||
### 6.72.14
|
||||
|
||||
Upgraded to Python 3.12.3 where possible.
|
||||
|
||||
@@ -213,6 +213,7 @@ Section: DEFAULT
|
||||
todrive_timezone = ''
|
||||
todrive_upload_nodata = true
|
||||
todrive_user = ''
|
||||
truncate_client_id = false
|
||||
update_cros_ou_with_id = false
|
||||
use_projectid_as_name = false
|
||||
user_max_results = 500
|
||||
@@ -334,7 +335,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.72.14 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.75.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.3 64-bit final
|
||||
MacOS Sonoma 14.4.1 x86_64
|
||||
@@ -661,6 +662,7 @@ Section: DEFAULT
|
||||
todrive_timezone = ''
|
||||
todrive_upload_nodata = true
|
||||
todrive_user = ''
|
||||
truncate_client_id = false
|
||||
update_cros_ou_with_id = false
|
||||
use_projectid_as_name = false
|
||||
user_max_results = 500
|
||||
@@ -863,6 +865,7 @@ Section: DEFAULT
|
||||
todrive_timezone = ''
|
||||
todrive_upload_nodata = true
|
||||
todrive_user = ''
|
||||
truncate_client_id = false
|
||||
update_cros_ou_with_id = false
|
||||
use_projectid_as_name = false
|
||||
user_max_results = 500
|
||||
@@ -1006,7 +1009,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.72.14 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.75.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.3 64-bit final
|
||||
Windows-10-10.0.17134 AMD64
|
||||
@@ -1335,6 +1338,7 @@ Section: DEFAULT
|
||||
todrive_timezone = ''
|
||||
todrive_upload_nodata = true
|
||||
todrive_user = ''
|
||||
truncate_client_id = false
|
||||
update_cros_ou_with_id = false
|
||||
use_projectid_as_name = false
|
||||
user_max_results = 500
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|--------------|------------|
|
||||
| AppSheet | 101038 |
|
||||
| Assured Controls | 101039 |
|
||||
| Beyond Corp Enterprise | 101040 |
|
||||
| Chrome Enterprise | 101040 |
|
||||
| Cloud Identity Free | 101001 |
|
||||
| Cloud Identity Premium | 101005 |
|
||||
| Cloud Search | 101035 |
|
||||
@@ -43,7 +43,7 @@
|
||||
| AppSheet Enterprise Standard | 1010380002 | appsheetstandard |
|
||||
| AppSheet Enterprise Plus | 1010380003 | appsheetplus |
|
||||
| Assured Controls | 1010390001 | assuredcontrols |
|
||||
| Beyond Corp Enterprise | 1010400001 | bce |
|
||||
| Chrome Enterprise Premium | 1010400001 | cep | chromeenterprisepremium |
|
||||
| Cloud Identity Free | 1010010001 | cloudidentity |
|
||||
| Cloud Identity Premium | 1010050001 | cloudidentitypremium |
|
||||
| Cloud Search | 1010350001 | cloudsearch |
|
||||
@@ -140,7 +140,7 @@
|
||||
appsheetstandard | appsheetenterprisestandard | 1010380002 | AppSheet Enterprise Standard |
|
||||
appsheetplus | appsheetenterpriseplus | 1010380003 | AppSheet Enterprise Plus |
|
||||
assuredcontrols | 1010390001 | Assured Controls |
|
||||
bce | beyondcorp | beyondcorpenterprise | 1010400001 | Beyond Corp Enterprise |
|
||||
bce | beyondcorp | beyondcorpenterprise | cep | chromeenterprisepremium | 1010400001 | Chrome Enterprise Premium |
|
||||
cdm | chrome | googlechromedevicemanagement | Google-Chrome-Device-Management |
|
||||
cloudidentity | identity | 1010010001 | Cloud Identity |
|
||||
cloudidentitypremium | identitypremium | 1010050001 | Cloud Identity Premium |
|
||||
|
||||
@@ -143,7 +143,8 @@ Get Shared Drives ID and Name
|
||||
```
|
||||
gam redirect csv ./SharedDrives.csv print shareddrives fields id,name
|
||||
```
|
||||
Options:
|
||||
|
||||
Options for the `gam report drive` commands below:
|
||||
* `maxactivities 1` - Limits the number of activities displayed for Shared Drives with activity.
|
||||
* `shownoactivities` - Displays a row for Shared Drives with no activity.
|
||||
* `addcsvdata shared_drive_id "~id"` adds the Shared Drive ID to the output.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Resources
|
||||
- [API documentation](#api-documentation)
|
||||
- [Definitions](#definitions)
|
||||
- [Region Codes](#region-codes)
|
||||
- [Special quoting](#special-quoting)
|
||||
- [Manage buildings](#manage-buildings)
|
||||
- [Display buildings](#display-buildings)
|
||||
@@ -121,6 +122,252 @@ See [Collections of Items](Collections-of-Items)
|
||||
uservisibledescription
|
||||
<ResourceFieldNameList> ::= "<ResourceFieldName>(,<ResourceFieldName>)*"
|
||||
```
|
||||
|
||||
## Region Codes
|
||||
|
||||
| Region | Code |
|
||||
|--------|------|
|
||||
| Afghanistan | AF |
|
||||
| Aland Islands | AX |
|
||||
| Albania | AL |
|
||||
| Algeria | DZ |
|
||||
| American Samoa | AS |
|
||||
| Andorra | AD |
|
||||
| Angola | AO |
|
||||
| Anguilla | AI |
|
||||
| Antarctica | AQ |
|
||||
| Antigua & Barbuda | AG |
|
||||
| Argentina | AR |
|
||||
| Armenia | AM |
|
||||
| Aruba | AW |
|
||||
| Ascension Island | AC |
|
||||
| Australia | AU |
|
||||
| Austria | AT |
|
||||
| Azerbaijan | AZ |
|
||||
| Bahamas | BS |
|
||||
| Bahrain | BH |
|
||||
| Bangladesh | BD |
|
||||
| Barbados | BB |
|
||||
| Belarus | BY |
|
||||
| Belgium | BE |
|
||||
| Belize | BZ |
|
||||
| Benin | BJ |
|
||||
| Bermuda | BM |
|
||||
| Bhutan | BT |
|
||||
| Bolivia | BO |
|
||||
| Bosnia & Herzegovina | BA |
|
||||
| Botswana | BW |
|
||||
| Bouvet Island | BV |
|
||||
| Brazil | BR |
|
||||
| British Indian Ocean Territory | IO |
|
||||
| British Virgin Islands | VG |
|
||||
| Brunei | BN |
|
||||
| Bulgaria | BG |
|
||||
| Burkina Faso | BF |
|
||||
| Burundi | BI |
|
||||
| Cambodia | KH |
|
||||
| Cameroon | CM |
|
||||
| Canada | CA |
|
||||
| Canary Islands | IC |
|
||||
| Cape Verde | CV |
|
||||
| Caribbean Netherlands | BQ |
|
||||
| Cayman Islands | KY |
|
||||
| Central African Republic | CF |
|
||||
| Ceuta & Melilla | EA |
|
||||
| Chad | TD |
|
||||
| Chile | CL |
|
||||
| China | CN |
|
||||
| Christmas Island | CX |
|
||||
| Clipperton Island | CP |
|
||||
| Cocos (Keeling) Islands | CC |
|
||||
| Columbia | CO |
|
||||
| Comoros | KM |
|
||||
| Congo - Brazzaville | CG |
|
||||
| Congo - Kinshasa | CD |
|
||||
| Cook Islands | CK |
|
||||
| Costa Rica | CR |
|
||||
| Cote d’Ivoire | CI |
|
||||
| Croatia | HR |
|
||||
| Cuba | CU |
|
||||
| Curacao | CW |
|
||||
| Cyprus | CY |
|
||||
| Czech Republic | CZ |
|
||||
| Falkland Islands | FK |
|
||||
| Faroe Islands | FO |
|
||||
| Fiji | FJ |
|
||||
| Finland | FI |
|
||||
| France | FR |
|
||||
| Gabon | GA |
|
||||
| Gambia | GM |
|
||||
| Georgia | GE |
|
||||
| Germany | DE |
|
||||
| Ghana | GH |
|
||||
| Gibraltar | GI |
|
||||
| Greece | GR |
|
||||
| Greenland | GL |
|
||||
| Grenada | GD |
|
||||
| Guadeloupe | GP |
|
||||
| Guam | GU |
|
||||
| Guatemala | GT |
|
||||
| Guernsey | GG |
|
||||
| Guinea | GN |
|
||||
| Guinea-Bissau | GW |
|
||||
| Guyana | GY |
|
||||
| Haiti | HT |
|
||||
| Heard & McDonald Islands | HM |
|
||||
| Honduras | HN |
|
||||
| Hong Kong SAR China | HK |
|
||||
| Hungary | HU |
|
||||
| Iceland | IS |
|
||||
| India | IN |
|
||||
| Indonesia | ID |
|
||||
| Iran | IR |
|
||||
| Iraq | IQ |
|
||||
| Ireland | IE |
|
||||
| Isle of Man | IM |
|
||||
| Israel | IL |
|
||||
| Italy | IT |
|
||||
| Jamaica | JM |
|
||||
| Japan | JP |
|
||||
| Jersey | JE |
|
||||
| Jordan | JO |
|
||||
| Kazakhstan | KZ |
|
||||
| Kenya | KE |
|
||||
| Kiribati | KI |
|
||||
| Kosovo | XK |
|
||||
| Kuwait | KW |
|
||||
| Kyrgyzstan | KG |
|
||||
| Laos | LA |
|
||||
| Latvia | LV |
|
||||
| Lebanon | LB |
|
||||
| Lesotho | LS |
|
||||
| Liberia | LR |
|
||||
| Libya | LY |
|
||||
| Liechtenstein | LI |
|
||||
| Lithuania | LT |
|
||||
| Luxembourg | LU |
|
||||
| Macau SAR China | MO |
|
||||
| Macedonia | MK |
|
||||
| Madagascar | MG |
|
||||
| Malawi | MW |
|
||||
| Malaysia | MY |
|
||||
| Maldives | MV |
|
||||
| Mali | ML |
|
||||
| Malta | MT |
|
||||
| Marshall Islands | MH |
|
||||
| Martinique | MQ |
|
||||
| Mauritania | MR |
|
||||
| Mauritius | MU |
|
||||
| Mayotte | YT |
|
||||
| Mexico | MX |
|
||||
| Micronesia | FM |
|
||||
| Moldova | MD |
|
||||
| Monaco | MC |
|
||||
| Mongolia | MN |
|
||||
| Montenegro | ME |
|
||||
| Montserrat | MS |
|
||||
| Morocco | MA |
|
||||
| Mozambique | MZ |
|
||||
| Myanmar | MM |
|
||||
| Namibia | NA |
|
||||
| Nauru | NR |
|
||||
| Nepal | NP |
|
||||
| Netherlands | NL |
|
||||
| New Caledonia | NC |
|
||||
| New Zealand | NZ |
|
||||
| Nicaragua | NI |
|
||||
| Niger | NE |
|
||||
| Nigeria | NG |
|
||||
| Niue | NU |
|
||||
| Norfolk Island | NF |
|
||||
| North Korea | KP |
|
||||
| Northern Mariana Islands | MP |
|
||||
| Norway | NO |
|
||||
| Oman | OM |
|
||||
| Pakistan | PK |
|
||||
| Palau | PW |
|
||||
| Palestinia Territories | PS |
|
||||
| Panama | PA |
|
||||
| Papua New Guinea | PG |
|
||||
| Paraguay | PY |
|
||||
| Peru | PE |
|
||||
| Philippines | PH |
|
||||
| Pitcairn Islands | PN |
|
||||
| Poland | PL |
|
||||
| Portugal | PT |
|
||||
| Puerto Rico | PR |
|
||||
| Qatar | QA |
|
||||
| Reunion | RE |
|
||||
| Romania | RO |
|
||||
| Russia | RU |
|
||||
| Rwanda | RW |
|
||||
| Samoa | WS |
|
||||
| San Marino | SM |
|
||||
| Sao Tomm & Principe | ST |
|
||||
| Saudi Arabia | SA |
|
||||
| Senegal | SN |
|
||||
| Serbia | RS |
|
||||
| Seychelles | SC |
|
||||
| Sierra Leone | SL |
|
||||
| Singapore | SG |
|
||||
| Sint Maarten | SX |
|
||||
| Slovakia | SK |
|
||||
| Slovenia | SI |
|
||||
| Solomon Islands | SB |
|
||||
| Somalia | SO |
|
||||
| South Africa | ZA |
|
||||
| South Georgia & South Sandwich Islands | GS |
|
||||
| South Korea | KR |
|
||||
| South Sudan | SS |
|
||||
| Spain | ES |
|
||||
| Sri Lanka | LK |
|
||||
| St. Barthelemy | BL |
|
||||
| St. Helena | SH |
|
||||
| St. Kitts & Nevis | KN |
|
||||
| St. Lucia | LC |
|
||||
| St. Martin | MF |
|
||||
| St. Pierre & Miquelon | PM |
|
||||
| St. Vincent & Grenadines | VC |
|
||||
| Sudan | SD |
|
||||
| Suriname | SR |
|
||||
| Svalbard & Jan Mayen | SJ |
|
||||
| Swaziland | SZ |
|
||||
| Sweden | SE |
|
||||
| Switzerland | CH |
|
||||
| Syria | SY |
|
||||
| Taiwan | TW |
|
||||
| Tajikistan | TJ |
|
||||
| Tanzania | TZ |
|
||||
| Thailand | TH |
|
||||
| Timor-Leste | TL |
|
||||
| Togo | TG |
|
||||
| Tokelau | TK |
|
||||
| Tonga | TO |
|
||||
| Trinidad & Tobago | TT |
|
||||
| Tristan da Cunha | TA |
|
||||
| Tunisia | TN |
|
||||
| Turkey | TR |
|
||||
| Turkmenistan | TM |
|
||||
| Turks & Caicos Islands | TC |
|
||||
| Tuvalu | TV |
|
||||
| U.S. Outlying Islands | UM |
|
||||
| U.S. Virgin Islands | VI |
|
||||
| Uganda | UG |
|
||||
| Ukraine | UA |
|
||||
| United Arab Emirates | AE |
|
||||
| United Kingdom | GB |
|
||||
| United States | US |
|
||||
| Unknown Region | ZZ |
|
||||
| Uraguay | UY |
|
||||
| Uzbekistan | UZ |
|
||||
| Vanuatu | VU |
|
||||
| Vatican City | VA |
|
||||
| Venezuela | VE |
|
||||
| Vietnam | VN |
|
||||
| Yemen | YE |
|
||||
| Zambia | ZM |
|
||||
| Zimbabwe | ZW |
|
||||
|
||||
## Special quoting
|
||||
When entering `<FeatureNameList>` with `<FeatureName>s`containing spaces, enclose the list in `"` and the names containing spaces in `'`.
|
||||
```
|
||||
@@ -133,10 +380,8 @@ When creating a building, at a minimum you must enter `address|addresslines` and
|
||||
|
||||
* Enter a single-line address as `address "123 Main Street"`
|
||||
* Enter a multi-line address as `addresslines "123 Main Street\nAnytown, US"`
|
||||
|
||||
For `country|regioncode` see: http://www.unicode.org/cldr/charts/30/supplemental/territory_information.html
|
||||
```
|
||||
gam create|add building <BuildIngID> <Name> <BuildingAttribute>*
|
||||
gam create|add building <Name> <BuildingAttribute>*
|
||||
gam update building <BuildIngID> <BuildingAttribute>*
|
||||
gam delete building <BuildingID>
|
||||
```
|
||||
|
||||
@@ -238,6 +238,20 @@ Delete members by specifying chatmember names.
|
||||
gam <UserTypeEntity> remove chatmember members <ChatMemberList>
|
||||
```
|
||||
|
||||
### Update members role
|
||||
Update members by specifying a chat space, user/group email addresses and role.
|
||||
```
|
||||
gam <UserTypeEntity> update chatmember <ChatSpace>
|
||||
role member|manager
|
||||
((user <UserItem>)|(members <UserTypeEntity>))+
|
||||
```
|
||||
Update members by specifying chatmember names and role.
|
||||
```
|
||||
gam <UserTypeEntity> modify chatmember
|
||||
role member|manager
|
||||
members <ChatMemberList>
|
||||
```
|
||||
|
||||
## Display Chat Members
|
||||
### Display information about a specific chat members
|
||||
```
|
||||
|
||||
@@ -69,6 +69,8 @@ gam <UserTypeEntity> create task <TasklistEntity>
|
||||
<TaskAttribute>* [parent <TaskID>] [previous <TaskID>]
|
||||
[compact|formatjson|returnidonly]
|
||||
```
|
||||
The API only supports all-day tasks; you should specify: `due YYYY-MM-DDT00:00:00Z`.
|
||||
|
||||
By default, Gam displays the created task as an indented list of keys and values; the task notes text is displayed as individual lines.
|
||||
* `compact` - Display the task notes text with escaped carriage returns as \r and newlines as \n
|
||||
* `formatjson` - Display the task in JSON format
|
||||
@@ -100,6 +102,9 @@ By default, Gam displays the moved task as an indented list of keys and values;
|
||||
* `formatjson` - Display the task in JSON format
|
||||
|
||||
## Display Tasks
|
||||
All commands that display tasks display the due date in GMT as the time portion
|
||||
is not supported by the API and converting the due date to local time may display the wrong date.
|
||||
|
||||
### Display selected tasks
|
||||
```
|
||||
gam <UserTypeEntity> info task <TasklistIDTaskIDEntity>
|
||||
@@ -119,6 +124,13 @@ gam <UserTypeEntity> show tasks [tasklists <TasklistEntity>]
|
||||
[orderby completed|due|updated]
|
||||
[countsonly|compact|formatjson]
|
||||
```
|
||||
The API only supports dates in `duemin` and `duemax' but you must supply a null time:
|
||||
* `duemin YYYY-MM-DDT00:00:00Z` - Specify the starting due date
|
||||
* `duemax YYYY-MM-DDT00:00:00Z` - Specify one day beyond the ending due date
|
||||
|
||||
For example: `duemin 2024-05-01T00:00:00Z duemax 2024-05-02T00:00:00Z` will
|
||||
display all tasks on 2024-05-01.
|
||||
|
||||
By default, tasks are displayed in hierarchical order.
|
||||
* `orderby completed` - Display tasks in completed date order regardless of the hierarchy.
|
||||
* `orderby due` - Display tasks in due date order regardless of the hierarchy.
|
||||
@@ -142,6 +154,13 @@ gam <UserTypeEntity> print tasks [tasklists <TasklistEntity>] [todrive <ToDriveA
|
||||
[orderby completed|due|updated]
|
||||
[countsonly | (formatjson [quotechar <Character>])]
|
||||
```
|
||||
The API only supports dates in `duemin` and `duemax' but you must supply a null time:
|
||||
* `duemin YYYY-MM-DDT00:00:00Z` - Specify the starting due date
|
||||
* `duemax YYYY-MM-DDT00:00:00Z` - Specify one day beyond the ending due date
|
||||
|
||||
For example: `duemin 2024-05-01T00:00:00Z duemax 2024-05-02T00:00:00Z` will
|
||||
display all tasks on 2024-05-01.
|
||||
|
||||
By default, tasks are displayed in hierarchical order.
|
||||
* `orderby completed` - Display tasks in completed date order regardless of the hierarchy.
|
||||
* `orderby due` - Display tasks in due date order regardless of the hierarchy.
|
||||
|
||||
@@ -28,7 +28,7 @@ The YubiKey can be configured with a PIN that must be entered in order for it to
|
||||
Yes but in practice this does not work very well with GAMADV-XTD3. The YubiKey will need to be touched every time there is a GAMADV-XTD3 command running which for batch or cron jobs may be constant. GAMADV-XTD3 can use a PIN configured on the YubiKey in order to offer an additional layer of protection.
|
||||
|
||||
### If I use a YubiKey, do I need to rotate the private key regularly?
|
||||
No, because the YubiKey generated the private key it cannot be digitally exported from the YubiKey so there is not chance for it to be copied and stolen. Instead you should physically secure the YubiKey from theft.
|
||||
No, because the YubiKey generated the private key it cannot be digitally exported from the YubiKey so there is no chance for it to be copied and stolen. Instead you should physically secure the YubiKey from theft.
|
||||
|
||||
### What data does the service account private key have access to?
|
||||
When using domain-wide delegation with GAMADV-XTD3, the service account and anyone possessing the service account private key oauth2service.json file has access to the Gmail, Drive and Calendar data of ALL Workspace users in your domain. For this reason, whether using a YubiKey or not, you should take strong measures to protect the service account private key.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Print the current version of Gam with details
|
||||
```
|
||||
gam version
|
||||
GAMADV-XTD3 6.72.14 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.75.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.3 64-bit final
|
||||
MacOS Sonoma 14.4.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.72.14 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.75.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.3 64-bit final
|
||||
MacOS Sonoma 14.4.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.72.14 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 6.75.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.3 64-bit final
|
||||
MacOS Sonoma 14.4.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.72.14
|
||||
Latest: 6.75.02
|
||||
echo $?
|
||||
1
|
||||
```
|
||||
@@ -72,7 +72,7 @@ echo $?
|
||||
Print the current version number without details
|
||||
```
|
||||
gam version simple
|
||||
6.72.14
|
||||
6.75.02
|
||||
```
|
||||
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.72.14 - https://github.com/taers232c/GAMADV-XTD3
|
||||
GAM 6.75.02 - https://github.com/taers232c/GAMADV-XTD3
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.3 64-bit final
|
||||
MacOS Sonoma 14.4.1 x86_64
|
||||
|
||||
@@ -580,6 +580,10 @@ todrive_upload_nodata
|
||||
todrive_user
|
||||
Email address of user to receive CSV files when todrive is specified
|
||||
Default: '' which becomes admin user in admin_email or address from oauth2.txt
|
||||
truncate_client_id
|
||||
Prior to version 6.74.00, GAM stripped '.apps.googleusercontent.com' from the client_id in oauth2.txt
|
||||
and passed the truncated value in API calls; this is no longer performed unless truncate_client_id is true
|
||||
Default: False
|
||||
update_cros_ou_with_id
|
||||
Update the OU of a Chromebook with the OU ID rather than the OU path.
|
||||
Set to true if you are getting the following error:
|
||||
@@ -730,6 +734,7 @@ Section: DEFAULT
|
||||
todrive_timezone = ''
|
||||
todrive_upload_nodata = true
|
||||
todrive_user = ''
|
||||
truncate_client_id = false
|
||||
update_cros_ou_with_id = false
|
||||
use_projectid_as_name = false
|
||||
user_max_results = 500
|
||||
@@ -916,6 +921,7 @@ todrive_timestamp = false
|
||||
todrive_timezone = ''
|
||||
todrive_upload_nodata = true
|
||||
todrive_user = ''
|
||||
truncate_client_id = false
|
||||
update_cros_ou_with_id = false
|
||||
use_projectid_as_name = false
|
||||
|
||||
|
||||
@@ -263,7 +263,7 @@ If an item contains spaces, it should be surrounded by ".
|
||||
appsheetstandard | appsheetenterprisestandard | 1010380002 | AppSheet Enterprise Standard |
|
||||
appsheetplus | appsheetenterpriseplus | 1010380003 | AppSheet Enterprise Plus |
|
||||
assuredcontrols | 1010390001 | Assured Controls |
|
||||
bce | beyondcorp | beyondcorpenterprise | 1010400001 | Beyond Corp Enterprise |
|
||||
bce | beyondcorp | beyondcorpenterprise | cep | chromeenterprisepremium | 1010400001 | Chrome Enterprise Premium |
|
||||
cdm | chrome | googlechromedevicemanagement | Google-Chrome-Device-Management |
|
||||
cloudidentity | identity | 1010010001 | Cloud Identity |
|
||||
cloudidentitypremium | identitypremium | 1010050001 | Cloud Identity Premium |
|
||||
@@ -1406,6 +1406,13 @@ gam rotate sakey|sakeys retain_none
|
||||
yubikey_serialnumber <Number>
|
||||
[localkeysize 1024|2048|4096])
|
||||
|
||||
gam upload sakey [admin <EmailAddress>]
|
||||
(algorithm KEY_ALG_RSA_1024|KEY_ALG_RSA_2048)|
|
||||
((localkeysize 1024|2048|4096 [validityhours <Number>])|
|
||||
(yubikey yubikey_pin yubikey_slot AUTHENTICATION|SIGNATURE
|
||||
yubikey_serialnumber <Number>
|
||||
[localkeysize 1024|2048|4096])
|
||||
|
||||
gam delete sakeys <ServiceAccountKeyList>+ [doit]
|
||||
gam show sakeys [all|system|user]
|
||||
|
||||
@@ -5980,6 +5987,12 @@ gam <UserTypeEntity> delete chatmember <ChatSpace>
|
||||
((user <UserItem>)|(members <UserTypeEntity>)|
|
||||
(group <GroupItem>)|(groups <GroupEntity>))+
|
||||
gam <UserTypeEntity> remove chatmember members <ChatMemberList>
|
||||
gam <UserTypeEntity> update chatmember <ChatSpace>
|
||||
role member|manager
|
||||
((user <UserItem>)|(members <UserTypeEntity>))+
|
||||
gam <UserTypeEntity> modify chatmember
|
||||
role member|manager
|
||||
members <ChatMemberList>
|
||||
|
||||
gam <UserTypeEntity> info chatmember members <ChatMemberList>
|
||||
[formatjson]
|
||||
|
||||
@@ -2,6 +2,64 @@
|
||||
|
||||
Merged GAM-Team version
|
||||
|
||||
6.75.02
|
||||
|
||||
Updated `gam report <ActivityApplictionName>` to retry/handle the following error:
|
||||
```
|
||||
ERROR: 503: serviceNotAvailable - The service is currently unavailable.
|
||||
```
|
||||
|
||||
6.75.01
|
||||
|
||||
Added option `admin <EmailAddress>` to `gam upload sakey`.
|
||||
|
||||
6.75.00
|
||||
|
||||
Updated `gam create project` to simplify handling the situation where your workspace is configured to disable service account private key uploads.
|
||||
|
||||
Added command `gam upload sakey` to aid in this process.
|
||||
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Authorization#upload-a-service-account-key-to-a-service-account-with-no-keys
|
||||
|
||||
6.74.02
|
||||
|
||||
Fixed bug in `gam <UserTypeEntity> print shareddrives ... formatjson` that caused a trap.
|
||||
|
||||
6.74.01
|
||||
|
||||
Updated `gam create|update drivefileacl <DriveFileEntity> ... expiration <Time>` to handle
|
||||
the following error caused by tryig to add an expiration time to a member of a Shared Drive.
|
||||
```
|
||||
ERROR: 403: expirationDateNotAllowedForSharedDriveMembers - Expiration dates are not allowed for shared drive members.
|
||||
```
|
||||
|
||||
6.74.00
|
||||
|
||||
Added `truncate_client_id` Boolean variable to `gam.cfg`. Prior to version 6.74.00, GAM stripped
|
||||
'.apps.googleusercontent.com' from `client_id` in `oauth2.txt` and passed the truncated value in API calls.
|
||||
At Jay's suggestion this is no longer performed by default; setting `truncate_client_id = true` restores the previous behavior.
|
||||
|
||||
Do `gam oauth delete` and `gam oauth create` to set the untruncated value of `client_id` in `oauth2.txt`.
|
||||
|
||||
6.73.00
|
||||
|
||||
The Google Chat API has been updated so that chat members can now have their role set to manager.
|
||||
|
||||
* See: https://github.com/taers232c/GAMADV-XTD3/wiki/Users-Chat#manage-chat-members
|
||||
|
||||
6.72.16
|
||||
|
||||
Updated `emailaddressList <EmailAddressList>` and `domainlist|notdomainlist <DomainNameList>`
|
||||
in `<PermissionMatch>` to perform case-insensitive matches as the API is returning mixed case
|
||||
ACL email addresses in some cases.
|
||||
|
||||
6.72.15
|
||||
|
||||
Updated all commands that display tasks to display the due date in GMT as the time portion
|
||||
is not supported by the API and converting the due date to local time may display the wrong date.
|
||||
|
||||
Renamed license SKU `1010400001` from `Beyond Corp Enterprise` to `Chrome Enterprise Premium`.
|
||||
|
||||
6.72.14
|
||||
|
||||
Upgraded to Python 3.12.3 where possible.
|
||||
|
||||
@@ -4194,6 +4194,7 @@ def SetGlobalVariables():
|
||||
# Set environment variables so GData API can find cacerts.pem
|
||||
os.environ['REQUESTS_CA_BUNDLE'] = GC.Values[GC.CACERTS_PEM]
|
||||
os.environ['DEFAULT_CA_BUNDLE_PATH'] = GC.Values[GC.CACERTS_PEM]
|
||||
os.environ['HTTPLIB2_CA_CERTS'] = GC.Values[GC.CACERTS_PEM]
|
||||
os.environ['SSL_CERT_FILE'] = GC.Values[GC.CACERTS_PEM]
|
||||
httplib2.CA_CERTS = GC.Values[GC.CACERTS_PEM]
|
||||
# Needs to be set so oauthlib doesn't puke when Google changes our scopes
|
||||
@@ -4445,6 +4446,9 @@ def getOauth2TxtCredentials(exitOnError=True, api=None, noDASA=False, refreshOnl
|
||||
else:
|
||||
GM.Globals[GM.CREDENTIALS_SCOPES] = set(jsonDict.pop('scopes', API.REQUIRED_SCOPES))
|
||||
token_expiry = jsonDict.get('token_expiry', REFRESH_EXPIRY)
|
||||
if GC.Values[GC.TRUNCATE_CLIENT_ID]:
|
||||
# chop off .apps.googleusercontent.com suffix as it's not needed and we need to keep things short for the Auth URL.
|
||||
jsonDict['client_id'] = re.sub(r'\.apps\.googleusercontent\.com$', '', jsonDict['client_id'])
|
||||
creds = google.oauth2.credentials.Credentials.from_authorized_user_info(jsonDict)
|
||||
if 'id_token_jwt' not in jsonDict:
|
||||
creds.token = jsonDict['token']
|
||||
@@ -10392,9 +10396,7 @@ def getOAuthClientIDAndSecret():
|
||||
cs_json = json.loads(cs_data)
|
||||
if not cs_json:
|
||||
systemErrorExit(CLIENT_SECRETS_JSON_REQUIRED_RC, Msg.NO_CLIENT_ACCESS_CREATE_UPDATE_ALLOWED)
|
||||
# chop off .apps.googleusercontent.com suffix as it's not needed and we need to keep things short for the Auth URL.
|
||||
return (re.sub(r'\.apps\.googleusercontent\.com$', '', cs_json['installed']['client_id']),
|
||||
cs_json['installed']['client_secret'])
|
||||
return (cs_json['installed']['client_id'], cs_json['installed']['client_secret'])
|
||||
except (IndexError, KeyError, SyntaxError, TypeError, ValueError) as e:
|
||||
invalidClientSecretsJsonExit(str(e))
|
||||
|
||||
@@ -10811,7 +10813,7 @@ class Credentials(google.oauth2.credentials.Credentials):
|
||||
'client_id': client_id,
|
||||
'client_secret': client_secret,
|
||||
'redirect_uris': ['http://localhost'],
|
||||
'auth_uri': 'https://accounts.google.com/o/oauth2/v2/auth',
|
||||
'auth_uri': API.GOOGLE_OAUTH2_ENDPOINT,
|
||||
'token_uri': API.GOOGLE_OAUTH2_TOKEN_ENDPOINT,
|
||||
}
|
||||
}
|
||||
@@ -11249,8 +11251,6 @@ def _createClientSecretsOauth2service(httpObj, login_hint, appInfo, projectInfo,
|
||||
return
|
||||
if appInfo:
|
||||
setGAMProjectConsentScreen(httpObj, projectInfo['projectId'], appInfo)
|
||||
if not _createOauth2serviceJSON(httpObj, projectInfo, svcAcctInfo):
|
||||
return
|
||||
console_url = f'https://console.cloud.google.com/apis/credentials/oauthclient?project={projectInfo["projectId"]}&authuser={login_hint}'
|
||||
csHttpObj = getHttpObj()
|
||||
while True:
|
||||
@@ -11269,8 +11269,8 @@ def _createClientSecretsOauth2service(httpObj, login_hint, appInfo, projectInfo,
|
||||
# Deleted: "redirect_uris": ["http://localhost", "urn:ietf:wg:oauth:2.0:oob"],
|
||||
cs_data = f'''{{
|
||||
"installed": {{
|
||||
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
||||
"auth_uri": "https://accounts.google.com/o/oauth2/v2/auth",
|
||||
"auth_provider_x509_cert_url": "{API.GOOGLE_AUTH_PROVIDER_X509_CERT_URL}",
|
||||
"auth_uri": "{API.GOOGLE_OAUTH2_ENDPOINT}",
|
||||
"client_id": "{client_id}",
|
||||
"client_secret": "{client_secret}",
|
||||
"created_by": "{login_hint}",
|
||||
@@ -11282,6 +11282,8 @@ def _createClientSecretsOauth2service(httpObj, login_hint, appInfo, projectInfo,
|
||||
sys.stdout.write(Msg.GO_BACK_TO_YOUR_BROWSER_AND_CLICK_OK_TO_CLOSE_THE_OAUTH_CLIENT_POPUP)
|
||||
sys.stdout.write(Msg.TRUST_GAM_CLIENT_ID.format(GAM, client_id))
|
||||
readStdin('')
|
||||
if not _createOauth2serviceJSON(httpObj, projectInfo, svcAcctInfo):
|
||||
return
|
||||
sys.stdout.write(Msg.YOUR_GAM_PROJECT_IS_CREATED_AND_READY_TO_USE)
|
||||
|
||||
def _getProjects(crm, pfilter, returnNF=False):
|
||||
@@ -12315,8 +12317,8 @@ def _generatePrivateKeyAndPublicCert(projectId, clientEmail, name, key_size, b64
|
||||
|
||||
def _formatOAuth2ServiceData(service_data):
|
||||
quotedEmail = quote(service_data.get('client_email', ''))
|
||||
service_data['auth_provider_x509_cert_url'] = 'https://www.googleapis.com/oauth2/v1/certs'
|
||||
service_data['auth_uri'] = 'https://accounts.google.com/o/oauth2/auth'
|
||||
service_data['auth_provider_x509_cert_url'] = API.GOOGLE_AUTH_PROVIDER_X509_CERT_URL
|
||||
service_data['auth_uri'] = API.GOOGLE_OAUTH2_ENDPOINT
|
||||
service_data['client_x509_cert_url'] = f'https://www.googleapis.com/robot/v1/metadata/x509/{quotedEmail}'
|
||||
service_data['token_uri'] = API.GOOGLE_OAUTH2_TOKEN_ENDPOINT
|
||||
service_data['type'] = 'service_account'
|
||||
@@ -12333,8 +12335,9 @@ def doProcessSvcAcctKeys(mode=None, iam=None, projectId=None, clientEmail=None,
|
||||
local_key_size = 2048
|
||||
validityHours = 0
|
||||
body = {}
|
||||
if iam is None:
|
||||
_, iam = buildGAPIServiceObject(API.IAM, None)
|
||||
if iam is None or mode == 'upload':
|
||||
if iam is None:
|
||||
_, iam = buildGAPIServiceObject(API.IAM, None)
|
||||
_getSvcAcctData()
|
||||
currentPrivateKeyId, projectId, clientEmail, clientId = _getSvcAcctKeyProjectClientFields()
|
||||
# dict() ensures we have a real copy, not pointer
|
||||
@@ -12411,6 +12414,7 @@ def doProcessSvcAcctKeys(mode=None, iam=None, projectId=None, clientEmail=None,
|
||||
result = callGAPI(iam.projects().serviceAccounts().keys(), 'upload',
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.BAD_REQUEST, GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
name=name, body={'publicKeyData': publicKeyData})
|
||||
newPrivateKeyId = result['name'].rsplit('/', 1)[-1]
|
||||
break
|
||||
except GAPI.notFound as e:
|
||||
if retry == maxRetries:
|
||||
@@ -12422,10 +12426,19 @@ def doProcessSvcAcctKeys(mode=None, iam=None, projectId=None, clientEmail=None,
|
||||
entityActionFailedWarning([Ent.PROJECT, projectId, Ent.SVCACCT, clientEmail], Msg.UPDATE_PROJECT_TO_VIEW_MANAGE_SAKEYS)
|
||||
return False
|
||||
waitForCompletion(retry)
|
||||
except (GAPI.badRequest, GAPI.failedPrecondition) as e:
|
||||
except GAPI.badRequest as e:
|
||||
entityActionFailedWarning([Ent.PROJECT, projectId, Ent.SVCACCT, clientEmail], str(e))
|
||||
return False
|
||||
newPrivateKeyId = result['name'].rsplit('/', 1)[-1]
|
||||
except GAPI.failedPrecondition as e:
|
||||
entityActionFailedWarning([Ent.PROJECT, projectId, Ent.SVCACCT, clientEmail], str(e))
|
||||
if 'iam.disableServiceAccountKeyUpload' not in str(e):
|
||||
return False
|
||||
if retry == maxRetries or mode != 'upload':
|
||||
sys.stdout.write(Msg.ENABLE_SERVICE_ACCOUNT_PRIVATE_KEY_UPLOAD.format(projectId))
|
||||
new_data['private_key'] = ''
|
||||
newPrivateKeyId = ''
|
||||
break
|
||||
waitForCompletion(retry)
|
||||
new_data['private_key_id'] = newPrivateKeyId
|
||||
oauth2service_data = _formatOAuth2ServiceData(new_data)
|
||||
else:
|
||||
@@ -12436,6 +12449,7 @@ def doProcessSvcAcctKeys(mode=None, iam=None, projectId=None, clientEmail=None,
|
||||
result = callGAPI(iam.projects().serviceAccounts().keys(), 'create',
|
||||
throwReasons=[GAPI.BAD_REQUEST, GAPI.PERMISSION_DENIED],
|
||||
name=name, body=body)
|
||||
newPrivateKeyId = result['name'].rsplit('/', 1)[-1]
|
||||
break
|
||||
except GAPI.permissionDenied:
|
||||
if retry == maxRetries:
|
||||
@@ -12445,9 +12459,9 @@ def doProcessSvcAcctKeys(mode=None, iam=None, projectId=None, clientEmail=None,
|
||||
except GAPI.badRequest as e:
|
||||
entityActionFailedWarning([Ent.PROJECT, projectId, Ent.SVCACCT, clientEmail], str(e))
|
||||
return False
|
||||
newPrivateKeyId = result['name'].rsplit('/', 1)[-1]
|
||||
oauth2service_data = base64.b64decode(result['privateKeyData']).decode(UTF8)
|
||||
entityActionPerformed([Ent.PROJECT, projectId, Ent.SVCACCT, clientEmail, Ent.SVCACCT_KEY, newPrivateKeyId])
|
||||
if newPrivateKeyId != '':
|
||||
entityActionPerformed([Ent.PROJECT, projectId, Ent.SVCACCT, clientEmail, Ent.SVCACCT_KEY, newPrivateKeyId])
|
||||
if GM.Globals[GM.SVCACCT_SCOPES_DEFINED]:
|
||||
try:
|
||||
GM.Globals[GM.OAUTH2SERVICE_JSON_DATA] = json.loads(oauth2service_data)
|
||||
@@ -12459,35 +12473,36 @@ def doProcessSvcAcctKeys(mode=None, iam=None, projectId=None, clientEmail=None,
|
||||
Act.Set(Act.UPDATE)
|
||||
entityActionPerformed([Ent.OAUTH2SERVICE_JSON_FILE, GC.Values[GC.OAUTH2SERVICE_JSON],
|
||||
Ent.SVCACCT_KEY, newPrivateKeyId])
|
||||
if mode != 'retainexisting':
|
||||
Act.Set(Act.REVOKE)
|
||||
count = len(keys) if mode == 'retainnone' else 1
|
||||
entityPerformActionNumItems([Ent.PROJECT, projectId, Ent.SVCACCT, clientEmail], count, Ent.SVCACCT_KEY)
|
||||
Ind.Increment()
|
||||
i = 0
|
||||
for key in keys:
|
||||
keyName = key['name'].rsplit('/', 1)[-1]
|
||||
if mode == 'retainnone' or keyName == currentPrivateKeyId and keyName != newPrivateKeyId:
|
||||
i += 1
|
||||
maxRetries = 5
|
||||
for retry in range(1, maxRetries+1):
|
||||
try:
|
||||
callGAPI(iam.projects().serviceAccounts().keys(), 'delete',
|
||||
throwReasons=[GAPI.BAD_REQUEST, GAPI.PERMISSION_DENIED],
|
||||
name=key['name'])
|
||||
entityActionPerformed([Ent.SVCACCT_KEY, keyName], i, count)
|
||||
break
|
||||
except GAPI.permissionDenied:
|
||||
if retry == maxRetries:
|
||||
entityActionFailedWarning([Ent.SVCACCT_KEY, keyName], Msg.UPDATE_PROJECT_TO_VIEW_MANAGE_SAKEYS)
|
||||
break
|
||||
waitForCompletion(retry)
|
||||
except GAPI.badRequest as e:
|
||||
entityActionFailedWarning([Ent.SVCACCT_KEY, keyName], str(e), i, count)
|
||||
break
|
||||
if mode != 'retainnone':
|
||||
if mode in {'retainexisting', 'upload'}:
|
||||
return newPrivateKeyId != ''
|
||||
Act.Set(Act.REVOKE)
|
||||
count = len(keys) if mode == 'retainnone' else 1
|
||||
entityPerformActionNumItems([Ent.PROJECT, projectId, Ent.SVCACCT, clientEmail], count, Ent.SVCACCT_KEY)
|
||||
Ind.Increment()
|
||||
i = 0
|
||||
for key in keys:
|
||||
keyName = key['name'].rsplit('/', 1)[-1]
|
||||
if mode == 'retainnone' or keyName == currentPrivateKeyId and keyName != newPrivateKeyId:
|
||||
i += 1
|
||||
maxRetries = 5
|
||||
for retry in range(1, maxRetries+1):
|
||||
try:
|
||||
callGAPI(iam.projects().serviceAccounts().keys(), 'delete',
|
||||
throwReasons=[GAPI.BAD_REQUEST, GAPI.PERMISSION_DENIED],
|
||||
name=key['name'])
|
||||
entityActionPerformed([Ent.SVCACCT_KEY, keyName], i, count)
|
||||
break
|
||||
Ind.Decrement()
|
||||
except GAPI.permissionDenied:
|
||||
if retry == maxRetries:
|
||||
entityActionFailedWarning([Ent.SVCACCT_KEY, keyName], Msg.UPDATE_PROJECT_TO_VIEW_MANAGE_SAKEYS)
|
||||
break
|
||||
waitForCompletion(retry)
|
||||
except GAPI.badRequest as e:
|
||||
entityActionFailedWarning([Ent.SVCACCT_KEY, keyName], str(e), i, count)
|
||||
break
|
||||
if mode != 'retainnone':
|
||||
break
|
||||
Ind.Decrement()
|
||||
return True
|
||||
|
||||
# gam create sakey|sakeys
|
||||
@@ -12522,6 +12537,21 @@ def doUpdateSvcAcctKeys():
|
||||
def doReplaceSvcAcctKeys():
|
||||
doProcessSvcAcctKeys(mode='retainnone')
|
||||
|
||||
# gam upload sakey|sakeys [admin <EmailAddress>]
|
||||
# (algorithm KEY_ALG_RSA_1024|KEY_ALG_RSA_2048)|
|
||||
# ((localkeysize 1024|2048|4096 [validityhours <Number>])|
|
||||
# (yubikey yubikey_pin yubikey_slot AUTHENTICATION
|
||||
# yubikey_serialnumber <String>
|
||||
# [localkeysize 1024|2048|4096])
|
||||
def doUploadSvcAcctKeys():
|
||||
login_hint = getEmailAddress(noUid=True) if checkArgumentPresent(['admin']) else None
|
||||
httpObj, _ = getCRMService(login_hint)
|
||||
iam = getAPIService(API.IAM, httpObj)
|
||||
if doProcessSvcAcctKeys(mode='upload', iam=iam):
|
||||
sa_email = GM.Globals[GM.OAUTH2SERVICE_JSON_DATA]['client_email']
|
||||
_grantRotateRights(iam, GM.Globals[GM.OAUTH2SERVICE_JSON_DATA]['project_id'], sa_email, sa_email)
|
||||
sys.stdout.write(Msg.YOUR_GAM_PROJECT_IS_CREATED_AND_READY_TO_USE)
|
||||
|
||||
# gam delete sakeys <ServiceAccountKeyList>
|
||||
def doDeleteSvcAcctKeys():
|
||||
_, iam = buildGAPIServiceObject(API.IAM, None)
|
||||
@@ -13851,7 +13881,8 @@ def doReport():
|
||||
try:
|
||||
feed = callGAPIpages(service, 'list', 'items',
|
||||
pageMessage=pageMessage, maxItems=maxActivities,
|
||||
throwReasons=[GAPI.BAD_REQUEST, GAPI.INVALID, GAPI.INVALID_INPUT, GAPI.AUTH_ERROR],
|
||||
throwReasons=[GAPI.BAD_REQUEST, GAPI.INVALID, GAPI.INVALID_INPUT, GAPI.AUTH_ERROR, GAPI.SERVICE_NOT_AVAILABLE],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
applicationName=report, userKey=user, customerId=customerId,
|
||||
actorIpAddress=actorIpAddress, orgUnitID=orgUnitId,
|
||||
startTime=startEndTime.startTime, endTime=startEndTime.endTime,
|
||||
@@ -13863,7 +13894,7 @@ def doReport():
|
||||
continue
|
||||
printErrorMessage(BAD_REQUEST_RC, Msg.BAD_REQUEST)
|
||||
break
|
||||
except (GAPI.invalid, GAPI.invalidInput) as e:
|
||||
except (GAPI.invalid, GAPI.invalidInput, GAPI.serviceNotAvailable) as e:
|
||||
systemErrorExit(GOOGLE_API_ERROR_RC, str(e))
|
||||
except GAPI.authError:
|
||||
accessErrorExit(None)
|
||||
@@ -25511,7 +25542,7 @@ def createChatMember(users):
|
||||
member = callGAPI(chat.spaces().members(), 'patch',
|
||||
bailOnInternalError=True,
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
|
||||
name=name, updateMask='role', body={'role': role})
|
||||
name=member['name'], updateMask='role', body={'role': role})
|
||||
if not returnIdOnly:
|
||||
kvList[-1] = member['name']
|
||||
_getChatMemberEmail(cd, member)
|
||||
@@ -52957,7 +52988,7 @@ class PermissionMatch():
|
||||
body['emailAddress'] = getREPattern(re.IGNORECASE)
|
||||
self.permissionFields.add('emailAddress')
|
||||
elif myarg == 'emailaddresslist':
|
||||
body[myarg] = set(getString(Cmd.OB_EMAIL_ADDRESS_LIST).replace(',', ' ').split())
|
||||
body[myarg] = set(getString(Cmd.OB_EMAIL_ADDRESS_LIST).replace(',', ' ').lower().split())
|
||||
self.permissionFields.add('emailAddress')
|
||||
elif myarg == 'permissionidlist':
|
||||
body[myarg] = set(getString(Cmd.OB_PERMISSION_ID_LIST).replace(',', ' ').split())
|
||||
@@ -52967,7 +52998,7 @@ class PermissionMatch():
|
||||
self.permissionFields.add('domain')
|
||||
self.permissionFields.add('emailAddress')
|
||||
elif myarg in {'domainlist', 'notdomainlist'}:
|
||||
body[myarg] = set(getString(Cmd.OB_DOMAIN_NAME_LIST).replace(',', ' ').split())
|
||||
body[myarg] = set(getString(Cmd.OB_DOMAIN_NAME_LIST).replace(',', ' ').lower().split())
|
||||
self.permissionFields.add('domain')
|
||||
self.permissionFields.add('emailAddress')
|
||||
elif myarg == 'withlink':
|
||||
@@ -53074,7 +53105,7 @@ class PermissionMatch():
|
||||
elif field == 'emailaddresslist':
|
||||
emailAddress = permission.get('emailAddress')
|
||||
if emailAddress:
|
||||
if emailAddress not in value:
|
||||
if emailAddress.lower() not in value:
|
||||
break
|
||||
else:
|
||||
break
|
||||
@@ -53090,9 +53121,9 @@ class PermissionMatch():
|
||||
break
|
||||
else:
|
||||
if 'domain' in permission:
|
||||
domain = permission['domain']
|
||||
domain = permission['domain'].lower()
|
||||
elif 'emailAddress' in permission and permission['emailAddress']:
|
||||
_, domain = splitEmailAddress(permission['emailAddress'])
|
||||
_, domain = splitEmailAddress(permission['emailAddress'].lower())
|
||||
else:
|
||||
break
|
||||
if ((field == 'domain' and not value.match(domain)) or
|
||||
@@ -60912,7 +60943,7 @@ def createDriveFileACL(users, useDomainAdminAccess=False):
|
||||
if showDetails:
|
||||
_showDriveFilePermission(permission, printKeys, timeObjects)
|
||||
except (GAPI.badRequest, GAPI.invalid, GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError,
|
||||
GAPI.cannotSetExpiration,
|
||||
GAPI.cannotSetExpiration, GAPI.expirationDateNotAllowedForSharedDriveMembers,
|
||||
GAPI.insufficientFilePermissions, GAPI.unknownError, GAPI.ownershipChangeAcrossDomainNotPermitted,
|
||||
GAPI.teamDriveDomainUsersOnlyRestriction, GAPI.teamDriveTeamMembersOnlyRestriction,
|
||||
GAPI.targetUserRoleLimitedByLicenseRestriction, GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded,
|
||||
@@ -61041,7 +61072,7 @@ def updateDriveFileACLs(users, useDomainAdminAccess=False):
|
||||
if showDetails:
|
||||
_showDriveFilePermission(permission, printKeys, timeObjects)
|
||||
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError,
|
||||
GAPI.cannotSetExpiration,
|
||||
GAPI.cannotSetExpiration, GAPI.expirationDateNotAllowedForSharedDriveMembers,
|
||||
GAPI.badRequest, GAPI.invalidOwnershipTransfer, GAPI.cannotRemoveOwner,
|
||||
GAPI.fileNeverWritable, GAPI.ownershipChangeAcrossDomainNotPermitted, GAPI.sharingRateLimitExceeded,
|
||||
GAPI.targetUserRoleLimitedByLicenseRestriction, GAPI.insufficientAdministratorPrivileges,
|
||||
@@ -61141,6 +61172,7 @@ def createDriveFilePermissions(users, useDomainAdminAccess=False):
|
||||
body=_makePermissionBody(ri[RI_ITEM]), fields='', supportsAllDrives=True)
|
||||
entityActionPerformed([Ent.DRIVE_FILE_OR_FOLDER_ID, ri[RI_ENTITY], Ent.PERMITTEE, ri[RI_ITEM]], int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
||||
except (GAPI.badRequest, GAPI.invalid, GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError,
|
||||
GAPI.cannotSetExpiration, GAPI.expirationDateNotAllowedForSharedDriveMembers,
|
||||
GAPI.insufficientFilePermissions, GAPI.unknownError, GAPI.ownershipChangeAcrossDomainNotPermitted,
|
||||
GAPI.teamDriveDomainUsersOnlyRestriction, GAPI.teamDriveTeamMembersOnlyRestriction,
|
||||
GAPI.targetUserRoleLimitedByLicenseRestriction, GAPI.insufficientAdministratorPrivileges, GAPI.sharingRateLimitExceeded,
|
||||
@@ -62956,6 +62988,9 @@ def printShowSharedDrives(users, useDomainAdminAccess=False):
|
||||
if fieldsList:
|
||||
showFields.add('role')
|
||||
csvPF.AddTitle('role')
|
||||
if FJQC.formatJSON:
|
||||
csvPF.AddJSONTitles(['role'])
|
||||
csvPF.MoveJSONTitlesToEnd(['JSON'])
|
||||
if showOrgUnitPaths and useDomainAdminAccess and ((not showFields) or ('orgUnitId' in showFields)):
|
||||
orgUnitIdToPathMap = getOrgUnitIdToPathMap(cd)
|
||||
if showFields:
|
||||
@@ -71789,7 +71824,7 @@ def getTaskListIDfromTitle(svc, userTasklists, title, user, i, count):
|
||||
return userTasklists, None
|
||||
|
||||
TASK_SKIP_OBJECTS = ['selfLink']
|
||||
TASK_TIME_OBJECTS = ['due', 'completed', 'updated']
|
||||
TASK_TIME_OBJECTS = ['completed', 'updated']
|
||||
|
||||
def _showTask(tasklist, task, j=0, jcount=0, FJQC=None, compact=False):
|
||||
task['tasklistId'] = tasklist
|
||||
@@ -73209,6 +73244,11 @@ MAIN_COMMANDS_WITH_OBJECTS = {
|
||||
Cmd.ARG_USERS: doSuspendUnsuspendUsers,
|
||||
}
|
||||
),
|
||||
'upload':
|
||||
(Act.USE,
|
||||
{Cmd.ARG_SAKEY: doUploadSvcAcctKeys,
|
||||
}
|
||||
),
|
||||
'use':
|
||||
(Act.USE,
|
||||
{Cmd.ARG_PROJECT: doUseProject,
|
||||
|
||||
@@ -95,7 +95,9 @@ YOUTUBE = 'youtube'
|
||||
CHROMEVERSIONHISTORY_URL = 'https://versionhistory.googleapis.com/v1/chrome/platforms'
|
||||
DRIVE_SCOPE = 'https://www.googleapis.com/auth/drive'
|
||||
GMAIL_SEND_SCOPE = 'https://www.googleapis.com/auth/gmail.send'
|
||||
GOOGLE_OAUTH2_TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token"
|
||||
GOOGLE_AUTH_PROVIDER_X509_CERT_URL = 'https://www.googleapis.com/oauth2/v1/certs'
|
||||
GOOGLE_OAUTH2_ENDPOINT = 'https://accounts.google.com/o/oauth2/v2/auth'
|
||||
GOOGLE_OAUTH2_TOKEN_ENDPOINT = 'https://oauth2.googleapis.com/token'
|
||||
CLOUD_PLATFORM_SCOPE = 'https://www.googleapis.com/auth/cloud-platform'
|
||||
IAM_SCOPE = 'https://www.googleapis.com/auth/iam'
|
||||
PEOPLE_SCOPE = 'https://www.googleapis.com/auth/contacts'
|
||||
|
||||
@@ -288,6 +288,8 @@ TODRIVE_TIMEZONE = 'todrive_timezone'
|
||||
TODRIVE_UPLOAD_NODATA = 'todrive_upload_nodata'
|
||||
# User for todrive files
|
||||
TODRIVE_USER = 'todrive_user'
|
||||
# Truncate Client ID
|
||||
TRUNCATE_CLIENT_ID = 'truncate_client_id'
|
||||
# Update CrOS org unit with orgUnitId
|
||||
UPDATE_CROS_OU_WITH_ID = 'update_cros_ou_with_id'
|
||||
# Use course owner for course access
|
||||
@@ -430,6 +432,7 @@ Defaults = {
|
||||
TODRIVE_TIMEZONE: '',
|
||||
TODRIVE_UPLOAD_NODATA: TRUE,
|
||||
TODRIVE_USER: '',
|
||||
TRUNCATE_CLIENT_ID: FALSE,
|
||||
UPDATE_CROS_OU_WITH_ID: FALSE,
|
||||
USE_COURSE_OWNER_ACCESS: FALSE,
|
||||
USE_PROJECTID_AS_NAME: FALSE,
|
||||
@@ -590,6 +593,7 @@ VAR_INFO = {
|
||||
TODRIVE_TIMEZONE: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)},
|
||||
TODRIVE_UPLOAD_NODATA: {VAR_TYPE: TYPE_BOOLEAN},
|
||||
TODRIVE_USER: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)},
|
||||
TRUNCATE_CLIENT_ID: {VAR_TYPE: TYPE_BOOLEAN},
|
||||
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},
|
||||
|
||||
@@ -70,6 +70,7 @@ DOMAIN_POLICY = 'domainPolicy'
|
||||
DOWNLOAD_QUOTA_EXCEEDED = 'downloadQuotaExceeded'
|
||||
DUPLICATE = 'duplicate'
|
||||
EVENT_DURATION_EXCEEDS_LIMIT = 'eventDurationExceedsLimit'
|
||||
EXPIRATION_DATE_NOT_ALLOWED_FOR_SHARED_DRIVE_MEMBERS = 'expirationDateNotAllowedForSharedDriveMembers'
|
||||
FAILED_PRECONDITION = 'failedPrecondition'
|
||||
FIELD_IN_USE = 'fieldInUse'
|
||||
FIELD_NOT_WRITABLE = 'fieldNotWritable'
|
||||
@@ -208,7 +209,8 @@ DRIVE_COPY_THROW_REASONS = DRIVE_ACCESS_THROW_REASONS+[CANNOT_COPY_FILE, BAD_REQ
|
||||
FIELD_NOT_WRITABLE, RATE_LIMIT_EXCEEDED, USER_RATE_LIMIT_EXCEEDED,
|
||||
STORAGE_QUOTA_EXCEEDED, TEAMDRIVE_FILE_LIMIT_EXCEEDED, TEAMDRIVE_HIERARCHY_TOO_DEEP]
|
||||
DRIVE_GET_THROW_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, DOWNLOAD_QUOTA_EXCEEDED]
|
||||
DRIVE3_CREATE_ACL_THROW_REASONS = [BAD_REQUEST, INVALID, INVALID_SHARING_REQUEST, OWNERSHIP_CHANGE_ACROSS_DOMAIN_NOT_PERMITTED, CANNOT_SET_EXPIRATION,
|
||||
DRIVE3_CREATE_ACL_THROW_REASONS = [BAD_REQUEST, INVALID, INVALID_SHARING_REQUEST, OWNERSHIP_CHANGE_ACROSS_DOMAIN_NOT_PERMITTED,
|
||||
CANNOT_SET_EXPIRATION, EXPIRATION_DATE_NOT_ALLOWED_FOR_SHARED_DRIVE_MEMBERS,
|
||||
NOT_FOUND, TEAMDRIVE_DOMAIN_USERS_ONLY_RESTRICTION, TEAMDRIVE_TEAM_MEMBERS_ONLY_RESTRICTION,
|
||||
TARGET_USER_ROLE_LIMITED_BY_LICENSE_RESTRICTION, INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, SHARING_RATE_LIMIT_EXCEEDED,
|
||||
PUBLISH_OUT_NOT_PERMITTED, SHARE_IN_NOT_PERMITTED, SHARE_OUT_NOT_PERMITTED, SHARE_OUT_NOT_PERMITTED_TO_USER,
|
||||
@@ -224,7 +226,8 @@ DRIVE3_CREATE_ACL_THROW_REASONS = [BAD_REQUEST, INVALID, INVALID_SHARING_REQUEST
|
||||
DRIVE3_GET_ACL_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, FORBIDDEN, INTERNAL_ERROR,
|
||||
INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, INSUFFICIENT_FILE_PERMISSIONS,
|
||||
UNKNOWN_ERROR, INVALID]
|
||||
DRIVE3_UPDATE_ACL_THROW_REASONS = [BAD_REQUEST, INVALID_OWNERSHIP_TRANSFER, CANNOT_REMOVE_OWNER, CANNOT_SET_EXPIRATION,
|
||||
DRIVE3_UPDATE_ACL_THROW_REASONS = [BAD_REQUEST, INVALID_OWNERSHIP_TRANSFER, CANNOT_REMOVE_OWNER,
|
||||
CANNOT_SET_EXPIRATION, EXPIRATION_DATE_NOT_ALLOWED_FOR_SHARED_DRIVE_MEMBERS,
|
||||
OWNERSHIP_CHANGE_ACROSS_DOMAIN_NOT_PERMITTED,
|
||||
NOT_FOUND, TEAMDRIVE_DOMAIN_USERS_ONLY_RESTRICTION, TEAMDRIVE_TEAM_MEMBERS_ONLY_RESTRICTION,
|
||||
TARGET_USER_ROLE_LIMITED_BY_LICENSE_RESTRICTION, INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, SHARING_RATE_LIMIT_EXCEEDED,
|
||||
@@ -442,6 +445,8 @@ class duplicate(Exception):
|
||||
pass
|
||||
class eventDurationExceedsLimit(Exception):
|
||||
pass
|
||||
class expirationDateNotAllowedForSharedDriveMembers(Exception):
|
||||
pass
|
||||
class failedPrecondition(Exception):
|
||||
pass
|
||||
class fieldInUse(Exception):
|
||||
@@ -702,6 +707,7 @@ REASON_EXCEPTION_MAP = {
|
||||
DOWNLOAD_QUOTA_EXCEEDED: downloadQuotaExceeded,
|
||||
DUPLICATE: duplicate,
|
||||
EVENT_DURATION_EXCEEDS_LIMIT: eventDurationExceedsLimit,
|
||||
EXPIRATION_DATE_NOT_ALLOWED_FOR_SHARED_DRIVE_MEMBERS: expirationDateNotAllowedForSharedDriveMembers,
|
||||
FAILED_PRECONDITION: failedPrecondition,
|
||||
FIELD_IN_USE: fieldInUse,
|
||||
FIELD_NOT_WRITABLE: fieldNotWritable,
|
||||
|
||||
@@ -91,7 +91,21 @@ Please go to:
|
||||
8. Press enter here on the terminal once trust is complete.
|
||||
'''
|
||||
|
||||
YOUR_GAM_PROJECT_IS_CREATED_AND_READY_TO_USE = 'That\'s it! Your GAM Project is created and ready to use.\n'
|
||||
ENABLE_SERVICE_ACCOUNT_PRIVATE_KEY_UPLOAD = '''
|
||||
Your workspace is configured to disable service account private key uploads.
|
||||
|
||||
Please go to:
|
||||
|
||||
https://github.com/taers232c/GAMADV-XTD3/wiki/Authorization#authorize-service-account-key-uploads
|
||||
|
||||
Follow the steps to allow a service account private key upload for the project ({0}) just created.
|
||||
Once those steps are completed, you can continue with your project authentication.
|
||||
'''
|
||||
|
||||
YOUR_GAM_PROJECT_IS_CREATED_AND_READY_TO_USE = '''
|
||||
That\'s it! Your GAM Project is created and ready to use.
|
||||
Proceed to the authentication steps.
|
||||
'''
|
||||
|
||||
# check|update service messages in order of appearance
|
||||
SYSTEM_TIME_STATUS = 'System time status'
|
||||
|
||||
Reference in New Issue
Block a user