Opened 5 years ago

Closed 5 years ago

#12504 closed enhancement (fixed)

Create BridgeDB config setting for which Pluggable Transports are supported

Reported by: isis Owned by: isis
Priority: Low Milestone:
Component: Circumvention/BridgeDB Version:
Severity: Keywords: easy, bridgedb-ui, pluggable-transports, bridgedb-0.3.2
Cc: isis, sysrqb Actual Points:
Parent ID: Points:
Reviewer: Sponsor:

Description

Currently, there is a list of the "currently supported Pluggable Transports" in bridgedb.strings. This module attribute can be used to change which PTs are listed in the dropdown menu on https://bridges.torproject.org/options, as well as in the list sent out in email responses. Changing this will easily change what both UIs display, however, there still are some sections of BridgeDB's code where the supported PTs are hardcoded.

We need to:

  1. Identify where and why PT method names are hardcoded.
  2. Create a config setting in bridgedb.conf to set this list globally (in the UI, and in code logic).
  3. Get rid of all the hardcoded PT method names in (1) and replace them with the thing from (2).

Child Tickets

Change History (4)

comment:1 Changed 5 years ago by isis

This would be nice to have done before #13202.

comment:2 Changed 5 years ago by isis

So the biggest problem with this is getting the somewhat janky HTML templating system (Mako version 0.8.1) to populate the <select> dropdown on the form on the options.html page.

I tried doing it with the following patch, however the <select> dropdown was left with only a none option in it:

 bridgedb.conf                       | 14 +++++++++
 lib/bridgedb/configure.py           | 11 +++++++
 lib/bridgedb/email/templates.py     |  2 +-
 lib/bridgedb/strings.py             | 57 +++++++++++++++++++++++++++++++------
 lib/bridgedb/templates/options.html | 13 +++++----
 5 files changed, 82 insertions(+), 15 deletions(-)

diff --git i/bridgedb.conf w/bridgedb.conf
index e0b25f0..251c678 100644
--- i/bridgedb.conf
+++ w/bridgedb.conf
@@ -237,6 +237,20 @@ 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,
+}
+
+#: The transport which is selected by default (e.g. in the webserver dropdown
+#: menu):
+DEFAULT_TRANSPORT = 'obfs4'
+
 #-------------------------------
 # HTTP(S) Distribution Options  \
 #------------------------------------------------------------------------------
diff --git i/lib/bridgedb/configure.py w/lib/bridgedb/configure.py
index 90c5e2f..5dc262b 100644
--- i/lib/bridgedb/configure.py
+++ w/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,14 @@ 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", ""))
+
     for domain in config.EMAIL_DOMAINS:
         config.EMAIL_DOMAIN_MAP[domain] = domain
 
diff --git i/lib/bridgedb/email/templates.py w/lib/bridgedb/email/templates.py
index e81283e..ae85e8f 100644
--- i/lib/bridgedb/email/templates.py
+++ w/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 i/lib/bridgedb/strings.py w/lib/bridgedb/strings.py
index 5a9c528..02323c0 100644
--- i/lib/bridgedb/strings.py
+++ w/lib/bridgedb/strings.py
@@ -166,21 +166,60 @@ EMAIL_COMMANDS = {
 #           All of the following containers are untranslated!
 #-----------------------------------------------------------------------------
 
-#: A list of all currently available pluggable transports. By "currently
-#: available" we mean:
+#: A dictionary of all pluggable transports and 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",
-]
+#: **Don't** change this setting here; change it in :file:`bridgedb.conf`.
+SUPPORTED_TRANSPORTS = {}
+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.
+    """
+    return [methodname.lower() for methodname, support in SUPPORTED_TRANSPORTS.items() if support]
+
+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.
+    """
+    supported = dict(zip(
+        [methodname for methodname, support in SUPPORTED_TRANSPORTS.items() if support],
+        [False for methodname in SUPPORTED_TRANSPORTS.keys()]))
+
+    if DEFAULT_TRANSPORT:
+        supported[DEFAULT_TRANSPORT] = True
+
+    return supported
+
+def _setDefaultTransport(transport):
+    global DEFAULT_TRANSPORT
+    DEFAULT_TRANSPORT = transport
+
 
 EMAIL_SPRINTF = {
     # Goes into the "%s types of Pluggable Transports %s" part of ``WELCOME[0]``
diff --git i/lib/bridgedb/templates/options.html w/lib/bridgedb/templates/options.html
index e765ce7..0255c1b 100644
--- i/lib/bridgedb/templates/options.html
+++ w/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():
+    <option label=${methodname}
+            value=${methodname}
+    % if default:
+            selected
+    % endif
+            > ${methodname} </option>
+% endfor
                       </select>
                     </div>
                   </div>


I suspect the issue isn't with the templating system here, but rather with configure.py being able to set the global variables before the other modules import them and thus have a copy in their own module-level __dict__, which would make setattring all the silly copies of the thing rather icky and super hacky.

We may not be able to set the SUPPORTED_TRANSPORTS in the bridgedb.conf file. It might need to always be done in lib/bridgedb/strings.py.

Let me try something else…

comment:3 Changed 5 years ago by isis

Keywords: bridgedb-0.3.2 added; bridgedb-0.2.x removed
Status: newneeds_review

Alright, I have a working fix that isn't hacky which allows us to set this in the bridgedb.conf file. It's in my fix/12504-config-pts branch.

comment:4 Changed 5 years ago by isis

Resolution: fixed
Status: needs_reviewclosed

Fixed a typo in a comment in bridgedb.configure. (Thanks to Robert Ransom for spotting it.)

This is merged for bridgedb-0.3.2.

Note: See TracTickets for help on using tickets.