Skip to content

Commit

Permalink
Add Password Hardening CLI test
Browse files Browse the repository at this point in the history
  • Loading branch information
davidpil committed Apr 13, 2022
1 parent 03b3a57 commit 8773eae
Show file tree
Hide file tree
Showing 3 changed files with 243 additions and 0 deletions.
40 changes: 40 additions & 0 deletions tests/passw_hardening_input/assert_show_output.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""
Module holding the correct values for show CLI command outputs for the passw_hardening_test.py
"""

show_passw_hardening_policies_default="""\
STATE EXPIRATION EXPIRATION WARNING HISTORY CNT LEN MIN REJECT USER PASSW MATCH LOWER CLASS UPPER CLASS DIGITS CLASS SPECIAL CLASS
-------- ------------ -------------------- ------------- --------- ------------------------- ------------- ------------- -------------- ---------------
disabled 180 15 10 8 true true true true true
"""

show_passw_hardening_policies_classes_disabled="""\
STATE EXPIRATION EXPIRATION WARNING HISTORY CNT LEN MIN REJECT USER PASSW MATCH LOWER CLASS UPPER CLASS DIGITS CLASS SPECIAL CLASS
-------- ------------ -------------------- ------------- --------- ------------------------- ------------- ------------- -------------- ---------------
disabled 180 15 10 8 false false false false false
"""

show_passw_hardening_policies_enabled="""\
STATE EXPIRATION EXPIRATION WARNING HISTORY CNT LEN MIN REJECT USER PASSW MATCH LOWER CLASS UPPER CLASS DIGITS CLASS SPECIAL CLASS
------- ------------ -------------------- ------------- --------- ------------------------- ------------- ------------- -------------- ---------------
enabled 180 15 10 8 true true true true true
"""


show_passw_hardening_policies_expiration="""\
STATE EXPIRATION EXPIRATION WARNING HISTORY CNT LEN MIN REJECT USER PASSW MATCH LOWER CLASS UPPER CLASS DIGITS CLASS SPECIAL CLASS
------- ------------ -------------------- ------------- --------- ------------------------- ------------- ------------- -------------- ---------------
enabled 100 15 10 8 true true true true true
"""

show_passw_hardening_policies_history_cnt="""\
STATE EXPIRATION EXPIRATION WARNING HISTORY CNT LEN MIN REJECT USER PASSW MATCH LOWER CLASS UPPER CLASS DIGITS CLASS SPECIAL CLASS
-------- ------------ -------------------- ------------- --------- ------------------------- ------------- ------------- -------------- ---------------
disabled 180 15 40 8 true true true true true
"""

show_passw_hardening_policies_len_min="""\
STATE EXPIRATION EXPIRATION WARNING HISTORY CNT LEN MIN REJECT USER PASSW MATCH LOWER CLASS UPPER CLASS DIGITS CLASS SPECIAL CLASS
-------- ------------ -------------------- ------------- --------- ------------------------- ------------- ------------- -------------- ---------------
disabled 180 15 10 30 true true true true true
"""
16 changes: 16 additions & 0 deletions tests/passw_hardening_input/default_config_db.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"PASSW_HARDENING": {
"POLICIES": {
"state": "enabled",
"expiration": "180",
"expiration_warning": "15",
"history_cnt": "10",
"len_min": "8",
"reject_user_passw_match": "true",
"digits_class": "true",
"lower_class": "true",
"special_class": "true",
"upper_class": "true"
}
}
}
187 changes: 187 additions & 0 deletions tests/passw_hardening_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
#!/usr/bin/env python

import os
import logging
import show.main as show
import config.main as config

from .passw_hardening_input import assert_show_output
from utilities_common.db import Db
from click.testing import CliRunner
from .mock_tables import dbconnector

logger = logging.getLogger(__name__)
test_path = os.path.dirname(os.path.abspath(__file__))
mock_db_path = os.path.join(test_path, "passw_hardening_input")

SUCCESS = 0
ERROR = 1
INVALID_VALUE = 'INVALID'
EXP_GOOD_FLOW = 1
EXP_BAD_FLOW = 0

class TestPasswHardening:
@classmethod
def setup_class(cls):
logger.info("SETUP")
os.environ['UTILITIES_UNIT_TESTING'] = "2"


@classmethod
def teardown_class(cls):
logger.info("TEARDOWN")
os.environ['UTILITIES_UNIT_TESTING'] = "0"
os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] = ""
dbconnector.dedicated_dbs['CONFIG_DB'] = None

def verify_passw_policies_output(self, db, runner, output, expected=EXP_GOOD_FLOW):
result = runner.invoke(show.cli.commands["passw-hardening"].commands["policies"], [], obj=db)
logger.debug("\n" + result.output)
logger.debug(result.exit_code)

if expected: # good flow expected (default)
assert result.exit_code == SUCCESS
assert result.output == output
else: # bad flow expected
assert result.exit_code == ERROR

def passw_hardening_set_policy(self, runner, db, attr, value, expected=EXP_GOOD_FLOW):
result = runner.invoke(
config.config.commands["passw-hardening"].commands["policies"].commands[attr],
[value], obj=db
)

if expected: # good flow expected (default)
logger.debug("\n" + result.output)
logger.debug(result.exit_code)
assert result.exit_code == SUCCESS
else: # bad flow expected
assert result.exit_code == ERROR

def set_passw_default_values(self, runner, db):

passw_policies = {
"state": "disabled",
"expiration": "180",
"expiration-warning": "15",
"history-cnt": "10",
"len-min": "8",
"reject-user-passw-match": "true",
"digits-class": "true",
"lower-class": "true",
"special-class": "true",
"upper-class": "true"
}

for k, v in passw_policies.items():
self.passw_hardening_set_policy(runner, db, k, v)

######### PASSW-HARDENING #########

def test_passw_hardening_default(self, set_passw_hardening_default):
dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'default_config_db')
db = Db()
runner = CliRunner()

self.verify_passw_policies_output(db, runner, assert_show_output.show_passw_hardening_policies_default)

def test_passw_hardening_feature_enabled(self):
dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'default_config_db')
db = Db()
runner = CliRunner()

self.set_passw_default_values(runner, db)

self.passw_hardening_set_policy(runner, db, "state", "enabled")

self.verify_passw_policies_output(db, runner, assert_show_output.show_passw_hardening_policies_enabled)

def test_passw_hardening_policies_classes_disabled(self):
"""Disable passw hardening classes & reject user passw match policies"""

dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'default_config_db')
db = Db()
runner = CliRunner()

self.set_passw_default_values(runner, db)
passw_classes = { "reject-user-passw-match": "false",
"digits-class": "false",
"lower-class": "false",
"special-class": "false",
"upper-class": "false"
}

for k, v in passw_classes.items():
self.passw_hardening_set_policy(runner, db, k, v)

self.verify_passw_policies_output(db, runner, assert_show_output.show_passw_hardening_policies_classes_disabled)

def test_passw_hardening_policies_exp_time(self):
dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'default_config_db')
db = Db()
runner = CliRunner()

self.set_passw_default_values(runner, db)

self.passw_hardening_set_policy(runner, db, "state", "enabled")
self.passw_hardening_set_policy(runner, db, "expiration", "100")
self.passw_hardening_set_policy(runner, db, "expiration-warning", "15")

self.verify_passw_policies_output(db, runner, assert_show_output.show_passw_hardening_policies_expiration)

def test_passw_hardening_policies_history(self):
dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'default_config_db')
db = Db()
runner = CliRunner()

self.set_passw_default_values(runner, db)
self.passw_hardening_set_policy(runner, db, "history-cnt", "40")

self.verify_passw_policies_output(db, runner, assert_show_output.show_passw_hardening_policies_history_cnt)

def test_passw_hardening_policies_len_min(self):
dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'default_config_db')
db = Db()
runner = CliRunner()

self.set_passw_default_values(runner, db)
self.passw_hardening_set_policy(runner, db, "len-min", "30")

self.verify_passw_policies_output(db, runner, assert_show_output.show_passw_hardening_policies_len_min)

def test_passw_hardening_policy_expiration_invalid(self):
dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'default_config_db')
db = Db()
runner = CliRunner()
INVALID_EXP_TIME = "600"

self.set_passw_default_values(runner, db)
self.passw_hardening_set_policy(runner, db, "expiration", INVALID_EXP_TIME, EXP_BAD_FLOW)

# expect default values, because invalid values should not succed to modify default configuration
self.verify_passw_policies_output(db, runner, assert_show_output.show_passw_hardening_policies_default)

def test_passw_hardening_policy_len_min_invalid(self):
dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'default_config_db')
db = Db()
runner = CliRunner()
INVALID_EXP_LEN = "500"

self.set_passw_default_values(runner, db)
self.passw_hardening_set_policy(runner, db, "len-min", INVALID_EXP_LEN, EXP_BAD_FLOW)

# expect default values, because invalid values should not succed to modify default configuration
self.verify_passw_policies_output(db, runner, assert_show_output.show_passw_hardening_policies_default)

def test_passw_hardening_policy_class_invalid(self):
dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'default_config_db')
db = Db()
runner = CliRunner()
INVALID_VALUE = '?'

self.set_passw_default_values(runner, db)
self.passw_hardening_set_policy(runner, db, "expiration", INVALID_VALUE, EXP_BAD_FLOW)

# expect default values, because invalid values should not succed to modify default configuration
self.verify_passw_policies_output(db, runner, assert_show_output.show_passw_hardening_policies_default)

0 comments on commit 8773eae

Please sign in to comment.