[CalendarServer-changes] [5570] CalendarServer/trunk/twistedcaldav

source_changes at macosforge.org source_changes at macosforge.org
Wed May 5 08:48:15 PDT 2010


Revision: 5570
          http://trac.macosforge.org/projects/calendarserver/changeset/5570
Author:   cdaboo at apple.com
Date:     2010-05-05 08:48:13 -0700 (Wed, 05 May 2010)
Log Message:
-----------
Add CS:common-name element in sharing.

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/customxml.py
    CalendarServer/trunk/twistedcaldav/sharing.py
    CalendarServer/trunk/twistedcaldav/test/test_sharing.py

Modified: CalendarServer/trunk/twistedcaldav/customxml.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/customxml.py	2010-05-05 15:43:40 UTC (rev 5569)
+++ CalendarServer/trunk/twistedcaldav/customxml.py	2010-05-05 15:48:13 UTC (rev 5570)
@@ -295,7 +295,7 @@
     protected = True
     hidden = True
     allowed_children = {
-        (calendarserver_namespace, "xmpp-heartbeat-uri" )  : (1, 1),
+        (calendarserver_namespace, "xmpp-heartbeat-uri" )     : (1, 1),
         (calendarserver_namespace, "xmpp-heartbeat-minutes" ) : (1, 1),
     }
 
@@ -580,6 +580,10 @@
     namespace = calendarserver_namespace
     name = "auto-schedule"
 
+##
+# Sharing
+##
+
 class ReadAccess (davxml.WebDAVEmptyElement):
     """
     Denotes read and update attendee partstat on a shared calendar.
@@ -609,10 +613,6 @@
     namespace = calendarserver_namespace
     name = "in-reply-to"
 
-##
-# Notifications
-##
-
 class SharedOwner (davxml.WebDAVEmptyElement):
     """
     Denotes a shared collection.
@@ -649,7 +649,7 @@
     name = "shared-calendar"
 
     allowed_children = {
-        davxml.HRef.qname()    : (1, 1),
+        (dav_namespace, "href")    : (1, 1),
     }
 
 class SharedAcceptEmailNotification (davxml.WebDAVTextElement):
@@ -673,8 +673,8 @@
     hidden = True
 
     allowed_children = {
-        (calendarserver_namespace, "can-be-shared" )    : (0, 1),
-        (calendarserver_namespace, "can-be-published" ) : (0, 1),
+        (calendarserver_namespace, "can-be-shared")    : (0, 1),
+        (calendarserver_namespace, "can-be-published") : (0, 1),
     }
 
 class CanBeShared (davxml.WebDAVEmptyElement):
@@ -690,8 +690,8 @@
     name = "share"
 
     allowed_children = {
-        (calendarserver_namespace, "set" )    : (0, None),
-        (calendarserver_namespace, "remove" ) : (0, None),
+        (calendarserver_namespace, "set")    : (0, None),
+        (calendarserver_namespace, "remove") : (0, None),
     }
 
 class InviteSet (davxml.WebDAVElement):
@@ -699,11 +699,12 @@
     name = "set"
 
     allowed_children = {
-        (dav_namespace,            "href" )                : (1, 1),
-        (calendarserver_namespace, "summary" )             : (0, 1),
-        (calendarserver_namespace, "read" )                : (0, 1),
-        (calendarserver_namespace, "read-write" )          : (0, 1),
-        (calendarserver_namespace, "read-write-schedule" ) : (0, 1),
+        (dav_namespace, "href")                           : (1, 1),
+        (calendarserver_namespace, "common-name")         : (0, 1),
+        (calendarserver_namespace, "summary")             : (0, 1),
+        (calendarserver_namespace, "read")                : (0, 1),
+        (calendarserver_namespace, "read-write")          : (0, 1),
+        (calendarserver_namespace, "read-write-schedule") : (0, 1),
     }
 
 class InviteRemove (davxml.WebDAVElement):
@@ -711,10 +712,10 @@
     name = "remove"
 
     allowed_children = {
-        (dav_namespace,            "href" )                : (1, 1),
-        (calendarserver_namespace, "read" )                : (0, 1),
-        (calendarserver_namespace, "read-write" )          : (0, 1),
-        (calendarserver_namespace, "read-write-schedule" ) : (0, 1),
+        (dav_namespace, "href")                           : (1, 1),
+        (calendarserver_namespace, "read")                : (0, 1),
+        (calendarserver_namespace, "read-write")          : (0, 1),
+        (calendarserver_namespace, "read-write-schedule") : (0, 1),
     }
 
 class InviteUser (davxml.WebDAVElement):
