[CalendarServer-changes] [10749] CalendarServer/branches/users/gaya/sharedgroups/txdav

source_changes at macosforge.org source_changes at macosforge.org
Fri Feb 15 16:47:02 PST 2013


Revision: 10749
          http://trac.calendarserver.org//changeset/10749
Author:   gaya at apple.com
Date:     2013-02-15 16:47:02 -0800 (Fri, 15 Feb 2013)
Log Message:
-----------
fix sharedAs(), invitedAs(), unshareWith(), add GroupForSharedAddressBookDeleteNotAllowedError

Modified Paths:
--------------
    CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CardDAV/aclreports.xml
    CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CardDAV/sharing-addressbooks.xml
    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
    CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql.py

Added Paths:
-----------
    CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CardDAV/sharing/addressbooks/group/15a.xml

Added: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CardDAV/sharing/addressbooks/group/15a.xml
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CardDAV/sharing/addressbooks/group/15a.xml	                        (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CardDAV/sharing/addressbooks/group/15a.xml	2013-02-16 00:47:02 UTC (rev 10749)
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<CS:share xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/">
+    <CS:remove>
+        <D:href>$cuaddr2:</D:href>
+    </CS:remove>
+</CS:share>

Modified: CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CardDAV/aclreports.xml
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CardDAV/aclreports.xml	2013-02-16 00:11:19 UTC (rev 10748)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CardDAV/aclreports.xml	2013-02-16 00:47:02 UTC (rev 10749)
@@ -34,6 +34,7 @@
 				<filepath>Resource/CardDAV/vaclreports/10.xml</filepath>
 			</data>
 		</request>
+<!--
 		<request end-delete='yes'>
 			<method>MKCOL</method>
 			<ruri>$addressbookhome1:/adbktest2/</ruri>
@@ -58,6 +59,7 @@
 				<filepath>Resource/CardDAV/mkcol/1.xml</filepath>
 			</data>
 		</request>
+-->
 	</start>
 	
 	<test-suite name='acl-principal-prop-set REPORT' ignore='no'>
@@ -295,7 +297,7 @@
 				</verify>
 			</request>
 		</test>
-		<test name='6' ignore='no'>
+		<test name='6' ignore='yes'>
 			<description>Valid principal-search report with DAV:prop</description>
 			<request print-response='no'>
 				<method>REPORT</method>
@@ -313,7 +315,7 @@
 				</verify>
 			</request>
 		</test>
-		<test name='7' ignore='no'>
+		<test name='7' ignore='yes'>
 			<description>Valid principal-search report without DAV:prop</description>
 			<request print-response='no'>
 				<method>REPORT</method>

Modified: CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CardDAV/sharing-addressbooks.xml
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CardDAV/sharing-addressbooks.xml	2013-02-16 00:11:19 UTC (rev 10748)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CardDAV/sharing-addressbooks.xml	2013-02-16 00:47:02 UTC (rev 10749)
@@ -1285,6 +1285,24 @@
 				</verify>
 			</request>
 		</test>
+		<test name="20a" ignore="yes">
+			<description>Unshare main address book</description>
+			<request print-response="no">
+				<method>POST</method>
+				<ruri>$addressbookpath1:/3.vcf</ruri>
+				<data>
+					<content-type>text/xml; charset=utf-8</content-type>
+					<filepath>Resource/CardDAV/sharing/addressbooks/group/15a.xml</filepath>
+				</data>
+				<verify>
+					<callback>statusCode</callback>
+					<arg>
+						<name>status</name>
+						<value>200</value>
+					</arg>
+				</verify>
+			</request>
+		</test>
 		<test name='21' ignore='no'>
 			<description>Check Sharee notification collection and delete invite-deleted</description>
 			<request user="$userid2:" pswd="$pswd2:" print-response='no'>

Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/storebridge.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/storebridge.py	2013-02-16 00:11:19 UTC (rev 10748)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/storebridge.py	2013-02-16 00:47:02 UTC (rev 10749)
@@ -73,7 +73,7 @@
 from twext.web2.filter.location import addLocation
 
 from txdav.carddav.iaddressbookstore import GroupWithUnsharedAddressNotAllowedError, \
-    SharedGroupDeleteNotAllowedError
+    GroupForSharedAddressBookDeleteNotAllowedError, SharedGroupDeleteNotAllowedError
 
 """
 Wrappers to translate between the APIs in L{txdav.caldav.icalendarstore} and
@@ -3010,14 +3010,19 @@
         try:
             returnValue((yield super(AddressBookObjectResource, self).http_DELETE(request)))
 
+        except GroupForSharedAddressBookDeleteNotAllowedError:
+            raise HTTPError(StatusResponse(
+                FORBIDDEN,
+                "Sharee cannot delete the group for a whole address book ",)
+            )
+
         except SharedGroupDeleteNotAllowedError:
             raise HTTPError(StatusResponse(
                 FORBIDDEN,
-                "Sharee cannot delete group vcard shadowing shared address book",)
+                "Sharee cannot delete a shared group",)
             )
 
 
-
 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	2013-02-16 00:11:19 UTC (rev 10748)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py	2013-02-16 00:47:02 UTC (rev 10749)
@@ -43,8 +43,8 @@
 from txdav.base.propertystore.sql import PropertyStore
 from txdav.carddav.datastore.util import validateAddressBookComponent
 from txdav.carddav.iaddressbookstore import IAddressBookHome, IAddressBook, \
-    IAddressBookObject, GroupWithUnsharedAddressNotAllowedError, \
-    SharedGroupDeleteNotAllowedError
+    IAddressBookObject, GroupForSharedAddressBookDeleteNotAllowedError, \
+    GroupWithUnsharedAddressNotAllowedError, SharedGroupDeleteNotAllowedError
 from txdav.common.datastore.sql import CommonHome, CommonHomeChild, \
     CommonObjectResource, EADDRESSBOOKTYPE, SharingMixIn
 from txdav.common.datastore.sql_legacy import PostgresLegacyABIndexEmulator
@@ -936,9 +936,8 @@
 
         returnValue(shareeView._name)
 
-
     @inlineCallbacks
-    def asShared(self):
+    def asShared(self, includeGroupBinds=False):
         """
         Retrieve all the versions of this L{CommonHomeChild} as it is shared to
         everyone.
@@ -953,26 +952,30 @@
             returnValue([])
 
         # get all accepted shared binds
-        rows = yield self._sharedBindForResourceID.on(
+        bindRows = yield self._sharedBindForResourceID.on(
             self._txn, resourceID=self._resourceID, homeID=self._home._resourceID
         )
-        homeIDToBindRowMap = dict([(row[1], row) for row in rows])
 
-        groupBindRows = yield AddressBookObject._acceptedBindWithAddressBookID.on(
-                self._txn, addressbookID=self._resourceID
-        )
-        for groupBindRow in groupBindRows:
-            bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = groupBindRow #@UnusedVariable
-            if homeID not in homeIDToBindRowMap:
-                groupBindRow[0] = _BIND_MODE_WRITE
-                groupBindRow[3] = None # bindName
-                groupBindRow[4] = None # bindStatus
-                groupBindRow[5] = None # bindMessage
-                homeIDToBindRowMap[homeID] = groupBindRow
+        if includeGroupBinds:
+            homeIDToBindRowMap = dict([(bindRow[1], bindRow) for bindRow in bindRows])
 
+            groupBindRows = yield AddressBookObject._acceptedBindWithAddressBookID.on(
+                    self._txn, addressbookID=self._resourceID
+            )
+            for groupBindRow in groupBindRows:
+                bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = groupBindRow #@UnusedVariable
+                if homeID not in homeIDToBindRowMap:
+                    groupBindRow[0] = _BIND_MODE_WRITE
+                    groupBindRow[3] = None # bindName
+                    groupBindRow[4] = None # bindStatus
+                    groupBindRow[5] = None # bindMessage
+                    homeIDToBindRowMap[homeID] = groupBindRow
+
+            bindRows = homeIDToBindRowMap.values()
+
         result = []
         cls = self._home._childClass # for ease of grepping...
-        for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in homeIDToBindRowMap.values(): #@UnusedVariable
+        for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in bindRows: #@UnusedVariable
 
             home = yield self._txn.homeWithResourceID(self._home._homeType, homeID)
             new = cls(
@@ -989,7 +992,7 @@
 
 
     @inlineCallbacks
-    def asInvited(self):
+    def asInvited(self, includeGroupBinds=False):
         """
         Retrieve all the versions of this L{CommonHomeChild} as it is invited to
         everyone.
@@ -1004,27 +1007,30 @@
             returnValue([])
 
         # get all accepted shared binds
-        rows = yield self._unacceptedBindForResourceID.on(
+        bindRows = yield self._unacceptedBindForResourceID.on(
             self._txn, resourceID=self._resourceID
         )
-        homeIDToBindRowMap = dict([(row[1], row) for row in rows])
+        homeIDToBindRowMap = dict([(bindRow[1], bindRow) for bindRow in bindRows])
 
-        groupBindRows = yield AddressBookObject._unacceptedBindWithAddressBookID.on(
-                self._txn, addressbookID=self._resourceID
-        )
-        for groupBindRow in groupBindRows:
-            bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = groupBindRow #@UnusedVariable
-            if homeID not in homeIDToBindRowMap:
-                groupBindRow[0] = _BIND_MODE_WRITE
-                groupBindRow[3] = None # bindName
-                groupBindRow[4] = None # bindStatus
-                groupBindRow[5] = None # bindMessage
-                homeIDToBindRowMap[homeID] = groupBindRow
-                break
+        if includeGroupBinds:
+            groupBindRows = yield AddressBookObject._unacceptedBindWithAddressBookID.on(
+                    self._txn, addressbookID=self._resourceID
+            )
+            for groupBindRow in groupBindRows:
+                bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = groupBindRow #@UnusedVariable
+                if homeID not in homeIDToBindRowMap:
+                    groupBindRow[0] = _BIND_MODE_WRITE
+                    groupBindRow[3] = None # bindName
+                    groupBindRow[4] = None # bindStatus
+                    groupBindRow[5] = None # bindMessage
+                    homeIDToBindRowMap[homeID] = groupBindRow
+                    break
 
+            bindRows = homeIDToBindRowMap.values()
+
         result = []
         cls = self._home._childClass # for ease of grepping...
-        for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in homeIDToBindRowMap.values(): #@UnusedVariable
+        for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in bindRows: #@UnusedVariable
 
             home = yield self._txn.homeWithResourceID(self._home._homeType, homeID)
             new = cls(
@@ -1051,10 +1057,8 @@
         @param shareeHome: The home with which this L{CommonHomeChild} was
             previously shared.
 
-        @return: a L{Deferred} which will fire with the previously-used name.
+        @return: a L{Deferred} which will fire with the previous shareUID
         """
-        resourceName = None
-
         sharedAddressBook = yield shareeHome.addressbookWithName(self.shareeABName())
         if sharedAddressBook:
 
@@ -1063,26 +1067,27 @@
                     self._txn, homeID=sharedAddressBook._home._resourceID, addressbookID=sharedAddressBook._resourceID
             )))
             if acceptedBinds == 1:
