X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=roundup%2Fmailgw.py;h=7a71d6a7017dc9e90705ec7b0c0335d600342696;hb=f2228172dcbed77780ef7b60b10ac3e85cded918;hp=922dc12656a8d6dafc601aba82223b97fad1a32c;hpb=1631bfec580afbc7c7051a8c0e169297092304ba;p=roundup.git diff --git a/roundup/mailgw.py b/roundup/mailgw.py index 922dc12..7a71d6a 100644 --- a/roundup/mailgw.py +++ b/roundup/mailgw.py @@ -247,6 +247,22 @@ class Message(mimetools.Message): parts.append(part) return parts + def _decode_header_to_utf8(self, hdr): + l = [] + prev_encoded = False + for part, encoding in decode_header(hdr): + if encoding: + part = part.decode(encoding) + # RFC 2047 specifies that between encoded parts spaces are + # swallowed while at the borders from encoded to non-encoded + # or vice-versa we must preserve a space. Multiple adjacent + # non-encoded parts should not occur. + if l and prev_encoded != bool(encoding): + l.append(' ') + prev_encoded = bool(encoding) + l.append(part) + return ''.join([s.encode('utf-8') for s in l]) + def getheader(self, name, default=None): hdr = mimetools.Message.getheader(self, name, default) # TODO are there any other False values possible? @@ -257,24 +273,13 @@ class Message(mimetools.Message): return '' if hdr: hdr = hdr.replace('\n','') # Inserted by rfc822.readheaders - # historically this method has returned utf-8 encoded string - l = [] - for part, encoding in decode_header(hdr): - if encoding: - part = part.decode(encoding) - l.append(part) - return ''.join([s.encode('utf-8') for s in l]) + return self._decode_header_to_utf8(hdr) def getaddrlist(self, name): # overload to decode the name part of the address l = [] for (name, addr) in mimetools.Message.getaddrlist(self, name): - p = [] - for part, encoding in decode_header(name): - if encoding: - part = part.decode(encoding) - p.append(part) - name = ''.join([s.encode('utf-8') for s in p]) + name = self._decode_header_to_utf8(name) l.append((name, addr)) return l @@ -549,6 +554,7 @@ class parsedMessage: self.nodeid = None self.author = None self.recipients = None + self.msg_props = {} self.props = None self.content = None self.attachments = None @@ -1052,13 +1058,14 @@ encrypted.""") 'You are not permitted to add files to %(classname)s.' ) % self.__dict__ + self.msg_props['files'] = files if self.nodeid: # extend the existing files list fileprop = self.cl.get(self.nodeid, 'files') fileprop.extend(files) files = fileprop - self.props['files'] = files + self.props['files'] = files def create_msg(self): ''' Create msg containing all the relevant information from the message @@ -1066,6 +1073,7 @@ encrypted.""") if not self.properties.has_key('messages'): return msg_props = self.mailgw.get_class_arguments('msg') + self.msg_props.update (msg_props) # Get the message ids inreplyto = self.message.getheader('in-reply-to') or '' @@ -1093,8 +1101,8 @@ not find a text/plain part to use. try: message_id = self.db.msg.create(author=self.author, recipients=self.recipients, date=date.Date('.'), - summary=summary, content=content, files=self.props['files'], - messageid=messageid, inreplyto=inreplyto, **msg_props) + summary=summary, content=content, + messageid=messageid, inreplyto=inreplyto, **self.msg_props) except exceptions.Reject, error: raise MailUsageError, _(""" Mail message was rejected by a detector. @@ -1658,7 +1666,17 @@ def uidFromAddress(db, address, create=1, **user_props): props = db.user.getprops() if props.has_key('alternate_addresses'): users = db.user.filter(None, {'alternate_addresses': address}) - user = extractUserFromList(db.user, users) + # We want an exact match of the email, not just a substring + # match. Otherwise e.g. support@example.com would match + # discuss-support@example.com which is not what we want. + found_users = [] + for u in users: + alt = db.user.get(u, 'alternate_addresses').split('\n') + for a in alt: + if a.strip().lower() == address.lower(): + found_users.append(u) + break + user = extractUserFromList(db.user, found_users) if user is not None: return user @@ -1688,7 +1706,7 @@ def uidFromAddress(db, address, create=1, **user_props): try: return db.user.create(username=trying, address=address, realname=realname, roles=db.config.NEW_EMAIL_USER_ROLES, - password=password.Password(password.generatePassword()), + password=password.Password(password.generatePassword(), config=db.config), **user_props) except exceptions.Reject: return 0