Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Use canonical calendar user address for group attendees and vCard X-A…

…DDRESSBOOKSERVER-MEMBER

git-svn-id: https://svn.calendarserver.org/repository/calendarserver/CalendarServer/trunk@13250 e27351fd-9f3e-4f54-a53b-843176b1656c
  • Loading branch information
bgaya committed Apr 10, 2014
1 parent bde8198 commit f99a9597ca6aebbd6abaa36935a4af4ea94fe29d
Showing with 27 additions and 26 deletions.
  1. +10 −12 twistedcaldav/ical.py
  2. +14 −11 txdav/caldav/datastore/sql.py
  3. +2 −2 txdav/who/test/test_group_attendees.py
  4. +1 −1 txdav/who/vcard.py
@@ -3384,38 +3384,36 @@ def normalizeCalendarUserAddresses(self, lookupFunction, recordFunction,


@inlineCallbacks
def expandGroupAttendee(self, groupGUID, memberGUIDs, recordFunction):
def expandGroupAttendee(self, groupCUA, memberCUAs, recordFunction):

memberUUIDs = set(["urn:uuid:" + str(memberGUID) for memberGUID in memberGUIDs])
groupUUID = "urn:uuid:" + str(groupGUID)
changed = False
for component in self.subcomponents():
if component.name() in ignoredComponents:
continue

oldAttendeeProps = tuple(component.properties("ATTENDEE"))
oldAttendeeUUIDs = set([attendeeProp.value() for attendeeProp in oldAttendeeProps])
oldAttendeeCUAs = set([attendeeProp.value() for attendeeProp in oldAttendeeProps])

# add new member attendees
for memberUUID in sorted(memberUUIDs - oldAttendeeUUIDs):
directoryRecord = yield recordFunction(memberUUID)
newAttendeeProp = directoryRecord.attendee(params={"MEMBER": groupUUID})
for memberCUA in sorted(set(memberCUAs) - oldAttendeeCUAs):
directoryRecord = yield recordFunction(memberCUA)
newAttendeeProp = directoryRecord.attendee(params={"MEMBER": groupCUA})
component.addProperty(newAttendeeProp)
changed = True

# remove attendee or update MEMBER attribute for non-primary attendees in this group,
for attendeeProp in oldAttendeeProps:
if attendeeProp.hasParameter("MEMBER"):
parameterValues = tuple(attendeeProp.parameterValues("MEMBER"))
if groupUUID in parameterValues:
if attendeeProp.value() not in memberUUIDs:
attendeeProp.removeParameterValue("MEMBER", groupUUID)
if groupCUA in parameterValues:
if attendeeProp.value() not in memberCUAs:
attendeeProp.removeParameterValue("MEMBER", groupCUA)
if not attendeeProp.parameterValues("MEMBER"):
component.removeProperty(attendeeProp)
changed = True
else:
if attendeeProp.value() in memberUUIDs:
attendeeProp.setParameter("MEMBER", parameterValues + (groupUUID,))
if attendeeProp.value() in memberCUAs:
attendeeProp.setParameter("MEMBER", parameterValues + (groupCUA,))
changed = True

returnValue(changed)
@@ -1937,30 +1937,29 @@ def expandGroupAttendees(self, component):
"""
Expand group attendees
"""

if not config.Scheduling.Options.AllowGroupAsAttendee:
return

attendeeProps = component.getAllAttendeeProperties()
groupGUIDs = set([
uuid.UUID(attendeeProp.value()[len("urn:uuid:"):]) for attendeeProp in attendeeProps
groupCUAs = set([
attendeeProp.value() for attendeeProp in attendeeProps
if attendeeProp.parameterValue("CUTYPE") == "GROUP"
])
for groupCUA in groupCUAs:

for groupGUID in groupGUIDs:

groupRecord = yield self.directoryService().recordWithGUID(groupGUID)
groupRecord = yield self.directoryService().recordWithCalendarUserAddress(groupCUA)
if groupRecord:
members = yield groupRecord.expandedMembers()
memberGUIDs = sorted([member.guid for member in members])

# calculate hash
memberUIDs = sorted([member.uid for member in members])
membershipHashContent = hashlib.md5()
for memberGUID in memberGUIDs:
membershipHashContent.update(str(memberGUID))
for memberUID in memberUIDs:
membershipHashContent.update(memberUID)
membershipHash = membershipHashContent.hexdigest()

# associate group ID with self
groupID, _ignore_name, membershipHash, _ignore_modDate = yield self._txn.groupByUID(str(groupGUID))
groupID, _ignore_name, membershipHash, _ignore_modDate = yield self._txn.groupByUID(groupRecord.uid)
try:
groupAttendee = schema.GROUP_ATTENDEE
yield Insert({
@@ -1972,7 +1971,11 @@ def expandGroupAttendees(self, component):
pass

# get members
yield component.expandGroupAttendee(groupGUID, memberGUIDs, self.directoryService().recordWithCalendarUserAddress)
yield component.expandGroupAttendee(
groupRecord.canonicalCalendarUserAddress(),
set([member.canonicalCalendarUserAddress() for member in members]),
self.directoryService().recordWithCalendarUserAddress
)


def validCalendarDataCheck(self, component, inserting):
@@ -317,8 +317,8 @@ def test_twoGroupPUT(self):
ATTENDEE;CN=User 01;EMAIL=user01@example.com;RSVP=TRUE:urn:uuid:10000000-0000-0000-0000-000000000001
ATTENDEE;CN=Group 02;CUTYPE=GROUP;EMAIL=group02@example.com;RSVP=TRUE;SCHEDULE-STATUS=3.7:urn:uuid:20000000-0000-0000-0000-000000000002
ATTENDEE;CN=Group 04;CUTYPE=GROUP;RSVP=TRUE;SCHEDULE-STATUS=3.7:urn:uuid:20000000-0000-0000-0000-000000000004
ATTENDEE;CN=User 06;EMAIL=user06@example.com;MEMBER="urn:uuid:20000000-0000-0000-0000-000000000002","urn:uuid:20000000-0000-0000-0000-000000000004";PARTSTAT=NEEDS-ACTION;RSVP=TRUE;SCHEDULE-STATUS=1.2:urn:uuid:10000000-0000-0000-0000-000000000006
ATTENDEE;CN=User 07;EMAIL=user07@example.com;MEMBER="urn:uuid:20000000-0000-0000-0000-000000000002","urn:uuid:20000000-0000-0000-0000-000000000004";PARTSTAT=NEEDS-ACTION;RSVP=TRUE;SCHEDULE-STATUS=1.2:urn:uuid:10000000-0000-0000-0000-000000000007
ATTENDEE;CN=User 06;EMAIL=user06@example.com;MEMBER="urn:uuid:20000000-0000-0000-0000-000000000004","urn:uuid:20000000-0000-0000-0000-000000000002";PARTSTAT=NEEDS-ACTION;RSVP=TRUE;SCHEDULE-STATUS=1.2:urn:uuid:10000000-0000-0000-0000-000000000006
ATTENDEE;CN=User 07;EMAIL=user07@example.com;MEMBER="urn:uuid:20000000-0000-0000-0000-000000000004","urn:uuid:20000000-0000-0000-0000-000000000002";PARTSTAT=NEEDS-ACTION;RSVP=TRUE;SCHEDULE-STATUS=1.2:urn:uuid:10000000-0000-0000-0000-000000000007
ATTENDEE;CN=User 08;EMAIL=user08@example.com;MEMBER="urn:uuid:20000000-0000-0000-0000-000000000004";PARTSTAT=NEEDS-ACTION;RSVP=TRUE;SCHEDULE-STATUS=1.2:urn:uuid:10000000-0000-0000-0000-000000000008
ATTENDEE;CN=User 09;EMAIL=user09@example.com;MEMBER="urn:uuid:20000000-0000-0000-0000-000000000004";PARTSTAT=NEEDS-ACTION;RSVP=TRUE;SCHEDULE-STATUS=1.2:urn:uuid:10000000-0000-0000-0000-000000000009
ATTENDEE;CN=User 10;EMAIL=user10@example.com;MEMBER="urn:uuid:20000000-0000-0000-0000-000000000004";PARTSTAT=NEEDS-ACTION;RSVP=TRUE;SCHEDULE-STATUS=1.2:urn:uuid:10000000-0000-0000-0000-000000000010
@@ -322,7 +322,7 @@ def addUniqueProperty(newProperty, ignoredParameters=None):
# FIXME: members() is a deferred, so all of vCardFromRecord is deferred.
for memberRecord in (yield record.members()):
if memberRecord:
vcard.addProperty(Property("X-ADDRESSBOOKSERVER-MEMBER", "urn:uuid:" + memberRecord.fields[FieldName.uid].encode("utf-8")))
vcard.addProperty(Property("X-ADDRESSBOOKSERVER-MEMBER", memberRecord.canonicalCalendarUserAddress().encode("utf-8")))

#===================================================================
# vCard 4.0 http://tools.ietf.org/html/rfc6350

0 comments on commit f99a959

Please sign in to comment.
You can’t perform that action at this time.