# HG changeset patch # User Paul Boddie # Date 1414709547 -3600 # Node ID 3d5387851b23eb04fd266acab85d28df305108bb # Parent e8de97cdb2a1df357e3adc5a42d8b007980f27eb Fixed the validation of objects originating from attendees. Added the storage of participation updates from attendees, in addition to the existing storage of objects sent by organisers. diff -r e8de97cdb2a1 -r 3d5387851b23 imiptools/content.py --- a/imiptools/content.py Thu Oct 30 23:44:37 2014 +0100 +++ b/imiptools/content.py Thu Oct 30 23:52:27 2014 +0100 @@ -385,7 +385,7 @@ else: return addresses - def require_organiser_and_attendees(self): + def require_organiser_and_attendees(self, from_organiser=True): """ Return the organiser and attendees for the current object, filtered by @@ -397,8 +397,10 @@ # Only provide details for recipients who are also attendees. + filter_fn = from_organiser and self.filter_by_recipients or self.filter_by_senders + attendees = {} - for attendee in map(get_uri, self.filter_by_recipients(attendee_map)): + for attendee in map(get_uri, filter_fn(attendee_map)): attendees[attendee] = attendee_map[attendee] if not attendees or not organiser: @@ -425,23 +427,33 @@ return self.filter_by_senders(identities) - def have_new_object(self, attendee, objtype): + def get_object(self, user, objtype): + + """ + Return the stored object to which the current object refers for the + given 'user' and for the given 'objtype'. + """ + + f = self.store.get_event(user, self.uid) + obj = f and parse_object(f, "utf-8", objtype) + return obj + + def have_new_object(self, attendee, objtype, obj=None): """ Return whether the current object is new to the 'attendee' for the given 'objtype'. """ - f = self.store.get_event(attendee, self.uid) - event = f and parse_object(f, "utf-8", objtype) + obj = obj or self.get_object(attendee, objtype) # If found, compare SEQUENCE and potentially DTSTAMP. - if event: - sequence = get_value(event, "SEQUENCE") - dtstamp = get_value(event, "DTSTAMP") + if obj: + sequence = get_value(obj, "SEQUENCE") + dtstamp = get_value(obj, "DTSTAMP") - # If the request refers to an older version of the event, ignore + # If the request refers to an older version of the object, ignore # it. old_dtstamp = self.dtstamp < dtstamp diff -r e8de97cdb2a1 -r 3d5387851b23 imiptools/handlers/person.py --- a/imiptools/handlers/person.py Thu Oct 30 23:44:37 2014 +0100 +++ b/imiptools/handlers/person.py Thu Oct 30 23:52:27 2014 +0100 @@ -20,7 +20,7 @@ def _record_and_deliver(self, objtype, from_organiser=True, queue=False): - oa = self.require_organiser_and_attendees() + oa = self.require_organiser_and_attendees(from_organiser) if not oa: return False @@ -28,24 +28,47 @@ # Validate the organiser or attendee, ignoring spoofed requests. - if not self.validate_identities(from_organiser and [organiser_item] or attendees): + if not self.validate_identities(from_organiser and [organiser_item] or attendees.items()): return False # Process each attendee separately. - for attendee, attendee_attr in attendees.items(): + if from_organiser: + for attendee, attendee_attr in attendees.items(): + + if not self.have_new_object(attendee, objtype): + continue + + # Store the object and queue any request. - if not self.have_new_object(attendee, objtype): - continue + self.store.set_event(attendee, self.uid, to_node( + {objtype : [(self.details, {})]} + )) - # Store the object and queue any request. + if queue: + self.store.queue_request(attendee, self.uid) + + # As organiser, update attendance. - self.store.set_event(attendee, self.uid, to_node( - {objtype : [(self.details, {})]} - )) + else: + obj = self.get_object(organiser, objtype) + + if obj and self.have_new_object(organiser, objtype, obj): + attendee_map = self.get_value_map("ATTENDEE") + + for attendee, attendee_attr in attendees.items(): + + # Update attendance in the loaded object. - if queue: - self.store.queue_request(attendee, self.uid) + attendee_map[attendee] = attendee_attr + + # Set the new details and store the object. + + obj["ATTENDEE"] = attendee_map.items() + + self.store.set_event(organiser, self.uid, to_node( + {objtype : [(obj, {})]} + )) return True