# HG changeset patch # User Paul Boddie # Date 1414533686 -3600 # Node ID ba35611d36e2e392ec6b32a9236ec5d8aab13702 # Parent 726bb4c65d5517f9ddf5b840f28e9d2c5fc50870 Fixed attendee filtering, added organiser validation based on message senders and the sent-by attribute, adding the attribute to messages sent by the agent on behalf of resources. diff -r 726bb4c65d55 -r ba35611d36e2 imiptools/__init__.py --- a/imiptools/__init__.py Tue Oct 28 22:59:00 2014 +0100 +++ b/imiptools/__init__.py Tue Oct 28 23:01:26 2014 +0100 @@ -53,7 +53,7 @@ if part.get_content_type() in itip_content_types and \ part.get_param("method"): - all_responses += handle_itip_part(part, original_recipients, self.handlers) + all_responses += handle_itip_part(part, senders, original_recipients, self.handlers, self.messenger) handled = True # Pack any returned parts into a single message. diff -r 726bb4c65d55 -r ba35611d36e2 imiptools/content.py --- a/imiptools/content.py Tue Oct 28 22:59:00 2014 +0100 +++ b/imiptools/content.py Tue Oct 28 23:01:26 2014 +0100 @@ -223,12 +223,13 @@ # Handler mechanism objects. -def handle_itip_part(part, recipients, handlers): +def handle_itip_part(part, senders, recipients, handlers, messenger): """ - Handle the given iTIP 'part' for the given 'recipients' using the given - 'handlers'. Return a list of responses, each response being a tuple of the - form (is-outgoing, message-part). + Handle the given iTIP 'part' from the given 'senders' for the given + 'recipients' using the given 'handlers' and information provided by the + given 'messenger'. Return a list of responses, each response being a tuple + of the form (is-outgoing, message-part). """ method = part.get_param("method") @@ -257,10 +258,10 @@ # Dispatch to a handler and obtain any response. - handler = cls(details, recipients) + handler = cls(details, senders, recipients, messenger) result = methods[method](handler)() - # Concatenate responses for a single calendar object. + # Aggregate responses for a single message. if result: response_method, part = result @@ -318,15 +319,17 @@ "General handler support." - def __init__(self, details, recipients=None): + def __init__(self, details, senders=None, recipients=None, messenger=None): """ Initialise the handler with the 'details' of a calendar object and the - 'recipients' of the object (if specifically indicated). + 'senders' and 'recipients' of the object (if specifically indicated). """ self.details = details + self.senders = senders and set(senders) self.recipients = recipients and set(recipients) + self.messenger = messenger self.uid = get_value(details, "UID") self.sequence = get_value(details, "SEQUENCE") @@ -368,9 +371,19 @@ def can_schedule(self, freebusy, periods): return can_schedule(freebusy, periods, self.uid) + def filter_by_senders(self, values): + addresses = map(get_address, values) + if self.senders: + return self.senders.intersection(addresses) + else: + return addresses + def filter_by_recipients(self, values): addresses = map(get_address, values) - return self.recipients and self.recipients.intersection(addresses) or addresses + if self.recipients: + return self.recipients.intersection(addresses) + else: + return addresses def require_organiser_and_attendees(self): @@ -388,7 +401,15 @@ for attendee in map(get_uri, self.filter_by_recipients(attendee_map)): attendees[attendee] = attendee_map[attendee] - if not attendees and not organiser: + if not attendees or not organiser: + return None + + # Reject organisers that do not match any senders. + + organiser_value, organiser_attr = self.get_item("ORGANIZER") + sent_by = organiser_attr.get("SENT-BY") + + if not self.filter_by_senders([organiser_value] + (sent_by and [sent_by] or [])): return None return organiser, attendees diff -r 726bb4c65d55 -r ba35611d36e2 imiptools/handlers/resource.py --- a/imiptools/handlers/resource.py Tue Oct 28 22:59:00 2014 +0100 +++ b/imiptools/handlers/resource.py Tue Oct 28 23:01:26 2014 +0100 @@ -4,7 +4,7 @@ Handlers for a resource. """ -from imiptools.content import Handler, format_datetime, to_part +from imiptools.content import Handler, format_datetime, get_address, get_uri, to_part from vCalendar import to_node class Event(Handler): @@ -78,6 +78,8 @@ scheduled = self.can_schedule(freebusy, periods) attendee_attr["PARTSTAT"] = scheduled and "ACCEPTED" or "DECLINED" + if self.messenger and self.messenger.sender != get_address(attendee): + attendee_attr["SENT-BY"] = get_uri(self.messenger.sender) self.details["ATTENDEE"] = [(attendee, attendee_attr)] event = to_node({"VEVENT" : [(self.details, {})]})