[CalendarServer-changes] [7295] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Thu Apr 7 11:30:27 PDT 2011
Revision: 7295
http://trac.macosforge.org/projects/calendarserver/changeset/7295
Author: cdaboo at apple.com
Date: 2011-04-07 11:30:26 -0700 (Thu, 07 Apr 2011)
Log Message:
-----------
Fix sharing of multiple items to the same user.
Modified Paths:
--------------
CalendarServer/trunk/twistedcaldav/resource.py
CalendarServer/trunk/twistedcaldav/sharing.py
CalendarServer/trunk/twistedcaldav/storebridge.py
CalendarServer/trunk/txdav/common/datastore/sql_legacy.py
Modified: CalendarServer/trunk/twistedcaldav/resource.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/resource.py 2011-04-07 18:28:06 UTC (rev 7294)
+++ CalendarServer/trunk/twistedcaldav/resource.py 2011-04-07 18:30:26 UTC (rev 7295)
@@ -1178,7 +1178,14 @@
return principal
return None
+ def principalForUID(self, principalUID):
+ for principalCollection in self.principalCollections():
+ principal = principalCollection.principalForUID(principalUID)
+ if principal is not None:
+ return principal
+ return None
+
@inlineCallbacks
def vCard(self):
"""
Modified: CalendarServer/trunk/twistedcaldav/sharing.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/sharing.py 2011-04-07 18:28:06 UTC (rev 7294)
+++ CalendarServer/trunk/twistedcaldav/sharing.py 2011-04-07 18:30:26 UTC (rev 7295)
@@ -1,6 +1,6 @@
# -*- test-case-name: twistedcaldav.test.test_sharing -*-
##
-# Copyright (c) 2010 Apple Inc. All rights reserved.
+# Copyright (c) 2010-2011 Apple Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -102,12 +102,6 @@
@inlineCallbacks
- def removeUserFromInvite(self, userid, request):
- """ Remove a user from this shared calendar """
- returnValue((yield self.invitesDB().removeRecordForUserID(userid)))
-
-
- @inlineCallbacks
def changeUserInviteState(self, request, inviteUID, principalURL, state, summary=None):
shared = (yield self.isShared(request))
if not shared:
@@ -116,9 +110,10 @@
(customxml.calendarserver_namespace, "valid-request"),
"Invalid share",
))
-
+
+ principalUID = principalURL.split("/")[3]
record = yield self.invitesDB().recordForInviteUID(inviteUID)
- if record is None or record.principalURL != principalURL:
+ if record is None or record.principalUID != principalUID:
raise HTTPError(ErrorResponse(
responsecode.FORBIDDEN,
(customxml.calendarserver_namespace, "valid-request"),
@@ -480,13 +475,14 @@
returnValue(False)
# Look for existing invite and update its fields or create new one
- record = yield self.invitesDB().recordForPrincipalURL(principalURL)
+ principalUID = principalURL.split("/")[3]
+ record = yield self.invitesDB().recordForPrincipalUID(principalUID)
if record:
record.name = cn
record.access = inviteAccessMapFromXML[type(ace)]
record.summary = summary
else:
- record = Invite(str(uuid4()), userid, principalURL, cn, inviteAccessMapFromXML[type(ace)], "NEEDS-ACTION", summary)
+ record = Invite(str(uuid4()), userid, principalUID, cn, inviteAccessMapFromXML[type(ace)], "NEEDS-ACTION", summary)
# Send invite
yield self.sendInvite(record, request)
@@ -529,7 +525,7 @@
yield self.sendInvite(record, request)
# Remove from database
- yield self.invitesDB().removeRecordForUserID(record.userid)
+ yield self.invitesDB().removeRecordForInviteUID(record.inviteuid)
returnValue(True)
@@ -802,10 +798,10 @@
class Invite(object):
- def __init__(self, inviteuid, userid, principalURL, common_name, access, state, summary):
+ def __init__(self, inviteuid, userid, principalUID, common_name, access, state, summary):
self.inviteuid = inviteuid
self.userid = userid
- self.principalURL = principalURL
+ self.principalUID = principalUID
self.name = common_name
self.access = access
self.state = state
@@ -862,9 +858,9 @@
row = self._db_execute("select * from INVITE where USERID = :1", userid)
return self._makeRecord(row[0]) if row else None
- def recordForPrincipalURL(self, principalURL):
+ def recordForPrincipalUID(self, principalUID):
- row = self._db_execute("select * from INVITE where PRINCIPALURL = :1", principalURL)
+ row = self._db_execute("select * from INVITE where PRINCIPALUID = :1", principalUID)
return self._makeRecord(row[0]) if row else None
def recordForInviteUID(self, inviteUID):
@@ -874,15 +870,11 @@
def addOrUpdateRecord(self, record):
- self._db_execute("""insert or replace into INVITE (INVITEUID, USERID, PRINCIPALURL, NAME, ACCESS, STATE, SUMMARY)
+ self._db_execute("""insert or replace into INVITE (INVITEUID, USERID, PRINCIPALUID, NAME, ACCESS, STATE, SUMMARY)
values (:1, :2, :3, :4, :5, :6, :7)
- """, record.inviteuid, record.userid, record.principalURL, record.name, record.access, record.state, record.summary,
+ """, record.inviteuid, record.userid, record.principalUID, record.name, record.access, record.state, record.summary,
)
- def removeRecordForUserID(self, userid):
-
- self._db_execute("delete from INVITE where USERID = :1", userid)
-
def removeRecordForInviteUID(self, inviteUID):
self._db_execute("delete from INVITE where INVITEUID = :1", inviteUID)
@@ -913,7 +905,7 @@
# INVITE table is the primary table
# INVITEUID: UID for this invite
# USERID: identifier of invitee
- # PRINCIPALURL: principal-URL of invitee
+ # PRINCIPALUID: principal-UID of invitee
# NAME: common name of invitee
# ACCESS: Access mode for share
# STATE: Invite response status
@@ -924,7 +916,7 @@
create table INVITE (
INVITEUID text unique,
USERID text unique,
- PRINCIPALURL text unique,
+ PRINCIPALUID text unique,
NAME text,
ACCESS text,
STATE text,
@@ -940,7 +932,7 @@
)
q.execute(
"""
- create index PRINCIPALURL on INVITE (PRINCIPALURL)
+ create index PRINCIPALUID on INVITE (PRINCIPALUID)
"""
)
q.execute(
Modified: CalendarServer/trunk/twistedcaldav/storebridge.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/storebridge.py 2011-04-07 18:28:06 UTC (rev 7294)
+++ CalendarServer/trunk/twistedcaldav/storebridge.py 2011-04-07 18:30:26 UTC (rev 7295)
@@ -1455,10 +1455,11 @@
proxyprivs = list(userprivs)
proxyprivs.remove(davxml.Privilege(davxml.ReadACL()))
+ principal = self.principalForUID(record.principalUID)
aces += (
# Inheritable specific access for the resource's associated principal.
davxml.ACE(
- davxml.Principal(davxml.HRef(record.principalURL)),
+ davxml.Principal(davxml.HRef(principal.principalURL())),
davxml.Grant(*userprivs),
davxml.Protected(),
TwistedACLInheritable(),
@@ -1469,7 +1470,7 @@
aces += (
# DAV:read/DAV:read-current-user-privilege-set access for this principal's calendar-proxy-read users.
davxml.ACE(
- davxml.Principal(davxml.HRef(joinURL(record.principalURL, "calendar-proxy-read/"))),
+ davxml.Principal(davxml.HRef(joinURL(principal.principalURL(), "calendar-proxy-read/"))),
davxml.Grant(
davxml.Privilege(davxml.Read()),
davxml.Privilege(davxml.ReadCurrentUserPrivilegeSet()),
@@ -1479,7 +1480,7 @@
),
# DAV:read/DAV:read-current-user-privilege-set/DAV:write access for this principal's calendar-proxy-write users.
davxml.ACE(
- davxml.Principal(davxml.HRef(joinURL(record.principalURL, "calendar-proxy-write/"))),
+ davxml.Principal(davxml.HRef(joinURL(principal.principalURL(), "calendar-proxy-write/"))),
davxml.Grant(*proxyprivs),
davxml.Protected(),
TwistedACLInheritable(),
Modified: CalendarServer/trunk/txdav/common/datastore/sql_legacy.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_legacy.py 2011-04-07 18:28:06 UTC (rev 7294)
+++ CalendarServer/trunk/txdav/common/datastore/sql_legacy.py 2011-04-07 18:30:26 UTC (rev 7295)
@@ -1,6 +1,6 @@
# -*- test-case-name: twistedcaldav.test.test_sharing,twistedcaldav.test.test_calendarquery -*-
##
-# Copyright (c) 2010 Apple Inc. All rights reserved.
+# Copyright (c) 2010-2011 Apple Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -198,21 +198,40 @@
"""
inv = schema.INVITE
return cls._allColumnsQuery(
- inv.RECIPIENT_ADDRESS == Parameter("recipient"))
+ (inv.RESOURCE_ID == Parameter("resourceID")).And(inv.RECIPIENT_ADDRESS == Parameter("recipient"))
+ )
@inlineCallbacks
def recordForUserID(self, userid):
- rows = yield self._inviteForRecipientQuery.on(self._txn,
- recipient=userid)
+ rows = yield self._inviteForRecipientQuery.on(
+ self._txn,
+ resourceID=self._collection._resourceID,
+ recipient=userid
+ )
returnValue(self._makeInvite(rows[0]) if rows else None)
+ @classproperty
+ def _inviteForPrincipalUIDQuery(cls): #@NoSelf
+ """
+ DAL query to retrieve an invite record for a given principal UID.
+ """
+ inv = schema.INVITE
+ home = cls._homeSchema
+ return cls._allColumnsQuery(
+ (inv.RESOURCE_ID == Parameter("resourceID")).And(home.OWNER_UID == Parameter("principalUID"))
+ )
+
+
@inlineCallbacks
- def recordForPrincipalURL(self, principalURL):
- for record in (yield self.allRecords()):
- if record.principalURL == principalURL:
- returnValue(record)
+ def recordForPrincipalUID(self, principalUID):
+ rows = yield self._inviteForPrincipalUIDQuery.on(
+ self._txn,
+ resourceID=self._collection._resourceID,
+ principalUID=principalUID
+ )
+ returnValue(self._makeInvite(rows[0]) if rows else None)
@classproperty
@@ -245,9 +264,8 @@
_BIND_MODE_READ: "read-only",
_BIND_MODE_WRITE: "read-write"
}[bindMode]
- principalURL = "/principals/__uids__/%s/" % (ownerUID,)
return Invite(
- inviteuid, userid, principalURL, common_name,
+ inviteuid, userid, ownerUID, common_name,
access, state, summary
)
@@ -265,11 +283,11 @@
@classproperty
- def _idsForRecipient(cls): #@NoSelf
+ def _idsForInviteUID(cls): #@NoSelf
inv = schema.INVITE
return Select([inv.RESOURCE_ID, inv.HOME_RESOURCE_ID],
From=inv,
- Where=inv.RECIPIENT_ADDRESS == Parameter("recipient"))
+ Where=inv.INVITE_UID == Parameter("inviteuid"))
@classproperty
@@ -278,9 +296,8 @@
DAL query to update an invitation for a given recipient.
"""
inv = schema.INVITE
- return Update({inv.NAME: Parameter("name"),
- inv.INVITE_UID: Parameter("uid")},
- Where=inv.RECIPIENT_ADDRESS == Parameter("recipient"))
+ return Update({inv.NAME: Parameter("name")},
+ Where=inv.INVITE_UID == Parameter("uid"))
@classproperty
@@ -327,13 +344,9 @@
"DECLINED": _BIND_STATUS_DECLINED,
"INVALID": _BIND_STATUS_INVALID,
}[record.state]
- # principalURL is derived from a directory record's principalURL() so
- # it will always contain the UID. The form is '/principals/__uids__/x'
- # (and may contain a trailing slash).
- principalUID = record.principalURL.split("/")[3]
- shareeHome = yield self._getHomeWithUID(principalUID)
- rows = yield self._idsForRecipient.on(self._txn,
- recipient=record.userid)
+ shareeHome = yield self._getHomeWithUID(record.principalUID)
+ rows = yield self._idsForInviteUID.on(self._txn,
+ inviteuid=record.inviteuid)
if rows:
[[resourceID, homeResourceID]] = rows
yield self._updateBindQuery.on(
@@ -342,8 +355,7 @@
resourceID=resourceID, homeID=homeResourceID
)
yield self._updateInviteQuery.on(
- self._txn, name=record.name, uid=record.inviteuid,
- recipient=record.userid
+ self._txn, name=record.name, uid=record.inviteuid
)
else:
yield self._insertInviteQuery.on(
@@ -379,20 +391,6 @@
@classproperty
- def _deleteBindByRecipient(cls): #@NoSelf
- inv = schema.INVITE
- return cls._deleteOneBindQuery(
- inv.RECIPIENT_ADDRESS == Parameter("recipient"))
-
-
- @classproperty
- def _deleteInviteByRecipient(cls): #@NoSelf
- inv = schema.INVITE
- return cls._deleteOneInviteQuery(
- inv.RECIPIENT_ADDRESS == Parameter("recipient"))
-
-
- @classproperty
def _deleteBindByUID(cls): #@NoSelf
inv = schema.INVITE
return cls._deleteOneBindQuery(inv.INVITE_UID == Parameter("uid"))
@@ -405,12 +403,6 @@
@inlineCallbacks
- def removeRecordForUserID(self, userid):
- yield self._deleteBindByRecipient.on(self._txn, recipient=userid)
- yield self._deleteInviteByRecipient.on(self._txn, recipient=userid)
-
-
- @inlineCallbacks
def removeRecordForInviteUID(self, inviteUID):
yield self._deleteBindByUID.on(self._txn, uid=inviteUID)
yield self._deleteInviteByUID.on(self._txn, uid=inviteUID)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110407/23104ca4/attachment-0001.html>
More information about the calendarserver-changes
mailing list