mirror of
https://github.com/GAM-team/GAM.git
synced 2026-07-03 20:31:35 +00:00
Updated commands that send emails to not downshift 'First Last<firstlast@domain.com>'
This commit is contained in:
@@ -10,6 +10,10 @@ 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
|
See [Downloads](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads) for Windows or other options, including manual installation
|
||||||
|
|
||||||
|
### 6.72.07
|
||||||
|
|
||||||
|
Updated commands that send emails to not downshift `'First Last<firstlast@domain.com>'` to `'first last<firstlast@domain.com>'`.
|
||||||
|
|
||||||
### 6.72.06
|
### 6.72.06
|
||||||
|
|
||||||
Updated the following commands to properly handle emailaddress lists containing addresses of the form: `'First Last<firstlast@domain.com>'`.
|
Updated the following commands to properly handle emailaddress lists containing addresses of the form: `'First Last<firstlast@domain.com>'`.
|
||||||
|
|||||||
@@ -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$ rm -f /Users/admin/GAMConfig/oauth2.txt
|
||||||
admin@server:/Users/admin/bin/gamadv-xtd3$ ./gam version
|
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
|
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.06 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.72.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.2 64-bit final
|
Python 3.12.2 64-bit final
|
||||||
MacOS Sonoma 14.2.1 x86_64
|
MacOS Sonoma 14.2.1 x86_64
|
||||||
@@ -1006,7 +1006,7 @@ writes the credentials into the file oauth2.txt.
|
|||||||
C:\GAMADV-XTD3>del C:\GAMConfig\oauth2.txt
|
C:\GAMADV-XTD3>del C:\GAMConfig\oauth2.txt
|
||||||
C:\GAMADV-XTD3>gam version
|
C:\GAMADV-XTD3>gam version
|
||||||
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
|
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
|
||||||
GAMADV-XTD3 6.72.06 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.72.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.2 64-bit final
|
Python 3.12.2 64-bit final
|
||||||
Windows-10-10.0.17134 AMD64
|
Windows-10-10.0.17134 AMD64
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
Print the current version of Gam with details
|
Print the current version of Gam with details
|
||||||
```
|
```
|
||||||
gam version
|
gam version
|
||||||
GAMADV-XTD3 6.72.06 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.72.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.2 64-bit final
|
Python 3.12.2 64-bit final
|
||||||
MacOS Sonoma 14.2.1 x86_64
|
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
|
Print the current version of Gam with details and time offset information
|
||||||
```
|
```
|
||||||
gam version timeoffset
|
gam version timeoffset
|
||||||
GAMADV-XTD3 6.72.06 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.72.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.2 64-bit final
|
Python 3.12.2 64-bit final
|
||||||
MacOS Sonoma 14.2.1 x86_64
|
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
|
Print the current version of Gam with extended details and SSL information
|
||||||
```
|
```
|
||||||
gam version extended
|
gam version extended
|
||||||
GAMADV-XTD3 6.72.06 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.72.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.2 64-bit final
|
Python 3.12.2 64-bit final
|
||||||
MacOS Sonoma 14.2.1 x86_64
|
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
|
Path: /Users/Admin/bin/gamadv-xtd3
|
||||||
Version Check:
|
Version Check:
|
||||||
Current: 5.35.08
|
Current: 5.35.08
|
||||||
Latest: 6.72.06
|
Latest: 6.72.07
|
||||||
echo $?
|
echo $?
|
||||||
1
|
1
|
||||||
```
|
```
|
||||||
@@ -72,7 +72,7 @@ echo $?
|
|||||||
Print the current version number without details
|
Print the current version number without details
|
||||||
```
|
```
|
||||||
gam version simple
|
gam version simple
|
||||||
6.72.06
|
6.72.07
|
||||||
```
|
```
|
||||||
In Linux/MacOS you can do:
|
In Linux/MacOS you can do:
|
||||||
```
|
```
|
||||||
@@ -82,7 +82,7 @@ echo $VER
|
|||||||
Print the current version of Gam and address of this Wiki
|
Print the current version of Gam and address of this Wiki
|
||||||
```
|
```
|
||||||
gam help
|
gam help
|
||||||
GAM 6.72.06 - https://github.com/taers232c/GAMADV-XTD3
|
GAM 6.72.07 - https://github.com/taers232c/GAMADV-XTD3
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.2 64-bit final
|
Python 3.12.2 64-bit final
|
||||||
MacOS Sonoma 14.2.1 x86_64
|
MacOS Sonoma 14.2.1 x86_64
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
Merged GAM-Team version
|
Merged GAM-Team version
|
||||||
|
|
||||||
|
6.72.07
|
||||||
|
|
||||||
|
Updated commands that send emails to not downshift `'First Last<firstlast@domain.com>'` to `'first last<firstlast@domain.com>'`.
|
||||||
|
|
||||||
6.72.06
|
6.72.06
|
||||||
|
|
||||||
Updated the following commands to properly handle emailaddress lists containing addresses of the form: `'First Last<firstlast@domain.com>'`.
|
Updated the following commands to properly handle emailaddress lists containing addresses of the form: `'First Last<firstlast@domain.com>'`.
|
||||||
|
|||||||
@@ -6975,8 +6975,8 @@ def getEntityList(item, shlexSplit=False):
|
|||||||
return getEntitySelection(entitySelector, shlexSplit)
|
return getEntitySelection(entitySelector, shlexSplit)
|
||||||
return convertEntityToList(getString(item, minLen=0), shlexSplit=shlexSplit)
|
return convertEntityToList(getString(item, minLen=0), shlexSplit=shlexSplit)
|
||||||
|
|
||||||
def getNormalizedEmailAddressEntity(shlexSplit=False, noUid=True):
|
def getNormalizedEmailAddressEntity(shlexSplit=False, noUid=True, noLower=False):
|
||||||
return [normalizeEmailAddressOrUID(emailAddress, noUid) for emailAddress in getEntityList(Cmd.OB_EMAIL_ADDRESS_ENTITY, shlexSplit)]
|
return [normalizeEmailAddressOrUID(emailAddress, noUid=noUid, noLower=noLower) for emailAddress in getEntityList(Cmd.OB_EMAIL_ADDRESS_ENTITY, shlexSplit)]
|
||||||
|
|
||||||
def getUserObjectEntity(clObject, itemType, shlexSplit=False):
|
def getUserObjectEntity(clObject, itemType, shlexSplit=False):
|
||||||
entity = {'item': itemType, 'list': getEntityList(clObject, shlexSplit), 'dict': None}
|
entity = {'item': itemType, 'list': getEntityList(clObject, shlexSplit), 'dict': None}
|
||||||
@@ -7136,7 +7136,7 @@ def send_email(msgSubject, msgBody, msgTo, i=0, count=0, clientAccess=False, msg
|
|||||||
message[header] = value
|
message[header] = value
|
||||||
if mailBox is None:
|
if mailBox is None:
|
||||||
mailBox = msgFrom
|
mailBox = msgFrom
|
||||||
mailBoxAddr = normalizeEmailAddressOrUID(cleanAddr(mailBox), noUid=True)
|
mailBoxAddr = normalizeEmailAddressOrUID(cleanAddr(mailBox), noUid=True, noLower=True)
|
||||||
action = Act.Get()
|
action = Act.Get()
|
||||||
Act.Set(Act.SENDEMAIL)
|
Act.Set(Act.SENDEMAIL)
|
||||||
if not GC.Values[GC.SMTP_HOST]:
|
if not GC.Values[GC.SMTP_HOST]:
|
||||||
@@ -7147,7 +7147,7 @@ def send_email(msgSubject, msgBody, msgTo, i=0, count=0, clientAccess=False, msg
|
|||||||
else:
|
else:
|
||||||
userId = mailBoxAddr
|
userId = mailBoxAddr
|
||||||
gmail = buildGAPIObject(API.GMAIL)
|
gmail = buildGAPIObject(API.GMAIL)
|
||||||
message['To'] = (msgTo if msgTo else userId).lower()
|
message['To'] = msgTo if msgTo else userId
|
||||||
try:
|
try:
|
||||||
result = callGAPI(gmail.users().messages(), 'send',
|
result = callGAPI(gmail.users().messages(), 'send',
|
||||||
throwReasons=[GAPI.SERVICE_NOT_AVAILABLE, GAPI.AUTH_ERROR, GAPI.DOMAIN_POLICY,
|
throwReasons=[GAPI.SERVICE_NOT_AVAILABLE, GAPI.AUTH_ERROR, GAPI.DOMAIN_POLICY,
|
||||||
@@ -7158,7 +7158,7 @@ def send_email(msgSubject, msgBody, msgTo, i=0, count=0, clientAccess=False, msg
|
|||||||
GAPI.invalid, GAPI.invalidArgument, GAPI.forbidden, GAPI.permissionDenied) as e:
|
GAPI.invalid, GAPI.invalidArgument, GAPI.forbidden, GAPI.permissionDenied) as e:
|
||||||
entityActionFailedWarning([Ent.RECIPIENT, msgTo, Ent.MESSAGE, msgSubject], str(e), i, count)
|
entityActionFailedWarning([Ent.RECIPIENT, msgTo, Ent.MESSAGE, msgSubject], str(e), i, count)
|
||||||
else:
|
else:
|
||||||
message['To'] = (msgTo if msgTo else mailBoxAddr).lower()
|
message['To'] = msgTo if msgTo else mailBoxAddr
|
||||||
server = None
|
server = None
|
||||||
try:
|
try:
|
||||||
server = smtplib.SMTP(GC.Values[GC.SMTP_HOST], 587, GC.Values[GC.SMTP_FQDN])
|
server = smtplib.SMTP(GC.Values[GC.SMTP_HOST], 587, GC.Values[GC.SMTP_FQDN])
|
||||||
@@ -14504,6 +14504,12 @@ def sendCreateUpdateUserNotification(body, basenotify, tagReplacements, i=0, cou
|
|||||||
send_email(notify['subject'], notify['message'], recipient, i, count,
|
send_email(notify['subject'], notify['message'], recipient, i, count,
|
||||||
msgFrom=msgFrom, msgReplyTo=msgReplyTo, html=notify['html'], charset=notify['charset'], mailBox=mailBox)
|
msgFrom=msgFrom, msgReplyTo=msgReplyTo, html=notify['html'], charset=notify['charset'], mailBox=mailBox)
|
||||||
|
|
||||||
|
def getRecipients():
|
||||||
|
if checkArgumentPresent('select'):
|
||||||
|
_, recipients = getEntityToModify(defaultEntityType=Cmd.ENTITY_USERS)
|
||||||
|
return [normalizeEmailAddressOrUID(emailAddress, noUid=True, noLower=True) for emailAddress in recipients]
|
||||||
|
return getNormalizedEmailAddressEntity(shlexSplit=True, noLower=True)
|
||||||
|
|
||||||
# gam sendemail [recipient|to] <RecipientEntity> [from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>]
|
# gam sendemail [recipient|to] <RecipientEntity> [from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>]
|
||||||
# [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
# [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
|
||||||
# [subject <String>]
|
# [subject <String>]
|
||||||
@@ -14529,12 +14535,6 @@ def sendCreateUpdateUserNotification(body, basenotify, tagReplacements, i=0, cou
|
|||||||
# [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
# [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
|
||||||
# (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
# (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
|
||||||
def doSendEmail(users=None):
|
def doSendEmail(users=None):
|
||||||
def getRecipients():
|
|
||||||
if checkArgumentPresent('select'):
|
|
||||||
_, recipients = getEntityToModify(defaultEntityType=Cmd.ENTITY_USERS)
|
|
||||||
return [normalizeEmailAddressOrUID(emailAddress, noUid=True) for emailAddress in recipients]
|
|
||||||
return getNormalizedEmailAddressEntity(shlexSplit=True)
|
|
||||||
|
|
||||||
body = {}
|
body = {}
|
||||||
notify = {'subject': '', 'message': '', 'html': False, 'charset': UTF8, 'password': ''}
|
notify = {'subject': '', 'message': '', 'html': False, 'charset': UTF8, 'password': ''}
|
||||||
msgFroms = [_getAdminEmail()]
|
msgFroms = [_getAdminEmail()]
|
||||||
@@ -41205,7 +41205,7 @@ def getUserAttributes(cd, updateCmd, noUid=False):
|
|||||||
while Cmd.ArgumentsRemaining():
|
while Cmd.ArgumentsRemaining():
|
||||||
myarg = getArgument()
|
myarg = getArgument()
|
||||||
if myarg == 'notify':
|
if myarg == 'notify':
|
||||||
notify['recipients'] = getNormalizedEmailAddressEntity(shlexSplit=True)
|
notify['recipients'] = getNormalizedEmailAddressEntity(shlexSplit=True, noLower=True)
|
||||||
elif myarg == 'subject':
|
elif myarg == 'subject':
|
||||||
notify['subject'] = getString(Cmd.OB_STRING)
|
notify['subject'] = getString(Cmd.OB_STRING)
|
||||||
elif myarg in SORF_MSG_FILE_ARGUMENTS:
|
elif myarg in SORF_MSG_FILE_ARGUMENTS:
|
||||||
@@ -67254,12 +67254,6 @@ def _decodeHeader(header):
|
|||||||
# (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_forward <Number>])|(ids <ThreadIDEntity>)
|
# (((query <QueryGmail> [querytime<String> <Date>]*) (matchlabel <LabelName>) [or|and])+ [quick|notquick] [doit] [max_to_forward <Number>])|(ids <ThreadIDEntity>)
|
||||||
# [subject <String>] [addorigfieldstosubject [<Boolean>]] [altcharset <String>]
|
# [subject <String>] [addorigfieldstosubject [<Boolean>]] [altcharset <String>]
|
||||||
def forwardMessagesThreads(users, entityType):
|
def forwardMessagesThreads(users, entityType):
|
||||||
def getRecipients():
|
|
||||||
if checkArgumentPresent('select'):
|
|
||||||
_, recipients = getEntityToModify(defaultEntityType=Cmd.ENTITY_USERS)
|
|
||||||
return [normalizeEmailAddressOrUID(emailAddress, noUid=True) for emailAddress in recipients]
|
|
||||||
return getNormalizedEmailAddressEntity()
|
|
||||||
|
|
||||||
checkArgumentPresent({'recipient', 'recipients', 'to'})
|
checkArgumentPresent({'recipient', 'recipients', 'to'})
|
||||||
recipients = getRecipients()
|
recipients = getRecipients()
|
||||||
parameters = _initMessageThreadParameters(entityType, False, 1)
|
parameters = _initMessageThreadParameters(entityType, False, 1)
|
||||||
|
|||||||
@@ -53,6 +53,13 @@ try:
|
|||||||
except ImportError: # pragma: NO COVER
|
except ImportError: # pragma: NO COVER
|
||||||
google_auth_httplib2 = None
|
google_auth_httplib2 = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
from google.api_core import universe
|
||||||
|
|
||||||
|
HAS_UNIVERSE = True
|
||||||
|
except ImportError:
|
||||||
|
HAS_UNIVERSE = False
|
||||||
|
|
||||||
# Local imports
|
# Local imports
|
||||||
from googleapiclient import _auth, mimeparse
|
from googleapiclient import _auth, mimeparse
|
||||||
from googleapiclient._helpers import _add_query_parameter, positional
|
from googleapiclient._helpers import _add_query_parameter, positional
|
||||||
@@ -116,12 +123,22 @@ _PAGE_TOKEN_NAMES = ("pageToken", "nextPageToken")
|
|||||||
# Parameters controlling mTLS behavior. See https://google.aip.dev/auth/4114.
|
# Parameters controlling mTLS behavior. See https://google.aip.dev/auth/4114.
|
||||||
GOOGLE_API_USE_CLIENT_CERTIFICATE = "GOOGLE_API_USE_CLIENT_CERTIFICATE"
|
GOOGLE_API_USE_CLIENT_CERTIFICATE = "GOOGLE_API_USE_CLIENT_CERTIFICATE"
|
||||||
GOOGLE_API_USE_MTLS_ENDPOINT = "GOOGLE_API_USE_MTLS_ENDPOINT"
|
GOOGLE_API_USE_MTLS_ENDPOINT = "GOOGLE_API_USE_MTLS_ENDPOINT"
|
||||||
|
GOOGLE_CLOUD_UNIVERSE_DOMAIN = "GOOGLE_CLOUD_UNIVERSE_DOMAIN"
|
||||||
|
DEFAULT_UNIVERSE = "googleapis.com"
|
||||||
# Parameters accepted by the stack, but not visible via discovery.
|
# Parameters accepted by the stack, but not visible via discovery.
|
||||||
# TODO(dhermes): Remove 'userip' in 'v2'.
|
# TODO(dhermes): Remove 'userip' in 'v2'.
|
||||||
STACK_QUERY_PARAMETERS = frozenset(["trace", "pp", "userip", "strict"])
|
STACK_QUERY_PARAMETERS = frozenset(["trace", "pp", "userip", "strict"])
|
||||||
STACK_QUERY_PARAMETER_DEFAULT_VALUE = {"type": "string", "location": "query"}
|
STACK_QUERY_PARAMETER_DEFAULT_VALUE = {"type": "string", "location": "query"}
|
||||||
|
|
||||||
|
|
||||||
|
class APICoreVersionError(ValueError):
|
||||||
|
def __init__(self):
|
||||||
|
message = (
|
||||||
|
"google-api-core >= 2.18.0 is required to use the universe domain feature."
|
||||||
|
)
|
||||||
|
super().__init__(message)
|
||||||
|
|
||||||
|
|
||||||
# Library-specific reserved words beyond Python keywords.
|
# Library-specific reserved words beyond Python keywords.
|
||||||
RESERVED_WORDS = frozenset(["body"])
|
RESERVED_WORDS = frozenset(["body"])
|
||||||
|
|
||||||
@@ -436,6 +453,13 @@ def _retrieve_discovery_doc(
|
|||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
|
def _check_api_core_compatible_with_credentials_universe(credentials):
|
||||||
|
if not HAS_UNIVERSE:
|
||||||
|
credentials_universe = getattr(credentials, "universe_domain", None)
|
||||||
|
if credentials_universe and credentials_universe != DEFAULT_UNIVERSE:
|
||||||
|
raise APICoreVersionError
|
||||||
|
|
||||||
|
|
||||||
@positional(1)
|
@positional(1)
|
||||||
def build_from_document(
|
def build_from_document(
|
||||||
service,
|
service,
|
||||||
@@ -544,6 +568,18 @@ def build_from_document(
|
|||||||
|
|
||||||
# If an API Endpoint is provided on client options, use that as the base URL
|
# If an API Endpoint is provided on client options, use that as the base URL
|
||||||
base = urllib.parse.urljoin(service["rootUrl"], service["servicePath"])
|
base = urllib.parse.urljoin(service["rootUrl"], service["servicePath"])
|
||||||
|
universe_domain = None
|
||||||
|
if HAS_UNIVERSE:
|
||||||
|
universe_domain_env = os.getenv(GOOGLE_CLOUD_UNIVERSE_DOMAIN, None)
|
||||||
|
universe_domain = universe.determine_domain(
|
||||||
|
client_options.universe_domain, universe_domain_env
|
||||||
|
)
|
||||||
|
base = base.replace(universe.DEFAULT_UNIVERSE, universe_domain)
|
||||||
|
else:
|
||||||
|
client_universe = getattr(client_options, "universe_domain", None)
|
||||||
|
if client_universe:
|
||||||
|
raise APICoreVersionError
|
||||||
|
|
||||||
audience_for_self_signed_jwt = base
|
audience_for_self_signed_jwt = base
|
||||||
if client_options.api_endpoint:
|
if client_options.api_endpoint:
|
||||||
base = client_options.api_endpoint
|
base = client_options.api_endpoint
|
||||||
@@ -582,6 +618,9 @@ def build_from_document(
|
|||||||
quota_project_id=client_options.quota_project_id,
|
quota_project_id=client_options.quota_project_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Check google-api-core >= 2.18.0 if credentials' universe != "googleapis.com".
|
||||||
|
_check_api_core_compatible_with_credentials_universe(credentials)
|
||||||
|
|
||||||
# The credentials need to be scoped.
|
# The credentials need to be scoped.
|
||||||
# If the user provided scopes via client_options don't override them
|
# If the user provided scopes via client_options don't override them
|
||||||
if not client_options.scopes:
|
if not client_options.scopes:
|
||||||
@@ -666,7 +705,15 @@ def build_from_document(
|
|||||||
if use_mtls_endpoint == "always" or (
|
if use_mtls_endpoint == "always" or (
|
||||||
use_mtls_endpoint == "auto" and client_cert_to_use
|
use_mtls_endpoint == "auto" and client_cert_to_use
|
||||||
):
|
):
|
||||||
|
if HAS_UNIVERSE and universe_domain != universe.DEFAULT_UNIVERSE:
|
||||||
|
raise MutualTLSChannelError(
|
||||||
|
f"mTLS is not supported in any universe other than {universe.DEFAULT_UNIVERSE}."
|
||||||
|
)
|
||||||
base = mtls_endpoint
|
base = mtls_endpoint
|
||||||
|
else:
|
||||||
|
# Check google-api-core >= 2.18.0 if credentials' universe != "googleapis.com".
|
||||||
|
http_credentials = getattr(http, "credentials", None)
|
||||||
|
_check_api_core_compatible_with_credentials_universe(http_credentials)
|
||||||
|
|
||||||
if model is None:
|
if model is None:
|
||||||
features = service.get("features", [])
|
features = service.get("features", [])
|
||||||
@@ -681,6 +728,7 @@ def build_from_document(
|
|||||||
resourceDesc=service,
|
resourceDesc=service,
|
||||||
rootDesc=service,
|
rootDesc=service,
|
||||||
schema=schema,
|
schema=schema,
|
||||||
|
universe_domain=universe_domain,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -1043,6 +1091,9 @@ def createMethod(methodName, methodDesc, rootDesc, schema):
|
|||||||
def method(self, **kwargs):
|
def method(self, **kwargs):
|
||||||
# Don't bother with doc string, it will be over-written by createMethod.
|
# Don't bother with doc string, it will be over-written by createMethod.
|
||||||
|
|
||||||
|
# Validate credentials for the configured universe.
|
||||||
|
self._validate_credentials()
|
||||||
|
|
||||||
for name in kwargs:
|
for name in kwargs:
|
||||||
if name not in parameters.argmap:
|
if name not in parameters.argmap:
|
||||||
raise TypeError("Got an unexpected keyword argument {}".format(name))
|
raise TypeError("Got an unexpected keyword argument {}".format(name))
|
||||||
@@ -1352,6 +1403,7 @@ class Resource(object):
|
|||||||
resourceDesc,
|
resourceDesc,
|
||||||
rootDesc,
|
rootDesc,
|
||||||
schema,
|
schema,
|
||||||
|
universe_domain=universe.DEFAULT_UNIVERSE if HAS_UNIVERSE else "",
|
||||||
):
|
):
|
||||||
"""Build a Resource from the API description.
|
"""Build a Resource from the API description.
|
||||||
|
|
||||||
@@ -1369,6 +1421,8 @@ class Resource(object):
|
|||||||
is considered a resource.
|
is considered a resource.
|
||||||
rootDesc: object, the entire deserialized discovery document.
|
rootDesc: object, the entire deserialized discovery document.
|
||||||
schema: object, mapping of schema names to schema descriptions.
|
schema: object, mapping of schema names to schema descriptions.
|
||||||
|
universe_domain: string, the universe for the API. The default universe
|
||||||
|
is "googleapis.com".
|
||||||
"""
|
"""
|
||||||
self._dynamic_attrs = []
|
self._dynamic_attrs = []
|
||||||
|
|
||||||
@@ -1380,6 +1434,8 @@ class Resource(object):
|
|||||||
self._resourceDesc = resourceDesc
|
self._resourceDesc = resourceDesc
|
||||||
self._rootDesc = rootDesc
|
self._rootDesc = rootDesc
|
||||||
self._schema = schema
|
self._schema = schema
|
||||||
|
self._universe_domain = universe_domain
|
||||||
|
self._credentials_validated = False
|
||||||
|
|
||||||
self._set_service_methods()
|
self._set_service_methods()
|
||||||
|
|
||||||
@@ -1502,6 +1558,7 @@ class Resource(object):
|
|||||||
resourceDesc=methodDesc,
|
resourceDesc=methodDesc,
|
||||||
rootDesc=rootDesc,
|
rootDesc=rootDesc,
|
||||||
schema=schema,
|
schema=schema,
|
||||||
|
universe_domain=self._universe_domain,
|
||||||
)
|
)
|
||||||
|
|
||||||
setattr(methodResource, "__doc__", "A collection resource.")
|
setattr(methodResource, "__doc__", "A collection resource.")
|
||||||
@@ -1546,6 +1603,27 @@ class Resource(object):
|
|||||||
fixedMethodName, method.__get__(self, self.__class__)
|
fixedMethodName, method.__get__(self, self.__class__)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _validate_credentials(self):
|
||||||
|
"""Validates client's and credentials' universe domains are consistent.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True iff the configured universe domain is valid.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
UniverseMismatchError: If the configured universe domain is not valid.
|
||||||
|
"""
|
||||||
|
credentials = getattr(self._http, "credentials", None)
|
||||||
|
|
||||||
|
self._credentials_validated = (
|
||||||
|
(
|
||||||
|
self._credentials_validated
|
||||||
|
or universe.compare_domains(self._universe_domain, credentials)
|
||||||
|
)
|
||||||
|
if HAS_UNIVERSE
|
||||||
|
else True
|
||||||
|
)
|
||||||
|
return self._credentials_validated
|
||||||
|
|
||||||
|
|
||||||
def _findPageTokenName(fields):
|
def _findPageTokenName(fields):
|
||||||
"""Search field names for one like a page token.
|
"""Search field names for one like a page token.
|
||||||
|
|||||||
@@ -12,4 +12,4 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
__version__ = "2.114.0"
|
__version__ = "2.124.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user