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