commit 0a6bea1ddae7e9a3885b2d4486e625c2b3f7f7ac Author: Isis Lovecruft isis@torproject.org Date: Thu Mar 26 03:03:15 2015 +0000
Make which pluggable transports are distributed easily configurable.
* REMOVE bridgedb.strings.CURRENT_TRANSPORTS.
* ADD b.strings.SUPPORTED_TRANSPORTS, which can be get/set with b.strings._getSupportedTransports() and _setSupportedTransports(). There is also a new SUPPORTED_TRANSPORTS option in bridgedb.conf; the setting at bridgedb.strings.SUPPORTED_TRANSPORTS is now automatically configured via the bridgedb.conf file.
* ADD b.strings.DEFAULT_TRANSPORT, which can be get/set with b.strings._getDefaultTransport() and _setDefaultTransport(). There is also a new DEFAULT_TRANSPORT option in bridgedb.conf; the setting at bridgedb.strings.DEFAULT_TRANSPORT is now automatically configured via the bridgedb.conf file.
* CHANGE options.html template to automatically populate the list of available transports. The DEFAULT_TRANSPORT is automatically the selected default.
* FIXES #12504: https://bugs.torproject.org/12504 --- bridgedb.conf | 18 +++++++ lib/bridgedb/configure.py | 14 ++++++ lib/bridgedb/email/templates.py | 2 +- lib/bridgedb/strings.py | 90 +++++++++++++++++++++++++++++++---- lib/bridgedb/templates/options.html | 13 +++-- 5 files changed, 121 insertions(+), 16 deletions(-)
diff --git a/bridgedb.conf b/bridgedb.conf index e0b25f0..c91cc73 100644 --- a/bridgedb.conf +++ b/bridgedb.conf @@ -20,6 +20,9 @@ # # CHANGELOG: # ~~~~~~~~~~ +# Changed in version 0.0.15 - 2015-03-26 +# * ADD new SUPPORTED_TRANSPORTS and DEFAULT_TRANSPORT settings. +# # Changes in version 0.0.14 - 2015-02-22 # * ADD new OpenPGP-related options: # - EMAIL_GPG_HOMEDIR @@ -237,6 +240,21 @@ TASKS = { 'GET_TOR_EXIT_LIST': 3 * 60 * 60, }
+# SUPPORTED_TRANSPORTS is a dictionary mapping Pluggable Transport methodnames +# to booleans. If ``True``, the PT is distributed; if ``False``, it isn't. +SUPPORTED_TRANSPORTS = { + 'obfs2': True, + 'obfs3': True, + 'obfs4': True, + 'scramblesuit': True, + 'fte': True, +} + +# DEFAULT_TRANSPORT is a string. It should be the PT methodname of the +# transport which is selected by default (e.g. in the webserver dropdown +# menu). +DEFAULT_TRANSPORT = 'obfs4' + #------------------------------- # HTTP(S) Distribution Options \ #------------------------------------------------------------------------------ diff --git a/lib/bridgedb/configure.py b/lib/bridgedb/configure.py index 90c5e2f..4fb6cc0 100644 --- a/lib/bridgedb/configure.py +++ b/lib/bridgedb/configure.py @@ -14,6 +14,9 @@ import logging import os
+# Used to set the SUPPORTED_TRANSPORTS: +from bridgedb import strings +
def loadConfig(configFile=None, configCls=None): """Load configuration settings on top of the current settings. @@ -116,6 +119,17 @@ def loadConfig(configFile=None, configCls=None): setting = getattr(config, attr, []) # Default to empty lists setattr(config, attr, setting)
+ for attr in ["SUPPORTED_TRANSPORTS"]: + setting = getattr(config, attr, {}) # Default to emtpy dicts + setattr(config, attr, setting) + + # Set the SUPPORTED_TRANSPORTS to populate the webserver and email options: + strings._setSupportedTransports(getattr(config, "SUPPORTED_TRANSPORTS", {})) + strings._setDefaultTransport(getattr(config, "DEFAULT_TRANSPORT", "")) + logging.info("Currently supported transports: %s" % + " ".join(strings._getSupportedTransports())) + logging.info("Default transport: %s" % strings._getDefaultTransport()) + for domain in config.EMAIL_DOMAINS: config.EMAIL_DOMAIN_MAP[domain] = domain
diff --git a/lib/bridgedb/email/templates.py b/lib/bridgedb/email/templates.py index e81283e..ae85e8f 100644 --- a/lib/bridgedb/email/templates.py +++ b/lib/bridgedb/email/templates.py @@ -53,7 +53,7 @@ def addCommands(template): # And include the currently supported transports: commands += template.gettext(strings.EMAIL_MISC_TEXT.get(5)) commands += "\n" - for pt in strings.CURRENT_TRANSPORTS: + for pt in strings._getSupportedTransports(): commands += ' ' + pt + "\n"
return commands diff --git a/lib/bridgedb/strings.py b/lib/bridgedb/strings.py index 5a9c528..1f38e4b 100644 --- a/lib/bridgedb/strings.py +++ b/lib/bridgedb/strings.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# -*- coding: utf-8 ; test-case-name: bridgedb.test.test_strings ; -*- # # This file is part of BridgeDB, a Tor bridge distribution system. # @@ -10,6 +10,12 @@
from __future__ import unicode_literals
+# This won't work on Python2.6, however +# 1) We don't use Python2.6, and +# 2) We don't care about supporting Python2.6, because Python 2.6 (and, +# honestly, all of Python2) should die. +from collections import OrderedDict +
def _(text): """This is necessary because strings are translated when they're imported. @@ -166,21 +172,85 @@ EMAIL_COMMANDS = { # All of the following containers are untranslated! #-----------------------------------------------------------------------------
-#: A list of all currently available pluggable transports. By "currently -#: available" we mean: +#: SUPPORTED TRANSPORTS is dictionary mapping all Pluggable Transports +#: methodname to whether or not we actively distribute them. The ones which we +#: distribute SHOULD have the following properties: #: #: 1. The PT is in a widely accepted, usable state for most Tor users. #: 2. The PT is currently publicly deployed *en masse*". #: 3. The PT is included within the transports which Tor Browser offers in #: the stable releases. #: -CURRENT_TRANSPORTS = [ - "obfs2", - "obfs3", - "obfs4", - "scramblesuit", - "fte", -] +#: These will be sorted by methodname in alphabetical order. +#: +#: ***Don't change this setting here; change it in :file:`bridgedb.conf`.*** +SUPPORTED_TRANSPORTS = {} + +#: DEFAULT_TRANSPORT is a string. It should be the PT methodname of the +#: transport which is selected by default (e.g. in the webserver dropdown +#: menu). +#: +#: ***Don't change this setting here; change it in :file:`bridgedb.conf`.*** +DEFAULT_TRANSPORT = '' + +def _getSupportedTransports(): + """Get the list of currently supported transports. + + :rtype: list + :returns: A list of strings, one for each supported Pluggable Transport + methodname, sorted in alphabetical order. + """ + supported = [name.lower() for name,w00t in SUPPORTED_TRANSPORTS.items() if w00t] + supported.sort() + return supported + +def _setDefaultTransport(transport): + global DEFAULT_TRANSPORT + DEFAULT_TRANSPORT = transport + +def _getDefaultTransport(): + return DEFAULT_TRANSPORT + +def _setSupportedTransports(transports): + """Set the list of currently supported transports. + + .. note: You shouldn't need to touch this. This is used by the config file + parser. You should change the SUPPORTED_TRANSPORTS dictionary in + :file:`bridgedb.conf`. + + :param dict transports: A mapping of Pluggable Transport methodnames + (strings) to booleans. If the boolean is ``True``, then the Pluggable + Transport is one which we will (more easily) distribute to clients. + If ``False``, then we (sort of) don't distribute it. + """ + global SUPPORTED_TRANSPORTS + SUPPORTED_TRANSPORTS = transports + +def _getSupportedAndDefaultTransports(): + """Get a dictionary of currently supported transports, along with a boolean + marking which transport is the default. + + It is returned as a :class:`collections.OrderedDict`, because if it is a + regular dict, then the dropdown menu would populated in random order each + time the page is rendered. It is sorted in alphabetical order. + + :rtype: :class:`collections.OrderedDict` + :returns: An :class:`~collections.OrderedDict` of the Pluggable Transport + methodnames from :data:`SUPPORTED_TRANSPORTS` whose value in + ``SUPPORTED_TRANSPORTS`` is ``True``. If :data:`DEFAULT_TRANSPORT` is + set, then the PT methodname in the ``DEFAULT_TRANSPORT`` setting is + added to the :class:`~collections.OrderedDict`, with the value + ``True``. Every other transport in the returned ``OrderedDict`` has + its value set to ``False``, so that only the one which should be the + default PT is ``True``. + """ + supported = _getSupportedTransports() + transports = OrderedDict(zip(supported, [False for _ in range(len(supported))])) + + if DEFAULT_TRANSPORT: + transports[DEFAULT_TRANSPORT] = True + + return transports
EMAIL_SPRINTF = { # Goes into the "%s types of Pluggable Transports %s" part of ``WELCOME[0]`` diff --git a/lib/bridgedb/templates/options.html b/lib/bridgedb/templates/options.html index e765ce7..9486199 100644 --- a/lib/bridgedb/templates/options.html +++ b/lib/bridgedb/templates/options.html @@ -87,11 +87,14 @@ accesskey="t"> ${_("""No""")} <option label="none" value="0" >${_("none")}</option> -<option label="obfs2" value="obfs2" >obfs2</option> -<option label="obfs3" value="obfs3" selected >obfs3</option> -<option label="obfs4" value="obfs4" >obfs4</option> -<option label="scramblesuit" value="scramblesuit">scramblesuit</option> -<option label="fte" value="fte" >fteproxy</option> +% for methodname, default in strings._getSupportedAndDefaultTransports().items(): + <option label=${methodname} + value=${methodname} + % if default: + selected + % endif + > ${methodname} </option> +% endfor </select> </div> </div>