(Steve Dougherty)
2013-06-18: Remove redundant full-key local identity matching. Remove redundant full-key local identity matching. Partial key matching works for full key matching too.
diff --git a/infocalypse/__init__.py b/infocalypse/__init__.py --- a/infocalypse/__init__.py +++ b/infocalypse/__init__.py @@ -353,7 +353,7 @@ from wikicmds import execute_wiki, execu from arccmds import execute_arc_create, execute_arc_pull, execute_arc_push, \ execute_arc_reinsert -from config import read_freesite_cfg +from config import read_freesite_cfg, Config from validate import is_hex_string, is_fms_id def set_target_version(ui_, repo, opts, params, msg_fmt): @@ -555,6 +555,13 @@ def infocalypse_pull(ui_, repo, **opts): # Hmmmm... can't really implement rev. execute_pull(ui_, repo, params, stored_cfg) + +def infocalypse_pull_request(ui, repo, **opts): + if not opts['wot']: + ui.warning("Who do you want to send the pull request to? Set --wot.") + return + + def infocalypse_push(ui_, repo, **opts): """ Push to an Infocalypse repository in Freenet. """ params, stored_cfg = get_config_info(ui_, opts) @@ -798,6 +805,20 @@ 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'] + 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) + #----------------------------------------------------------" def do_archive_create(ui_, opts, params, stored_cfg): """ fn-archive --create.""" @@ -920,6 +941,11 @@ cmdtable = { + AGGRESSIVE_OPT, "[options]"), + "fn-pull-request": (infocalypse_pull_request, + WOT_OPTS + + FCP_OPTS, + "--wot id@key/repo"), + "fn-push": (infocalypse_push, [('', 'uri', '', 'insert URI to push to'), # Buggy. Not well thought out. @@ -1025,6 +1051,12 @@ cmdtable = { WOT_OPTS, "[options]"), + "fn-setupfreemail": (infocalypse_setupfreemail, + [('', 'password', '', 'Freemail password')] + + WOT_OPTS + + FCP_OPTS, + "[--truster nick@key] --password <password>"), + "fn-archive": (infocalypse_archive, [('', 'uri', '', 'Request URI for --pull, Insert URI ' + 'for --create, --push'), diff --git a/infocalypse/wot.py b/infocalypse/wot.py --- a/infocalypse/wot.py +++ b/infocalypse/wot.py @@ -2,6 +2,32 @@ import fcp from config import Config import xml.etree.ElementTree as ET from defusedxml.ElementTree import fromstring +import smtplib +from base64 import b32encode +from fcp.node import base64decode + + +def send_pull_request(ui, from_identity, to_identity): + local_identity = resolve_local_identity(ui, from_identity) + target_identity = resolve_identity(ui, from_identity, to_identity) + + if local_identity is None or target_identity is None: + # Error. + return + + from_address = to_freemail_address(local_identity) + to_address = to_freemail_address(to_identity) + + if from_address is None or to_address is None: + ui.warn("At least one of {0} and {2} is not using Freemail." + .format(from_identity['Nickname'], to_identity['Nickname'])) + return + + # TODO: Use FCP host; default port. + smtp = smtplib.SMTP() + # TODO: Where to configure Freemail password? + smtp.login(from_address, ) + smtp.sendmail() def update_repo_listing(ui, for_identity): @@ -86,6 +112,12 @@ def execute_setup_wot(ui_, opts): Config.to_file(cfg) +def execute_setup_freemail(ui, identity, password): + + # TODO: get truster from config; check password. + pass + + def resolve_local_identity(ui, identity): """ Mercurial ui for error messages. @@ -109,19 +141,6 @@ def resolve_local_identity(ui, identity) ui.warn("Unexpected reply. Got {0}\n.".format(response)) return - prefix = 'Replies.Identity' - id_num = -1 - # Go by full key instead. - if nickname_prefix is None: - for item in response.iteritems(): - if item[1] == key_prefix: - # Assuming identities will always be unique. - id_num = item[0][len(prefix):] - return read_local_identity(response, id_num) - - ui.warn("No identity found with key '{0}'.\n".format(key_prefix)) - return - # Find nicknames starting with the supplied nickname prefix. prefix = 'Replies.Nickname' # Key: nickname, value (id_num, public key hash). @@ -288,3 +307,22 @@ def parse_name(identity): key_prefix = split[1] return nickname_prefix, key_prefix + + +def to_freemail_address(identity): + """ + Return a Freemail address to contact the given identity if it has a + Freemail context. Return None if it does not have a Freemail context. + """ + + # Freemail addresses encode the public key hash with base32 instead of + # base64 as WoT does. This is to be case insensitive because email + # addresses are not case sensitive, so some clients may mangle case. + # See https://github.com/zidel/Freemail/blob/v0.2.2.1/docs/spec/spec.tex#L32 + + for item in identity.iteritem(): + if item[1] == 'Freemail' and item[0].startswith('Context'): + return identity['Nickname'] + '@' + b32encode(base64decode( + identity['Identity'])) + 'freemail' + + return None