[CalendarServer-changes] [10564] CalendarServer/branches/users/glyph/unshare-when-access-revoked

source_changes at macosforge.org source_changes at macosforge.org
Mon Jan 28 19:28:42 PST 2013


Revision: 10564
          http://trac.calendarserver.org//changeset/10564
Author:   glyph at apple.com
Date:     2013-01-28 19:28:42 -0800 (Mon, 28 Jan 2013)
Log Message:
-----------
As I work my way through various bits of sharing logic, add lots of docstrings explaining it.

Modified Paths:
--------------
    CalendarServer/branches/users/glyph/unshare-when-access-revoked/twistedcaldav/sharing.py

Property Changed:
----------------
    CalendarServer/branches/users/glyph/unshare-when-access-revoked/

Modified: CalendarServer/branches/users/glyph/unshare-when-access-revoked/twistedcaldav/sharing.py
===================================================================
--- CalendarServer/branches/users/glyph/unshare-when-access-revoked/twistedcaldav/sharing.py	2013-01-29 03:28:40 UTC (rev 10563)
+++ CalendarServer/branches/users/glyph/unshare-when-access-revoked/twistedcaldav/sharing.py	2013-01-29 03:28:42 UTC (rev 10564)
@@ -57,7 +57,15 @@
 
 
 class SharedCollectionMixin(object):
+    """
+    A mix-in for calendar/addressbook resources that implements sharing-related
+    functionality.
 
+    @ivar _share: If this L{SharedCollectionMixin} is the sharee's version of a
+        resource, this refers to the L{Share} that describes it.
+    @type _share: L{Share} or L{NoneType}
+    """
+
     @inlineCallbacks
     def inviteProperty(self, request):
         """
@@ -110,8 +118,10 @@
 
 
     def upgradeToShare(self):
-        """ Upgrade this collection to a shared state """
-
+        """
+        Set the resource-type property on this resource to indicate that this
+        is the owner's version of a resource which has been shared.
+        """
         # Change resourcetype
         rtype = self.resourceType()
         rtype = element.ResourceType(*(rtype.children + (customxml.SharedOwner(),)))
@@ -160,11 +170,16 @@
     @inlineCallbacks
     def directShare(self, request):
         """
-        Directly bind an accessible calendar/address book collection into the current
-        principal's calendar/addressbook home.
+        Directly bind an accessible calendar/address book collection into the
+        current principal's calendar/addressbook home.
 
         @param request: the request triggering this action
         @type request: L{IRequest}
+
+        @return: the (asynchronous) HTTP result to respond to the direct-share
+            request.
+        @rtype: L{Deferred} firing L{twext.web2.http.Response}, failing with
+            L{HTTPError}
         """
 
         # Need to have at least DAV:read to do this
@@ -228,17 +243,25 @@
 
     @inlineCallbacks
     def isShared(self, request):
-        """ Return True if this is an owner shared calendar collection """
+        """
+        Return True if this is an owner shared calendar collection.
+        """
         returnValue((yield self.isSpecialCollection(customxml.SharedOwner)))
 
 
     def setShare(self, share):
-        self._isShareeCollection = True #  _isShareeCollection attr is used by self tests
+        """
+        Set the L{Share} associated with this L{SharedCollectionMixin}.  (This
+        is only invoked on the sharee's resource, not the owner's.)
+        """
+        self._isShareeCollection = True
         self._share = share
 
 
     def isShareeCollection(self):
-        """ Return True if this is a sharee view of a shared calendar collection """
+        """
+        Return True if this is a sharee view of a shared calendar collection.
+        """
         return hasattr(self, "_isShareeCollection")
 
 
@@ -291,12 +314,16 @@
     @inlineCallbacks
     def shareeAccessControlList(self, request, *args, **kwargs):
         """
-        Return WebDAV ACLs appropriate for the current user accessing the shared collection. For
-        an "invite" share we take the privilege granted to the sharee in the invite and map that
-        to WebDAV ACLs. For a "direct" share, if it is a wiki collection we map the wiki privileges
-        into WebDAV ACLs, otherwise we use whatever privileges exist on the underlying shared
-        collection.
+        Return WebDAV ACLs appropriate for the current user accessing the
+        shared collection.  For an "invite" share we take the privilege granted
+        to the sharee in the invite and map that to WebDAV ACLs.  For a
+        "direct" share, if it is a wiki collection we map the wiki privileges
+        into WebDAV ACLs, otherwise we use whatever privileges exist on the
+        underlying shared collection.
 
