Files @ 1e88ff36efbd
Branch filter:

Location: majic-ansible-roles/roles/ldap_server/molecule/default/tests/test_mandatory.py

branko
MAR-243: Drop inventory_hostname use from tests where possible:

- Primarily focused on Ansible playbooks and variable files.
- The variable is still used within some Python test fixtures. Test
behaviour should still be correct, with one advantage being that
lookups should be much faster than using the setup module (which
would require running Ansible code on each remote/test machine).
import os

import defusedxml.ElementTree as ElementTree

import testinfra.utils.ansible_runner


testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
    os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('parameters-mandatory')


def test_base_entry(host):
    """
    Tests if the base entry has been created correctly.
    """

    with host.sudo():

        base_dn = host.run("ldapsearch -H ldapi:/// -Q -LLL -Y EXTERNAL -b dc=local -s base")

        assert base_dn.rc == 0
        assert "dc: local" in base_dn.stdout.split("\n")
        assert "o: Private" in base_dn.stdout.split("\n")


def test_log_level(host):
    """
    Tests if the logging level has been set correctly.
    """

    with host.sudo():

        log_level = host.run('ldapsearch -H ldapi:/// -Q -LLL -Y EXTERNAL -b cn=config -s base olcLogLevel')

        assert log_level.rc == 0
        assert 'olcLogLevel: 256' in log_level.stdout


def test_certificate_validity_check_configuration(host):
    """
    Tests if certificate validity check configuration file has been deployed
    correctly.
    """

    inventory_hostname = host.ansible.get_variables()['inventory_hostname']

    config = host.file('/etc/check_certificate/%s_ldap.conf' % inventory_hostname)

    assert config.is_file
    assert config.user == 'root'
    assert config.group == 'root'
    assert config.mode == 0o644
    assert config.content_string == "/etc/ssl/certs/%s_ldap.pem" % inventory_hostname


def test_tls_connectivity(host):
    """
    Tests if it is possible to connect to the LDAP server using
    STARTTLS/TLS.
    """

    starttls = host.run('ldapwhoami -Z -x -H ldap://parameters-mandatory/')
    assert starttls.rc == 0
    assert starttls.stdout == 'anonymous\n'

    tls = host.run('ldapwhoami -x -H ldaps://parameters-mandatory/')
    assert tls.rc == 0
    assert tls.stdout == 'anonymous\n'


def test_tls_version_and_ciphers(host):
    """
    Tests if the correct TLS version and ciphers have been enabled.
    """

    expected_tls_versions = ["TLSv1.2", "TLSv1.3"]

    expected_tls_ciphers = [
        "TLS_AKE_WITH_AES_128_GCM_SHA256",
        "TLS_AKE_WITH_AES_256_GCM_SHA384",
        "TLS_AKE_WITH_CHACHA20_POLY1305_SHA256",
        "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
        "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
        "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
        "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
        "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
        "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
    ]

    # Run the nmap scanner against the LDAP server, and fetch the
    # results.
    nmap = host.run("nmap -sV --script ssl-enum-ciphers -p 636 localhost -oX /tmp/report.xml")
    assert nmap.rc == 0
    report_content = host.file('/tmp/report.xml').content_string

    report_root = ElementTree.fromstring(report_content)

    tls_versions = []
    tls_ciphers = set()

    for child in report_root.findall("./host/ports/port/script/table"):
        tls_versions.append(child.attrib['key'])

    for child in report_root.findall(".//table[@key='ciphers']/table/elem[@key='name']"):
        tls_ciphers.add(child.text)

    tls_versions.sort()
    tls_ciphers = sorted(list(tls_ciphers))

    assert tls_versions == expected_tls_versions
    assert tls_ciphers == expected_tls_ciphers


def test_ssf_configuration(host):
    """
    Tests if the SSF olcSecurity configuration has been set-up correctly.
    """

    with host.sudo():
        ssf = host.run('ldapsearch -H ldapi:/// -Q -LLL -Y EXTERNAL -b cn=config olcSecurity')

        assert ssf.rc == 0
        assert "olcSecurity: ssf=128" in ssf.stdout


def test_permissions(host):
    """
    Tests if LDAP directory permissions have been set-up correctly.
    """

    with host.sudo():
        permissions = host.run("ldapsearch -o ldif-wrap=no -H ldapi:/// -Q -LLL -Y EXTERNAL -b 'olcDatabase={1}mdb,cn=config' -s base olcAccess olcAccess")

        expected_permissions = \
            """olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by dn="cn=admin,dc=local" manage by * break
olcAccess: {1}to attrs=userPassword,shadowLastChange by self write by anonymous auth by * none
olcAccess: {2}to dn.base="" by * read
olcAccess: {3}to * by self write by dn="cn=admin,dc=local" write by users read by * none"""

        assert permissions.rc == 0
        assert expected_permissions in permissions.stdout


def test_services_login_entries(host):
    """
    Tests if the service/consumer login entries have been set correctly.
    """

    with host.sudo():

        entries = host.run("ldapsearch -H ldapi:/// -Q -LLL -Y EXTERNAL -s one -b ou=services,dc=local '(objectClass=simpleSecurityObject)'")

        assert entries.rc == 0
        assert entries.stdout == ""


def test_group_entries(host):
    """
    Tests that no group entries have been created out-of-the-box.
    """

    with host.sudo():

        entries = host.run("ldapsearch -H ldapi:/// -Q -LLL -Y EXTERNAL -s one -b ou=groups,dc=local '(objectClass=groupOfUniqueNames)'")

        assert entries.rc == 0
        assert entries.stdout == ""