コード例 #1
0
ファイル: verify.py プロジェクト: yonglehou/commcare-hq
def initiate_sms_verification_workflow(contact, phone_number):
    # For now this is only applicable to mobile workers
    assert isinstance(contact, CommCareUser)

    logged_event = MessagingEvent.get_current_verification_event(
        contact.domain, contact.get_id, phone_number)

    with CriticalSection(['verifying-phone-number-%s' % phone_number]):
        vn = PhoneNumber.by_phone(phone_number, include_pending=True)
        if vn:
            if vn.owner_id != contact.get_id:
                return VERIFICATION__ALREADY_IN_USE
            if vn.verified:
                return VERIFICATION__ALREADY_VERIFIED
            else:
                result = VERIFICATION__RESENT_PENDING
        else:
            contact.save_verified_number(contact.domain, phone_number, False)
            result = VERIFICATION__WORKFLOW_STARTED
            # Always create a new event when the workflow starts
            if logged_event:
                logged_event.status = MessagingEvent.STATUS_NOT_COMPLETED
                logged_event.save()
            logged_event = MessagingEvent.create_verification_event(
                contact.domain, contact)

        if not logged_event:
            logged_event = MessagingEvent.create_verification_event(
                contact.domain, contact)

        send_verification(contact.domain, contact, phone_number, logged_event)
        return result
コード例 #2
0
ファイル: opt_tests.py プロジェクト: saketkanth/commcare-hq
    def test_opt_out_and_opt_in(self):
        self.assertEqual(PhoneBlacklist.objects.count(), 0)

        incoming('99912345678', 'join opt-test', 'GVI')
        v = PhoneNumber.by_phone('99912345678')
        self.assertIsNotNone(v)

        incoming('99912345678', 'stop', 'GVI')
        self.assertEqual(PhoneBlacklist.objects.count(), 1)
        phone_number = PhoneBlacklist.objects.get(phone_number='99912345678')
        self.assertFalse(phone_number.send_sms)
        self.assertEqual(phone_number.domain, self.domain)
        self.assertIsNotNone(phone_number.last_sms_opt_out_timestamp)
        self.assertIsNone(phone_number.last_sms_opt_in_timestamp)

        sms = self.get_last_sms('+99912345678')
        self.assertEqual(sms.direction, 'O')
        self.assertEqual(sms.text, get_message(MSG_OPTED_OUT, context=('START',)))

        incoming('99912345678', 'start', 'GVI')
        self.assertEqual(PhoneBlacklist.objects.count(), 1)
        phone_number = PhoneBlacklist.objects.get(phone_number='99912345678')
        self.assertTrue(phone_number.send_sms)
        self.assertEqual(phone_number.domain, self.domain)
        self.assertIsNotNone(phone_number.last_sms_opt_out_timestamp)
        self.assertIsNotNone(phone_number.last_sms_opt_in_timestamp)

        sms = self.get_last_sms('+99912345678')
        self.assertEqual(sms.direction, 'O')
        self.assertEqual(sms.text, get_message(MSG_OPTED_IN, context=('STOP',)))
コード例 #3
0
ファイル: verify.py プロジェクト: saketkanth/commcare-hq
def initiate_sms_verification_workflow(contact, phone_number):
    # For now this is only applicable to mobile workers
    assert isinstance(contact, CommCareUser)

    logged_event = MessagingEvent.get_current_verification_event(
        contact.domain, contact.get_id, phone_number)

    with CriticalSection(['verifying-phone-number-%s' % phone_number]):
        vn = PhoneNumber.by_phone(phone_number, include_pending=True)
        if vn:
            if vn.owner_id != contact.get_id:
                return VERIFICATION__ALREADY_IN_USE
            if vn.verified:
                return VERIFICATION__ALREADY_VERIFIED
            else:
                result = VERIFICATION__RESENT_PENDING
        else:
            contact.save_verified_number(contact.domain, phone_number, False)
            result = VERIFICATION__WORKFLOW_STARTED
            # Always create a new event when the workflow starts
            if logged_event:
                logged_event.status = MessagingEvent.STATUS_NOT_COMPLETED
                logged_event.save()
            logged_event = MessagingEvent.create_verification_event(contact.domain, contact)

        if not logged_event:
            logged_event = MessagingEvent.create_verification_event(contact.domain, contact)

        send_verification(contact.domain, contact, phone_number, logged_event)
        return result
