Beispiel #1
0
def test_load_file(mocker):
    environ = dict()
    mod = 'ldap2pg.config.'
    mocker.patch(mod + 'os.environ', environ)
    ff = mocker.patch(mod + 'Configuration.find_filename')
    mocker.patch(mod + 'open', create=True)
    read = mocker.patch(mod + 'Configuration.read')
    warn = mocker.patch(mod + 'logger.warning')

    from ldap2pg.config import Configuration

    config = Configuration()

    ff.return_value = ['filename.yml', 0o0]
    read.return_value = dict(
        sync_map=[dict(role='alice')],
        # To trigger a warning.
        unknown_key=True,
        # Should not trigger a warning.
        privileges=dict(ro=['__connect__']),
    )
    # send one env var
    environ.update(dict(PGDSN=b'envdsn'))

    config.load(argv=['--verbose'])

    assert 'envdsn' == config['postgres']['dsn']
    maplist = config['sync_map']
    assert 1 == len(maplist)
    assert 'DEBUG' == config['verbosity']
    # logger.warning is called once for unknown_key, not for privileges.
    assert 1 == warn.call_count
Beispiel #2
0
def test_find_filename_default(mocker):
    stat = mocker.patch('ldap2pg.config.stat')

    from ldap2pg.config import Configuration, NoConfigurationError

    config = Configuration()

    def mk_oserror(errno=None):
        e = OSError()
        e.errno = errno
        return e

    # Search default path
    stat.side_effect = [
        mk_oserror(),
        mk_oserror(13),
        mocker.Mock(st_mode=0o600),
    ]
    filename, mode = config.find_filename(environ=dict())
    assert config._file_candidates[2] == filename
    assert 0o600 == mode

    # No files at all
    stat.side_effect = OSError()
    with pytest.raises(NoConfigurationError):
        config.find_filename(environ=dict())
Beispiel #3
0
def test_security():
    from ldap2pg.config import Configuration

    config = Configuration()

    minimal_config = dict(sync_map=[])
    with pytest.raises(ValueError):
        config.merge(environ=dict(),
                     file_config=dict(
                         minimal_config,
                         ldap=dict(password='******'),
                     ))

    with pytest.raises(ValueError):
        # Refuse world readable postgres URI with password
        config.merge(environ=dict(),
                     file_config=dict(
                         minimal_config,
                         postgres=dict(dsn='password=unsecure'),
                     ))

    with pytest.raises(ValueError):
        # Refuse world readable postgres URI with password
        config.merge(environ=dict(),
                     file_config=dict(
                         minimal_config,
                         postgres=dict(dsn='postgres://*****:*****@h'),
                     ))

    config.merge(environ=dict(),
                 file_config=dict(
                     minimal_config,
                     postgres=dict(dsn='postgres://u@h'),
                 ))
Beispiel #4
0
def test_find_filename_custom(mocker):
    stat = mocker.patch('ldap2pg.config.stat')

    from ldap2pg.config import Configuration, UserError

    config = Configuration()

    # Read from env var LDAP2PG_CONFIG
    stat.reset_mock()
    stat.side_effect = [
        OSError(),
        AssertionError("Not reached."),
    ]
    with pytest.raises(UserError):
        config.find_filename(environ=dict(LDAP2PG_CONFIG=b'my.yml'))

    # Read from args
    stat.reset_mock()
    stat.side_effect = [
        mocker.Mock(st_mode=0o600),
        AssertionError("Not reached."),
    ]
    filename, mode = config.find_filename(
        environ=dict(LDAP2PG_CONFIG=b'env.yml'),
        args=MockArgs(config='argv.yml'),
    )

    assert filename.endswith('argv.yml')
Beispiel #5
0
def test_find_filename_stdin():
    from ldap2pg.config import Configuration

    config = Configuration()

    filename, mode = config.find_filename(environ=dict(LDAP2PG_CONFIG=b'-'), )

    assert '-' == filename
    assert 0o400 == mode
Beispiel #6
0
def test_has_ldap():
    from ldap2pg.config import Configuration

    config = Configuration()

    config['sync_map'] = [dict(roles=dict())]
    assert not config.has_ldap_query()

    config['sync_map'] = [dict(ldap=dict())]
    assert config.has_ldap_query()
