forked from public/pyceo
add tests for Group class
This commit is contained in:
parent
e7bfe36c0b
commit
3ecf43731f
|
@ -2,15 +2,13 @@ from typing import Dict, List
|
|||
|
||||
from zope.interface import Interface, Attribute
|
||||
|
||||
from .IUser import IUser
|
||||
|
||||
|
||||
class IGroup(Interface):
|
||||
"""Represents a Unix group."""
|
||||
|
||||
cn = Attribute('common name')
|
||||
gid_number = Attribute('gid number')
|
||||
unique_members = Attribute('DNs of group members')
|
||||
members = Attribute('usernames of group members')
|
||||
dn = Attribute('distinguished name')
|
||||
|
||||
def add_to_ldap():
|
||||
|
@ -22,9 +20,6 @@ class IGroup(Interface):
|
|||
def remove_member(username: str):
|
||||
"""Remove the member from this group in LDAP."""
|
||||
|
||||
def get_members() -> List[IUser]:
|
||||
"""Get a list of the members in this group."""
|
||||
|
||||
def serialize_for_ldap() -> Dict[str, List[bytes]]:
|
||||
"""
|
||||
Serialize this group into a dict to be passed to
|
||||
|
@ -37,3 +32,6 @@ class IGroup(Interface):
|
|||
|
||||
:returns: IGroup
|
||||
"""
|
||||
|
||||
def to_dict():
|
||||
"""Serialize this group as JSON."""
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import copy
|
||||
import json
|
||||
from typing import List, Dict, Union
|
||||
|
||||
from zope import component
|
||||
from zope.interface import implementer
|
||||
|
||||
from .utils import strings_to_bytes, bytes_to_strings, dn_to_uid
|
||||
from ceo_common.interfaces import ILDAPService, IGroup, IConfig, IUser
|
||||
from ceo_common.interfaces import ILDAPService, IGroup, IConfig
|
||||
|
||||
|
||||
@implementer(IGroup)
|
||||
|
@ -16,8 +17,8 @@ class Group:
|
|||
):
|
||||
self.cn = cn
|
||||
self.gid_number = gid_number
|
||||
# this is a list of the DNs of the members in this group
|
||||
self.member_DNs = members or []
|
||||
# this is a list of the usernames of the members in this group
|
||||
self.members = members or []
|
||||
|
||||
cfg = component.getUtility(IConfig)
|
||||
self.dn = f'cn={cn},{cfg.get("ldap_groups_base")}'
|
||||
|
@ -25,17 +26,15 @@ class Group:
|
|||
self.ldap_srv = component.getUtility(ILDAPService)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
lines = [
|
||||
'dn: ' + self.dn,
|
||||
'cn: ' + self.cn,
|
||||
'gidNumber: ' + str(self.gid_number),
|
||||
'objectClass: top',
|
||||
'objectClass: group',
|
||||
'objectClass: posixGroup',
|
||||
]
|
||||
for member_dn in self.member_DNs:
|
||||
lines.append('uniqueMember: ' + member_dn)
|
||||
return '\n'.join(lines)
|
||||
return json.dumps(self.to_dict(), indent=2)
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
'dn': self.dn,
|
||||
'cn': self.cn,
|
||||
'gid_number': self.gid_number,
|
||||
'members': self.members,
|
||||
}
|
||||
|
||||
def add_to_ldap(self):
|
||||
self.ldap_srv.add_group(self)
|
||||
|
@ -53,8 +52,11 @@ class Group:
|
|||
'posixGroup',
|
||||
],
|
||||
}
|
||||
if self.member_DNs:
|
||||
data['uniqueMember'] = self.member_DNs
|
||||
if self.members:
|
||||
data['uniqueMember'] = [
|
||||
f'uid={member},{self.ldap_users_base}'
|
||||
for member in self.members
|
||||
]
|
||||
return strings_to_bytes(data)
|
||||
|
||||
@staticmethod
|
||||
|
@ -63,25 +65,21 @@ class Group:
|
|||
return Group(
|
||||
cn=data['cn'][0],
|
||||
gid_number=int(data['gidNumber'][0]),
|
||||
members=data.get('uniqueMember'),
|
||||
members=[
|
||||
dn_to_uid(dn) for dn in data.get('uniqueMember', [])
|
||||
],
|
||||
)
|
||||
|
||||
def add_member(self, username: str):
|
||||
new_group = copy.copy(self)
|
||||
new_group.member_DNs = self.member_DNs.copy()
|
||||
new_group.member_DNs.append(f'uid={username},{self.ldap_users_base}')
|
||||
new_group.members = self.members.copy()
|
||||
new_group.members.append(username)
|
||||
self.ldap_srv.modify_group(self, new_group)
|
||||
self.member_DNs = new_group.member_DNs
|
||||
self.members = new_group.members
|
||||
|
||||
def remove_member(self, username: str):
|
||||
new_group = copy.copy(self)
|
||||
new_group.member_DNs = self.member_DNs.copy()
|
||||
new_group.member_DNs.remove(f'uid={username},{self.ldap_users_base}')
|
||||
new_group.members = self.members.copy()
|
||||
new_group.members.remove(username)
|
||||
self.ldap_srv.modify_group(self, new_group)
|
||||
self.member_DNs = new_group.member_DNs
|
||||
|
||||
def get_members(self) -> List[IUser]:
|
||||
members = []
|
||||
for dn in self.member_DNs:
|
||||
members.append(self.ldap_srv.get_user(dn_to_uid(dn)))
|
||||
return members
|
||||
self.members = new_group.members
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
import pytest
|
||||
|
||||
from ceo_common.errors import GroupNotFoundError
|
||||
|
||||
|
||||
def test_group_add_to_ldap(simple_group, ldap_srv):
|
||||
group = simple_group
|
||||
|
||||
group.add_to_ldap()
|
||||
retrieved_group = ldap_srv.get_group(group.cn)
|
||||
assert retrieved_group.cn == group.cn
|
||||
|
||||
group.remove_from_ldap()
|
||||
with pytest.raises(GroupNotFoundError):
|
||||
ldap_srv.get_group(group.cn)
|
||||
|
||||
|
||||
def test_group_members(ldap_group, ldap_srv):
|
||||
group = ldap_group
|
||||
|
||||
group.add_member('member1')
|
||||
assert group.members == ['member1']
|
||||
assert ldap_srv.get_group(group.cn).members == group.members
|
||||
|
||||
group.add_member('member2')
|
||||
assert group.members == ['member1', 'member2']
|
||||
assert ldap_srv.get_group(group.cn).members == group.members
|
||||
|
||||
group.remove_member('member1')
|
||||
assert group.members == ['member2']
|
||||
assert ldap_srv.get_group(group.cn).members == group.members
|
||||
|
||||
|
||||
def test_group_to_dict(simple_group):
|
||||
group = simple_group
|
||||
|
||||
expected = {
|
||||
'dn': group.dn,
|
||||
'cn': group.cn,
|
||||
'gid_number': group.gid_number,
|
||||
'members': group.members,
|
||||
}
|
||||
assert group.to_dict() == expected
|
|
@ -2,4 +2,4 @@
|
|||
ignore =
|
||||
# line too long
|
||||
E501
|
||||
exclude = .git,.vscode,venv,__pycache__,__init__.py,build,dist
|
||||
exclude = .git,.vscode,venv,__pycache__,__init__.py,conftest.py,build,dist
|
||||
|
|
|
@ -11,7 +11,7 @@ from ceo_common.interfaces import IConfig, IKerberosService, ILDAPService, \
|
|||
IFileService, IMailmanService, IHTTPClient
|
||||
from ceo_common.model import Config, RemoteMailmanService, HTTPClient
|
||||
from ceod.model import KerberosService, LDAPService, FileService, User, \
|
||||
MailmanService
|
||||
MailmanService, Group
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True, scope='session')
|
||||
|
@ -138,3 +138,18 @@ def mailman_srv(cfg, http_client):
|
|||
mailman = RemoteMailmanService()
|
||||
component.provideUtility(mailman, IMailmanService)
|
||||
return mailman
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def simple_group():
|
||||
return Group(
|
||||
cn='group1',
|
||||
gid_number=21000,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ldap_group(simple_group):
|
||||
simple_group.add_to_ldap()
|
||||
yield simple_group
|
||||
simple_group.remove_from_ldap()
|
||||
|
|
Loading…
Reference in New Issue