Verified Commit 29dbaecd authored by Jakob Moser's avatar Jakob Moser
Browse files

Try implementing LDAP-based login logic

parent 3ff1a28d
Loading
Loading
Loading
Loading
+33 −0
Changes for portal/model/LdapDirectory.py: 33 added lines, 0 removed lines.
Original line number Diff line number Diff line
from functools import cache

from sqlalchemy.orm import Mapped
from typing import Any, Self

from ldap import Directory
from portal.model.Base import Base


class LdapDirectory(Base):
    url: Mapped[str]
    base_dn: Mapped[str]

    @property
    @cache
    def __directory_delegate(self) -> Directory:
        return Directory(self.url, self.base_dn)

    def is_valid(self, username: str, password: str) -> bool:
        return self.__directory_delegate.is_valid(username, password)

    @classmethod
    def get_the_one(cls) -> Self:
        instances = cls.get_all()
        if len(instances) != 1:
            raise ValueError(
                f"Expected there to be exactly 1 instance of {cls.__name__}, but there were {len(instances)}"
            )

        return instances[0]

    def to_dict(self) -> dict[str, Any]:
        return {"uuid": self.uuid, "url": self.url, "baseDn": self.base_dn}
+15 −1
Changes for portal/model/User.py: 15 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ from sqlalchemy.orm import Mapped, mapped_column

from portal import db
from portal.model.Base import Base
from portal.model.LdapDirectory import LdapDirectory


class User(Base):
@@ -15,7 +16,20 @@ class User(Base):

        :return: A "User" instance, if successful. None, otherwise.
        """
        return None  # TODO
        directory = LdapDirectory.get_the_one()
        if not directory.is_valid(name, password):
            return False

        # There exists a user with that name and password. Let's see if they are already in the database:
        user = cls.get_by_name(name)
        if not user:
            # If not, create them and then return them
            user = cls()
            user.name = name
            db.session.add(user)
            db.session.commit()

        return user

    @classmethod
    def get_by_name(cls, name: str) -> Optional[Self]:
+1 −0
Changes for portal/model/__init__.py: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -5,5 +5,6 @@ from .Retrievable import Retrievable
from .User import User
from .Uuid import Uuid
from .Key import Key
from .LdapDirectory import LdapDirectory
from .UtcDateTime import UtcDateTime
from .TaigaUserStoryProvider import TaigaUserStoryProvider