Beispiel #7
0
def test_read_yml():
    from io import StringIO

    from ldap2pg.config import Configuration, ConfigurationError

    config = Configuration()

    fo = StringIO("- role: alice")
    payload = config.read(fo, 'memory', mode=0o0)
    assert 'sync_map' in payload

    fo = StringIO("sync_map: []")
    payload = config.read(fo, 'memory', mode=0o644)
    assert 'sync_map' in payload
    assert payload['world_readable'] is True

    # Refuse empty file (e.g. /dev/null)
    with pytest.raises(ConfigurationError):
        fo = StringIO("")
        config.read(fo, 'memory', mode=0o600)

    with pytest.raises(ConfigurationError):
        fo = StringIO("bad_value")
        payload = config.read(fo, 'memory', mode=0o600)

    with pytest.raises(ConfigurationError):
        fo = StringIO("bad: { yaml ] *&")
        payload = config.read(fo, 'memory', mode=0o600)

    # No sync_map.
    with pytest.raises(ConfigurationError):
        fo = StringIO("postgres: {}")
        payload = config.read(fo, 'memory', mode=0o600)
Beispiel #8
0
def test_logging_config():
    from ldap2pg.config import Configuration, UserError

    config = Configuration()

    config['verbosity'] = 'DEBUG'
    dict_ = config.logging_dict()
    assert 'DEBUG' == dict_['loggers']['ldap2pg']['level']

    with pytest.raises(UserError):
        config.bootstrap(environ=dict(VERBOSITY='TOTO'))
Beispiel #9
0
def test_logging_config():
    from ldap2pg.config import Configuration

    config = Configuration()

    config['verbose'] = True
    l = config.logging_dict()
    assert 'DEBUG' == l['loggers']['ldap2pg']['level']

    config['verbose'] = False
    l = config.logging_dict()
    assert 'INFO' == l['loggers']['ldap2pg']['level']
Beispiel #10
0
def test_load_badfiles(mocker):
    environ = dict()
    mocker.patch('ldap2pg.config.os.environ', environ)
    ff = mocker.patch('ldap2pg.config.Configuration.find_filename')
    merge = mocker.patch('ldap2pg.config.Configuration.merge')

    from ldap2pg.config import (
        Configuration,
        ConfigurationError,
        NoConfigurationError,
        UserError,
    )

    config = Configuration()

    # No file specified
    ff.side_effect = NoConfigurationError()
    config.load(argv=['--color'])

    ff.side_effect = None
    # Invalid file
    ff.return_value = ['filename.yml', 0o0]
    merge.side_effect = ValueError()
    o = mocker.patch('ldap2pg.config.open', mocker.mock_open(), create=True)
    with pytest.raises(ConfigurationError):
        config.load(argv=[])

    # Not readable.
    o.side_effect = OSError("failed to open")
    with pytest.raises(UserError):
        config.load(argv=[])
Beispiel #11
0
def test_read_yml():
    from io import StringIO

    from ldap2pg.config import Configuration, ConfigurationError

    config = Configuration()

    fo = StringIO("- role: alice")
    payload = config.read(fo, 'memory', mode=0o0)
    assert 'sync_map' in payload

    fo = StringIO("entry: value")
    payload = config.read(fo, 'memory', mode=0o644)
    assert 'entry' in payload
    assert payload['world_readable'] is True

    # Accept empty file (e.g. /dev/null)
    fo = StringIO("")
    payload = config.read(fo, 'memory', mode=0o600)
    assert payload['world_readable'] is False

    with pytest.raises(ConfigurationError):
        fo = StringIO("bad_value")
        payload = config.read(fo, 'memory', mode=0o600)

    with pytest.raises(ConfigurationError):
        fo = StringIO("bad: { yaml ] *&")
        payload = config.read(fo, 'memory', mode=0o600)
Beispiel #12
0
def test_load_stdin(mocker):
    environ = dict()
    mocker.patch('ldap2pg.config.os.environ', environ)
    ff = mocker.patch('ldap2pg.config.Configuration.find_filename')
    mocker.patch('ldap2pg.config.open', create=True)
    read = mocker.patch('ldap2pg.config.Configuration.read')

    from ldap2pg.config import Configuration

    config = Configuration()

    ff.return_value = ['-', 0o400]
    read.return_value = dict(sync_map=[dict(role='alice')])

    config.load(argv=[])

    maplist = config['sync_map']
    assert 1 == len(maplist)