-                resourceName = self.shareeABName()
                 sharedAddressBook._deletedSyncToken(sharedRemoval=True)
                 shareeHome._children.pop(self.shareeABName(), None)
 
+            # Must send notification to ensure cache invalidation occurs
+            yield self.notifyChanged()
+
+        # delete binds including invites
+        deletedBindNameRows = yield self._deleteBindWithResourceIDAndHomeID.on(self._txn, resourceID=self._resourceID,
+             homeID=shareeHome._resourceID)
+        if deletedBindNameRows:
+            deletedBindName = deletedBindNameRows[0][0]
             queryCacher = self._txn._queryCacher
             if queryCacher:
                 cacheKey = queryCacher.keyForObjectWithName(shareeHome._resourceID, self.shareeABName())
                 queryCacher.invalidateAfterCommit(self._txn, cacheKey)
+        else:
+            deletedBindName = None
 
-            deleted = yield self._deleteBindWithResourceIDAndHomeID.on(self._txn, resourceID=self._resourceID,
-                 homeID=shareeHome._resourceID)
+        returnValue(deletedBindName)
 
-            # Must send notification to ensure cache invalidation occurs
-            yield self.notifyChanged()
 
-        returnValue(resourceName)
-
-
-
-
 class AddressBookObject(CommonObjectResource, SharingMixIn):
 
     implements(IAddressBookObject)
