From 67cf338dc81a6fb1a153d77bd9629e5aac886d4d Mon Sep 17 00:00:00 2001 From: Aditi Chikkali Date: Thu, 20 Nov 2025 09:52:36 -0500 Subject: [PATCH 1/6] added new endpoint for test login page --- src/nsls2api/api/v1/whoami_api.py | 15 ++++++++++ src/nsls2api/main.py | 2 ++ src/nsls2api/services/ldap_service.py | 43 +++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 src/nsls2api/api/v1/whoami_api.py create mode 100644 src/nsls2api/services/ldap_service.py diff --git a/src/nsls2api/api/v1/whoami_api.py b/src/nsls2api/api/v1/whoami_api.py new file mode 100644 index 00000000..b1cafa9b --- /dev/null +++ b/src/nsls2api/api/v1/whoami_api.py @@ -0,0 +1,15 @@ +from fastapi import APIRouter, Depends, Request +from nsls2api.services.ldap_service import get_user_info +router = APIRouter() + +@router.get("/whoami") +async def whoami(request: Request): + #ldap logic + LDAP_SERVER = "ldap://ldapproxy.nsls2.bnl.gov" + BASE_DN = "dc=bnl,dc=gov" + BIND_USER = "CN=n2snbind3,OU=CAM - Service Accounts,OU=CAM,DC=bnl,DC=gov" + BIND_PASSWORD = "V3%aKntg8woNa*b3#J" + upn = "swilkins@bnl.gov" + + user_info = get_user_info(upn, LDAP_SERVER, BASE_DN, BIND_USER, BIND_PASSWORD) + return {"user": user_info} \ No newline at end of file diff --git a/src/nsls2api/main.py b/src/nsls2api/main.py index 1c0f599f..365956d9 100644 --- a/src/nsls2api/main.py +++ b/src/nsls2api/main.py @@ -22,6 +22,7 @@ from nsls2api.infrastructure.logging import logger from nsls2api.middleware import ProcessTimeMiddleware from nsls2api.views import diagnostics, home +from nsls2api.api.v1 import whoami_api as whoami_api_v1 settings = get_settings() @@ -78,6 +79,7 @@ def configure_routing(): app.include_router(user_api_v1.router, prefix="/v1", tags=["user"]) app.include_router(admin_api_v1.router, prefix="/v1", tags=["admin"]) app.include_router(jobs_api_v1.router, prefix="/v1", tags=["jobs"]) + app.include_router(whoami_api_v1.router, prefix="/v1", tags=["whoami"]) # Just log the current working directory - useful is some of the static files are not found. logger.info(f"Current working directory: {os.getcwd()}") diff --git a/src/nsls2api/services/ldap_service.py b/src/nsls2api/services/ldap_service.py new file mode 100644 index 00000000..aab22d73 --- /dev/null +++ b/src/nsls2api/services/ldap_service.py @@ -0,0 +1,43 @@ +from ldap3 import Server, Connection + +def get_user_info(upn, ldap_server, base_dn, bind_user, bind_password): + conn = None + try: + server = Server(ldap_server) + conn = Connection(server, user=bind_user, password=bind_password, auto_bind=True) + search_filter = f"(&(objectclass=person)(userPrincipalName={upn}))" + conn.search(base_dn, search_filter, attributes=['sAMAccountName']) + if conn.entries: + entry = conn.entries[0] + else: + print("No entries found for the given UPN.") + if conn is not None: + conn.unbind() + return None + username = entry.sAMAccountName.value if 'sAMAccountName' in entry else None + print(f"Resolved username: {username}") + if username is None: + if conn is not None: + conn.unbind() + return None + search_filter = f"(&(objectclass=posixaccount)(sAMAccountName={username}))" + conn.search(base_dn, search_filter, attributes=['*']) + print('posix search result:",conn.entries') + if conn.entries: + entry = conn.entries[0] + if conn is not None: + conn.unbind() + user = dict() + for attribute in entry.entry_attributes: + user[attribute] = str(entry[attribute].value) + return user + else: + print("no posix entries found for the given username.") + except Exception as e: + print(f"LDAP Error: {e}") + if conn is not None: + conn.unbind() + return None + if conn is not None: + conn.unbind() + return None \ No newline at end of file From 6e68bd00628fb40036b2601ba0718cd975b95b9a Mon Sep 17 00:00:00 2001 From: Aditi Yashwant Chikkali Date: Fri, 21 Nov 2025 09:59:03 -0500 Subject: [PATCH 2/6] changed ldap server configs --- src/nsls2api/api/v1/whoami_api.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/nsls2api/api/v1/whoami_api.py b/src/nsls2api/api/v1/whoami_api.py index b1cafa9b..d4ffffcc 100644 --- a/src/nsls2api/api/v1/whoami_api.py +++ b/src/nsls2api/api/v1/whoami_api.py @@ -1,15 +1,16 @@ -from fastapi import APIRouter, Depends, Request +from fastapi import APIRouter, Depends, Request, Query from nsls2api.services.ldap_service import get_user_info router = APIRouter() - +import os +from dotenv import load_dotenv +load_dotenv(dotenv_path="src/nsls2api/.env") @router.get("/whoami") -async def whoami(request: Request): - #ldap logic - LDAP_SERVER = "ldap://ldapproxy.nsls2.bnl.gov" - BASE_DN = "dc=bnl,dc=gov" - BIND_USER = "CN=n2snbind3,OU=CAM - Service Accounts,OU=CAM,DC=bnl,DC=gov" - BIND_PASSWORD = "V3%aKntg8woNa*b3#J" - upn = "swilkins@bnl.gov" +async def whoami(request: Request, upn: str = Query(..., description="User Principal Name")): + LDAP_SERVER = os.getenv("LDAP_SERVER") + BASE_DN = os.getenv("BASE_DN") + BIND_USER = os.getenv("BIND_USER") + BIND_PASSWORD = os.getenv("LDAP_BIND_PASSWORD") + user_info = get_user_info(upn, LDAP_SERVER, BASE_DN, BIND_USER, BIND_PASSWORD) return {"user": user_info} \ No newline at end of file From a6d67465a1b6450e1cfd981f36fe2f94950c0dce Mon Sep 17 00:00:00 2001 From: Aditi Yashwant Chikkali Date: Mon, 24 Nov 2025 21:54:25 -0500 Subject: [PATCH 3/6] refactored api response --- src/nsls2api/api/v1/whoami_api.py | 17 ++++- src/nsls2api/services/ldap_service.py | 103 +++++++++++++++++++++++++- 2 files changed, 114 insertions(+), 6 deletions(-) diff --git a/src/nsls2api/api/v1/whoami_api.py b/src/nsls2api/api/v1/whoami_api.py index d4ffffcc..779b610e 100644 --- a/src/nsls2api/api/v1/whoami_api.py +++ b/src/nsls2api/api/v1/whoami_api.py @@ -1,16 +1,27 @@ from fastapi import APIRouter, Depends, Request, Query -from nsls2api.services.ldap_service import get_user_info +from nsls2api.services.ldap_service import get_user_info, shape_ldap_response router = APIRouter() import os from dotenv import load_dotenv + +router = APIRouter() load_dotenv(dotenv_path="src/nsls2api/.env") + @router.get("/whoami") async def whoami(request: Request, upn: str = Query(..., description="User Principal Name")): LDAP_SERVER = os.getenv("LDAP_SERVER") BASE_DN = os.getenv("BASE_DN") BIND_USER = os.getenv("BIND_USER") BIND_PASSWORD = os.getenv("LDAP_BIND_PASSWORD") - user_info = get_user_info(upn, LDAP_SERVER, BASE_DN, BIND_USER, BIND_PASSWORD) - return {"user": user_info} \ No newline at end of file + + if not user_info: + return {"error": "User not found or lookup failed"} + + shaped_info = shape_ldap_response(user_info) + if shaped_info["identity"]["unix"]["uidNumber"] and shaped_info["identity"]["unix"]["gidNumber"]: + "Unix account present" + else: + "Unix account present" + return {"user": shaped_info} \ No newline at end of file diff --git a/src/nsls2api/services/ldap_service.py b/src/nsls2api/services/ldap_service.py index aab22d73..13919595 100644 --- a/src/nsls2api/services/ldap_service.py +++ b/src/nsls2api/services/ldap_service.py @@ -1,5 +1,12 @@ from ldap3 import Server, Connection +from datetime import datetime, timedelta + +def to_hex(val): + import binascii + if isinstance(val, bytes): + return binascii.hexlify(val).decode() + return None def get_user_info(upn, ldap_server, base_dn, bind_user, bind_password): conn = None try: @@ -22,14 +29,18 @@ def get_user_info(upn, ldap_server, base_dn, bind_user, bind_password): return None search_filter = f"(&(objectclass=posixaccount)(sAMAccountName={username}))" conn.search(base_dn, search_filter, attributes=['*']) - print('posix search result:",conn.entries') if conn.entries: entry = conn.entries[0] if conn is not None: conn.unbind() user = dict() for attribute in entry.entry_attributes: - user[attribute] = str(entry[attribute].value) + value = entry[attribute].value + if attribute in ("objectGUID", "objectSid"): + user[attribute] = value # keep as bytes + else: + user[attribute] = str(value) + return user else: print("no posix entries found for the given username.") @@ -40,4 +51,90 @@ def get_user_info(upn, ldap_server, base_dn, bind_user, bind_password): return None if conn is not None: conn.unbind() - return None \ No newline at end of file + return None + +def filetime_to_str(filetime): + try: + if filetime is None or int(filetime) == 0 or int(filetime) == 9223372036854775807: + return "Never" + dt = datetime(1601, 1, 1) + timedelta(microseconds=int(filetime) // 10) + return dt.strftime("%Y-%m-%d %H:%M:%S UTC") + except Exception: + return str(filetime) + +def generalized_time_to_str(gt): + try: + if not gt: return "" + dt = datetime.strptime(gt.split(".")[0], "%Y%m%d%H%M%S") + return dt.strftime("%Y-%m-%d %H:%M:%S UTC") + except Exception: + return str(gt) + +def decode_uac(uac): + flags = [] + try: + val = int(uac) + if val & 0x0001: flags.append("SCRIPT") + if val & 0x0002: flags.append("ACCOUNTDISABLE") + if val & 0x0008: flags.append("HOMEDIR_REQUIRED") + if val & 0x0200: flags.append("NORMAL_ACCOUNT") + if val & 0x1000: flags.append("PASSWORD_EXPIRED") + except Exception: + return [] + return flags or ["NORMAL_ACCOUNT"] + +def shape_ldap_response(user_info, dn=None, status="Read", read_time=None): + def clean_groups(groups_val): + if not groups_val: + return [] + if isinstance(groups_val, list): + return groups_val + elif isinstance(groups_val, str): + return [g.strip() for g in groups_val.replace("\n", ",").split(",") if g.strip()] + return [] + + return { + "dn": dn or user_info.get("distinguishedName"), + "status": status, + "readTime": read_time, + "identity": { + "displayName": user_info.get("displayName"), + "email": user_info.get("mail") or user_info.get("email"), + "department": user_info.get("department"), + "manager": user_info.get("manager"), + "unix": { + "uid": user_info.get("uid"), + "uidNumber": user_info.get("uidNumber"), + "gidNumber": user_info.get("gidNumber"), + "homeDirectory": user_info.get("homeDirectory"), + "loginShell": user_info.get("loginShell") + } + }, + "account": { + "accountExpires": filetime_to_str(user_info.get("accountExpires")), + "badPasswordTime": filetime_to_str(user_info.get("badPasswordTime")), + "badPwdCount": int(user_info.get("badPwdCount") or 0), + "pwdLastSet": filetime_to_str(user_info.get("pwdLastSet")), + "lastLogon": filetime_to_str(user_info.get("lastLogon")), + "userAccountControlFlags": decode_uac(user_info.get("userAccountControl")), + "userPrincipalName": user_info.get("userPrincipalName"), + }, + "directory": { + "objectGUID": to_hex(user_info.get("objectGUID")), + "objectSid": to_hex(user_info.get("objectSid")), + "primaryGroupID": user_info.get("primaryGroupID"), + "distinguishedName": user_info.get("distinguishedName"), + }, + "groups": clean_groups(user_info.get("memberOf")), + "attributes": { + "sn": user_info.get("sn"), + "givenName": user_info.get("givenName"), + "description": user_info.get("description"), + "gecos": user_info.get("gecos"), + "street": user_info.get("street"), + "codePage": user_info.get("codePage"), + "countryCode": user_info.get("countryCode"), + "instanceType": user_info.get("instanceType"), + "objectClass": [s.strip() for s in user_info.get("objectClass", "").split() if s.strip()] + } + } \ No newline at end of file From 34e38d04a4f9b6896591b8117008d0d0d2313bab Mon Sep 17 00:00:00 2001 From: Aditi Yashwant Chikkali Date: Fri, 5 Dec 2025 13:37:57 -0500 Subject: [PATCH 4/6] improve ldap connection handling && refactor api to use config settings --- src/nsls2api/api/v1/whoami_api.py | 21 +++++++------ src/nsls2api/infrastructure/config.py | 8 ++++- src/nsls2api/services/ldap_service.py | 45 +++++++++++---------------- 3 files changed, 36 insertions(+), 38 deletions(-) diff --git a/src/nsls2api/api/v1/whoami_api.py b/src/nsls2api/api/v1/whoami_api.py index 779b610e..705db1d8 100644 --- a/src/nsls2api/api/v1/whoami_api.py +++ b/src/nsls2api/api/v1/whoami_api.py @@ -1,18 +1,17 @@ from fastapi import APIRouter, Depends, Request, Query from nsls2api.services.ldap_service import get_user_info, shape_ldap_response -router = APIRouter() -import os -from dotenv import load_dotenv +from nsls2api.infrastructure.config import get_settings router = APIRouter() -load_dotenv(dotenv_path="src/nsls2api/.env") @router.get("/whoami") async def whoami(request: Request, upn: str = Query(..., description="User Principal Name")): - LDAP_SERVER = os.getenv("LDAP_SERVER") - BASE_DN = os.getenv("BASE_DN") - BIND_USER = os.getenv("BIND_USER") - BIND_PASSWORD = os.getenv("LDAP_BIND_PASSWORD") + settings = get_settings() + + LDAP_SERVER = settings.ldap_server + BASE_DN = settings.base_dn + BIND_USER = settings.bind_user + BIND_PASSWORD = settings.ldap_bind_password user_info = get_user_info(upn, LDAP_SERVER, BASE_DN, BIND_USER, BIND_PASSWORD) @@ -21,7 +20,9 @@ async def whoami(request: Request, upn: str = Query(..., description="User Princ shaped_info = shape_ldap_response(user_info) if shaped_info["identity"]["unix"]["uidNumber"] and shaped_info["identity"]["unix"]["gidNumber"]: - "Unix account present" + unix_status = "Unix account present" else: - "Unix account present" + unix_status = "Unix account not found" + + shaped_info["unix_account_status"] = unix_status return {"user": shaped_info} \ No newline at end of file diff --git a/src/nsls2api/infrastructure/config.py b/src/nsls2api/infrastructure/config.py index b14214d8..90ad01dc 100644 --- a/src/nsls2api/infrastructure/config.py +++ b/src/nsls2api/infrastructure/config.py @@ -2,7 +2,7 @@ from functools import lru_cache from pathlib import Path -from pydantic import HttpUrl, MongoDsn +from pydantic import HttpUrl, MongoDsn, Field from pydantic_settings import BaseSettings, SettingsConfigDict from nsls2api.infrastructure.logging import logger @@ -78,6 +78,12 @@ class Settings(BaseSettings): extra="ignore", ) + #Whoami LDAP settings + ldap_server: str = Field(default="ldap://ldapproxy.nsls2.bnl.gov", alias="LDAP_SERVER") + base_dn: str = Field(default="dc=bnl,dc=gov", alias="BASE_DN") + bind_user: str = Field(default="", alias="BIND_USER") + ldap_bind_password: str = Field(default="", alias="LDAP_BIND_PASSWORD") + @lru_cache() def get_settings() -> Settings: diff --git a/src/nsls2api/services/ldap_service.py b/src/nsls2api/services/ldap_service.py index 13919595..761c78ac 100644 --- a/src/nsls2api/services/ldap_service.py +++ b/src/nsls2api/services/ldap_service.py @@ -1,12 +1,13 @@ from ldap3 import Server, Connection from datetime import datetime, timedelta - +import binascii def to_hex(val): - import binascii + if isinstance(val, bytes): return binascii.hexlify(val).decode() return None + def get_user_info(upn, ldap_server, base_dn, bind_user, bind_password): conn = None try: @@ -14,44 +15,34 @@ def get_user_info(upn, ldap_server, base_dn, bind_user, bind_password): conn = Connection(server, user=bind_user, password=bind_password, auto_bind=True) search_filter = f"(&(objectclass=person)(userPrincipalName={upn}))" conn.search(base_dn, search_filter, attributes=['sAMAccountName']) - if conn.entries: - entry = conn.entries[0] - else: + if not conn.entries: print("No entries found for the given UPN.") - if conn is not None: - conn.unbind() return None + entry = conn.entries[0] username = entry.sAMAccountName.value if 'sAMAccountName' in entry else None print(f"Resolved username: {username}") if username is None: - if conn is not None: - conn.unbind() return None search_filter = f"(&(objectclass=posixaccount)(sAMAccountName={username}))" conn.search(base_dn, search_filter, attributes=['*']) - if conn.entries: - entry = conn.entries[0] - if conn is not None: - conn.unbind() - user = dict() - for attribute in entry.entry_attributes: - value = entry[attribute].value - if attribute in ("objectGUID", "objectSid"): - user[attribute] = value # keep as bytes - else: - user[attribute] = str(value) - - return user - else: + if not conn.entries: print("no posix entries found for the given username.") + return None + entry = conn.entries[0] + user = dict() + for attribute in entry.entry_attributes: + value = entry[attribute].value + if attribute in ("objectGUID", "objectSid"): + user[attribute] = value # keep as bytes + else: + user[attribute] = str(value) + return user except Exception as e: print(f"LDAP Error: {e}") + return None + finally: if conn is not None: conn.unbind() - return None - if conn is not None: - conn.unbind() - return None def filetime_to_str(filetime): try: From 014283a3a955bc226f649742a5214d63420ca7f8 Mon Sep 17 00:00:00 2001 From: Aditi Yashwant Chikkali Date: Fri, 5 Dec 2025 13:43:24 -0500 Subject: [PATCH 5/6] change print to logger --- src/nsls2api/services/ldap_service.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/nsls2api/services/ldap_service.py b/src/nsls2api/services/ldap_service.py index 761c78ac..8b120890 100644 --- a/src/nsls2api/services/ldap_service.py +++ b/src/nsls2api/services/ldap_service.py @@ -1,6 +1,7 @@ from ldap3 import Server, Connection from datetime import datetime, timedelta import binascii +import nsls2api.infrastructure.loggging as logger def to_hex(val): @@ -16,17 +17,16 @@ def get_user_info(upn, ldap_server, base_dn, bind_user, bind_password): search_filter = f"(&(objectclass=person)(userPrincipalName={upn}))" conn.search(base_dn, search_filter, attributes=['sAMAccountName']) if not conn.entries: - print("No entries found for the given UPN.") + logger.warning("No entries found for the given UPN.") return None entry = conn.entries[0] username = entry.sAMAccountName.value if 'sAMAccountName' in entry else None - print(f"Resolved username: {username}") if username is None: return None search_filter = f"(&(objectclass=posixaccount)(sAMAccountName={username}))" conn.search(base_dn, search_filter, attributes=['*']) if not conn.entries: - print("no posix entries found for the given username.") + logger.warning("no posix entries found for the given username.") return None entry = conn.entries[0] user = dict() @@ -38,7 +38,7 @@ def get_user_info(upn, ldap_server, base_dn, bind_user, bind_password): user[attribute] = str(value) return user except Exception as e: - print(f"LDAP Error: {e}") + logger.error(f"LDAP Error: {e}") return None finally: if conn is not None: From f041862ab4b95c3070f569b2fa8b766c48a80335 Mon Sep 17 00:00:00 2001 From: Aditi Yashwant Chikkali Date: Fri, 5 Dec 2025 16:33:28 -0500 Subject: [PATCH 6/6] revive existing /person/me endpoitn to fetch ldap user info --- src/nsls2api/api/v1/user_api.py | 25 ++++++++++++++++++++---- src/nsls2api/api/v1/whoami_api.py | 28 --------------------------- src/nsls2api/main.py | 2 -- src/nsls2api/services/ldap_service.py | 9 +++++++-- 4 files changed, 28 insertions(+), 36 deletions(-) delete mode 100644 src/nsls2api/api/v1/whoami_api.py diff --git a/src/nsls2api/api/v1/user_api.py b/src/nsls2api/api/v1/user_api.py index 5a9d7211..37daa182 100644 --- a/src/nsls2api/api/v1/user_api.py +++ b/src/nsls2api/api/v1/user_api.py @@ -1,16 +1,18 @@ from typing import Annotated import fastapi -from fastapi import Depends +from fastapi import Depends, Request, HTTPException from nsls2api.api.models.person_model import DataSessionAccess, Person from nsls2api.infrastructure.security import ( get_current_user, + get_settings ) from nsls2api.services import ( bnlpeople_service, person_service, ) +from nsls2api.services.ldap_service import get_user_info, shape_ldap_response router = fastapi.APIRouter() @@ -74,9 +76,24 @@ async def get_person_by_department(department_code: str = "PS"): # TODO: Add back into schema if we decide to use this endpoint. -@router.get("/person/me", response_model=str, include_in_schema=False) -async def get_myself(current_user: Annotated[Person, Depends(get_current_user)]): - return current_user +@router.get("/person/me",include_in_schema=True) +async def get_myself(request: Request): + upn = request.headers.get("upn") + if not upn: + raise HTTPException(status_code=400, detail = "upn not found") + settings = get_settings() + ldap_info = get_user_info( + upn, + settings.ldap_server, + settings.base_dn, + settings.bind_user, + settings.ldap_bind_password + ) + if not ldap_info: + raise HTTPException(status_code=404, detail="User not found in LDAP") + + shaped_info = shape_ldap_response(ldap_info) + return shaped_info @router.get("/data-session/{username}", response_model=DataSessionAccess, tags=["data"]) diff --git a/src/nsls2api/api/v1/whoami_api.py b/src/nsls2api/api/v1/whoami_api.py deleted file mode 100644 index 705db1d8..00000000 --- a/src/nsls2api/api/v1/whoami_api.py +++ /dev/null @@ -1,28 +0,0 @@ -from fastapi import APIRouter, Depends, Request, Query -from nsls2api.services.ldap_service import get_user_info, shape_ldap_response -from nsls2api.infrastructure.config import get_settings - -router = APIRouter() - -@router.get("/whoami") -async def whoami(request: Request, upn: str = Query(..., description="User Principal Name")): - settings = get_settings() - - LDAP_SERVER = settings.ldap_server - BASE_DN = settings.base_dn - BIND_USER = settings.bind_user - BIND_PASSWORD = settings.ldap_bind_password - - user_info = get_user_info(upn, LDAP_SERVER, BASE_DN, BIND_USER, BIND_PASSWORD) - - if not user_info: - return {"error": "User not found or lookup failed"} - - shaped_info = shape_ldap_response(user_info) - if shaped_info["identity"]["unix"]["uidNumber"] and shaped_info["identity"]["unix"]["gidNumber"]: - unix_status = "Unix account present" - else: - unix_status = "Unix account not found" - - shaped_info["unix_account_status"] = unix_status - return {"user": shaped_info} \ No newline at end of file diff --git a/src/nsls2api/main.py b/src/nsls2api/main.py index 365956d9..1c0f599f 100644 --- a/src/nsls2api/main.py +++ b/src/nsls2api/main.py @@ -22,7 +22,6 @@ from nsls2api.infrastructure.logging import logger from nsls2api.middleware import ProcessTimeMiddleware from nsls2api.views import diagnostics, home -from nsls2api.api.v1 import whoami_api as whoami_api_v1 settings = get_settings() @@ -79,7 +78,6 @@ def configure_routing(): app.include_router(user_api_v1.router, prefix="/v1", tags=["user"]) app.include_router(admin_api_v1.router, prefix="/v1", tags=["admin"]) app.include_router(jobs_api_v1.router, prefix="/v1", tags=["jobs"]) - app.include_router(whoami_api_v1.router, prefix="/v1", tags=["whoami"]) # Just log the current working directory - useful is some of the static files are not found. logger.info(f"Current working directory: {os.getcwd()}") diff --git a/src/nsls2api/services/ldap_service.py b/src/nsls2api/services/ldap_service.py index 8b120890..b5e38169 100644 --- a/src/nsls2api/services/ldap_service.py +++ b/src/nsls2api/services/ldap_service.py @@ -1,7 +1,7 @@ -from ldap3 import Server, Connection +from ldap3 import Server, Connection, ASYNC from datetime import datetime, timedelta import binascii -import nsls2api.infrastructure.loggging as logger +from nsls2api.infrastructure.logging import logger def to_hex(val): @@ -16,18 +16,23 @@ def get_user_info(upn, ldap_server, base_dn, bind_user, bind_password): conn = Connection(server, user=bind_user, password=bind_password, auto_bind=True) search_filter = f"(&(objectclass=person)(userPrincipalName={upn}))" conn.search(base_dn, search_filter, attributes=['sAMAccountName']) + if not conn.entries: logger.warning("No entries found for the given UPN.") return None + entry = conn.entries[0] username = entry.sAMAccountName.value if 'sAMAccountName' in entry else None if username is None: return None + search_filter = f"(&(objectclass=posixaccount)(sAMAccountName={username}))" conn.search(base_dn, search_filter, attributes=['*']) + if not conn.entries: logger.warning("no posix entries found for the given username.") return None + entry = conn.entries[0] user = dict() for attribute in entry.entry_attributes: