[CalendarServer-changes] [10009] CalendarServer/branches/users/gaya/sharedgroups

source_changes at macosforge.org source_changes at macosforge.org
Thu Nov 8 15:50:21 PST 2012


Revision: 10009
          http://trac.calendarserver.org//changeset/10009
Author:   gaya at apple.com
Date:     2012-11-08 15:50:21 -0800 (Thu, 08 Nov 2012)
Log Message:
-----------
Send delete notification when shared group is deleted. Add GroupWithUnsharedAddressNotAllowedError in iaddressbookstore.py and use it.

Modified Paths:
--------------
    CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/sharing.py
    CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/storebridge.py
    CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py
    CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/iaddressbookstore.py

Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/sharing.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/sharing.py	2012-11-08 23:22:14 UTC (rev 10008)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/sharing.py	2012-11-08 23:50:21 UTC (rev 10009)
@@ -126,11 +126,12 @@
     @inlineCallbacks
     def downgradeFromShare(self, request):
 
-        # Change resource type (note this might be called after deleting a resource
-        # so we have to cope with that)
-        rtype = self.resourceType()
-        rtype = element.ResourceType(*([child for child in rtype.children if child != customxml.SharedOwner()]))
-        self.writeDeadProperty(rtype)
+        if self.isCollection():
+            # Change resource type (note this might be called after deleting a resource
+            # so we have to cope with that)
+            rtype = self.resourceType()
+            rtype = element.ResourceType(*([child for child in rtype.children if child != customxml.SharedOwner()]))
+            self.writeDeadProperty(rtype)
 
         # Remove all invitees
         for invitation in (yield self._allInvitations()):
@@ -234,7 +235,7 @@
     @inlineCallbacks
     def isShared(self, request):
         """ Return True if this is an owner shared calendar collection """
-        returnValue((yield self.isSpecialCollection(customxml.SharedOwner)) or (yield self._allInvitations()))
+        returnValue((yield self.isSpecialCollection(customxml.SharedOwner)) or bool((yield self._allInvitations())))
 
 
     def setShare(self, share):
@@ -1018,11 +1019,10 @@
             url = joinURL(sharerHomeCollection.url(), itemShared.name())
         else:
             for sharerHomeChild in (yield child.ownerHome().children()):
-                for objectResource in (yield sharerHomeChild.objectResources()):
-                    if objectResource._resourceID == child._resourceID:
-                        itemShared = objectResource
-                        url = joinURL(sharerHomeCollection.url(), itemShared._parentCollection.name(), itemShared.name())
-                        break
+                itemShared = yield sharerHomeChild.objectResourceWithID(child._resourceID)
+                if itemShared:
+                    url = joinURL(sharerHomeCollection.url(), itemShared._parentCollection.name(), itemShared.name())
+                    break
 
         share = Share(shareeHomeChild=child, sharerHomeChild=itemShared, url=url)
 

Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/storebridge.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/storebridge.py	2012-11-08 23:22:14 UTC (rev 10008)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/storebridge.py	2012-11-08 23:50:21 UTC (rev 10009)
@@ -67,6 +67,7 @@
 from twistedcaldav.scheduling.caldav.resource import ScheduleInboxResource
 from twistedcaldav.scheduling.implicit import ImplicitScheduler
 from twistedcaldav.vcard import Component as VCard, InvalidVCardDataError
+from txdav.carddav.iaddressbookstore import  GroupWithUnsharedAddressNotAllowedError
 
 """
 Wrappers to translate between the APIs in L{txdav.caldav.icalendarstore} and
@@ -2234,7 +2235,30 @@
     vCard = _CommonObjectResource.component
 
 
+    @inlineCallbacks
+    def storeRemove(self, request, viaRequest, where):
 
+        # Handle sharing
+        wasShared = (yield self.isShared(request))
+        if wasShared:
+            yield self.downgradeFromShare(request)
+
+        returnValue((yield super(AddressBookObjectResource, self).storeRemove(request, viaRequest, where)))
+
+
+    @inlineCallbacks
+    def http_PUT(self, request):
+
+        try:
+            returnValue((yield super(AddressBookObjectResource, self).http_PUT(request)))
+
+        except GroupWithUnsharedAddressNotAllowedError:
+            raise HTTPError(StatusResponse(
+                FORBIDDEN,
+                "Group vcard cannot contain addresses of unshared vcards.",)
+            )
+
+
 class _NotificationChildHelper(object):
     """
     Methods for things which are like notification objects.

Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py	2012-11-08 23:22:14 UTC (rev 10008)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py	2012-11-08 23:50:21 UTC (rev 10009)
@@ -31,8 +31,6 @@
 
 from twext.python.clsprop import classproperty
 from twext.web2.http_headers import MimeType
-from twext.web2 import responsecode
-from twext.web2.http import HTTPError
 
 
 from twisted.internet.defer import inlineCallbacks, returnValue
@@ -45,7 +43,7 @@
 from txdav.base.propertystore.base import PropertyName
 from txdav.carddav.datastore.util import validateAddressBookComponent
 from txdav.carddav.iaddressbookstore import IAddressBookHome, IAddressBook, \
-    IAddressBookObject
+    IAddressBookObject, GroupWithUnsharedAddressNotAllowedError
 from txdav.common.datastore.sql import CommonHome, CommonHomeChild, \
     CommonObjectResource, EADDRESSBOOKTYPE, SharingMixIn
 from txdav.common.datastore.sql_legacy import PostgresLegacyABIndexEmulator
@@ -57,7 +55,6 @@
     ADDRESSBOOK_OBJECT_REVISIONS_AND_BIND_TABLE, \
     _ABO_KIND_PERSON, _ABO_KIND_GROUP, _ABO_KIND_RESOURCE, _ABO_KIND_LOCATION, \
     schema
