1.1 --- a/imiptools/__init__.py Tue Oct 28 22:59:00 2014 +0100
1.2 +++ b/imiptools/__init__.py Tue Oct 28 23:01:26 2014 +0100
1.3 @@ -53,7 +53,7 @@
1.4 if part.get_content_type() in itip_content_types and \
1.5 part.get_param("method"):
1.6
1.7 - all_responses += handle_itip_part(part, original_recipients, self.handlers)
1.8 + all_responses += handle_itip_part(part, senders, original_recipients, self.handlers, self.messenger)
1.9 handled = True
1.10
1.11 # Pack any returned parts into a single message.
2.1 --- a/imiptools/content.py Tue Oct 28 22:59:00 2014 +0100
2.2 +++ b/imiptools/content.py Tue Oct 28 23:01:26 2014 +0100
2.3 @@ -223,12 +223,13 @@
2.4
2.5 # Handler mechanism objects.
2.6
2.7 -def handle_itip_part(part, recipients, handlers):
2.8 +def handle_itip_part(part, senders, recipients, handlers, messenger):
2.9
2.10 """
2.11 - Handle the given iTIP 'part' for the given 'recipients' using the given
2.12 - 'handlers'. Return a list of responses, each response being a tuple of the
2.13 - form (is-outgoing, message-part).
2.14 + Handle the given iTIP 'part' from the given 'senders' for the given
2.15 + 'recipients' using the given 'handlers' and information provided by the
2.16 + given 'messenger'. Return a list of responses, each response being a tuple
2.17 + of the form (is-outgoing, message-part).
2.18 """
2.19
2.20 method = part.get_param("method")
2.21 @@ -257,10 +258,10 @@
2.22
2.23 # Dispatch to a handler and obtain any response.
2.24
2.25 - handler = cls(details, recipients)
2.26 + handler = cls(details, senders, recipients, messenger)
2.27 result = methods[method](handler)()
2.28
2.29 - # Concatenate responses for a single calendar object.
2.30 + # Aggregate responses for a single message.
2.31
2.32 if result:
2.33 response_method, part = result
2.34 @@ -318,15 +319,17 @@
2.35
2.36 "General handler support."
2.37
2.38 - def __init__(self, details, recipients=None):
2.39 + def __init__(self, details, senders=None, recipients=None, messenger=None):
2.40
2.41 """
2.42 Initialise the handler with the 'details' of a calendar object and the
2.43 - 'recipients' of the object (if specifically indicated).
2.44 + 'senders' and 'recipients' of the object (if specifically indicated).
2.45 """
2.46
2.47 self.details = details
2.48 + self.senders = senders and set(senders)
2.49 self.recipients = recipients and set(recipients)
2.50 + self.messenger = messenger
2.51
2.52 self.uid = get_value(details, "UID")
2.53 self.sequence = get_value(details, "SEQUENCE")
2.54 @@ -368,9 +371,19 @@
2.55 def can_schedule(self, freebusy, periods):
2.56 return can_schedule(freebusy, periods, self.uid)
2.57
2.58 + def filter_by_senders(self, values):
2.59 + addresses = map(get_address, values)
2.60 + if self.senders:
2.61 + return self.senders.intersection(addresses)
2.62 + else:
2.63 + return addresses
2.64 +
2.65 def filter_by_recipients(self, values):
2.66 addresses = map(get_address, values)
2.67 - return self.recipients and self.recipients.intersection(addresses) or addresses
2.68 + if self.recipients:
2.69 + return self.recipients.intersection(addresses)
2.70 + else:
2.71 + return addresses
2.72
2.73 def require_organiser_and_attendees(self):
2.74
2.75 @@ -388,7 +401,15 @@
2.76 for attendee in map(get_uri, self.filter_by_recipients(attendee_map)):
2.77 attendees[attendee] = attendee_map[attendee]
2.78
2.79 - if not attendees and not organiser:
2.80 + if not attendees or not organiser:
2.81 + return None
2.82 +
2.83 + # Reject organisers that do not match any senders.
2.84 +
2.85 + organiser_value, organiser_attr = self.get_item("ORGANIZER")
2.86 + sent_by = organiser_attr.get("SENT-BY")
2.87 +
2.88 + if not self.filter_by_senders([organiser_value] + (sent_by and [sent_by] or [])):
2.89 return None
2.90
2.91 return organiser, attendees
3.1 --- a/imiptools/handlers/resource.py Tue Oct 28 22:59:00 2014 +0100
3.2 +++ b/imiptools/handlers/resource.py Tue Oct 28 23:01:26 2014 +0100
3.3 @@ -4,7 +4,7 @@
3.4 Handlers for a resource.
3.5 """
3.6
3.7 -from imiptools.content import Handler, format_datetime, to_part
3.8 +from imiptools.content import Handler, format_datetime, get_address, get_uri, to_part
3.9 from vCalendar import to_node
3.10
3.11 class Event(Handler):
3.12 @@ -78,6 +78,8 @@
3.13 scheduled = self.can_schedule(freebusy, periods)
3.14
3.15 attendee_attr["PARTSTAT"] = scheduled and "ACCEPTED" or "DECLINED"
3.16 + if self.messenger and self.messenger.sender != get_address(attendee):
3.17 + attendee_attr["SENT-BY"] = get_uri(self.messenger.sender)
3.18 self.details["ATTENDEE"] = [(attendee, attendee_attr)]
3.19
3.20 event = to_node({"VEVENT" : [(self.details, {})]})