(Steve Dougherty)
2013-06-21: Add per-repo Freemail password configuration. Add per-repo Freemail password configuration.
diff --git a/infocalypse/__init__.py b/infocalypse/__init__.py --- a/infocalypse/__init__.py +++ b/infocalypse/__init__.py @@ -499,10 +499,9 @@ cmdtable = { "[options]"), "fn-setupfreemail": (infocalypse_setupfreemail, - [('', 'password', '', 'Freemail password')] - + WOT_OPTS + WOT_OPTS + FCP_OPTS, - "[--truster nick@key] --password <password>"), + "[--truster nick@key]"), "fn-archive": (infocalypse_archive, [('', 'uri', '', 'Request URI for --pull, Insert URI ' + @@ -527,7 +526,6 @@ commands.norepo += ' fn-setupfms' commands.norepo += ' fn-genkey' commands.norepo += ' fn-archive' commands.norepo += ' fn-setupwot' -commands.norepo += ' fn-setupfreemail' ## Wrap core commands for use with freenet keys. diff --git a/infocalypse/commands.py b/infocalypse/commands.py --- a/infocalypse/commands.py +++ b/infocalypse/commands.py @@ -465,20 +465,24 @@ def infocalypse_setupwot(ui_, **opts): wot.execute_setup_wot(ui_, opts) -# TODO: Should Freemail setup also be part of fn-setup? -# TODO: Should there be per-Identity config? Then each one would have a list -# of repos and optionally a Freemail password. -# Nah, FMS config is global. -def infocalypse_setupfreemail(ui, **opts): - if 'truster' in opts: - identity = opts['truster'] +def infocalypse_setupfreemail(ui, repo, **opts): + """ + Set a Freemail password. If --truster is not given uses the default + truster. + """ + import wot + # TODO: Here --truster doesn't make sense. There is no trust involved. + # TODO: Should this be part of the normal fn-setup? + wot.execute_setup_freemail(ui, get_truster(ui, repo, opts)) + + +def get_truster(ui, repo, opts): + if opts['truster']: + return opts['truster'] else: cfg = Config().from_ui(ui) - identity = cfg.defaults['TRUSTER'] - import wot - # TODO: Should this be part of the normal fn-setup? - wot.execute_setup_freemail(ui, identity) - + # TODO: What about if there's no request URI set? + return '@' + cfg.get_wot_identity(cfg.get_request_uri(repo.root)) #----------------------------------------------------------" def do_archive_create(ui_, opts, params, stored_cfg): diff --git a/infocalypse/config.py b/infocalypse/config.py --- a/infocalypse/config.py +++ b/infocalypse/config.py @@ -127,6 +127,8 @@ class Config: self.insert_usks = {} # repo id -> publisher WoT identity self.wot_identities = {} + # WoT public key hash -> Freemail password + self.freemail_passwords = {} # fms_id -> (usk_hash, ...) map self.fmsread_trust_map = DEFAULT_TRUST.copy() self.fmsread_groups = DEFAULT_GROUPS @@ -219,6 +221,22 @@ class Config: """ return normalize(for_usk_or_id) in self.wot_identities + def set_freemail_password(self, wot_identity, password): + """ + Set the password for the given WoT identity. + """ + self.freemail_passwords[wot_identity] = password + + def get_freemail_password(self, wot_identity): + """ + Return the password associated with the given WoT identity, + or None if one is not set. + """ + if wot_identity in self.freemail_passwords: + return self.freemail_passwords[wot_identity] + else: + return None + # Hmmm... really nescessary? def get_dir_insert_uri(self, repo_dir): """ Return the insert USK for repo_dir or None. """ @@ -328,6 +346,11 @@ class Config: cfg.wot_identities[repo_id] = parser.get('wot_identities', repo_id) + if parser.has_section('freemail_passwords'): + for wot_id in parser.options('freemail_passwords'): + cfg.freemail_passwords[wot_id] = parser.get( + 'freemail_passwords', wot_id) + # ignored = fms_id|usk_hash|usk_hash|... if parser.has_section('fmsread_trust_map'): cfg.fmsread_trust_map.clear() # Wipe defaults. @@ -408,6 +431,10 @@ class Config: parser.add_section('wot_identities') for repo_id in cfg.wot_identities: parser.set('wot_identities', repo_id, cfg.wot_identities[repo_id]) + parser.add_section('freemail_passwords') + for wot_id in cfg.freemail_passwords: + parser.set('freemail_passwords', wot_id, cfg.freemail_passwords[ + wot_id]) parser.add_section('fmsread_trust_map') for index, fms_id in enumerate(cfg.fmsread_trust_map): entry = cfg.fmsread_trust_map[fms_id] diff --git a/infocalypse/wot.py b/infocalypse/wot.py --- a/infocalypse/wot.py +++ b/infocalypse/wot.py @@ -117,10 +117,49 @@ def execute_setup_wot(ui_, opts): Config.to_file(cfg) -def execute_setup_freemail(ui, identity, password): +def execute_setup_freemail(ui, wot_identifier): + """ + Prompt for, test, and set a Freemail password for the identity. + """ + local_id = resolve_local_identity(ui, wot_identifier) - # TODO: get truster from config; check password. - pass + if local_id is None: + return + + address = to_freemail_address(local_id) + + if address is None: + ui.warn("{0}@{1} does not have a Freemail address.\n".format( + local_id['Nickname'], local_id['Identity'])) + return + + password = ui.getpass() + if password is None: + ui.warn("Cannot prompt for a password in a non-interactive context.") + return + + ui.status("Checking password for {0}@{1}.\n".format(local_id['Nickname'], + local_id['Identity'])) + + cfg = config.Config() + cfg.from_ui(ui) + + # Check that the password works. + try: + # TODO: Is this the correct way to get the configured host? + smtp = smtplib.SMTP(cfg.defaults['HOST'], FREEMAIL_SMTP_PORT) + smtp.login(address, password) + except smtplib.SMTPAuthenticationError, e: + ui.warn("Could not log in using password '{0}'.\n".format(password)) + ui.warn("Got '{0}'\n".format(e.smtp_error)) + return + except smtplib.SMTPConnectError, e: + ui.warn("Could not connect to server.\n") + ui.warn("Got '{0}'\n".format(e.smtp_error)) + return + + cfg.set_freemail_password(wot_identifier, password) + ui.status("Password set.\n") def resolve_local_identity(ui, identity):