@@ -722,14 +723,16 @@
     name = "user"
 
     allowed_children = {
-        (calendarserver_namespace, "href" )              : (1, 1),
-        (calendarserver_namespace, "invite-noresponse" ) : (0, 1),
-        (calendarserver_namespace, "invite-deleted" )    : (0, 1),
-        (calendarserver_namespace, "invite-accepted" )   : (0, 1),
-        (calendarserver_namespace, "invite-declined" )   : (0, 1),
-        (calendarserver_namespace, "invite-invalid" )    : (0, 1),
-        (calendarserver_namespace, "access" )            : (1, 1),
-        (calendarserver_namespace, "summary" )           : (0, 1),
+        (calendarserver_namespace, "uid")               : (1, 1),
+        (dav_namespace, "href")                         : (1, 1),
+        (calendarserver_namespace, "common-name")       : (0, 1),
+        (calendarserver_namespace, "invite-noresponse") : (0, 1),
+        (calendarserver_namespace, "invite-deleted")    : (0, 1),
+        (calendarserver_namespace, "invite-accepted")   : (0, 1),
+        (calendarserver_namespace, "invite-declined")   : (0, 1),
+        (calendarserver_namespace, "invite-invalid")    : (0, 1),
+        (calendarserver_namespace, "access")            : (1, 1),
+        (calendarserver_namespace, "summary")           : (0, 1),
     }
 
 class InviteAccess (davxml.WebDAVElement):
@@ -737,9 +740,9 @@
     name = "access"
 
     allowed_children = {
-        (calendarserver_namespace, "read" )               : (0, 1),
-        (calendarserver_namespace, "read-write" )         : (0, 1),
-        (calendarserver_namespace, "read-write-schedule" ): (0, 1),
+        (calendarserver_namespace, "read")                : (0, 1),
+        (calendarserver_namespace, "read-write")          : (0, 1),
+        (calendarserver_namespace, "read-write-schedule") : (0, 1),
     }
 
 class Invite (davxml.WebDAVElement):
@@ -747,7 +750,7 @@
     name = "invite"
 
     allowed_children = {
-        (calendarserver_namespace, "user" )   : (0, None),
+        (calendarserver_namespace, "user") : (0, None),
     }
 
 class InviteSummary (davxml.WebDAVTextElement):
@@ -781,7 +784,9 @@
     namespace = calendarserver_namespace
     name = "hosturl"
 
