1 --- old/zopeedit.py 2010-04-19 12:06:41.000000000 +0200
2 +++ zopeedit.py 2010-04-19 12:06:52.000000000 +0200
4 -#!/usr/bin/env python2.5
6 ##############################################################################
8 # Copyright (c) 2001, 2002 Zope Corporation and Contributors.
20 from urlparse import urlparse
21 +from urllib2 import parse_http_list, parse_keqv_list
23 LOG_LEVELS = {'debug': logging.DEBUG,
27 def __init__(self, input_file):
28 self.input_file = input_file
29 + self.identity = None
32 #log_file = NamedTemporaryFile(suffix='-zopeedit-log.txt')
34 headers = {'Lock-Token':self.lock_token}
35 response = self.zopeRequest('UNLOCK', headers)
39 + def _get_authorization(self, host, method, selector, cookie, ssl,
43 + h = HTTPSConnection(host)
45 + h = HTTPConnection(host)
46 + if cookie is not None:
47 + headers = {'Cookie': cookie}
50 + h.request('HEAD', selector, headers=headers)
54 + auth_header = r.getheader('www-authenticate').strip()
55 + if auth_header is None or not auth_header.lower().startswith('digest'):
57 + # XXX undocumented functions
58 + chal = parse_keqv_list(parse_http_list(auth_header[7:]))
60 + #get the user/password
61 + if self.identity is not None:
62 + username, password = self.identity
64 + # XXX undocumented functions
65 + username = parse_keqv_list(parse_http_list(old_response[7:])
67 + password = askPassword(chal['realm'], username)
68 + self.identity = (username, password)
70 + #compute the authorization
71 + algorithm = chal.get('algorithm', 'MD5')
72 + if algorithm == 'MD5':
73 + H = lambda x: hashlib.md5(x).hexdigest()
74 + elif algorithm == 'SHA':
75 + H = lambda x: hashlib.sha1(x).hexdigest()
76 + # XXX MD5-sess not implemented
77 + KD = lambda s, d: H("%s:%s" % (s, d))
79 + nonce = chal['nonce']
80 + res = ('Digest username="%s", realm="%s", nonce="%s", algorithm="%s", '
81 + 'uri="%s"' % (username, chal['realm'], nonce, chal['algorithm'],
83 + if 'opaque' in chal:
84 + res += ', opaque="%s"' % chal['opaque']
86 + A1 = '%s:%s:%s' % (username, chal['realm'], password)
87 + A2 = '%s:%s' % (method, selector)
90 + # XXX auth-int not implemented
94 + res += ', qop="%s", nc="%s", cnonce="%s"' % (qop, nc, cnonce)
96 + response = KD( H(A1), '%s:%s:%s:%s:%s' % (nonce, nc, cnonce, qop,
99 + response = KD( H(A1), '%s:%s' % (nonce, H(A2)) )
101 + res += ', response="%s"' % response
104 def zopeRequest(self, method, headers={}, body='', command=''):
105 """Send a request back to Zope"""
108 for header, value in headers.items():
109 h.putheader(header, value)
110 h.putheader("Content-Length", str(len(body)))
111 - if self.metadata.get('auth','').lower().startswith('basic'):
113 + auth_header = self.metadata.get('auth','')
114 + if auth_header.lower().startswith('basic'):
115 h.putheader("Authorization", self.metadata['auth'])
116 + if auth_header.lower().startswith('digest'):
117 + authorization = self._get_authorization(host, method, url,
118 + self.metadata.get('cookie'),
119 + False, auth_header)
120 + if authorization is not None:
121 + h.putheader("Authorization", authorization)
123 if self.metadata.get('cookie'):
124 h.putheader("Cookie", self.metadata['cookie'])
127 for header, value in headers.items():
128 h.putheader(header, value)
129 h.putheader("Content-Length", str(len(body)))
130 - if self.metadata.get('auth','').lower().startswith('basic'):
132 + auth_header = self.metadata.get('auth','')
133 + if auth_header.lower().startswith('basic'):
134 h.putheader("Authorization", self.metadata['auth'])
135 + if auth_header.lower().startswith('digest'):
136 + authorization = self._get_authorization(host, method, url,
137 + self.metadata.get('cookie'),
138 + self.ssl and not self.proxy,
140 + if authorization is not None:
141 + h.putheader("Authorization", authorization)
143 if self.metadata.get('cookie'):
144 h.putheader("Cookie", self.metadata['cookie'])
146 @@ -1100,6 +1187,30 @@
149 ## Platform specific declarations ##
151 + """Sets up a suitable tk root window if one has not
152 + already been setup. Returns true if tk is happy,
153 + false if tk throws an error (like its not available)"""
154 + # create a hidden root window to make Tk happy
155 + if not locals().has_key('tk_root'):
158 + from Tkinter import Tk
166 +#askPassword is common to win32 and Posix
167 +def askPassword(realm, username):
169 + from tkSimpleDialog import askstring
170 + r = askstring(title, "Please enter the password for '%s' in '%s'" %
171 + (username, realm), show='*')
176 import Plugins # Assert dependancy
177 @@ -1130,22 +1241,6 @@
178 from time import sleep
182 - """Sets up a suitable tk root window if one has not
183 - already been setup. Returns true if tk is happy,
184 - false if tk throws an error (like its not available)"""
185 - # create a hidden root window to make Tk happy
186 - if not locals().has_key('tk_root'):
189 - from Tkinter import Tk
197 def errorDialog(message):
198 """Error dialog box"""