コード例 #4
0
ファイル: opt_tests.py プロジェクト: zbidi/commcare-hq
    def test_opt_out_and_opt_in(self):
        self.assertEqual(PhoneBlacklist.objects.count(), 0)

        incoming('99912345678', 'join opt-test', 'GVI')
        v = PhoneNumber.by_phone('99912345678')
        self.assertIsNotNone(v)

        incoming('99912345678', 'stop', 'GVI')
        self.assertEqual(PhoneBlacklist.objects.count(), 1)
        phone_number = PhoneBlacklist.objects.get(phone_number='99912345678')
        self.assertFalse(phone_number.send_sms)
        self.assertEqual(phone_number.domain, self.domain)
        self.assertIsNotNone(phone_number.last_sms_opt_out_timestamp)
        self.assertIsNone(phone_number.last_sms_opt_in_timestamp)

        sms = self.get_last_sms('+99912345678')
        self.assertEqual(sms.direction, 'O')
        self.assertEqual(sms.text,
                         get_message(MSG_OPTED_OUT, context=('START', )))

        incoming('99912345678', 'start', 'GVI')
        self.assertEqual(PhoneBlacklist.objects.count(), 1)
        phone_number = PhoneBlacklist.objects.get(phone_number='99912345678')
        self.assertTrue(phone_number.send_sms)
        self.assertEqual(phone_number.domain, self.domain)
        self.assertIsNotNone(phone_number.last_sms_opt_out_timestamp)
        self.assertIsNotNone(phone_number.last_sms_opt_in_timestamp)

        sms = self.get_last_sms('+99912345678')
        self.assertEqual(sms.direction, 'O')
        self.assertEqual(sms.text, get_message(MSG_OPTED_IN,
                                               context=('STOP', )))
コード例 #5
0
ファイル: opt_tests.py プロジェクト: saketkanth/commcare-hq
    def test_sending_to_opted_out_number(self):
        self.assertEqual(PhoneBlacklist.objects.count(), 0)

        incoming('99912345678', 'join opt-test', 'GVI')
        v = PhoneNumber.by_phone('99912345678')
        self.assertIsNotNone(v)

        send_sms_to_verified_number(v, 'hello')
        sms = self.get_last_sms('+99912345678')
        self.assertEqual(sms.direction, 'O')
        self.assertEqual(sms.text, 'hello')

        incoming('99912345678', 'stop', 'GVI')
        self.assertEqual(PhoneBlacklist.objects.count(), 1)
        phone_number = PhoneBlacklist.objects.get(phone_number='99912345678')
        self.assertFalse(phone_number.send_sms)

        send_sms_to_verified_number(v, 'hello')
        sms = self.get_last_sms('+99912345678')
        self.assertEqual(sms.direction, 'O')
        self.assertEqual(sms.text, 'hello')
        self.assertTrue(sms.error)
        self.assertEqual(sms.system_error_message, SMS.ERROR_PHONE_NUMBER_OPTED_OUT)

        incoming('99912345678', 'start', 'GVI')
        self.assertEqual(PhoneBlacklist.objects.count(), 1)
        phone_number = PhoneBlacklist.objects.get(phone_number='99912345678')
        self.assertTrue(phone_number.send_sms)

        send_sms_to_verified_number(v, 'hello')
        sms = self.get_last_sms('+99912345678')
        self.assertEqual(sms.direction, 'O')
        self.assertEqual(sms.text, 'hello')
        self.assertFalse(sms.error)
        self.assertIsNone(sms.system_error_message)