-    allowed_children = { (dav_namespace, "href"): (0, None) }
+    allowed_children = {
+        (dav_namespace, "href") : (0, None)
+    }
 
 class Organizer (davxml.WebDAVElement):
     """
@@ -790,23 +795,33 @@
     namespace = calendarserver_namespace
     name = "organizer"
 
-    allowed_children = { (dav_namespace, "href"): (0, None) }
+    allowed_children = {
+        (dav_namespace, "href") : (0, None),
+        (calendarserver_namespace, "common-name")  : (0, 1)
+    }
 
+class CommonName (davxml.WebDAVTextElement):
+    """
+    Common name for Sharer or Sharee
+    """
+    namespace = calendarserver_namespace
+    name = "common-name"
+
 class InviteNotification (davxml.WebDAVElement):
     namespace = calendarserver_namespace
     name = "invite-notification"
 
     allowed_children = {
-        UID.qname()                      : (0, 1),
-        (dav_namespace, "href")          : (0, 1),
-        InviteStatusNoResponse.qname()   : (0, 1),
-        InviteStatusDeleted.qname()      : (0, 1),
-        InviteStatusAccepted.qname()     : (0, 1),
-        InviteStatusDeclined.qname()     : (0, 1),
-        InviteAccess.qname()             : (0, 1),
-        HostURL.qname()                  : (0, 1),
-        Organizer.qname()                : (0, 1),
-        InviteSummary.qname()            : (0, 1),
+        (calendarserver_namespace, "uid")               : (0, 1),
+        (dav_namespace, "href")                         : (0, 1),
+        (calendarserver_namespace, "invite-noresponse") : (0, 1),
+        (calendarserver_namespace, "invite-deleted")    : (0, 1),
+        (calendarserver_namespace, "invite-accepted")   : (0, 1),
+        (calendarserver_namespace, "invite-declined")   : (0, 1),
+        (calendarserver_namespace, "access")            : (0, 1),
+        (calendarserver_namespace, "hosturl")           : (0, 1),
+        (calendarserver_namespace, "organizer")         : (0, 1),
+        (calendarserver_namespace, "summary")           : (0, 1),
     }
 
     allowed_attributes = {
@@ -818,14 +833,26 @@
     name = "invite-reply"
 
     allowed_children = {
-        (dav_namespace, "href")          : (0, 1),
-        InviteStatusAccepted.qname()     : (0, 1),
-        InviteStatusDeclined.qname()     : (0, 1),
-        HostURL.qname()                  : (0, 1),
-        InReplyTo.qname()                : (0, 1),
-        InviteSummary.qname()            : (0, 1),
+        (dav_namespace, "href")                       : (0, 1),
+        (calendarserver_namespace, "invite-accepted") : (0, 1),
+        (calendarserver_namespace, "invite-declined") : (0, 1),
+        (calendarserver_namespace, "hosturl")         : (0, 1),
+        (calendarserver_namespace, "in-reply-to")     : (0, 1),
+        (calendarserver_namespace, "summary")         : (0, 1),
     }
 
+class ResourceUpdateNotification (davxml.WebDAVElement):
+    namespace = calendarserver_namespace
+    name = "resource-update-notification"
+
+    allowed_children = {
+        (dav_namespace, "href")                                     : (0, 1),
+        (calendarserver_namespace, "uid")                           : (0, 1),
+        (calendarserver_namespace, "resource-added-notification")   : (0, 1),
+        (calendarserver_namespace, "resource-updated-notification") : (0, 1),
+        (calendarserver_namespace, "resource-deleted-notification") : (0, 1),
+    }
+
 class ResourceUpdateAdded(davxml.WebDAVEmptyElement):
     namespace = calendarserver_namespace
     name = "resource-added-notification"
@@ -834,34 +861,26 @@
     namespace = calendarserver_namespace
     name = "resource-updated-notification"
 
-class ResourceDeletedUpdated(davxml.WebDAVEmptyElement):
+class ResourceUpdateDeleted(davxml.WebDAVEmptyElement):
     namespace = calendarserver_namespace
     name = "resource-deleted-notification"
 
-class ResourceUpdateNotification (davxml.WebDAVElement):
-    namespace = calendarserver_namespace
-    name = "resource-update-notification"
-
-    allowed_children = {
-        (dav_namespace, "href")          : (0, 1),
-        UID.qname()                      : (0, 1),
-        ResourceUpdateAdded.qname()      : (0, 1),
-        ResourceUpdateUpdated.qname()    : (0, 1),
-        ResourceDeletedUpdated.qname()   : (0, 1),
-    }
-
 class SharedCalendarUpdateNotification (davxml.WebDAVElement):
     namespace = calendarserver_namespace
     name = "shared-update-notification"
 
     allowed_children = {
-        HostURL.qname()                  : (0, 1), # The shared calendar url
-        (dav_namespace, "href")          : (0, 1), # Email userid that was invited
-        InviteStatusDeleted.qname()      : (0, 1), # What the user did...
-        InviteStatusAccepted.qname()     : (0, 1),
-        InviteStatusDeclined.qname()     : (0, 1),
+        (calendarserver_namespace, "hosturl")           : (0, 1), # The shared calendar url
+        (dav_namespace, "href")                         : (0, 1), # Email userid that was invited
+        (calendarserver_namespace, "invite-deleted")    : (0, 1), # What the user did...
+        (calendarserver_namespace, "invite-accepted")   : (0, 1),
+        (calendarserver_namespace, "invite-declined")   : (0, 1),
     }
 
+##
+# Notifications
+##
+
 class Notification (davxml.WebDAVElement):
     """
     Denotes a notification collection, or a notification message.
@@ -870,11 +889,11 @@
     name = "notification"
 
     allowed_children = {
-        DTStamp.qname()                            : (0, None),
-        InviteNotification.qname()                 : (0, None),
-        InviteReply.qname()                        : (0, None),
-        ResourceUpdateNotification.qname()         : (0, None),
-        SharedCalendarUpdateNotification.qname()   : (0, None),
+        (calendarserver_namespace, "dtstamp")                       : (0, None),
+        (calendarserver_namespace, "invite-notification")           : (0, None),
+        (calendarserver_namespace, "invite-reply")                  : (0, None),
+        (calendarserver_namespace, "resource-update-notification")  : (0, None),
+        (calendarserver_namespace, "shared-update-notification")    : (0, None),
     }
 
 class NotificationURL (davxml.WebDAVElement):
@@ -886,7 +905,9 @@
     hidden = True
     protected = True
 
