[CalendarServer-changes] [9454] CalendarServer/branches/users/gaya/inviteclean/twistedcaldav/sharing .py
source_changes at macosforge.org
source_changes at macosforge.org
Sat Jul 14 16:09:49 PDT 2012
Revision: 9454
http://trac.macosforge.org/projects/calendarserver/changeset/9454
Author: gaya at apple.com
Date: 2012-07-14 16:09:49 -0700 (Sat, 14 Jul 2012)
Log Message:
-----------
use Invitation object instead of Invite() object. This an in intermediate step to test new Invitation interface.
Modified Paths:
--------------
CalendarServer/branches/users/gaya/inviteclean/twistedcaldav/sharing.py
Modified: CalendarServer/branches/users/gaya/inviteclean/twistedcaldav/sharing.py
===================================================================
--- CalendarServer/branches/users/gaya/inviteclean/twistedcaldav/sharing.py 2012-07-14 23:06:29 UTC (rev 9453)
+++ CalendarServer/branches/users/gaya/inviteclean/twistedcaldav/sharing.py 2012-07-14 23:09:49 UTC (rev 9454)
@@ -65,22 +65,22 @@
def invitePropertyElement(record, includeUID=True):
- userid = "urn:uuid:" + record.principalUID
- principal = self.principalForUID(record.principalUID)
- cn = principal.displayName() if principal else record.principalUID
+ userid = "urn:uuid:" + record.shareeUID()
+ principal = self.principalForUID(record.shareeUID())
+ cn = principal.displayName() if principal else record.shareeUID()
return customxml.InviteUser(
- customxml.UID.fromString(record.inviteuid) if includeUID else None,
+ customxml.UID.fromString(record.uid()) if includeUID else None,
element.HRef.fromString(userid),
customxml.CommonName.fromString(cn),
- customxml.InviteAccess(inviteAccessMapToXML[record.access]()),
- inviteStatusMapToXML[record.state](),
+ customxml.InviteAccess(inviteAccessMapToXML[record.shareeAccess()]()),
+ inviteStatusMapToXML[record.state()](),
)
# See if this property is on the shared calendar
isShared = yield self.isShared(request)
if isShared:
yield self.validateInvites()
- records = yield self.invitesDB().allRecords()
+ records = yield self._allInvites()
returnValue(customxml.Invite(
*[invitePropertyElement(record) for record in records]
))
@@ -89,7 +89,7 @@
if self.isVirtualShare():
original = (yield request.locateResource(self._share.hosturl))
yield original.validateInvites()
- records = yield original.invitesDB().allRecords()
+ records = yield original._allInvites()
ownerPrincipal = (yield original.ownerPrincipal(request))
owner = ownerPrincipal.principalURL()
@@ -127,7 +127,7 @@
self.writeDeadProperty(rtype)
# Remove all invitees
- for record in (yield self.invitesDB().allRecords()):
+ for record in (yield self._allInvites()):
yield self.uninviteRecordFromShare(record, request)
# Remove invites database
@@ -147,8 +147,8 @@
"Invalid share",
))
- record = yield self._recordForInviteUID(inviteUID)
- if record is None or record.principalUID != principalUID:
+ record = yield self._inviteForInviteUID(inviteUID)
+ if record is None or record.shareeUID() != principalUID:
raise HTTPError(ErrorResponse(
responsecode.FORBIDDEN,
(customxml.calendarserver_namespace, "valid-request"),
@@ -156,11 +156,11 @@
))
# Only certain states are sharer controlled
- if record.state in ("NEEDS-ACTION", "ACCEPTED", "DECLINED",):
- record.state = state
+ if record.state() in ("NEEDS-ACTION", "ACCEPTED", "DECLINED",):
+ record._state = state
if summary is not None:
- record.summary = summary
- yield self.invitesDB().addOrUpdateRecord(record)
+ record._summary = summary
+ yield self.invitesDB().addOrUpdateRecord(record.invite())
@inlineCallbacks
@@ -328,12 +328,12 @@
# Invite shares use access mode from the invite
# Get the invite for this sharee
- invite = yield self._recordForInviteUID(
+ invite = yield self._inviteForInviteUID(
self._share.shareuid
)
if invite is None:
returnValue(element.ACL())
- inviteAccess = invite.access
+ inviteAccess = invite.shareeAccess()
userprivs = [
]
@@ -407,11 +407,11 @@
Make sure each userid in an invite is valid - if not re-write status.
"""
- records = yield self.invitesDB().allRecords()
+ records = yield self._allInvites()
for record in records:
- if not self.principalForUID(record.principalUID) and record.state != "INVALID":
- record.state = "INVALID"
- yield self.invitesDB().addOrUpdateRecord(record)
+ if not self.principalForUID(record.shareeUID()) and record.state() != "INVALID":
+ record._state = "INVALID"
+ yield self.invitesDB().addOrUpdateRecord(record.invite())
def inviteUserToShare(self, userid, cn, ace, summary, request):
@@ -497,28 +497,39 @@
"""
hosturl = (yield self.canonicalURL(request))
returnValue("%s:%s" % (hosturl, userid))
+
+ @inlineCallbacks
+ def _allInvites(self):
+ """
+ replaces self.invitesDB().allRecords()
+ """
+ records = yield self.invitesDB().allRecords()
+ invitations = [record.invitation() for record in records]
+ returnValue(invitations)
@inlineCallbacks
- def _recordForPrincipalUID(self, principalUID):
+ def _inviteForPrincipalUID(self, principalUID):
"""
replaces self.invitesDB().recordForPrincipalUID(principalUID)
"""
- records = yield self.invitesDB().allRecords()
+ records = yield self._allInvites()
for record in records:
- if record.principalUID == principalUID:
+ if record.shareeUID() == principalUID:
returnValue(record)
returnValue(None)
+
@inlineCallbacks
- def _recordForInviteUID(self, inviteUID):
+ def _inviteForInviteUID(self, inviteUID):
"""
replaces self.invitesDB().recordForInviteUID(inviteUID)
"""
- records = yield self.invitesDB().allRecords()
+ records = yield self._allInvites()
for record in records:
- if record.inviteuid == inviteUID:
+ if record.uid() == inviteUID:
returnValue(record)
returnValue(None)
+
@@ -543,18 +554,23 @@
try:
# Look for existing invite and update its fields or create new one
- record = yield self._recordForPrincipalUID(principalUID)
+ record = yield self._inviteForPrincipalUID(principalUID)
if record:
- record.access = inviteAccessMapFromXML[type(ace)]
- record.summary = summary
+ record._shareeAccess = inviteAccessMapFromXML[type(ace)]
+ record._summary = summary
else:
- record = Invite(str(uuid4()), "userid", principalUID, "cn", inviteAccessMapFromXML[type(ace)], "NEEDS-ACTION", summary)
+ record = Invitation(uid=str(uuid4()),
+ sharerUID=None,
+ shareeUID=principalUID,
+ shareeAccess=inviteAccessMapFromXML[type(ace)],
+ state="NEEDS-ACTION",
+ summary=summary)
# Send invite
yield self.sendInvite(record, request)
# Add to database
- yield self.invitesDB().addOrUpdateRecord(record)
+ yield self.invitesDB().addOrUpdateRecord(record.invite())
finally:
lock.clean()
@@ -580,7 +596,7 @@
yield self._acquireLock(lock)
try:
- record = yield self._recordForPrincipalUID(principalUID)
+ record = yield self._inviteForPrincipalUID(principalUID)
if record:
result = (yield self.uninviteRecordFromShare(record, request))
else:
@@ -595,35 +611,37 @@
def uninviteRecordFromShare(self, record, request):
# Remove any shared calendar or address book
- sharee = self.principalForUID(record.principalUID)
+ sharee = self.principalForUID(record.shareeUID())
if sharee:
if self.isCalendarCollection():
shareeHomeResource = yield sharee.calendarHome(request)
elif self.isAddressBookCollection():
shareeHomeResource = yield sharee.addressBookHome(request)
- yield shareeHomeResource.removeShareByUID(request, record.inviteuid)
+ yield shareeHomeResource.removeShareByUID(request, record.uid())
# If current user state is accepted then we send an invite with the new state, otherwise
# we cancel any existing invites for the user
- if record and record.state != "ACCEPTED":
+ if record and record.state() != "ACCEPTED":
yield self.removeInvite(record, request)
elif record:
- record.state = "DELETED"
+ record._state = "DELETED"
yield self.sendInvite(record, request)
-
- # use new API
- from twistedcaldav.directory.util import transactionFromRequest
- transaction = transactionFromRequest(request, self._newStoreObject)
- if self.isCalendarCollection():
- shareeHome = yield transaction.calendarHomeWithUID(record.principalUID, create=True)
- elif self.isAddressBookCollection():
- shareeHome = yield transaction.addressbookHomeWithUID(record.principalUID, create=True)
+ if hasattr(self._newStoreObject, "unshareWith"):
- yield self._newStoreObject.unshareWith(shareeHome)
- # old
- # yield self.invitesDB().removeRecordForInviteUID(record.inviteuid)
+ from twistedcaldav.directory.util import transactionFromRequest
+ transaction = transactionFromRequest(request, self._newStoreObject)
+
+ if self.isCalendarCollection():
+ shareeHome = yield transaction.calendarHomeWithUID(record.shareeUID(), create=True)
+ elif self.isAddressBookCollection():
+ shareeHome = yield transaction.addressbookHomeWithUID(record.shareeUID(), create=True)
+
+ yield self._newStoreObject.unshareWith(shareeHome)
+ else:
+ yield self.invitesDB().removeRecordForInviteUID(record.uid())
+
returnValue(True)
def inviteSingleUserUpdateToShare(self, userid, commonName, acesOLD, aceNEW, summary, request):
@@ -640,7 +658,7 @@
hosturl = (yield self.canonicalURL(request))
# Locate notifications collection for user
- sharee = self.principalForUID(record.principalUID)
+ sharee = self.principalForUID(record.shareeUID())
if sharee is None:
raise ValueError("sharee is None but principalUID was valid before")
@@ -649,23 +667,23 @@
notifications = notificationResource._newStoreNotifications
# Look for existing notification
- oldnotification = (yield notifications.notificationObjectWithUID(record.inviteuid))
+ oldnotification = (yield notifications.notificationObjectWithUID(record.uid()))
if oldnotification:
# TODO: rollup changes?
pass
# Generate invite XML
- userid = "urn:uuid:" + record.principalUID
+ userid = "urn:uuid:" + record.shareeUID()
typeAttr = {'shared-type':self.sharedResourceType()}
xmltype = customxml.InviteNotification(**typeAttr)
xmldata = customxml.Notification(
customxml.DTStamp.fromString(PyCalendarDateTime.getNowUTC().getText()),
customxml.InviteNotification(
- customxml.UID.fromString(record.inviteuid),
+ customxml.UID.fromString(record.uid()),
element.HRef.fromString(userid),
- inviteStatusMapToXML[record.state](),
- customxml.InviteAccess(inviteAccessMapToXML[record.access]()),
+ inviteStatusMapToXML[record.state()](),
+ customxml.InviteAccess(inviteAccessMapToXML[record.shareeAccess()]()),
customxml.HostURL(
element.HRef.fromString(hosturl),
),
@@ -673,26 +691,26 @@
element.HRef.fromString(owner),
customxml.CommonName.fromString(ownerCN),
),
- customxml.InviteSummary.fromString(record.summary),
+ customxml.InviteSummary.fromString(record.summary()),
self.getSupportedComponentSet() if self.isCalendarCollection() else None,
**typeAttr
),
).toxml()
# Add to collections
- yield notifications.writeNotificationObject(record.inviteuid, xmltype, xmldata)
+ yield notifications.writeNotificationObject(record.uid(), xmltype, xmldata)
@inlineCallbacks
def removeInvite(self, record, request):
# Locate notifications collection for user
- sharee = self.principalForUID(record.principalUID)
+ sharee = self.principalForUID(record.shareeUID())
if sharee is None:
raise ValueError("sharee is None but principalUID was valid before")
notifications = (yield request.locateResource(sharee.notificationURL()))
# Add to collections
- yield notifications.deleteNotifictionMessageByUID(request, record.inviteuid)
+ yield notifications.deleteNotifictionMessageByUID(request, record.uid())
@inlineCallbacks
def _xmlHandleInvite(self, request, docroot):
@@ -913,7 +931,96 @@
self.state = state
self.summary = summary
+ def invitation(self):
+ return Invitation(uid=self.inviteuid,
+ sharerUID=None,
+ shareeUID=self.principalUID,
+ shareeAccess=self.access,
+ state=self.state,
+ summary=self.summary, )
+
+
+from zope.interface import implements
+from txdav.common.iinvitation import IInvitation
+
+class Invitation(object):
+ implements(IInvitation)
+
+
+ def __init__(self, uid, sharerUID, shareeUID, shareeAccess, state, summary):
+ self._uid = uid
+ self._sharerUID = sharerUID
+ self._shareeUID = shareeUID
+ self._shareeAccess = shareeAccess
+ self._state = state
+ self._summary = summary
+
+ def invite(self):
+ return Invite(inviteuid=self.uid(),
+ userid="userid",
+ principalUID=self.shareeUID(),
+ common_name="common_name",
+ access=self.shareeAccess(),
+ state=self.state(),
+ summary=self.summary() )
+
+ def uid(self):
+ """
+ Unique identifier for this record. Randomly generated.
+
+ @return: the invite unique identifier
+ @rtype: C{str}
+ """
+ return self._uid
+
+ def sharerUID(self):
+ """
+ Sharer's unique identifier.
+
+ @return: the Sharer's unique identifier.
+ @rtype: C{str}
+ """
+ return self._sharerUID
+
+ def shareeUID(self):
+ """
+ Sharee's unique identifier.
+
+ @return: the Sharee's unique identifier.
+ @rtype: C{str}
+ """
+ return self._shareeUID
+
+ def shareeAccess(self):
+ """
+ Sharee's access. Currently, one of "own", "read-only", or "read-write".
+
+ @return: the Sharee's access to the shared resource
+ @rtype: C{str}
+ """
+ return self._shareeAccess
+
+ def state(self):
+ """
+ Invitation or bind state. Currently, one of "NEEDS-ACTION","ACCEPTED", "DECLINED", "INVALID".
+
+ @return: the record state
+ @rtype: C{str}
+ """
+ return self._state
+
+ def summary(self):
+ """
+ The shared resource's name, purpose, or description.
+
+ @return: the summary
+ @rtype: C{str}
+ """
+ return self._summary
+
+
+
class InvitesDatabase(AbstractSQLDatabase, LoggingMixIn):
db_basename = db_prefix + "invites"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120714/985e4d72/attachment-0001.html>
More information about the calendarserver-changes
mailing list