@@ -1144,9 +1149,9 @@
             # cannot delete share for now
             # TODO: convert to unshare
             if self._resourceID == self._addressbook._resourceID:
+                raise GroupForSharedAddressBookDeleteNotAllowedError
+            elif self.shareUID():
                 raise SharedGroupDeleteNotAllowedError
-            elif self._bindName:
-                raise SharedGroupDeleteNotAllowedError
 
         aboMembers = schema.ABO_MEMBERS
         aboForeignMembers = schema.ABO_FOREIGN_MEMBERS
@@ -1937,7 +1942,6 @@
 
         @return: a L{Deferred} which will fire with the previously-used name.
         """
-
         resourceName = None
         sharedAddressBook = yield shareeHome.addressbookWithName(self._addressbook.shareeABName())
         if sharedAddressBook:
@@ -1952,20 +1956,24 @@
                 sharedAddressBook._deletedSyncToken(sharedRemoval=True)
                 shareeHome._children.pop(resourceName, None)
 
+            # Must send notification to ensure cache invalidation occurs
+            yield self._addressbook.notifyChanged()
+
+        # delete binds including invites
+        deletedBindNameRows = yield self._deleteBindWithResourceIDAndHomeID.on(self._txn, resourceID=self._addressbook._resourceID,
+             homeID=shareeHome._resourceID)
+        if deletedBindNameRows:
+            deletedBindName = deletedBindNameRows[0][0]
             queryCacher = self._txn._queryCacher
             if queryCacher:
-                cacheKey = queryCacher.keyForObjectWithName(shareeHome._resourceID, self._addressbook.shareeABName())
+                cacheKey = queryCacher.keyForObjectWithName(shareeHome._resourceID, self.shareeABName())
                 queryCacher.invalidateAfterCommit(self._txn, cacheKey)
+        else:
+            deletedBindName = None
 
-            deleted = yield self._deleteBindWithResourceIDAndHomeID.on(self._txn, resourceID=self._resourceID,
-                 homeID=shareeHome._resourceID)
+        returnValue(deletedBindName)
 
-            # Must send notification to ensure cache invalidation occurs
-            yield self._addressbook.notifyChanged()
 
-        returnValue(resourceName)
-
-
     @inlineCallbacks
     def updateShare(self, shareeView, mode=None, status=None, message=None, name=None):
         """

Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/iaddressbookstore.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/iaddressbookstore.py	2013-02-16 00:11:19 UTC (rev 10748)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/iaddressbookstore.py	2013-02-16 00:47:02 UTC (rev 10749)
@@ -26,6 +26,7 @@
 
 __all__ = [
     # Classes
+    "GroupForSharedAddressBookDeleteNotAllowedError"
     "GroupWithUnsharedAddressNotAllowedError",
     "SharedGroupDeleteNotAllowedError",
     "IAddressBookTransaction",
@@ -34,6 +35,11 @@
     "IAddressBookObject",
 ]
 