-from txdav.common.icommondatastore import NoSuchObjectResourceError
 from txdav.xml.rfc2518 import ResourceType
 
 from uuid import uuid4
@@ -383,7 +380,7 @@
             ownerGroup, ownerAddressBook = yield self._ownerGroupAndAddressBook()  #@UnusedVariable 
             print("remove:%s, ownerGroup=%s, ownerAddressBook=%s" % (self, ownerGroup, ownerAddressBook,))
             if ownerGroup:
-                # convert a delete inside of a shared group to a remove of in shared group and subgroups
+                # convert a delete of a shared group member to a remove of that member in shared group and subgroups
 
                 groupIDRows = yield Select(
                     [aboMembers.GROUP_ID],
@@ -394,17 +391,13 @@
                 groupIDs = [groupID[0] for groupID in groupIDRows]
                 print("remove:self=%s, groupIDs=%s" % (self, groupIDs,))
 
-                objectResources = yield ownerAddressBook.objectResources()
-                groupObjects = [groupObject for groupObject in objectResources
-                                    if groupObject._resourceID in groupIDs]
-
-                print("remove:self=%s, groupIDs=%s, objectResources=%s, groupObjects=%s" % (self, groupIDs, objectResources, groupObjects,))
                 member = "urn:uuid:" + self._uid
-                for groupObject in groupObjects:
-                    groupObjectComponent = yield groupObject.component()
-                    if member in groupObjectComponent.resourceMembers():
-                        groupObjectComponent.removeProperty(Property("X-ADDRESSBOOKSERVER-MEMBER", member))
-                        groupObject.updateDatabase(groupObjectComponent)
+                for groupID in groupIDs:
+                    groupObject = yield ownerAddressBook.objectResourceWithID(groupID)
+                    groupComponent = yield groupObject.component()
+                    if member in groupComponent.resourceMembers():
+                        groupComponent.removeProperty(Property("X-ADDRESSBOOKSERVER-MEMBER", member))
+                        groupObject.updateDatabase(groupComponent)
 
                 return
 
@@ -484,7 +477,7 @@
                 self._txn, uid=self._uid,
                 resourceIDs=memberIDs,)) if memberIDs else []
         elif self._resourceID:
-            rows = (yield self._allWithResourceID(memberIDs).on(
+            rows = (yield self._allWithResourceID.on(
                 self._txn, resourceID=self._resourceID,)) if self._resourceID in memberIDs else []
         print("initFromStore:self=%s, self._name=%s, self._uid=%s, self._resourceID=%s, self._parentCollection._resourceID=%s rows=%s" %
               (self, self._name, self._uid, self._resourceID, self._parentCollection._resourceID, rows))
@@ -595,14 +588,14 @@
         if self._addressbook.owned():
             ownerAddressBook = self._addressbook
         else:
-            ownerAddressBook = yield self._addressbook.ownerHome().childWithID(self._addressbook._resourceID)
+            ownerAddressBook = yield self._addressbook.ownerAddressBookHome().childWithID(self._addressbook._resourceID)
             if not ownerAddressBook:
-                for addressbook in (yield self._addressbook.ownerHome().children()):
-                    for addressBookObject in (yield addressbook.objectResources()):
-                        if addressBookObject._resourceID == self._addressbook._resourceID:
-                            ownerGroup = addressBookObject
-                            ownerAddressBook = addressbook
-                            break
+                for addressbook in (yield self._addressbook.ownerAddressBookHome().addressbooks()):
+                    ownerGroup = yield addressbook.objectResourceWithID(self._addressbook._resourceID)
+                    if ownerGroup:
+                        ownerAddressBook = addressbook
+                        break
+
         returnValue((ownerGroup, ownerAddressBook))
 
     @inlineCallbacks
@@ -682,13 +675,9 @@
 
             #in shared group, all members must be inside the shared group
             if ownerGroup:
-                if len(resourceMembers) != len(memberIDs):
-                    raise NoSuchObjectResourceError
-                    raise HTTPError(responsecode.NOT_FOUND)
-                elif set(memberIDs) - set((yield self._addressbook._addressBookObjectIDs())):
-                    print("e2")
-                    raise NoSuchObjectResourceError
-                    raise HTTPError(responsecode.NOT_FOUND)
+                if len(resourceMembers) != len(memberIDs) or \
+                    set(memberIDs) - set((yield self._addressbook._addressBookObjectIDs())):
+                    raise GroupWithUnsharedAddressNotAllowedError
 
         if inserting:
 

Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/iaddressbookstore.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/iaddressbookstore.py	2012-11-08 23:22:14 UTC (rev 10008)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/iaddressbookstore.py	2012-11-08 23:50:21 UTC (rev 10009)
@@ -20,18 +20,24 @@
 """
 
 from txdav.common.icommondatastore import ICommonTransaction, \
-    IShareableCollection
+    IShareableCollection, CommonStoreError
 from txdav.idav import INotifier
 from txdav.idav import IDataStoreObject
 
 __all__ = [
     # Classes
+    "GroupWithUnsharedAddressNotAllowedError",
     "IAddressBookTransaction",
     "IAddressBookHome",
     "IAddressBook",
     "IAddressBookObject",
 ]
 
+class GroupWithUnsharedAddressNotAllowedError(CommonStoreError):
+    """
+    Sharee cannot add group with unshared group addresses (that could expand the scope of sharing).
+    """
+
 class IAddressBookTransaction(ICommonTransaction):
     """
     Transaction interface that addressbook stores must provide.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20121108/1d229fbe/attachment-0001.html>


More information about the calendarserver-changes mailing list