[CalendarServer-changes] [6252] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Tue Sep 7 11:04:34 PDT 2010


Revision: 6252
          http://trac.macosforge.org/projects/calendarserver/changeset/6252
Author:   cdaboo at apple.com
Date:     2010-09-07 11:04:33 -0700 (Tue, 07 Sep 2010)
Log Message:
-----------
Fix direct share with sql.

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/resource.py
    CalendarServer/trunk/twistedcaldav/sharing.py
    CalendarServer/trunk/txdav/common/datastore/sql_legacy.py
    CalendarServer/trunk/txdav/common/datastore/sql_schema_v1.sql
    CalendarServer/trunk/txdav/common/datastore/sql_tables.py

Modified: CalendarServer/trunk/twistedcaldav/resource.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/resource.py	2010-09-07 18:02:47 UTC (rev 6251)
+++ CalendarServer/trunk/twistedcaldav/resource.py	2010-09-07 18:04:33 UTC (rev 6252)
@@ -757,7 +757,7 @@
         acls = None
         isvirt = self.isVirtualShare()
         if isvirt:
-            acls = self.shareeAccessControlList()
+            acls = (yield self.shareeAccessControlList(request, *args, **kwargs))
 
         if acls is None:
             acls = (yield super(CalDAVResource, self).accessControlList(request, *args, **kwargs))

Modified: CalendarServer/trunk/twistedcaldav/sharing.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/sharing.py	2010-09-07 18:02:47 UTC (rev 6251)
+++ CalendarServer/trunk/twistedcaldav/sharing.py	2010-09-07 18:04:33 UTC (rev 6252)
@@ -259,83 +259,86 @@
         else:
             return ""
 
-    def shareeAccessControlList(self):
+    @inlineCallbacks
+    def shareeAccessControlList(self, request, *args, **kwargs):
 
         assert self._isVirtualShare, "Only call this for a virtual share"
 
         # Direct shares use underlying privileges of shared collection
         if self._share.sharetype == SHARETYPE_DIRECT:
-            return None
-
-        # Invite shares use access mode from the invite
-
-        # Get the invite for this sharee
-        invite = self.invitesDB().recordForInviteUID(self._share.shareuid)
-        if invite is None:
-            return davxml.ACL()
-        
-        userprivs = [
-        ]
-        if invite.access in ("read-only", "read-write", "read-write-schedule",):
-            userprivs.append(davxml.Privilege(davxml.Read()))
-            userprivs.append(davxml.Privilege(davxml.ReadACL()))
-            userprivs.append(davxml.Privilege(davxml.ReadCurrentUserPrivilegeSet()))
-        if invite.access in ("read-only",):
-            userprivs.append(davxml.Privilege(davxml.WriteProperties()))
-        if invite.access in ("read-write", "read-write-schedule",):
-            userprivs.append(davxml.Privilege(davxml.Write()))
-        proxyprivs = list(userprivs)
-        proxyprivs.remove(davxml.Privilege(davxml.ReadACL()))
-
-        aces = (
-            # Inheritable specific access for the resource's associated principal.
-            davxml.ACE(
-                davxml.Principal(davxml.HRef(self._shareePrincipal.principalURL())),
-                davxml.Grant(*userprivs),
-                davxml.Protected(),
-                TwistedACLInheritable(),
-            ),
-        )
-        
-        if self.isCalendarCollection():
-            aces += (
-                # Inheritable CALDAV:read-free-busy access for authenticated users.
+            original = (yield request.locateResource(self._share.hosturl))
+            result = (yield original.accessControlList(request, *args, **kwargs))
+            returnValue(result)
+        else:
+            # Invite shares use access mode from the invite
+    
+            # Get the invite for this sharee
+            invite = self.invitesDB().recordForInviteUID(self._share.shareuid)
+            if invite is None:
+                returnValue(davxml.ACL())
+            
+            userprivs = [
+            ]
+            if invite.access in ("read-only", "read-write", "read-write-schedule",):
+                userprivs.append(davxml.Privilege(davxml.Read()))
+                userprivs.append(davxml.Privilege(davxml.ReadACL()))
+                userprivs.append(davxml.Privilege(davxml.ReadCurrentUserPrivilegeSet()))
+            if invite.access in ("read-only",):
+                userprivs.append(davxml.Privilege(davxml.WriteProperties()))
+            if invite.access in ("read-write", "read-write-schedule",):
+                userprivs.append(davxml.Privilege(davxml.Write()))
+            proxyprivs = list(userprivs)
+            proxyprivs.remove(davxml.Privilege(davxml.ReadACL()))
+    
+            aces = (
+                # Inheritable specific access for the resource's associated principal.
                 davxml.ACE(
-                    davxml.Principal(davxml.Authenticated()),
-                    davxml.Grant(davxml.Privilege(caldavxml.ReadFreeBusy())),
+                    davxml.Principal(davxml.HRef(self._shareePrincipal.principalURL())),
+                    davxml.Grant(*userprivs),
+                    davxml.Protected(),
                     TwistedACLInheritable(),
                 ),
             )
-
-        # Give read access to config.ReadPrincipals
-        aces += config.ReadACEs
-
-        # Give all access to config.AdminPrincipals
-        aces += config.AdminACEs
-        
-        if config.EnableProxyPrincipals:
-            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(self._shareePrincipal.principalURL(), "calendar-proxy-read/"))),
-                    davxml.Grant(
-                        davxml.Privilege(davxml.Read()),
-                        davxml.Privilege(davxml.ReadCurrentUserPrivilegeSet()),
+            
+            if self.isCalendarCollection():
+                aces += (
+                    # Inheritable CALDAV:read-free-busy access for authenticated users.
+                    davxml.ACE(
+                        davxml.Principal(davxml.Authenticated()),
+                        davxml.Grant(davxml.Privilege(caldavxml.ReadFreeBusy())),
+                        TwistedACLInheritable(),
                     ),
-                    davxml.Protected(),
-                    TwistedACLInheritable(),
-                ),
-                # 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(self._shareePrincipal.principalURL(), "calendar-proxy-write/"))),
-                    davxml.Grant(*proxyprivs),
-                    davxml.Protected(),
-                    TwistedACLInheritable(),
-                ),
-            )
+                )
+    
+            # Give read access to config.ReadPrincipals
+            aces += config.ReadACEs
+    
+            # Give all access to config.AdminPrincipals
+            aces += config.AdminACEs
+            
+            if config.EnableProxyPrincipals:
+                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(self._shareePrincipal.principalURL(), "calendar-proxy-read/"))),
+                        davxml.Grant(
+                            davxml.Privilege(davxml.Read()),
+                            davxml.Privilege(davxml.ReadCurrentUserPrivilegeSet()),
+                        ),
+                        davxml.Protected(),
+                        TwistedACLInheritable(),
+                    ),
+                    # 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(self._shareePrincipal.principalURL(), "calendar-proxy-write/"))),
+                        davxml.Grant(*proxyprivs),
+                        davxml.Protected(),
+                        TwistedACLInheritable(),
+                    ),
+                )
+    
+            returnValue(davxml.ACL(*aces))
 
