Example #1
0
    def test_is_contact_active_for_user(self):
        self.assertTrue(is_contact_active(self.domain, "CommCareUser", self.user.get_id))

        self.user.is_active = False
        self.user.save()
        self.assertFalse(is_contact_active(self.domain, "CommCareUser", self.user.get_id))

        self.user.is_active = True
        self.user.save()
        self.assertTrue(is_contact_active(self.domain, "CommCareUser", self.user.get_id))
    def test_is_contact_active_for_user(self):
        self.assertTrue(is_contact_active(self.domain, 'CommCareUser', self.user.get_id))

        self.user.is_active = False
        self.user.save()
        self.assertFalse(is_contact_active(self.domain, 'CommCareUser', self.user.get_id))

        self.user.is_active = True
        self.user.save()
        self.assertTrue(is_contact_active(self.domain, 'CommCareUser', self.user.get_id))
Example #3
0
def process_incoming(msg):
    v = PhoneNumber.by_phone(msg.phone_number, include_pending=True)

    if v:
        msg.couch_recipient_doc_type = v.owner_doc_type
        msg.couch_recipient = v.owner_id
        msg.domain = v.domain
        msg.location_id = get_location_id_by_verified_number(v)
        msg.save()
    elif msg.domain_scope:
        msg.domain = msg.domain_scope
        msg.save()

    can_receive_sms = PhoneBlacklist.can_receive_sms(msg.phone_number)
    opt_in_keywords, opt_out_keywords = get_opt_keywords(msg)
    domain = v.domain if v else None

    if is_opt_message(msg.text, opt_out_keywords) and can_receive_sms:
        if PhoneBlacklist.opt_out_sms(msg.phone_number, domain=domain):
            metadata = MessageMetadata(ignore_opt_out=True)
            text = get_message(MSG_OPTED_OUT, v, context=(opt_in_keywords[0],))
            if v:
                send_sms_to_verified_number(v, text, metadata=metadata)
            else:
                send_sms(msg.domain, None, msg.phone_number, text, metadata=metadata)
    elif is_opt_message(msg.text, opt_in_keywords) and not can_receive_sms:
        if PhoneBlacklist.opt_in_sms(msg.phone_number, domain=domain):
            text = get_message(MSG_OPTED_IN, v, context=(opt_out_keywords[0],))
            if v:
                send_sms_to_verified_number(v, text)
            else:
                send_sms(msg.domain, None, msg.phone_number, text)
    else:
        handled = False
        is_verified = v is not None and v.verified

        if msg.domain and domain_has_privilege(msg.domain, privileges.INBOUND_SMS):
            handled = load_and_call(settings.CUSTOM_SMS_HANDLERS, v, msg.text, msg)

            if not handled and is_verified and is_contact_active(v.domain, v.owner_doc_type, v.owner_id):
                handled = load_and_call(settings.SMS_HANDLERS, v, msg.text, msg)

        if not handled and not is_verified:
            handled = process_pre_registration(msg)

            if not handled:
                handled = process_sms_registration(msg)

            if not handled:
                import verify
                verify.process_verification(v, msg)

    # If the sms queue is enabled, then the billable gets created in remove_from_queue()
    if (
        not settings.SMS_QUEUE_ENABLED and
        msg.domain and
        domain_has_privilege(msg.domain, privileges.INBOUND_SMS)
    ):
        create_billable_for_sms(msg)
