Module for functions that validate the internal setting structure
authorKarl O. Pinc <kop@karlpinc.com>
Sat, 12 Sep 2020 21:14:02 +0000 (16:14 -0500)
committerKarl O. Pinc <kop@karlpinc.com>
Sun, 13 Sep 2020 00:15:16 +0000 (19:15 -0500)
src/pgwui_server/__init__.py
src/pgwui_server/checkset.py [new file with mode: 0644]
tests/test___init__.py
tests/test_checkset.py [new file with mode: 0644]

index fdc930fe82ed5e73c3b6efb8918f4c04e801ca25..2db01be924476d4dc7f2b58b84494a83939b1bf1 100644 (file)
@@ -1,4 +1,5 @@
-# Copyright (C) 2018, 2019 The Meme Factory, Inc.  http://www.karlpinc.com/
+# Copyright (C) 2018, 2019, 2020 The Meme Factory, Inc.
+# http://www.karlpinc.com/
 
 # This file is part of PGWUI_Server.
 #
 '''Provide a way to configure PGWUI.
 '''
 
-from ast import literal_eval
 from pyramid.config import Configurator
 import logging
 import sys
 
 from . import exceptions as server_ex
-from . import constants
+from . import checkset
 from pgwui_common import exceptions as common_ex
 from pgwui_common import plugin
 
@@ -77,74 +77,6 @@ def dot_to_dict(settings, key, new_key):
     del settings[key]
 
 
-def key_to_ini(key):
-    '''Convert the setting key to a key used in an ini file's declaration
-    '''
-    return 'pgwui.{}'.format(key)
-
-
-def require_setting(errors, setting, pgwui_settings):
-    if setting not in pgwui_settings:
-        errors.append(common_ex.MissingSettingError(key_to_ini(setting)))
-
-
-def boolean_setting(errors, setting, pgwui_settings):
-    if setting in pgwui_settings:
-        try:
-            val = literal_eval(pgwui_settings[setting])
-        except ValueError:
-            val = None
-        if (val is not True
-                and val is not False):
-            errors.append(common_ex.NotBooleanSettingError(
-                key_to_ini(setting), pgwui_settings[setting]))
-
-
-def validate_setting_values(errors, settings):
-    '''Check each settings value for validity
-    '''
-    pgwui_settings = settings['pgwui']
-
-    # pg_host can be missing, it defaults to the Unix socket (in psycopg2)
-
-    # pg_port can be missing, it defaults to 5432 (in psycopg2)
-
-    # default_db can be missing, then the user sees no default
-
-    # dry_run
-    require_setting(errors, 'dry_run', pgwui_settings)
-    boolean_setting(errors, 'dry_run', pgwui_settings)
-
-    # route_prefix can be missing, defaults to no route prefix which is fine.
-
-    # routes can be missing, sensible defaults are built-in.
-
-    # validate_hmac
-    boolean_setting(errors, 'validate_hmac', pgwui_settings)
-
-
-def do_validate_hmac(settings):
-    '''True unless the user has specificly rejected hmac validation
-    '''
-    pgwui_settings = settings['pgwui']
-    return ('validate_hmac' not in pgwui_settings
-            or literal_eval(pgwui_settings['validate_hmac']))
-
-
-def validate_hmac(errors, settings):
-    '''Unless otherwise requested, validate the session.secret setting'''
-    if not do_validate_hmac(settings):
-        return
-
-    if 'session.secret' not in settings:
-        errors.append(server_ex.NoHMACError())
-        return
-
-    if len(settings['session.secret']) != constants.HMAC_LEN:
-        errors.append(server_ex.HMACLengthError())
-        return
-
-
 def parse_assignments(lines):
     '''Return a list of key/value tuples from the lines of a setting
     '''
@@ -187,8 +119,8 @@ def dictify_settings(errors, settings, components):
     for key in list(settings.keys()):
         setting_into_dict(
             errors, components, component_checkers, key, settings)
