From 47232308a9d40adf23c3bd29b873dd62a17059d9 Mon Sep 17 00:00:00 2001 From: Romain Bignon Date: Fri, 16 Jan 2015 12:21:51 +0100 Subject: [PATCH] prompt user to accept an untrusted keyring (closes #771) --- weboob/applications/weboobcfg/weboobcfg.py | 3 ++- weboob/core/repositories.py | 25 ++++++++++++++-------- weboob/tools/application/console.py | 20 ++++++++++++++--- weboob/tools/application/qt/backendcfg.py | 5 +++++ 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/weboob/applications/weboobcfg/weboobcfg.py b/weboob/applications/weboobcfg/weboobcfg.py index 3b695fff..cbc85a4a 100644 --- a/weboob/applications/weboobcfg/weboobcfg.py +++ b/weboob/applications/weboobcfg/weboobcfg.py @@ -25,6 +25,7 @@ import re from weboob.capabilities.account import CapAccount from weboob.core.modules import ModuleLoadError from weboob.tools.application.repl import ReplApplication +from weboob.tools.application.console import ConsoleProgress from weboob.tools.ordereddict import OrderedDict from weboob.tools.application.formatters.iformatter import IFormatter @@ -308,4 +309,4 @@ class WeboobCfg(ReplApplication): Update weboob. """ - self.weboob.update() + self.weboob.update(ConsoleProgress(self)) diff --git a/weboob/core/repositories.py b/weboob/core/repositories.py index 49e5f424..5afde3ed 100644 --- a/weboob/core/repositories.py +++ b/weboob/core/repositories.py @@ -26,6 +26,7 @@ import re import sys import os import subprocess +import hashlib from datetime import datetime from contextlib import closing from compileall import compile_dir @@ -181,7 +182,7 @@ class Repository(object): # Save the repository index in ~/.weboob/repositories/ self.save(repo_path, private=True) - def retrieve_keyring(self, browser, keyring_path): + def retrieve_keyring(self, browser, keyring_path, progress): # ignore local if self.local: return @@ -203,11 +204,11 @@ class Repository(object): if keyring.exists(): if not keyring.is_valid(keyring_data, sig_data): raise InvalidSignature('the keyring itself') - print('The keyring was updated (and validated by the previous one).') - else: - print('First time saving the keyring, blindly accepted.') + progress.progress(0.0, 'The keyring was updated (and validated by the previous one).') + 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())): + raise RepositoryUnavailable('Repository not trusted') keyring.save(keyring_data, self.key_update) - print(keyring) + progress.progress(0.0, str(keyring)) def parse_index(self, fp): """ @@ -380,6 +381,9 @@ class IProgress(object): def error(self, message): raise NotImplementedError() + def prompt(self, message): + raise NotImplementedError() + def __repr__(self): return '<%s>' % self.__class__.__name__ @@ -391,6 +395,10 @@ class PrintProgress(IProgress): def error(self, message): print('ERROR: %s' % message, file=sys.stderr) + def prompt(self, message): + print('%s (Y/n): *** ASSUMING YES ***' % message) + return True + class ModuleInstallError(Exception): pass @@ -581,7 +589,7 @@ class Repositories(object): try: repository.retrieve_index(self.browser, repo_path) if gpgv: - repository.retrieve_keyring(self.browser, keyring_path) + repository.retrieve_keyring(self.browser, keyring_path, progress) else: progress.error('Cannot find gpgv to check for repository authenticity.\n' 'You should install GPG for better security.') @@ -612,7 +620,7 @@ class Repositories(object): :param progress: observer object. :type progress: :class:`IProgress` """ - self.update_repositories() + self.update_repositories(progress) to_update = [] for name, info in self.get_all_modules_info().iteritems(): @@ -807,8 +815,7 @@ class Keyring(object): def __str__(self): if self.exists(): - with open(self.vpath, 'r') as f: - import hashlib + with open(self.path, 'r') as f: h = hashlib.sha1(f.read()).hexdigest() return 'Keyring version %s, checksum %s' % (self.version, h) return 'NO KEYRING' diff --git a/weboob/tools/application/console.py b/weboob/tools/application/console.py index b73ef4e6..2b37ad51 100644 --- a/weboob/tools/application/console.py +++ b/weboob/tools/application/console.py @@ -31,7 +31,7 @@ from weboob.capabilities import UserError from weboob.capabilities.account import CapAccount, Account, AccountRegisterError from weboob.core.backendscfg import BackendAlreadyExists 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.tools.value import Value, ValueBool, ValueFloat, ValueInt, ValueBackendPassword from weboob.tools.misc import to_unicode @@ -55,6 +55,20 @@ class BackendNotFound(Exception): 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): """ Base application class for CLI applications. @@ -289,7 +303,7 @@ class ConsoleApplication(Application): def install_module(self, name): try: - self.weboob.repositories.install(name) + self.weboob.repositories.install(name, ConsoleProgress(self)) except ModuleInstallError as e: print('Unable to install module "%s": %s' % (name, e), file=self.stderr) return False @@ -564,7 +578,7 @@ class ConsoleApplication(Application): minfo = self.weboob.repositories.get_module_info(backend.NAME) 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 = self.weboob.repositories.get_module_info(backend.NAME) diff --git a/weboob/tools/application/qt/backendcfg.py b/weboob/tools/application/qt/backendcfg.py index fc5531a6..0b8db780 100644 --- a/weboob/tools/application/qt/backendcfg.py +++ b/weboob/tools/application/qt/backendcfg.py @@ -80,6 +80,11 @@ class ProgressDialog(IProgress, QProgressDialog): def error(self, message): 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): def __init__(self, weboob, caps=None, parent=None):