diff --git a/bridgedb.conf b/bridgedb.conf index e0b25f0f..c91cc736 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 90c5e2f0..4fb6cc0c 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 e81283e1..ae85e8f1 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 5a9c5284..1f38e4ba 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 @@ def _(text): # 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 e765ce76..9486199f 100644 --- a/lib/bridgedb/templates/options.html +++ b/lib/bridgedb/templates/options.html @@ -87,11 +87,14 @@

${_("""Advanced Options""")}

accesskey="t"> ${_("""No""")} - - - - - +% for methodname, default in strings._getSupportedAndDefaultTransports().items(): + +% endfor