-    allowed_children = { (davxml.dav_namespace, "href"): (0, 1) }
+    allowed_children = {
+        (dav_namespace, "href") : (0, 1)
+    }
 
 class NotificationType (davxml.WebDAVElement):
     """
@@ -898,8 +919,8 @@
     protected = True
 
     allowed_children = {
-        InviteNotification.qname()                 : (0, None),
-        InviteReply.qname()                        : (0, None),
+        (calendarserver_namespace, "invite-notification")   : (0, None),
+        (calendarserver_namespace, "invite-reply")          : (0, None),
     }
 
 ##

Modified: CalendarServer/trunk/twistedcaldav/sharing.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/sharing.py	2010-05-05 15:43:40 UTC (rev 5569)
+++ CalendarServer/trunk/twistedcaldav/sharing.py	2010-05-05 15:48:13 UTC (rev 5570)
@@ -269,6 +269,31 @@
         else:
             return None
 
+    def validUserIDWithCommonNameForShare(self, userid, cn):
+        """
+        Validate user ID and find the common name.
+
+        @param userid: the userid to test
+        @type userid: C{str}
+        @param cn: default common name to use if principal has none
+        @type cn: C{str}
+        
+        @return: C{tuple} of C{str} of normalized userid or C{None} if
+            userid is not allowed, and appropriate common name.
+        """
+        
+        # First try to resolve as a principal
+        principal = self.principalForCalendarUserAddress(userid)
+        if principal:
+            return principal.principalURL(), principal.displayName()
+        
+        # TODO: we do not support external users right now so this is being hard-coded
+        # off in spite of the config option.
+        #elif config.Sharing.AllowExternalUsers:
+        #    return userid, cn
+        else:
+            return None, None
+
     def validateInvites(self):
         """
         Make sure each userid in an invite is valid - if not re-write status.
@@ -287,26 +312,24 @@
         """ Possibly send a push and or email notification on a change to a resource in a shared collection """
         return succeed(True)
 
-    def inviteUserToShare(self, userid, ace, summary, request, commonName="", shareName="", add=True):
+    def inviteUserToShare(self, userid, cn, ace, summary, request):
         """ Send out in invite first, and then add this user to the share list
             @param userid: 
             @param ace: Must be one of customxml.ReadWriteAccess or customxml.ReadAccess
         """
         
         # Check for valid userid first
-        userid = self.validUserIDForShare(userid)
+        userid, cn = self.validUserIDWithCommonNameForShare(userid, cn)
         if userid is None:
             return succeed(False)
 
         # TODO: Check if this collection is shared, and error out if it isn't
         if type(userid) is not list:
             userid = [userid]
-        if type(commonName) is not list:
-            commonName = [commonName]
-        if type(shareName) is not list:
-            shareName = [shareName]
+        if type(cn) is not list:
+            cn = [cn]
             
-        dl = [self.inviteSingleUserToShare(user, ace, summary, request, cn=cn, sn=sn) for user, cn, sn in zip(userid, commonName, shareName)]
+        dl = [self.inviteSingleUserToShare(user, cn, ace, summary, request) for user, cn in zip(userid, cn)]
         return DeferredList(dl).addCallback(lambda _:True)
 
     def uninviteUserToShare(self, userid, ace, request):
@@ -321,32 +344,31 @@
             userid = [userid]
         return DeferredList([self.uninviteSingleUserFromShare(user, ace, request) for user in userid]).addCallback(lambda _:True)
 
-    def inviteUserUpdateToShare(self, userid, aceOLD, aceNEW, summary, request, commonName="", shareName=""):
+    def inviteUserUpdateToShare(self, userid, cn, aceOLD, aceNEW, summary, request):
 
         # Check for valid userid first
-        userid = self.validUserIDForShare(userid)
+        userid, cn = self.validUserIDWithCommonNameForShare(userid, cn)
         if userid is None:
             return succeed(False)
 
         if type(userid) is not list:
             userid = [userid]
-        if type(commonName) is not list:
-            commonName = [commonName]
-        if type(shareName) is not list:
-            shareName = [shareName]
-        dl = [self.inviteSingleUserUpdateToShare(user, aceOLD, aceNEW, summary, request, commonName=cn, shareName=sn) for user, cn, sn in zip(userid, commonName, shareName)]
+        if type(cn) is not list:
+            cn = [cn]
+        dl = [self.inviteSingleUserUpdateToShare(user, cn, aceOLD, aceNEW, summary, request) for user, cn in zip(userid, cn)]
         return DeferredList(dl).addCallback(lambda _:True)
 
     @inlineCallbacks
-    def inviteSingleUserToShare(self, userid, ace, summary, request, cn="", sn=""):
+    def inviteSingleUserToShare(self, userid, cn, ace, summary, request):
         
         # Look for existing invite and update its fields or create new one
         record = self.invitesDB().recordForUserID(userid)
         if record:
+            record.name = cn
             record.access = inviteAccessMapFromXML[type(ace)]
             record.summary = summary
         else:
-            record = Invite(str(uuid4()), userid, inviteAccessMapFromXML[type(ace)], "NEEDS-ACTION", summary)
+            record = Invite(str(uuid4()), userid, cn, inviteAccessMapFromXML[type(ace)], "NEEDS-ACTION", summary)
         
         # Send invite
         yield self.sendInvite(record, request)
@@ -368,34 +390,34 @@
         
         # Remove any shared calendar
         sharee = self.principalForCalendarUserAddress(record.userid)
-        if sharee is None:
-            raise ValueError("sharee is None but userid was valid before")
-        shareeHome = sharee.calendarHome()
-        yield shareeHome.removeShareByUID(request, record.inviteuid)
-
-        # If current user state is accepted then we send an invite with the new state, otherwise
-        # we cancel any existing invites for the user
-        if record and record.state != "ACCEPTED":
-            yield self.removeInvite(record, request)
-        elif record:
-            record.state = "DELETED"
-            yield self.sendInvite(record, request)
-
+        if sharee:
+            shareeHome = sharee.calendarHome()
+            yield shareeHome.removeShareByUID(request, record.inviteuid)
+    
+            # If current user state is accepted then we send an invite with the new state, otherwise
+            # we cancel any existing invites for the user
+            if record and record.state != "ACCEPTED":
+                yield self.removeInvite(record, request)
+            elif record:
+                record.state = "DELETED"
+                yield self.sendInvite(record, request)
+    
         # Remove from database
         self.invitesDB().removeRecordForUserID(userid)
         
         returnValue(True)            
 
-    def inviteSingleUserUpdateToShare(self, userid, acesOLD, aceNEW, summary, request, commonName="", shareName=""):
+    def inviteSingleUserUpdateToShare(self, userid, commonName, acesOLD, aceNEW, summary, request):
         
         # Just update existing
-        return self.inviteSingleUserToShare(userid, aceNEW, summary, request, commonName, shareName) 
+        return self.inviteSingleUserToShare(userid, commonName, aceNEW, summary, request) 
 
     @inlineCallbacks
     def sendInvite(self, record, request):
         
-        owner = (yield self.ownerPrincipal(request))
-        owner = owner.principalURL()
+        ownerPrincipal = (yield self.ownerPrincipal(request))
+        owner = ownerPrincipal.principalURL()
+        ownerCN = ownerPrincipal.displayName()
         hosturl = (yield self.canonicalURL(request))
 
         # Locate notifications collection for user
@@ -425,6 +447,7 @@
                 ),
                 customxml.Organizer(
                     davxml.HRef.fromString(owner),
+                    customxml.CommonName.fromString(ownerCN),
                 ),
                 customxml.InviteSummary.fromString(record.summary),
                 **typeAttr
@@ -455,12 +478,16 @@
         def _handleInvite(invitedoc):
             def _handleInviteSet(inviteset):
                 userid = None
+                cn = None
                 access = None
                 summary = None
                 for item in inviteset.children:
                     if isinstance(item, davxml.HRef):
                         userid = str(item)
                         continue
+                    if isinstance(item, customxml.CommonName):
+                        cn = str(item)
+                        continue
                     if isinstance(item, customxml.InviteSummary):
                         summary = str(item)
                         continue
@@ -468,26 +495,20 @@
                         access = item
                         continue
                 if userid and access and summary:
-                    return (userid, access, summary)
+                    return (userid, cn, access, summary)
                 else:
+                    error_text = []
                     if userid is None:
-                        raise HTTPError(ErrorResponse(
-                            responsecode.FORBIDDEN,
-                            (customxml.calendarserver_namespace, "valid-request"),
-                            "missing href: %s" % (inviteset,),
-                        ))
+                        error_text.append("missing href")
                     if access is None:
-                        raise HTTPError(ErrorResponse(
-                            responsecode.FORBIDDEN,
-                            (customxml.calendarserver_namespace, "valid-request"),
-                            "missing access: %s" % (inviteset,),
-                        ))
+                        error_text.append("missing access")
                     if summary is None:
-                        raise HTTPError(ErrorResponse(
-                            responsecode.FORBIDDEN,
-                            (customxml.calendarserver_namespace, "valid-request"),
-                            "missing summary: %s" % (inviteset,),
-                        ))
+                        error_text.append("missing summary")
+                    raise HTTPError(ErrorResponse(
+                        responsecode.FORBIDDEN,
+                        (customxml.calendarserver_namespace, "valid-request"),
+                        "%s: %s" % (", ".join(error_text), inviteset,),
+                    ))
 
             def _handleInviteRemove(inviteremove):
                 userid = None
