[CalendarServer-changes] [10945] CalendarServer/branches/users/gaya/sharedgroups/txdav
source_changes at macosforge.org
source_changes at macosforge.org
Mon Mar 18 15:33:22 PDT 2013
Revision: 10945
http://trac.calendarserver.org//changeset/10945
Author: gaya at apple.com
Date: 2013-03-18 15:33:22 -0700 (Mon, 18 Mar 2013)
Log Message:
-----------
fix revisions, properties bugs with shared groups in AddressBook.loadAllObjects()
Modified Paths:
--------------
CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CardDAV/sharing-addressbooks.xml
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/sharing.py
CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py
CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql.py
Modified: CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CardDAV/sharing-addressbooks.xml
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CardDAV/sharing-addressbooks.xml 2013-03-18 19:57:28 UTC (rev 10944)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CardDAV/sharing-addressbooks.xml 2013-03-18 22:33:22 UTC (rev 10945)
@@ -837,7 +837,7 @@
<test-suite name='Share group' ignore='no'>
<test name='1' ignore='no'>
- <description>Sharee create 2 persons and a group</description>
+ <description>Sharee creates 2 persons and a group</description>
<request print-response='no'>
<method>PUT</method>
<ruri>$addressbookpath1:/1.vcf</ruri>
@@ -984,6 +984,44 @@
</verify>
</request>
</test>
+ <test name='6aa'>
+ <description>Shared address book exists Depth:1</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>PROPFIND</method>
+ <ruri>$addressbookhome2:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/CardDAV/sharing/addressbooks/read-write/4.xml</filepath>
+ </data>
+ <verify>
+ <callback>xmlElementMatch</callback>
+ <arg>
+ <name>parent</name>
+ <value>$multistatus-response-prefix:[^{DAV:}href=$addressbookhome2:/$userid1:/]</value>
+ </arg>
+ <arg>
+ <name>exists</name>
+ <value>$verify-response-prefix:/{DAV:}owner/{DAV:}href[=$principaluri1:]</value>
+ <value>$verify-response-prefix:/{DAV:}resourcetype/{DAV:}collection</value>
+ <value>$verify-response-prefix:/{DAV:}resourcetype/{urn:ietf:params:xml:ns:carddav}addressbook</value>
+ <value>$verify-response-prefix:/{DAV:}resourcetype/{http://calendarserver.org/ns/}shared</value>
+ <value>$verify-response-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}read</value>
+ <value>$verify-response-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}write</value>
+ <value>$verify-response-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}bind</value>
+ <value>$verify-response-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}unbind</value>
+ </arg>
+ <arg>
+ <name>notexists</name>
+ <value>$verify-property-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}admin</value>
+ <value>$verify-property-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}all</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
<test name='6a' ignore='no'>
<description>Sharee sees shared group vcard</description>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/sharing.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/sharing.py 2013-03-18 19:57:28 UTC (rev 10944)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/sharing.py 2013-03-18 22:33:22 UTC (rev 10945)
@@ -1153,7 +1153,7 @@
shareeStoreObject = yield self._newStoreHome.objectWithShareUID(shareUID)
if shareeStoreObject:
share = yield self._shareForStoreObject(shareeStoreObject, request)
- if share and share.uid() == shareUID:
+ if share:
returnValue(share)
# find direct shares
Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py 2013-03-18 19:57:28 UTC (rev 10944)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py 2013-03-18 22:33:22 UTC (rev 10945)
@@ -61,6 +61,7 @@
from zope.interface.declarations import implements
+
class AddressBookHome(CommonHome):
implements(IAddressBookHome)
@@ -336,6 +337,7 @@
AddressBookHome._register(EADDRESSBOOKTYPE)
+
class AddressBook(CommonHomeChild, SharingMixIn):
"""
SQL-based implementation of L{IAddressBook}.
@@ -588,9 +590,33 @@
else:
returnValue((yield super(AddressBook, self).bumpModified()))
+ '''
+ @classproperty
+ def _revisionsForHomeID(cls): #@NoSelf
+ bind = cls._bindSchema
+ rev = cls._revisionsSchema
+ return Select(
+ [rev.RESOURCE_ID, Max(rev.REVISION)],
+ From=rev.join(bind, rev.RESOURCE_ID == bind.RESOURCE_ID, 'left'),
+ Where=(bind.HOME_RESOURCE_ID == Parameter("homeID")).
+ And((rev.RESOURCE_NAME != None).Or(rev.DELETED == False)),
+ GroupBy=rev.RESOURCE_ID
+ )
+ '''
@classmethod
+ def _revisionsForResourceIDs(cls, resourceIDs):
+ rev = cls._revisionsSchema
+ return Select(
+ [rev.RESOURCE_ID, Max(rev.REVISION)],
+ From=rev,
+ Where=rev.RESOURCE_ID.In(Parameter("resourceIDs", len(resourceIDs))),
+ GroupBy=rev.RESOURCE_ID
+ )
+
+
+ @classmethod
@inlineCallbacks
def loadAllObjects(cls, home):
"""
@@ -601,20 +627,18 @@
optimization for Depth:1 operations on the home.
"""
results = [home.addressbook(), ]
- ownerHomeIDToDataRowMap = {}
+ ownerHomeToDataRowMap = {}
# Load from the main table first
dataRows = yield cls._childrenAndMetadataForHomeID.on(
home._txn, homeID=home._resourceID
)
-
# get ownerHomeIDs
for dataRow in dataRows:
bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = dataRow[:6] #@UnusedVariable
assert bindStatus != _BIND_MODE_OWN
ownerHome = yield home.ownerHomeWithChildID(resourceID)
- ownerHomeID = ownerHome._resourceID
- ownerHomeIDToDataRowMap[ownerHomeID] = dataRow
+ ownerHomeToDataRowMap[ownerHome] = dataRow
# now get group rows:
groupBindRows = yield AddressBookObject._childrenAndMetadataForHomeID.on(
@@ -623,37 +647,36 @@
for groupBindRow in groupBindRows:
bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = groupBindRow[:6] #@UnusedVariable
ownerAddressBookID = yield AddressBookObject.ownerAddressBookFromGroupID(home._txn, resourceID)
- ownerHome = yield home.ownerHomeWithChildID(home._txn, ownerAddressBookID)
- ownerHomeID = ownerHome._resourceID
- if ownerHomeID not in ownerHomeIDToDataRowMap:
+ ownerHome = yield home.ownerHomeWithChildID(ownerAddressBookID)
+ if ownerHome not in ownerHomeToDataRowMap:
groupBindRow[0] = _BIND_MODE_WRITE
groupBindRow[3] = None # bindName
groupBindRow[4] = None # bindStatus
groupBindRow[5] = None # bindMessage
- ownerHomeIDToDataRowMap[ownerHomeID] = groupBindRow
+ ownerHomeToDataRowMap[ownerHome] = groupBindRow
- if ownerHomeIDToDataRowMap:
-
+ if ownerHomeToDataRowMap:
# Get property stores for all these child resources (if any found)
+ #FIXME: this does not load address books that are not fully owned.
propertyStores = (yield PropertyStore.forMultipleResources(
home.uid(), home._txn,
cls._bindSchema.RESOURCE_ID, cls._bindSchema.HOME_RESOURCE_ID,
home._resourceID
))
- revisions = yield cls._revisionsForHomeID.on(home._txn, homeID=home._resourceID)
+
+ childResourceIDs = [ownerHome._resourceID for ownerHome in ownerHomeToDataRowMap]
+ revisions = yield cls._revisionsForResourceIDs(childResourceIDs).on(home._txn, resourceIDs=childResourceIDs)
revisions = dict(revisions)
# Create the actual objects merging in properties
- for dataRow in ownerHomeIDToDataRowMap.values():
+ for ownerHome, dataRow in ownerHomeToDataRowMap.iteritems():
bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = dataRow[:6] #@UnusedVariable
metadata = dataRow[6:]
- ownerHome = yield home.ownerHomeWithChildID(resourceID)
- ownerAddressBook = yield ownerHome.addressbook()
-
child = cls(
home=home,
- name=ownerAddressBook.shareeAddressBookName(), resourceID=ownerAddressBook._resourceID,
+ name=ownerHome.shareeAddressBookName(),
+ resourceID=ownerHome._resourceID,
mode=bindMode, status=bindStatus,
message=bindMessage, ownerHome=ownerHome,
bindName=bindName
@@ -661,13 +684,13 @@
for attr, value in zip(cls.metadataAttributes(), metadata):
setattr(child, attr, value)
- child._syncTokenRevision = revisions[resourceID]
- propstore = propertyStores.get(resourceID, None)
-
- # We have to re-adjust the property store object to account for possible shared
- # collections as previously we loaded them all as if they were owned
- propstore._setDefaultUserUID(ownerHome.uid())
- yield child._loadPropertyStore(propstore)
+ child._syncTokenRevision = revisions[child._resourceID]
+ propstore = propertyStores.get(child._resourceID, None)
+ if propstore:
+ # We have to re-adjust the property store object to account for possible shared
+ # collections as previously we loaded them all as if they were owned
+ propstore._setDefaultUserUID(ownerHome.uid())
+ yield child._loadPropertyStore(None)
results.append(child)
returnValue(results)
@@ -1132,19 +1155,16 @@
L{CommonHomeChild} as a child of different L{CommonHome}s
@rtype: a L{Deferred} which fires with a L{list} of L{ICalendar}s.
"""
- if not self.owned():
- returnValue([])
-
- # get all accepted shared binds
- bindRows = yield self._sharedBindForResourceID.on(
- self._txn, resourceID=self._resourceID, homeID=self._home._resourceID
- )
-
result = []
- for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in bindRows: #@UnusedVariable
- home = yield self._txn.homeWithResourceID(self._home._homeType, homeID)
- new = yield home.childWithName(self.shareeAddressBookName())
- result.append(new)
+ if self.owned():
+ # get all accepted shared binds
+ bindRows = yield self._sharedBindForResourceID.on(
+ self._txn, resourceID=self._resourceID, homeID=self._home._resourceID
+ )
+ for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in bindRows: #@UnusedVariable
+ home = yield self._txn.homeWithResourceID(self._home._homeType, homeID)
+ new = yield home.childWithName(self.shareeAddressBookName())
+ result.append(new)
returnValue(result)
@@ -1161,18 +1181,16 @@
L{CommonHomeChild} as a child of different L{CommonHome}s
@rtype: a L{Deferred} which fires with a L{list} of L{ICalendar}s.
"""
- if not self.owned():
- returnValue([])
-
- # get all accepted shared binds
result = []
- bindRows = yield self._unacceptedBindForResourceID.on(
- self._txn, resourceID=self._resourceID
- )
- for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in bindRows: #@UnusedVariable
- home = yield self._txn.homeWithResourceID(self._home._homeType, homeID)
- new = yield self.objectWithName(home, self.shareeAddressBookName(), accepted=False)
- result.append(new)
+ if self.owned():
+ # get all accepted shared binds
+ bindRows = yield self._unacceptedBindForResourceID.on(
+ self._txn, resourceID=self._resourceID
+ )
+ for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in bindRows: #@UnusedVariable
+ home = yield self._txn.homeWithResourceID(self._home._homeType, homeID)
+ new = yield self.objectWithName(home, self.shareeAddressBookName(), accepted=False)
+ result.append(new)
returnValue(result)
@@ -1224,6 +1242,7 @@
returnValue(deletedBindName)
+
class AddressBookObject(CommonObjectResource, SharingMixIn):
implements(IAddressBookObject)
@@ -1973,19 +1992,17 @@
in different L{CommonHome}s
@rtype: a L{Deferred} which fires with a L{list} of L{AddressBookObject}s.
"""
- if not self.owned():
- returnValue([])
-
- # get all accepted shared binds
- groupBindRows = yield self._sharedBindForResourceID.on(
- self._txn, resourceID=self._resourceID, homeID=self._home._resourceID
- )
result = []
- for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in groupBindRows: #@UnusedVariable
- home = yield self._txn.homeWithResourceID(self._home._homeType, homeID)
- addressbook = yield home.childWithName(self._home.shareeAddressBookName())
- new = yield addressbook.objectResourceWithID(resourceID)
- result.append(new)
+ if self.owned():
+ # get all accepted shared binds
+ groupBindRows = yield self._sharedBindForResourceID.on(
+ self._txn, resourceID=self._resourceID, homeID=self._home._resourceID
+ )
+ for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in groupBindRows: #@UnusedVariable
+ home = yield self._txn.homeWithResourceID(self._home._homeType, homeID)
+ addressbook = yield home.childWithName(self._home.shareeAddressBookName())
+ new = yield addressbook.objectResourceWithID(resourceID)
+ result.append(new)
returnValue(result)
@@ -2003,22 +2020,19 @@
in different L{CommonHome}s
@rtype: a L{Deferred} which fires with a L{list} of L{AddressBookObject}s.
"""
- if not self.owned():
- returnValue([])
-
- # get all accepted shared binds
- groupBindRows = yield self._unacceptedBindForResourceID.on(
- self._txn, resourceID=self._resourceID
- )
result = []
- for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in groupBindRows: #@UnusedVariable
- home = yield self._txn.homeWithResourceID(self._home._homeType, homeID)
- addressbook = yield home.childWithName(self._home.shareeAddressBookName())
- if not addressbook:
- #addressbook = yield self._home._childClass.objectWithName(home, self._home.shareeAddressBookName(), accepted=False)
- addressbook = yield AddressBook.objectWithName(home, self._home.shareeAddressBookName(), accepted=False)
- new = yield AddressBookObject.objectWithID(addressbook, resourceID) # avoids object cache
- result.append(new)
+ if self.owned():
+ # get all accepted shared binds
+ groupBindRows = yield self._unacceptedBindForResourceID.on(
+ self._txn, resourceID=self._resourceID
+ )
+ for bindMode, homeID, resourceID, bindName, bindStatus, bindMessage in groupBindRows: #@UnusedVariable
+ home = yield self._txn.homeWithResourceID(self._home._homeType, homeID)
+ addressbook = yield home.childWithName(self._home.shareeAddressBookName())
+ if not addressbook:
+ addressbook = yield AddressBook.objectWithName(home, self._home.shareeAddressBookName(), accepted=False)
+ new = yield AddressBookObject.objectWithID(addressbook, resourceID) # avoids object cache
+ result.append(new)
returnValue(result)
Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql.py 2013-03-18 19:57:28 UTC (rev 10944)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql.py 2013-03-18 22:33:22 UTC (rev 10945)
@@ -111,6 +111,8 @@
EADDRESSBOOKTYPE : "CardDAV",
}
+
+
class CommonDataStore(Service, object):
"""
Shared logic for SQL-based data stores, between calendar and addressbook
@@ -2451,6 +2453,8 @@
Maybe notify changed. (Overridden in NotificationCollection.)
"""
+
+
class SharingMixIn(object):
"""
Common class for CommonHomeChild and AddressBookObject
@@ -2883,6 +2887,7 @@
)
+
class CommonHomeChild(LoggingMixIn, FancyEqMixin, Memoizable, _SharedSyncLogic, HomeChildBase, SharingMixIn):
"""
Common ancestor class of AddressBooks and Calendars.
@@ -5121,6 +5126,7 @@
yield Update({column: after}, Where=where).on(txn)
+
class _AndNothing(object):
"""
Simple placeholder for iteratively generating a 'Where' clause; the 'And'
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20130318/3f4cd6bd/attachment-0001.html>
More information about the calendarserver-changes
mailing list