(challenge_fn, allow_cc_users=False, api_key=False,
                        allow_sessions=True, require_domain=True)
return _outer
Ensure someone is logged in, or issue a challenge / failure.

    challenge_fn: a decorator function that takes in a view and returns a wrapped version of that
      view with additional "challenges" applied - namely checking authentication.
      If the "challenges" are met the decorator function should:
        1. Add a ".user" property to the request object.
        2. Call the decorated view
      If the "challenges" are not met, the decorator function should either return an
      HttpUnauthorized response, or a response allowing the caller to provide additional
      authentication details.
    allow_cc_users: authorize non-WebUser users
    allow_sessions: allow session based authorization
    require_domain: whether domain checks should be used/assumed in API request
Ensure someone is logged in, or issue a challenge / failure.
Ensure someone is logged in or issue a challenge / failure .
def _login_or_challenge(challenge_fn, allow_cc_users=False, api_key=False,
                        allow_sessions=True, require_domain=True):
    """
    Ensure someone is logged in, or issue a challenge / failure.

    challenge_fn: a decorator function that takes in a view and returns a wrapped version of that
      view with additional "challenges" applied - namely checking authentication.
      If the "challenges" are met the decorator function should:
        1. Add a ".user" property to the request object.
        2. Call the decorated view
      If the "challenges" are not met, the decorator function should either return an
      HttpUnauthorized response, or a response allowing the caller to provide additional
      authentication details.
    allow_cc_users: authorize non-WebUser users
    allow_sessions: allow session based authorization
    require_domain: whether domain checks should be used/assumed in API request
    """
    def _outer(fn):
        if require_domain:
            @wraps(fn)
            def safe_fn_with_domain(request, domain, *args, **kwargs):
                if request.user.is_authenticated and allow_sessions:
                    return login_and_domain_required(fn)(request, domain, *args, **kwargs)
                else:
                    # if sessions are blocked or user is not already authenticated, check for authentication
                    @check_lockout
                    @challenge_fn
                    @two_factor_check(fn, api_key)
                    def _inner(request, domain, *args, **kwargs):
                        couch_user = _ensure_request_couch_user(request)
                        if (
                            couch_user
                            and (allow_cc_users or couch_user.is_web_user())
                            and couch_user.is_member_of(domain, allow_enterprise=True)
                        ):
                            clear_login_attempts(couch_user)
                            return fn(request, domain, *args, **kwargs)
                        else:
                            return HttpResponseForbidden()

                    return _inner(request, domain, *args, **kwargs)

            return safe_fn_with_domain
        else:
            # basically a mirror of the above implementation but for a request without a domain
            @wraps(fn)
            def safe_fn_no_domain(request, *args, **kwargs):
                if request.user.is_authenticated and allow_sessions:
                    # replaces login_and_domain_required
                    return login_required(fn)(request, *args, **kwargs)
                else:
                    # two_factor_check is removed because 2fa enforcement
                    # only happens in the context of a domain
                    @check_lockout
                    @challenge_fn
                    def _inner(request, *args, **kwargs):
                        couch_user = _ensure_request_couch_user(request)
                        if (
                            couch_user
                            and (allow_cc_users or couch_user.is_web_user())
                        ):
                            clear_login_attempts(couch_user)
                            return fn(request, *args, **kwargs)
                        else:
                            return HttpResponseForbidden()

                    return _inner(request, *args, **kwargs)
            return safe_fn_no_domain

    return _outer
def _login_or_challenge ( challenge_fn , allow_cc_users = False , api_key = False , allow_sessions = True , require_domain = True ) : def _outer ( fn ) : if require_domain : @ wraps ( fn ) def safe_fn_with_domain ( request , domain , * args , * * kwargs ) : if request . user . is_authenticated and allow_sessions : return login_and_domain_required ( fn ) ( request , domain , * args , * * kwargs ) else : # if sessions are blocked or user is not already authenticated, check for authentication @ check_lockout @ challenge_fn @ two_factor_check ( fn , api_key ) def _inner ( request , domain , * args , * * kwargs ) : couch_user = _ensure_request_couch_user ( request ) if ( couch_user and ( allow_cc_users or couch_user . is_web_user ( ) ) and couch_user . is_member_of ( domain , allow_enterprise = True ) ) : clear_login_attempts ( couch_user ) return fn ( request , domain , * args , * * kwargs ) else : return HttpResponseForbidden ( ) return _inner ( request , domain , * args , * * kwargs ) return safe_fn_with_domain else : # basically a mirror of the above implementation but for a request without a domain @ wraps ( fn ) def safe_fn_no_domain ( request , * args , * * kwargs ) : if request . user . is_authenticated and allow_sessions : # replaces login_and_domain_required return login_required ( fn ) ( request , * args , * * kwargs ) else : # two_factor_check is removed because 2fa enforcement # only happens in the context of a domain @ check_lockout @ challenge_fn def _inner ( request , * args , * * kwargs ) : couch_user = _ensure_request_couch_user ( request ) if ( couch_user and ( allow_cc_users or couch_user . is_web_user ( ) ) ) : clear_login_attempts ( couch_user ) return fn ( request , * args , * * kwargs ) else : return HttpResponseForbidden ( ) return _inner ( request , * args , * * kwargs ) return safe_fn_no_domain return _outer