[CalendarServer-changes] [10710] CalendarServer/branches/users/gaya/sharedgroups/txdav
source_changes at macosforge.org
source_changes at macosforge.org
Tue Feb 12 19:10:21 PST 2013
Revision: 10710
http://trac.calendarserver.org//changeset/10710
Author: gaya at apple.com
Date: 2013-02-12 19:10:20 -0800 (Tue, 12 Feb 2013)
Log Message:
-----------
Fix multiple problems in group sharing
Modified Paths:
--------------
CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/server/serverinfo.xml
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/server/serverinfo.xml
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/server/serverinfo.xml 2013-02-13 01:56:19 UTC (rev 10709)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/server/serverinfo.xml 2013-02-13 03:10:20 UTC (rev 10710)
@@ -755,7 +755,7 @@
<!-- group name-->
<substitution>
<key>$i18nname:</key>
- <value>まだ</value>
+ <value>まだ</value>
</substitution>
<!-- password -->
<substitution>
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-13 01:56:19 UTC (rev 10709)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CardDAV/sharing-addressbooks.xml 2013-02-13 03:10:20 UTC (rev 10710)
@@ -542,11 +542,10 @@
</verify>
</request>
</test>
- </test-suite>
- <test-suite name='Share main address book' ignore='no'>
- <test name='1' ignore='no'>
+ </test-suite><test-suite name="Share main address book" ignore="no">
+ <test name="1" ignore="no">
<description>POST invitation</description>
- <request print-response='no'>
+ <request print-response="no">
<method>POST</method>
<ruri>$addressbookpath1:/</ruri>
<data>
@@ -558,13 +557,13 @@
</verify>
</request>
</test>
- <test name='2' ignore='no'>
+ <test name="2" ignore="no">
<description>Check Sharee notification collection</description>
- <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response="no">
<method>WAITCOUNT 1</method>
<ruri>$notificationpath2:/</ruri>
</request>
- <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response="no">
<method>GETNEW</method>
<ruri>$notificationpath2:/</ruri>
<verify>
@@ -585,12 +584,12 @@
</grabelement>
</request>
</test>
- <test name='3' ignore='no'>
+ <test name="3" ignore="no">
<description>Sharee replies ACCEPTED</description>
- <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response="no">
<method>POST</method>
<ruri>$addressbookhome2:/</ruri>
- <data substitutions='yes'>
+ <data substitutions="yes">
<content-type>application/xml; charset=utf-8</content-type>
<filepath>Resource/CardDAV/sharing/addressbooks/main/3.xml</filepath>
</data>
@@ -603,9 +602,9 @@
</grabelement>
</request>
</test>
- <test name='4' ignore='no'>
+ <test name="4" ignore="no">
<description>Shared address book exists</description>
- <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response="no">
<method>PROPFIND</method>
<ruri>$sharedaddressbook:/</ruri>
<header>
@@ -635,9 +634,9 @@
</verify>
</request>
</test>
- <test name='5' ignore='no'>
+ <test name="5" ignore="no">
<description>Sharee creates vcard</description>
- <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response="no">
<method>PUT</method>
<ruri>$sharedaddressbook:/1.vcf</ruri>
<data>
@@ -649,9 +648,9 @@
</verify>
</request>
</test>
- <test name='6' ignore='no'>
+ <test name="6" ignore="no">
<description>Sharer sees vcard</description>
- <request print-response='no'>
+ <request print-response="no">
<method>GET</method>
<ruri>$addressbookpath1:/1.vcf</ruri>
<verify>
@@ -663,9 +662,9 @@
</verify>
</request>
</test>
- <test name='7' ignore='no'>
+ <test name="7" ignore="no">
<description>Sharer changes vcard</description>
- <request print-response='no'>
+ <request print-response="no">
<method>PUT</method>
<ruri>$addressbookpath1:/1.vcf</ruri>
<data>
@@ -677,9 +676,9 @@
</verify>
</request>
</test>
- <test name='8' ignore='no'>
+ <test name="8" ignore="no">
<description>Sharee sees changed vcard</description>
- <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response="no">
<method>GET</method>
<ruri>$sharedaddressbook:/1.vcf</ruri>
<verify>
@@ -691,9 +690,9 @@
</verify>
</request>
</test>
- <test name='9' ignore='no'>
+ <test name="9" ignore="no">
<description>Sharer creates vcard</description>
- <request print-response='no'>
+ <request print-response="no">
<method>PUT</method>
<ruri>$addressbookpath1:/2.vcf</ruri>
<data>
@@ -705,9 +704,9 @@
</verify>
</request>
</test>
- <test name='10' ignore='no'>
+ <test name="10" ignore="no">
<description>Sharee sees new vcard</description>
- <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response="no">
<method>GET</method>
<ruri>$sharedaddressbook:/2.vcf</ruri>
<verify>
@@ -719,9 +718,9 @@
</verify>
</request>
</test>
- <test name='11' ignore='no'>
+ <test name="11" ignore="no">
<description>Sharee changes vcard</description>
- <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response="no">
<method>PUT</method>
<ruri>$sharedaddressbook:/2.vcf</ruri>
<data>
@@ -733,9 +732,9 @@
</verify>
</request>
</test>
- <test name='12' ignore='no'>
+ <test name="12" ignore="no">
<description>Sharer sees changed event</description>
- <request print-response='no'>
+ <request print-response="no">
<method>GET</method>
<ruri>$addressbookpath1:/2.vcf</ruri>
<verify>
@@ -747,9 +746,9 @@
</verify>
</request>
</test>
- <test name='12.1' ignore='no'>
+ <test name="12.1" ignore="no">
<description>Sharee sees group with shared address book members</description>
- <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response="no">
<method>GET</method>
<ruri>$sharedaddressbook:/addressbook.vcf</ruri>
<verify>
@@ -765,9 +764,9 @@
</verify>
</request>
</test>
- <test name='12.2' ignore='no'>
+ <test name="12.2" ignore="no">
<description>Sharee cannot delete special group</description>
- <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response="no">
<method>DELETE</method>
<ruri>$sharedaddressbook:/addressbook.vcf</ruri>
<verify>
@@ -779,9 +778,9 @@
</verify>
</request>
</test>
- <test name='13' ignore='no'>
+ <test name="13" ignore="no">
<description>Unshare main address book</description>
- <request print-response='no'>
+ <request print-response="no">
<method>POST</method>
<ruri>$addressbookpath1:/</ruri>
<data>
@@ -797,13 +796,13 @@
</verify>
</request>
</test>
- <test name='14' ignore='no'>
+ <test name="14" ignore="no">
<description>Check Sharee notification collection and delete invite-deleted</description>
- <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response="no">
<method>WAITCOUNT 1</method>
<ruri>$notificationpath2:/</ruri>
</request>
- <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response="no">
<method>GETNEW</method>
<ruri>$notificationpath2:/</ruri>
<verify>
@@ -819,14 +818,14 @@
</arg>
</verify>
</request>
- <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response="no">
<method>DELETE</method>
<ruri>$</ruri>
</request>
</test>
- <test name='15' ignore='no'>
+ <test name="15" ignore="no">
<description>No more shared addressbook</description>
- <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response="no">
<method>PROPFIND</method>
<ruri>$sharedaddressbook:/</ruri>
<header>
@@ -854,8 +853,9 @@
</request>
</test>
</test-suite>
+
- <test-suite name='Share group' ignore='yes'>
+ <test-suite name='Share group' ignore='no'>
<test name='1' ignore='no'>
<description>Sharee create 2 persons and a group</description>
<request print-response='no'>
@@ -927,11 +927,11 @@
</test>
<test name='4' ignore='no'>
<description>Check Sharee notification collection</description>
- <request user="$userid2:" pswd="$pswd2:" print-request='no' print-response='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>WAITCOUNT 1</method>
<ruri>$notificationpath2:/</ruri>
</request>
- <request user="$userid2:" pswd="$pswd2:" print-request='no' print-response='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>GETNEW</method>
<ruri>$notificationpath2:/</ruri>
<verify>
@@ -954,7 +954,7 @@
</test>
<test name='5' ignore='no'>
<description>Sharee replies ACCEPTED</description>
- <request user="$userid2:" pswd="$pswd2:" print-request='no' print-response='no'>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>POST</method>
<ruri>$addressbookhome2:/</ruri>
<data substitutions='yes'>
@@ -966,15 +966,15 @@
</verify>
<grabelement>
<name>{DAV:}href</name>
- <variable>$sharedaddressbook:</variable>
+ <variable>$sharedgroup:</variable>
</grabelement>
</request>
</test>
<test name='6' ignore='no'>
- <description>Sharee sees shared group as address book</description>
+ <description>Sharee sees shared address book</description>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>PROPFIND</method>
- <ruri>$sharedaddressbook:/</ruri>
+ <ruri>$addressbookhome2:/$userid1:/</ruri>
<header>
<name>Depth</name>
<value>0</value>
@@ -1006,7 +1006,7 @@
<description>Sharee sees shared group vcard</description>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>GET</method>
- <ruri>$sharedaddressbook:/3.vcf</ruri>
+ <ruri>$sharedgroup:</ruri>
<verify>
<callback>addressDataMatch</callback>
<arg>
@@ -1016,11 +1016,11 @@
</verify>
</request>
</test>
- <test name='6b' ignore='no'>
+ <test name='6b' ignore='yes'>
<description>Sharee cannot delete shared group vcard</description>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>DELETE</method>
- <ruri>$sharedaddressbook:/3.vcf</ruri>
+ <ruri>$sharedgroup:</ruri>
<verify>
<callback>statusCode</callback>
<arg>
@@ -1034,7 +1034,7 @@
<description>Sharee creates group vcard with unknown member UID</description>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>PUT</method>
- <ruri>$sharedaddressbook:/4.vcf</ruri>
+ <ruri>$addressbookhome2:/$userid1:/4.vcf</ruri>
<data>
<content-type>text/vcard; charset=utf-8</content-type>
<filepath>Resource/CardDAV/sharing/addressbooks/group/8.vcf</filepath>
@@ -1052,7 +1052,7 @@
<description>Sharee creates group vcard with member UID in ab but not in group</description>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>PUT</method>
- <ruri>$sharedaddressbook:/4.vcf</ruri>
+ <ruri>$addressbookhome2:/$userid1:/4.vcf</ruri>
<data>
<content-type>text/vcard; charset=utf-8</content-type>
<filepath>Resource/CardDAV/sharing/addressbooks/group/9.vcf</filepath>
@@ -1070,7 +1070,7 @@
<description>Sharee creates vcard</description>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>PUT</method>
- <ruri>$sharedaddressbook:/4.vcf</ruri>
+ <ruri>$addressbookhome2:/$userid1:/4.vcf</ruri>
<data>
<content-type>text/vcard; charset=utf-8</content-type>
<filepath>Resource/CardDAV/sharing/addressbooks/group/10.vcf</filepath>
@@ -1123,7 +1123,7 @@
<description>Sharee sees changed vcard</description>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>GET</method>
- <ruri>$sharedaddressbook:/4.vcf</ruri>
+ <ruri>$addressbookhome2:/$userid1:/4.vcf</ruri>
<verify>
<callback>addressDataMatch</callback>
<arg>
@@ -1151,7 +1151,7 @@
<description>Sharee sees new vcards</description>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>GET</method>
- <ruri>$sharedaddressbook:/5.vcf</ruri>
+ <ruri>$addressbookhome2:/$userid1:/5.vcf</ruri>
<verify>
<callback>addressDataMatch</callback>
<arg>
@@ -1162,7 +1162,7 @@
</request>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>GET</method>
- <ruri>$sharedaddressbook:/2.vcf</ruri>
+ <ruri>$addressbookhome2:/$userid1:/2.vcf</ruri>
<verify>
<callback>addressDataMatch</callback>
<arg>
@@ -1173,7 +1173,7 @@
</request>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>GET</method>
- <ruri>$sharedaddressbook:/1.vcf</ruri>
+ <ruri>$addressbookhome2:/$userid1:/1.vcf</ruri>
<verify>
<callback>addressDataMatch</callback>
<arg>
@@ -1187,7 +1187,7 @@
<description>Sharee removes vCard from subgroup</description>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>PUT</method>
- <ruri>$sharedaddressbook:/5.vcf</ruri>
+ <ruri>$addressbookhome2:/$userid1:/5.vcf</ruri>
<data>
<content-type>text/vcard; charset=utf-8</content-type>
<filepath>Resource/CardDAV/sharing/addressbooks/group/14.vcf</filepath>
@@ -1201,7 +1201,7 @@
<description>Sharee cannot access removed sub group member</description>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>GET</method>
- <ruri>$sharedaddressbook:/1.vcf</ruri>
+ <ruri>$addressbookhome2:/$userid1:/1.vcf</ruri>
<verify>
<callback>statusCode</callback>
<arg>
@@ -1240,7 +1240,7 @@
<description>Sharee deletes vCard in subgroup</description>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>DELETE</method>
- <ruri>$sharedaddressbook:/2.vcf</ruri>
+ <ruri>$addressbookhome2:/$userid1:/2.vcf</ruri>
<verify>
<callback>statusCode</callback>
</verify>
@@ -1316,7 +1316,7 @@
<description>No more shared addressbook</description>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>PROPFIND</method>
- <ruri>$sharedaddressbook:/</ruri>
+ <ruri>$addressbookhome2:/$userid1:/</ruri>
<header>
<name>Depth</name>
<value>0</value>
@@ -1346,6 +1346,7 @@
<end>
<request user="$useradmin:" pswd="$pswdadmin:">
<method>DELETEALL</method>
+ <ruri>$addressbookpath1:/</ruri>
<ruri>$notificationpath1:/</ruri>
<ruri>$notificationpath2:/</ruri>
<ruri>$notificationpath3:/</ruri>
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/sharing.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/sharing.py 2013-02-13 01:56:19 UTC (rev 10709)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/sharing.py 2013-02-13 03:10:20 UTC (rev 10710)
@@ -546,7 +546,7 @@
if not self.exists():
returnValue([])
- if not hasattr(self, "_invitations"):
+ if True:#not hasattr(self, "_invitations"):
acceptedHomeChildren = yield self._newStoreObject.asShared()
# remove direct shares (it might be OK not to remove these, but that would be different from legacy code)
@@ -685,11 +685,15 @@
pass
'''
+
# Generate invite XML
userid = "urn:uuid:" + invitation.shareeUID()
state = notificationState if notificationState else invitation.state()
summary = invitation.summary() if displayName is None else displayName
+
+ assert state != "DECLINED"
+
typeAttr = {'shared-type': self.sharedResourceType()}
xmltype = customxml.InviteNotification(**typeAttr)
xmldata = customxml.Notification(
Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py 2013-02-13 01:56:19 UTC (rev 10709)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/sql.py 2013-02-13 03:10:20 UTC (rev 10710)
@@ -471,6 +471,7 @@
if ownerHomeID not in ownerHomeIDToDataRowMap:
groupBindRow[0] = _BIND_MODE_WRITE
groupBindRow[3] = None # bindName
+ groupBindRow[4] = None # bindStatus
groupBindRow[5] = None # bindMessage
ownerHomeIDToDataRowMap[ownerHomeID] = groupBindRow
@@ -578,6 +579,7 @@
groupBindRow = groupBindRows[0]
groupBindRow[0] = _BIND_MODE_WRITE
groupBindRow[3] = None # bindName
+ groupBindRow[4] = None # bindStatus
groupBindRow[5] = None # bindMessage
groupBindRow.append(ownerHome._resourceID)
rows = [groupBindRow]
@@ -663,15 +665,20 @@
yield child.initFromStore()
returnValue(child)
else:
-
- groupBindRows = yield AddressBookObject._bindWithHomeIDAndAddressBookID.on(
+ # TODO: do one query
+ groupBindRows = yield AddressBookObject._invitedBindWithHomeIDAndAddressBookID.on(
home._txn, homeID=home._resourceID, addressbookID=resourceID
)
+ if not groupBindRows:
+ groupBindRows = yield AddressBookObject._acceptedBindWithHomeIDAndAddressBookID.on(
+ home._txn, homeID=home._resourceID, addressbookID=resourceID
+ )
if groupBindRows:
#bindMode, homeID, resourceID, bindName, bindStatus, bindMessage = groupBindRows[0] #@UnusedVariable
groupBindRow = groupBindRows[0]
groupBindRow[0] = _BIND_MODE_WRITE
groupBindRow[3] = None # bindName
+ groupBindRow[4] = None # bindStatus
groupBindRow[5] = None # bindMessage
rows = [groupBindRow]
@@ -735,7 +742,7 @@
def fullyShared(self):
- return bool(self._bindName)
+ return not self.owned() and self._bindStatus == _BIND_STATUS_ACCEPTED
@classmethod
@@ -845,6 +852,91 @@
@inlineCallbacks
+ def updateShare(self, shareeView, mode=None, status=None, message=None, name=None):
+ """
+ Update share mode, status, and message for a home child shared with
+ this (owned) L{CommonHomeChild}.
+
+ @param shareeView: The sharee home child that shares this.
+ @type shareeView: L{CommonHomeChild}
+
+ @param mode: The sharing mode; L{_BIND_MODE_READ} or
+ L{_BIND_MODE_WRITE} or None to not update
+ @type mode: L{str}
+
+ @param status: The sharing status; L{_BIND_STATUS_INVITED} or
+ L{_BIND_STATUS_ACCEPTED} or L{_BIND_STATUS_DECLINED} or
+ L{_BIND_STATUS_INVALID} or None to not update
+ @type status: L{str}
+
+ @param message: The proposed message to go along with the share, which
+ will be used as the default display name, or None to not update
+ @type message: L{str}
+
+ @param name: The bind resource name or None to not update
+ @type message: L{str}
+
+ @return: the name of the shared item in the sharee's home.
+ @rtype: a L{Deferred} which fires with a L{str}
+ """
+ # TODO: raise a nice exception if shareeView is not, in fact, a shared
+ # version of this same L{CommonHomeChild}
+
+ #remove None parameters, and substitute None for empty string
+ bind = self._bindSchema
+ columnMap = dict([(k, v if v else None)
+ for k, v in {bind.BIND_MODE:mode,
+ bind.BIND_STATUS:status,
+ bind.MESSAGE:message,
+ bind.RESOURCE_NAME:name}.iteritems() if v is not None])
+
+ if len(columnMap):
+
+ # count accepted
+ if status is not None:
+ previouslyAcceptedBinds = 1 if shareeView.fullyShared() else 0
+ previouslyAcceptedBinds += len((yield AddressBookObject._acceptedBindWithHomeIDAndAddressBookID.on(
+ self._txn, homeID=shareeView._home._resourceID, addressbookID=shareeView._resourceID
+ )))
+
+ #TODO: with bit of parameter wrangling, call shareWith() here instead.
+ sharedname = yield self._updateBindColumnsQuery(columnMap).on(
+ self._txn,
+ resourceID=self._resourceID, homeID=shareeView._home._resourceID
+ )
+
+ #update affected attributes
+ if mode is not None:
+ shareeView._bindMode = columnMap[bind.BIND_MODE]
+
+ if status is not None:
+ shareeView._bindStatus = columnMap[bind.BIND_STATUS]
+ if shareeView._bindStatus == _BIND_STATUS_ACCEPTED:
+ if 0 == previouslyAcceptedBinds:
+ yield shareeView._initSyncToken()
+ elif shareeView._bindStatus == _BIND_STATUS_DECLINED:
+ if 1 == previouslyAcceptedBinds:
+ shareeView._deletedSyncToken(sharedRemoval=True)
+ shareeView._home._children.pop(shareeView._name, None)
+
+
+ if message is not None:
+ shareeView._bindMessage = columnMap[bind.MESSAGE]
+
+ queryCacher = self._txn._queryCacher
+ if queryCacher:
+ cacheKey = queryCacher.keyForObjectWithName(shareeView._home._resourceID, shareeView._name)
+ queryCacher.invalidateAfterCommit(self._txn, cacheKey)
+
+ shareeView._name = sharedname[0][0]
+
+ # Must send notification to ensure cache invalidation occurs
+ yield self.notifyChanged()
+
+ returnValue(shareeView._name)
+
+
+ @inlineCallbacks
def asShared(self):
"""
Retrieve all the versions of this L{CommonHomeChild} as it is shared to
@@ -873,6 +965,7 @@
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
@@ -910,12 +1003,12 @@
returnValue([])
# get all accepted shared binds
- rows = yield self._invitedBindForResourceID.on(
- self._txn, resourceID=self._resourceID, homeID=self._home._resourceID
+ rows = yield self._unacceptedBindForResourceID.on(
+ self._txn, resourceID=self._resourceID
)
homeIDToBindRowMap = dict([(row[1], row) for row in rows])
- groupBindRows = yield AddressBookObject._invitedBindWithAddressBookID.on(
+ groupBindRows = yield AddressBookObject._unacceptedBindWithAddressBookID.on(
self._txn, addressbookID=self._resourceID
)
for groupBindRow in groupBindRows:
@@ -923,6 +1016,7 @@
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
@@ -958,33 +1052,32 @@
@return: a L{Deferred} which will fire with the previously-used name.
"""
+ resourceName = None
+
sharedAddressBook = yield shareeHome.addressbookWithName(self.shareeABName())
- if not sharedAddressBook:
- returnValue(None)
+ if sharedAddressBook:
- sharedRemoval = False
- if sharedAddressBook.fullyShared():
- groupIDs = yield sharedAddressBook.acceptedGroupIDs()
- sharedRemoval = not bool(len(groupIDs))
- if sharedRemoval:
- sharedAddressBook._deletedSyncToken(sharedRemoval=True)
+ sharedRemoval = False
+ if sharedAddressBook.fullyShared():
+ acceptedGroupBinds = len((yield AddressBookObject._acceptedBindWithHomeIDAndAddressBookID.on(
+ self._txn, homeID=sharedAddressBook._home._resourceID, addressbookID=sharedAddressBook._resourceID
+ )))
+ sharedRemoval = acceptedGroupBinds == 0
+ if sharedRemoval:
+ sharedAddressBook._deletedSyncToken(sharedRemoval=True)
+ shareeHome._children.pop(resourceName, None)
+ # Must send notification to ensure cache invalidation occurs
+ yield self.notifyChanged()
+
queryCacher = self._txn._queryCacher
if queryCacher:
cacheKey = queryCacher.keyForObjectWithName(shareeHome._resourceID, self.shareeABName())
queryCacher.invalidateAfterCommit(self._txn, cacheKey)
- rows = yield self._deleteBindWithResourceIDAndHomeID.on(self._txn, resourceID=self._resourceID,
+ yield self._deleteBindWithResourceIDAndHomeID.on(self._txn, resourceID=self._resourceID,
homeID=shareeHome._resourceID)
- resourceName = None
- if rows and sharedRemoval:
- resourceName = self.shareeABName()
- shareeHome._children.pop(resourceName, None)
-
- # Must send notification to ensure cache invalidation occurs
- yield self.notifyChanged()
-
returnValue(resourceName)
@@ -1005,6 +1098,10 @@
# super._objectText now contains the text as read of the database only,
# not including group member text
self._component = None
+ self._bindMode = None
+ self._bindStatus = None
+ self._bindMessage = None
+ self._bindName = None
super(AddressBookObject, self).__init__(addressbook, name, uid, resourceID)
@@ -1045,6 +1142,8 @@
# sharee cannot delete group representing shared address book
if self._resourceID == self._addressbook._resourceID:
raise DeleteOfGroupForSharedAddressBookNotAllowedError
+ elif self._bindName:
+ raise DeleteOfGroupForSharedAddressBookNotAllowedError
aboMembers = schema.ABO_MEMBERS
aboForeignMembers = schema.ABO_FOREIGN_MEMBERS
@@ -1165,8 +1264,8 @@
self._txn, uid=self._uid,
resourceIDs=allowedObjectIDs,)) if allowedObjectIDs else []
elif self._resourceID:
- invitedGroupIDs = yield self._addressbook.invitedGroupIDs()
- allowedObjectIDs = tuple(set(allowedObjectIDs) | set(invitedGroupIDs))
+ if self._resourceID not in allowedObjectIDs:
+ allowedObjectIDs = yield self._addressbook.invitedGroupIDs()
rows = (yield self._allColumnsWithResourceID.on(
self._txn, resourceID=self._resourceID,)) if (self._resourceID in allowedObjectIDs) else []
@@ -1650,44 +1749,11 @@
return self._addressbook.viewerHome()
- def shareMode(self):
- """
- @see: L{ICalendar.shareMode}
- """
- if hasattr(self, "_bindMode"):
- return self._bindMode
- else:
- return self._addressbook.shareMode()
-
-
- def shareStatus(self):
- """
- @see: L{ICalendar.shareStatus}
- """
- if hasattr(self, "_bindStatus"):
- return self._bindStatus
- else:
- return self._addressbook.shareStatus()
-
-
- def shareMessage(self):
- """
- @see: L{ICalendar.shareMessage}
- """
- if hasattr(self, "_bindMessage"):
- return self._bindMessage
- else:
- return self._addressbook.shareMessage()
-
-
def shareUID(self):
"""
@see: L{ICalendar.shareUID}
"""
- if hasattr(self, "_bindName"):
- return self._bindName
- else:
- return self._addressbook.shareUID()
+ return self._bindName
@classmethod
@@ -1747,8 +1813,7 @@
will be used as the default display name.
@type mode: L{str}
- @return: the name of the shared calendar in the new calendar home.
- @rtype: L{str}
+ @rtype: a L{Deferred} which fires with a L{ICalendar} if the sharee item
"""
yield self._shareWith(shareeHome, mode, status=status, message=message)
@@ -1806,15 +1871,15 @@
returnValue([])
# get all accepted shared binds
- groupBindRows = yield self._invitedBindForResourceID.on(
- self._txn, resourceID=self._resourceID, homeID=self._home._resourceID
+ 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.childWithID(self._addressbook._resourceID)
- new = yield addressbook.objectResourceWithID(resourceID)
+ new = yield AddressBookObject.objectWithID(addressbook, resourceID) # avoids object cache
result.append(new)
returnValue(result)
@@ -1844,34 +1909,33 @@
@return: a L{Deferred} which will fire with the previously-used name.
"""
+ resourceName = None
sharedAddressBook = yield shareeHome.addressbookWithName(self._addressbook.shareeABName())
- if not sharedAddressBook:
+ if sharedAddressBook:
returnValue(None)
- sharedRemoval = False
- if not sharedAddressBook.fullyShared():
- groupIDs = yield sharedAddressBook.acceptedGroupIDs()
- assert self._resourceID in groupIDs
- sharedRemoval = len(groupIDs) == 1
- if sharedRemoval:
- sharedAddressBook._deletedSyncToken(sharedRemoval=True)
+ sharedRemoval = False
+ if not sharedAddressBook.fullyShared():
+ acceptedGroupBinds = len((yield AddressBookObject._acceptedBindWithHomeIDAndAddressBookID.on(
+ self._txn, homeID=sharedAddressBook._home._resourceID, addressbookID=sharedAddressBook._resourceID
+ )))
+ sharedRemoval = acceptedGroupBinds == 1
+ if sharedRemoval:
+ sharedAddressBook._deletedSyncToken(sharedRemoval=True)
+ shareeHome._children.pop(resourceName, None)
+ # Must send notification to ensure cache invalidation occurs
+ yield self._addressbook.notifyChanged()
+
queryCacher = self._txn._queryCacher
if queryCacher:
cacheKey = queryCacher.keyForObjectWithName(shareeHome._resourceID, self._addressbook.shareeABName())
queryCacher.invalidateAfterCommit(self._txn, cacheKey)
- rows = yield self._deleteBindWithResourceIDAndHomeID.on(self._txn, resourceID=self._resourceID,
+ yield self._deleteBindWithResourceIDAndHomeID.on(self._txn, resourceID=self._resourceID,
homeID=shareeHome._resourceID)
- resourceName = None
- if rows and sharedRemoval:
- resourceName = rows[0][0]
- shareeHome._children.pop(resourceName, None)
- # Must send notification to ensure cache invalidation occurs
- yield self._addressbook.notifyChanged()
-
returnValue(resourceName)
@@ -1917,6 +1981,13 @@
if len(columnMap):
+ # count accepted
+ if status is not None:
+ previouslyAcceptedBinds = 1 if shareeView._addressbook.fullyShared() else 0
+ previouslyAcceptedBinds += len((yield AddressBookObject._acceptedBindWithHomeIDAndAddressBookID.on(
+ self._txn, homeID=shareeView._home._resourceID, addressbookID=shareeView._resourceID
+ )))
+
#TODO: with bit of parameter wrangling, call shareWith() here instead.
sharedname = yield self._updateBindColumnsQuery(columnMap).on(
self._txn,
@@ -1924,20 +1995,23 @@
)
#update affected attributes
- if mode:
+ if mode is not None:
shareeView._bindMode = columnMap[bind.BIND_MODE]
- if status:
+ if status is not None:
shareeView._bindStatus = columnMap[bind.BIND_STATUS]
if shareeView._bindStatus == _BIND_STATUS_ACCEPTED:
- yield shareeView._addressbook._initSyncToken()
+ if 0 == previouslyAcceptedBinds:
+ yield shareeView._addressbook._initSyncToken()
elif shareeView._bindStatus == _BIND_STATUS_DECLINED:
- shareeView._addressbook._deletedSyncToken(sharedRemoval=True)
- shareeView._home._children.pop(shareeView._addressbook._name, None)
+ if 1 == previouslyAcceptedBinds:
+ shareeView._addressbook._deletedSyncToken(sharedRemoval=True)
+ shareeView._home._children.pop(shareeView._addressbook._name, None)
- if message:
+ if message is not None:
shareeView._bindMessage = columnMap[bind.MESSAGE]
+ # safer to just invalidate in all cases rather than calculate when to invalidate
queryCacher = self._txn._queryCacher
if queryCacher:
cacheKey = queryCacher.keyForObjectWithName(shareeView._home._resourceID, shareeView._addressbook._name)
@@ -1964,13 +2038,13 @@
)
@classproperty
- def _invitedBindWithAddressBookID(cls): #@NoSelf
+ def _unacceptedBindWithAddressBookID(cls): #@NoSelf
bind = cls._bindSchema
abo = cls._objectSchema
return Select(
cls._bindColumns,
From=bind.join(abo),
- Where=(bind.BIND_STATUS == _BIND_STATUS_INVITED)
+ Where=(bind.BIND_STATUS != _BIND_STATUS_ACCEPTED)
.And(bind.RESOURCE_ID == abo.RESOURCE_ID)
.And(abo.ADDRESSBOOK_RESOURCE_ID == Parameter("addressbookID"))
)
Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql.py 2013-02-13 01:56:19 UTC (rev 10709)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql.py 2013-02-13 03:10:20 UTC (rev 10710)
@@ -2342,7 +2342,7 @@
@classproperty
- def _invitedBindForResourceID(cls): #@NoSelf
+ def _unacceptedBindForResourceID(cls): #@NoSelf
bind = cls._bindSchema
return cls._bindFor((bind.RESOURCE_ID == Parameter("resourceID"))
.And(bind.BIND_STATUS != _BIND_STATUS_ACCEPTED)
@@ -2443,8 +2443,7 @@
will be used as the default display name.
@type mode: L{str}
- @return: the name of the shared home child in the new home.
- @rtype: L{CommonHomeChild}
+ @rtype: a L{Deferred} which fires with a L{ICalendar} if the sharee item
"""
yield self._shareWith(shareeHome, mode, status=status, message=message)
@@ -2510,10 +2509,10 @@
)
#update affected attributes
- if mode:
+ if mode is not None:
shareeView._bindMode = columnMap[bind.BIND_MODE]
- if status:
+ if status is not None:
shareeView._bindStatus = columnMap[bind.BIND_STATUS]
if shareeView._bindStatus == _BIND_STATUS_ACCEPTED:
yield shareeView._initSyncToken()
@@ -2521,7 +2520,7 @@
shareeView._deletedSyncToken(sharedRemoval=True)
shareeView._home._children.pop(shareeView._name, None)
- if message:
+ if message is not None:
shareeView._bindMessage = columnMap[bind.MESSAGE]
queryCacher = self._txn._queryCacher
@@ -2562,6 +2561,8 @@
@return: a L{Deferred} which will fire with the previously-used name.
"""
+ resourceName = None
+
#remove sync tokens
shareeChildren = yield shareeHome.children()
for shareeChild in shareeChildren:
@@ -2573,19 +2574,18 @@
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
- rows = yield self._deleteBindWithResourceIDAndHomeID.on(self._txn, resourceID=self._resourceID,
+ # delete binds including invites
+ yield self._deleteBindWithResourceIDAndHomeID.on(self._txn, resourceID=self._resourceID,
homeID=shareeHome._resourceID)
- resourceName = None
- if rows:
- resourceName = rows[0][0]
- shareeHome._children.pop(resourceName, None)
-
- # Must send notification to ensure cache invalidation occurs
- yield self.notifyChanged()
-
returnValue(resourceName)
@inlineCallbacks
@@ -2640,7 +2640,7 @@
if not self.owned():
returnValue([])
- rows = yield self._invitedBindForResourceID.on(
+ rows = yield self._unacceptedBindForResourceID.on(
self._txn, resourceID=self._resourceID,
)
cls = self._home._childClass # for ease of grepping...
@@ -3351,11 +3351,11 @@
if resourceID in self._objects:
return succeed(self._objects[resourceID])
else:
- return self._makeObjectResource(resourceID=resourceID, cache=False)
+ return self._makeObjectResource(resourceID=resourceID)
@inlineCallbacks
- def _makeObjectResource(self, name=None, uid=None, resourceID=None, cache=True):
+ def _makeObjectResource(self, name=None, uid=None, resourceID=None):
"""
We create the empty object first then have it initialize itself from the
store.
@@ -3368,7 +3368,7 @@
objectResource = (
yield self._objectResourceClass.objectWithName(self, name, uid)
)
- if objectResource and cache:
+ if objectResource:
self._objects[objectResource.name()] = objectResource
self._objects[objectResource.uid()] = objectResource
self._objects[objectResource._resourceID] = objectResource
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20130212/185700b1/attachment-0001.html>
More information about the calendarserver-changes
mailing list