<!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" />
<title>[13548] CalendarServer/trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { 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 { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#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>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.calendarserver.org//changeset/13548">13548</a></dd>
<dt>Author</dt> <dd>cdaboo@apple.com</dd>
<dt>Date</dt> <dd>2014-05-28 11:29:34 -0700 (Wed, 28 May 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Make sure access log displays user names rather than principal URLs.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#CalendarServertrunkcalendarserveraccesslogpy">CalendarServer/trunk/calendarserver/accesslog.py</a></li>
<li><a href="#CalendarServertrunkcalendarserverprovisionrootpy">CalendarServer/trunk/calendarserver/provision/root.py</a></li>
<li><a href="#CalendarServertrunkcalendarserverprovisiontesttest_rootpy">CalendarServer/trunk/calendarserver/provision/test/test_root.py</a></li>
<li><a href="#CalendarServertrunkcalendarserverpushapplepushpy">CalendarServer/trunk/calendarserver/push/applepush.py</a></li>
<li><a href="#CalendarServertrunkcalendarservertaputilpy">CalendarServer/trunk/calendarserver/tap/util.py</a></li>
<li><a href="#CalendarServertrunkcalendarserverwebcalresourcepy">CalendarServer/trunk/calendarserver/webcal/resource.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavauthkerbpy">CalendarServer/trunk/twistedcaldav/authkerb.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavcachepy">CalendarServer/trunk/twistedcaldav/cache.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavdirectoryutilpy">CalendarServer/trunk/twistedcaldav/directory/util.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavtesttest_addressbookmultigetpy">CalendarServer/trunk/twistedcaldav/test/test_addressbookmultiget.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavtesttest_addressbookquerypy">CalendarServer/trunk/twistedcaldav/test/test_addressbookquery.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavtesttest_cachepy">CalendarServer/trunk/twistedcaldav/test/test_cache.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavtesttest_calendarquerypy">CalendarServer/trunk/twistedcaldav/test/test_calendarquery.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavtesttest_collectioncontentspy">CalendarServer/trunk/twistedcaldav/test/test_collectioncontents.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavtesttest_mkcalendarpy">CalendarServer/trunk/twistedcaldav/test/test_mkcalendar.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavtesttest_multigetpy">CalendarServer/trunk/twistedcaldav/test/test_multiget.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavtesttest_propspy">CalendarServer/trunk/twistedcaldav/test/test_props.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavtesttest_resourcepy">CalendarServer/trunk/twistedcaldav/test/test_resource.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavtesttest_sharingpy">CalendarServer/trunk/twistedcaldav/test/test_sharing.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavtesttest_wrappingpy">CalendarServer/trunk/twistedcaldav/test/test_wrapping.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavtestutilpy">CalendarServer/trunk/twistedcaldav/test/util.py</a></li>
<li><a href="#CalendarServertrunktwistedcaldavupgradepy">CalendarServer/trunk/twistedcaldav/upgrade.py</a></li>
<li><a href="#CalendarServertrunktxdavwhowikipy">CalendarServer/trunk/txdav/who/wiki.py</a></li>
<li><a href="#CalendarServertrunktxweb2davauthpy">CalendarServer/trunk/txweb2/dav/auth.py</a></li>
<li><a href="#CalendarServertrunktxweb2davidavpy">CalendarServer/trunk/txweb2/dav/idav.py</a></li>
<li><a href="#CalendarServertrunktxweb2davresourcepy">CalendarServer/trunk/txweb2/dav/resource.py</a></li>
<li><a href="#CalendarServertrunktxweb2davtesttest_resourcepy">CalendarServer/trunk/txweb2/dav/test/test_resource.py</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="CalendarServertrunkcalendarserveraccesslogpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/accesslog.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/accesslog.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/calendarserver/accesslog.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx">     getAdjustedClientName
</span><span class="cx"> 
</span><span class="cx"> from twext.python.log import Logger
</span><ins>+from twext.who.idirectory import RecordType
</ins><span class="cx"> from txweb2 import iweb
</span><span class="cx"> from txweb2.log import BaseCommonAccessLoggingObserver
</span><span class="cx"> from txweb2.log import LogWrapperResource
</span><span class="lines">@@ -49,8 +50,6 @@
</span><span class="cx"> 
</span><span class="cx"> from twistedcaldav.config import config
</span><span class="cx"> 
</span><del>-from txdav.xml import element as davxml
-
</del><span class="cx"> log = Logger()
</span><span class="cx"> 
</span><span class="cx"> class DirectoryLogWrapperResource(LogWrapperResource):
</span><span class="lines">@@ -83,39 +82,21 @@
</span><span class="cx"> 
</span><span class="cx">             # Try to determine authentication and authorization identifiers
</span><span class="cx">             uid = &quot;-&quot;
</span><del>-            if hasattr(request, &quot;authnUser&quot;):
-                if isinstance(request.authnUser.children[0], davxml.HRef):
-                    uidn = str(request.authnUser.children[0])
-                    uidz = None
-                    if hasattr(request, &quot;authzUser&quot;) and str(request.authzUser.children[0]) != uidn:
-                        uidz = str(request.authzUser.children[0])
</del><ins>+            if getattr(request, &quot;authnUser&quot;, None) is not None:
+                def convertPrincipaltoShortName(principal):
+                    if principal.record.recordType == RecordType.user:
+                        return principal.record.shortNames[0]
+                    else:
+                        return &quot;({rtype}){name}&quot;.format(rtype=principal.record.recordType, name=principal.record.shortNames[0],)
</ins><span class="cx"> 
</span><del>-                    # def convertUIDtoShortName(uid):
-                    #     uid = uid.rstrip(&quot;/&quot;)
-                    #     uid = uid[uid.rfind(&quot;/&quot;) + 1:]
-                    #     record = request.site.resource.getDirectory().recordWithUID(uid)
-                    #     if record:
-                    #         if record.recordType == DirectoryService.recordType_users:
-                    #             return record.shortNames[0]
-                    #         else:
-                    #             return &quot;(%s)%s&quot; % (record.recordType, record.shortNames[0],)
-                    #     else:
-                    #         return uid
</del><ins>+                uidn = convertPrincipaltoShortName(request.authnUser)
+                uidz = convertPrincipaltoShortName(request.authzUser)
</ins><span class="cx"> 
</span><del>-                    # MOVE2WHO
-                    # Better to stick the records directly on the request at
-                    # an earlier point, since we can't do anything deferred
-                    # in here.
</del><ins>+                if uidn != uidz:
+                    uid = '&quot;{authn} as {authz}&quot;'.format(authn=uidn, authz=uidz,)
+                else:
+                    uid = uidn
</ins><span class="cx"> 
</span><del>-                    # uidn = convertUIDtoShortName(uidn)
-                    # if uidz:
-                    #     uidz = convertUIDtoShortName(uidz)
-
-                    if uidn and uidz:
-                        uid = '&quot;%s as %s&quot;' % (uidn, uidz,)
-                    else:
-                        uid = uidn
-
</del><span class="cx">             #
</span><span class="cx">             # For some methods which basically allow you to tunnel a
</span><span class="cx">             # custom request (eg. REPORT, POST), the method name
</span></span></pre></div>
<a id="CalendarServertrunkcalendarserverprovisionrootpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/provision/root.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/provision/root.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/calendarserver/provision/root.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -35,7 +35,6 @@
</span><span class="cx"> from twistedcaldav.resource import CalDAVComplianceMixIn
</span><span class="cx"> from txdav.who.wiki import DirectoryService as WikiDirectoryService
</span><span class="cx"> from txdav.who.wiki import uidForAuthToken
</span><del>-from txdav.xml import element as davxml
</del><span class="cx"> from txweb2 import responsecode
</span><span class="cx"> from txweb2.auth.wrapper import UnauthorizedResponse
</span><span class="cx"> from txweb2.dav.xattrprops import xattrPropertyStore
</span><span class="lines">@@ -146,7 +145,7 @@
</span><span class="cx">         # be a SACL group assigned to this service.  Let's see if
</span><span class="cx">         # unauthenticated users are allowed by calling CheckSACL
</span><span class="cx">         # with an empty string.
</span><del>-        if authzUser == davxml.Principal(davxml.Unauthenticated()):
</del><ins>+        if authzUser is None:
</ins><span class="cx">             for saclService in saclServices:
</span><span class="cx">                 if RootResource.CheckSACL(&quot;&quot;, saclService) == 0:
</span><span class="cx">                     # No group actually exists for this SACL, so allow
</span><span class="lines">@@ -166,22 +165,8 @@
</span><span class="cx">         request.authzUser = authzUser
</span><span class="cx"> 
</span><span class="cx">         # Figure out the &quot;username&quot; from the davxml.Principal object
</span><del>-        request.checkingSACL = True
</del><ins>+        username = authzUser.record.shortNames[0]
</ins><span class="cx"> 
</span><del>-        for collection in self.principalCollections():
-            principal = yield collection._principalForURI(
-                authzUser.children[0].children[0].data
-            )
-            if principal is None:
-                response = (yield UnauthorizedResponse.makeResponse(
-                    request.credentialFactories,
-                    request.remoteAddr
-                ))
-                raise HTTPError(response)
-
-        delattr(request, &quot;checkingSACL&quot;)
-        username = principal.record.shortNames[0]
-
</del><span class="cx">         access = False
</span><span class="cx">         for saclService in saclServices:
</span><span class="cx">             if RootResource.CheckSACL(username, saclService) == 0:
</span><span class="lines">@@ -278,21 +263,7 @@
</span><span class="cx">                         log.debug(
</span><span class="cx">                             &quot;Wiki lookup returned uid: {uid}&quot;, uid=uid
</span><span class="cx">                         )
</span><del>-                        principal = None
-                        directory = request.site.resource.getDirectory()
-                        record = yield directory.recordWithUID(uid)
-                        if record is not None:
-                            username = record.shortNames[0]
-                            log.debug(
-                                &quot;Wiki user record for user {user}: {record}&quot;,
-                                user=username, record=record
-                            )
-                            for collection in self.principalCollections():
-                                principal = (
-                                    yield collection.principalForRecord(record)
-                                )
-                                if principal is not None:
-                                    break
</del><ins>+                        principal = yield self.principalForUID(request, uid)
</ins><span class="cx"> 
</span><span class="cx">                         if principal:
</span><span class="cx">                             log.debug(
</span><span class="lines">@@ -300,14 +271,7 @@
</span><span class="cx">                                 &quot;being assigned to authnUser and authzUser&quot;,
</span><span class="cx">                                 record=record
</span><span class="cx">                             )
</span><del>-                            request.authzUser = request.authnUser = (
-                                davxml.Principal(
-                                    davxml.HRef.fromString(
-                                        &quot;/principals/__uids__/{}/&quot;
-                                        .format(record.uid)
-                                    )
-                                )
-                            )
</del><ins>+                            request.authzUser = request.authnUser = principal
</ins><span class="cx"> 
</span><span class="cx">         if not hasattr(request, &quot;authzUser&quot;) and config.WebCalendarAuthPath:
</span><span class="cx">             topLevel = request.path.strip(&quot;/&quot;).split(&quot;/&quot;)[0]
</span><span class="lines">@@ -366,26 +330,21 @@
</span><span class="cx">             # The authzuser value is set to that of the wiki principal if
</span><span class="cx">             # not already set.
</span><span class="cx">             if not hasattr(request, &quot;authzUser&quot;):
</span><del>-                wikiName = None
</del><ins>+                wikiUid = None
</ins><span class="cx">                 if segments[1] == &quot;wikis&quot;:
</span><del>-                    wikiName = segments[2]
</del><ins>+                    wikiUid = &quot;{}{}&quot;.format(WikiDirectoryService.uidPrefix, segments[2])
</ins><span class="cx">                 else:
</span><del>-                    wikiName = segments[2][5:]
-                if wikiName:
</del><ins>+                    wikiUid = segments[2]
+                if wikiUid:
</ins><span class="cx">                     log.debug(
</span><span class="cx">                         &quot;Wiki principal {name} being assigned to authzUser&quot;,
</span><del>-                        name=wikiName
</del><ins>+                        name=wikiUid
</ins><span class="cx">                     )
</span><del>-                    request.authzUser = davxml.Principal(
-                        davxml.HRef.fromString(
-                            &quot;/principals/wikis/{}/&quot;.format(wikiName)
-                        )
-                    )
</del><ins>+                    request.authzUser = yield self.principalForUID(request, wikiUid)
</ins><span class="cx"> 
</span><span class="cx">         elif (
</span><span class="cx">             self.useSacls and
</span><del>-            not hasattr(request, &quot;checkedSACL&quot;) and
-            not hasattr(request, &quot;checkingSACL&quot;)
</del><ins>+            not hasattr(request, &quot;checkedSACL&quot;)
</ins><span class="cx">         ):
</span><span class="cx">             yield self.checkSacl(request)
</span><span class="cx"> 
</span><span class="lines">@@ -442,6 +401,25 @@
</span><span class="cx">         returnValue(child)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+    @inlineCallbacks
+    def principalForUID(self, request, uid):
+        principal = None
+        directory = request.site.resource.getDirectory()
+        record = yield directory.recordWithUID(uid)
+        if record is not None:
+            username = record.shortNames[0]
+            log.debug(
+                &quot;Wiki user record for user {user}: {record}&quot;,
+                user=username, record=record
+            )
+            for collection in self.principalCollections():
+                principal = yield collection.principalForRecord(record)
+                if principal is not None:
+                    break
+
+        returnValue(principal)
+
+
</ins><span class="cx">     def http_COPY(self, request):
</span><span class="cx">         return responsecode.FORBIDDEN
</span><span class="cx"> 
</span></span></pre></div>
<a id="CalendarServertrunkcalendarserverprovisiontesttest_rootpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/provision/test/test_root.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/provision/test/test_root.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/calendarserver/provision/test/test_root.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -17,7 +17,6 @@
</span><span class="cx"> 
</span><span class="cx"> from twisted.internet.defer import inlineCallbacks, maybeDeferred, returnValue
</span><span class="cx"> 
</span><del>-from twext.who.idirectory import RecordType
</del><span class="cx"> from txweb2 import http_headers
</span><span class="cx"> from txweb2 import responsecode
</span><span class="cx"> from txdav.xml import element as davxml
</span><span class="lines">@@ -126,15 +125,12 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         self.actualRoot.useSacls = True
</span><span class="cx"> 
</span><del>-        record = yield self.directory.recordWithShortName(
-            RecordType.user,
-            u&quot;dreid&quot;
-        )
</del><ins>+        principal = yield self.actualRoot.findPrincipalForAuthID(&quot;dreid&quot;)
</ins><span class="cx">         request = SimpleStoreRequest(
</span><span class="cx">             self,
</span><span class="cx">             &quot;GET&quot;,
</span><span class="cx">             &quot;/principals/&quot;,
</span><del>-            authRecord=record
</del><ins>+            authPrincipal=principal
</ins><span class="cx">         )
</span><span class="cx"> 
</span><span class="cx">         resrc, segments = (yield maybeDeferred(
</span><span class="lines">@@ -150,11 +146,10 @@
</span><span class="cx">         self.assertEquals(segments, [])
</span><span class="cx"> 
</span><span class="cx">         self.assertEquals(
</span><del>-            request.authzUser,
</del><ins>+            request.authzUser.principalElement(),
</ins><span class="cx">             davxml.Principal(
</span><span class="cx">                 davxml.HRef(
</span><del>-                    &quot;/principals/__uids__/&quot;
-                    &quot;5FF60DAD-0BDE-4508-8C77-15F0CA5C8DD1/&quot;
</del><ins>+                    &quot;/principals/__uids__/5FF60DAD-0BDE-4508-8C77-15F0CA5C8DD1/&quot;
</ins><span class="cx">                 )
</span><span class="cx">             )
</span><span class="cx">         )
</span><span class="lines">@@ -170,16 +165,13 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         self.actualRoot.useSacls = True
</span><span class="cx"> 
</span><del>-        record = yield self.directory.recordWithShortName(
-            RecordType.user,
-            u&quot;wsanchez&quot;
-        )
</del><ins>+        principal = yield self.actualRoot.findPrincipalForAuthID(&quot;wsanchez&quot;)
</ins><span class="cx"> 
</span><span class="cx">         request = SimpleStoreRequest(
</span><span class="cx">             self,
</span><span class="cx">             &quot;GET&quot;,
</span><span class="cx">             &quot;/principals/&quot;,
</span><del>-            authRecord=record
</del><ins>+            authPrincipal=principal
</ins><span class="cx">         )
</span><span class="cx"> 
</span><span class="cx">         try:
</span><span class="lines">@@ -338,10 +330,7 @@
</span><span class="cx"> &lt;/D:prop&gt;
</span><span class="cx"> &lt;/D:propfind&gt;
</span><span class="cx"> &quot;&quot;&quot;
</span><del>-        record = yield self.directory.recordWithShortName(
-            RecordType.user,
-            u&quot;dreid&quot;
-        )
</del><ins>+        principal = yield self.actualRoot.findPrincipalForAuthID(&quot;dreid&quot;)
</ins><span class="cx"> 
</span><span class="cx">         request = SimpleStoreRequest(
</span><span class="cx">             self,
</span><span class="lines">@@ -350,7 +339,7 @@
</span><span class="cx">             headers=http_headers.Headers({
</span><span class="cx">                     'Depth': '1',
</span><span class="cx">             }),
</span><del>-            authRecord=record,
</del><ins>+            authPrincipal=principal,
</ins><span class="cx">             content=body
</span><span class="cx">         )
</span><span class="cx">         response = yield self.send(request)
</span><span class="lines">@@ -366,7 +355,7 @@
</span><span class="cx">             headers=http_headers.Headers({
</span><span class="cx">                     'Depth': '1',
</span><span class="cx">             }),
</span><del>-            authRecord=record,
</del><ins>+            authPrincipal=principal,
</ins><span class="cx">             content=body
</span><span class="cx">         )
</span><span class="cx">         response = yield self.send(request)
</span></span></pre></div>
<a id="CalendarServertrunkcalendarserverpushapplepushpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/push/applepush.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/push/applepush.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/calendarserver/push/applepush.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -872,20 +872,6 @@
</span><span class="cx">     http_GET = http_POST
</span><span class="cx"> 
</span><span class="cx">     @inlineCallbacks
</span><del>-    def principalFromRequest(self, request):
-        &quot;&quot;&quot;
-        Given an authenticated request, return the principal based on
-        request.authnUser
-        &quot;&quot;&quot;
-        principal = None
-        for collection in self.principalCollections():
-            data = request.authnUser.children[0].children[0].data
-            principal = yield collection._principalForURI(data)
-            if principal is not None:
-                returnValue(principal)
-
-
-    @inlineCallbacks
</del><span class="cx">     def processSubscription(self, request):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Given an authenticated request, use the token and key arguments
</span><span class="lines">@@ -913,8 +899,7 @@
</span><span class="cx">             msg = &quot;Invalid request: bad 'token' %s&quot; % (token,)
</span><span class="cx"> 
</span><span class="cx">         else:
</span><del>-            principal = yield self.principalFromRequest(request)
-            uid = principal.record.uid
</del><ins>+            uid = request.authnUser.record.uid
</ins><span class="cx">             try:
</span><span class="cx">                 yield self.addSubscription(token, key, uid, userAgent, host)
</span><span class="cx">                 code = responsecode.OK
</span></span></pre></div>
<a id="CalendarServertrunkcalendarservertaputilpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/tap/util.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/tap/util.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/calendarserver/tap/util.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -310,8 +310,6 @@
</span><span class="cx">             # If we get here with Kerberos, then authentication has already succeeded
</span><span class="cx">             returnValue(
</span><span class="cx">                 (
</span><del>-                    credentials.authnPrincipal.principalURL(),
-                    credentials.authzPrincipal.principalURL(),
</del><span class="cx">                     credentials.authnPrincipal,
</span><span class="cx">                     credentials.authzPrincipal,
</span><span class="cx">                 )
</span><span class="lines">@@ -320,8 +318,6 @@
</span><span class="cx">             if (yield credentials.authnPrincipal.record.verifyCredentials(credentials.credentials)):
</span><span class="cx">                 returnValue(
</span><span class="cx">                     (
</span><del>-                        credentials.authnPrincipal.principalURL(),
-                        credentials.authzPrincipal.principalURL(),
</del><span class="cx">                         credentials.authnPrincipal,
</span><span class="cx">                         credentials.authzPrincipal,
</span><span class="cx">                     )
</span></span></pre></div>
<a id="CalendarServertrunkcalendarserverwebcalresourcepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/webcal/resource.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/webcal/resource.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/calendarserver/webcal/resource.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -154,9 +154,7 @@
</span><span class="cx">         # Don't need to authenticate here because the ACL will have already
</span><span class="cx">         # required it.
</span><span class="cx">         #
</span><del>-        authenticatedPrincipalURL = str(
-            request.authnUser.childOfType(davxml.HRef)
-        )
</del><ins>+        authenticatedPrincipalURL = request.authnUser.principalURL()
</ins><span class="cx"> 
</span><span class="cx">         def queryValue(arg):
</span><span class="cx">             query = parse_qs(urlparse(request.uri).query, True)
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavauthkerbpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/authkerb.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/authkerb.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/twistedcaldav/authkerb.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -191,8 +191,6 @@
</span><span class="cx">                 raise error.UnauthorizedLogin(&quot;Bad credentials for: %s (%s: %s)&quot; % (pcreds.authnURI, ex[0], ex[1],))
</span><span class="cx">             else:
</span><span class="cx">                 return succeed((
</span><del>-                    pcreds.authnPrincipal.principalURL(),
-                    pcreds.authzPrincipal.principalURL(),
</del><span class="cx">                     pcreds.authnPrincipal,
</span><span class="cx">                     pcreds.authzPrincipal,
</span><span class="cx">                 ))
</span><span class="lines">@@ -332,8 +330,6 @@
</span><span class="cx">         creds = pcreds.credentials
</span><span class="cx">         if isinstance(creds, NegotiateCredentials):
</span><span class="cx">             return succeed((
</span><del>-                pcreds.authnPrincipal.principalURL(),
-                pcreds.authzPrincipal.principalURL(),
</del><span class="cx">                 pcreds.authnPrincipal,
</span><span class="cx">                 pcreds.authzPrincipal,
</span><span class="cx">             ))
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavcachepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/cache.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/cache.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/twistedcaldav/cache.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -142,7 +142,7 @@
</span><span class="cx">     log = Logger()
</span><span class="cx"> 
</span><span class="cx">     def _principalURI(self, principal):
</span><del>-        return str(principal.children[0])
</del><ins>+        return principal.principalURL() if principal is not None else &quot;unauthenticated&quot;
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def _uriNotFound(self, f, uri):
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavdirectoryutilpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/directory/util.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/directory/util.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/twistedcaldav/directory/util.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -32,7 +32,6 @@
</span><span class="cx"> from txweb2.dav.resource import DAVResource
</span><span class="cx"> from txweb2.http import StatusResponse
</span><span class="cx"> from twisted.internet.defer import inlineCallbacks, returnValue
</span><del>-from txdav.xml import element as davxml
</del><span class="cx"> from uuid import UUID, uuid5
</span><span class="cx"> from twisted.python.failure import Failure
</span><span class="cx"> from twisted.web.template import tags
</span><span class="lines">@@ -139,10 +138,10 @@
</span><span class="cx">         try:
</span><span class="cx">             _ignore_authnUser, authzUser = yield self.authenticate(request)
</span><span class="cx">         except Exception:
</span><del>-            authzUser = davxml.Principal(davxml.Unauthenticated())
</del><ins>+            authzUser = None
</ins><span class="cx"> 
</span><span class="cx">         # Turn 404 into 401
</span><del>-        if authzUser == davxml.Principal(davxml.Unauthenticated()):
</del><ins>+        if authzUser is None:
</ins><span class="cx">             response = (yield UnauthorizedResponse.makeResponse(
</span><span class="cx">                 request.credentialFactories,
</span><span class="cx">                 request.remoteAddr
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavtesttest_addressbookmultigetpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/test/test_addressbookmultiget.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/test/test_addressbookmultiget.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/twistedcaldav/test/test_addressbookmultiget.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -31,7 +31,6 @@
</span><span class="cx"> from twisted.internet.defer import inlineCallbacks, returnValue
</span><span class="cx"> 
</span><span class="cx"> from txdav.xml import element as davxml
</span><del>-from twext.who.idirectory import RecordType
</del><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -46,7 +45,7 @@
</span><span class="cx">     @inlineCallbacks
</span><span class="cx">     def setUp(self):
</span><span class="cx">         yield StoreTestCase.setUp(self)
</span><del>-        self.authRecord = yield self.directory.recordWithShortName(RecordType.user, u&quot;wsanchez&quot;)
</del><ins>+        self.authPrincipal = yield self.actualRoot.findPrincipalForAuthID(&quot;wsanchez&quot;)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def test_multiget_some_vcards(self):
</span><span class="lines">@@ -217,7 +216,7 @@
</span><span class="cx"> &lt;/D:set&gt;
</span><span class="cx"> &lt;/D:mkcol&gt;
</span><span class="cx"> &quot;&quot;&quot;
</span><del>-            response = yield self.send(SimpleStoreRequest(self, &quot;MKCOL&quot;, addressbook_uri, content=mkcol, authRecord=self.authRecord))
</del><ins>+            response = yield self.send(SimpleStoreRequest(self, &quot;MKCOL&quot;, addressbook_uri, content=mkcol, authPrincipal=self.authPrincipal))
</ins><span class="cx"> 
</span><span class="cx">             response = IResponse(response)
</span><span class="cx"> 
</span><span class="lines">@@ -231,7 +230,7 @@
</span><span class="cx">                         &quot;PUT&quot;,
</span><span class="cx">                         joinURL(addressbook_uri, filename + &quot;.vcf&quot;),
</span><span class="cx">                         headers=Headers({&quot;content-type&quot;: MimeType.fromString(&quot;text/vcard&quot;)}),
</span><del>-                        authRecord=self.authRecord
</del><ins>+                        authPrincipal=self.authPrincipal
</ins><span class="cx">                     )
</span><span class="cx">                     request.stream = MemoryStream(icaldata)
</span><span class="cx">                     yield self.send(request)
</span><span class="lines">@@ -245,12 +244,12 @@
</span><span class="cx">                         &quot;PUT&quot;,
</span><span class="cx">                         joinURL(addressbook_uri, child.basename()),
</span><span class="cx">                         headers=Headers({&quot;content-type&quot;: MimeType.fromString(&quot;text/vcard&quot;)}),
</span><del>-                        authRecord=self.authRecord
</del><ins>+                        authPrincipal=self.authPrincipal
</ins><span class="cx">                     )
</span><span class="cx">                     request.stream = MemoryStream(child.getContent())
</span><span class="cx">                     yield self.send(request)
</span><span class="cx"> 
</span><del>-        request = SimpleStoreRequest(self, &quot;REPORT&quot;, addressbook_uri, authRecord=self.authRecord)
</del><ins>+        request = SimpleStoreRequest(self, &quot;REPORT&quot;, addressbook_uri, authPrincipal=self.authPrincipal)
</ins><span class="cx">         request.stream = MemoryStream(query.toxml())
</span><span class="cx">         response = yield self.send(request)
</span><span class="cx"> 
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavtesttest_addressbookquerypy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/test/test_addressbookquery.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/test/test_addressbookquery.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/twistedcaldav/test/test_addressbookquery.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -27,7 +27,6 @@
</span><span class="cx"> from twistedcaldav.test.util import StoreTestCase, SimpleStoreRequest
</span><span class="cx"> from twisted.internet.defer import inlineCallbacks, returnValue
</span><span class="cx"> from twisted.python.filepath import FilePath
</span><del>-from twext.who.idirectory import RecordType
</del><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -196,16 +195,16 @@
</span><span class="cx">         if response.code != responsecode.CREATED:
</span><span class="cx">             self.fail(&quot;MKCOL failed: %s&quot; % (response.code,))
</span><span class="cx">         '''
</span><del>-        authRecord = yield self.directory.recordWithShortName(RecordType.user, u&quot;wsanchez&quot;)
</del><ins>+        principal = yield self.actualRoot.findPrincipalForAuthID(&quot;wsanchez&quot;)
</ins><span class="cx">         # Add vCards to addressbook
</span><span class="cx">         for child in FilePath(self.vcards_dir).children():
</span><span class="cx">             if os.path.splitext(child.basename())[1] != &quot;.vcf&quot;:
</span><span class="cx">                 continue
</span><del>-            request = SimpleStoreRequest(self, &quot;PUT&quot;, joinURL(addressbook_uri, child.basename()), authRecord=authRecord)
</del><ins>+            request = SimpleStoreRequest(self, &quot;PUT&quot;, joinURL(addressbook_uri, child.basename()), authPrincipal=principal)
</ins><span class="cx">             request.stream = MemoryStream(child.getContent())
</span><span class="cx">             yield self.send(request)
</span><span class="cx"> 
</span><del>-        request = SimpleStoreRequest(self, &quot;REPORT&quot;, addressbook_uri, authRecord=authRecord)
</del><ins>+        request = SimpleStoreRequest(self, &quot;REPORT&quot;, addressbook_uri, authPrincipal=principal)
</ins><span class="cx">         request.stream = MemoryStream(query.toxml())
</span><span class="cx">         response = yield self.send(request)
</span><span class="cx"> 
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavtesttest_cachepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/test/test_cache.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/test/test_cache.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/twistedcaldav/test/test_cache.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -24,14 +24,13 @@
</span><span class="cx"> from txweb2.stream import MemoryStream
</span><span class="cx"> from txweb2.http_headers import Headers
</span><span class="cx"> 
</span><del>-from txdav.xml import element as davxml
-
</del><span class="cx"> from twistedcaldav.cache import MemcacheResponseCache, CacheStoreNotifier
</span><span class="cx"> from twistedcaldav.cache import MemcacheChangeNotifier
</span><span class="cx"> from twistedcaldav.cache import PropfindCacheMixin
</span><span class="cx"> 
</span><span class="cx"> from twistedcaldav.test.util import InMemoryMemcacheProtocol
</span><span class="cx"> from twistedcaldav.test.util import TestCase
</span><ins>+from txdav.xml import element
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> def _newCacheToken(self):
</span><span class="lines">@@ -90,13 +89,27 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+class StubPrincipal(object):
+    def __init__(self, user):
+        self.user = user
+
+
+    def principalURL(self):
+        return self.user
+
+
+    def principalElement(self):
+        return element.Principal(element.HRef.fromString(self.user))
+
+
+
</ins><span class="cx"> class StubRequest(object):
</span><span class="cx">     resources = {}
</span><span class="cx"> 
</span><span class="cx">     def __init__(self, method, uri, authnUser, depth='1', body=None):
</span><span class="cx">         self.method = method
</span><span class="cx">         self.uri = uri
</span><del>-        self.authnUser = davxml.Principal(davxml.HRef.fromString(authnUser))
</del><ins>+        self.authnUser = StubPrincipal(authnUser)
</ins><span class="cx">         self.headers = Headers({'depth': depth})
</span><span class="cx"> 
</span><span class="cx">         if body is None:
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavtesttest_calendarquerypy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/test/test_calendarquery.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/test/test_calendarquery.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/twistedcaldav/test/test_calendarquery.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -345,8 +345,8 @@
</span><span class="cx">     @inlineCallbacks
</span><span class="cx">     def calendar_query(self, query, got_xml):
</span><span class="cx"> 
</span><del>-        authRecord = yield self.directory.recordWithShortName(RecordType.user, u&quot;wsanchez&quot;)
-        request = SimpleStoreRequest(self, &quot;REPORT&quot;, &quot;/calendars/users/wsanchez/calendar/&quot;, authRecord=authRecord)
</del><ins>+        principal = yield self.actualRoot.findPrincipalForAuthID(&quot;wsanchez&quot;)
+        request = SimpleStoreRequest(self, &quot;REPORT&quot;, &quot;/calendars/users/wsanchez/calendar/&quot;, authPrincipal=principal)
</ins><span class="cx">         request.stream = MemoryStream(query.toxml())
</span><span class="cx">         response = yield self.send(request)
</span><span class="cx"> 
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavtesttest_collectioncontentspy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/test/test_collectioncontents.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/test/test_collectioncontents.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/twistedcaldav/test/test_collectioncontents.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -15,7 +15,6 @@
</span><span class="cx"> ##
</span><span class="cx"> 
</span><span class="cx"> from twext.python.filepath import CachingFilePath as FilePath
</span><del>-from twext.who.idirectory import RecordType
</del><span class="cx"> from twisted.internet.defer import inlineCallbacks
</span><span class="cx"> from twistedcaldav.ical import Component
</span><span class="cx"> from twistedcaldav.memcachelock import MemcacheLock
</span><span class="lines">@@ -68,15 +67,15 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         calendar_uri = &quot;/calendars/users/wsanchez/collection_in_calendar/&quot;
</span><span class="cx"> 
</span><del>-        authRecord = yield self.directory.recordWithShortName(RecordType.user, u&quot;wsanchez&quot;)
-        request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, calendar_uri, authRecord=authRecord)
</del><ins>+        principal = yield self.actualRoot.findPrincipalForAuthID(&quot;wsanchez&quot;)
+        request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, calendar_uri, authPrincipal=principal)
</ins><span class="cx">         response = yield self.send(request)
</span><span class="cx">         response = IResponse(response)
</span><span class="cx">         if response.code != responsecode.CREATED:
</span><span class="cx">             self.fail(&quot;MKCALENDAR failed: %s&quot; % (response.code,))
</span><span class="cx">             nested_uri = joinURL(calendar_uri, &quot;nested&quot;)
</span><span class="cx"> 
</span><del>-            request = SimpleStoreRequest(self, &quot;MKCOL&quot;, nested_uri, authRecord=authRecord)
</del><ins>+            request = SimpleStoreRequest(self, &quot;MKCOL&quot;, nested_uri, authPrincipal=principal)
</ins><span class="cx">             response = yield self.send(request)
</span><span class="cx">             response = IResponse(response)
</span><span class="cx"> 
</span><span class="lines">@@ -168,8 +167,8 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         calendar_uri = &quot;/calendars/users/wsanchez/testing_calendar/&quot;
</span><span class="cx"> 
</span><del>-        authRecord = yield self.directory.recordWithShortName(RecordType.user, u&quot;wsanchez&quot;)
-        request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, calendar_uri, authRecord=authRecord)
</del><ins>+        principal = yield self.actualRoot.findPrincipalForAuthID(&quot;wsanchez&quot;)
+        request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, calendar_uri, authPrincipal=principal)
</ins><span class="cx">         response = yield self.send(request)
</span><span class="cx">         response = IResponse(response)
</span><span class="cx">         if response.code != responsecode.CREATED:
</span><span class="lines">@@ -178,7 +177,7 @@
</span><span class="cx">         c = 0
</span><span class="cx">         for stream, response_code in work:
</span><span class="cx">             dst_uri = joinURL(calendar_uri, &quot;dst%d.ics&quot; % (c,))
</span><del>-            request = SimpleStoreRequest(self, &quot;PUT&quot;, dst_uri, authRecord=authRecord)
</del><ins>+            request = SimpleStoreRequest(self, &quot;PUT&quot;, dst_uri, authPrincipal=principal)
</ins><span class="cx">             request.headers.setHeader(&quot;if-none-match&quot;, &quot;*&quot;)
</span><span class="cx">             request.headers.setHeader(&quot;content-type&quot;, MimeType(&quot;text&quot;, &quot;calendar&quot;))
</span><span class="cx">             request.stream = stream
</span><span class="lines">@@ -197,8 +196,8 @@
</span><span class="cx">         Make (regular) collection in calendar
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         calendar_uri = &quot;/calendars/users/wsanchez/dot_file_in_calendar/&quot;
</span><del>-        authRecord = yield self.directory.recordWithShortName(RecordType.user, u&quot;wsanchez&quot;)
-        request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, calendar_uri, authRecord=authRecord)
</del><ins>+        principal = yield self.actualRoot.findPrincipalForAuthID(&quot;wsanchez&quot;)
+        request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, calendar_uri, authPrincipal=principal)
</ins><span class="cx">         response = yield self.send(request)
</span><span class="cx">         response = IResponse(response)
</span><span class="cx">         if response.code != responsecode.CREATED:
</span><span class="lines">@@ -215,7 +214,7 @@
</span><span class="cx"> 
</span><span class="cx">         event_uri = &quot;/&quot;.join([calendar_uri, &quot;.event.ics&quot;])
</span><span class="cx"> 
</span><del>-        request = SimpleStoreRequest(self, &quot;PUT&quot;, event_uri, authRecord=authRecord)
</del><ins>+        request = SimpleStoreRequest(self, &quot;PUT&quot;, event_uri, authPrincipal=principal)
</ins><span class="cx">         request.headers.setHeader(&quot;content-type&quot;, MimeType(&quot;text&quot;, &quot;calendar&quot;))
</span><span class="cx">         request.stream = MemoryStream(calendar)
</span><span class="cx">         response = yield self.send(request)
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavtesttest_mkcalendarpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/test/test_mkcalendar.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/test/test_mkcalendar.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/twistedcaldav/test/test_mkcalendar.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -27,10 +27,8 @@
</span><span class="cx"> from twistedcaldav import caldavxml
</span><span class="cx"> from twistedcaldav.test.util import StoreTestCase, SimpleStoreRequest
</span><span class="cx"> 
</span><del>-from twext.who.idirectory import RecordType
</del><span class="cx"> 
</span><span class="cx"> 
</span><del>-
</del><span class="cx"> class MKCALENDAR (StoreTestCase):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     MKCALENDAR request
</span><span class="lines">@@ -42,7 +40,7 @@
</span><span class="cx">     @inlineCallbacks
</span><span class="cx">     def setUp(self):
</span><span class="cx">         yield StoreTestCase.setUp(self)
</span><del>-        self.authRecord = yield self.directory.recordWithShortName(RecordType.user, u&quot;user01&quot;)
</del><ins>+        self.authPrincipal = yield self.actualRoot.findPrincipalForAuthID(&quot;user01&quot;)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def test_make_calendar(self):
</span><span class="lines">@@ -55,7 +53,7 @@
</span><span class="cx">         if os.path.exists(path):
</span><span class="cx">             rmdir(path)
</span><span class="cx"> 
</span><del>-        request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, uri, authRecord=self.authRecord)
</del><ins>+        request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, uri, authPrincipal=self.authPrincipal)
</ins><span class="cx"> 
</span><span class="cx">         @inlineCallbacks
</span><span class="cx">         def do_test(response):
</span><span class="lines">@@ -156,7 +154,7 @@
</span><span class="cx">             )
</span><span class="cx">         )
</span><span class="cx"> 
</span><del>-        request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, uri, authRecord=self.authRecord)
</del><ins>+        request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, uri, authPrincipal=self.authPrincipal)
</ins><span class="cx">         request.stream = MemoryStream(mk.toxml())
</span><span class="cx">         return self.send(request, do_test)
</span><span class="cx"> 
</span><span class="lines">@@ -175,7 +173,7 @@
</span><span class="cx"> 
</span><span class="cx">             # FIXME: Check for DAV:resource-must-be-null element
</span><span class="cx"> 
</span><del>-        request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, uri, authRecord=self.authRecord)
</del><ins>+        request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, uri, authPrincipal=self.authPrincipal)
</ins><span class="cx">         return self.send(request, do_test)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -200,8 +198,8 @@
</span><span class="cx"> 
</span><span class="cx">             nested_uri = os.path.join(first_uri, &quot;nested&quot;)
</span><span class="cx"> 
</span><del>-            request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, nested_uri, authRecord=self.authRecord)
</del><ins>+            request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, nested_uri, authPrincipal=self.authPrincipal)
</ins><span class="cx">             yield self.send(request, do_test)
</span><span class="cx"> 
</span><del>-        request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, first_uri, authRecord=self.authRecord)
</del><ins>+        request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, first_uri, authPrincipal=self.authPrincipal)
</ins><span class="cx">         return self.send(request, next)
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavtesttest_multigetpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/test/test_multiget.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/test/test_multiget.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/twistedcaldav/test/test_multiget.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -14,7 +14,6 @@
</span><span class="cx"> ##
</span><span class="cx"> 
</span><span class="cx"> from twext.python.filepath import CachingFilePath as FilePath
</span><del>-from twext.who.idirectory import RecordType
</del><span class="cx"> from txweb2 import responsecode
</span><span class="cx"> from txweb2.dav.util import davXMLFromStream, joinURL
</span><span class="cx"> from txweb2.http_headers import Headers, MimeType
</span><span class="lines">@@ -42,7 +41,7 @@
</span><span class="cx">     @inlineCallbacks
</span><span class="cx">     def setUp(self):
</span><span class="cx">         yield StoreTestCase.setUp(self)
</span><del>-        self.authRecord = yield self.directory.recordWithShortName(RecordType.user, u&quot;wsanchez&quot;)
</del><ins>+        self.authPrincipal = yield self.actualRoot.findPrincipalForAuthID(&quot;wsanchez&quot;)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def test_multiget_some_events(self):
</span><span class="lines">@@ -269,7 +268,7 @@
</span><span class="cx">     def calendar_query(self, calendar_uri, query, got_xml, data, no_init):
</span><span class="cx"> 
</span><span class="cx">         if not no_init:
</span><del>-            response = yield self.send(SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, calendar_uri, authRecord=self.authRecord))
</del><ins>+            response = yield self.send(SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, calendar_uri, authPrincipal=self.authPrincipal))
</ins><span class="cx">             response = IResponse(response)
</span><span class="cx">             if response.code != responsecode.CREATED:
</span><span class="cx">                 self.fail(&quot;MKCALENDAR failed: %s&quot; % (response.code,))
</span><span class="lines">@@ -281,7 +280,7 @@
</span><span class="cx">                         &quot;PUT&quot;,
</span><span class="cx">                         joinURL(calendar_uri, filename + &quot;.ics&quot;),
</span><span class="cx">                         headers=Headers({&quot;content-type&quot;: MimeType.fromString(&quot;text/calendar&quot;)}),
</span><del>-                        authRecord=self.authRecord
</del><ins>+                        authPrincipal=self.authPrincipal
</ins><span class="cx">                     )
</span><span class="cx">                     request.stream = MemoryStream(icaldata)
</span><span class="cx">                     yield self.send(request)
</span><span class="lines">@@ -295,12 +294,12 @@
</span><span class="cx">                         &quot;PUT&quot;,
</span><span class="cx">                         joinURL(calendar_uri, child.basename()),
</span><span class="cx">                         headers=Headers({&quot;content-type&quot;: MimeType.fromString(&quot;text/calendar&quot;)}),
</span><del>-                        authRecord=self.authRecord
</del><ins>+                        authPrincipal=self.authPrincipal
</ins><span class="cx">                     )
</span><span class="cx">                     request.stream = MemoryStream(child.getContent())
</span><span class="cx">                     yield self.send(request)
</span><span class="cx"> 
</span><del>-        request = SimpleStoreRequest(self, &quot;REPORT&quot;, calendar_uri, authRecord=self.authRecord)
</del><ins>+        request = SimpleStoreRequest(self, &quot;REPORT&quot;, calendar_uri, authPrincipal=self.authPrincipal)
</ins><span class="cx">         request.stream = MemoryStream(query.toxml())
</span><span class="cx">         response = yield self.send(request)
</span><span class="cx"> 
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavtesttest_propspy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/test/test_props.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/test/test_props.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/twistedcaldav/test/test_props.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -26,10 +26,8 @@
</span><span class="cx"> 
</span><span class="cx"> from txdav.xml import element as davxml
</span><span class="cx"> 
</span><del>-from twext.who.idirectory import RecordType
</del><span class="cx"> 
</span><span class="cx"> 
</span><del>-
</del><span class="cx"> class Properties(StoreTestCase):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     CalDAV properties
</span><span class="lines">@@ -38,7 +36,7 @@
</span><span class="cx">     @inlineCallbacks
</span><span class="cx">     def setUp(self):
</span><span class="cx">         yield StoreTestCase.setUp(self)
</span><del>-        self.authRecord = yield self.directory.recordWithShortName(RecordType.user, u&quot;user01&quot;)
</del><ins>+        self.authPrincipal = yield self.actualRoot.findPrincipalForAuthID(&quot;user01&quot;)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def test_live_props(self):
</span><span class="lines">@@ -149,12 +147,12 @@
</span><span class="cx">                 &quot;PROPFIND&quot;,
</span><span class="cx">                 calendar_uri,
</span><span class="cx">                 headers=http_headers.Headers({&quot;Depth&quot;: &quot;0&quot;}),
</span><del>-                authRecord=self.authRecord,
</del><ins>+                authPrincipal=self.authPrincipal,
</ins><span class="cx">             )
</span><span class="cx">             request.stream = MemoryStream(query.toxml())
</span><span class="cx">             return self.send(request, propfind_cb)
</span><span class="cx"> 
</span><del>-        request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, calendar_uri, authRecord=self.authRecord)
</del><ins>+        request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, calendar_uri, authPrincipal=self.authPrincipal)
</ins><span class="cx">         return self.send(request, mkcalendar_cb)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -221,10 +219,10 @@
</span><span class="cx">                 &quot;PROPFIND&quot;,
</span><span class="cx">                 calendar_uri,
</span><span class="cx">                 headers=http_headers.Headers({&quot;Depth&quot;: &quot;0&quot;}),
</span><del>-                authRecord=self.authRecord,
</del><ins>+                authPrincipal=self.authPrincipal,
</ins><span class="cx">             )
</span><span class="cx">             request.stream = MemoryStream(query.toxml())
</span><span class="cx">             return self.send(request, propfind_cb)
</span><span class="cx"> 
</span><del>-        request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, calendar_uri, authRecord=self.authRecord)
</del><ins>+        request = SimpleStoreRequest(self, &quot;MKCALENDAR&quot;, calendar_uri, authPrincipal=self.authPrincipal)
</ins><span class="cx">         return self.send(request, mkcalendar_cb)
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavtesttest_resourcepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/test/test_resource.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/test/test_resource.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/twistedcaldav/test/test_resource.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -14,7 +14,6 @@
</span><span class="cx"> # limitations under the License.
</span><span class="cx"> ##
</span><span class="cx"> 
</span><del>-from twext.who.idirectory import RecordType
</del><span class="cx"> from twisted.internet.defer import inlineCallbacks
</span><span class="cx"> from twistedcaldav import carddavxml
</span><span class="cx"> from twistedcaldav.config import config
</span><span class="lines">@@ -27,9 +26,10 @@
</span><span class="cx">     InMemoryPropertyStore, StoreTestCase, SimpleStoreRequest
</span><span class="cx"> )
</span><span class="cx"> from twistedcaldav.test.util import TestCase
</span><del>-from txdav.xml.element import HRef, Principal, Unauthenticated
</del><ins>+from txdav.xml.element import HRef
</ins><span class="cx"> from txweb2.http import HTTPError
</span><span class="cx"> from txweb2.test.test_server import SimpleRequest
</span><ins>+from txdav.xml import element
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -61,6 +61,16 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+class StubPrincipal(object):
+    def __init__(self, user):
+        self.user = user
+
+
+    def principalElement(self):
+        return element.Principal(element.HRef.fromString(self.user))
+
+
+
</ins><span class="cx"> class CalDAVResourceTests(TestCase):
</span><span class="cx">     def setUp(self):
</span><span class="cx">         TestCase.setUp(self)
</span><span class="lines">@@ -115,7 +125,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         site = None
</span><span class="cx">         request = SimpleRequest(site, &quot;GET&quot;, &quot;/not/a/real/url/&quot;)
</span><del>-        request.authzUser = request.authnUser = Principal(Unauthenticated())
</del><ins>+        request.authzUser = request.authnUser = None
</ins><span class="cx">         rsrc = CalDAVResource()
</span><span class="cx">         rsrc.owner = lambda igreq: HRef(&quot;/somebody/&quot;)
</span><span class="cx">         self.assertEquals((yield rsrc.isOwner(request)), False)
</span><span class="lines">@@ -129,8 +139,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         site = None
</span><span class="cx">         request = SimpleRequest(site, &quot;GET&quot;, &quot;/not/a/real/url/&quot;)
</span><del>-        theOwner = Principal(HRef(&quot;/yes-i-am-the-owner/&quot;))
-        request.authzUser = request.authnUser = theOwner
</del><ins>+        request.authzUser = request.authnUser = StubPrincipal(&quot;/yes-i-am-the-owner/&quot;)
</ins><span class="cx">         rsrc = CalDAVResource()
</span><span class="cx">         rsrc.owner = lambda igreq: HRef(&quot;/no-i-am-not-the-owner/&quot;)
</span><span class="cx">         self.assertEquals((yield rsrc.isOwner(request)), False)
</span><span class="lines">@@ -144,8 +153,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         site = None
</span><span class="cx">         request = SimpleRequest(site, &quot;GET&quot;, &quot;/not/a/real/url/&quot;)
</span><del>-        theOwner = Principal(HRef(&quot;/yes-i-am-the-owner/&quot;))
-        request.authzUser = request.authnUser = theOwner
</del><ins>+        request.authzUser = request.authnUser = StubPrincipal(&quot;/yes-i-am-the-owner/&quot;)
</ins><span class="cx">         rsrc = CalDAVResource()
</span><span class="cx">         rsrc.owner = lambda igreq: HRef(&quot;/yes-i-am-the-owner/&quot;)
</span><span class="cx">         self.assertEquals((yield rsrc.isOwner(request)), True)
</span><span class="lines">@@ -162,7 +170,7 @@
</span><span class="cx">         self.patch(config, &quot;AdminPrincipals&quot;, [theAdmin])
</span><span class="cx">         site = None
</span><span class="cx">         request = SimpleRequest(site, &quot;GET&quot;, &quot;/not/a/real/url/&quot;)
</span><del>-        request.authzUser = request.authnUser = Principal(HRef(theAdmin))
</del><ins>+        request.authzUser = request.authnUser = StubPrincipal(theAdmin)
</ins><span class="cx">         rsrc = CalDAVResource()
</span><span class="cx">         rsrc.owner = lambda igreq: HRef(&quot;/some-other-user/&quot;)
</span><span class="cx">         self.assertEquals((yield rsrc.isOwner(request)), True)
</span><span class="lines">@@ -179,7 +187,7 @@
</span><span class="cx">         self.patch(config, &quot;ReadPrincipals&quot;, [theAdmin])
</span><span class="cx">         site = None
</span><span class="cx">         request = SimpleRequest(site, &quot;GET&quot;, &quot;/not/a/real/url/&quot;)
</span><del>-        request.authzUser = request.authnUser = Principal(HRef(theAdmin))
</del><ins>+        request.authzUser = request.authnUser = StubPrincipal(theAdmin)
</ins><span class="cx">         rsrc = CalDAVResource()
</span><span class="cx">         rsrc.owner = lambda igreq: HRef(&quot;/some-other-user/&quot;)
</span><span class="cx">         self.assertEquals((yield rsrc.isOwner(request)), True)
</span><span class="lines">@@ -192,7 +200,7 @@
</span><span class="cx">     @inlineCallbacks
</span><span class="cx">     def setUp(self):
</span><span class="cx">         yield StoreTestCase.setUp(self)
</span><del>-        self.authRecord = yield self.directory.recordWithShortName(RecordType.user, u&quot;wsanchez&quot;)
</del><ins>+        self.authPrincipal = yield self.actualRoot.findPrincipalForAuthID(&quot;wsanchez&quot;)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     @inlineCallbacks
</span><span class="lines">@@ -201,7 +209,7 @@
</span><span class="cx">         Get adbk
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-        request = SimpleStoreRequest(self, &quot;GET&quot;, &quot;/addressbooks/users/wsanchez/&quot;, authRecord=self.authRecord)
</del><ins>+        request = SimpleStoreRequest(self, &quot;GET&quot;, &quot;/addressbooks/users/wsanchez/&quot;, authPrincipal=self.authPrincipal)
</ins><span class="cx">         home = yield request.locateResource(&quot;/addressbooks/users/wsanchez&quot;)
</span><span class="cx"> 
</span><span class="cx">         # default property initially not present
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavtesttest_sharingpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/test/test_sharing.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/test/test_sharing.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/twistedcaldav/test/test_sharing.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -84,8 +84,8 @@
</span><span class="cx"> 
</span><span class="cx">     @inlineCallbacks
</span><span class="cx">     def _doPOST(self, body, resultcode=responsecode.OK):
</span><del>-        authRecord = yield self.directory.recordWithUID(u&quot;user01&quot;)
-        request = SimpleStoreRequest(self, &quot;POST&quot;, &quot;/calendars/__uids__/user01/calendar/&quot;, content=body, authRecord=authRecord)
</del><ins>+        authPrincipal = yield self.actualRoot.findPrincipalForAuthID(&quot;user01&quot;)
+        request = SimpleStoreRequest(self, &quot;POST&quot;, &quot;/calendars/__uids__/user01/calendar/&quot;, content=body, authPrincipal=authPrincipal)
</ins><span class="cx">         request.headers.setHeader(&quot;content-type&quot;, MimeType(&quot;text&quot;, &quot;xml&quot;))
</span><span class="cx">         response = yield self.send(request)
</span><span class="cx">         response = IResponse(response)
</span><span class="lines">@@ -110,8 +110,8 @@
</span><span class="cx"> 
</span><span class="cx">     @inlineCallbacks
</span><span class="cx">     def _doPOSTSharerAccept(self, body, resultcode=responsecode.OK, sharer=&quot;user02&quot;):
</span><del>-        authRecord = yield self.directory.recordWithUID(unicode(sharer))
-        request = SimpleStoreRequest(self, &quot;POST&quot;, &quot;/calendars/__uids__/{}/&quot;.format(sharer), content=body, authRecord=authRecord)
</del><ins>+        authPrincipal = yield self.actualRoot.findPrincipalForAuthID(sharer)
+        request = SimpleStoreRequest(self, &quot;POST&quot;, &quot;/calendars/__uids__/{}/&quot;.format(sharer), content=body, authPrincipal=authPrincipal)
</ins><span class="cx">         request.headers.setHeader(&quot;content-type&quot;, MimeType(&quot;text&quot;, &quot;xml&quot;))
</span><span class="cx">         response = yield self.send(request)
</span><span class="cx">         response = IResponse(response)
</span><span class="lines">@@ -712,8 +712,8 @@
</span><span class="cx"> 
</span><span class="cx">         @inlineCallbacks
</span><span class="cx">         def listChildrenViaPropfind():
</span><del>-            authRecord = yield self.directory.recordWithUID(u&quot;user01&quot;)
-            request = SimpleStoreRequest(self, &quot;PROPFIND&quot;, &quot;/calendars/__uids__/user01/&quot;, authRecord=authRecord)
</del><ins>+            authPrincipal = yield self.actualRoot.findPrincipalForAuthID(&quot;user01&quot;)
+            request = SimpleStoreRequest(self, &quot;PROPFIND&quot;, &quot;/calendars/__uids__/user01/&quot;, authPrincipal=authPrincipal)
</ins><span class="cx">             request.headers.setHeader(&quot;depth&quot;, &quot;1&quot;)
</span><span class="cx">             response = yield self.send(request)
</span><span class="cx">             response = IResponse(response)
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavtesttest_wrappingpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/test/test_wrapping.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/test/test_wrapping.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/twistedcaldav/test/test_wrapping.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -175,11 +175,8 @@
</span><span class="cx">             &quot;http://localhost:8008/&quot; + path
</span><span class="cx">         )
</span><span class="cx">         if user is not None:
</span><del>-            record = yield self.directory.recordWithShortName(RecordType.user, user)
-            uid = record.uid
-            req.authnUser = req.authzUser = (
-                davxml.Principal(davxml.HRef('/principals/__uids__/' + uid + '/'))
-            )
</del><ins>+            principal = yield self.actualRoot.findPrincipalForAuthID(user)
+            req.authnUser = req.authzUser = principal
</ins><span class="cx">         returnValue(aResource)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -585,13 +582,13 @@
</span><span class="cx">         yield NamedLock.acquire(txn, &quot;ImplicitUIDLock:%s&quot; % (hashlib.md5(&quot;uid1&quot;).hexdigest(),))
</span><span class="cx"> 
</span><span class="cx">         # PUT fails
</span><del>-        authRecord = yield self.directory.recordWithShortName(RecordType.user, u&quot;wsanchez&quot;)
</del><ins>+        principal = yield self.actualRoot.findPrincipalForAuthID(&quot;wsanchez&quot;)
</ins><span class="cx">         request = SimpleStoreRequest(
</span><span class="cx">             self,
</span><span class="cx">             &quot;PUT&quot;,
</span><span class="cx">             &quot;/calendars/users/wsanchez/calendar/1.ics&quot;,
</span><span class="cx">             headers=Headers({&quot;content-type&quot;: MimeType.fromString(&quot;text/calendar&quot;)}),
</span><del>-            authRecord=authRecord
</del><ins>+            authPrincipal=principal
</ins><span class="cx">         )
</span><span class="cx">         request.stream = MemoryStream(&quot;&quot;&quot;BEGIN:VCALENDAR
</span><span class="cx"> CALSCALE:GREGORIAN
</span><span class="lines">@@ -617,13 +614,13 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="cx">         # PUT works
</span><del>-        authRecord = yield self.directory.recordWithShortName(RecordType.user, u&quot;wsanchez&quot;)
</del><ins>+        principal = yield self.actualRoot.findPrincipalForAuthID(&quot;wsanchez&quot;)
</ins><span class="cx">         request = SimpleStoreRequest(
</span><span class="cx">             self,
</span><span class="cx">             &quot;PUT&quot;,
</span><span class="cx">             &quot;/calendars/users/wsanchez/calendar/1.ics&quot;,
</span><span class="cx">             headers=Headers({&quot;content-type&quot;: MimeType.fromString(&quot;text/calendar&quot;)}),
</span><del>-            authRecord=authRecord
</del><ins>+            authPrincipal=principal
</ins><span class="cx">         )
</span><span class="cx">         request.stream = MemoryStream(&quot;&quot;&quot;BEGIN:VCALENDAR
</span><span class="cx"> CALSCALE:GREGORIAN
</span><span class="lines">@@ -647,12 +644,11 @@
</span><span class="cx">         txn = self.transactionUnderTest()
</span><span class="cx">         yield NamedLock.acquire(txn, &quot;ImplicitUIDLock:%s&quot; % (hashlib.md5(&quot;uid1&quot;).hexdigest(),))
</span><span class="cx"> 
</span><del>-        authRecord = yield self.directory.recordWithShortName(RecordType.user, u&quot;wsanchez&quot;)
</del><span class="cx">         request = SimpleStoreRequest(
</span><span class="cx">             self,
</span><span class="cx">             &quot;DELETE&quot;,
</span><span class="cx">             &quot;/calendars/users/wsanchez/calendar/1.ics&quot;,
</span><del>-            authRecord=authRecord
</del><ins>+            authPrincipal=principal
</ins><span class="cx">         )
</span><span class="cx">         response = yield self.send(request)
</span><span class="cx">         self.assertEqual(response.code, responsecode.SERVICE_UNAVAILABLE)
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavtestutilpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/test/util.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/test/util.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/twistedcaldav/test/util.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -37,7 +37,6 @@
</span><span class="cx"> from twistedcaldav.stdconfig import config
</span><span class="cx"> from txdav.common.datastore.file import CommonDataStore
</span><span class="cx"> from txdav.common.datastore.test.util import deriveQuota, CommonCommonTests
</span><del>-from txdav.xml import element as element
</del><span class="cx"> from txweb2.dav.test.util import SimpleRequest
</span><span class="cx"> import txweb2.dav.test.util
</span><span class="cx"> from txweb2.http import HTTPError, StatusResponse
</span><span class="lines">@@ -79,15 +78,15 @@
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     A SimpleRequest that automatically grabs the proper transaction for a test.
</span><span class="cx">     &quot;&quot;&quot;
</span><del>-    def __init__(self, test, method, uri, headers=None, content=None, authRecord=None):
</del><ins>+    def __init__(self, test, method, uri, headers=None, content=None, authPrincipal=None):
</ins><span class="cx">         super(SimpleStoreRequest, self).__init__(test.site, method, uri, headers, content)
</span><span class="cx">         self._test = test
</span><span class="cx">         self._newStoreTransaction = test.transactionUnderTest(txn=transactionFromRequest(self, test.storeUnderTest()))
</span><span class="cx">         self.credentialFactories = {}
</span><span class="cx"> 
</span><span class="cx">         # Fake credentials if auth needed
</span><del>-        if authRecord is not None:
-            self.authzUser = self.authnUser = element.Principal(element.HRef(&quot;/principals/__uids__/%s/&quot; % (authRecord.uid,)))
</del><ins>+        if authPrincipal is not None:
+            self.authzUser = self.authnUser = authPrincipal
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     @inlineCallbacks
</span></span></pre></div>
<a id="CalendarServertrunktwistedcaldavupgradepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/twistedcaldav/upgrade.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/twistedcaldav/upgrade.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/twistedcaldav/upgrade.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -1119,9 +1119,7 @@
</span><span class="cx">                     request = FakeRequest(root, &quot;PUT&quot;, None)
</span><span class="cx">                     request.noAttendeeRefresh = True  # tell scheduling to skip refresh
</span><span class="cx">                     request.checkedSACL = True
</span><del>-                    request.authnUser = request.authzUser = element.Principal(
-                        element.HRef.fromString(&quot;/principals/__uids__/%s/&quot; % (uuid,))
-                    )
</del><ins>+                    request.authnUser = request.authzUser = principal
</ins><span class="cx"> 
</span><span class="cx">                     # The request may end up with an associated transaction and we must make sure that is
</span><span class="cx">                     # either committed or aborted, so use try/finally to handle that case.
</span></span></pre></div>
<a id="CalendarServertrunktxdavwhowikipy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txdav/who/wiki.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txdav/who/wiki.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/txdav/who/wiki.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -261,7 +261,7 @@
</span><span class="cx">     userRecord = None
</span><span class="cx"> 
</span><span class="cx">     try:
</span><del>-        url = str(request.authnUser.children[0])
</del><ins>+        url = request.authnUser.principalURL()
</ins><span class="cx">         principal = (yield request.locateResource(url))
</span><span class="cx">         if isinstance(principal, DirectoryPrincipalResource):
</span><span class="cx">             userRecord = principal.record
</span><span class="lines">@@ -277,7 +277,7 @@
</span><span class="cx">         if access == WikiAccessLevel.read:
</span><span class="cx">             request.wikiACL = davxml.ACL(
</span><span class="cx">                 davxml.ACE(
</span><del>-                    request.authnUser,
</del><ins>+                    request.authnUser.principalElement(),
</ins><span class="cx">                     davxml.Grant(
</span><span class="cx">                         davxml.Privilege(davxml.Read()),
</span><span class="cx">                         davxml.Privilege(davxml.ReadCurrentUserPrivilegeSet()),
</span><span class="lines">@@ -306,7 +306,7 @@
</span><span class="cx">         elif access == WikiAccessLevel.write:
</span><span class="cx">             request.wikiACL = davxml.ACL(
</span><span class="cx">                 davxml.ACE(
</span><del>-                    request.authnUser,
</del><ins>+                    request.authnUser.principalElement(),
</ins><span class="cx">                     davxml.Grant(
</span><span class="cx">                         davxml.Privilege(davxml.Read()),
</span><span class="cx">                         davxml.Privilege(davxml.ReadCurrentUserPrivilegeSet()),
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davauthpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/auth.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/auth.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/txweb2/dav/auth.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -33,7 +33,7 @@
</span><span class="cx"> from twisted.cred import checkers, error, portal
</span><span class="cx"> from txweb2.resource import WrapperResource
</span><span class="cx"> from txdav.xml.element import twisted_private_namespace, registerElement
</span><del>-from txdav.xml.element import WebDAVTextElement, Principal, HRef
</del><ins>+from txdav.xml.element import WebDAVTextElement
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> class AuthenticationWrapper(WrapperResource):
</span><span class="lines">@@ -67,6 +67,7 @@
</span><span class="cx">         # FIXME: some unit tests access self.credentialFactories, so assigning here
</span><span class="cx">         self.credentialFactories = self.wireEncryptedCredentialFactories
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def hook(self, req):
</span><span class="cx">         req.portal = self.portal
</span><span class="cx">         req.loginInterfaces = self.loginInterfaces
</span><span class="lines">@@ -83,23 +84,29 @@
</span><span class="cx">         )
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class IPrincipal(Interface):
</span><span class="cx">     pass
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class DavRealm(object):
</span><span class="cx">     implements(portal.IRealm)
</span><span class="cx"> 
</span><span class="cx">     def requestAvatar(self, avatarId, mind, *interfaces):
</span><span class="cx">         if IPrincipal in interfaces:
</span><del>-            return IPrincipal, Principal(HRef(avatarId[0])), Principal(HRef(avatarId[1]))
-        
</del><ins>+            # Return the associated principal resources
+            return IPrincipal, avatarId[0], avatarId[1]
+
</ins><span class="cx">         raise NotImplementedError(&quot;Only IPrincipal interface is supported&quot;)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class IPrincipalCredentials(Interface):
</span><span class="cx">     pass
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class PrincipalCredentials(object):
</span><span class="cx">     implements(IPrincipalCredentials)
</span><span class="cx"> 
</span><span class="lines">@@ -110,19 +117,19 @@
</span><span class="cx">         (.e.g.. proxy auth, cookies, forms etc) that make result in authentication and authorization being different.
</span><span class="cx"> 
</span><span class="cx">         @param authnPrincipal: L{IDAVPrincipalResource} for the authenticated principal.
</span><del>-        @param authnURI: C{str} containing the URI of the authenticated principal.
</del><span class="cx">         @param authzPrincipal: L{IDAVPrincipalResource} for the authorized principal.
</span><del>-        @param authzURI: C{str} containing the URI of the authorized principal.
</del><span class="cx">         @param credentials: L{ICredentials} for the authentication credentials.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         self.authnPrincipal = authnPrincipal
</span><span class="cx">         self.authzPrincipal = authzPrincipal
</span><span class="cx">         self.credentials = credentials
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def checkPassword(self, password):
</span><span class="cx">         return self.credentials.checkPassword(password)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class TwistedPropertyChecker(object):
</span><span class="cx">     implements(checkers.ICredentialsChecker)
</span><span class="cx"> 
</span><span class="lines">@@ -135,19 +142,20 @@
</span><span class="cx">         else:
</span><span class="cx">             raise error.UnauthorizedLogin(&quot;Bad credentials for: %s&quot; % (principalURIs[0],))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def requestAvatarId(self, credentials):
</span><span class="cx">         pcreds = IPrincipalCredentials(credentials)
</span><span class="cx">         pswd = str(pcreds.authnPrincipal.readDeadProperty(TwistedPasswordProperty))
</span><span class="cx"> 
</span><span class="cx">         d = defer.maybeDeferred(credentials.checkPassword, pswd)
</span><span class="cx">         d.addCallback(self._cbPasswordMatch, (
</span><del>-            pcreds.authnPrincipal.principalURL(),
-            pcreds.authzPrincipal.principalURL(),
</del><span class="cx">             pcreds.authnPrincipal,
</span><span class="cx">             pcreds.authzPrincipal,
</span><span class="cx">         ))
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> ##
</span><span class="cx"> # Utilities
</span><span class="cx"> ##
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davidavpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/idav.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/idav.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/txweb2/dav/idav.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -26,7 +26,7 @@
</span><span class="cx"> web2.dav interfaces.
</span><span class="cx"> &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-__all__ = [ &quot;IDAVResource&quot;, &quot;IDAVPrincipalResource&quot;, &quot;IDAVPrincipalCollectionResource&quot;, ]
</del><ins>+__all__ = [&quot;IDAVResource&quot;, &quot;IDAVPrincipalResource&quot;, &quot;IDAVPrincipalCollectionResource&quot;, ]
</ins><span class="cx"> 
</span><span class="cx"> from txweb2.iweb import IResource
</span><span class="cx"> 
</span><span class="lines">@@ -44,13 +44,13 @@
</span><span class="cx">     def findChildren(depth, request, callback, privileges, inherited_aces):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Returns an iterable of child resources for the given depth.
</span><del>-        Because resources do not know their request URIs, chidren are returned
</del><ins>+        Because resources do not know their request URIs, children are returned
</ins><span class="cx">         as tuples C{(resource, uri)}, where C{resource} is the child resource
</span><span class="cx">         and C{uri} is a URL path relative to this resource.
</span><span class="cx">         @param depth: the search depth (one of C{&quot;0&quot;}, C{&quot;1&quot;}, or C{&quot;infinity&quot;})
</span><span class="cx">         @param request: The current L{IRequest} responsible for this call.
</span><span class="cx">         @param callback: C{callable} that will be called for each child found
</span><del>-        @param privileges: the list of L{Privilege}s to test for.  This should 
</del><ins>+        @param privileges: the list of L{Privilege}s to test for.  This should
</ins><span class="cx">             default to None.
</span><span class="cx">         @param inherited_aces: a list of L{Privilege}s for aces being inherited from
</span><span class="cx">             the parent collection used to bypass inheritance lookup.
</span><span class="lines">@@ -135,7 +135,7 @@
</span><span class="cx"> 
</span><span class="cx">     def principalCollections():
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        @return: an interable of L{IDAVPrincipalCollectionResource}s which
</del><ins>+        @return: an iterable of L{IDAVPrincipalCollectionResource}s which
</ins><span class="cx">             contain principals used in ACLs for this resource.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -176,8 +176,8 @@
</span><span class="cx">     def privilegesForPrincipal(principal, request):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Evaluate the set of privileges that apply to the specified principal.
</span><del>-        This involves examing all ace's and granting/denying as appropriate for
-        the specified principal's membership of the ace's prinicpal.
</del><ins>+        This involves examining all ace's and granting/denying as appropriate for
+        the specified principal's membership of the ace's principal.
</ins><span class="cx">         @param request: the request being processed.
</span><span class="cx">         @return: a list of L{Privilege}s that are allowed on this resource for
</span><span class="cx">             the specified principal.
</span><span class="lines">@@ -186,32 +186,31 @@
</span><span class="cx">     ##
</span><span class="cx">     # Quota
</span><span class="cx">     ##
</span><del>-    
</del><ins>+
</ins><span class="cx">     def quota(request):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Get current available &amp; used quota values for this resource's quota root
</span><span class="cx">         collection.
</span><span class="cx"> 
</span><del>-        @return: a C{tuple} containing two C{int}'s the first is 
</del><ins>+        @return: a C{tuple} containing two C{int}'s the first is
</ins><span class="cx">             quota-available-bytes, the second is quota-used-bytes, or
</span><span class="cx">             C{None} if quota is not defined on the resource.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-    
</del><ins>+
</ins><span class="cx">     def hasQuota(request):
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        Check whether this resource is undre quota control by checking each parent to see if
</del><ins>+        Check whether this resource is under quota control by checking each parent to see if
</ins><span class="cx">         it has a quota root.
</span><del>-        
</del><ins>+
</ins><span class="cx">         @return: C{True} if under quota control, C{False} if not.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">     def hasQuotaRoot(request):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Determine whether the resource has a quota root.
</span><span class="cx"> 
</span><span class="cx">         @return: a C{True} if this resource has quota root, C{False} otherwise.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-    
</del><span class="cx"> 
</span><span class="cx">     def quotaRoot(request):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="lines">@@ -220,7 +219,7 @@
</span><span class="cx">         @return: a C{int} containing the maximum allowed bytes if this collection
</span><span class="cx">             is quota-controlled, or C{None} if not quota controlled.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-    
</del><ins>+
</ins><span class="cx">     def setQuotaRoot(request, maxsize):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Set the quota root (max. allowed bytes) value for this collection.
</span><span class="lines">@@ -228,7 +227,7 @@
</span><span class="cx">         @param maxsize: a C{int} containing the maximum allowed bytes for the contents
</span><span class="cx">             of this collection.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-    
</del><ins>+
</ins><span class="cx">     def quotaSize(request):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Get the size of this resource (if its a collection get total for all children as well).
</span><span class="lines">@@ -236,7 +235,7 @@
</span><span class="cx"> 
</span><span class="cx">         @return: a L{Deferred} with a C{int} result containing the size of the resource.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">     def currentQuotaUse(request):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Get the cached quota use value, or if not present (or invalid) determine
</span><span class="lines">@@ -245,7 +244,7 @@
</span><span class="cx">         @return: an L{Deferred} with a C{int} result containing the current used byte count if
</span><span class="cx">             this collection is quota-controlled, or C{None} if not quota controlled.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">     def updateQuotaUse(request, adjust):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Adjust current quota use on this all all parent collections that also
</span><span class="lines">@@ -257,6 +256,8 @@
</span><span class="cx">             is quota-controlled, or C{None} if not quota controlled.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class IDAVPrincipalResource (IDAVResource):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     WebDAV principal resource.  (RFC 3744, section 2)
</span><span class="lines">@@ -270,7 +271,6 @@
</span><span class="cx">         @return: a iterable of URIs.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-
</del><span class="cx">     def principalURL():
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Provides the URL which must be used to identify this principal in ACL
</span><span class="lines">@@ -278,6 +278,12 @@
</span><span class="cx">         @return: a URL.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><ins>+    def principalElement():
+        &quot;&quot;&quot;
+        Provides the XML element which must be used to identify this principal in ACL
+        requests.  (RFC 3744, section 4.2)
+        @return: L{element.Principal}.
+        &quot;&quot;&quot;
</ins><span class="cx"> 
</span><span class="cx">     def groupMembers():
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="lines">@@ -286,7 +292,6 @@
</span><span class="cx">         @return: a deferred returning an iterable of principal URLs.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-
</del><span class="cx">     def expandedGroupMembers():
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Provides the principal URLs of principals that are members of this
</span><span class="lines">@@ -296,7 +301,6 @@
</span><span class="cx">         @return: a L{Deferred} that fires with an iterable of principal URLs.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-
</del><span class="cx">     def groupMemberships():
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Provides the URLs of the group principals in which the principal is
</span><span class="lines">@@ -318,7 +322,6 @@
</span><span class="cx">         @return: a URL.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-
</del><span class="cx">     def principalForUser(user):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Retrieve the principal for a given username.
</span><span class="lines">@@ -331,4 +334,3 @@
</span><span class="cx"> 
</span><span class="cx">         @rtype: L{IDAVPrincipalResource}
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-
</del></span></pre></div>
<a id="CalendarServertrunktxweb2davresourcepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/resource.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/resource.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/txweb2/dav/resource.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -133,7 +133,7 @@
</span><span class="cx">     can only be accessed via the dead property store.
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     # Note: The DAV:owner and DAV:group live properties are only
</span><del>-    # meaningful if you are using ACL semantics (ie. Unix-like) which
</del><ins>+    # meaningful if you are using ACL semantics (i.e. Unix-like) which
</ins><span class="cx">     # use them.  This (generic) class does not.
</span><span class="cx"> 
</span><span class="cx">     def liveProperties(self):
</span><span class="lines">@@ -957,7 +957,7 @@
</span><span class="cx">             def translateError(response):
</span><span class="cx">                 return Failure(HTTPError(response))
</span><span class="cx"> 
</span><del>-            if request.authnUser == element.Principal(element.Unauthenticated()):
</del><ins>+            if request.authnUser == None:
</ins><span class="cx">                 return UnauthorizedResponse.makeResponse(
</span><span class="cx">                     request.credentialFactories,
</span><span class="cx">                     request.remoteAddr).addCallback(translateError)
</span><span class="lines">@@ -973,9 +973,9 @@
</span><span class="cx">     def authenticate(self, request):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Authenticate the given request against the portal, setting
</span><del>-        both C{request.authzUser} (a C{str}, the username for the
-        purposes of authorization) and C{request.authnUser} (a C{str},
-        the username for the purposes of authentication) when it has
</del><ins>+        both C{request.authzUser} (a L{DAVPrincipalResource}, the user for the
+        purposes of authorization) and C{request.authnUser} (a L{DAVPrincipalResource},
+        the user for the purposes of authentication) when it has
</ins><span class="cx">         been authenticated.
</span><span class="cx"> 
</span><span class="cx">         In order to authenticate, the request must have been
</span><span class="lines">@@ -984,7 +984,7 @@
</span><span class="cx">         necessary authentication metadata.
</span><span class="cx"> 
</span><span class="cx">         If the request was not thusly prepared, both C{authzUser} and
</span><del>-        C{authnUser} will be L{element.Unauthenticated}.
</del><ins>+        C{authnUser} will be None.
</ins><span class="cx"> 
</span><span class="cx">         @param request: the request which may contain authentication
</span><span class="cx">             information and a reference to a portal to authenticate
</span><span class="lines">@@ -1000,10 +1000,8 @@
</span><span class="cx"> 
</span><span class="cx">         # Bypass normal authentication if its already been done (by SACL check)
</span><span class="cx">         if (
</span><del>-            hasattr(request, &quot;authnUser&quot;) and
-            hasattr(request, &quot;authzUser&quot;) and
-            request.authnUser is not None and
-            request.authzUser is not None
</del><ins>+            getattr(request, &quot;authnUser&quot;, None) is not None and
+            getattr(request, &quot;authzUser&quot;, None) is not None
</ins><span class="cx">         ):
</span><span class="cx">             return succeed((request.authnUser, request.authzUser))
</span><span class="cx"> 
</span><span class="lines">@@ -1012,8 +1010,8 @@
</span><span class="cx">             hasattr(request, &quot;credentialFactories&quot;) and
</span><span class="cx">             hasattr(request, &quot;loginInterfaces&quot;)
</span><span class="cx">         ):
</span><del>-            request.authnUser = element.Principal(element.Unauthenticated())
-            request.authzUser = element.Principal(element.Unauthenticated())
</del><ins>+            request.authnUser = None
+            request.authzUser = None
</ins><span class="cx">             return succeed((request.authnUser, request.authzUser))
</span><span class="cx"> 
</span><span class="cx">         authHeader = request.headers.getHeader(&quot;authorization&quot;)
</span><span class="lines">@@ -1082,8 +1080,8 @@
</span><span class="cx">                 # This request has already been authenticated via the wiki
</span><span class="cx">                 return succeed((request.authnUser, request.authzUser))
</span><span class="cx"> 
</span><del>-            request.authnUser = element.Principal(element.Unauthenticated())
-            request.authzUser = element.Principal(element.Unauthenticated())
</del><ins>+            request.authnUser = None
+            request.authzUser = None
</ins><span class="cx">             return succeed((request.authnUser, request.authzUser))
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -1097,8 +1095,8 @@
</span><span class="cx">         @return: the current authorized principal, as derived from the
</span><span class="cx">             given request.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        if hasattr(request, &quot;authzUser&quot;):
-            return request.authzUser
</del><ins>+        if getattr(request, &quot;authzUser&quot;, None) is not None:
+            return request.authzUser.principalElement()
</ins><span class="cx">         else:
</span><span class="cx">             return unauthenticatedPrincipal
</span><span class="cx"> 
</span><span class="lines">@@ -2489,6 +2487,17 @@
</span><span class="cx">         unimplemented(self)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+    def principalElement(self):
+        &quot;&quot;&quot;
+        See L{IDAVPrincipalResource.principalURL}.
+
+        This implementation raises L{NotImplementedError}.  Subclasses
+        must override this method to provide the principal URL for
+        this resource.
+        &quot;&quot;&quot;
+        return element.Principal(element.HRef.fromString(self.principalURL()))
+
+
</ins><span class="cx">     def groupMembers(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         This implementation returns a Deferred which fires with C{()},
</span></span></pre></div>
<a id="CalendarServertrunktxweb2davtesttest_resourcepy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/txweb2/dav/test/test_resource.py (13547 => 13548)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/txweb2/dav/test/test_resource.py        2014-05-28 18:12:03 UTC (rev 13547)
+++ CalendarServer/trunk/txweb2/dav/test/test_resource.py        2014-05-28 18:29:34 UTC (rev 13548)
</span><span class="lines">@@ -7,10 +7,10 @@
</span><span class="cx"> # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
</span><span class="cx"> # copies of the Software, and to permit persons to whom the Software is
</span><span class="cx"> # furnished to do so, subject to the following conditions:
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # The above copyright notice and this permission notice shall be included in all
</span><span class="cx"> # copies or substantial portions of the Software.
</span><del>-# 
</del><ins>+#
</ins><span class="cx"> # THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
</span><span class="cx"> # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
</span><span class="cx"> # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
</span><span class="lines">@@ -41,6 +41,8 @@
</span><span class="cx">         txweb2.dav.test.util.TestCase.setUp(self)
</span><span class="cx">         TestResource._cachedPropertyStores = {}
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class GenericDAVResource(TestCase):
</span><span class="cx">     def setUp(self):
</span><span class="cx">         TestCase.setUp(self)
</span><span class="lines">@@ -49,7 +51,7 @@
</span><span class="cx">             &quot;file1&quot;: TestResource(&quot;/file1&quot;),
</span><span class="cx">             &quot;file2&quot;: AuthAllResource(&quot;/file2&quot;),
</span><span class="cx">             &quot;dir1&quot;: TestResource(&quot;/dir1/&quot;, {
</span><del>-                &quot;subdir1&quot;: TestResource(&quot;/dir1/subdir1/&quot;,{})
</del><ins>+                &quot;subdir1&quot;: TestResource(&quot;/dir1/subdir1/&quot;, {})
</ins><span class="cx">             }),
</span><span class="cx">             &quot;dir2&quot;: AuthAllResource(&quot;/dir2/&quot;, {
</span><span class="cx">                 &quot;file1&quot;: TestResource(&quot;/dir2/file1&quot;),
</span><span class="lines">@@ -63,6 +65,7 @@
</span><span class="cx"> 
</span><span class="cx">         self.site = Site(rootresource)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_findChildren(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         This test asserts that we have:
</span><span class="lines">@@ -134,7 +137,7 @@
</span><span class="cx">         resource to verify that we can not find them giving our unauthenticated
</span><span class="cx">         privileges.
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        
</del><ins>+
</ins><span class="cx">         expected_children = [
</span><span class="cx">             &quot;/file1&quot;,
</span><span class="cx">             &quot;/dir1/&quot;,
</span><span class="lines">@@ -193,12 +196,14 @@
</span><span class="cx">                 resource.findChildren(&quot;infinity&quot;, request, raiseOnChild),
</span><span class="cx">                 Exception
</span><span class="cx">             )
</span><del>-        
</del><ins>+
</ins><span class="cx">         request = SimpleRequest(self.site, &quot;GET&quot;, &quot;/&quot;)
</span><span class="cx">         d = request.locateResource(&quot;/&quot;).addCallback(findChildren)
</span><span class="cx"> 
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
+
</ins><span class="cx"> class AccessTests(TestCase):
</span><span class="cx">     def setUp(self):
</span><span class="cx">         TestCase.setUp(self)
</span><span class="lines">@@ -244,6 +249,7 @@
</span><span class="cx">             loginInterfaces,
</span><span class="cx">         ))
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def checkSecurity(self, request):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Locate the resource named by the given request's URI, then authorize it
</span><span class="lines">@@ -253,10 +259,12 @@
</span><span class="cx">         d.addCallback(lambda r: r.authorize(request, (davxml.Read(),)))
</span><span class="cx">         return d
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def assertErrorResponse(self, error, expectedcode, otherExpectations=lambda err: None):
</span><span class="cx">         self.assertEquals(error.response.code, expectedcode)
</span><span class="cx">         otherExpectations(error)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_checkPrivileges(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         DAVResource.checkPrivileges()
</span><span class="lines">@@ -296,8 +304,7 @@
</span><span class="cx"> 
</span><span class="cx">         # Has auth; should allow
</span><span class="cx">         request = SimpleRequest(site, &quot;GET&quot;, &quot;/&quot;)
</span><del>-        request.authnUser = davxml.Principal(davxml.HRef(&quot;/users/d00d&quot;))
-        request.authzUser = davxml.Principal(davxml.HRef(&quot;/users/d00d&quot;))
</del><ins>+        request.authzUser = request.authnUser = self.rootresource.principalForUser(&quot;gooduser&quot;)
</ins><span class="cx">         d = request.locateResource(&quot;/&quot;)
</span><span class="cx">         d.addCallback(_checkPrivileges)
</span><span class="cx">         d.addCallback(expectOK)
</span><span class="lines">@@ -318,6 +325,7 @@
</span><span class="cx">             (&quot;basic&quot;, &quot;gooduser:goodpass&quot;.encode(&quot;base64&quot;)))
</span><span class="cx">         return self.checkSecurity(request)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def test_badUsernameOrPassword(self):
</span><span class="cx">         request = SimpleRequest(self.site, &quot;GET&quot;, &quot;/protected&quot;)
</span><span class="cx">         request.headers.setHeader(
</span><span class="lines">@@ -343,6 +351,7 @@
</span><span class="cx">         return d
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> ##
</span><span class="cx"> # Utilities
</span><span class="cx"> ##
</span><span class="lines">@@ -370,6 +379,7 @@
</span><span class="cx">         self.children = children
</span><span class="cx">         self.uri = uri
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def deadProperties(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Retrieve deadProperties from a special place in memory
</span><span class="lines">@@ -382,20 +392,18 @@
</span><span class="cx">             self._dead_properties = dp
</span><span class="cx">         return self._dead_properties
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def isCollection(self):
</span><span class="cx">         return self.children is not None
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def listChildren(self):
</span><span class="cx">         return self.children.keys()
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def supportedPrivileges(self, request):
</span><span class="cx">         return succeed(davPrivilegeSet)
</span><span class="cx"> 
</span><del>-    def currentPrincipal(self, request):
-        if hasattr(request, &quot;authzUser&quot;):
-            return request.authzUser
-        else:
-            return davxml.Principal(davxml.Unauthenticated())
</del><span class="cx"> 
</span><span class="cx">     def locateChild(self, request, segments):
</span><span class="cx">         child = segments[0]
</span><span class="lines">@@ -406,9 +414,11 @@
</span><span class="cx">         else:
</span><span class="cx">             raise HTTPError(404)
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def setAccessControlList(self, acl):
</span><span class="cx">         self.acl = acl
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def accessControlList(self, request, **kwargs):
</span><span class="cx">         return succeed(self.acl)
</span><span class="cx"> 
</span><span class="lines">@@ -497,7 +507,8 @@
</span><span class="cx">         )
</span><span class="cx">     )
</span><span class="cx"> 
</span><del>-    
</del><ins>+
+
</ins><span class="cx"> class TestDAVPrincipalResource(DAVPrincipalResource, TestResource):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Get deadProperties from TestResource
</span></span></pre>
</div>
</div>

</body>
</html>