-    validate_setting_values(errors, settings)
-    validate_hmac(errors, settings)
+    checkset.validate_setting_values(errors, settings)
+    checkset.validate_hmac(errors, settings)
 
 
 def exit_reporting_errors(errors):
diff --git a/src/pgwui_server/checkset.py b/src/pgwui_server/checkset.py
new file mode 100644 (file)
index 0000000..62746ba
--- /dev/null
@@ -0,0 +1,98 @@
+# Copyright (C) 2018, 2019, 2020 The Meme Factory, Inc.
+# http://www.karlpinc.com/
+
+# This file is part of PGWUI_Server.
+#
+# This program is free software: you can redistribute it and/or
+# modify it under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public
+# License along with this program.  If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
+# Karl O. Pinc <kop@karlpinc.com>
+
+'''Check the pgwui settings (in the internal "dict format")
+'''
+
+from ast import literal_eval
+
+from . import constants
+from pgwui_common import exceptions as common_ex
+import pgwui_server.exceptions as server_ex
+
+
+def key_to_ini(key):
+    '''Convert the setting key to a key used in an ini file's declaration
+    '''
+    return 'pgwui.{}'.format(key)
+
+
+def require_setting(errors, setting, pgwui_settings):
+    if setting not in pgwui_settings:
+        errors.append(common_ex.MissingSettingError(key_to_ini(setting)))
+
+
+def boolean_setting(errors, setting, pgwui_settings):
+    if setting in pgwui_settings:
+        try:
+            val = literal_eval(pgwui_settings[setting])
+        except ValueError:
+            val = None
+        if (val is not True
+                and val is not False):
+            errors.append(common_ex.NotBooleanSettingError(
+                key_to_ini(setting), pgwui_settings[setting]))
+
+
+def validate_setting_values(errors, settings):
+    '''Check each settings value for validity
+    '''
+    pgwui_settings = settings['pgwui']
+
+    # pg_host can be missing, it defaults to the Unix socket (in psycopg2)
+
+    # pg_port can be missing, it defaults to 5432 (in psycopg2)
+
+    # default_db can be missing, then the user sees no default
+
+    # dry_run
+    require_setting(errors, 'dry_run', pgwui_settings)
+    boolean_setting(errors, 'dry_run', pgwui_settings)
+
+    # route_prefix can be missing, defaults to no route prefix which is fine.
+
+    # routes can be missing, sensible defaults are built-in.
+
+    # validate_hmac
+    boolean_setting(errors, 'validate_hmac', pgwui_settings)
+
+
+def do_validate_hmac(settings):
+    '''True unless the user has specificly rejected hmac validation
+    '''
+    pgwui_settings = settings['pgwui']
+    return ('validate_hmac' not in pgwui_settings
+            or literal_eval(pgwui_settings['validate_hmac']))
+
+
+def validate_hmac(errors, settings):
+    '''Unless otherwise requested, validate the session.secret setting'''
+    if not do_validate_hmac(settings):
+        return
+
+    if 'session.secret' not in settings:
+        errors.append(server_ex.NoHMACError())
+        return
+
+    if len(settings['session.secret']) != constants.HMAC_LEN:
+        errors.append(server_ex.HMACLengthError())
+        return
index 6f786f6442b47faf7be848915c611627d0b96be1..95ad04c9b164d86494ec50528e37144322ad33a4 100644 (file)
@@ -32,8 +32,7 @@ import pgwui_common.plugin
 # Use as a regular module, not a plugin, so lint checks work
 from pgwui_testing import testing
 
-import pgwui_server.constants as constants
-import pgwui_server.exceptions as server_ex
+import pgwui_server.checkset
 import pgwui_server.__init__ as pgwui_server_init
 
 