Example #4
0
def process_incoming(msg):
    v = PhoneNumber.by_phone(msg.phone_number, include_pending=True)

    if v is not None and v.verified:
        msg.couch_recipient_doc_type = v.owner_doc_type
        msg.couch_recipient = v.owner_id
        msg.domain = v.domain
        msg.location_id = get_location_id_by_verified_number(v)
        msg.save()

    if msg.domain_scope:
        # only process messages for phones known to be associated with this domain
        if v is None or v.domain != msg.domain_scope:
            raise DomainScopeValidationError(
                'Attempted to simulate incoming sms from phone number not ' \
                'verified with this domain'
            )

    can_receive_sms = PhoneBlacklist.can_receive_sms(msg.phone_number)
    opt_in_keywords, opt_out_keywords = get_opt_keywords(msg)
    domain = v.domain if v else None

    if is_opt_message(msg.text, opt_out_keywords) and can_receive_sms:
        if PhoneBlacklist.opt_out_sms(msg.phone_number, domain=domain):
            metadata = MessageMetadata(ignore_opt_out=True)
            text = get_message(MSG_OPTED_OUT, v, context=(opt_in_keywords[0],))
            if v:
                send_sms_to_verified_number(v, text, metadata=metadata)
            else:
                send_sms(msg.domain, None, msg.phone_number, text, metadata=metadata)
    elif is_opt_message(msg.text, opt_in_keywords) and not can_receive_sms:
        if PhoneBlacklist.opt_in_sms(msg.phone_number, domain=domain):
            text = get_message(MSG_OPTED_IN, v, context=(opt_out_keywords[0],))
            if v:
                send_sms_to_verified_number(v, text)
            else:
                send_sms(msg.domain, None, msg.phone_number, text)
    elif v is not None and v.verified:
        if (
            domain_has_privilege(msg.domain, privileges.INBOUND_SMS) and
            is_contact_active(v.domain, v.owner_doc_type, v.owner_id)
        ):
            for h in settings.SMS_HANDLERS:
                try:
                    handler = to_function(h)
                except:
                    notify_exception(None, message=('error loading sms handler: %s' % h))
                    continue

                try:
                    was_handled = handler(v, msg.text, msg=msg)
                except Exception, e:
                    log_sms_exception(msg)
                    was_handled = False

                if was_handled:
                    break
Example #5
0
def process_incoming(msg):
    sms_load_counter("inbound", msg.domain)()
    v, has_domain_two_way_scope = get_inbound_phone_entry(msg)

    if v:
        if any_migrations_in_progress(v.domain):
            raise DelayProcessing()

        msg.couch_recipient_doc_type = v.owner_doc_type
        msg.couch_recipient = v.owner_id
        msg.domain = v.domain
        msg.location_id = get_location_id_by_verified_number(v)
        msg.save()
    elif msg.domain_scope:
        if any_migrations_in_progress(msg.domain_scope):
            raise DelayProcessing()

        msg.domain = msg.domain_scope
        msg.save()

    opt_in_keywords, opt_out_keywords, pass_through_opt_in_keywords = get_opt_keywords(
        msg)
    domain = v.domain if v else None

    if is_opt_message(msg.text, opt_out_keywords):
        if PhoneBlacklist.opt_out_sms(msg.phone_number, domain=domain):
            metadata = MessageMetadata(ignore_opt_out=True)
            text = get_message(MSG_OPTED_OUT,
                               v,
                               context=(opt_in_keywords[0], ))
            if v:
                send_sms_to_verified_number(v, text, metadata=metadata)
            elif msg.backend_id:
                send_sms_with_backend(msg.domain,
                                      msg.phone_number,
                                      text,
                                      msg.backend_id,
                                      metadata=metadata)
            else:
                send_sms(msg.domain,
                         None,
                         msg.phone_number,
                         text,
                         metadata=metadata)
    elif is_opt_message(msg.text, opt_in_keywords):
        if PhoneBlacklist.opt_in_sms(msg.phone_number, domain=domain):
            text = get_message(MSG_OPTED_IN,
                               v,
                               context=(opt_out_keywords[0], ))
            if v:
                send_sms_to_verified_number(v, text)
            elif msg.backend_id:
                send_sms_with_backend(msg.domain, msg.phone_number, text,
                                      msg.backend_id)
            else:
                send_sms(msg.domain, None, msg.phone_number, text)
    else:
        if is_opt_message(msg.text, pass_through_opt_in_keywords):
            # Opt the phone number in, and then process the message normally
            PhoneBlacklist.opt_in_sms(msg.phone_number, domain=domain)

        handled = False
        is_two_way = v is not None and v.is_two_way

        if msg.domain and domain_has_privilege(msg.domain,
                                               privileges.INBOUND_SMS):
            if v and v.pending_verification:
                from . import verify
                handled = verify.process_verification(
                    v,
                    msg,
                    create_subevent_for_inbound=not has_domain_two_way_scope)

            if ((is_two_way or has_domain_two_way_scope) and is_contact_active(
                    v.domain, v.owner_doc_type, v.owner_id)):
                handled = load_and_call(settings.SMS_HANDLERS, v, msg.text,
                                        msg)

        if not handled and not is_two_way:
            handled = process_pre_registration(msg)

            if not handled:
                handled = process_sms_registration(msg)

    # If the sms queue is enabled, then the billable gets created in remove_from_queue()
    if (not settings.SMS_QUEUE_ENABLED and msg.domain
            and domain_has_privilege(msg.domain, privileges.INBOUND_SMS)):
        create_billable_for_sms(msg)