コード例 #6
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)
コード例 #7
0
    def test_other_registration_from_invite(self):
        self.domain_obj.sms_mobile_worker_registration_enabled = True
        self.domain_obj.enable_registration_welcome_sms_for_mobile_worker = True
        self.domain_obj.save()

        user_data = {'abc': 'def'}

        # Initiate Registration Workflow
        SelfRegistrationInvitation.initiate_workflow(
            self.domain,
            [SelfRegistrationUserInfo('999123', user_data)],
            app_id=self.app_id,
        )

        self.assertRegistrationInvitation(
            phone_number='999123',
            app_id=self.app_id,
            phone_type=None,
            android_only=False,
            require_email=False,
            custom_user_data=user_data,
            status=SelfRegistrationInvitation.STATUS_PENDING,
        )

        self.assertLastOutgoingSMS(
            '+999123', [_MESSAGES[MSG_MOBILE_WORKER_INVITATION_START]])

        # Choose phone type 'other'
        incoming('+999123', '2', self.backend.hq_api_id)

        self.assertRegistrationInvitation(
            phone_number='999123',
            app_id=self.app_id,
            phone_type=SelfRegistrationInvitation.PHONE_TYPE_OTHER,
            android_only=False,
            require_email=False,
            custom_user_data=user_data,
            status=SelfRegistrationInvitation.STATUS_PENDING,
        )

        self.assertLastOutgoingSMS(
            '+999123',
            [_MESSAGES[MSG_MOBILE_WORKER_JAVA_INVITATION].format(self.domain)])

        # Register over SMS
        incoming('+999123', 'JOIN {} WORKER test'.format(self.domain),
                 self.backend.hq_api_id)
        user = CommCareUser.get_by_username(
            format_username('test', self.domain))
        self.assertIsNotNone(user)
        self.assertEqual(user.user_data, user_data)
        self.assertEqual(PhoneNumber.by_phone('999123').owner_id, user.get_id)

        self.assertLastOutgoingSMS(
            '+999123', [_MESSAGES[MSG_REGISTRATION_WELCOME_MOBILE_WORKER]])

        self.assertRegistrationInvitation(
            status=SelfRegistrationInvitation.STATUS_REGISTERED, )
コード例 #8
0
ファイル: api.py プロジェクト: yonglehou/commcare-hq
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
コード例 #9
0
    def assertMatch(self, match, phone_search, suffix_search, owner_id_search):
        lookedup = PhoneNumber.by_phone(phone_search)
        self.assertPhoneNumbersEqual(match, lookedup)

        lookedup = PhoneNumber.by_suffix(suffix_search)
        self.assertPhoneNumbersEqual(match, lookedup)

        [lookedup] = PhoneNumber.by_owner_id(owner_id_search)
        self.assertPhoneNumbersEqual(match, lookedup)
コード例 #10
0
    def assertMatch(self, match, phone_search, suffix_search, owner_id_search):
        lookedup = PhoneNumber.by_phone(phone_search)
        self.assertPhoneNumbersEqual(match, lookedup)

        lookedup = PhoneNumber.by_suffix(suffix_search)
        self.assertPhoneNumbersEqual(match, lookedup)

        [lookedup] = PhoneNumber.by_owner_id(owner_id_search)
        self.assertPhoneNumbersEqual(match, lookedup)
コード例 #11
0
    def test_android_only_registration_from_invite(self):
        self.domain_obj.sms_mobile_worker_registration_enabled = True
        self.domain_obj.enable_registration_welcome_sms_for_mobile_worker = True
        self.domain_obj.save()

        # Initiate Registration Workflow
        with patch('corehq.apps.sms.models.SelfRegistrationInvitation.odk_url') as mock_odk_url, \
                patch.object(SelfRegistrationInvitation, 'get_user_registration_url', return_value=DUMMY_REGISTRATION_URL), \
                patch.object(SelfRegistrationInvitation, 'get_app_info_url', return_value=DUMMY_APP_INFO_URL):
            mock_odk_url.__get__ = Mock(return_value=DUMMY_APP_ODK_URL)
            SelfRegistrationInvitation.initiate_workflow(
                self.domain,
                [SelfRegistrationUserInfo('999123')],
                app_id=self.app_id,
                android_only=True,
            )

        self.assertRegistrationInvitation(
            phone_number='999123',
            app_id=self.app_id,
            phone_type=SelfRegistrationInvitation.PHONE_TYPE_ANDROID,
            android_only=True,
            require_email=False,
            custom_user_data={},
            status=SelfRegistrationInvitation.STATUS_PENDING,
        )

        self.assertLastOutgoingSMS('+999123', [
            _MESSAGES[MSG_MOBILE_WORKER_ANDROID_INVITATION].format(
                DUMMY_REGISTRATION_URL),
            '[commcare app - do not delete] {}'.format(DUMMY_APP_INFO_URL),
        ])

        invite = self._get_sms_registration_invitation()
        c = Client()
        response = c.post(
            '/a/{}/settings/users/commcare/register/{}/'.format(
                self.domain, invite.token), {
                    'username': '******',
                    'password': '******',
                    'password2': 'abc',
                    'email': '*****@*****.**',
                })
        self.assertEqual(response.status_code, 200)

        user = CommCareUser.get_by_username(
            format_username('new_user', self.domain))
        self.assertIsNotNone(user)
        self.assertEqual(user.user_data, {})
        self.assertEqual(user.email, '*****@*****.**')
        self.assertEqual(PhoneNumber.by_phone('999123').owner_id, user.get_id)

        self.assertRegistrationInvitation(
            status=SelfRegistrationInvitation.STATUS_REGISTERED, )