@@ -71,6 +70,11 @@ mock_find_pgwui_components = testing.make_mock_fixture(
 mock_find_pgwui_check_settings = testing.make_mock_fixture(
     pgwui_common.plugin, 'find_pgwui_check_settings')
 
+mock_validate_setting_values = testing.make_mock_fixture(
+    pgwui_server.checkset, 'validate_setting_values')
+mock_validate_hmac = testing.make_mock_fixture(
+    pgwui_server.checkset, 'validate_hmac')
+
 
 # Unit tests
 
@@ -169,179 +173,6 @@ mock_dot_to_dict = testing.make_mock_fixture(
     pgwui_server_init, 'dot_to_dict')
 
 
-# key_to_ini()
-
-def test_key_to_ini():
-    '''The return value is as expected
-    '''
-    key = 'pgwui_example'
-    result = pgwui_server_init.key_to_ini(key)
-
-    assert result == 'pgwui.' + key
-
-
-mock_key_to_ini = testing.make_mock_fixture(
-    pgwui_server_init, 'key_to_ini')
-
-
-# require_setting()
-
-def test_require_setting_missing():
-    '''Deliver exception when a required setting is missing'''
-    errors = []
-    pgwui_server_init.require_setting(errors, 'key', {})
-
-    assert errors
-    assert isinstance(errors[0], common_ex.MissingSettingError)
-
-
-def test_require_setting_present():
-    '''Does nothing when a required setting is present'''
-    errors = []
-    pgwui_server_init.require_setting(errors, 'key', {'key': 'value'})
-
-    assert errors == []
-
-
-mock_require_setting = testing.make_mock_fixture(
-    pgwui_server_init, 'require_setting')
-
-
-# boolean_setting()
-
-def test_boolean_setting_missing():
-    '''Does nothing when the setting is not in the settings'''
-    errors = []
-    pgwui_server_init.boolean_setting(errors, 'key', {})
-
-    assert errors == []
-
-
-def test_boolean_setting_true():
-    '''Does nothing when the setting is "True"'''
-    errors = []
-    pgwui_server_init.boolean_setting(errors, 'key', {'key': 'True'})
-
-    assert errors == []
-
-
-def test_boolean_setting_false():
-    '''Does nothing when the setting is "False"'''
-    errors = []
-    pgwui_server_init.boolean_setting(errors, 'key', {'key': 'False'})
-
-    assert errors == []
-
-
-def test_boolean_setting_notboolean():
-    '''Deliver an exception when the setting does not evaluate to a boolean'''
-    errors = []
-    pgwui_server_init.boolean_setting(errors, 'key', {'key': '0'})
-
-    assert errors
-    assert isinstance(errors[0], common_ex.NotBooleanSettingError)
-
-
-def test_boolean_setting_notparsable():
-    '''Deliver an exception when the setting does not evaluate to a
-    boolean because it is not parseable
-    '''
-    errors = []
-    pgwui_server_init.boolean_setting(errors, 'key', {'key': 'a'})
-
-    assert errors
-    assert isinstance(errors[0], common_ex.NotBooleanSettingError)
-
-
-mock_boolean_setting = testing.make_mock_fixture(
-    pgwui_server_init, 'boolean_setting')
-
-
-# validate_setting_values()
-
-def test_validate_setting_values(mock_require_setting, mock_boolean_setting):
-    '''Calls require_setting() and boolean_setting()'''
-
-    pgwui_server_init.validate_setting_values([], {'pgwui': {}})
-
-    assert mock_require_setting.called
-    assert mock_boolean_setting.called
-
-
-mock_validate_setting_values = testing.make_mock_fixture(
-    pgwui_server_init, 'validate_setting_values')
-
-
-# do_validate_hmac()
-
-def test_do_validate_hmac_none():
-    '''pgwui.validate_hmac defaults to True'''
-    assert pgwui_server_init.do_validate_hmac({'pgwui': {}}) is True
-
-
-def test_do_validate_hmac_True():
-    '''Require hmac validation when pgwui.validate_hmac is True'''
-    result = pgwui_server_init.do_validate_hmac(
-        {'pgwui': {'validate_hmac': 'True'}})
-    assert result is True
-
-
-def test_do_validate_hmac_False():
-    '''No hmac validation when pgwui.validate_hmac is False'''
-    result = pgwui_server_init.do_validate_hmac(
-        {'pgwui': {'validate_hmac': 'False'}})
-    assert result is False
-
-
-mock_do_validate_hmac = testing.make_mock_fixture(
-    pgwui_server_init, 'do_validate_hmac')
-
-
-# validate_hmac()
-
-def test_validate_hmac_unvalidated(mock_do_validate_hmac):
-    '''No error is returned when hmac validation is off'''
-    mock_do_validate_hmac.return_value = False
-    errors = []
-    pgwui_server_init.validate_hmac(errors, {})
-
-    assert errors == []
-
-
-def test_validate_hmac_success(mock_do_validate_hmac):
-    '''No error is returned when hmac is validated an the right length'''
-    mock_do_validate_hmac.return_value = True
-    errors = []
-    pgwui_server_init.validate_hmac(
-        errors, {'session.secret': 'x' * constants.HMAC_LEN})
-
-    assert errors == []
-
-
-def test_validate_hmac_missing(mock_do_validate_hmac):
-    '''Deliver error when hmac is validated and missing'''
-    mock_do_validate_hmac.return_value = True
-    errors = []
-    pgwui_server_init.validate_hmac(errors, {})
-
-    assert errors
-    assert isinstance(errors[0], server_ex.NoHMACError)
-
-
-def test_validate_hmac_length(mock_do_validate_hmac):
-    '''Deliver error when hmac is validated and the wrong length'''
-    mock_do_validate_hmac.return_value = True
-    errors = []
-    pgwui_server_init.validate_hmac(errors, {'session.secret': ''})
-
-    assert errors
-    assert isinstance(errors[0], server_ex.HMACLengthError)
-
-
-mock_validate_hmac = testing.make_mock_fixture(
-    pgwui_server_init, 'validate_hmac')
-
-
 # parse_assignments()
 
 def test_parse_assignments_str():
diff --git a/tests/test_checkset.py b/tests/test_checkset.py
new file mode 100644 (file)
index 0000000..fa3509d
--- /dev/null
@@ -0,0 +1,201 @@
+# Copyright (C) 2018, 2019, 2020 The Meme Factory, Inc.
+# http://www.karlpinc.com/
+
+# This file is part of PGWUI_Server.
+#
+# This program is free software: you can redistribute it and/or
+# modify it under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public
+# License along with this program.  If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
+# Karl O. Pinc <kop@karlpinc.com>
+
+
+import pgwui_common.exceptions as common_ex
+from pgwui_server import checkset
+import pgwui_server.constants as constants
+from pgwui_server import exceptions as server_ex
+from pgwui_testing import testing
+
+
+# key_to_ini()
+
+def test_key_to_ini():
+    '''The return value is as expected
+    '''
+    key = 'pgwui_example'
+    result = checkset.key_to_ini(key)
+
+    assert result == 'pgwui.' + key
+
+
+mock_key_to_ini = testing.make_mock_fixture(
+    checkset, 'key_to_ini')
+
+
+# require_setting()
+
+def test_require_setting_missing():
+    '''Deliver exception when a required setting is missing'''
+    errors = []
+    checkset.require_setting(errors, 'key', {})
+
+    assert errors
+    assert isinstance(errors[0], common_ex.MissingSettingError)
+
+
+def test_require_setting_present():
+    '''Does nothing when a required setting is present'''
+    errors = []
+    checkset.require_setting(errors, 'key', {'key': 'value'})
+
+    assert errors == []
+
+
+mock_require_setting = testing.make_mock_fixture(
+    checkset, 'require_setting')
+
+
+# boolean_setting()
+
+def test_boolean_setting_missing():
+    '''Does nothing when the setting is not in the settings'''
+    errors = []
+    checkset.boolean_setting(errors, 'key', {})
+
+    assert errors == []
+
+
+def test_boolean_setting_true():
+    '''Does nothing when the setting is "True"'''
+    errors = []
+    checkset.boolean_setting(errors, 'key', {'key': 'True'})
+
+    assert errors == []
+
+
+def test_boolean_setting_false():
+    '''Does nothing when the setting is "False"'''
+    errors = []
+    checkset.boolean_setting(errors, 'key', {'key': 'False'})
+
+    assert errors == []
+
+
+def test_boolean_setting_notboolean():
+    '''Deliver an exception when the setting does not evaluate to a boolean'''
+    errors = []
+    checkset.boolean_setting(errors, 'key', {'key': '0'})
+
+    assert errors
+    assert isinstance(errors[0], common_ex.NotBooleanSettingError)
+
+
+def test_boolean_setting_notparsable():
+    '''Deliver an exception when the setting does not evaluate to a
+    boolean because it is not parseable
+    '''
+    errors = []
+    checkset.boolean_setting(errors, 'key', {'key': 'a'})
+
+    assert errors
+    assert isinstance(errors[0], common_ex.NotBooleanSettingError)
+
+
+mock_boolean_setting = testing.make_mock_fixture(
+    checkset, 'boolean_setting')
+
+
+# validate_setting_values()
+
+def test_validate_setting_values(mock_require_setting, mock_boolean_setting):
+    '''Calls require_setting() and boolean_setting()'''
+
+    checkset.validate_setting_values([], {'pgwui': {}})
+
+    assert mock_require_setting.called
+    assert mock_boolean_setting.called
+
+
+mock_validate_setting_values = testing.make_mock_fixture(
+    checkset, 'validate_setting_values')
+
+
+# do_validate_hmac()
+
+def test_do_validate_hmac_none():
+    '''pgwui.validate_hmac defaults to True'''
+    assert checkset.do_validate_hmac({'pgwui': {}}) is True
+
+
+def test_do_validate_hmac_True():
+    '''Require hmac validation when pgwui.validate_hmac is True'''
+    result = checkset.do_validate_hmac(
+        {'pgwui': {'validate_hmac': 'True'}})
+    assert result is True
+
+
+def test_do_validate_hmac_False():
+    '''No hmac validation when pgwui.validate_hmac is False'''
+    result = checkset.do_validate_hmac(
+        {'pgwui': {'validate_hmac': 'False'}})
+    assert result is False
+
+
+mock_do_validate_hmac = testing.make_mock_fixture(
+    checkset, 'do_validate_hmac')
+
+
+# validate_hmac()
+
+def test_validate_hmac_unvalidated(mock_do_validate_hmac):
+    '''No error is returned when hmac validation is off'''
+    mock_do_validate_hmac.return_value = False
+    errors = []
+    checkset.validate_hmac(errors, {})
+
+    assert errors == []
+
+
+def test_validate_hmac_success(mock_do_validate_hmac):
+    '''No error is returned when hmac is validated an the right length'''
+    mock_do_validate_hmac.return_value = True
+    errors = []
+    checkset.validate_hmac(
+        errors, {'session.secret': 'x' * constants.HMAC_LEN})
+
+    assert errors == []
+
+
+def test_validate_hmac_missing(mock_do_validate_hmac):
+    '''Deliver error when hmac is validated and missing'''
+    mock_do_validate_hmac.return_value = True
+    errors = []
+    checkset.validate_hmac(errors, {})
+
+    assert errors
+    assert isinstance(errors[0], server_ex.NoHMACError)
+
+
+def test_validate_hmac_length(mock_do_validate_hmac):
+    '''Deliver error when hmac is validated and the wrong length'''
+    mock_do_validate_hmac.return_value = True
+    errors = []
+    checkset.validate_hmac(errors, {'session.secret': ''})
+
+    assert errors
+    assert isinstance(errors[0], server_ex.HMACLengthError)
+
+
+mock_validate_hmac = testing.make_mock_fixture(
+    checkset, 'validate_hmac')