Example #6
0
def process_sms(queued_sms_pk):
    """
    queued_sms_pk - pk of a QueuedSMS entry
    """
    utcnow = get_utcnow()
    # Prevent more than one task from processing this SMS, just in case
    # the message got enqueued twice.
    message_lock = get_lock("sms-queue-processing-%s" % queued_sms_pk)

    if message_lock.acquire(blocking=False):
        try:
            msg = QueuedSMS.objects.get(pk=queued_sms_pk)
        except QueuedSMS.DoesNotExist:
            # The message was already processed and removed from the queue
            release_lock(message_lock, True)
            return

        if message_is_stale(msg, utcnow):
            msg.set_system_error(SMS.ERROR_MESSAGE_IS_STALE)
            remove_from_queue(msg)
            release_lock(message_lock, True)
            return

        outbound_counter = None
        if msg.direction == OUTGOING:
            domain_object = Domain.get_by_name(
                msg.domain) if msg.domain else None

            if domain_object and handle_domain_specific_delays(
                    msg, domain_object, utcnow):
                release_lock(message_lock, True)
                return

            outbound_counter = OutboundDailyCounter(domain_object)
            if not outbound_counter.can_send_outbound_sms(msg):
                release_lock(message_lock, True)
                return

        requeue = False
        # Process inbound SMS from a single contact one at a time
        recipient_block = msg.direction == INCOMING

        # We check datetime_to_process against utcnow plus a small amount
        # of time because timestamps can differ between machines which
        # can cause us to miss sending the message the first time and
        # result in an unnecessary delay.
        if (isinstance(msg.processed, bool) and not msg.processed
                and not msg.error and msg.datetime_to_process <
            (utcnow + timedelta(seconds=10))):
            if recipient_block:
                recipient_lock = get_lock("sms-queue-recipient-phone-%s" %
                                          msg.phone_number)
                recipient_lock.acquire(blocking=True)

            if msg.direction == OUTGOING:
                if (msg.domain and msg.couch_recipient_doc_type
                        and msg.couch_recipient and not is_contact_active(
                            msg.domain, msg.couch_recipient_doc_type,
                            msg.couch_recipient)):
                    msg.set_system_error(SMS.ERROR_CONTACT_IS_INACTIVE)
                    remove_from_queue(msg)
                else:
                    requeue = handle_outgoing(msg)
            elif msg.direction == INCOMING:
                try:
                    handle_incoming(msg)
                except DelayProcessing:
                    process_sms.apply_async([queued_sms_pk], countdown=60)
                    if recipient_block:
                        release_lock(recipient_lock, True)
                    release_lock(message_lock, True)
            else:
                msg.set_system_error(SMS.ERROR_INVALID_DIRECTION)
                remove_from_queue(msg)

            if recipient_block:
                release_lock(recipient_lock, True)

        release_lock(message_lock, True)
        if requeue:
            if outbound_counter:
                outbound_counter.decrement()
            send_to_sms_queue(msg)
