Quellcode durchsuchen

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

Mike Naberezny vor 9 Jahren
Ursprung
Commit
4572170838
3 geänderte Dateien mit 68 neuen und 8 gelöschten Zeilen
  1. 9 0
      CHANGES.txt
  2. 6 4
      supervisor/options.py
  3. 53 4
      supervisor/tests/test_options.py

+ 9 - 0
CHANGES.txt

@@ -1,3 +1,12 @@
+Next 3.x Release
+----------------
+
+- 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)
 3.2.1 (2016-02-06)
 ------------------
 ------------------
 
 

+ 6 - 4
supervisor/options.py

@@ -988,10 +988,12 @@ class ServerOptions(Options):
         get = parser.saneget
         get = parser.saneget
         username = get(section, 'username', None)
         username = get(section, 'username', None)
         password = get(section, 'password', 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}
         return {'username':username, 'password':password}
 
 
     def server_configs_from_parser(self, parser):
     def server_configs_from_parser(self, parser):

+ 53 - 4
supervisor/tests/test_options.py

@@ -1123,6 +1123,28 @@ class ServerOptionsTests(unittest.TestCase):
             self.assertEqual(exc.args[0],
             self.assertEqual(exc.args[0],
                 "section [unix_http_server] has no file value")
                 "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):
     def test_options_afunix_password_without_username(self):
         instance = self._makeOne()
         instance = self._makeOne()
         text = lstrip("""\
         text = lstrip("""\
@@ -1130,6 +1152,7 @@ class ServerOptionsTests(unittest.TestCase):
 
 
         [unix_http_server]
         [unix_http_server]
         file=/tmp/supvtest.sock
         file=/tmp/supvtest.sock
+        ;no username=
         password=passwordhere
         password=passwordhere
         chmod=0755
         chmod=0755
         """)
         """)
@@ -1139,8 +1162,10 @@ class ServerOptionsTests(unittest.TestCase):
             self.fail("nothing raised")
             self.fail("nothing raised")
         except ValueError, exc:
         except ValueError, exc:
             self.assertEqual(exc.args[0],
             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):
     def test_options_afunix_file_expands_here(self):
         instance = self._makeOne()
         instance = self._makeOne()
@@ -1167,6 +1192,28 @@ class ServerOptionsTests(unittest.TestCase):
         finally:
         finally:
             shutil.rmtree(here, ignore_errors=True)
             shutil.rmtree(here, ignore_errors=True)
 
 
+    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):
     def test_options_afinet_password_without_username(self):
         instance = self._makeOne()
         instance = self._makeOne()
         text = lstrip("""\
         text = lstrip("""\
@@ -1182,8 +1229,10 @@ class ServerOptionsTests(unittest.TestCase):
             self.fail("nothing raised")
             self.fail("nothing raised")
         except ValueError, exc:
         except ValueError, exc:
             self.assertEqual(exc.args[0],
             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):
     def test_options_afinet_no_port(self):
         instance = self._makeOne()
         instance = self._makeOne()