2022-11-09 13:45:47 +00:00
|
|
|
"""Unit tests for the lumi2.ldap module."""
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
import lumi2.ldap as ll
|
2022-11-15 23:22:39 +00:00
|
|
|
import lumi2.usermodel as lu
|
2022-11-09 13:45:47 +00:00
|
|
|
import lumi2.exceptions as le
|
|
|
|
|
|
|
|
|
|
|
|
def test_assert_is_valid_base_dn():
|
|
|
|
for invalid_type in [None, 0, True, ("x",), ["x"]]:
|
|
|
|
with pytest.raises(TypeError):
|
|
|
|
ll._assert_is_valid_base_dn(invalid_type)
|
|
|
|
|
|
|
|
for invalid_string in [
|
|
|
|
"", " ", "ou=foo", "abc", "\u1337",
|
|
|
|
"a,b", "dc=,dc=", "dc=a,dc=b", "ou=example,dc=com", "dc=example,dc="
|
|
|
|
"dc=,dc=com", "dc=EXAMPLE,dc=com", "dc=example,dc=COM",
|
|
|
|
"dc=example$,dc=com", "dc=foo,dc=com$", "dc=exa%,dc=com%",
|
|
|
|
"dc=ex-ample,dc=com", "dc=f_oo,dc=com",
|
|
|
|
]:
|
|
|
|
with pytest.raises(ll.InvalidStringFormatException):
|
|
|
|
ll._assert_is_valid_base_dn(invalid_string)
|
|
|
|
|
|
|
|
for valid_string in ["dc=example,dc=com", "dc=a,dc=de"]:
|
|
|
|
assert ll._assert_is_valid_base_dn(valid_string) == None
|
|
|
|
|
|
|
|
|
|
|
|
def test_assert_is_valid_ou_dn():
|
|
|
|
for invalid_type in [None, 0, True, ("x",), ["x"]]:
|
|
|
|
with pytest.raises(TypeError):
|
|
|
|
ll._assert_is_valid_ou_dn(invalid_type)
|
|
|
|
|
|
|
|
for invalid_string in [
|
|
|
|
"", " ", "ou=foo", "abc", "\u1337",
|
|
|
|
"ou=,dc=example,dc=com", "ou=foo,dc=example,dc=", "ou=foo,dc=example,",
|
|
|
|
"ou=foo,dc=example", "ou=foo,ou=bar,dc=example",
|
|
|
|
"ou=foo,ou=bar,dc=example,dc=com", "cn=foo,dc=example,dc=com",
|
|
|
|
"ou=abc%,dc=example,dc=com",
|
|
|
|
]:
|
|
|
|
with pytest.raises(ll.InvalidStringFormatException):
|
|
|
|
print(invalid_string)
|
|
|
|
ll._assert_is_valid_ou_dn(invalid_string)
|
|
|
|
|
|
|
|
for valid_string in [
|
|
|
|
"ou=users,dc=example,dc=com", "ou=users,dc=a,dc=de",
|
|
|
|
"ou=Users,dc=example,dc=com", "ou=abcdABCD,dc=example,dc=com",
|
|
|
|
]:
|
|
|
|
assert ll._assert_is_valid_ou_dn(valid_string) == None
|
|
|
|
|
|
|
|
|
2022-11-09 18:30:10 +00:00
|
|
|
def test_assert_is_valid_user_dn():
|
|
|
|
for invalid_type in [None, 0, True, ("x",), ["x"]]:
|
|
|
|
with pytest.raises(TypeError):
|
|
|
|
ll._assert_is_valid_user_dn(invalid_type)
|
|
|
|
|
|
|
|
for invalid_string in [
|
|
|
|
"", " ", "uid=foo", "abc", "\u1337",
|
|
|
|
"uid=,ou=foo,dc=bar,dc=baz", "uid=foo,ou=,dc=bar,dc=baz",
|
|
|
|
"uid=foo,ou=bar,dc=,dc=baz", "uid=foo,ou=bar,dc=baz,dc=",
|
|
|
|
"uid=foo,dc=example,dc=com", "uid=1foo,ou=bar,dc=example,dc=com",
|
|
|
|
"uid=.bob,ou=foo,dc=bar,dc=baz", "uid=_foo,ou=foo,dc=bar,dc=baz",
|
|
|
|
"uid=foo,uid=bar,ou=bar,dc=com", "cn=foo,ou=bar,dc=example,dc=com",
|
|
|
|
"uid=abc%,ou=foo,dc=example,dc=com",
|
|
|
|
]:
|
|
|
|
with pytest.raises(ll.InvalidStringFormatException):
|
|
|
|
print(invalid_string)
|
|
|
|
ll._assert_is_valid_user_dn(invalid_string)
|
|
|
|
|
|
|
|
for valid_string in [
|
|
|
|
"uid=foo,ou=users,dc=example,dc=com", "uid=Foo-bar.baz_,ou=users,dc=a,dc=de",
|
|
|
|
"uid=bOb_.-,ou=Users,dc=example,dc=com", "uid=foo,ou=foo,dc=bar,dc=baz",
|
|
|
|
]:
|
|
|
|
assert ll._assert_is_valid_user_dn(valid_string) == None
|
|
|
|
|
|
|
|
|
|
|
|
def test_assert_is_valid_group_dn():
|
|
|
|
for invalid_type in [None, 0, True, ("x",), ["x"]]:
|
|
|
|
with pytest.raises(TypeError):
|
|
|
|
ll._assert_is_valid_group_dn(invalid_type)
|
|
|
|
|
|
|
|
for invalid_string in [
|
|
|
|
"", " ", "cn=foo", "abc", "\u1337",
|
|
|
|
"cn=,ou=foo,dc=bar,dc=baz", "cn=foo,ou=,dc=bar,dc=baz",
|
|
|
|
"cn=foo,ou=bar,dc=,dc=baz", "cn=foo,ou=bar,dc=baz,dc=",
|
|
|
|
"cn=foo,dc=example,dc=com", "cn=1foo,ou=bar,dc=example,dc=com",
|
|
|
|
"cn=.bob,ou=foo,dc=bar,dc=baz", "cn=_foo,ou=foo,dc=bar,dc=baz",
|
|
|
|
"cn=foo,cn=bar,ou=bar,dc=com",
|
|
|
|
"cn=abc%,ou=foo,dc=bar,dc=baz", "cn=abc1,ou=foo,dc=bar,dc=baz",
|
|
|
|
"cn=ab-c,ou=foo,dc=bar,dc=baz",
|
|
|
|
]:
|
|
|
|
with pytest.raises(ll.InvalidStringFormatException):
|
|
|
|
print(invalid_string)
|
|
|
|
ll._assert_is_valid_group_dn(invalid_string)
|
|
|
|
|
|
|
|
for valid_string in [
|
|
|
|
"cn=foo,ou=groups,dc=example,dc=com", "cn=foo,ou=bar,dc=a,dc=de",
|
|
|
|
"cn=Abc,ou=foo,dc=bar,dc=baz",
|
|
|
|
]:
|
|
|
|
assert ll._assert_is_valid_group_dn(valid_string) == None
|
|
|
|
|
|
|
|
|
2022-11-09 13:45:47 +00:00
|
|
|
def test_assert_is_valid_user_object_class():
|
|
|
|
for invalid_type in [None, 0, True, ("x",), ["x"]]:
|
|
|
|
with pytest.raises(TypeError):
|
|
|
|
ll._assert_is_valid_user_object_class(invalid_type)
|
|
|
|
|
|
|
|
for invalid_string in [
|
|
|
|
"", " ", "\u1337",
|
|
|
|
"organizationalUnit", "INETORGPERSON", "inetorgperson",
|
|
|
|
]:
|
|
|
|
with pytest.raises(ll.InvalidStringFormatException):
|
|
|
|
ll._assert_is_valid_user_object_class(invalid_string)
|
|
|
|
|
|
|
|
assert ll._assert_is_valid_user_object_class("inetOrgPerson") == None
|
|
|
|
|
|
|
|
|
|
|
|
def test_assert_is_valid_group_object_class():
|
|
|
|
for invalid_type in [None, 0, True, ("x",), ["x"]]:
|
|
|
|
with pytest.raises(TypeError):
|
|
|
|
ll._assert_is_valid_group_object_class(invalid_type)
|
|
|
|
|
|
|
|
for invalid_string in [
|
|
|
|
"", " ", "\u1337",
|
|
|
|
"organizationalUnit", "inetOrgPerson",
|
|
|
|
"groupofuniquenames", "GROUPOFUNIQUENAMES",
|
|
|
|
]:
|
|
|
|
with pytest.raises(ll.InvalidStringFormatException):
|
|
|
|
ll._assert_is_valid_group_object_class(invalid_string)
|
|
|
|
|
|
|
|
assert ll._assert_is_valid_group_object_class("groupOfUniqueNames") == None
|
|
|
|
|
|
|
|
|
|
|
|
def test_assert_is_valid_connection(connection):
|
|
|
|
for invalid_type in [1, "", None, (connection,)]:
|
|
|
|
with pytest.raises(TypeError):
|
|
|
|
ll._assert_is_valid_connection(invalid_type)
|
|
|
|
|
|
|
|
assert ll._assert_is_valid_connection(connection) == None
|
|
|
|
|
|
|
|
with pytest.raises(ll.InvalidConnectionException):
|
|
|
|
connection.unbind()
|
|
|
|
ll._assert_is_valid_connection(connection)
|
|
|
|
|
|
|
|
|
|
|
|
def test_ou_exists(app, connection):
|
|
|
|
with app.app_context():
|
|
|
|
for invalid_type in [1, True, None]:
|
|
|
|
with pytest.raises(TypeError):
|
|
|
|
ll.ou_exists(connection, invalid_type)
|
|
|
|
|
|
|
|
with pytest.raises(ll.InvalidStringFormatException):
|
|
|
|
ll.ou_exists(connection, "cn=foo,dc=example,dc=com")
|
|
|
|
|
|
|
|
assert ll.ou_exists(connection, "ou=users,dc=example,dc=com")
|
|
|
|
assert ll.ou_exists(connection, "ou=groups,dc=example,dc=com")
|
|
|
|
assert not ll.ou_exists(connection, "ou=nonexsistent,dc=example,dc=com")
|
|
|
|
|
|
|
|
|
|
|
|
def test_ou_exists_unpopulated(app, connection_empty_dit):
|
|
|
|
with app.app_context():
|
|
|
|
assert not ll.ou_exists(connection_empty_dit, "ou=users,dc=example,dc=com")
|
|
|
|
assert not ll.ou_exists(connection_empty_dit, "ou=groups,dc=example,dc=com")
|
|
|
|
|
2022-11-15 23:22:39 +00:00
|
|
|
|
2022-11-09 13:45:47 +00:00
|
|
|
def test_create_ou(app, connection):
|
|
|
|
with app.app_context():
|
|
|
|
with pytest.raises(ll.EntryExistsException):
|
|
|
|
ll.create_ou(connection, "ou=users,dc=example,dc=com")
|
|
|
|
|
|
|
|
assert not ll.ou_exists(connection, "ou=foo,dc=example,dc=com")
|
|
|
|
ll.create_ou(connection, "ou=foo,dc=example,dc=com")
|
|
|
|
assert ll.ou_exists(connection, "ou=foo,dc=example,dc=com")
|
2022-11-15 23:22:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_user_exists(app, connection):
|
|
|
|
with app.app_context():
|
|
|
|
assert ll.user_exists(connection, "uid=alice,ou=users,dc=example,dc=com")
|
|
|
|
assert not ll.user_exists(connection, "uid=nonexistent,ou=users,dc=example,dc=com")
|
|
|
|
|
|
|
|
|
|
|
|
def test_get_user(app, connection):
|
|
|
|
with app.app_context():
|
|
|
|
for invalid_type in [1, True, None]:
|
|
|
|
with pytest.raises(TypeError):
|
|
|
|
ll.get_user(connection, invalid_type)
|
|
|
|
|
|
|
|
with pytest.raises(ll.EntryNotFoundException):
|
|
|
|
ll.get_user(connection, "nonexistent")
|
|
|
|
|
|
|
|
assert ll.get_user(connection, "alice").username == "alice"
|
|
|
|
|
|
|
|
|
|
|
|
def test_create_user(app, connection):
|
|
|
|
with app.app_context():
|
|
|
|
user0 = lu.User(
|
|
|
|
username="user0",
|
|
|
|
password_hash=lu.User.generate_password_hash("password"),
|
|
|
|
email="valid@example.com",
|
|
|
|
first_name="Test",
|
|
|
|
last_name="User",
|
|
|
|
)
|
|
|
|
alice_duplicate = lu.User(
|
|
|
|
username="alice",
|
|
|
|
password_hash=lu.User.generate_password_hash("password"),
|
|
|
|
email="valid@example.com",
|
|
|
|
first_name="Test",
|
|
|
|
last_name="User",
|
|
|
|
)
|
|
|
|
|
|
|
|
with pytest.raises(ll.EntryExistsException):
|
|
|
|
ll.create_user(connection, alice_duplicate)
|
|
|
|
|
|
|
|
assert ll.create_user(connection, user0) == None
|
|
|
|
|
|
|
|
|
|
|
|
def test_update_user(app, connection):
|
|
|
|
with app.app_context():
|
|
|
|
user0 = lu.User(
|
|
|
|
username="user0",
|
|
|
|
password_hash=lu.User.generate_password_hash("password"),
|
|
|
|
email="valid@example.com",
|
|
|
|
first_name="Test",
|
|
|
|
last_name="User",
|
|
|
|
)
|
|
|
|
|
|
|
|
with pytest.raises(TypeError):
|
|
|
|
ll.update_user(connection, None)
|
|
|
|
with pytest.raises(ll.EntryNotFoundException):
|
|
|
|
ll.update_user(connection, user0)
|
|
|
|
|
|
|
|
ll.create_user(connection, user0)
|
|
|
|
assert ll.get_user(connection, "user0").email == "valid@example.com"
|
|
|
|
user0.email = "other@example.com"
|
|
|
|
ll.update_user(connection, user0)
|
|
|
|
assert ll.get_user(connection, "user0").email == "other@example.com"
|
|
|
|
|
|
|
|
|
|
|
|
def test_delete_user(app, connection):
|
|
|
|
with app.app_context():
|
|
|
|
user0 = lu.User(
|
|
|
|
username="user0",
|
|
|
|
password_hash=lu.User.generate_password_hash("password"),
|
|
|
|
email="valid@example.com",
|
|
|
|
first_name="Test",
|
|
|
|
last_name="User",
|
|
|
|
)
|
|
|
|
|
|
|
|
with pytest.raises(ll.EntryNotFoundException):
|
|
|
|
ll.delete_user(connection, "user0")
|
|
|
|
|
|
|
|
ll.create_user(connection, user0)
|
|
|
|
assert ll.user_exists(connection, user0.get_dn())
|
|
|
|
ll.delete_user(connection, "user0")
|
|
|
|
assert not ll.user_exists(connection, user0.get_dn())
|
|
|
|
|
|
|
|
# TODO check that group deletion works
|
|
|
|
|
|
|
|
|
|
|
|
def test_get_users(app, connection):
|
|
|
|
with app.app_context():
|
|
|
|
assert len(ll.get_users(connection)) == 2
|
|
|
|
for user in ll.get_users(connection):
|
|
|
|
assert user.username in ["alice", "bobbuilder"]
|
|
|
|
|
2022-11-16 10:42:25 +00:00
|
|
|
ll.create_user(
|
|
|
|
connection,
|
|
|
|
lu.User(
|
|
|
|
username="user0",
|
|
|
|
password_hash=lu.User.generate_password_hash("password"),
|
|
|
|
email="valid@example.com",
|
|
|
|
first_name="Test",
|
|
|
|
last_name="User",
|
|
|
|
),
|
|
|
|
)
|
|
|
|
|
|
|
|
assert len(ll.get_users(connection)) == 3
|
|
|
|
for user in ll.get_users(connection):
|
|
|
|
assert user.username in ["alice", "bobbuilder", "user0"]
|
|
|
|
|
2022-11-15 23:22:39 +00:00
|
|
|
|
|
|
|
def test_group_exists(app, connection):
|
|
|
|
with app.app_context():
|
2022-11-16 10:42:25 +00:00
|
|
|
assert ll.group_exists(
|
|
|
|
connection, "cn=employees,ou=groups,dc=example,dc=com"
|
|
|
|
)
|
|
|
|
assert not ll.group_exists(
|
|
|
|
connection, "cn=nonexistent,ou=groups,dc=example,dc=com"
|
|
|
|
)
|
2022-11-15 23:22:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_create_group(app, connection):
|
|
|
|
with app.app_context():
|
2022-11-16 10:42:25 +00:00
|
|
|
alice = ll.get_user(connection, "alice")
|
|
|
|
testgroup = lu.Group("testgroup", {alice})
|
|
|
|
|
|
|
|
ll.create_group(connection, testgroup)
|
|
|
|
assert ll.group_exists(connection, "cn=testgroup,ou=groups,dc=example,dc=com")
|
|
|
|
|
|
|
|
with pytest.raises(ll.EntryExistsException):
|
|
|
|
ll.create_group(connection, testgroup)
|
|
|
|
|
|
|
|
user0 = lu.User(
|
|
|
|
username="user0",
|
|
|
|
password_hash=lu.User.generate_password_hash("password"),
|
|
|
|
email="valid@example.com",
|
|
|
|
first_name="Test",
|
|
|
|
last_name="User",
|
|
|
|
)
|
|
|
|
with pytest.raises(ll.EntryNotFoundException):
|
|
|
|
ll.create_group(connection, lu.Group("invalidgroup", {user0}))
|
|
|
|
|
2022-11-15 23:22:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_delete_group(app, connection):
|
|
|
|
with app.app_context():
|
2022-11-16 10:42:25 +00:00
|
|
|
assert ll.group_exists(connection, "cn=employees,ou=groups,dc=example,dc=com")
|
|
|
|
ll.delete_group(connection, "employees")
|
|
|
|
assert not ll.group_exists(connection, "cn=employees,ou=groups,dc=example,dc=com")
|
|
|
|
|
|
|
|
with pytest.raises(ll.EntryNotFoundException):
|
|
|
|
ll.delete_group(connection, "employees")
|
|
|
|
|
2022-11-15 23:22:39 +00:00
|
|
|
|
2022-11-16 13:02:22 +00:00
|
|
|
def test_update_group(app, connection):
|
|
|
|
with app.app_context():
|
|
|
|
employees = ll.get_group(connection, "employees")
|
|
|
|
user0 = lu.User(
|
|
|
|
username="user0",
|
|
|
|
password_hash=lu.User.generate_password_hash("password"),
|
|
|
|
email="valid@example.com",
|
|
|
|
first_name="Test",
|
|
|
|
last_name="User",
|
|
|
|
)
|
|
|
|
employees.members.add(user0)
|
|
|
|
with pytest.raises(ll.EntryNotFoundException):
|
|
|
|
ll.update_group(connection, employees)
|
|
|
|
ll.create_user(connection, user0)
|
|
|
|
ll.update_group(connection, employees)
|
|
|
|
assert user0 in ll.get_group(connection, "employees").members
|
|
|
|
|
2022-11-15 23:22:39 +00:00
|
|
|
|
|
|
|
def test_get_group(app, connection):
|
|
|
|
with app.app_context():
|
2022-11-16 10:42:25 +00:00
|
|
|
employees = ll.get_group(connection, "employees")
|
|
|
|
assert len(employees.members) == 2
|
|
|
|
|
|
|
|
with pytest.raises(ll.EntryNotFoundException):
|
|
|
|
ll.get_group(connection, "nonexistent")
|
2022-11-15 23:22:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_get_groups(app, connection):
|
|
|
|
with app.app_context():
|
2022-11-16 10:42:25 +00:00
|
|
|
groups = ll.get_groups(connection)
|
|
|
|
assert len(groups) == 2
|
|
|
|
|
|
|
|
for group in groups:
|
|
|
|
ll.delete_group(connection, group.groupname)
|
|
|
|
assert len(ll.get_groups(connection)) == 0
|
2022-11-15 23:22:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_get_groups_of_user(app, connection):
|
|
|
|
with app.app_context():
|
2022-11-16 10:42:25 +00:00
|
|
|
alice = ll.get_user(connection, "alice")
|
|
|
|
bobbuilder = ll.get_user(connection, "bobbuilder")
|
|
|
|
|
|
|
|
assert len(ll.get_groups_of_user(connection, alice)) == 2
|
|
|
|
assert len(ll.get_groups_of_user(connection, bobbuilder)) == 1
|