mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-03 22:01:39 +00:00
Fixed bug in gam [<UserTypeEntity>] sendemail
This commit is contained in:
@@ -1,3 +1,8 @@
|
|||||||
|
7.33.03
|
||||||
|
|
||||||
|
Fixed bug in `gam [<UserTypeEntity>] sendemail ... from <EmailAddress> replyto <EmailAddress>`
|
||||||
|
where an `<EmailAddress>` of the form `Text <user@domain.com>` had the `Text` removed.
|
||||||
|
|
||||||
7.33.02
|
7.33.02
|
||||||
|
|
||||||
Added `hideinvitationssetting` to `<UserCalendarSettingsField>` used by
|
Added `hideinvitationssetting` to `<UserCalendarSettingsField>` used by
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
||||||
__version__ = '7.33.02'
|
__version__ = '7.33.03'
|
||||||
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
||||||
|
|
||||||
# pylint: disable=wrong-import-position
|
# pylint: disable=wrong-import-position
|
||||||
@@ -1331,6 +1331,8 @@ def validateEmailAddressOrUID(emailAddressOrUID, checkPeople=True, ciGroupsAPI=F
|
|||||||
return emailAddressOrUID
|
return emailAddressOrUID
|
||||||
return emailAddressOrUID.find('@') != 0 and emailAddressOrUID.count('@') <= 1
|
return emailAddressOrUID.find('@') != 0 and emailAddressOrUID.count('@') <= 1
|
||||||
|
|
||||||
|
NAME_EMAIL_ADDRESS_PATTERN = re.compile(r'^(.*)<(.+)>$')
|
||||||
|
|
||||||
# Normalize user/group email address/uid
|
# Normalize user/group email address/uid
|
||||||
# uid:12345abc -> 12345abc
|
# uid:12345abc -> 12345abc
|
||||||
# foo -> foo@domain
|
# foo -> foo@domain
|
||||||
@@ -1349,6 +1351,10 @@ def normalizeEmailAddressOrUID(emailAddressOrUID, noUid=False, checkForCustomerI
|
|||||||
return cg.group(1)
|
return cg.group(1)
|
||||||
if ciGroupsAPI and emailAddressOrUID.startswith('groups/'):
|
if ciGroupsAPI and emailAddressOrUID.startswith('groups/'):
|
||||||
return emailAddressOrUID
|
return emailAddressOrUID
|
||||||
|
if emailAddressOrUID.find('<') >= 0:
|
||||||
|
match = NAME_EMAIL_ADDRESS_PATTERN.match(emailAddressOrUID)
|
||||||
|
if match:
|
||||||
|
emailAddressOrUID = match.group(2)
|
||||||
atLoc = emailAddressOrUID.find('@')
|
atLoc = emailAddressOrUID.find('@')
|
||||||
if atLoc == 0:
|
if atLoc == 0:
|
||||||
return emailAddressOrUID[1:].lower() if not noLower else emailAddressOrUID[1:]
|
return emailAddressOrUID[1:].lower() if not noLower else emailAddressOrUID[1:]
|
||||||
@@ -4147,7 +4153,7 @@ def SetGlobalVariables():
|
|||||||
GC.Values[itemName] = _getCfgPassword(sectionName, itemName)
|
GC.Values[itemName] = _getCfgPassword(sectionName, itemName)
|
||||||
elif varType == GC.TYPE_STRING:
|
elif varType == GC.TYPE_STRING:
|
||||||
GC.Values[itemName] = _getCfgString(sectionName, itemName)
|
GC.Values[itemName] = _getCfgString(sectionName, itemName)
|
||||||
elif varType in {GC.TYPE_STRINGLIST, GC.TYPE_HEADERFORCE, GC.TYPE_HEADERORDER}:
|
elif varType in {GC.TYPE_STRINGLIST, GC.TYPE_HEADERFORCEREQUIRED, GC.TYPE_HEADERORDER}:
|
||||||
GC.Values[itemName] = _getCfgStringList(sectionName, itemName)
|
GC.Values[itemName] = _getCfgStringList(sectionName, itemName)
|
||||||
elif varType == GC.TYPE_FILE:
|
elif varType == GC.TYPE_FILE:
|
||||||
GC.Values[itemName] = _getCfgFile(sectionName, itemName)
|
GC.Values[itemName] = _getCfgFile(sectionName, itemName)
|
||||||
@@ -4290,7 +4296,7 @@ def SetGlobalVariables():
|
|||||||
if GM.Globals[GM.PID] == 0:
|
if GM.Globals[GM.PID] == 0:
|
||||||
for itemName, itemEntry in sorted(GC.VAR_INFO.items()):
|
for itemName, itemEntry in sorted(GC.VAR_INFO.items()):
|
||||||
varType = itemEntry[GC.VAR_TYPE]
|
varType = itemEntry[GC.VAR_TYPE]
|
||||||
if varType in {GC.TYPE_HEADERFILTER, GC.TYPE_HEADERFORCE, GC.TYPE_HEADERORDER, GC.TYPE_ROWFILTER}:
|
if varType in {GC.TYPE_HEADERFILTER, GC.TYPE_HEADERFORCEREQUIRED, GC.TYPE_HEADERORDER, GC.TYPE_ROWFILTER}:
|
||||||
GM.Globals[GM.PARSER].set(sectionName, itemName, '')
|
GM.Globals[GM.PARSER].set(sectionName, itemName, '')
|
||||||
elif (varType == GC.TYPE_INTEGER) and itemName in {GC.CSV_INPUT_ROW_LIMIT, GC.CSV_OUTPUT_ROW_LIMIT}:
|
elif (varType == GC.TYPE_INTEGER) and itemName in {GC.CSV_INPUT_ROW_LIMIT, GC.CSV_OUTPUT_ROW_LIMIT}:
|
||||||
GM.Globals[GM.PARSER].set(sectionName, itemName, '0')
|
GM.Globals[GM.PARSER].set(sectionName, itemName, '0')
|
||||||
@@ -7328,8 +7334,6 @@ def _addEmbeddedImagesToMessage(message, embeddedImages):
|
|||||||
except (IOError, UnicodeDecodeError) as e:
|
except (IOError, UnicodeDecodeError) as e:
|
||||||
usageErrorExit(f'{imageFilename}: {str(e)}')
|
usageErrorExit(f'{imageFilename}: {str(e)}')
|
||||||
|
|
||||||
NAME_EMAIL_ADDRESS_PATTERN = re.compile(r'^.*<(.+)>$')
|
|
||||||
|
|
||||||
# Send an email
|
# Send an email
|
||||||
def send_email(msgSubject, msgBody, msgTo, i=0, count=0, clientAccess=False, msgFrom=None, msgReplyTo=None,
|
def send_email(msgSubject, msgBody, msgTo, i=0, count=0, clientAccess=False, msgFrom=None, msgReplyTo=None,
|
||||||
html=False, charset=UTF8, attachments=None, embeddedImages=None,
|
html=False, charset=UTF8, attachments=None, embeddedImages=None,
|
||||||
@@ -7351,8 +7355,11 @@ def send_email(msgSubject, msgBody, msgTo, i=0, count=0, clientAccess=False, msg
|
|||||||
def cleanAddr(emailAddr):
|
def cleanAddr(emailAddr):
|
||||||
match = NAME_EMAIL_ADDRESS_PATTERN.match(emailAddr)
|
match = NAME_EMAIL_ADDRESS_PATTERN.match(emailAddr)
|
||||||
if match:
|
if match:
|
||||||
return match.group(1)
|
emailName = match.group(1)
|
||||||
return emailAddr
|
emailAddr = normalizeEmailAddressOrUID(match.group(2), noUid=True, noLower=True)
|
||||||
|
return (f'{emailName} <{emailAddr}>', emailAddr)
|
||||||
|
emailAddr = normalizeEmailAddressOrUID(emailAddr, noUid=True, noLower=True)
|
||||||
|
return (emailAddr, emailAddr)
|
||||||
|
|
||||||
if msgFrom is None:
|
if msgFrom is None:
|
||||||
msgFrom = _getAdminEmail()
|
msgFrom = _getAdminEmail()
|
||||||
@@ -7372,9 +7379,9 @@ def send_email(msgSubject, msgBody, msgTo, i=0, count=0, clientAccess=False, msg
|
|||||||
if embeddedImages:
|
if embeddedImages:
|
||||||
_addEmbeddedImagesToMessage(message, embeddedImages)
|
_addEmbeddedImagesToMessage(message, embeddedImages)
|
||||||
message['Subject'] = msgSubject
|
message['Subject'] = msgSubject
|
||||||
message['From'] = normalizeEmailAddressOrUID(cleanAddr(msgFrom), noUid=True, noLower=True)
|
message['From'], msgFromAddr = cleanAddr(msgFrom)
|
||||||
if msgReplyTo is not None:
|
if msgReplyTo is not None:
|
||||||
message['Reply-To'] = normalizeEmailAddressOrUID(cleanAddr(msgReplyTo), noUid=True, noLower=True)
|
message['Reply-To'], _ = cleanAddr(msgReplyTo)
|
||||||
if ccRecipients:
|
if ccRecipients:
|
||||||
message['Cc'] = ccRecipients.lower()
|
message['Cc'] = ccRecipients.lower()
|
||||||
if bccRecipients:
|
if bccRecipients:
|
||||||
@@ -7384,8 +7391,8 @@ def send_email(msgSubject, msgBody, msgTo, i=0, count=0, clientAccess=False, msg
|
|||||||
if header not in {'Subject', 'From', 'To', 'Reply-To', 'Cc', 'Bcc'}:
|
if header not in {'Subject', 'From', 'To', 'Reply-To', 'Cc', 'Bcc'}:
|
||||||
message[header] = value
|
message[header] = value
|
||||||
if mailBox is None:
|
if mailBox is None:
|
||||||
mailBox = msgFrom
|
mailBox = msgFromAddr
|
||||||
mailBoxAddr = normalizeEmailAddressOrUID(cleanAddr(mailBox), noUid=True, noLower=True)
|
_, mailBoxAddr = cleanAddr(mailBox)
|
||||||
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]:
|
||||||
|
|||||||
@@ -123,6 +123,8 @@ CSV_OUTPUT_HEADER_DROP_FILTER = 'csv_output_header_drop_filter'
|
|||||||
CSV_OUTPUT_HEADER_FORCE = 'csv_output_header_force'
|
CSV_OUTPUT_HEADER_FORCE = 'csv_output_header_force'
|
||||||
# Orde output column headers
|
# Orde output column headers
|
||||||
CSV_OUTPUT_HEADER_ORDER = 'csv_output_header_order'
|
CSV_OUTPUT_HEADER_ORDER = 'csv_output_header_order'
|
||||||
|
# Required output column headers
|
||||||
|
CSV_OUTPUT_HEADER_REQUIRED = 'csv_output_header_required'
|
||||||
# Line terminator in CSV output file
|
# Line terminator in CSV output file
|
||||||
CSV_OUTPUT_LINE_TERMINATOR = 'csv_output_line_terminator'
|
CSV_OUTPUT_LINE_TERMINATOR = 'csv_output_line_terminator'
|
||||||
# Quote character in CSV output file
|
# Quote character in CSV output file
|
||||||
@@ -329,6 +331,7 @@ CSV_INPUT_ROW_FILTER_ITEMS = {CSV_INPUT_ROW_FILTER, CSV_INPUT_ROW_FILTER_MODE,
|
|||||||
|
|
||||||
CSV_OUTPUT_ROW_FILTER_ITEMS = {CSV_OUTPUT_HEADER_FILTER, CSV_OUTPUT_HEADER_DROP_FILTER,
|
CSV_OUTPUT_ROW_FILTER_ITEMS = {CSV_OUTPUT_HEADER_FILTER, CSV_OUTPUT_HEADER_DROP_FILTER,
|
||||||
CSV_OUTPUT_HEADER_FORCE, CSV_OUTPUT_HEADER_ORDER,
|
CSV_OUTPUT_HEADER_FORCE, CSV_OUTPUT_HEADER_ORDER,
|
||||||
|
# CSV_OUTPUT_HEADER_REQUIRED,
|
||||||
CSV_OUTPUT_ROW_FILTER, CSV_OUTPUT_ROW_FILTER_MODE,
|
CSV_OUTPUT_ROW_FILTER, CSV_OUTPUT_ROW_FILTER_MODE,
|
||||||
CSV_OUTPUT_ROW_DROP_FILTER, CSV_OUTPUT_ROW_DROP_FILTER_MODE,
|
CSV_OUTPUT_ROW_DROP_FILTER, CSV_OUTPUT_ROW_DROP_FILTER_MODE,
|
||||||
CSV_OUTPUT_ROW_LIMIT}
|
CSV_OUTPUT_ROW_LIMIT}
|
||||||
@@ -373,6 +376,7 @@ Defaults = {
|
|||||||
CSV_OUTPUT_HEADER_DROP_FILTER: '',
|
CSV_OUTPUT_HEADER_DROP_FILTER: '',
|
||||||
CSV_OUTPUT_HEADER_FORCE: '',
|
CSV_OUTPUT_HEADER_FORCE: '',
|
||||||
CSV_OUTPUT_HEADER_ORDER: '',
|
CSV_OUTPUT_HEADER_ORDER: '',
|
||||||
|
# CSV_OUTPUT_HEADER_REQUIRED: '',
|
||||||
CSV_OUTPUT_LINE_TERMINATOR: 'lf',
|
CSV_OUTPUT_LINE_TERMINATOR: 'lf',
|
||||||
CSV_OUTPUT_QUOTE_CHAR: '\'"\'',
|
CSV_OUTPUT_QUOTE_CHAR: '\'"\'',
|
||||||
CSV_OUTPUT_ROW_FILTER: '',
|
CSV_OUTPUT_ROW_FILTER: '',
|
||||||
@@ -487,7 +491,7 @@ TYPE_EMAIL_OPTIONAL = 'emao'
|
|||||||
TYPE_FILE = 'file'
|
TYPE_FILE = 'file'
|
||||||
TYPE_FLOAT = 'floa'
|
TYPE_FLOAT = 'floa'
|
||||||
TYPE_HEADERFILTER = 'heaf'
|
TYPE_HEADERFILTER = 'heaf'
|
||||||
TYPE_HEADERFORCE = 'hefo'
|
TYPE_HEADERFORCEREQUIRED = 'hefr'
|
||||||
TYPE_HEADERORDER = 'heor'
|
TYPE_HEADERORDER = 'heor'
|
||||||
TYPE_INTEGER = 'inte'
|
TYPE_INTEGER = 'inte'
|
||||||
TYPE_LANGUAGE = 'lang'
|
TYPE_LANGUAGE = 'lang'
|
||||||
@@ -544,8 +548,9 @@ VAR_INFO = {
|
|||||||
CSV_OUTPUT_FIELD_DELIMITER: {VAR_TYPE: TYPE_CHARACTER},
|
CSV_OUTPUT_FIELD_DELIMITER: {VAR_TYPE: TYPE_CHARACTER},
|
||||||
CSV_OUTPUT_HEADER_FILTER: {VAR_TYPE: TYPE_HEADERFILTER},
|
CSV_OUTPUT_HEADER_FILTER: {VAR_TYPE: TYPE_HEADERFILTER},
|
||||||
CSV_OUTPUT_HEADER_DROP_FILTER: {VAR_TYPE: TYPE_HEADERFILTER},
|
CSV_OUTPUT_HEADER_DROP_FILTER: {VAR_TYPE: TYPE_HEADERFILTER},
|
||||||
CSV_OUTPUT_HEADER_FORCE: {VAR_TYPE: TYPE_HEADERFORCE},
|
CSV_OUTPUT_HEADER_FORCE: {VAR_TYPE: TYPE_HEADERFORCEREQUIRED},
|
||||||
CSV_OUTPUT_HEADER_ORDER: {VAR_TYPE: TYPE_HEADERORDER},
|
CSV_OUTPUT_HEADER_ORDER: {VAR_TYPE: TYPE_HEADERORDER},
|
||||||
|
# CSV_OUTPUT_HEADER_REQUIRED: {VAR_TYPE: TYPE_HEADERFORCEREQUIRED},
|
||||||
CSV_OUTPUT_LINE_TERMINATOR: {VAR_TYPE: TYPE_CHOICE, VAR_CHOICES: {'cr': '\r', 'lf': '\n', 'crlf': '\r\n'}},
|
CSV_OUTPUT_LINE_TERMINATOR: {VAR_TYPE: TYPE_CHOICE, VAR_CHOICES: {'cr': '\r', 'lf': '\n', 'crlf': '\r\n'}},
|
||||||
CSV_OUTPUT_QUOTE_CHAR: {VAR_TYPE: TYPE_CHARACTER},
|
CSV_OUTPUT_QUOTE_CHAR: {VAR_TYPE: TYPE_CHARACTER},
|
||||||
CSV_OUTPUT_ROW_FILTER: {VAR_TYPE: TYPE_ROWFILTER},
|
CSV_OUTPUT_ROW_FILTER: {VAR_TYPE: TYPE_ROWFILTER},
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ CSV_OUTPUT_HEADER_FILTER = 'cohf'
|
|||||||
CSV_OUTPUT_HEADER_FORCE = 'cofh'
|
CSV_OUTPUT_HEADER_FORCE = 'cofh'
|
||||||
# Order output column headers
|
# Order output column headers
|
||||||
CSV_OUTPUT_HEADER_ORDER = 'coho'
|
CSV_OUTPUT_HEADER_ORDER = 'coho'
|
||||||
|
# Required output column headers
|
||||||
|
CSV_OUTPUT_HEADER_REQUIRED = 'corh'
|
||||||
# No escape character in CSV output file
|
# No escape character in CSV output file
|
||||||
CSV_OUTPUT_NO_ESCAPE_CHAR = 'cone'
|
CSV_OUTPUT_NO_ESCAPE_CHAR = 'cone'
|
||||||
# Quote character in CSV output file
|
# Quote character in CSV output file
|
||||||
@@ -248,6 +250,7 @@ Globals = {
|
|||||||
CSV_OUTPUT_HEADER_FILTER: [],
|
CSV_OUTPUT_HEADER_FILTER: [],
|
||||||
CSV_OUTPUT_HEADER_FORCE: [],
|
CSV_OUTPUT_HEADER_FORCE: [],
|
||||||
CSV_OUTPUT_HEADER_ORDER: [],
|
CSV_OUTPUT_HEADER_ORDER: [],
|
||||||
|
# CSV_OUTPUT_HEADER_REQUIRED: [],
|
||||||
CSV_OUTPUT_NO_ESCAPE_CHAR: None,
|
CSV_OUTPUT_NO_ESCAPE_CHAR: None,
|
||||||
CSV_OUTPUT_QUOTE_CHAR: None,
|
CSV_OUTPUT_QUOTE_CHAR: None,
|
||||||
CSV_OUTPUT_ROW_DROP_FILTER: [],
|
CSV_OUTPUT_ROW_DROP_FILTER: [],
|
||||||
|
|||||||
Reference in New Issue
Block a user