-        return davxml.ACL(*aces)
-
     def validUserIDForShare(self, userid):
         """
         Test the user id to see if it is a valid identifier for sharing and

Modified: CalendarServer/trunk/txdav/common/datastore/sql_legacy.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_legacy.py	2010-09-07 18:02:47 UTC (rev 6251)
+++ CalendarServer/trunk/txdav/common/datastore/sql_legacy.py	2010-09-07 18:04:33 UTC (rev 6252)
@@ -42,8 +42,8 @@
 from twistedcaldav.sharing import Invite
 
 from txdav.common.datastore.sql_tables import \
-    _BIND_MODE_OWN, _BIND_MODE_READ, _BIND_MODE_WRITE, _BIND_STATUS_INVITED,\
-    _BIND_STATUS_ACCEPTED, _BIND_STATUS_DECLINED, _BIND_STATUS_INVALID,\
+    _BIND_MODE_OWN, _BIND_MODE_READ, _BIND_MODE_WRITE, _BIND_MODE_DIRECT, \
+    _BIND_STATUS_INVITED, _BIND_STATUS_ACCEPTED, _BIND_STATUS_DECLINED, _BIND_STATUS_INVALID,\
     CALENDAR_BIND_TABLE, CALENDAR_HOME_TABLE, ADDRESSBOOK_HOME_TABLE,\
     ADDRESSBOOK_BIND_TABLE
 
@@ -397,7 +397,7 @@
         # much simpler anyway; we should just do that.
         shareRows = self._txn.execSQL(
             """
-            select %(column_RESOURCE_ID)s, %(column_RESOURCE_NAME)s, %(column_MESSAGE)s
+            select %(column_RESOURCE_ID)s, %(column_RESOURCE_NAME)s, %(column_BIND_MODE)s, %(column_MESSAGE)s
             from %(name)s
             where %(column_HOME_RESOURCE_ID)s = %%s
              and %(column_BIND_MODE)s != %%s