Example #7
0
def process_sms(queued_sms_pk):
    """
    queued_sms_pk - pk of a QueuedSMS entry
    """
    client = get_redis_client()
    utcnow = get_utcnow()
    # Prevent more than one task from processing this SMS, just in case
    # the message got enqueued twice.
    message_lock = get_lock(client, "sms-queue-processing-%s" % queued_sms_pk)

    if message_lock.acquire(blocking=False):
        try:
            msg = QueuedSMS.objects.get(pk=queued_sms_pk)
        except QueuedSMS.DoesNotExist:
            # The message was already processed and removed from the queue
            release_lock(message_lock, True)
            return

        if message_is_stale(msg, utcnow):
            msg.set_system_error(SMS.ERROR_MESSAGE_IS_STALE)
            remove_from_queue(msg)
            release_lock(message_lock, True)
            return

        if msg.direction == OUTGOING:
            if msg.domain:
                domain_object = Domain.get_by_name(msg.domain)
            else:
                domain_object = None
            if domain_object and handle_domain_specific_delays(
                    msg, domain_object, utcnow):
                release_lock(message_lock, True)
                return

        requeue = False
        # Process inbound SMS from a single contact one at a time
        recipient_block = msg.direction == INCOMING
        if (isinstance(msg.processed, bool) and not msg.processed
                and not msg.error and msg.datetime_to_process < utcnow):
            if recipient_block:
                recipient_lock = get_lock(
                    client, "sms-queue-recipient-phone-%s" % msg.phone_number)
                recipient_lock.acquire(blocking=True)

            if msg.direction == OUTGOING:
                if (msg.domain and msg.couch_recipient_doc_type
                        and msg.couch_recipient and not is_contact_active(
                            msg.domain, msg.couch_recipient_doc_type,
                            msg.couch_recipient)):
                    msg.set_system_error(SMS.ERROR_CONTACT_IS_INACTIVE)
                    remove_from_queue(msg)
                else:
                    requeue = handle_outgoing(msg)
            elif msg.direction == INCOMING:
                handle_incoming(msg)
            else:
                msg.set_system_error(SMS.ERROR_INVALID_DIRECTION)
                remove_from_queue(msg)

            if recipient_block:
                release_lock(recipient_lock, True)

        release_lock(message_lock, True)
        if requeue:
            process_sms.delay(queued_sms_pk)
Example #8
0
 def test_is_contact_active_for_case(self):
     with create_test_case(self.domain, "contact", "test-case") as case:
         self.assertTrue(is_contact_active(self.domain, "CommCareCase", case.case_id))
         update_case(self.domain, case.case_id, close=True)
         self.assertFalse(is_contact_active(self.domain, "CommCareCase", case.case_id))
Example #9
0
def process_incoming(msg):
    v = PhoneNumber.by_phone(msg.phone_number, include_pending=True)

    if v:
        msg.couch_recipient_doc_type = v.owner_doc_type
        msg.couch_recipient = v.owner_id
        msg.domain = v.domain
        msg.location_id = get_location_id_by_verified_number(v)
        msg.save()
    elif msg.domain_scope:
        msg.domain = msg.domain_scope
        msg.save()

    can_receive_sms = PhoneBlacklist.can_receive_sms(msg.phone_number)
    opt_in_keywords, opt_out_keywords = get_opt_keywords(msg)
    domain = v.domain if v else None

    if is_opt_message(msg.text, opt_out_keywords) and can_receive_sms:
        if PhoneBlacklist.opt_out_sms(msg.phone_number, domain=domain):
            metadata = MessageMetadata(ignore_opt_out=True)
            text = get_message(MSG_OPTED_OUT,
                               v,
                               context=(opt_in_keywords[0], ))
            if v:
                send_sms_to_verified_number(v, text, metadata=metadata)
            else:
                send_sms(msg.domain,
                         None,
                         msg.phone_number,
                         text,
                         metadata=metadata)
    elif is_opt_message(msg.text, opt_in_keywords) and not can_receive_sms:
        if PhoneBlacklist.opt_in_sms(msg.phone_number, domain=domain):
            text = get_message(MSG_OPTED_IN,
                               v,
                               context=(opt_out_keywords[0], ))
            if v:
                send_sms_to_verified_number(v, text)
            else:
                send_sms(msg.domain, None, msg.phone_number, text)
    else:
        handled = False
        is_verified = v is not None and v.verified

        if msg.domain and domain_has_privilege(msg.domain,
                                               privileges.INBOUND_SMS):
            handled = load_and_call(settings.CUSTOM_SMS_HANDLERS, v, msg.text,
                                    msg)

            if not handled and is_verified and is_contact_active(
                    v.domain, v.owner_doc_type, v.owner_id):
                handled = load_and_call(settings.SMS_HANDLERS, v, msg.text,
                                        msg)

        if not handled and not is_verified:
            handled = process_pre_registration(msg)

            if not handled:
                handled = process_sms_registration(msg)

            if not handled:
                import verify
                verify.process_verification(v, msg)

    # If the sms queue is enabled, then the billable gets created in remove_from_queue()
    if (not settings.SMS_QUEUE_ENABLED and msg.domain
            and domain_has_privilege(msg.domain, privileges.INBOUND_SMS)):
        create_billable_for_sms(msg)