Beispiel #13
0
def test_load_file(mocker):
    environ = dict()
    mocker.patch('ldap2pg.config.os.environ', environ)
    ff = mocker.patch('ldap2pg.config.Configuration.find_filename')
    mocker.patch('ldap2pg.config.open', create=True)
    read = mocker.patch('ldap2pg.config.Configuration.read')

    from ldap2pg.config import Configuration

    config = Configuration()

    ff.return_value = ['filename.yml', 0o0]
    read.return_value = dict(sync_map=[dict(role='alice')])
    # send one env var for LDAP bind
    environ.update(dict(LDAPPASSWORD=b'envpass'))

    config.load(argv=['--verbose'])

    assert 'envpass' == config['ldap']['password']
    maplist = config['sync_map']
    assert 1 == len(maplist)
    assert 'DEBUG' == config['verbosity']
Beispiel #14
0
def test_merge():
    from ldap2pg.config import Configuration

    # Noop
    config = Configuration()
    config.merge(file_config={}, environ={})

    minimal_config = dict(verbose=True, sync_map=[])
    config.merge(
        file_config=minimal_config,
        environ=dict(),
    )
    config.merge(
        file_config=minimal_config,
        environ=dict(LDAPPASSWORD=b'envpass', PGDSN=b'envdsn'),
    )
    assert 'envpass' == config['ldap']['password']
    assert 'envdsn' == config['postgres']['dsn']
Beispiel #15
0
def test_load(mocker):
    environ = dict()
    mocker.patch('ldap2pg.config.os.environ', environ)
    ff = mocker.patch('ldap2pg.config.Configuration.find_filename')
    read = mocker.patch('ldap2pg.config.Configuration.read')
    o = mocker.patch('ldap2pg.config.open', create=True)

    from ldap2pg.config import (
        Configuration,
        ConfigurationError,
        NoConfigurationError,
        UserError,
    )

    config = Configuration()

    ff.side_effect = NoConfigurationError()
    # Missing sync_map
    with pytest.raises(ConfigurationError):
        config.load(argv=[])

    ff.side_effect = None
    # Find `filename.yml`
    ff.return_value = ['filename.yml', 0o0]

    # Not readable.
    o.side_effect = OSError("failed to open")
    with pytest.raises(UserError):
        config.load(argv=[])

    # Readable..
    o.side_effect = None
    # ...containing mapping
    read.return_value = dict(sync_map=dict(ldap=dict(), role=dict()))
    # send one env var for LDAP bind
    environ.update(dict(LDAP_BIND='envbind'))

    config.load(argv=['--verbose'])

    assert 'envbind' == config['ldap']['bind']
    assert 1 == len(config['sync_map'])
    assert 'ldap' in config['sync_map'][0]
    assert config['verbose'] is True
Beispiel #16
0
def test_merge_and_mappings():
    from ldap2pg.config import Configuration

    # Noop
    config = Configuration()
    with pytest.raises(ValueError):
        config.merge(file_config={}, environ={})

    # Minimal configuration
    minimal_config = dict(
        ldap=dict(host='confighost'),
        sync_map=dict(ldap=dict(), role=dict()),
    )
    config.merge(
        file_config=minimal_config,
        environ=dict(),
    )
    config.merge(
        file_config=minimal_config,
        environ=dict(LDAP_PASSWORD='******', PGDSN='envdsn'),
    )
    assert 'confighost' == config['ldap']['host']
    assert 'envpass' == config['ldap']['password']
    assert 'envdsn' == config['postgres']['dsn']
Beispiel #17
0
def test_read_yml():
    from io import StringIO

    from ldap2pg.config import Configuration, ConfigurationError

    config = Configuration()

    # Deny list file
    fo = StringIO("- listentry")
    with pytest.raises(ConfigurationError):
        config.read(fo, mode=0o0)

    fo = StringIO("entry: value")
    payload = config.read(fo, mode=0o644)
    assert 'entry' in payload
    assert payload['world_readable'] is True

    # Accept empty file (e.g. /dev/null)
    fo = StringIO("")
    payload = config.read(fo, mode=0o600)
    assert payload['world_readable'] is False
Beispiel #18
0
def test_show_versions(mocker):
    from ldap2pg.config import Configuration

    config = Configuration()
    with pytest.raises(SystemExit):
        config.load(argv=['--version'])