コード例 #12
0
ファイル: api.py プロジェクト: saketkanth/commcare-hq
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):
            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
コード例 #13
0
    def test_other_registration_from_invite(self):
        self.domain_obj.sms_mobile_worker_registration_enabled = True
        self.domain_obj.enable_registration_welcome_sms_for_mobile_worker = True
        self.domain_obj.save()

        user_data = {'abc': 'def'}

        # Initiate Registration Workflow
        SelfRegistrationInvitation.initiate_workflow(
            self.domain,
            [SelfRegistrationUserInfo('999123', user_data)],
            app_id=self.app_id,
        )

        self.assertRegistrationInvitation(
            phone_number='999123',
            app_id=self.app_id,
            phone_type=None,
            android_only=False,
            require_email=False,
            custom_user_data=user_data,
            status=SelfRegistrationInvitation.STATUS_PENDING,
        )

        self.assertLastOutgoingSMS('+999123', [_MESSAGES[MSG_MOBILE_WORKER_INVITATION_START]])

        # Choose phone type 'other'
        incoming('+999123', '2', self.backend.hq_api_id)

        self.assertRegistrationInvitation(
            phone_number='999123',
            app_id=self.app_id,
            phone_type=SelfRegistrationInvitation.PHONE_TYPE_OTHER,
            android_only=False,
            require_email=False,
            custom_user_data=user_data,
            status=SelfRegistrationInvitation.STATUS_PENDING,
        )

        self.assertLastOutgoingSMS('+999123', [_MESSAGES[MSG_MOBILE_WORKER_JAVA_INVITATION].format(self.domain)])

        # Register over SMS
        incoming('+999123', 'JOIN {} WORKER test'.format(self.domain), self.backend.hq_api_id)
        user = CommCareUser.get_by_username(format_username('test', self.domain))
        self.assertIsNotNone(user)
        self.assertEqual(user.user_data, user_data)
        self.assertEqual(PhoneNumber.by_phone('999123').owner_id, user.get_id)

        self.assertLastOutgoingSMS('+999123', [_MESSAGES[MSG_REGISTRATION_WELCOME_MOBILE_WORKER]])

        self.assertRegistrationInvitation(
            status=SelfRegistrationInvitation.STATUS_REGISTERED,
        )
コード例 #14
0
 def run_script(self, script):
     commands = self.parse_script(script)
     for command in commands:
         phone_number = command['phone_number']
         v = PhoneNumber.by_phone(phone_number)
         if command['direction'] == '>':
             incoming(phone_number, command['text'], v.backend_id)
         else:
             msg = self.get_last_outbound_sms(v.owner_doc_type, v.owner_id)
             self.assertEqual(msg.text, unicode(command['text']))
             self.assertEqual(strip_plus(msg.phone_number), strip_plus(phone_number))
             msg.delete()
コード例 #15
0
ファイル: mixin.py プロジェクト: saketkanth/commcare-hq
    def verify_unique_number(self, phone_number):
        """
        Verifies that the given phone number is not already in use by any other contacts.

        return  void
        raises  InvalidFormatException if the phone number format is invalid
        raises  PhoneNumberInUseException if the phone number is already in use by another contact
        """
        from corehq.apps.sms.models import PhoneNumber
        self.validate_number_format(phone_number)
        v = PhoneNumber.by_phone(phone_number, include_pending=True)
        if v is not None and (v.owner_doc_type != self.doc_type or v.owner_id != self.get_id):
            raise PhoneNumberInUseException("Phone number is already in use.")
