diff --git a/CHANGELOG.md b/CHANGELOG.md index f63bfd98..2738cc4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +- added methods for extracting persons by name or ID from ldap - `contains_only_types` to check if fields are annotated as desired - `group_fields_by_class_name` utility to simplify filtered model/field lookups diff --git a/mex/common/ldap/extract.py b/mex/common/ldap/extract.py index 62abf7ef..89854dd0 100644 --- a/mex/common/ldap/extract.py +++ b/mex/common/ldap/extract.py @@ -1,7 +1,8 @@ from collections import defaultdict -from collections.abc import Iterable +from collections.abc import Generator, Iterable from mex.common.identity import get_provider +from mex.common.ldap.connector import LDAPConnector from mex.common.ldap.models.person import LDAPPerson, LDAPPersonWithQuery from mex.common.models import ExtractedPrimarySource from mex.common.types import MergedPersonIdentifier @@ -111,3 +112,41 @@ def get_merged_ids_by_query_string( MergedPersonIdentifier(identities[0].stableTargetId) ) return merged_ids_by_attribute + + +def get_persons_by_name( + surname: str = "*", + given_name: str = "*", + **filters: str, +) -> Generator[LDAPPerson, None, None]: + """Get all ldap persons matching the filters. + + Args: + given_name: Given name of a person, defaults to non-null. + surname: Surname of a person, defaults to non-null. + **filters: Additional filters. + + Returns: + Generator for LDAP persons. + """ + connector = LDAPConnector.get() + return connector.get_persons(surname, given_name, **filters) + + +def get_count_of_found_persons_by_name( + surname: str = "*", + given_name: str = "*", + **filters: str, +) -> int: + """Get total count of found ldap persons. + + Args: + given_name: Given name of a person, defaults to non-null. + surname: Surname of a person, defaults to non-null. + **filters: Additional filters. + + Returns: + count of found persons. + """ + connector = LDAPConnector.get() + return len(list(connector.get_persons(surname, given_name, **filters))) diff --git a/tests/ldap/test_extract.py b/tests/ldap/test_extract.py index b7a4d308..a3aa30a8 100644 --- a/tests/ldap/test_extract.py +++ b/tests/ldap/test_extract.py @@ -5,13 +5,16 @@ from mex.common.identity import get_provider from mex.common.ldap.extract import ( _get_merged_ids_by_attribute, + get_count_of_found_persons_by_name, get_merged_ids_by_email, get_merged_ids_by_employee_ids, get_merged_ids_by_query_string, + get_persons_by_name, ) from mex.common.ldap.models.person import LDAPPerson, LDAPPersonWithQuery from mex.common.models import ExtractedPrimarySource from mex.common.types import Identifier +from tests.ldap.conftest import SAMPLE_PERSON_ATTRS, LDAPMocker @pytest.fixture @@ -173,3 +176,35 @@ def test_get_merged_ids_by_query_string( ldap_persons_with_query, ldap_primary_source ) assert merged_ids_by_query_string == expected + + +def test_get_persons_by_name_mocked(ldap_mocker: LDAPMocker) -> None: + ldap_mocker([[SAMPLE_PERSON_ATTRS]]) + persons = get_persons_by_name(surname="Sample", given_name="Sam") + persons_list = list(persons) + expected = { + "company": "RKI", + "department": "XY", + "departmentNumber": "XY2", + "displayName": "Sample, Sam", + "employeeID": "1024", + "givenName": ["Sam"], + "mail": ["SampleS@mail.tld"], + "objectGUID": UUID("00000000-0000-4000-8000-000000000000"), + "ou": ["XY"], + "sAMAccountName": "SampleS", + "sn": "Sample", + } + assert len(persons_list) == 1 + assert ( + persons_list[0].model_dump(exclude_none=True)["givenName"] + == expected["givenName"] + ) + + +def test_get_count_of_found_persons_by_name_mocked(ldap_mocker: LDAPMocker) -> None: + ldap_mocker([[SAMPLE_PERSON_ATTRS]]) + persons_count = get_count_of_found_persons_by_name( + surname="Sample", given_name="Sam" + ) + assert persons_count == 1