Wraps authentication logic, verify_user through to the authentication function.

    The verify_user function passed in should accept an API key and return a user object to
    store in the request context if authentication succeeded.

def authenticator(function, challenges=()):
    """Wraps authentication logic, verify_user through to the authentication function.

    The verify_user function passed in should accept an API key and return a user object to
    store in the request context if authentication succeeded.
    """
    challenges = challenges or ('{} realm="simple"'.format(function.__name__), )

    def wrapper(verify_user):
        def authenticate(request, response, **kwargs):
            result = function(request, response, verify_user, **kwargs)

            def authenticator_name():
                try:
                    return function.__doc__.splitlines()[0]
                except AttributeError:
                    return function.__name__

            if result is None:
                raise HTTPUnauthorized('Authentication Required',
                                       'Please provide valid {0} credentials'.format(authenticator_name()),
                                       challenges=challenges)

            if result is False:
                raise HTTPUnauthorized('Invalid Authentication',
                                       'Provided {0} credentials were invalid'.format(authenticator_name()),
                                       challenges=challenges)

            request.context['user'] = result
            return True

        authenticate.__doc__ = function.__doc__
        return authenticate

    return wrapper