Mercurial > hg > easyhg
comparison easyhg.py @ 673:e4d18e8ef430
Update for newer APIs
author | Chris Cannam |
---|---|
date | Wed, 05 Dec 2018 13:20:51 +0000 |
parents | e34de484415c |
children | c59c17665162 |
comparison
equal
deleted
inserted
replaced
672:88fa1544b407 | 673:e4d18e8ef430 |
---|---|
33 # the Python version suffixed | 33 # the Python version suffixed |
34 version_suffix = 'Py%d.%d' % (sys.version_info[0], sys.version_info[1]) | 34 version_suffix = 'Py%d.%d' % (sys.version_info[0], sys.version_info[1]) |
35 sys.path.append(easyhg_import_path + "/" + version_suffix) | 35 sys.path.append(easyhg_import_path + "/" + version_suffix) |
36 sys.path.append(easyhg_import_path) | 36 sys.path.append(easyhg_import_path) |
37 | 37 |
38 # Try to load the PyQt4 module that we need. If this fails, we should | 38 # Try to load the PyQt5 module that we need. If this fails, we should |
39 # bail out later (in uisetup), because if we bail out now, Mercurial | 39 # bail out later (in uisetup), because if we bail out now, Mercurial |
40 # will just continue without us and report success. The invoking | 40 # will just continue without us and report success. The invoking |
41 # application needs to be able to discover whether the module load | 41 # application needs to be able to discover whether the module load |
42 # succeeded or not, so we need to ensure that Mercurial itself returns | 42 # succeeded or not, so we need to ensure that Mercurial itself returns |
43 # failure if it didn't. | 43 # failure if it didn't. |
44 # | 44 # |
45 easyhg_pyqt_ok = True | 45 easyhg_pyqt_ok = True |
46 try: | 46 try: |
47 from PyQt4 import QtCore, QtGui | 47 from PyQt5 import QtCore, QtGui, QtWidgets |
48 except ImportError: | 48 except ImportError: |
49 easyhg_pyqt_ok = False | 49 easyhg_pyqt_ok = False |
50 easyhg_qtapp = None | 50 easyhg_qtapp = None |
51 | 51 |
52 # These imports are optional, we just can't use the authfile (i.e. | 52 # These imports are optional, we just can't use the authfile (i.e. |
80 | 80 |
81 self.auth_key = self.ui.config('easyhg', 'authkey') | 81 self.auth_key = self.ui.config('easyhg', 'authkey') |
82 self.auth_file = self.ui.config('easyhg', 'authfile') | 82 self.auth_file = self.ui.config('easyhg', 'authfile') |
83 | 83 |
84 self.use_auth_file = (easyhg_authfile_imports_ok and | 84 self.use_auth_file = (easyhg_authfile_imports_ok and |
85 self.auth_key and self.auth_file) | 85 self.auth_key and self.auth_file) |
86 | 86 |
87 self.auth_config = None | 87 self.auth_config = None |
88 self.auth_cipher = None | 88 self.auth_cipher = None |
89 self.remember = False | 89 self.remember = False |
90 | 90 |
91 if self.use_auth_file: | 91 if self.use_auth_file: |
92 self.auth_cipher = AES.new(self.auth_key, AES.MODE_CBC, | |
93 os.urandom(16)) | |
94 self.auth_file = os.path.expanduser(self.auth_file) | 92 self.auth_file = os.path.expanduser(self.auth_file) |
95 self.load_auth_data() | 93 self.load_auth_data() |
96 | 94 |
97 def save(self): | 95 def save(self): |
98 if self.use_auth_file: | 96 if self.use_auth_file: |
99 self.save_auth_data() | 97 self.save_auth_data() |
100 | 98 |
101 def encrypt(self, text): | 99 def encrypt(self, utext): |
102 iv = os.urandom(12) | 100 iv = os.urandom(12) |
101 text = utext.encode('utf-8') | |
103 text = '%s.%d.%s.easyhg' % (base64.b64encode(iv), len(text), text) | 102 text = '%s.%d.%s.easyhg' % (base64.b64encode(iv), len(text), text) |
104 text += (16 - (len(text) % 16)) * ' ' | 103 text += (16 - (len(text) % 16)) * ' ' |
105 ctext = base64.b64encode(self.auth_cipher.encrypt(text)) | 104 cipher = AES.new(self.auth_key, AES.MODE_CBC, os.urandom(16)) |
105 ctext = base64.b64encode(cipher.encrypt(text)) | |
106 return ctext | 106 return ctext |
107 | 107 |
108 def decrypt(self, ctext): | 108 def decrypt(self, ctext): |
109 try: | 109 try: |
110 text = self.auth_cipher.decrypt(base64.b64decode(ctext)) | 110 cipher = AES.new(self.auth_key, AES.MODE_CBC, os.urandom(16)) |
111 text = cipher.decrypt(base64.b64decode(ctext)) | |
111 (iv, d, text) = text.partition('.') | 112 (iv, d, text) = text.partition('.') |
112 (tlen, d, text) = text.partition('.') | 113 (tlen, d, text) = text.partition('.') |
113 return text[0:int(tlen)] | 114 return text[0:int(tlen)].decode('utf-8') |
114 except: | 115 except: |
115 self.ui.write("failed to decrypt/convert cached data!") | 116 self.ui.write("failed to decrypt/convert cached data!") |
116 return '' | 117 return '' |
117 | 118 |
118 def argless_url(self): | 119 def argless_url(self): |
241 | 242 |
242 if self.auth_store.user and self.auth_store.passwd and self.auth_store.remember: | 243 if self.auth_store.user and self.auth_store.passwd and self.auth_store.remember: |
243 if not repeat: | 244 if not repeat: |
244 return (self.auth_store.user, self.auth_store.passwd) | 245 return (self.auth_store.user, self.auth_store.passwd) |
245 | 246 |
246 dialog = QtGui.QDialog() | 247 dialog = QtWidgets.QDialog() |
247 layout = QtGui.QGridLayout() | 248 layout = QtWidgets.QGridLayout() |
248 dialog.setLayout(layout) | 249 dialog.setLayout(layout) |
249 | 250 |
250 heading = _('Login required') | 251 heading = _('Login required') |
251 if repeat: | 252 if repeat: |
252 heading = _('Login failed: please try again') | 253 heading = _('Login failed: please try again') |
253 label_text = _(('<h3>%s</h3><p>Please provide your login details for the repository at<br><code>%s</code>:') % (heading, self.auth_store.argless_url())) | 254 label_text = _(('<h3>%s</h3><p>Please provide your login details for the repository at<br><code>%s</code>:') % (heading, self.auth_store.argless_url())) |
254 layout.addWidget(QtGui.QLabel(label_text), 0, 0, 1, 2) | 255 layout.addWidget(QtWidgets.QLabel(label_text), 0, 0, 1, 2) |
255 | 256 |
256 user_field = QtGui.QLineEdit() | 257 user_field = QtWidgets.QLineEdit() |
257 if self.auth_store.user: user_field.setText(self.auth_store.user) | 258 if self.auth_store.user: user_field.setText(self.auth_store.user) |
258 layout.addWidget(QtGui.QLabel(_('User:')), 1, 0) | 259 layout.addWidget(QtWidgets.QLabel(_('User:')), 1, 0) |
259 layout.addWidget(user_field, 1, 1) | 260 layout.addWidget(user_field, 1, 1) |
260 | 261 |
261 passwd_field = QtGui.QLineEdit() | 262 passwd_field = QtWidgets.QLineEdit() |
262 passwd_field.setEchoMode(QtGui.QLineEdit.Password) | 263 passwd_field.setEchoMode(QtWidgets.QLineEdit.Password) |
263 if self.auth_store.passwd: passwd_field.setText(self.auth_store.passwd) | 264 if self.auth_store.passwd: passwd_field.setText(self.auth_store.passwd) |
264 layout.addWidget(QtGui.QLabel(_('Password:')), 2, 0) | 265 layout.addWidget(QtWidgets.QLabel(_('Password:')), 2, 0) |
265 layout.addWidget(passwd_field, 2, 1) | 266 layout.addWidget(passwd_field, 2, 1) |
266 user_field.textChanged.connect(passwd_field.clear) | 267 user_field.textChanged.connect(passwd_field.clear) |
267 | 268 |
268 remember_field = None | 269 remember_field = None |
269 if self.auth_store.use_auth_file: | 270 if self.auth_store.use_auth_file: |
270 remember_field = QtGui.QCheckBox() | 271 remember_field = QtWidgets.QCheckBox() |
271 remember_field.setChecked(self.auth_store.remember) | 272 remember_field.setChecked(self.auth_store.remember) |
272 remember_field.setText(_('Remember these details while EasyMercurial is running')) | 273 remember_field.setText(_('Remember these details while EasyMercurial is running')) |
273 layout.addWidget(remember_field, 3, 1) | 274 layout.addWidget(remember_field, 3, 1) |
274 warning_field = QtGui.QLabel() | 275 warning_field = QtWidgets.QLabel() |
275 warning_field.setText(_('<qt><i><small>Do not use this option if anyone else has access to your computer!</small></i><br></qt>')) | 276 warning_field.setText(_('<qt><i><small>Do not use this option if anyone else has access to your computer!</small></i><br></qt>')) |
276 warning_field.hide() | 277 warning_field.hide() |
277 remember_field.clicked.connect(warning_field.show) | 278 remember_field.clicked.connect(warning_field.show) |
278 layout.addWidget(warning_field, 4, 1, QtCore.Qt.AlignRight) | 279 layout.addWidget(warning_field, 4, 1, QtCore.Qt.AlignRight) |
279 | 280 |
280 bb = QtGui.QDialogButtonBox() | 281 bb = QtWidgets.QDialogButtonBox() |
281 ok = bb.addButton(bb.Ok) | 282 ok = bb.addButton(bb.Ok) |
282 cancel = bb.addButton(bb.Cancel) | 283 cancel = bb.addButton(bb.Cancel) |
283 cancel.setDefault(False) | 284 cancel.setDefault(False) |
284 cancel.setAutoDefault(False) | 285 cancel.setAutoDefault(False) |
285 ok.setDefault(True) | 286 ok.setDefault(True) |
298 ok.setFocus(True) | 299 ok.setFocus(True) |
299 | 300 |
300 dialog.raise_() | 301 dialog.raise_() |
301 ok = dialog.exec_() | 302 ok = dialog.exec_() |
302 if not ok: | 303 if not ok: |
303 raise util.Abort(_('password entry cancelled')) | 304 raise error.Abort(_('password entry cancelled')) |
304 | 305 |
305 self.auth_store.user = user_field.text() | 306 self.auth_store.user = user_field.text() |
306 self.auth_store.passwd = passwd_field.text() | 307 self.auth_store.passwd = passwd_field.text() |
307 | 308 |
308 if remember_field: | 309 if remember_field: |
313 return (self.auth_store.user, self.auth_store.passwd) | 314 return (self.auth_store.user, self.auth_store.passwd) |
314 | 315 |
315 | 316 |
316 def uisetup(ui): | 317 def uisetup(ui): |
317 if not easyhg_pyqt_ok: | 318 if not easyhg_pyqt_ok: |
318 raise util.Abort(_('Failed to load PyQt4 module required by easyhg.py')) | 319 raise error.Abort(_('Failed to load PyQt5 module required by easyhg.py')) |
319 global easyhg_qtapp | 320 global easyhg_qtapp |
320 easyhg_qtapp = QtGui.QApplication([]) | 321 easyhg_qtapp = QtWidgets.QApplication([]) |
321 | 322 |
322 def monkeypatch_method(cls): | 323 def monkeypatch_method(cls): |
323 def decorator(func): | 324 def decorator(func): |
324 setattr(cls, func.__name__, func) | 325 setattr(cls, func.__name__, func) |
325 return func | 326 return func |
336 if not self.ui.interactive(): | 337 if not self.ui.interactive(): |
337 return orig_find(self, realm, authuri) | 338 return orig_find(self, realm, authuri) |
338 if not easyhg_pyqt_ok: | 339 if not easyhg_pyqt_ok: |
339 return orig_find(self, realm, authuri) | 340 return orig_find(self, realm, authuri) |
340 | 341 |
341 authinfo = urllib2.HTTPPasswordMgrWithDefaultRealm.find_user_password( | 342 mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() |
342 self, realm, authuri) | 343 authinfo = mgr.find_user_password(realm, authuri) |
343 user, passwd = authinfo | 344 user, passwd = authinfo |
344 | 345 |
345 repeat = False | 346 repeat = False |
346 | 347 |
347 if (realm, authuri) == self.__easyhg_last: | 348 if (realm, authuri) == self.__easyhg_last: |