コード例 #16
0
ファイル: test_script.py プロジェクト: zbidi/commcare-hq
 def run_script(self, script):
     commands = self.parse_script(script)
     for command in commands:
         phone_number = command['phone_number']
         v = PhoneNumber.by_phone(phone_number)
         if command['direction'] == '>':
             incoming(phone_number, command['text'], v.backend_id)
         else:
             msg = self.get_last_outbound_sms(v.owner_doc_type, v.owner_id)
             self.assertEqual(msg.text, unicode(command['text']))
             self.assertEqual(strip_plus(msg.phone_number),
                              strip_plus(phone_number))
             msg.delete()
コード例 #17
0
    def test_android_only_registration_from_invite(self):
        self.domain_obj.sms_mobile_worker_registration_enabled = True
        self.domain_obj.enable_registration_welcome_sms_for_mobile_worker = True
        self.domain_obj.save()

        # Initiate Registration Workflow
        with patch('corehq.apps.sms.models.SelfRegistrationInvitation.odk_url') as mock_odk_url, \
                patch.object(SelfRegistrationInvitation, 'get_user_registration_url', return_value=DUMMY_REGISTRATION_URL), \
                patch.object(SelfRegistrationInvitation, 'get_app_info_url', return_value=DUMMY_APP_INFO_URL):
            mock_odk_url.__get__ = Mock(return_value=DUMMY_APP_ODK_URL)
            SelfRegistrationInvitation.initiate_workflow(
                self.domain,
                [SelfRegistrationUserInfo('999123')],
                app_id=self.app_id,
                android_only=True,
            )

        self.assertRegistrationInvitation(
            phone_number='999123',
            app_id=self.app_id,
            phone_type=SelfRegistrationInvitation.PHONE_TYPE_ANDROID,
            android_only=True,
            require_email=False,
            custom_user_data={},
            status=SelfRegistrationInvitation.STATUS_PENDING,
        )

        self.assertLastOutgoingSMS('+999123', [
            _MESSAGES[MSG_MOBILE_WORKER_ANDROID_INVITATION].format(DUMMY_REGISTRATION_URL),
            '[commcare app - do not delete] {}'.format(DUMMY_APP_INFO_URL_B64),
        ])

        invite = self._get_sms_registration_invitation()
        c = Client()
        response = c.post('/a/{}/settings/users/commcare/register/{}/'.format(self.domain, invite.token), {
            'username': '******',
            'password': '******',
            'password2': 'abc',
            'email': '*****@*****.**',
        })
        self.assertEqual(response.status_code, 200)

        user = CommCareUser.get_by_username(format_username('new_user', self.domain))
        self.assertIsNotNone(user)
        self.assertEqual(user.user_data, {})
        self.assertEqual(user.email, '*****@*****.**')
        self.assertEqual(PhoneNumber.by_phone('999123').owner_id, user.get_id)

        self.assertRegistrationInvitation(
            status=SelfRegistrationInvitation.STATUS_REGISTERED,
        )
コード例 #18
0
ファイル: mixin.py プロジェクト: yonglehou/commcare-hq
    def verify_unique_number(self, phone_number):
        """
        Verifies that the given phone number is not already in use by any other contacts.

        return  void
        raises  InvalidFormatException if the phone number format is invalid
        raises  PhoneNumberInUseException if the phone number is already in use by another contact
        """
        from corehq.apps.sms.models import PhoneNumber
        self.validate_number_format(phone_number)
        v = PhoneNumber.by_phone(phone_number, include_pending=True)
        if v is not None and (v.owner_doc_type != self.doc_type
                              or v.owner_id != self.get_id):
            raise PhoneNumberInUseException("Phone number is already in use.")