+        @param request: the request used to locate the owner resource.
+        @type request: L{twext.web2.iweb.IRequest}
+
         @return: the appropriate WebDAV ACL for the sharee
         @rtype: L{davxml.ACL}
         """
@@ -991,6 +1018,11 @@
 
     @inlineCallbacks
     def provisionShare(self, child, request=None):
+        """
+        If the given child resource (a L{SharedCollectionMixin}) of this
+        L{SharedHomeMixin} is a I{sharee}'s view of a shared calendar object,
+        associate it with a L{Share}.
+        """
         share = yield self._shareForHomeChild(child._newStoreObject, request)
         if share:
             child.setShare(share)
@@ -998,6 +1030,19 @@
 
     @inlineCallbacks
     def _shareForHomeChild(self, child, request=None):
+        """
+        Determine the L{Share} associated with the given child.
+
+        @param child: A calendar or addressbook data store object, a child of
+            the resource represented by this L{SharedHomeMixin} instance, which
+            may be shared.
+        @type child: L{txdav.caldav.icalendarstore.ICalendar} or
+            L{txdav.carddav.iaddressbookstore.IAddressBook}
+
+        @return: a L{Share} if C{child} is not the owner's view of the share,
+            or C{None}.
+        @rtype: L{Share} or L{NoneType}
+        """
         # Try to find a matching share
         if not child or child.owned():
             returnValue(None)
@@ -1008,7 +1053,8 @@
         sharer = self.principalForUID(sharerHomeChild.viewerHome().uid())
 
         if not request:
-            # FIXEME:  Fake up a request that can be used to get the sharer home resource
+            # FIXME: Fake up a request that can be used to get the sharer home
+            # resource
             class _FakeRequest(object):
                 pass
             fakeRequest = _FakeRequest()
@@ -1021,7 +1067,8 @@
             sharerHomeCollection = yield sharer.addressBookHome(request)
 
         url = joinURL(sharerHomeCollection.url(), sharerHomeChild.name())
-        share = Share(shareeHomeChild=child, sharerHomeChild=sharerHomeChild, url=url)
+        share = Share(shareeHomeChild=child, sharerHomeChild=sharerHomeChild,
+                      url=url)
 
         returnValue(share)
 
@@ -1053,20 +1100,25 @@
         oldShare = yield self._shareForUID(inviteUID, request)
 
         # Send the invite reply then add the link
-        yield self._changeShare(request, "ACCEPTED", hostUrl, inviteUID, displayname)
+        yield self._changeShare(request, "ACCEPTED", hostUrl, inviteUID,
+                                displayname)
         if oldShare:
             share = oldShare
         else:
             sharedCollection = yield request.locateResource(hostUrl)
             shareeHomeChild = yield self._newStoreHome.childWithName(inviteUID)
-            share = Share(shareeHomeChild=shareeHomeChild, sharerHomeChild=sharedCollection._newStoreObject, url=hostUrl)
+            share = Share(shareeHomeChild=shareeHomeChild,
+                          sharerHomeChild=sharedCollection._newStoreObject,
+                          url=hostUrl)
 
-        response = yield self._acceptShare(request, not oldShare, share, displayname)
+        response = yield self._acceptShare(request, not oldShare, share,
+                                           displayname)
         returnValue(response)
 
 
     @inlineCallbacks
-    def acceptDirectShare(self, request, hostUrl, resourceUID, displayname=None):
+    def acceptDirectShare(self, request, hostUrl, resourceUID,
+                          displayname=None):
 
         # Just add the link
         oldShare = yield self._shareForUID(resourceUID, request)
@@ -1074,21 +1126,47 @@
             share = oldShare
         else:
             sharedCollection = yield request.locateResource(hostUrl)
-            sharedName = yield sharedCollection._newStoreObject.shareWith(shareeHome=self._newStoreHome,
-                                                    mode=_BIND_MODE_DIRECT,
-                                                    status=_BIND_STATUS_ACCEPTED,
-                                                    message=displayname)
+            sharedName = yield sharedCollection._newStoreObject.shareWith(
+                shareeHome=self._newStoreHome,
+                mode=_BIND_MODE_DIRECT,
+                status=_BIND_STATUS_ACCEPTED,
+                message=displayname
+            )
 
             shareeHomeChild = yield self._newStoreHome.childWithName(sharedName)
-            share = Share(shareeHomeChild=shareeHomeChild, sharerHomeChild=sharedCollection._newStoreObject, url=hostUrl)
+            share = Share(shareeHomeChild=shareeHomeChild,
+                          sharerHomeChild=sharedCollection._newStoreObject,
+                          url=hostUrl)
 
-        response = yield self._acceptShare(request, not oldShare, share, displayname)
+        response = yield self._acceptShare(request, not oldShare, share,
+                                           displayname)
         returnValue(response)
 
 
     @inlineCallbacks
     def _acceptShare(self, request, isNewShare, share, displayname=None):
+        """
+        Mark a pending shared invitation I{to} this, the owner's collection, as
+        accepted, generating the HTTP response to the request that accepted it.
 
