[CalendarServer-changes] [13651] CalendarServer/branches/release/CalendarServer-5.3-dev
source_changes at macosforge.org
source_changes at macosforge.org
Wed Jun 18 11:06:15 PDT 2014
Revision: 13651
http://trac.calendarserver.org//changeset/13651
Author: cdaboo at apple.com
Date: 2014-06-18 11:06:15 -0700 (Wed, 18 Jun 2014)
Log Message:
-----------
Hide missing or invalid proxyFors. Fix some sharing issues related to missing or invalid users.
Modified Paths:
--------------
CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/directory/principal.py
CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/directory/test/accounts.xml
CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/directory/test/augments.xml
CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/directory/test/test_proxyprincipalmembers.py
CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/sharing.py
CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/test/test_sharing.py
CalendarServer/branches/release/CalendarServer-5.3-dev/txdav/common/datastore/sql.py
Modified: CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/directory/principal.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/directory/principal.py 2014-06-17 21:55:29 UTC (rev 13650)
+++ CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/directory/principal.py 2014-06-18 18:06:15 UTC (rev 13651)
@@ -923,7 +923,7 @@
@inlineCallbacks
- def proxyFor(self, read_write, resolve_memberships=True):
+ def proxyFor(self, read_write, resolve_memberships=True, ignoreDisabled=True):
proxyFors = set()
@@ -960,7 +960,7 @@
uids = set()
for principal in tuple(proxyFors):
- if principal.principalUID() in uids:
+ if principal.principalUID() in uids or (ignoreDisabled and not principal.record.enabledForCalendaring):
proxyFors.remove(principal)
else:
uids.add(principal.principalUID())
Modified: CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/directory/test/accounts.xml
===================================================================
--- CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/directory/test/accounts.xml 2014-06-17 21:55:29 UTC (rev 13650)
+++ CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/directory/test/accounts.xml 2014-06-18 18:06:15 UTC (rev 13651)
@@ -139,7 +139,7 @@
<member type="users">delegateviagroup</member>
</members>
</group>
- <user repeat="2">
+ <user repeat="3">
<uid>user%02d</uid>
<guid>user%02d</guid>
<password>%02duser</password>
Modified: CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/directory/test/augments.xml
===================================================================
--- CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/directory/test/augments.xml 2014-06-17 21:55:29 UTC (rev 13650)
+++ CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/directory/test/augments.xml 2014-06-18 18:06:15 UTC (rev 13651)
@@ -57,7 +57,7 @@
<enable-calendar>false</enable-calendar>
<enable-addressbook>false</enable-addressbook>
</record>
- <record repeat="2">
+ <record repeat="3">
<uid>user%02d</uid>
<enable>true</enable>
<enable-calendar>true</enable-calendar>
Modified: CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/directory/test/test_proxyprincipalmembers.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/directory/test/test_proxyprincipalmembers.py 2014-06-17 21:55:29 UTC (rev 13650)
+++ CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/directory/test/test_proxyprincipalmembers.py 2014-06-18 18:06:15 UTC (rev 13651)
@@ -504,3 +504,49 @@
DirectoryService.recordType_users, "delegator", "calendar-proxy-write",
("Occasional Delegate", "Delegate Via Group", "Delegate Group"),
)
+
+
+ @inlineCallbacks
+ def test_hideDisabledProxies(self):
+ """
+ Make sure users that are missing or not enabled for calendaring are removed
+ from the proxyFor list.
+ """
+
+ # Check proxies empty right now
+ principal01 = self._getPrincipalByShortName(self.directoryService.recordType_users, "user01")
+ self.assertTrue(len((yield principal01.proxyFor(False))) == 0)
+ self.assertTrue(len((yield principal01.proxyFor(True))) == 0)
+
+ principal02 = self._getPrincipalByShortName(self.directoryService.recordType_users, "user02")
+ self.assertTrue(len((yield principal02.proxyFor(False))) == 0)
+ self.assertTrue(len((yield principal02.proxyFor(True))) == 0)
+
+ principal03 = self._getPrincipalByShortName(self.directoryService.recordType_users, "user03")
+ self.assertTrue(len((yield principal03.proxyFor(False))) == 0)
+ self.assertTrue(len((yield principal03.proxyFor(True))) == 0)
+
+ # Make user01 a read-only proxy for user02 and user03
+ yield self._addProxy(principal02, "calendar-proxy-read", principal01)
+ yield self._addProxy(principal03, "calendar-proxy-read", principal01)
+
+ self.assertTrue(len((yield principal01.proxyFor(False))) == 2)
+ self.assertTrue(len((yield principal01.proxyFor(True))) == 0)
+
+ # Now disable user02
+ principal02.record.enabledForCalendaring = False
+
+ self.assertTrue(len((yield principal01.proxyFor(False))) == 1)
+ self.assertTrue(len((yield principal01.proxyFor(True))) == 0)
+
+ # Now enable user02
+ principal02.record.enabledForCalendaring = True
+
+ self.assertTrue(len((yield principal01.proxyFor(False))) == 2)
+ self.assertTrue(len((yield principal01.proxyFor(True))) == 0)
+
+ # Now remove user02
+ self.directoryService._removeFromIndex(principal02.record)
+
+ self.assertTrue(len((yield principal01.proxyFor(False))) == 1)
+ self.assertTrue(len((yield principal01.proxyFor(True))) == 0)
Modified: CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/sharing.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/sharing.py 2014-06-17 21:55:29 UTC (rev 13650)
+++ CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/sharing.py 2014-06-18 18:06:15 UTC (rev 13651)
@@ -103,12 +103,16 @@
invitations = yield original.validateInvites(request)
ownerPrincipal = (yield original.ownerPrincipal(request))
- # FIXME: use urn:uuid in all cases
- if self.isCalendarCollection():
- owner = ownerPrincipal.principalURL()
+ if ownerPrincipal is None:
+ owner = "invalid"
+ ownerCN = "Invalid"
else:
- owner = "urn:uuid:" + ownerPrincipal.principalUID()
- ownerCN = ownerPrincipal.displayName()
+ # FIXME: use urn:uuid in all cases
+ if self.isCalendarCollection():
+ owner = ownerPrincipal.principalURL()
+ else:
+ owner = "urn:uuid:" + ownerPrincipal.principalUID()
+ ownerCN = ownerPrincipal.displayName()
returnValue(customxml.Invite(
customxml.Organizer(
@@ -315,7 +319,7 @@
access control mechanism has dictate the home should no longer have
any access at all.
"""
- if self._share.direct():
+ if self._share is not None and self._share.direct():
ownerUID = self._share.ownerUID()
owner = self.principalForUID(ownerUID)
if owner.record.recordType == WikiDirectoryService.recordType_wikis:
@@ -482,14 +486,17 @@
"""
# assert request
invitations = yield self._allInvitations()
+ adjusted_invitations = []
for invitation in invitations:
if invitation.status() != _BIND_STATUS_INVALID:
if not (yield self.validUserIDForShare("urn:uuid:" + invitation.shareeUID(), request)):
# FIXME: temporarily disable this to deal with flaky directory
#yield self._updateInvitation(invitation, status=_BIND_STATUS_INVALID)
self.log.error("Invalid sharee detected: {uid}", uid=invitation.shareeUID())
+ invitation = invitation._replace(status=_BIND_STATUS_INVALID)
+ adjusted_invitations.append(invitation)
- returnValue(invitations)
+ returnValue(adjusted_invitations)
def inviteUserToShare(self, userid, cn, ace, summary, request):
@@ -648,15 +655,19 @@
@inlineCallbacks
def uninviteSingleUserFromShare(self, userid, aces, request): #@UnusedVariable
- # Cancel invites - we'll just use whatever userid we are given
+ # Cancel invites - we'll just use whatever userid we are given. However, if we
+ # cannot find a matching principal, try to extract the uid from the userid
+ # and use that (to allow invalid principals to be removed).
sharee = self.principalForCalendarUserAddress(userid)
- if not sharee:
+ if sharee is not None:
+ uid = sharee.principalUID()
+ elif userid.startswith("urn:uuid:"):
+ uid = userid[9:]
+ else:
returnValue(False)
- shareeUID = sharee.principalUID()
-
- invitation = yield self._invitationForShareeUID(shareeUID)
+ invitation = yield self._invitationForShareeUID(uid)
if invitation:
result = (yield self.uninviteFromShare(invitation, request))
else:
@@ -1026,8 +1037,8 @@
L{SharedHomeMixin} is a I{sharee}'s view of a shared calendar object,
associate it with a L{Share}.
"""
- share = yield self._shareForStoreObject(child._newStoreObject, request)
- if share:
+ if child._newStoreObject is not None and not child._newStoreObject.owned():
+ share = yield self._shareForStoreObject(child._newStoreObject, request)
child.setShare(share)
access = yield child._checkAccessControl()
if access is None:
Modified: CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/test/test_sharing.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/test/test_sharing.py 2014-06-17 21:55:29 UTC (rev 13650)
+++ CalendarServer/branches/release/CalendarServer-5.3-dev/twistedcaldav/test/test_sharing.py 2014-06-18 18:06:15 UTC (rev 13651)
@@ -51,6 +51,12 @@
+class FakeRequest(object):
+ def locateResource(self, url):
+ return succeed(None)
+
+
+
class FakeHome(object):
def removeShareByUID(self, request, uid):
pass
@@ -171,8 +177,8 @@
that marks any principal without 'bogus' in its name.
"""
result = principalForCalendarUserAddress(resourceSelf, userid)
- if result is None:
- return result
+ if result is None or userid[9:] in result.invalid_names:
+ return None
return result.principalURL()
@patched
@@ -221,8 +227,8 @@
@inlineCallbacks
- def _doPOSTSharerAccept(self, body, resultcode=responsecode.OK):
- request = SimpleStoreRequest(self, "POST", "/calendars/__uids__/user02/", content=body, authid="user02")
+ def _doPOSTSharerAccept(self, body, resultcode=responsecode.OK, sharer="user02"):
+ request = SimpleStoreRequest(self, "POST", "/calendars/__uids__/{}/".format(sharer), content=body, authid=sharer)
request.headers.setHeader("content-type", MimeType("text", "xml"))
response = yield self.send(request)
response = IResponse(response)
@@ -252,12 +258,22 @@
return None
+ def _getUIDElementValues(self, xml):
+
+ results = {}
+ for user in xml.children:
+ href = str(user.childOfType(davxml.HRef))
+ uid = str(user.childOfType(customxml.UID))
+ results[href] = uid
+ return results
+
+
def _clearUIDElementValue(self, xml):
for user in xml.children:
- for element in user.children:
- if type(element) == customxml.UID:
- element.children[0].data = ""
+ uid = user.childOfType(customxml.UID)
+ if uid is not None:
+ uid.children[0].data = ""
return xml
@@ -717,25 +733,23 @@
)
))
- self.resource.validUserIDForShare = lambda userid, request: None
- self.resource.principalForCalendarUserAddress = lambda cuaddr: None
- self.resource.principalForUID = lambda principalUID: None
+ self.patch(FakePrincipal, "invalid_names", set(("user02",)))
propInvite = (yield self.resource.readProperty(customxml.Invite, None))
self.assertEquals(self._clearUIDElementValue(propInvite), customxml.Invite(
customxml.InviteUser(
customxml.UID.fromString(""),
davxml.HRef.fromString("urn:uuid:user02"),
- customxml.CommonName.fromString("user02"),
+ customxml.CommonName.fromString("USER02"),
customxml.InviteAccess(customxml.ReadWriteAccess()),
- customxml.InviteStatusNoResponse(),
+ customxml.InviteStatusInvalid(),
)
))
yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
<CS:share xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/">
<CS:remove>
- <D:href>mailto:user02 at example.com</D:href>
+ <D:href>urn:uuid:user02</D:href>
</CS:remove>
</CS:share>
""")
@@ -828,7 +842,7 @@
@inlineCallbacks
- def test_POSTDowngradeWithDisabledInvitee(self):
+ def test_POSTDowngradeWithMissingInvitee(self):
yield self.resource.upgradeToShare()
@@ -858,7 +872,7 @@
@inlineCallbacks
- def test_POSTRemoveWithDisabledInvitee(self):
+ def test_POSTRemoveWithMissingInvitee(self):
yield self.resource.upgradeToShare()
@@ -888,7 +902,7 @@
yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
<CS:share xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/">
<CS:remove>
- <D:href>mailto:user02 at example.com</D:href>
+ <D:href>urn:uuid:user02</D:href>
</CS:remove>
</CS:share>
""")
@@ -951,3 +965,252 @@
resource = (yield self._getResourceSharer(href))
self.assertFalse(resource.exists())
+
+
+ @inlineCallbacks
+ def test_POSTShareeRemoveWithMissingSharer(self):
+
+ yield self.resource.upgradeToShare()
+
+ yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
+ <CS:share xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/">
+ <CS:set>
+ <D:href>mailto:user02 at example.com</D:href>
+ <CS:summary>My Shared Calendar</CS:summary>
+ <CS:read-write/>
+ </CS:set>
+ </CS:share>
+ """)
+
+ propInvite = (yield self.resource.readProperty(customxml.Invite, None))
+ uid = self._getUIDElementValue(propInvite)
+ self.assertEquals(self._clearUIDElementValue(propInvite), customxml.Invite(
+ customxml.InviteUser(
+ customxml.UID.fromString(""),
+ davxml.HRef.fromString("urn:uuid:user02"),
+ customxml.CommonName.fromString("USER02"),
+ customxml.InviteAccess(customxml.ReadWriteAccess()),
+ customxml.InviteStatusNoResponse(),
+ ),
+ ))
+
+ result = (yield self._doPOSTSharerAccept("""<?xml version='1.0' encoding='UTF-8'?>
+ <invite-reply xmlns='http://calendarserver.org/ns/'>
+ <href xmlns='DAV:'>mailto:user01 at example.com</href>
+ <invite-accepted/>
+ <hosturl>
+ <href xmlns='DAV:'>/calendars/__uids__/user01/calendar/</href>
+ </hosturl>
+ <in-reply-to>%s</in-reply-to>
+ <summary>The Shared Calendar</summary>
+ <common-name>USER02</common-name>
+ <first-name>user</first-name>
+ <last-name>02</last-name>
+ </invite-reply>
+ """ % (uid,))
+ )
+ href = self._getHRefElementValue(result) + "/"
+
+ self.patch(FakePrincipal, "invalid_names", set(("user01",)))
+
+ resource = (yield self._getResourceSharer(href))
+ yield resource.removeShareeResource(SimpleStoreRequest(self, "DELETE", href))
+
+ resource = (yield self._getResourceSharer(href))
+ self.assertFalse(resource.exists())
+
+
+ @inlineCallbacks
+ def test_shareeInviteWithDisabledSharer(self):
+
+ yield self.resource.upgradeToShare()
+
+ yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
+ <CS:share xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/">
+ <CS:set>
+ <D:href>mailto:user02 at example.com</D:href>
+ <CS:summary>My Shared Calendar</CS:summary>
+ <CS:read-write/>
+ </CS:set>
+ </CS:share>
+ """)
+
+ propInvite = (yield self.resource.readProperty(customxml.Invite, None))
+ uid = self._getUIDElementValue(propInvite)
+ self.assertEquals(self._clearUIDElementValue(propInvite), customxml.Invite(
+ customxml.InviteUser(
+ customxml.UID.fromString(""),
+ davxml.HRef.fromString("urn:uuid:user02"),
+ customxml.CommonName.fromString("USER02"),
+ customxml.InviteAccess(customxml.ReadWriteAccess()),
+ customxml.InviteStatusNoResponse(),
+ ),
+ ))
+
+ result = (yield self._doPOSTSharerAccept("""<?xml version='1.0' encoding='UTF-8'?>
+ <invite-reply xmlns='http://calendarserver.org/ns/'>
+ <href xmlns='DAV:'>mailto:user01 at example.com</href>
+ <invite-accepted/>
+ <hosturl>
+ <href xmlns='DAV:'>/calendars/__uids__/user01/calendar/</href>
+ </hosturl>
+ <in-reply-to>%s</in-reply-to>
+ <summary>The Shared Calendar</summary>
+ <common-name>USER02</common-name>
+ <first-name>user</first-name>
+ <last-name>02</last-name>
+ </invite-reply>
+ """ % (uid,))
+ )
+ href = self._getHRefElementValue(result) + "/"
+
+ self.patch(FakePrincipal, "invalid_names", set(("user01",)))
+
+ resource = (yield self._getResourceSharer(href))
+ propInvite = yield resource.inviteProperty(FakeRequest())
+ self.assertEquals(propInvite, None)
+
+
+ @inlineCallbacks
+ def test_shareeInviteWithMissingSharer(self):
+
+ yield self.resource.upgradeToShare()
+
+ yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
+ <CS:share xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/">
+ <CS:set>
+ <D:href>mailto:user02 at example.com</D:href>
+ <CS:summary>My Shared Calendar</CS:summary>
+ <CS:read-write/>
+ </CS:set>
+ </CS:share>
+ """)
+
+ propInvite = (yield self.resource.readProperty(customxml.Invite, None))
+ uid = self._getUIDElementValue(propInvite)
+ self.assertEquals(self._clearUIDElementValue(propInvite), customxml.Invite(
+ customxml.InviteUser(
+ customxml.UID.fromString(""),
+ davxml.HRef.fromString("urn:uuid:user02"),
+ customxml.CommonName.fromString("USER02"),
+ customxml.InviteAccess(customxml.ReadWriteAccess()),
+ customxml.InviteStatusNoResponse(),
+ ),
+ ))
+
+ result = (yield self._doPOSTSharerAccept("""<?xml version='1.0' encoding='UTF-8'?>
+ <invite-reply xmlns='http://calendarserver.org/ns/'>
+ <href xmlns='DAV:'>mailto:user01 at example.com</href>
+ <invite-accepted/>
+ <hosturl>
+ <href xmlns='DAV:'>/calendars/__uids__/user01/calendar/</href>
+ </hosturl>
+ <in-reply-to>%s</in-reply-to>
+ <summary>The Shared Calendar</summary>
+ <common-name>USER02</common-name>
+ <first-name>user</first-name>
+ <last-name>02</last-name>
+ </invite-reply>
+ """ % (uid,))
+ )
+ href = self._getHRefElementValue(result) + "/"
+
+ self.patch(FakePrincipal, "invalid_names", set(("user01",)))
+
+ resource = (yield self._getResourceSharer(href))
+ propInvite = yield resource.inviteProperty(FakeRequest())
+ self.assertEquals(propInvite, None)
+
+
+ @inlineCallbacks
+ def test_hideInvalidSharers(self):
+
+ yield self.resource.upgradeToShare()
+
+ yield self._doPOST("""<?xml version="1.0" encoding="utf-8" ?>
+ <CS:share xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/">
+ <CS:set>
+ <D:href>mailto:user02 at example.com</D:href>
+ <CS:summary>My Shared Calendar</CS:summary>
+ <CS:read-write/>
+ </CS:set>
+ <CS:set>
+ <D:href>mailto:user03 at example.com</D:href>
+ <CS:summary>My Shared Calendar</CS:summary>
+ <CS:read-write/>
+ </CS:set>
+ </CS:share>
+ """)
+
+ propInvite = (yield self.resource.readProperty(customxml.Invite, None))
+ uids = self._getUIDElementValues(propInvite)
+ self.assertEquals(self._clearUIDElementValue(propInvite), customxml.Invite(
+ customxml.InviteUser(
+ customxml.UID.fromString(""),
+ davxml.HRef.fromString("urn:uuid:user02"),
+ customxml.CommonName.fromString("USER02"),
+ customxml.InviteAccess(customxml.ReadWriteAccess()),
+ customxml.InviteStatusNoResponse(),
+ ),
+ customxml.InviteUser(
+ customxml.UID.fromString(""),
+ davxml.HRef.fromString("urn:uuid:user03"),
+ customxml.CommonName.fromString("USER03"),
+ customxml.InviteAccess(customxml.ReadWriteAccess()),
+ customxml.InviteStatusNoResponse(),
+ ),
+ ))
+
+ yield self._doPOSTSharerAccept("""<?xml version='1.0' encoding='UTF-8'?>
+ <invite-reply xmlns='http://calendarserver.org/ns/'>
+ <href xmlns='DAV:'>mailto:user01 at example.com</href>
+ <invite-accepted/>
+ <hosturl>
+ <href xmlns='DAV:'>/calendars/__uids__/user01/calendar/</href>
+ </hosturl>
+ <in-reply-to>%s</in-reply-to>
+ <summary>The Shared Calendar</summary>
+ <common-name>USER02</common-name>
+ <first-name>user</first-name>
+ <last-name>02</last-name>
+ </invite-reply>
+ """ % (uids["urn:uuid:user02"],))
+
+ yield self._doPOSTSharerAccept(
+ """<?xml version='1.0' encoding='UTF-8'?>
+ <invite-reply xmlns='http://calendarserver.org/ns/'>
+ <href xmlns='DAV:'>mailto:user01 at example.com</href>
+ <invite-accepted/>
+ <hosturl>
+ <href xmlns='DAV:'>/calendars/__uids__/user01/calendar/</href>
+ </hosturl>
+ <in-reply-to>%s</in-reply-to>
+ <summary>The Shared Calendar</summary>
+ <common-name>USER03</common-name>
+ <first-name>user</first-name>
+ <last-name>03</last-name>
+ </invite-reply>
+ """ % (uids["urn:uuid:user03"],),
+ sharer="user03"
+ )
+
+ self.patch(FakePrincipal, "invalid_names", set(("user02",)))
+
+ resource = yield self._getResource()
+ propInvite = yield resource.inviteProperty(None)
+ self.assertEquals(self._clearUIDElementValue(propInvite), customxml.Invite(
+ customxml.InviteUser(
+ customxml.UID.fromString(""),
+ davxml.HRef.fromString("urn:uuid:user02"),
+ customxml.CommonName.fromString("USER02"),
+ customxml.InviteAccess(customxml.ReadWriteAccess()),
+ customxml.InviteStatusInvalid(),
+ ),
+ customxml.InviteUser(
+ customxml.UID.fromString(""),
+ davxml.HRef.fromString("urn:uuid:user03"),
+ customxml.CommonName.fromString("USER03"),
+ customxml.InviteAccess(customxml.ReadWriteAccess()),
+ customxml.InviteStatusAccepted(),
+ ),
+ ))
Modified: CalendarServer/branches/release/CalendarServer-5.3-dev/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/branches/release/CalendarServer-5.3-dev/txdav/common/datastore/sql.py 2014-06-17 21:55:29 UTC (rev 13650)
+++ CalendarServer/branches/release/CalendarServer-5.3-dev/txdav/common/datastore/sql.py 2014-06-18 18:06:15 UTC (rev 13651)
@@ -2740,6 +2740,27 @@
)
+ def _replace(self, status):
+ """
+ Create a copy of this invitation with the status changed to the specified value.
+
+ @param status: the new status value
+ @type status: L{int}
+ """
+ return SharingInvitation(
+ self._uid,
+ self._owner_uid,
+ self._owner_rid,
+ self._sharee_uid,
+ self._sharee_rid,
+ self._resource_id,
+ self._resource_name,
+ self._mode,
+ status,
+ self._summary,
+ )
+
+
def uid(self):
"""
This maps to the resource name in the bind table, the "bind name". This is used as the "uid"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20140618/fd8650a0/attachment-0001.html>
More information about the calendarserver-changes
mailing list