def test_inspect_roles(mocker): p = mocker.patch('ldap2pg.manager.SyncManager.process_pg_roles') ql = mocker.patch('ldap2pg.manager.SyncManager.query_ldap') r = mocker.patch('ldap2pg.manager.SyncManager.process_ldap_entry') psql = mocker.MagicMock() from ldap2pg.manager import SyncManager, Role p.return_value = {Role(name='spurious')} ql.return_value = [mocker.Mock(name='entry')] r.side_effect = [{Role(name='alice')}, {Role(name='bob')}] manager = SyncManager(psql=psql, ldapconn=mocker.Mock()) # Minimal effective syncmap syncmap = dict(db=dict(s=[ dict(roles=[]), dict( ldap=dict(base='ou=users,dc=tld', filter='*', attributes=['cn']), roles=[dict(), dict()], ), ])) manager.inspect(syncmap=syncmap) assert 2 is r.call_count, "sync did not iterate over each rules."
def test_diff(): from ldap2pg.role import Role, RoleSet pgmanagedroles = RoleSet([ Role('drop-me'), Role('alter-me'), Role('nothing'), Role('public'), ]) pgallroles = pgmanagedroles.union({ Role('reuse-me'), Role('dont-touch-me'), }) ldaproles = RoleSet([ Role('reuse-me'), Role('alter-me', options=dict(LOGIN=True)), Role('nothing'), Role('create-me') ]) queries = [q.args[0] for q in pgmanagedroles.diff(ldaproles, pgallroles)] assert fnfilter(queries, 'ALTER ROLE "alter-me" WITH* LOGIN*;') assert fnfilter(queries, 'CREATE ROLE "create-me" *;') assert fnfilter(queries, '*DROP ROLE "drop-me";*') assert not fnfilter(queries, 'CREATE ROLE "reuse-me" *') assert not fnfilter(queries, '*nothing*') assert not fnfilter(queries, '*dont-touch-me*') assert not fnfilter(queries, '*public*')
def test_inspect_ldap_roles(mocker): ql = mocker.patch('ldap2pg.manager.SyncManager.query_ldap') r = mocker.patch('ldap2pg.manager.SyncManager.process_ldap_entry') from ldap2pg.manager import SyncManager, Role ql.return_value = [mocker.Mock(name='entry')] r.side_effect = [ {Role(name='alice', options=dict(SUPERUSER=True))}, {Role(name='bob')}, ] manager = SyncManager( ldapconn=mocker.Mock(), ) # Minimal effective syncmap syncmap = [ dict(roles=[]), dict( ldap=dict(base='ou=users,dc=tld', filter='*', attributes=['cn']), roles=[dict(), dict()], ), ] ldaproles, _ = manager.inspect_ldap(syncmap=syncmap) assert 2 == r.call_count, "sync did not iterate over each rules." assert 'alice' in ldaproles assert 'bob' in ldaproles
def test_sync_map_loop(mocker): p = mocker.patch('ldap2pg.manager.RoleManager.process_pg_roles') l = mocker.patch('ldap2pg.manager.RoleManager.query_ldap') r = mocker.patch('ldap2pg.manager.RoleManager.process_ldap_entry') psql = mocker.patch('ldap2pg.manager.RoleManager.psql') RoleSet = mocker.patch('ldap2pg.manager.RoleSet') from ldap2pg.manager import RoleManager, Role p.return_value = {Role(name='spurious')} l.return_value = [mocker.Mock(name='entry')] r.side_effect = [{Role(name='alice')}, {Role(name='bob')}] manager = RoleManager(pgconn=mocker.Mock(), ldapconn=mocker.Mock()) # Minimal effective syncmap syncmap = [ dict( ldap=dict(base='ou=users,dc=global', filter='*', attributes=['cn']), roles=[dict(), dict()], ) ] # No queries to run, we're just testing mapping loop RoleSet.return_value.diff.return_value = [] manager.dry = False roles = manager.sync(map_=syncmap) assert 2 is r.call_count, "sync did not iterate over each rules." assert roles assert psql.called is False
def test_drop(): from ldap2pg.manager import Role role = Role(name='toto', members=['titi']) queries = [q.args[0] for q in role.drop()] assert fnfilter(queries, '*REASSIGN OWNED*DROP OWNED BY "toto";*') assert fnfilter(queries, 'DROP ROLE "toto";')
def test_create(): from ldap2pg.manager import Role role = Role(name='toto', members=['titi']) queries = [q.args[0] for q in role.create()] assert fnfilter(queries, "CREATE ROLE toto *;") assert fnfilter(queries, "INSERT INTO pg_catalog.pg_auth_members*")
def test_create(): from ldap2pg.manager import Role role = Role(name='toto', members=['titi']) queries = [q.args[0] for q in role.create()] assert fnfilter(queries, 'CREATE ROLE "toto" *;') assert fnfilter(queries, 'GRANT "toto" TO "titi";')
def test_drop(): from ldap2pg.manager import Role role = Role(name='toto', members=['titi']) queries = [q.args[0] for q in role.drop()] assert fnfilter(queries, "DROP ROLE toto;") assert fnfilter(queries, "*DELETE FROM pg_catalog.pg_auth_members*")
def test_create(): from ldap2pg.manager import Role role = Role(name='toto', members=['titi']) queries = [q.args[0] for q in role.create()] assert fnfilter(queries, "CREATE ROLE toto *;") assert fnfilter(queries, "GRANT toto TO titi;")
def test_role(): from ldap2pg.manager import Role role = Role(name='toto') assert 'toto' == role.name assert 'toto' == str(role) assert 'toto' in repr(role) roles = sorted([Role('b'), Role('a')]) assert ['a', 'b'] == roles
def test_resolve_membership(): from ldap2pg.role import RoleSet, Role alice = Role('alice') bob = Role('bob', members=['oscar']) oscar = Role('oscar', parents=['alice', 'bob']) roles = RoleSet([alice, bob, oscar]) roles.resolve_membership() assert not oscar.parents assert 'oscar' in alice.members
def test_alter(): from ldap2pg.manager import Role a = Role(name='toto', members=['titi'], options=dict(LOGIN=True)) b = Role(name='toto', members=['tata'], options=dict(LOGIN=False)) queries = [q.args[0] for q in a.alter(a)] assert not queries queries = [q.args[0] for q in a.alter(b)] assert fnfilter(queries, "ALTER ROLE toto *;") assert fnfilter(queries, "INSERT INTO pg_catalog.pg_auth_members*") assert fnfilter(queries, "*DELETE FROM pg_catalog.pg_auth_members*")
def test_alter(): from ldap2pg.manager import Role a = Role(name='toto', members=['titi'], options=dict(LOGIN=True)) b = Role(name='toto', members=['tata'], options=dict(LOGIN=False)) queries = [q.args[0] for q in a.alter(a)] assert not queries queries = [q.args[0] for q in a.alter(b)] assert fnfilter(queries, "ALTER ROLE toto *;") assert fnfilter(queries, "GRANT toto TO tata;") assert fnfilter(queries, "REVOKE toto FROM titi;")
def test_alter(): from ldap2pg.manager import Role a = Role(name='toto', members=['titi'], options=dict(LOGIN=True)) b = Role(name='toto', members=['tata'], options=dict(LOGIN=False)) queries = [q.args[0] for q in a.alter(a)] assert not queries queries = [q.args[0] for q in a.alter(b)] assert fnfilter(queries, 'ALTER ROLE "toto" *;') assert fnfilter(queries, 'GRANT "toto" TO "tata";') assert fnfilter(queries, 'REVOKE "toto" FROM "titi";')
def test_resolve_membership(): from ldap2pg.role import RoleSet, Role alice = Role('alice') bob = Role('bob', members=['oscar']) oscar = Role('oscar', parents=['alice', 'bob']) roles = RoleSet([alice, bob, oscar]) roles.resolve_membership() assert not oscar.parents assert 'oscar' in alice.members alice.parents = ['unknown'] with pytest.raises(ValueError): roles.resolve_membership()
def test_merge(): from ldap2pg.role import Role a = Role(name='daniel', parents=['group0']) b = Role(name='daniel', parents=['group1']) c = Role(name='daniel', members=['group2']) a.merge(b) assert 2 == len(a.parents) a.merge(c) assert 1 == len(a.members)
def test_roles_diff_queries(): from ldap2pg.manager import Role, RoleSet a = RoleSet([ Role('drop-me'), Role('alter-me'), Role('nothing'), ]) b = RoleSet([ Role('alter-me', options=dict(LOGIN=True)), Role('nothing'), Role('create-me') ]) queries = [q.args[0] for q in a.diff(b)] assert fnfilter(queries, "ALTER ROLE alter-me WITH* LOGIN*;") assert fnfilter(queries, "CREATE ROLE create-me *;") assert 'DROP ROLE drop-me;' in queries assert not fnfilter(queries, '*nothing*')
def test_diff_roles(mocker): from ldap2pg.manager import SyncManager, Role, RoleSet m = SyncManager() pgroles = RoleSet([ Role('drop-me'), Role('alter-me'), Role('nothing'), ]) ldaproles = RoleSet([ Role('alter-me', options=dict(LOGIN=True)), Role('nothing'), Role('create-me') ]) queries = [q.args[0] for q in m.diff(pgroles, set(), ldaproles, set())] assert fnfilter(queries, "ALTER ROLE alter-me WITH* LOGIN*;") assert fnfilter(queries, "CREATE ROLE create-me *;") assert fnfilter(queries, '*DROP ROLE drop-me;*') assert not fnfilter(queries, '*nothing*')
def test_flatten(): from ldap2pg.role import RoleSet, Role roles = RoleSet() roles.add(Role('parent0', members=['child0', 'child1'])) roles.add(Role('parent1', members=['child2', 'child3'])) roles.add(Role('parent2', members=['child4'])) roles.add(Role('child0', members=['subchild0'])) roles.add(Role('child1', members=['subchild1', 'subchild2'])) roles.add(Role('child2')) roles.add(Role('child3')) roles.add(Role('child4')) roles.add(Role('subchild0')) roles.add(Role('subchild1')) roles.add(Role('subchild2')) order = list(roles.flatten()) wanted = [ 'subchild0', 'child0', 'subchild1', 'subchild2', 'child1', 'child2', 'child3', 'child4', 'parent0', 'parent1', 'parent2', ] assert wanted == order
def test_merge_options(): from ldap2pg.role import Role a = Role(name='daniel', options=dict(SUPERUSER=True)) b = Role(name='daniel', options=dict(SUPERUSER=False)) c = Role(name='daniel', options=dict(SUPERUSER=None)) d = Role(name='daniel', options=dict(SUPERUSER=None)) with pytest.raises(ValueError): a.merge(b) # True is kept a.merge(c) assert a.options['SUPERUSER'] is True # False is kept b.merge(c) assert b.options['SUPERUSER'] is False # None is kept c.merge(d) assert c.options['SUPERUSER'] is None # None is replaced. d.merge(a) assert d.options['SUPERUSER'] is True