from repoze.who._compat import CONTENT_TYPE
|
from repoze.who._compat import REQUEST_METHOD
|
from repoze.who._compat import USER_AGENT
|
|
from zope.interface import directlyProvides
|
from repoze.who.interfaces import IRequestClassifier
|
from repoze.who.interfaces import IChallengeDecider
|
|
_DAV_METHODS = (
|
'OPTIONS',
|
'PROPFIND',
|
'PROPPATCH',
|
'MKCOL',
|
'LOCK',
|
'UNLOCK',
|
'TRACE',
|
'DELETE',
|
'COPY',
|
'MOVE'
|
)
|
|
_DAV_USERAGENTS = (
|
'Microsoft Data Access Internet Publishing Provider',
|
'WebDrive',
|
'Zope External Editor',
|
'WebDAVFS',
|
'Goliath',
|
'neon',
|
'davlib',
|
'wsAPI',
|
'Microsoft-WebDAV'
|
)
|
|
def default_request_classifier(environ):
|
"""Return one of the following classifiers:
|
|
'dav': the request comes from a WebDAV agent.
|
|
'xmlpost': the request is a POST of XML data.
|
|
'browser': the request comes from a normal browser (default).
|
"""
|
request_method = REQUEST_METHOD(environ)
|
if request_method in _DAV_METHODS:
|
return 'dav'
|
useragent = USER_AGENT(environ)
|
if useragent:
|
for agent in _DAV_USERAGENTS:
|
if useragent.find(agent) != -1:
|
return 'dav'
|
if request_method == 'POST':
|
if CONTENT_TYPE(environ).lower().startswith('text/xml'):
|
return 'xmlpost'
|
return 'browser'
|
directlyProvides(default_request_classifier, IRequestClassifier)
|
|
def default_challenge_decider(environ, status, headers):
|
return status.startswith('401 ')
|
directlyProvides(default_challenge_decider, IChallengeDecider)
|
|
def passthrough_challenge_decider(environ, status, headers):
|
""" Don't challenge for pre-challenged responses.
|
|
o Assume responsese with 'WWW-Authenticate' or an HTML content type
|
are pre-challenged.
|
"""
|
if not status.startswith('401 '):
|
return False
|
h_dict = dict(headers)
|
if 'WWW-Authenticate' in h_dict:
|
return False
|
ct = h_dict.get('Content-Type')
|
if ct is not None:
|
return not ct.startswith('text/html')
|
return True
|
directlyProvides(passthrough_challenge_decider, IChallengeDecider)
|