prompt user to accept an untrusted keyring (closes #771)

This commit is contained in:
Romain Bignon 2015-01-16 12:21:51 +01:00
commit 47232308a9
4 changed files with 40 additions and 13 deletions

View file

@ -25,6 +25,7 @@ import re
from weboob.capabilities.account import CapAccount from weboob.capabilities.account import CapAccount
from weboob.core.modules import ModuleLoadError from weboob.core.modules import ModuleLoadError
from weboob.tools.application.repl import ReplApplication from weboob.tools.application.repl import ReplApplication
from weboob.tools.application.console import ConsoleProgress
from weboob.tools.ordereddict import OrderedDict from weboob.tools.ordereddict import OrderedDict
from weboob.tools.application.formatters.iformatter import IFormatter from weboob.tools.application.formatters.iformatter import IFormatter
@ -308,4 +309,4 @@ class WeboobCfg(ReplApplication):
Update weboob. Update weboob.
""" """
self.weboob.update() self.weboob.update(ConsoleProgress(self))

View file

@ -26,6 +26,7 @@ import re
import sys import sys
import os import os
import subprocess import subprocess
import hashlib
from datetime import datetime from datetime import datetime
from contextlib import closing from contextlib import closing
from compileall import compile_dir from compileall import compile_dir
@ -181,7 +182,7 @@ class Repository(object):
# Save the repository index in ~/.weboob/repositories/ # Save the repository index in ~/.weboob/repositories/
self.save(repo_path, private=True) self.save(repo_path, private=True)
def retrieve_keyring(self, browser, keyring_path): def retrieve_keyring(self, browser, keyring_path, progress):
# ignore local # ignore local
if self.local: if self.local:
return return
@ -203,11 +204,11 @@ class Repository(object):
if keyring.exists(): if keyring.exists():
if not keyring.is_valid(keyring_data, sig_data): if not keyring.is_valid(keyring_data, sig_data):
raise InvalidSignature('the keyring itself') raise InvalidSignature('the keyring itself')
print('The keyring was updated (and validated by the previous one).') progress.progress(0.0, 'The keyring was updated (and validated by the previous one).')
else: elif not progress.prompt('The repository %s isn\'t trusted yet.\nFingerprint of keyring is %s\nAre you sure you want to continue?' % (self.url, hashlib.sha1(keyring_data).hexdigest())):
print('First time saving the keyring, blindly accepted.') raise RepositoryUnavailable('Repository not trusted')
keyring.save(keyring_data, self.key_update) keyring.save(keyring_data, self.key_update)
print(keyring) progress.progress(0.0, str(keyring))
def parse_index(self, fp): def parse_index(self, fp):
""" """
@ -380,6 +381,9 @@ class IProgress(object):
def error(self, message): def error(self, message):
raise NotImplementedError() raise NotImplementedError()
def prompt(self, message):
raise NotImplementedError()
def __repr__(self): def __repr__(self):
return '<%s>' % self.__class__.__name__ return '<%s>' % self.__class__.__name__
@ -391,6 +395,10 @@ class PrintProgress(IProgress):
def error(self, message): def error(self, message):
print('ERROR: %s' % message, file=sys.stderr) print('ERROR: %s' % message, file=sys.stderr)
def prompt(self, message):
print('%s (Y/n): *** ASSUMING YES ***' % message)
return True
class ModuleInstallError(Exception): class ModuleInstallError(Exception):
pass pass
@ -581,7 +589,7 @@ class Repositories(object):
try: try:
repository.retrieve_index(self.browser, repo_path) repository.retrieve_index(self.browser, repo_path)
if gpgv: if gpgv:
repository.retrieve_keyring(self.browser, keyring_path) repository.retrieve_keyring(self.browser, keyring_path, progress)
else: else:
progress.error('Cannot find gpgv to check for repository authenticity.\n' progress.error('Cannot find gpgv to check for repository authenticity.\n'
'You should install GPG for better security.') 'You should install GPG for better security.')
@ -612,7 +620,7 @@ class Repositories(object):
:param progress: observer object. :param progress: observer object.
:type progress: :class:`IProgress` :type progress: :class:`IProgress`
""" """
self.update_repositories() self.update_repositories(progress)
to_update = [] to_update = []
for name, info in self.get_all_modules_info().iteritems(): for name, info in self.get_all_modules_info().iteritems():
@ -807,8 +815,7 @@ class Keyring(object):
def __str__(self): def __str__(self):
if self.exists(): if self.exists():
with open(self.vpath, 'r') as f: with open(self.path, 'r') as f:
import hashlib
h = hashlib.sha1(f.read()).hexdigest() h = hashlib.sha1(f.read()).hexdigest()
return 'Keyring version %s, checksum %s' % (self.version, h) return 'Keyring version %s, checksum %s' % (self.version, h)
return 'NO KEYRING' return 'NO KEYRING'

View file

@ -31,7 +31,7 @@ from weboob.capabilities import UserError
from weboob.capabilities.account import CapAccount, Account, AccountRegisterError from weboob.capabilities.account import CapAccount, Account, AccountRegisterError
from weboob.core.backendscfg import BackendAlreadyExists from weboob.core.backendscfg import BackendAlreadyExists
from weboob.core.modules import ModuleLoadError from weboob.core.modules import ModuleLoadError
from weboob.core.repositories import ModuleInstallError from weboob.core.repositories import ModuleInstallError, IProgress
from weboob.exceptions import BrowserUnavailable, BrowserIncorrectPassword, BrowserForbidden, BrowserSSLError from weboob.exceptions import BrowserUnavailable, BrowserIncorrectPassword, BrowserForbidden, BrowserSSLError
from weboob.tools.value import Value, ValueBool, ValueFloat, ValueInt, ValueBackendPassword from weboob.tools.value import Value, ValueBool, ValueFloat, ValueInt, ValueBackendPassword
from weboob.tools.misc import to_unicode from weboob.tools.misc import to_unicode
@ -55,6 +55,20 @@ class BackendNotFound(Exception):
pass pass
class ConsoleProgress(IProgress):
def __init__(self, app):
self.app = app
def progress(self, percent, message):
self.app.stdout.write('=== [%3.0f%%] %s\n' % (percent*100, message))
def error(self, message):
self.app.stderr.write('ERROR: %s\n' % message)
def prompt(self, message):
return self.app.ask(message, default=True)
class ConsoleApplication(Application): class ConsoleApplication(Application):
""" """
Base application class for CLI applications. Base application class for CLI applications.
@ -289,7 +303,7 @@ class ConsoleApplication(Application):
def install_module(self, name): def install_module(self, name):
try: try:
self.weboob.repositories.install(name) self.weboob.repositories.install(name, ConsoleProgress(self))
except ModuleInstallError as e: except ModuleInstallError as e:
print('Unable to install module "%s": %s' % (name, e), file=self.stderr) print('Unable to install module "%s": %s' % (name, e), file=self.stderr)
return False return False
@ -564,7 +578,7 @@ class ConsoleApplication(Application):
minfo = self.weboob.repositories.get_module_info(backend.NAME) minfo = self.weboob.repositories.get_module_info(backend.NAME)
if minfo and not minfo.is_local(): if minfo and not minfo.is_local():
self.weboob.repositories.update_repositories() self.weboob.repositories.update_repositories(ConsoleProgress(self))
# minfo of the new available module # minfo of the new available module
minfo = self.weboob.repositories.get_module_info(backend.NAME) minfo = self.weboob.repositories.get_module_info(backend.NAME)

View file

@ -80,6 +80,11 @@ class ProgressDialog(IProgress, QProgressDialog):
def error(self, message): def error(self, message):
QMessageBox.critical(self, self.tr('Error'), '%s' % message, QMessageBox.Ok) QMessageBox.critical(self, self.tr('Error'), '%s' % message, QMessageBox.Ok)
def prompt(self, message):
reply = QMessageBox.question(self, '', unicode(message), QMessageBox.Yes|QMessageBox.No)
return reply == QMessageBox.Yes
class BackendCfg(QDialog): class BackendCfg(QDialog):
def __init__(self, weboob, caps=None, parent=None): def __init__(self, weboob, caps=None, parent=None):