@@ -524,8 +545,8 @@
                 setDict, removeDict, updateinviteDict = {}, {}, {}
                 for item in invitedoc.children:
                     if isinstance(item, customxml.InviteSet):
-                        userid, access, summary = _handleInviteSet(item)
-                        setDict[userid] = (access, summary)
+                        userid, cn, access, summary = _handleInviteSet(item)
+                        setDict[userid] = (cn, access, summary)
                     elif isinstance(item, customxml.InviteRemove):
                         userid, access = _handleInviteRemove(item)
                         removeDict[userid] = access
@@ -536,18 +557,18 @@
                 sameUseridInRemoveAndSet = [u for u in removeDict.keys() if u in setDict]
                 for u in sameUseridInRemoveAndSet:
                     removeACL = removeDict[u]
-                    newACL, summary = setDict[u]
-                    updateinviteDict[u] = (removeACL, newACL, summary)
+                    cn, newACL, summary = setDict[u]
+                    updateinviteDict[u] = (cn, removeACL, newACL, summary)
                     del removeDict[u]
                     del setDict[u]
                 for userid, access in removeDict.iteritems():
                     result = (yield self.uninviteUserToShare(userid, access, request))
                     (okusers if result else badusers).add(userid)
-                for userid, (access, summary) in setDict.iteritems():
-                    result = (yield self.inviteUserToShare(userid, access, summary, request))
+                for userid, (cn, access, summary) in setDict.iteritems():
+                    result = (yield self.inviteUserToShare(userid, cn, access, summary, request))
                     (okusers if result else badusers).add(userid)
-                for userid, (removeACL, newACL, summary) in updateinviteDict.iteritems():
-                    result = (yield self.inviteUserUpdateToShare(userid, removeACL, newACL, summary, request))
+                for userid, (cn, removeACL, newACL, summary) in updateinviteDict.iteritems():
+                    result = (yield self.inviteUserUpdateToShare(userid, cn, removeACL, newACL, summary, request))
                     (okusers if result else badusers).add(userid)
 
                 # Do a final validation of the entire set of invites
@@ -642,9 +663,10 @@
 
 class Invite(object):
     
-    def __init__(self, inviteuid, userid, access, state, summary):
+    def __init__(self, inviteuid, userid, common_name, access, state, summary):
         self.inviteuid = inviteuid
         self.userid = userid
+        self.name = common_name
         self.access = access
         self.state = state
         self.summary = summary
@@ -654,6 +676,7 @@
         return customxml.InviteUser(
             customxml.UID.fromString(self.inviteuid),
             davxml.HRef.fromString(self.userid),
+            customxml.CommonName.fromString(self.name),
             customxml.InviteAccess(inviteAccessMapToXML[self.access]()),
             inviteStatusMapToXML[self.state](),
         )
@@ -696,9 +719,9 @@
     
     def addOrUpdateRecord(self, record):
 
