Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
flockwave-server / server / model / authentication.py
Size: Mime:
from abc import ABC, abstractmethod
from dataclasses import dataclass
from enum import Enum
from typing import Optional

from .client import Client


class AuthenticationResultType(Enum):
    FAILURE = "failure"
    SUCCESS = "success"
    CHALLENGE = "challenge"


@dataclass
class AuthenticationResult:
    type: AuthenticationResultType
    data: Optional[str] = None
    reason: Optional[str] = None
    user: Optional[str] = None

    @classmethod
    def challenge(cls, data):
        return cls(type=AuthenticationResultType.CHALLENGE, data=data)

    @classmethod
    def success(cls, user):
        return cls(type=AuthenticationResultType.SUCCESS, user=user)

    @classmethod
    def failure(cls, reason=None):
        return cls(type=AuthenticationResultType.FAILURE, reason=reason)

    @property
    def json(self):
        """Converts the response into its JSON representation."""
        if self.type is AuthenticationResultType.SUCCESS:
            if self.user is None:
                raise ValueError("successful authentication responses need a username")
            result = {"result": True, "user": str(self.user)}
        elif self.type is AuthenticationResultType.FAILURE:
            result = {"result": False, "reason": self.reason or "Authentication failed"}
        else:
            if self.data is None:
                raise ValueError("authentication challenges need a data member")
            result = {"data": str(self.data)}
        result["type"] = "AUTH-RESP"
        return result

    @property
    def successful(self):
        """Returns whether the response represents a successful authentication
        attempt.
        """
        return self.type is AuthenticationResultType.SUCCESS and self.user is not None


class AuthenticationMethod(ABC):
    """Interface specification for authentication methods."""

    @property
    @abstractmethod
    def id(self):
        """Identifier of the authentication method with which it will be
        registered in the server.
        """
        raise NotImplementedError

    @abstractmethod
    def authenticate(self, client: Client, data: str) -> AuthenticationResult:
        """Handles an authentication request from a client.

        Parameters:
            client: the client that sent the authentication request
            data: the data that was sent in this request

        Returns:
            response to the authentication request
        """
        raise NotImplementedError

    def cancel(self, client: Client) -> None:  # noqa: B027
        """Cancels the current authentication session of the given client.

        This method is relevant only for multi-step authentication methods.

        Parameters:
            client: the client whose authentication attempt is cancelled
        """
        pass