Esempio n. 1
0
class DevpiAuthenticationPolicy(CallbackAuthenticationPolicy):
    def __init__(self, xom):
        self.realm = "pypi"
        self.auth = Auth(xom.model, xom.config.secret)
        self.hook = xom.config.hook

    def unauthenticated_userid(self, request):
        """ The userid parsed from the ``Authorization`` request header."""
        credentials = self._get_credentials(request)
        if credentials:
            return credentials[0]

    def remember(self, request, principal, **kw):
        """ A no-op. Devpi authentication does not provide a protocol for
        remembering the user. Credentials are sent on every request.
        """
        return []

    def forget(self, request):
        """ Returns challenge headers. This should be attached to a response
        to indicate that credentials are required."""
        return [('WWW-Authenticate', 'Basic realm="%s"' % self.realm)]

    def callback(self, username, request):
        # Username arg is ignored.  Unfortunately _get_credentials winds up
        # getting called twice when authenticated_userid is called.  Avoiding
        # that, however, winds up duplicating logic from the superclass.
        credentials = self._get_credentials(request)
        if credentials:
            status, auth_user, groups = self.auth.get_auth_status(credentials)
            request.log.debug("got auth status %r for user %r" %
                              (status, auth_user))
            if status == "ok":
                return [":%s" % g for g in groups]
            elif status == "reject":
                abort_authenticate(
                    request,
                    msg="credentials for user '%s' were rejected" % auth_user)
            elif status == "nouser":
                abort_authenticate(request,
                                   msg="user '%s' does not exist" % auth_user)
            elif status == "expired":
                abort_authenticate(request,
                                   msg="auth expired for '%s'" % auth_user)
            raise ValueError("Unknown authentication status: %s" % status)

    def _get_credentials(self, request):
        return self.hook.devpiserver_get_credentials(request=request)

    def verify_credentials(self, request):
        credentials = self._get_credentials(request)
        if credentials:
            status = self.auth._validate(*credentials)
            if status.get("status") == "ok":
                return True
        return False
Esempio n. 2
0
class DevpiAuthenticationPolicy(CallbackAuthenticationPolicy):
    def __init__(self, xom):
        self.realm = "pypi"
        self.auth = Auth(xom.model, xom.config.secret)
        self.hook = xom.config.hook

    def unauthenticated_userid(self, request):
        """ The userid parsed from the ``Authorization`` request header."""
        credentials = self._get_credentials(request)
        if credentials:
            return credentials[0]

    def remember(self, request, principal, **kw):
        """ A no-op. Devpi authentication does not provide a protocol for
        remembering the user. Credentials are sent on every request.
        """
        return []

    def forget(self, request):
        """ Returns challenge headers. This should be attached to a response
        to indicate that credentials are required."""
        return [("WWW-Authenticate", 'Basic realm="%s"' % self.realm)]

    def callback(self, username, request):
        # Username arg is ignored.  Unfortunately _get_credentials winds up
        # getting called twice when authenticated_userid is called.  Avoiding
        # that, however, winds up duplicating logic from the superclass.
        credentials = self._get_credentials(request)
        if credentials:
            status, auth_user, groups = self.auth.get_auth_status(credentials)
            request.log.debug("got auth status %r for user %r" % (status, auth_user))
            if status == "ok":
                return [":%s" % g for g in groups]
            elif status == "nouser":
                abort(request, 404, "user %r does not exist" % auth_user)
            elif status == "expired":
                abort_authenticate(request, msg="auth expired for %r" % auth_user)
            raise ValueError("Unknown authentication status: %s" % status)

    def _get_credentials(self, request):
        return self.hook.devpiserver_get_credentials(request=request)
Esempio n. 3
0
 def __init__(self, xom):
     self.realm = "pypi"
     self.auth = Auth(xom.model, xom.config.secret)
     self.hook = xom.config.hook
Esempio n. 4
0
 def __init__(self, xom):
     self.realm = "pypi"
     self.auth = Auth(xom.model, xom.config.secret)