-        self._db_execute("""insert or replace into INVITE (INVITEUID, USERID, ACCESS, STATE, SUMMARY)
-            values (:1, :2, :3, :4, :5)
-            """, record.inviteuid, record.userid, record.access, record.state, record.summary,
+        self._db_execute("""insert or replace into INVITE (INVITEUID, USERID, NAME, ACCESS, STATE, SUMMARY)
+            values (:1, :2, :3, :4, :5, :6)
+            """, record.inviteuid, record.userid, record.name, record.access, record.state, record.summary,
         )
     
     def removeRecordForUserID(self, userid):
@@ -734,7 +757,8 @@
         #
         # INVITE table is the primary table
         #   INVITEUID: UID for this invite
-        #   NAME: identifier of invitee
+        #   USERID: identifier of invitee
+        #   NAME: common name of invitee
         #   ACCESS: Access mode for share
         #   STATE: Invite response status
         #   SUMMARY: Invite summary
@@ -744,6 +768,7 @@
             create table INVITE (
                 INVITEUID      text unique,
                 USERID         text unique,
+                NAME           text,
                 ACCESS         text,
                 STATE          text,
                 SUMMARY        text

Modified: CalendarServer/trunk/twistedcaldav/test/test_sharing.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_sharing.py	2010-05-05 15:43:40 UTC (rev 5569)
+++ CalendarServer/trunk/twistedcaldav/test/test_sharing.py	2010-05-05 15:48:13 UTC (rev 5570)
@@ -27,10 +27,29 @@
 from twistedcaldav.test.util import InMemoryPropertyStore
 from twistedcaldav.test.util import TestCase
 import os
-from twext.web2.http import HTTPError
 
 
 class SharingTests(TestCase):
+
+    class FakePrincipal(object):
+        
+        def __init__(self, cuaddr):
+            self.path = "/principals/__uids__/%s" % (cuaddr[7:].split('@')[0],)
+            self.homepath = "/calendars/__uids__/%s" % (cuaddr[7:].split('@')[0],)
+            self.displayname = cuaddr[7:].split('@')[0].upper()
+
+        def calendarHome(self):
+            class FakeHome(object):
+                def removeShareByUID(self, request, uid):pass
+            return FakeHome()
+        
+        def principalURL(self):
+            return self.path
+        
+        def displayName(self):
+            return self.displayname
+            
+
     def setUp(self):
         super(SharingTests, self).setUp()
         config.Sharing.Enabled = True
@@ -44,33 +63,23 @@
         self.site.resource.putChild("calendar", self.resource)
         
         self.resource.validUserIDForShare = self._fakeValidUserID
+        self.resource.validUserIDWithCommonNameForShare = self._fakeValidUserID
         self.resource.sendInvite = lambda record, request:succeed(True)
         self.resource.removeInvite = lambda record, request:succeed(True)
         
-        class FakePrincipal(object):
-            
-            def __init__(self, cuaddr):
-                self.path = "/principals/__uids__/%s" % (cuaddr[7:].split('@')[0],)
-                self.homepath = "/calendars/__uids__/%s" % (cuaddr[7:].split('@')[0],)
-
-            def calendarHome(self):
-                class FakeHome(object):
-                    def removeShareByUID(self, request, uid):pass
-                return FakeHome()
-            
-        self.resource.principalForCalendarUserAddress = lambda cuaddr: FakePrincipal(cuaddr)
+        self.resource.principalForCalendarUserAddress = lambda cuaddr: SharingTests.FakePrincipal(cuaddr)
         
-    def _fakeValidUserID(self, userid):
+    def _fakeValidUserID(self, userid, *args):
+        if userid.startswith("/principals/"):
+            return userid
         if userid.endswith("@example.com"):
-            return userid
+            principal = SharingTests.FakePrincipal(userid)
+            return principal.path if len(args) == 0 else (principal.path, principal.displayname,)
         else:
-            return None
+            return None if len(args) == 0 else (None, None,)
 
-    def _fakeInvalidUserID(self, userid):
-        if userid.endswith("@example.net"):
-            return userid
-        else:
-            return None
+    def _fakeInvalidUserID(self, userid, *args):
+        return None if len(args) == 0 else (None, None,)
 
     @inlineCallbacks
     def _doPOST(self, body, resultcode = responsecode.OK):
@@ -174,7 +183,8 @@
         self.assertEquals(self._clearUIDElementValue(propInvite), customxml.Invite(
             customxml.InviteUser(
                 customxml.UID.fromString(""),
-                davxml.HRef.fromString("mailto:user02 at example.com"),
+                davxml.HRef.fromString("/principals/__uids__/user02"),
+                customxml.CommonName.fromString("USER02"),
                 customxml.InviteAccess(customxml.ReadWriteAccess()),
                 customxml.InviteStatusNoResponse(),
             )
@@ -203,7 +213,8 @@
         self.assertEquals(self._clearUIDElementValue(propInvite), customxml.Invite(
             customxml.InviteUser(
                 customxml.UID.fromString(""),
-                davxml.HRef.fromString("mailto:user02 at example.com"),
+                davxml.HRef.fromString("/principals/__uids__/user02"),
+                customxml.CommonName.fromString("USER02"),
                 customxml.InviteAccess(customxml.ReadWriteAccess()),
                 customxml.InviteStatusNoResponse(),
             )
@@ -243,7 +254,8 @@
         self.assertEquals(self._clearUIDElementValue(propInvite), customxml.Invite(
             customxml.InviteUser(
                 customxml.UID.fromString(""),
-                davxml.HRef.fromString("mailto:user02 at example.com"),
+                davxml.HRef.fromString("/principals/__uids__/user02"),
+                customxml.CommonName.fromString("USER02"),
                 customxml.InviteAccess(customxml.ReadAccess()),
                 customxml.InviteStatusNoResponse(),
             )
@@ -308,19 +320,22 @@
         self.assertEquals(self._clearUIDElementValue(propInvite), customxml.Invite(
             customxml.InviteUser(
                 customxml.UID.fromString(""),
-                davxml.HRef.fromString("mailto:user02 at example.com"),
+                davxml.HRef.fromString("/principals/__uids__/user02"),
+                customxml.CommonName.fromString("USER02"),
                 customxml.InviteAccess(customxml.ReadWriteAccess()),
                 customxml.InviteStatusNoResponse(),
             ),
             customxml.InviteUser(
                 customxml.UID.fromString(""),
-                davxml.HRef.fromString("mailto:user03 at example.com"),
+                davxml.HRef.fromString("/principals/__uids__/user03"),
+                customxml.CommonName.fromString("USER03"),
                 customxml.InviteAccess(customxml.ReadWriteAccess()),
                 customxml.InviteStatusNoResponse(),
             ),
             customxml.InviteUser(
                 customxml.UID.fromString(""),
-                davxml.HRef.fromString("mailto:user04 at example.com"),
+                davxml.HRef.fromString("/principals/__uids__/user04"),
+                customxml.CommonName.fromString("USER04"),
                 customxml.InviteAccess(customxml.ReadWriteAccess()),
                 customxml.InviteStatusNoResponse(),
             ),
@@ -362,13 +377,15 @@
         self.assertEquals(self._clearUIDElementValue(propInvite), customxml.Invite(
             customxml.InviteUser(
                 customxml.UID.fromString(""),
-                davxml.HRef.fromString("mailto:user02 at example.com"),
+                davxml.HRef.fromString("/principals/__uids__/user02"),
+                customxml.CommonName.fromString("USER02"),
                 customxml.InviteAccess(customxml.ReadWriteAccess()),
                 customxml.InviteStatusNoResponse(),
             ),
             customxml.InviteUser(
                 customxml.UID.fromString(""),
-                davxml.HRef.fromString("mailto:user04 at example.com"),
+                davxml.HRef.fromString("/principals/__uids__/user04"),
+                customxml.CommonName.fromString("USER04"),
                 customxml.InviteAccess(customxml.ReadWriteAccess()),
                 customxml.InviteStatusNoResponse(),
             ),
@@ -410,13 +427,15 @@
         self.assertEquals(self._clearUIDElementValue(propInvite), customxml.Invite(
             customxml.InviteUser(
                 customxml.UID.fromString(""),
-                davxml.HRef.fromString("mailto:user02 at example.com"),
+                davxml.HRef.fromString("/principals/__uids__/user02"),
+                customxml.CommonName.fromString("USER02"),
                 customxml.InviteAccess(customxml.ReadWriteAccess()),
                 customxml.InviteStatusNoResponse(),
             ),
             customxml.InviteUser(
                 customxml.UID.fromString(""),
-                davxml.HRef.fromString("mailto:user03 at example.com"),
+                davxml.HRef.fromString("/principals/__uids__/user03"),
+                customxml.CommonName.fromString("USER03"),
                 customxml.InviteAccess(customxml.ReadAccess()),
                 customxml.InviteStatusNoResponse(),
             ),
@@ -472,19 +491,23 @@
         self.assertEquals(self._clearUIDElementValue(propInvite), customxml.Invite(
             customxml.InviteUser(
                 customxml.UID.fromString(""),
-                davxml.HRef.fromString("mailto:user01 at example.com"),
+                davxml.HRef.fromString("/principals/__uids__/user01"),
+                customxml.CommonName.fromString("USER01"),
                 customxml.InviteAccess(customxml.ReadWriteAccess()),
                 customxml.InviteStatusNoResponse(),
             )
         ))
 
         self.resource.validUserIDForShare = self._fakeInvalidUserID
+        self.resource.validUserIDWithCommonNameForShare = self._fakeInvalidUserID
+        self.resource.principalForCalendarUserAddress = lambda cuaddr: None
 
         propInvite = (yield self.resource.readProperty(customxml.Invite, None))
         self.assertEquals(self._clearUIDElementValue(propInvite), customxml.Invite(
             customxml.InviteUser(
                 customxml.UID.fromString(""),
-                davxml.HRef.fromString("mailto:user01 at example.com"),
+                davxml.HRef.fromString("/principals/__uids__/user01"),
+                customxml.CommonName.fromString("USER01"),
                 customxml.InviteAccess(customxml.ReadWriteAccess()),
                 customxml.InviteStatusInvalid(),
             )
@@ -493,7 +516,7 @@
         yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
 <CS:share xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/">
     <CS:remove>
-        <D:href>mailto:user01 at example.com</D:href>
+        <D:href>/principals/__uids__/user01</D:href>
     </CS:remove>
 </CS:share>
 """)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20100505/c678819f/attachment-0001.html>


More information about the calendarserver-changes mailing list