@@ -405,42 +405,70 @@
             """ % self._bindTable,
             [self._home._resourceID, _BIND_MODE_OWN]
         )
-        for resourceID, resourceName, summary in shareRows:
-            [[shareuid]] = self._txn.execSQL(
-                """
-                select INVITE_UID
-                from INVITE
-                where RESOURCE_ID = %s and HOME_RESOURCE_ID = %s
-                """,
-                [resourceID, self._home._resourceID]
-            )
-            sharetype = 'I'
-            [[ownerHomeID, ownerResourceName]] = self._txn.execSQL(
-                """
-                select %(column_HOME_RESOURCE_ID)s, %(column_RESOURCE_NAME)s
-                from %(name)s
-                where %(column_RESOURCE_ID)s = %%s
-                 and %(column_BIND_MODE)s = %%s
-                """ % self._bindTable,
-                [resourceID, _BIND_MODE_OWN]
-            )
-            [[ownerUID]] = self._txn.execSQL(
-                """
-                select %(column_OWNER_UID)s from %(name)s
-                where %(column_RESOURCE_ID)s = %%s
-                """ % self._homeTable,
-                [ownerHomeID]
-            )
-            hosturl = '/%s/__uids__/%s/%s' % (
-                self._urlTopSegment, ownerUID, ownerResourceName
-            )
-            localname = resourceName
-            record = SharedCollectionRecord(
-                shareuid, sharetype, hosturl, localname, summary
-            )
-            yield record
+        for resourceID, resourceName, bindMode, summary in shareRows:
+            if bindMode != _BIND_MODE_DIRECT:
+                [[shareuid]] = self._txn.execSQL(
+                    """
+                    select INVITE_UID
+                    from INVITE
+                    where RESOURCE_ID = %s and HOME_RESOURCE_ID = %s
+                    """,
+                    [resourceID, self._home._resourceID]
+                )
+                sharetype = 'I'
+                [[ownerHomeID, ownerResourceName]] = self._txn.execSQL(
+                    """
+                    select %(column_HOME_RESOURCE_ID)s, %(column_RESOURCE_NAME)s
+                    from %(name)s
+                    where %(column_RESOURCE_ID)s = %%s
+                     and %(column_BIND_MODE)s = %%s
+                    """ % self._bindTable,
+                    [resourceID, _BIND_MODE_OWN]
+                )
+                [[ownerUID]] = self._txn.execSQL(
+                    """
+                    select %(column_OWNER_UID)s from %(name)s
+                    where %(column_RESOURCE_ID)s = %%s
+                    """ % self._homeTable,
+                    [ownerHomeID]
+                )
+                hosturl = '/%s/__uids__/%s/%s' % (
+                    self._urlTopSegment, ownerUID, ownerResourceName
+                )
+                localname = resourceName
+                record = SharedCollectionRecord(
+                    shareuid, sharetype, hosturl, localname, summary
+                )
+                yield record
+            else:
+                sharetype = 'D'
+                [[ownerHomeID, ownerResourceName]] = self._txn.execSQL(
+                    """
+                    select %(column_HOME_RESOURCE_ID)s, %(column_RESOURCE_NAME)s
+                    from %(name)s
+                    where %(column_RESOURCE_ID)s = %%s
+                     and %(column_BIND_MODE)s = %%s
+                    """ % self._bindTable,
+                    [resourceID, _BIND_MODE_OWN]
+                )
+                [[ownerUID]] = self._txn.execSQL(
+                    """
+                    select %(column_OWNER_UID)s from %(name)s
+                    where %(column_RESOURCE_ID)s = %%s
+                    """ % self._homeTable,
+                    [ownerHomeID]
+                )
+                hosturl = '/%s/__uids__/%s/%s' % (
+                    self._urlTopSegment, ownerUID, ownerResourceName
+                )
+                localname = resourceName
+                synthesisedUID = "Direct-%s-%s" % (self._home._resourceID, resourceID,)
+                record = SharedCollectionRecord(
+                    synthesisedUID, sharetype, hosturl, localname, summary
+                )
+                yield record
+                
 
-
     def _search(self, **kw):
         [[key, value]] = kw.items()
         for record in self.allRecords():
@@ -466,22 +494,52 @@
         ownerCollection = ownerHome.childWithName(ownerCollectionName)
         collectionResourceID = ownerCollection._resourceID
 
-        # There needs to be a bind already, one that corresponds to the
-        # invitation.  The invitation's UID is the same as the share UID.  I
-        # just need to update its 'localname', i.e.
-        # XXX_BIND.XXX_RESOURCE_NAME.
+        if record.sharetype == 'I':
+                
+            # There needs to be a bind already, one that corresponds to the
+            # invitation.  The invitation's UID is the same as the share UID.  I
+            # just need to update its 'localname', i.e.
+            # XXX_BIND.XXX_RESOURCE_NAME.
+    
+            self._txn.execSQL(
+                """
+                update %(name)s
+                set %(column_RESOURCE_NAME)s = %%s
+                where %(column_HOME_RESOURCE_ID)s = %%s
+                 and %(column_RESOURCE_ID)s = %%s
+                """ % self._bindTable,
+                [record.localname, self._home._resourceID, collectionResourceID]
+            )
+        elif record.sharetype == 'D':
+            
+            # There is no bind entry already so add one.
+    
+            self._txn.execSQL(
+                """
+                insert into %(name)s
+                (
+                    %(column_HOME_RESOURCE_ID)s,
+                    %(column_RESOURCE_ID)s, 
+                    %(column_RESOURCE_NAME)s,
+                    %(column_BIND_MODE)s,
+                    %(column_BIND_STATUS)s,
+                    %(column_SEEN_BY_OWNER)s,
+                    %(column_SEEN_BY_SHAREE)s,
+                    %(column_MESSAGE)s
+                )
+                values (%%s, %%s, %%s, %%s, %%s, %%s, %%s, %%s)
+                """ % self._bindTable,
+                [
+                    self._home._resourceID,
+                    collectionResourceID,
+                    record.localname,
+                    _BIND_MODE_DIRECT,
+                    _BIND_STATUS_ACCEPTED,
+                    True,
+                    True,
+                    record.summary,
+                ])
 
-        self._txn.execSQL(
-            """
-            update %(name)s
-            set %(column_RESOURCE_NAME)s = %%s
-            where %(column_HOME_RESOURCE_ID)s = %%s
-             and %(column_RESOURCE_ID)s = %%s
-            """ % self._bindTable,
-            [record.localname, self._home._resourceID, collectionResourceID]
-        )
-
-
     def removeRecordForLocalName(self, localname):
         self._txn.execSQL(
             """