コード例 #19
0
ファイル: opt_tests.py プロジェクト: zbidi/commcare-hq
    def test_sending_to_opted_out_number(self):
        self.assertEqual(PhoneBlacklist.objects.count(), 0)

        incoming('99912345678', 'join opt-test', 'GVI')
        v = PhoneNumber.by_phone('99912345678')
        self.assertIsNotNone(v)

        send_sms_to_verified_number(v, 'hello')
        sms = self.get_last_sms('+99912345678')
        self.assertEqual(sms.direction, 'O')
        self.assertEqual(sms.text, 'hello')

        incoming('99912345678', 'stop', 'GVI')
        self.assertEqual(PhoneBlacklist.objects.count(), 1)
        phone_number = PhoneBlacklist.objects.get(phone_number='99912345678')
        self.assertFalse(phone_number.send_sms)

        send_sms_to_verified_number(v, 'hello')
        sms = self.get_last_sms('+99912345678')
        self.assertEqual(sms.direction, 'O')
        self.assertEqual(sms.text, 'hello')
        self.assertTrue(sms.error)
        self.assertEqual(sms.system_error_message,
                         SMS.ERROR_PHONE_NUMBER_OPTED_OUT)

        incoming('99912345678', 'start', 'GVI')
        self.assertEqual(PhoneBlacklist.objects.count(), 1)
        phone_number = PhoneBlacklist.objects.get(phone_number='99912345678')
        self.assertTrue(phone_number.send_sms)

        send_sms_to_verified_number(v, 'hello')
        sms = self.get_last_sms('+99912345678')
        self.assertEqual(sms.direction, 'O')
        self.assertEqual(sms.text, 'hello')
        self.assertFalse(sms.error)
        self.assertIsNone(sms.system_error_message)
コード例 #20
0
    def test_phone_lookup(self):
        number = PhoneNumber.objects.create(domain=self.domain,
                                            owner_doc_type='X',
                                            owner_id='X',
                                            phone_number='999123',
                                            verified=True)

        self.assertEqual(PhoneNumber.by_phone('999123'), number)
        self.assertEqual(PhoneNumber.by_phone('+999 123'), number)
        self.assertIsNone(PhoneNumber.by_phone('999124'))

        # test cache clear on save
        number.phone_number = '999124'
        number.save()
        self.assertIsNone(PhoneNumber.by_phone('999123'))
        self.assertEqual(PhoneNumber.by_phone('999124'), number)

        # test pending
        number.verified = False
        number.save()
        self.assertIsNone(PhoneNumber.by_phone('999124'))
        self.assertEqual(PhoneNumber.by_phone('999124', include_pending=True),
                         number)
コード例 #21
0
    def test_phone_lookup(self):
        number = PhoneNumber.objects.create(
            domain=self.domain,
            owner_doc_type='X',
            owner_id='X',
            phone_number='999123',
            verified=True
        )

        self.assertEqual(PhoneNumber.by_phone('999123'), number)
        self.assertEqual(PhoneNumber.by_phone('+999 123'), number)
        self.assertIsNone(PhoneNumber.by_phone('999124'))

        # test cache clear on save
        number.phone_number = '999124'
        number.save()
        self.assertIsNone(PhoneNumber.by_phone('999123'))
        self.assertEqual(PhoneNumber.by_phone('999124'), number)

        # test pending
        number.verified = False
        number.save()
        self.assertIsNone(PhoneNumber.by_phone('999124'))
        self.assertEqual(PhoneNumber.by_phone('999124', include_pending=True), number)
コード例 #22
0
ファイル: models.py プロジェクト: zbidi/commcare-hq
 def verified_number(self):
     return PhoneNumber.by_phone(self.phone_number)
コード例 #23
0
 def assertNoMatch(self, phone_search, suffix_search, owner_id_search):
     self.assertIsNone(PhoneNumber.by_phone(phone_search))
     self.assertIsNone(PhoneNumber.by_suffix(suffix_search))
     self.assertEqual(PhoneNumber.by_owner_id(owner_id_search).count(), 0)
コード例 #24
0
ファイル: api.py プロジェクト: zbidi/commcare-hq
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)
コード例 #25
0
ファイル: models.py プロジェクト: saketkanth/commcare-hq
 def verified_number(self):
     return PhoneNumber.by_phone(self.phone_number)
コード例 #26
0
 def assertNoMatch(self, phone_search, suffix_search, owner_id_search):
     self.assertIsNone(PhoneNumber.by_phone(phone_search))
     self.assertIsNone(PhoneNumber.by_suffix(suffix_search))
     self.assertEqual(PhoneNumber.by_owner_id(owner_id_search).count(), 0)