+        @param request: The HTTP request that is accepting it.
+        @type request: L{twext.web2.iweb.IRequest}
+
+        @param isNewShare: a boolean indicating whether this share is new.
+        @type isNewShare: L{bool}
+
+        @param share: The share referencing the proposed sharer and sharee.
+        @type share: L{Share}
+
+        @param displayname: the UTF-8 encoded contents of the display-name
+            property on the resource to be created while accepting.
+        @type displayname: L{bytes}
+
+        @return: a L{twext.web2.iweb.IResponse} containing a serialized
+            L{customxml.SharedAs} element as its body.
+        @rtype: L{Deferred} firing L{XMLResponse}
+        """
+
         # Get shared collection in non-share mode first
         sharedCollection = yield request.locateResource(share.url())
 
@@ -1305,20 +1383,28 @@
 
 
 
-class SharedCollectionRecord(object):
+class Share(object):
+    """
+    A L{Share} represents information about a collection which has been shared
+    from one user to another.
+    """
 
-    def __init__(self, shareuid, sharetype, hosturl, localname, summary):
-        self.shareuid = shareuid
-        self.sharetype = sharetype
-        self.hosturl = hosturl
-        self.localname = localname
-        self.summary = summary
+    def __init__(self, sharerHomeChild, shareeHomeChild, url):
+        """
+        @param sharerHomeChild: The HTTP resource representing the shared
+            collection as present in the owner's home collection; the owner's
+            reference.
+        @type sharerHomeChild: L{twistedcaldav.resource.CalDAVResource}
 
+        @param shareeHomeChild: The data store object representing the
+            collection as present in the sharee's home collection; the sharee's
+            reference.
+        @type shareeHomeChild:
+            L{txdav.common.icommondatastore.IShareableCollection}
 
-
-class Share(object):
-
-    def __init__(self, sharerHomeChild, shareeHomeChild, url):
+        @param url: The URL referring to the sharer's version of the resource.
+        @type url: L{bytes}
+        """
         self._shareeHomeChild = shareeHomeChild
         self._sharerHomeChild = sharerHomeChild
         self._sharedResourceURL = url
@@ -1326,22 +1412,32 @@
 
     @classmethod
     def directUID(cls, shareeHome, sharerHomeChild):
-        return "Direct-%s-%s" % (shareeHome._resourceID, sharerHomeChild._resourceID,)
+        return "Direct-%s-%s" % (shareeHome._resourceID,
+                                 sharerHomeChild._resourceID,)
 
 
     def uid(self):
         # Move to CommonHomeChild shareUID?
         if self._shareeHomeChild.shareMode() == _BIND_MODE_DIRECT:
-            return self.directUID(shareeHome=self._shareeHomeChild.viewerHome(), sharerHomeChild=self._sharerHomeChild,)
+            return self.directUID(shareeHome=self._shareeHomeChild.viewerHome(),
+                                  sharerHomeChild=self._sharerHomeChild,)
         else:
             return self._shareeHomeChild.shareUID()
 
 
     def direct(self):
+        """
+        Is this L{Share} a "direct" share?
+
+        @return: a boolean indicating whether it's direct.
+        """
         return self._shareeHomeChild.shareMode() == _BIND_MODE_DIRECT
 
 
     def url(self):
+        """
+        @return: The URL to the owner's version of the shared collection.
+        """
         return self._sharedResourceURL
 
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20130128/ecc68616/attachment-0001.html>


More information about the calendarserver-changes mailing list