@@ -495,17 +553,32 @@
 
 
     def removeRecordForShareUID(self, shareUID):
-        self._txn.execSQL(
-            """
-            update %(name)s
-            set %(column_RESOURCE_NAME)s = NULL
-            from INVITE
-            where INVITE.INVITE_UID = %%s
-             and %(name)s.%(column_HOME_RESOURCE_ID)s = INVITE.HOME_RESOURCE_ID
-             and %(name)s.%(column_RESOURCE_ID)s = INVITE.RESOURCE_ID
-            """ % self._bindTable,
-            [shareUID,]
-        )
+        if not shareUID.startswith("Direct"):
+            self._txn.execSQL(
+                """
+                update %(name)s
+                set %(column_RESOURCE_NAME)s = NULL
+                from INVITE
+                where INVITE.INVITE_UID = %%s
+                 and %(name)s.%(column_HOME_RESOURCE_ID)s = INVITE.HOME_RESOURCE_ID
+                 and %(name)s.%(column_RESOURCE_ID)s = INVITE.RESOURCE_ID
+                """ % self._bindTable,
+                [shareUID,]
+            )
+        else:
+            # Extract pieces from synthesised UID
+            homeID, resourceID = shareUID[len("Direct-"):].split("-")
+            
+            # Now remove the binding for the direct share
+            self._txn.execSQL(
+                """
+                delete from %(name)s
+                where %(column_HOME_RESOURCE_ID)s = %%s
+                 and %(column_RESOURCE_ID)s = %%s
+                """ % self._bindTable,
+                [homeID, resourceID,]
+            )
+            
 
 class SQLLegacyCalendarShares(SQLLegacyShares):
     """

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema_v1.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema_v1.sql	2010-09-07 18:02:47 UTC (rev 6251)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema_v1.sql	2010-09-07 18:04:33 UTC (rev 6252)
@@ -96,6 +96,7 @@
 insert into CALENDAR_BIND_MODE values (0, 'own'  );
 insert into CALENDAR_BIND_MODE values (1, 'read' );
 insert into CALENDAR_BIND_MODE values (2, 'write');
+insert into CALENDAR_BIND_MODE values (3, 'direct');
 
 -- Enumeration of statuses
 

Modified: CalendarServer/trunk/txdav/common/datastore/sql_tables.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_tables.py	2010-09-07 18:02:47 UTC (rev 6251)
+++ CalendarServer/trunk/txdav/common/datastore/sql_tables.py	2010-09-07 18:04:33 UTC (rev 6252)
@@ -128,3 +128,4 @@
 _BIND_MODE_OWN = 0
 _BIND_MODE_READ = 1
 _BIND_MODE_WRITE = 2
+_BIND_MODE_DIRECT = 3
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20100907/5ed6792c/attachment-0001.html>


More information about the calendarserver-changes mailing list