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
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)
def __init__(self, xom): self.realm = "pypi" self.auth = Auth(xom.model, xom.config.secret) self.hook = xom.config.hook
def __init__(self, xom): self.realm = "pypi" self.auth = Auth(xom.model, xom.config.secret)
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