Example #10
0
def process_sms(queued_sms_pk):
    """
    queued_sms_pk - pk of a QueuedSMS entry
    """
    client = get_redis_client()
    utcnow = get_utcnow()
    # Prevent more than one task from processing this SMS, just in case
    # the message got enqueued twice.
    message_lock = get_lock(client, "sms-queue-processing-%s" % queued_sms_pk)

    if message_lock.acquire(blocking=False):
        try:
            msg = QueuedSMS.objects.get(pk=queued_sms_pk)
        except QueuedSMS.DoesNotExist:
            # The message was already processed and removed from the queue
            release_lock(message_lock, True)
            return

        if message_is_stale(msg, utcnow):
            msg.set_system_error(SMS.ERROR_MESSAGE_IS_STALE)
            remove_from_queue(msg)
            release_lock(message_lock, True)
            return

        if msg.direction == OUTGOING:
            if msg.domain:
                domain_object = Domain.get_by_name(msg.domain)
            else:
                domain_object = None
            if domain_object and handle_domain_specific_delays(msg, domain_object, utcnow):
                release_lock(message_lock, True)
                return

        requeue = False
        # Process inbound SMS from a single contact one at a time
        recipient_block = msg.direction == INCOMING
        if (isinstance(msg.processed, bool)
            and not msg.processed
            and not msg.error
            and msg.datetime_to_process < utcnow):
            if recipient_block:
                recipient_lock = get_lock(client, 
                    "sms-queue-recipient-phone-%s" % msg.phone_number)
                recipient_lock.acquire(blocking=True)

            if msg.direction == OUTGOING:
                if (
                    msg.domain and
                    msg.couch_recipient_doc_type and
                    msg.couch_recipient and
                    not is_contact_active(msg.domain, msg.couch_recipient_doc_type, msg.couch_recipient)
                ):
                    msg.set_system_error(SMS.ERROR_CONTACT_IS_INACTIVE)
                    remove_from_queue(msg)
                else:
                    requeue = handle_outgoing(msg)
            elif msg.direction == INCOMING:
                handle_incoming(msg)
            else:
                msg.set_system_error(SMS.ERROR_INVALID_DIRECTION)
                remove_from_queue(msg)

            if recipient_block:
                release_lock(recipient_lock, True)

        release_lock(message_lock, True)
        if requeue:
            process_sms.delay(queued_sms_pk)
Example #11
0
def process_sms(queued_sms_pk):
    """
    queued_sms_pk - pk of a QueuedSMS entry
    """
    utcnow = get_utcnow()
    # Prevent more than one task from processing this SMS, just in case
    # the message got enqueued twice.
    message_lock = get_lock("sms-queue-processing-%s" % queued_sms_pk)

    if message_lock.acquire(blocking=False):
        try:
            msg = QueuedSMS.objects.get(pk=queued_sms_pk)
        except QueuedSMS.DoesNotExist:
            # The message was already processed and removed from the queue
            release_lock(message_lock, True)
            return

        if message_is_stale(msg, utcnow):
            msg.set_system_error(SMS.ERROR_MESSAGE_IS_STALE)
            remove_from_queue(msg)
            release_lock(message_lock, True)
            return

        outbound_counter = None
        if msg.direction == OUTGOING:
            domain_object = Domain.get_by_name(msg.domain) if msg.domain else None

            if domain_object and handle_domain_specific_delays(msg, domain_object, utcnow):
                release_lock(message_lock, True)
                return

            outbound_counter = OutboundDailyCounter(domain_object)
            if not outbound_counter.can_send_outbound_sms(msg):
                release_lock(message_lock, True)
                return

        requeue = False
        # Process inbound SMS from a single contact one at a time
        recipient_block = msg.direction == INCOMING

        # We check datetime_to_process against utcnow plus a small amount
        # of time because timestamps can differ between machines which
        # can cause us to miss sending the message the first time and
        # result in an unnecessary delay.
        if (
            isinstance(msg.processed, bool) and
            not msg.processed and
            not msg.error and
            msg.datetime_to_process < (utcnow + timedelta(seconds=10))
        ):
            if recipient_block:
                recipient_lock = get_lock(
                    "sms-queue-recipient-phone-%s" % msg.phone_number)
                recipient_lock.acquire(blocking=True)

            if msg.direction == OUTGOING:
                if (
                    msg.domain and
                    msg.couch_recipient_doc_type and
                    msg.couch_recipient and
                    not is_contact_active(msg.domain, msg.couch_recipient_doc_type, msg.couch_recipient)
                ):
                    msg.set_system_error(SMS.ERROR_CONTACT_IS_INACTIVE)
                    remove_from_queue(msg)
                else:
                    requeue = handle_outgoing(msg)
            elif msg.direction == INCOMING:
                try:
                    handle_incoming(msg)
                except DelayProcessing:
                    process_sms.apply_async([queued_sms_pk], countdown=60)
                    if recipient_block:
                        release_lock(recipient_lock, True)
                    release_lock(message_lock, True)
            else:
                msg.set_system_error(SMS.ERROR_INVALID_DIRECTION)
                remove_from_queue(msg)

            if recipient_block:
                release_lock(recipient_lock, True)

        release_lock(message_lock, True)
        if requeue:
            if outbound_counter:
                outbound_counter.decrement()
            send_to_sms_queue(msg)
