1 from paste.httpheaders import REQUEST_METHOD
2 from paste.httpheaders import CONTENT_TYPE
3 from paste.httpheaders import USER_AGENT
4 from paste.httpheaders import WWW_AUTHENTICATE
5
6 import zope.interface
7 from repoze.who.interfaces import IRequestClassifier
8 from repoze.who.interfaces import IChallengeDecider
9
10 _DAV_METHODS = (
11 'OPTIONS',
12 'PROPFIND',
13 'PROPPATCH',
14 'MKCOL',
15 'LOCK',
16 'UNLOCK',
17 'TRACE',
18 'DELETE',
19 'COPY',
20 'MOVE'
21 )
22
23 _DAV_USERAGENTS = (
24 'Microsoft Data Access Internet Publishing Provider',
25 'WebDrive',
26 'Zope External Editor',
27 'WebDAVFS',
28 'Goliath',
29 'neon',
30 'davlib',
31 'wsAPI',
32 'Microsoft-WebDAV'
33 )
34
36 """ Returns one of the classifiers 'dav', 'xmlpost', or 'browser',
37 depending on the imperative logic below"""
38 request_method = REQUEST_METHOD(environ)
39 if request_method in _DAV_METHODS:
40 return 'dav'
41 useragent = USER_AGENT(environ)
42 if useragent:
43 for agent in _DAV_USERAGENTS:
44 if useragent.find(agent) != -1:
45 return 'dav'
46 if request_method == 'POST':
47 if CONTENT_TYPE(environ) == 'text/xml':
48 return 'xmlpost'
49 return 'browser'
50 zope.interface.directlyProvides(default_request_classifier, IRequestClassifier)
51
53 return status.startswith('401 ')
54 zope.interface.directlyProvides(default_challenge_decider, IChallengeDecider)
55
57 """ Don't challenge for pre-challenged responses.
58
59 o Assume responsese with 'WWW-Authenticate' or an HTML content type
60 are pre-challenged.
61 """
62 if not status.startswith('401 '):
63 return False
64 h_dict = dict(headers)
65 if 'WWW-Authenticate' in h_dict:
66 return False
67 ct = h_dict.get('Content-Type')
68 if ct is not None:
69 return not ct.startswith('text/html')
70 return True
71 zope.interface.directlyProvides(passthrough_challenge_decider,
72 IChallengeDecider)
73