+class GroupForSharedAddressBookDeleteNotAllowedError(CommonStoreError):
+    """
+    Sharee cannot delete the group for a shared address book
+    """
+
 class GroupWithUnsharedAddressNotAllowedError(CommonStoreError):
     """
     Sharee cannot add or modify group vcard such that result contains addresses of unshared vcards.
@@ -42,7 +48,7 @@
 
 class SharedGroupDeleteNotAllowedError(CommonStoreError):
     """
-    Sharee cannot delete group vcard shadowing shared address book
+    Sharee cannot delete a shared group
     """
 
 

Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql.py	2013-02-16 00:11:19 UTC (rev 10748)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql.py	2013-02-16 00:47:02 UTC (rev 10749)
@@ -2556,37 +2556,35 @@
         @param shareeHome: The home with which this L{CommonHomeChild} was
             previously shared.
 
-        @return: a L{Deferred} which will fire with the previously-used name.
+        @return: a L{Deferred} which will fire with the previous shareUID
         """
-
-        resourceName = None
-
         #remove sync tokens
         shareeChildren = yield shareeHome.children()
         for shareeChild in shareeChildren:
             if not shareeChild.owned() and shareeChild._resourceID == self._resourceID:
                 shareeChild._deletedSyncToken(sharedRemoval=True)
+                shareeHome._children.pop(shareeChild._name, None)
 
-                queryCacher = self._txn._queryCacher
-                if queryCacher:
-                    cacheKey = queryCacher.keyForObjectWithName(shareeHome._resourceID, shareeChild._name)
-                    queryCacher.invalidateAfterCommit(self._txn, cacheKey)
-
-                resourceName = shareeChild._name
-                shareeHome._children.pop(resourceName, None)
-
                 # Must send notification to ensure cache invalidation occurs
                 yield self.notifyChanged()
-
                 break
 
         # delete binds including invites
-        yield self._deleteBindWithResourceIDAndHomeID.on(self._txn, resourceID=self._resourceID,
+        deletedBindNameRows = yield self._deleteBindWithResourceIDAndHomeID.on(self._txn, resourceID=self._resourceID,
              homeID=shareeHome._resourceID)
 
-        returnValue(resourceName)
+        if deletedBindNameRows:
+            deletedBindName = deletedBindNameRows[0][0]
+            queryCacher = self._txn._queryCacher
+            if queryCacher:
+                cacheKey = queryCacher.keyForObjectWithName(shareeHome._resourceID, shareeChild._name)
+                queryCacher.invalidateAfterCommit(self._txn, cacheKey)
+        else:
+            deletedBindName = None
 
+        returnValue(deletedBindName)
 
+
     @inlineCallbacks
     def unshare(self):
         """
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20130215/b6168fa7/attachment-0001.html>


More information about the calendarserver-changes mailing list