diff --git a/freenit/api/user.py b/freenit/api/user.py index b2e1503..df5782a 100644 --- a/freenit/api/user.py +++ b/freenit/api/user.py @@ -28,37 +28,9 @@ async def get( if User.dbtype() == "ormar": return await paginate(User.objects, page, perpage) elif User.dbtype() == "bonsai": - import bonsai - - from freenit.models.ldap.base import get_client - - client = get_client() - try: - async with client.connect(is_async=True) as conn: - res = await conn.search( - f"dc=account,dc=ldap", - bonsai.LDAPSearchScope.SUB, - "objectClass=person", - ) - except bonsai.errors.AuthenticationError: - raise HTTPException(status_code=403, detail="Failed to login") - - data = [] - for udata in res: - email = udata.get("mail", None) - if email is None: - continue - user = User( - email=email[0], - sn=udata["sn"][0], - cn=udata["cn"][0], - dn=str(udata["dn"]), - uid=udata["uid"][0], - ) - data.append(user) - - total = len(res) - page = Page(total=total, page=1, pages=1, perpage=total, data=data) + users = await User.get_all() + total = len(users) + page = Page(total=total, page=1, pages=1, perpage=total, data=users) return page raise HTTPException(status_code=409, detail="Unknown user type") diff --git a/freenit/auth.py b/freenit/auth.py index c3e7a75..1ee9f18 100644 --- a/freenit/auth.py +++ b/freenit/auth.py @@ -25,7 +25,7 @@ async def decode(token): except ormar.exceptions.NoMatch: raise HTTPException(status_code=403, detail="Unauthorized") elif User.dbtype() == "bonsai": - user = User.get(pk) + user = await User.get(pk) return user raise HTTPException(status_code=409, detail="Unknown user type") diff --git a/freenit/models/ldap/role.py b/freenit/models/ldap/role.py index fbd4e32..2fe0b82 100644 --- a/freenit/models/ldap/role.py +++ b/freenit/models/ldap/role.py @@ -10,7 +10,7 @@ class Role(LDAPBaseModel): cn: str = Field("", description=("Common name")) - uniqueMembers: list = Field([], description=("Group members")) + uniqueMembers: list = Field([], description=("Role members")) @classmethod async def get(cls, dn): diff --git a/freenit/models/ldap/user.py b/freenit/models/ldap/user.py index cd709b9..9c260f0 100644 --- a/freenit/models/ldap/user.py +++ b/freenit/models/ldap/user.py @@ -1,6 +1,7 @@ from __future__ import annotations from bonsai import LDAPEntry, LDAPModOp, LDAPSearchScope, errors +from fastapi import HTTPException from pydantic import EmailStr, Field from freenit.config import getConfig @@ -15,6 +16,7 @@ class UserSafe(LDAPBaseModel, LDAPUserMixin): cn: str = Field("", description=("Common name")) sn: str = Field("", description=("Surname")) userClass: str = Field("", description=("User class")) + roles: list = Field([], description=("Roles the user is a member of")) class User(UserSafe): @@ -25,13 +27,18 @@ async def get(cls, dn): client = get_client() try: async with client.connect(is_async=True) as conn: - res = await conn.search(dn, LDAPSearchScope.BASE, "objectClass=person") + res = await conn.search( + dn, LDAPSearchScope.BASE, + "objectClass=person", + ["*", "memberOf"], + ) except errors.AuthenticationError: raise HTTPException(status_code=403, detail="Failed to login") if len(res) < 1: raise HTTPException(status_code=404, detail="No such user") if len(res) > 1: raise HTTPException(status_code=409, detail="Multiple users found") + print(res) data = res[0] user = cls( email=data["mail"][0], @@ -40,6 +47,7 @@ async def get(cls, dn): dn=str(data["dn"]), uid=data["uid"][0], userClass=data["userClass"][0], + roles=data["memberOf"], ) return user @@ -73,6 +81,37 @@ async def update(self, active=False, **kwargs): for field in kwargs: setattr(self, field, kwargs[field]) + @classmethod + async def get_all(cls): + client = get_client() + try: + async with client.connect(is_async=True) as conn: + res = await conn.search( + f"dc=account,dc=ldap", + LDAPSearchScope.SUB, + "objectClass=person", + ["*", "memberOf"], + ) + except errors.AuthenticationError: + raise HTTPException(status_code=403, detail="Failed to login") + + data = [] + for udata in res: + email = udata.get("mail", None) + if email is None: + continue + user = cls( + email=email[0], + sn=udata["sn"][0], + cn=udata["cn"][0], + dn=str(udata["dn"]), + uid=udata["uid"][0], + userClass=udata["userClass"][0], + roles=data["memberOf"], + ) + data.append(user) + return data + class UserOptional(User): pass