Explorar el Código

Show an error for username= without password=. Fixes #728

Mike Naberezny hace 9 años
padre
commit
85ef4f6fc2
Se han modificado 3 ficheros con 65 adiciones y 8 borrados
  1. 6 0
      CHANGES.txt
  2. 6 4
      supervisor/options.py
  3. 53 4
      supervisor/tests/test_options.py

+ 6 - 0
CHANGES.txt

@@ -31,6 +31,12 @@
 - Files included via the ``[include]`` section are now logged at the ``INFO``
   level instead of ``WARN``.  Patch by Daniel Hahler.
 
+- Parsing the config file will now fail with an error message if an
+  ``inet_http_server`` or ``unix_http_server`` section contains a ``username=``
+  but no ``password=``.  In previous versions, ``supervisord`` would start with
+  this invalid configuration but the HTTP server would always return a 500
+  Internal Server Error.  Thanks to Chris Ergatides for reporting this issue.
+
 3.2.1 (2016-02-06)
 ------------------
 

+ 6 - 4
supervisor/options.py

@@ -1021,10 +1021,12 @@ class ServerOptions(Options):
         get = parser.saneget
         username = get(section, 'username', None)
         password = get(section, 'password', None)
-        if username is None and password is not None:
-            raise ValueError(
-                'Must specify username if password is specified in [%s]'
-                % section)
+        if username is not None or password is not None:
+            if username is None or password is None:
+                raise ValueError(
+                    'Section [%s] contains incomplete authentication: '
+                    'If a username or a password is specified, both the '
+                    'username and password must be specified' % section)
         return {'username':username, 'password':password}
 
     def server_configs_from_parser(self, parser):

+ 53 - 4
supervisor/tests/test_options.py

@@ -1137,6 +1137,28 @@ class ServerOptionsTests(unittest.TestCase):
             self.assertEqual(exc.args[0],
                 "section [unix_http_server] has no file value")
 
+    def test_options_afunix_username_without_password(self):
+        instance = self._makeOne()
+        text = lstrip("""\
+        [supervisord]
+
+        [unix_http_server]
+        file=/tmp/supvtest.sock
+        username=usernamehere
+        ;no password=
+        chmod=0755
+        """)
+        instance.configfile = StringIO(text)
+        try:
+            instance.read_config(StringIO(text))
+            self.fail("nothing raised")
+        except ValueError as exc:
+            self.assertEqual(exc.args[0],
+                'Section [unix_http_server] contains incomplete '
+                'authentication: If a username or a password is '
+                'specified, both the username and password must '
+                'be specified')
+
     def test_options_afunix_password_without_username(self):
         instance = self._makeOne()
         text = lstrip("""\
@@ -1144,6 +1166,7 @@ class ServerOptionsTests(unittest.TestCase):
 
         [unix_http_server]
         file=/tmp/supvtest.sock
+        ;no username=
         password=passwordhere
         chmod=0755
         """)
@@ -1153,8 +1176,10 @@ class ServerOptionsTests(unittest.TestCase):
             self.fail("nothing raised")
         except ValueError as exc:
             self.assertEqual(exc.args[0],
-                "Must specify username if password is specified "
-                "in [unix_http_server]")
+                'Section [unix_http_server] contains incomplete '
+                'authentication: If a username or a password is '
+                'specified, both the username and password must '
+                'be specified')
 
     def test_options_afunix_file_expands_here(self):
         instance = self._makeOne()
@@ -1180,6 +1205,28 @@ class ServerOptionsTests(unittest.TestCase):
         self.assertEqual(serverconf['file'],
             os.path.join(here, 'supervisord.sock'))
 
+    def test_options_afinet_username_without_password(self):
+        instance = self._makeOne()
+        text = lstrip("""\
+        [supervisord]
+
+        [inet_http_server]
+        file=/tmp/supvtest.sock
+        username=usernamehere
+        ;no password=
+        chmod=0755
+        """)
+        instance.configfile = StringIO(text)
+        try:
+            instance.read_config(StringIO(text))
+            self.fail("nothing raised")
+        except ValueError as exc:
+            self.assertEqual(exc.args[0],
+                'Section [inet_http_server] contains incomplete '
+                'authentication: If a username or a password is '
+                'specified, both the username and password must '
+                'be specified')
+
     def test_options_afinet_password_without_username(self):
         instance = self._makeOne()
         text = lstrip("""\
@@ -1195,8 +1242,10 @@ class ServerOptionsTests(unittest.TestCase):
             self.fail("nothing raised")
         except ValueError as exc:
             self.assertEqual(exc.args[0],
-                "Must specify username if password is specified "
-                "in [inet_http_server]")
+                'Section [inet_http_server] contains incomplete '
+                'authentication: If a username or a password is '
+                'specified, both the username and password must '
+                'be specified')
 
     def test_options_afinet_no_port(self):
         instance = self._makeOne()