Example #12
0
def process_incoming(msg):
    v, has_domain_two_way_scope = get_inbound_phone_entry(msg)

    if v:
        if any_migrations_in_progress(v.domain):
            raise DelayProcessing()

        msg.couch_recipient_doc_type = v.owner_doc_type
        msg.couch_recipient = v.owner_id
        msg.domain = v.domain
        msg.location_id = get_location_id_by_verified_number(v)
        msg.save()
    elif msg.domain_scope:
        if any_migrations_in_progress(msg.domain_scope):
            raise DelayProcessing()

        msg.domain = msg.domain_scope
        msg.save()

    opt_in_keywords, opt_out_keywords, pass_through_opt_in_keywords = get_opt_keywords(msg)
    domain = v.domain if v else None

    if is_opt_message(msg.text, opt_out_keywords):
        if PhoneBlacklist.opt_out_sms(msg.phone_number, domain=domain):
            metadata = MessageMetadata(ignore_opt_out=True)
            text = get_message(MSG_OPTED_OUT, v, context=(opt_in_keywords[0],))
            if v:
                send_sms_to_verified_number(v, text, metadata=metadata)
            elif msg.backend_id:
                send_sms_with_backend(msg.domain, msg.phone_number, text, msg.backend_id, metadata=metadata)
            else:
                send_sms(msg.domain, None, msg.phone_number, text, metadata=metadata)
    elif is_opt_message(msg.text, opt_in_keywords):
        if PhoneBlacklist.opt_in_sms(msg.phone_number, domain=domain):
            text = get_message(MSG_OPTED_IN, v, context=(opt_out_keywords[0],))
            if v:
                send_sms_to_verified_number(v, text)
            elif msg.backend_id:
                send_sms_with_backend(msg.domain, msg.phone_number, text, msg.backend_id)
            else:
                send_sms(msg.domain, None, msg.phone_number, text)
    else:
        if is_opt_message(msg.text, pass_through_opt_in_keywords):
            # Opt the phone number in, and then process the message normally
            PhoneBlacklist.opt_in_sms(msg.phone_number, domain=domain)

        handled = False
        is_two_way = v is not None and v.is_two_way

        if msg.domain and domain_has_privilege(msg.domain, privileges.INBOUND_SMS):
            handled = load_and_call(settings.CUSTOM_SMS_HANDLERS, v, msg.text, msg)

            if not handled and v and v.pending_verification:
                from . import verify
                handled = verify.process_verification(v, msg,
                    create_subevent_for_inbound=not has_domain_two_way_scope)

            if (
                not handled
                and (is_two_way or has_domain_two_way_scope)
                and is_contact_active(v.domain, v.owner_doc_type, v.owner_id)
            ):
                handled = load_and_call(settings.SMS_HANDLERS, v, msg.text, msg)

        if not handled and not is_two_way:
            handled = process_pre_registration(msg)

            if not handled:
                handled = process_sms_registration(msg)

    # If the sms queue is enabled, then the billable gets created in remove_from_queue()
    if (
        not settings.SMS_QUEUE_ENABLED and
        msg.domain and
        domain_has_privilege(msg.domain, privileges.INBOUND_SMS)
    ):
        create_billable_for_sms(msg)
Example #13
0
def _allow_load_handlers(v, is_two_way, has_domain_two_way_scope):
    return ((is_two_way or has_domain_two_way_scope)
            and is_contact_active(v.domain, v.owner_doc_type, v.owner_id))