<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre, #msg p { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[2367] CalendarServer/branches/propfind-cache/twistedcaldav/directory</title>
</head>
<body>

<div id="msg">
<dl>
<dt>Revision</dt> <dd><a href="http://trac.macosforge.org/projects/calendarserver/changeset/2367">2367</a></dd>
<dt>Author</dt> <dd>dreid@apple.com</dd>
<dt>Date</dt> <dd>2008-05-05 13:03:39 -0700 (Mon, 05 May 2008)</dd>
</dl>

<h3>Log Message</h3>
<pre>delete-trailing-whitespace and add a test for setGroupMemberSet</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#CalendarServerbranchespropfindcachetwistedcaldavdirectorycalendaruserproxypy">CalendarServer/branches/propfind-cache/twistedcaldav/directory/calendaruserproxy.py</a></li>
<li><a href="#CalendarServerbranchespropfindcachetwistedcaldavdirectorytesttest_proxyprincipalmemberspy">CalendarServer/branches/propfind-cache/twistedcaldav/directory/test/test_proxyprincipalmembers.py</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="CalendarServerbranchespropfindcachetwistedcaldavdirectorycalendaruserproxypy"></a>
<div class="modfile"><h4>Modified: CalendarServer/branches/propfind-cache/twistedcaldav/directory/calendaruserproxy.py (2366 => 2367)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/branches/propfind-cache/twistedcaldav/directory/calendaruserproxy.py        2008-05-05 17:35:32 UTC (rev 2366)
+++ CalendarServer/branches/propfind-cache/twistedcaldav/directory/calendaruserproxy.py        2008-05-05 20:03:39 UTC (rev 2367)
</span><span class="lines">@@ -54,7 +54,7 @@
</span><span class="cx">                 davxml.Protected(),
</span><span class="cx">             ),
</span><span class="cx">         )
</span><del>-        
</del><ins>+
</ins><span class="cx">         # Add admins
</span><span class="cx">         aces += tuple([davxml.ACE(
</span><span class="cx">                     davxml.Principal(davxml.HRef(principal)),
</span><span class="lines">@@ -118,10 +118,10 @@
</span><span class="cx">     def _index(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Return the SQL database for this group principal.
</span><del>-        
</del><ins>+
</ins><span class="cx">         @return: the L{CalendarUserProxyDatabase} for the principal collection.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">         # The db is located in the principal collection root
</span><span class="cx">         if not hasattr(self.pcollection, &quot;calendar_user_proxy_db&quot;):
</span><span class="cx">             setattr(self.pcollection, &quot;calendar_user_proxy_db&quot;, CalendarUserProxyDatabase(self.pcollection.fp.path))
</span><span class="lines">@@ -166,7 +166,7 @@
</span><span class="cx"> 
</span><span class="cx">         # Break out the list into a set of URIs.
</span><span class="cx">         members = [str(h) for h in new_members.children]
</span><del>-        
</del><ins>+
</ins><span class="cx">         # Map the URIs to principals.
</span><span class="cx">         principals = []
</span><span class="cx">         for uri in members:
</span><span class="lines">@@ -178,7 +178,7 @@
</span><span class="cx">                     &quot;Attempt to use a non-existent principal %s as a group member of %s.&quot; % (uri, self.principalURL(),)
</span><span class="cx">                 ))
</span><span class="cx">             principals.append(principal)
</span><del>-        
</del><ins>+
</ins><span class="cx">         # Map the principals to UIDs.
</span><span class="cx">         uids = [p.principalUID() for p in principals]
</span><span class="cx"> 
</span><span class="lines">@@ -298,19 +298,19 @@
</span><span class="cx"> 
</span><span class="cx">     def hasEditableMembership(self):
</span><span class="cx">         return self.parent.hasEditableProxyMembership()
</span><del>-        
</del><ins>+
</ins><span class="cx"> class CalendarUserProxyDatabase(AbstractSQLDatabase):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     A database to maintain calendar user proxy group memberships.
</span><span class="cx"> 
</span><span class="cx">     SCHEMA:
</span><del>-    
</del><ins>+
</ins><span class="cx">     Group Database:
</span><del>-    
</del><ins>+
</ins><span class="cx">     ROW: GROUPNAME, MEMBER
</span><del>-    
</del><ins>+
</ins><span class="cx">     &quot;&quot;&quot;
</span><del>-    
</del><ins>+
</ins><span class="cx">     dbType = &quot;CALENDARUSERPROXY&quot;
</span><span class="cx">     dbFilename = db_prefix + &quot;calendaruserproxy&quot;
</span><span class="cx">     dbFormatVersion = &quot;4&quot;
</span><span class="lines">@@ -322,11 +322,11 @@
</span><span class="cx">     def setGroupMembers(self, principalUID, members):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Add a group membership record.
</span><del>-    
</del><ins>+
</ins><span class="cx">         @param principalUID: the UID of the group principal to add.
</span><span class="cx">         @param members: a list UIDs of principals that are members of this group.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">         # Remove what is there, then add it back.
</span><span class="cx">         self._delete_from_db(principalUID)
</span><span class="cx">         self._add_to_db(principalUID, members)
</span><span class="lines">@@ -335,12 +335,12 @@
</span><span class="cx">     def removeGroup(self, principalUID):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Remove a group membership record.
</span><del>-    
</del><ins>+
</ins><span class="cx">         @param principalUID: the UID of the group principal to remove.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         self._delete_from_db(principalUID)
</span><span class="cx">         self._db_commit()
</span><del>-    
</del><ins>+
</ins><span class="cx">     def getMembers(self, principalUID):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Return the list of group member UIDs for the specified principal.
</span><span class="lines">@@ -349,7 +349,7 @@
</span><span class="cx">         for row in self._db_execute(&quot;select MEMBER from GROUPS where GROUPNAME = :1&quot;, principalUID):
</span><span class="cx">             members.add(row[0])
</span><span class="cx">         return members
</span><del>-    
</del><ins>+
</ins><span class="cx">     def getMemberships(self, principalUID):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Return the list of group principal UIDs the specified principal is a member of.
</span><span class="lines">@@ -373,7 +373,7 @@
</span><span class="cx">                 values (:1, :2)
</span><span class="cx">                 &quot;&quot;&quot;, principalUID, member
</span><span class="cx">             )
</span><del>-       
</del><ins>+
</ins><span class="cx">     def _delete_from_db(self, principalUID):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Deletes the specified entry from the database.
</span><span class="lines">@@ -381,19 +381,19 @@
</span><span class="cx">         @param principalUID: the UID of the group principal to remove.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         self._db_execute(&quot;delete from GROUPS where GROUPNAME = :1&quot;, principalUID)
</span><del>-    
</del><ins>+
</ins><span class="cx">     def _db_version(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         @return: the schema version assigned to this index.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         return CalendarUserProxyDatabase.dbFormatVersion
</span><del>-        
</del><ins>+
</ins><span class="cx">     def _db_type(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         @return: the collection type assigned to this index.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         return CalendarUserProxyDatabase.dbType
</span><del>-        
</del><ins>+
</ins><span class="cx">     def _db_init_data_tables(self, q):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Initialise the underlying database tables.
</span></span></pre></div>
<a id="CalendarServerbranchespropfindcachetwistedcaldavdirectorytesttest_proxyprincipalmemberspy"></a>
<div class="modfile"><h4>Modified: CalendarServer/branches/propfind-cache/twistedcaldav/directory/test/test_proxyprincipalmembers.py (2366 => 2367)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/branches/propfind-cache/twistedcaldav/directory/test/test_proxyprincipalmembers.py        2008-05-05 17:35:32 UTC (rev 2366)
+++ CalendarServer/branches/propfind-cache/twistedcaldav/directory/test/test_proxyprincipalmembers.py        2008-05-05 20:03:39 UTC (rev 2367)
</span><span class="lines">@@ -17,6 +17,7 @@
</span><span class="cx"> import os
</span><span class="cx"> 
</span><span class="cx"> from twisted.web2.dav.fileop import rmdir
</span><ins>+from twisted.web2.dav import davxml
</ins><span class="cx"> 
</span><span class="cx"> from twistedcaldav.directory.directory import DirectoryService
</span><span class="cx"> from twistedcaldav.directory.xmlfile import XMLDirectoryService
</span><span class="lines">@@ -33,7 +34,7 @@
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     def setUp(self):
</span><span class="cx">         super(ProxyPrincipals, self).setUp()
</span><del>-        
</del><ins>+
</ins><span class="cx">         # Set up a principals hierarchy for each service we're testing with
</span><span class="cx">         self.principalRootResources = {}
</span><span class="cx">         name = directoryService.__class__.__name__
</span><span class="lines">@@ -114,7 +115,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         DirectoryPrincipalResource.groupMembers()
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">         # Setup the fake entry in the DB
</span><span class="cx">         proxy = self._getRecordByShortName(DirectoryService.recordType_users, &quot;cdaboo&quot;)
</span><span class="cx">         proxy_group = proxy.getChild(&quot;calendar-proxy-write&quot;)
</span><span class="lines">@@ -131,7 +132,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         DirectoryPrincipalResource.groupMembers()
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">         # Setup the fake entry in the DB
</span><span class="cx">         fake_uid = &quot;12345&quot;
</span><span class="cx">         proxy = self._getRecordByShortName(DirectoryService.recordType_users, &quot;cdaboo&quot;)
</span><span class="lines">@@ -157,3 +158,35 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         provisioningResource = self.principalRootResources[directoryService.__class__.__name__]
</span><span class="cx">         return provisioningResource.principalForShortName(type, name)
</span><ins>+
+
+    def test_setGroupMemberSet(self):
+        class StubMemberDB(object):
+            def __init__(self):
+                self.members = None
+
+            def setGroupMembers(self, uid, members):
+                self.members = members
+
+
+        proxy = self._getRecordByShortName(directoryService.recordType_users,
+                                           &quot;cdaboo&quot;)
+
+        proxy_group = proxy.getChild(&quot;calendar-proxy-write&quot;)
+
+        memberdb = StubMemberDB()
+
+        proxy_group._index = (lambda: memberdb)
+
+        new_members = davxml.GroupMemberSet(
+            davxml.HRef.fromString(
+                &quot;/XMLDirectoryService/__uids__/8B4288F6-CC82-491D-8EF9-642EF4F3E7D0/&quot;),
+            davxml.HRef.fromString(
+                &quot;/XMLDirectoryService/__uids__/5FF60DAD-0BDE-4508-8C77-15F0CA5C8DD1/&quot;))
+
+        proxy_group.setGroupMemberSet(new_members, None)
+
+        self.assertEquals(
+            set([str(p) for p in memberdb.members]),
+            set([&quot;5FF60DAD-0BDE-4508-8C77-15F0CA5C8DD1&quot;,
+                 &quot;8B4288F6-CC82-491D-8EF9-642EF4F3E7D0&quot;]))
</ins></span></pre>
</div>
</div>

</body>
</html>