Esempio n. 5
0
class DevpiAuthenticationPolicy(CallbackAuthenticationPolicy):
    def __init__(self, xom):
        self.realm = "pypi"
        self.auth = Auth(xom.model, xom.config.secret)

    def unauthenticated_userid(self, request):
        """ The userid parsed from the ``Authorization`` request header."""
        credentials = self._get_credentials(request)
        if credentials:
            return credentials[0]

    def remember(self, request, principal, **kw):
        """ A no-op. Devpi authentication does not provide a protocol for
        remembering the user. Credentials are sent on every request.
        """
        return []

    def forget(self, request):
        """ Returns challenge headers. This should be attached to a response
        to indicate that credentials are required."""
        return [('WWW-Authenticate', 'Basic realm="%s"' % self.realm)]

    def callback(self, username, request):
        # Username arg is ignored.  Unfortunately _get_credentials winds up
        # getting called twice when authenticated_userid is called.  Avoiding
        # that, however, winds up duplicating logic from the superclass.
        credentials = self._get_credentials(request)
        if credentials:
            status, auth_user = self.auth.get_auth_status(credentials)
            request.log.debug("got auth status %r for user %r" % (status, auth_user))
            if status == "ok":
                return []
            elif status == "nouser":
                abort(request, 404, "user %r does not exist" % auth_user)
            elif status == "expired":
                abort_authenticate(request, msg="auth expired for %r" % auth_user)
            raise ValueError("Unknown authentication status: %s" % status)

    def _get_credentials(self, request):
        authorization = request.headers.get('X-Devpi-Auth')
        if not authorization:
            # support basic authentication for setup.py upload/register
            authorization = request.headers.get('Authorization')
            if not authorization:
                return None
            try:
                authmeth, auth = authorization.split(' ', 1)
            except ValueError: # not enough values to unpack
                return None
            if authmeth.lower() != 'basic':
                return None
        else:
            auth = authorization

        try:
            authbytes = b64decode(auth.strip())
        except (TypeError, binascii.Error):  # can't decode
            return None

        # try utf-8 first, then latin-1; see discussion in
        # https://github.com/Pylons/pyramid/issues/898
        try:
            auth = authbytes.decode('utf-8')
        except UnicodeDecodeError:
            auth = authbytes.decode('latin-1')

        try:
            username, password = auth.split(':', 1)
        except ValueError:  # not enough values to unpack
            return None
        return username, password
Esempio n. 6
0
class DevpiAuthenticationPolicy(CallbackAuthenticationPolicy):
    def __init__(self, xom):
        self.realm = "pypi"
        self.auth = Auth(xom.model, xom.config.secret)

    def unauthenticated_userid(self, request):
        """ The userid parsed from the ``Authorization`` request header."""
        credentials = self._get_credentials(request)
        if credentials:
            return credentials[0]

    def remember(self, request, principal, **kw):
        """ A no-op. Devpi authentication does not provide a protocol for
        remembering the user. Credentials are sent on every request.
        """
        return []

    def forget(self, request):
        """ Returns challenge headers. This should be attached to a response
        to indicate that credentials are required."""
        return [('WWW-Authenticate', 'Basic realm="%s"' % self.realm)]

    def callback(self, username, request):
        # Username arg is ignored.  Unfortunately _get_credentials winds up
        # getting called twice when authenticated_userid is called.  Avoiding
        # that, however, winds up duplicating logic from the superclass.
        credentials = self._get_credentials(request)
        if credentials:
            status, auth_user = self.auth.get_auth_status(credentials)
            request.log.debug("got auth status %r for user %r" %
                              (status, auth_user))
            if status == "ok":
                return []
            elif status == "nouser":
                abort(request, 404, "user %r does not exist" % auth_user)
            elif status == "expired":
                abort_authenticate(request,
                                   msg="auth expired for %r" % auth_user)
            raise ValueError("Unknown authentication status: %s" % status)

    def _get_credentials(self, request):
        authorization = request.headers.get('X-Devpi-Auth')
        if not authorization:
            # support basic authentication for setup.py upload/register
            authorization = request.headers.get('Authorization')
            if not authorization:
                return None
            try:
                authmeth, auth = authorization.split(' ', 1)
            except ValueError:  # not enough values to unpack
                return None
            if authmeth.lower() != 'basic':
                return None
        else:
            auth = authorization

        try:
            authbytes = b64decode(auth.strip())
        except (TypeError, binascii.Error):  # can't decode
            return None

        # try utf-8 first, then latin-1; see discussion in
        # https://github.com/Pylons/pyramid/issues/898
        try:
            auth = authbytes.decode('utf-8')
        except UnicodeDecodeError:
            auth = authbytes.decode('latin-1')

        try:
            username, password = auth.split(':', 1)
        except ValueError:  # not enough values to unpack
            return None
        return username, password