示例#1
0
    def validate_sms_users(self):
        for sms_user in iterate_over_api_objects(self.endpoint.get_smsusers):
            description = ""
            user = CommCareUser.get_by_username(self.get_username(sms_user)[0])
            if not user:
                description = "Not exists"
                EWSMigrationProblem.objects.create(
                    domain=self.domain,
                    external_id=sms_user.id,
                    object_type='smsuser',
                    description=description
                )
                continue

            phone_numbers = {
                apply_leniency(connection.phone_number) for connection in sms_user.phone_numbers
            }

            if phone_numbers - set(user.phone_numbers):
                description += "Invalid phone numbers, "

            phone_to_backend = {
                connection.phone_number: connection.backend
                for connection in sms_user.phone_numbers
            }

            default_phone_number = [
                connection.phone_number for connection in sms_user.phone_numbers if connection.default
            ]

            default_phone_number = default_phone_number[0] if default_phone_number else None

            if default_phone_number and (apply_leniency(default_phone_number) != user.default_phone_number):
                description += "Invalid default phone number, "

            for phone_number in user.phone_numbers:
                vn = VerifiedNumber.by_phone(phone_number)
                if not vn or vn.owner_id != user.get_id:
                    description += "Phone number not verified, "
                else:
                    backend = phone_to_backend.get(phone_number)
                    if backend == 'message_tester' and vn.backend_id != 'MOBILE_BACKEND_TEST' \
                            or (backend != 'message_tester' and vn.backend_id):
                        description += "Invalid backend, "

            if description:
                migration_problem, _ = EWSMigrationProblem.objects.get_or_create(
                    domain=self.domain,
                    object_id=user.get_id,
                    object_type='smsuser'
                )
                migration_problem.external_id = sms_user.id
                migration_problem.description = description.rstrip(' ,')
                migration_problem.save()
            else:
                EWSMigrationProblem.objects.filter(
                    domain=self.domain,
                    external_id=sms_user.id,
                    object_type='smsuser'
                ).delete()
示例#2
0
    def add_language_to_user(self, logistics_sms_user):
        domain_part = "%s.commcarehq.org" % self.domain
        username_part = "%s%d" % (logistics_sms_user.name.strip().replace(' ', '.').lower(),
                                  logistics_sms_user.id)
        username = "******" % (username_part[:(128 - (len(domain_part) + 1))], domain_part)
        user = CouchUser.get_by_username(username)
        if not user:
            return

        if user.language != logistics_sms_user.language:
            user.language = logistics_sms_user.language
            user.save()

        logistics_numbers = {apply_leniency(phone_number) for phone_number in logistics_sms_user.phone_numbers}
        if set(user.phone_numbers) == logistics_numbers:
            return

        for phone_number in user.phone_numbers:
            user.delete_phone_number(phone_number)

        if logistics_sms_user.phone_numbers:
            phone_number = apply_leniency(logistics_sms_user.phone_numbers[0])
            if not phone_number:
                return
            user.set_default_phone_number(phone_number)
            self._save_verified_number(user, phone_number)
示例#3
0
 def add_phone_numbers(self, ilsgateway_smsuser, user):
     if ilsgateway_smsuser.phone_numbers:
         cleaned_number = apply_leniency(ilsgateway_smsuser.phone_numbers[0])
         if cleaned_number:
             user.set_default_phone_number(cleaned_number)
             user.user_data["backend"] = ilsgateway_smsuser.backend
             self._save_verified_number(user, cleaned_number)
示例#4
0
def _sync_user_phone_numbers(couch_user_id):
    couch_user = CouchUser.get_by_user_id(couch_user_id)

    if not isinstance(couch_user, CommCareUser):
        # It isn't necessary to sync WebUser's phone numbers right now
        # and we need to think through how to support entries when a user
        # can belong to multiple domains
        return

    with CriticalSection([couch_user.phone_sync_key], timeout=5 * 60):
        phone_entries = couch_user.get_phone_entries()

        if (
            couch_user.is_deleted() or
            (not couch_user.is_active and not USE_SMS_WITH_INACTIVE_CONTACTS.enabled(couch_user.domain))
        ):
            for phone_number in phone_entries.values():
                phone_number.delete()
            return

        numbers_that_should_exist = [apply_leniency(phone_number) for phone_number in couch_user.phone_numbers]

        # Delete entries that should not exist
        for phone_number in phone_entries.keys():
            if phone_number not in numbers_that_should_exist:
                phone_entries[phone_number].delete()

        # Create entries that should exist but do not exist
        for phone_number in numbers_that_should_exist:
            if phone_number not in phone_entries:
                try:
                    couch_user.create_phone_entry(phone_number)
                except InvalidFormatException:
                    pass
示例#5
0
 def add_phone_numbers(self, ilsgateway_smsuser, user):
     if ilsgateway_smsuser.phone_numbers:
         cleaned_number = apply_leniency(ilsgateway_smsuser.phone_numbers[0])
         if cleaned_number:
             user.phone_numbers = [cleaned_number]
             user.user_data['backend'] = ilsgateway_smsuser.backend
             user.save()
             self._save_verified_number(user, cleaned_number)
示例#6
0
 def _reassign_number(self, user, connection):
     v = VerifiedNumber.by_phone(apply_leniency(connection.phone_number), include_pending=True)
     if v.domain in self._get_logistics_domains():
         v.domain = self.domain
         v.owner_doc_type = user.doc_type
         v.owner_id = user.get_id
         backend_id = None
         if connection.backend == 'message_tester':
             backend_id = 'MOBILE_BACKEND_TEST'
         v.backend_id = backend_id
         v.verified = True
         v.save()
示例#7
0
def get_one_way_number_for_recipient(recipient):
    if isinstance(recipient, CouchUser):
        return recipient.phone_number
    elif is_commcarecase(recipient):
        one_way_number = recipient.get_case_property('contact_phone_number')
        one_way_number = apply_leniency(one_way_number)
        if one_way_number:
            try:
                CommCareMobileContactMixin.validate_number_format(one_way_number)
                return one_way_number
            except InvalidFormatException:
                return None
    return None
示例#8
0
 def edit_phone_numbers(self, ilsgateway_smsuser, user):
     verified_number = user.get_verified_number()
     phone_number = verified_number.phone_number if verified_number else None
     if ilsgateway_smsuser.phone_numbers:
         new_phone_number = apply_leniency(ilsgateway_smsuser.phone_numbers[0])
         if new_phone_number != phone_number:
             if phone_number:
                 user.delete_verified_number(phone_number)
                 user.phone_numbers = []
             self._save_verified_number(user, new_phone_number)
             user.set_default_phone_number(new_phone_number)
     elif phone_number:
         user.phone_numbers = []
         user.delete_verified_number(phone_number)
示例#9
0
    def _reassign_number(self, user, connection):
        from custom.ilsgateway import SLAB_DOMAIN

        v = VerifiedNumber.by_phone(apply_leniency(connection.phone_number), include_pending=True)
        if v.domain in self._get_logistics_domains() or v.domain == SLAB_DOMAIN:
            v.domain = self.domain
            v.owner_doc_type = user.doc_type
            v.owner_id = user.get_id
            backend_id = None
            if connection.backend != 'push_backend':
                backend_id = 'MOBILE_BACKEND_TEST'
            v.backend_id = backend_id
            v.verified = True
            v.save()
示例#10
0
    def edit_phone_numbers(self, ewsghana_smsuser, user):
        phone_numbers = {phone_number for phone_number in user.phone_numbers}
        saved_numbers = []

        for connection in ewsghana_smsuser.phone_numbers:
            phone_number = apply_leniency(connection.phone_number)
            if phone_number not in phone_numbers:
                self._save_verified_number(user, connection)
            if connection.default:
                saved_numbers = [phone_number] + saved_numbers
            else:
                saved_numbers.append(phone_number)

        for phone_number in phone_numbers - set(saved_numbers):
            user.delete_verified_number(phone_number)

        user.phone_numbers = saved_numbers
示例#11
0
    def add_phone_numbers(self, ilsgateway_smsuser, user):
        phone_numbers = ilsgateway_smsuser.phone_numbers
        if not phone_numbers:
            return

        saved_numbers = []
        for connection in phone_numbers:
            phone_number = apply_leniency(connection.phone_number)
            if connection.default:
                saved_numbers = [phone_number] + saved_numbers
            else:
                saved_numbers.append(phone_number)
        user.phone_numbers = saved_numbers
        user.save()

        for connection in phone_numbers:
            self._save_verified_number(user, connection)
示例#12
0
def get_unverified_number_for_recipient(recipient):
    if isinstance(recipient, CouchUser):
        try:
            return recipient.phone_number
        except Exception:
            # todo: catch more specific error
            return None
    elif isinstance(recipient, CommCareCase):
        unverified_number = recipient.get_case_property("contact_phone_number")
        unverified_number = apply_leniency(unverified_number)
        if unverified_number:
            try:
                CommCareMobileContactMixin.validate_number_format(unverified_number)
                return unverified_number
            except InvalidFormatException:
                return None
    return None
示例#13
0
    def add_phone_numbers(self, ewsghana_smsuser, user):
        phone_numbers = ewsghana_smsuser.phone_numbers
        if not phone_numbers:
            return

        default_phone_number = None
        saved_numbers = []
        for connection in phone_numbers:
            connection.phone_number = apply_leniency(connection.phone_number)
            self._save_verified_number(user, connection)
            saved_numbers.append(connection.phone_number)
            if connection.default:
                default_phone_number = connection.phone_number
        user.phone_numbers = saved_numbers

        if default_phone_number:
            user.set_default_phone_number(default_phone_number)
示例#14
0
    def edit_phone_numbers(self, ilsgateway_smsuser, user):
        phone_numbers = set(user.phone_numbers)
        saved_numbers = []

        for connection in ilsgateway_smsuser.phone_numbers:
            phone_number = apply_leniency(connection.phone_number)
            if phone_number not in phone_numbers:
                self._save_verified_number(user, connection)
            if connection.default:
                saved_numbers = [phone_number] + saved_numbers
            else:
                saved_numbers.append(phone_number)

        for phone_number in phone_numbers - set(saved_numbers):
            user.delete_verified_number(phone_number)

        user.phone_numbers = saved_numbers
        user.save()
示例#15
0
    def _validate_users(self, user_data):
        phone_numbers = set()
        for user_info in user_data:
            if not isinstance(user_info, dict):
                raise SelfRegistrationValidationException(
                    {'users': 'Expected a list of dictionaries'}
                )

            self._validate_toplevel_fields(user_info, [
                FieldDefinition('phone_number', True, basestring),
                FieldDefinition('custom_user_data', False, dict),
            ])

            phone_number = apply_leniency(user_info['phone_number'])
            if phone_number in phone_numbers:
                raise SelfRegistrationValidationException(
                    {'users': 'phone_number cannot be reused within a request: {}'.format(phone_number)}
                )
            phone_numbers.add(phone_number)
示例#16
0
    def _validate_users(self, user_data):
        phone_numbers = set()
        for user_info in user_data:
            if not isinstance(user_info, dict):
                raise SelfRegistrationValidationException(
                    {'users': 'Expected a list of dictionaries'})

            self._validate_toplevel_fields(user_info, [
                FieldDefinition('phone_number', True, six.string_types),
                FieldDefinition('custom_user_data', False, dict),
            ])

            phone_number = apply_leniency(user_info['phone_number'])
            if phone_number in phone_numbers:
                raise SelfRegistrationValidationException({
                    'users':
                    'phone_number cannot be reused within a request: {}'.
                    format(phone_number)
                })
            phone_numbers.add(phone_number)
示例#17
0
def initiate_sms_verification_workflow(contact, phone_number):
    # For now this is only applicable to mobile workers
    assert isinstance(contact, CommCareUser)

    phone_number = apply_leniency(phone_number)

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

    p = PhoneNumber.get_reserved_number(phone_number)
    if p:
        if p.owner_id != contact.get_id:
            return VERIFICATION__ALREADY_IN_USE
        if p.verified:
            return VERIFICATION__ALREADY_VERIFIED
        else:
            result = VERIFICATION__RESENT_PENDING
    else:
        entry = contact.get_or_create_phone_entry(phone_number)
        try:
            entry.set_pending_verification()
        except PhoneNumberInUseException:
            # On the off chance that the phone number was reserved between
            # the check above and now
            return VERIFICATION__ALREADY_IN_USE

        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
示例#18
0
def get_recipient_phone_number(reminder, recipient, verified_numbers):
    verified_number = verified_numbers.get(recipient.get_id, None)
    unverified_number = None

    if verified_number is None:
        if isinstance(recipient, CouchUser):
            try:
                unverified_number = recipient.phone_number
            except Exception:
                unverified_number = None
        elif isinstance(recipient, CommCareCase):
            unverified_number = recipient.get_case_property("contact_phone_number")
            unverified_number = apply_leniency(unverified_number)
            if unverified_number:
                try:
                    CommCareMobileContactMixin.validate_number_format(unverified_number)
                except InvalidFormatException:
                    unverified_number = None
            else:
                unverified_number = None

    return (verified_number, unverified_number)
示例#19
0
def initiate_sms_verification_workflow(contact, phone_number):
    # For now this is only applicable to mobile workers
    assert isinstance(contact, CommCareUser)

    phone_number = apply_leniency(phone_number)

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

    p = PhoneNumber.get_reserved_number(phone_number)
    if p:
        if p.owner_id != contact.get_id:
            return VERIFICATION__ALREADY_IN_USE
        if p.verified:
            return VERIFICATION__ALREADY_VERIFIED
        else:
            result = VERIFICATION__RESENT_PENDING
    else:
        entry = contact.get_or_create_phone_entry(phone_number)
        try:
            entry.set_pending_verification()
        except PhoneNumberInUseException:
            # On the off chance that the phone number was reserved between
            # the check above and now
            return VERIFICATION__ALREADY_IN_USE

        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
示例#20
0
def _sync_user_phone_numbers(couch_user_id):
    couch_user = CouchUser.get_by_user_id(couch_user_id)

    if not isinstance(couch_user, CommCareUser):
        # It isn't necessary to sync WebUser's phone numbers right now
        # and we need to think through how to support entries when a user
        # can belong to multiple domains
        return

    with CriticalSection([couch_user.phone_sync_key], timeout=5 * 60):
        phone_entries = couch_user.get_phone_entries()

        if (couch_user.is_deleted() or
            (not couch_user.is_active and
             not USE_SMS_WITH_INACTIVE_CONTACTS.enabled(couch_user.domain))):
            for phone_number in phone_entries.values():
                phone_number.delete()
            return

        numbers_that_should_exist = [
            apply_leniency(phone_number)
            for phone_number in couch_user.phone_numbers
        ]

        # Delete entries that should not exist
        for phone_number in phone_entries.keys():
            if phone_number not in numbers_that_should_exist:
                phone_entries[phone_number].delete()

        # Create entries that should exist but do not exist
        for phone_number in numbers_that_should_exist:
            if phone_number not in phone_entries:
                try:
                    couch_user.create_phone_entry(phone_number)
                except InvalidFormatException:
                    pass
示例#21
0
def get_recipient_phone_number(reminder, recipient, verified_numbers):
    verified_number = verified_numbers.get(recipient.get_id, None)
    unverified_number = None

    if verified_number is None:
        if isinstance(recipient, CouchUser):
            try:
                unverified_number = recipient.phone_number
            except Exception:
                unverified_number = None
        elif isinstance(recipient, CommCareCase):
            unverified_number = recipient.get_case_property(
                "contact_phone_number")
            unverified_number = apply_leniency(unverified_number)
            if unverified_number:
                try:
                    CommCareMobileContactMixin.validate_number_format(
                        unverified_number)
                except InvalidFormatException:
                    unverified_number = None
            else:
                unverified_number = None

    return (verified_number, unverified_number)
示例#22
0
 def test_apply_leniency(self):
     self.assertEqual('16175551234', apply_leniency(' 1 (617) 555-1234 '))
     self.assertEqual('16175551234', apply_leniency(' 1.617.555.1234 '))
     self.assertEqual('16175551234', apply_leniency(' +1 617 555 1234 '))
示例#23
0
 def test_apply_leniency(self):
     self.assertEqual("16175551234", apply_leniency(" 1 (617) 555-1234 "))
     self.assertEqual("16175551234", apply_leniency(" 1.617.555.1234 "))
     self.assertEqual("16175551234", apply_leniency(" +1 617 555 1234 "))
示例#24
0
 def test_apply_leniency(self):
     self.assertEqual('16175551234', apply_leniency(' 1 (617) 555-1234 '))
     self.assertEqual('16175551234', apply_leniency(' 1.617.555.1234 '))
     self.assertEqual('16175551234', apply_leniency(' +1 617 555 1234 '))
示例#25
0
 def clean_test_phone_number(self):
     value = self.cleaned_data.get('test_phone_number')
     value = apply_leniency(value)
     validate_phone_number(value,
         error_message=_("Please enter digits only, in international format (country code and phone number)."))
     return value
示例#26
0
    def sms_user_sync(self, ilsgateway_smsuser, username_part=None, password=None,
                      first_name='', last_name=''):
        domain_part = "%s.commcarehq.org" % self.domain
        if not username_part:
            username_part = "%s%d" % (ilsgateway_smsuser.name.strip().replace(' ', '.').lower(),
                                      ilsgateway_smsuser.id)
        username = "******" % (username_part[:(128 - (len(domain_part) + 1))], domain_part)
        # sanity check
        assert len(username) <= 128
        user = CouchUser.get_by_username(username)
        splitted_value = ilsgateway_smsuser.name.split(' ', 1)
        if not first_name:
            first_name = splitted_value[0][:30] if splitted_value else ''

        if not last_name:
            last_name = splitted_value[1][:30] if len(splitted_value) > 1 else ''

        language = ilsgateway_smsuser.language

        user_dict = {
            'first_name': first_name,
            'last_name': last_name,
            'is_active': bool(ilsgateway_smsuser.is_active),
            'email': ilsgateway_smsuser.email,
            'user_data': {}
        }

        if ilsgateway_smsuser.role:
            user_dict['user_data']['role'] = ilsgateway_smsuser.role

        if ilsgateway_smsuser.phone_numbers:
            cleaned_number = apply_leniency(ilsgateway_smsuser.phone_numbers[0])
            if cleaned_number:
                user_dict['phone_numbers'] = [cleaned_number]
                user_dict['user_data']['backend'] = ilsgateway_smsuser.backend

        if user is None and username_part:
            try:
                user_password = password or User.objects.make_random_password()
                user = CommCareUser.create(domain=self.domain, username=username, password=user_password,
                                           email=ilsgateway_smsuser.email, commit=False,
                                           password_hashed=bool(password))
                user.first_name = first_name
                user.last_name = last_name
                user.language = language
                user.is_active = bool(ilsgateway_smsuser.is_active)
                user.user_data = user_dict["user_data"]
                if "phone_numbers" in user_dict:
                    user.set_default_phone_number(user_dict["phone_numbers"][0])
                    try:
                        user.save_verified_number(self.domain, user_dict["phone_numbers"][0], True)
                    except PhoneNumberInUseException as e:
                        self._reassign_number(user, user_dict["phone_numbers"][0])
                    except InvalidFormatException:
                        pass
            except Exception as e:
                logging.error(e)
        else:
            verified_number = user.get_verified_number()
            phone_number = verified_number.phone_number if verified_number else None
            if apply_updates(user, user_dict):
                if user_dict.get('phone_numbers'):
                    new_phone_number = user_dict['phone_numbers'][0]
                    if new_phone_number != phone_number:
                        if phone_number:
                            user.delete_verified_number(phone_number)
                        self._save_verified_number(user, new_phone_number)
                elif phone_number:
                    user.phone_numbers = []
                    user.delete_verified_number(phone_number)
                user.save()
        return user
示例#27
0
    def web_user_sync(self, ews_webuser):
        username = ews_webuser.email.lower()
        if not username:
            try:
                validate_email(ews_webuser.username)
                username = ews_webuser.username
            except ValidationError:
                return None
        user = WebUser.get_by_username(username)
        user_dict = {
            'first_name': ews_webuser.first_name,
            'last_name': ews_webuser.last_name,
            'is_active': ews_webuser.is_active,
            'last_login': force_to_datetime(ews_webuser.last_login),
            'date_joined': force_to_datetime(ews_webuser.date_joined),
            'password_hashed': True,
        }
        location_id = None
        if ews_webuser.location:
            try:
                sql_location = SQLLocation.objects.get(domain=self.domain, external_id=ews_webuser.location)
                location_id = sql_location.location_id
            except SQLLocation.DoesNotExist:
                pass

        if user is None:
            try:
                user = WebUser.create(domain=None, username=username,
                                      password=ews_webuser.password, email=ews_webuser.email.lower(),
                                      **user_dict)
                user.add_domain_membership(self.domain, location_id=location_id)
            except Exception as e:
                logging.error(e)
        else:
            if self.domain not in user.get_domains():
                user.add_domain_membership(self.domain, location_id=location_id)

        ews_webuser_extension(user, ews_webuser)
        dm = user.get_domain_membership(self.domain)

        if dm.location_id != location_id:
            dm.location_id = location_id

        if ews_webuser.program:
            self._set_program(user, ews_webuser.program)

        self._set_extension(user, ews_webuser.supply_point, ews_webuser.sms_notifications)

        if ews_webuser.is_superuser:
            dm.role_id = UserRole.by_domain_and_name(self.domain, 'Administrator')[0].get_id
        elif ews_webuser.groups and ews_webuser.groups[0].name == 'facility_manager':
            dm.role_id = UserRole.by_domain_and_name(self.domain, 'Facility manager')[0].get_id
        else:
            if ews_webuser.supply_point:
                supply_point = get_supply_point_case_by_domain_external_id(self.domain, ews_webuser.supply_point)
                if supply_point:
                    dm.role_id = UserRole.by_domain_and_name(self.domain, 'Web Reporter')[0].get_id
                else:
                    dm.role_id = UserRole.get_read_only_role_by_domain(self.domain).get_id
            else:
                dm.role_id = UserRole.get_read_only_role_by_domain(self.domain).get_id

        if ews_webuser.contact:
            user.phone_numbers = []
            default_phone_number = None
            for connection in ews_webuser.contact.phone_numbers:
                phone_number = apply_leniency(connection.phone_number)
                user.phone_numbers.append(phone_number)
                if connection.default:
                    default_phone_number = phone_number
            if default_phone_number:
                user.set_default_phone_number(default_phone_number)
        user.save()
        return user
示例#28
0
    def validate_sms_users(self):
        for sms_user in iterate_over_api_objects(self.endpoint.get_smsusers, {'is_active': True}):
            description = ""
            user = CommCareUser.get_by_username(self.get_username(sms_user)[0])
            if not user:
                description = "Not exists"
                ILSMigrationProblem.objects.create(
                    domain=self.domain,
                    external_id=sms_user.id,
                    object_type='smsuser',
                    description=description
                )
                continue

            if user.domain != self.domain:
                description += "domain isn't correct"

            phone_numbers = {
                apply_leniency(connection.phone_number) for connection in sms_user.phone_numbers
            }

            if phone_numbers - set(user.phone_numbers):
                description += "Invalid phone numbers, "

            phone_to_backend = {
                apply_leniency(connection.phone_number): connection.backend
                for connection in sms_user.phone_numbers
            }

            default_phone_number = [
                connection.phone_number for connection in sms_user.phone_numbers if connection.default
            ]

            default_phone_number = default_phone_number[0] if default_phone_number else None

            if default_phone_number and (apply_leniency(default_phone_number) != user.default_phone_number):
                description += "Invalid default phone number, "

            for phone_number in user.phone_numbers:
                vn = VerifiedNumber.by_phone(phone_number)
                if vn and vn.owner_id != user.get_id and vn.domain == self.domain:
                    description += "Phone number already assigned to user({}) from this domain, "\
                        .format(vn.owner_id)
                elif vn and vn.domain != self.domain:
                    description += "Phone number already assigned on domain {}, ".format(vn.domain)
                elif not vn or not vn.verified:
                    description += "Phone number not verified, "
                else:
                    backend = phone_to_backend.get(phone_number)
                    if backend != 'push_backend' and vn.backend_id != 'MOBILE_BACKEND_TEST' \
                            or (backend == 'push_backend' and vn.backend_id):
                        description += "Invalid backend, "

            if description:
                migration_problem, _ = ILSMigrationProblem.objects.get_or_create(
                    domain=self.domain,
                    object_id=user.get_id,
                    object_type='smsuser'
                )
                migration_problem.external_id = sms_user.id
                migration_problem.description = description.rstrip(' ,')
                migration_problem.save()
            else:
                ILSMigrationProblem.objects.filter(
                    domain=self.domain,
                    external_id=sms_user.id,
                    object_type='smsuser'
                ).delete()
示例#29
0
    def validate_web_users(self, date=None):
        unique_usernames = set()
        for web_user in iterate_over_api_objects(
            self.endpoint.get_webusers, filters=dict(date_joined__gte=date)
        ):
            description = ""

            if web_user.email:
                username = web_user.email.lower()
            else:
                username = web_user.username.lower()
                try:
                    validate_email(username)
                except ValidationError:
                    # We are not migrating users without valid email in v1
                    continue

            unique_usernames.add(username)
            couch_web_user = WebUser.get_by_username(username)
            if not couch_web_user or self.domain not in couch_web_user.get_domains():
                description = "Not exists"
                EWSMigrationProblem.objects.create(
                    domain=self.domain,
                    object_type='webuser',
                    description=description,
                    external_id=web_user.email or web_user.username
                )
                continue

            user_contact = web_user.contact
            if not user_contact:
                continue

            phone_numbers = {
                apply_leniency(connection.phone_number)
                for connection in user_contact.phone_numbers
            }

            if set(phone_numbers) - set(couch_web_user.phone_numbers):
                description = "Invalid phone numbers, "

            default_phone_number = [
                connection.phone_number for connection in user_contact.phone_numbers if connection.default
            ]

            default_phone_number = default_phone_number[0] if default_phone_number else None

            if default_phone_number and \
                    (apply_leniency(default_phone_number) != couch_web_user.default_phone_number):
                description += "Invalid default phone number, "

            try:
                extension = EWSExtension.objects.get(user_id=couch_web_user.get_id, domain=self.domain)
                supply_point = extension.supply_point.external_id if extension.supply_point else None
                sms_notifications = extension.sms_notifications
            except EWSExtension.DoesNotExist:
                supply_point = None
                sms_notifications = False

            if str(supply_point) != str(web_user.supply_point):
                active = True
                if not supply_point and web_user.supply_point:
                    active = self.endpoint.get_supply_point(web_user.supply_point).active

                if active:
                    description += 'Invalid supply point, '

            if sms_notifications != web_user.sms_notifications:
                description += 'Invalid value of sms_notifications field'

            if description:
                migration_problem, _ = EWSMigrationProblem.objects.get_or_create(
                    domain=self.domain,
                    object_id=couch_web_user.get_id,
                    object_type='webuser'
                )
                migration_problem.external_id = web_user.email or web_user.username
                migration_problem.description = description.rstrip(' ,')
                migration_problem.save()
            else:
                EWSMigrationProblem.objects.filter(
                    domain=self.domain,
                    external_id=web_user.email or web_user.username,
                    object_type='webuser'
                ).delete()

        migration_stats = EWSMigrationStats.objects.get(domain=self.domain)
        migration_stats.web_users_count = len(unique_usernames)
        migration_stats.save()
示例#30
0
文件: api.py 项目: ekush/commcare-hq
    def sms_user_sync(self,
                      ilsgateway_smsuser,
                      username_part=None,
                      password=None,
                      first_name='',
                      last_name=''):
        domain_part = "%s.commcarehq.org" % self.domain
        if not username_part:
            username_part = "%s%d" % (ilsgateway_smsuser.name.strip().replace(
                ' ', '.').lower(), ilsgateway_smsuser.id)
        username = "******" % (username_part[:(128 - (len(domain_part) + 1))],
                              domain_part)
        # sanity check
        assert len(username) <= 128
        user = CouchUser.get_by_username(username)
        splitted_value = ilsgateway_smsuser.name.split(' ', 1)
        if not first_name:
            first_name = splitted_value[0][:30] if splitted_value else ''

        if not last_name:
            last_name = splitted_value[1][:30] if len(
                splitted_value) > 1 else ''

        language = ilsgateway_smsuser.language

        user_dict = {
            'first_name': first_name,
            'last_name': last_name,
            'is_active': bool(ilsgateway_smsuser.is_active),
            'email': ilsgateway_smsuser.email,
            'user_data': {}
        }

        if ilsgateway_smsuser.role:
            user_dict['user_data']['role'] = ilsgateway_smsuser.role

        if ilsgateway_smsuser.phone_numbers:
            cleaned_number = apply_leniency(
                ilsgateway_smsuser.phone_numbers[0])
            if cleaned_number:
                user_dict['phone_numbers'] = [cleaned_number]
                user_dict['user_data']['backend'] = ilsgateway_smsuser.backend

        if user is None and username_part:
            try:
                user_password = password or User.objects.make_random_password()
                user = CommCareUser.create(domain=self.domain,
                                           username=username,
                                           password=user_password,
                                           email=ilsgateway_smsuser.email,
                                           commit=False,
                                           password_hashed=bool(password))
                user.first_name = first_name
                user.last_name = last_name
                user.language = language
                user.is_active = bool(ilsgateway_smsuser.is_active)
                user.user_data = user_dict["user_data"]
                if "phone_numbers" in user_dict:
                    user.set_default_phone_number(
                        user_dict["phone_numbers"][0])
                    try:
                        user.save_verified_number(
                            self.domain, user_dict["phone_numbers"][0], True)
                    except PhoneNumberInUseException as e:
                        self._reassign_number(user,
                                              user_dict["phone_numbers"][0])
                    except InvalidFormatException:
                        pass
            except Exception as e:
                logging.error(e)
        else:
            verified_number = user.get_verified_number()
            phone_number = verified_number.phone_number if verified_number else None
            if apply_updates(user, user_dict):
                if user_dict.get('phone_numbers'):
                    new_phone_number = user_dict['phone_numbers'][0]
                    if new_phone_number != phone_number:
                        if phone_number:
                            user.delete_verified_number(phone_number)
                        self._save_verified_number(user, new_phone_number)
                elif phone_number:
                    user.phone_numbers = []
                    user.delete_verified_number(phone_number)
                user.save()
        return user
示例#31
0
    def phone_number_filter(self):
        value = self._filter['phone_number_filter']
        if isinstance(value, basestring):
            return apply_leniency(value.strip())

        return None
示例#32
0
    def phone_number_filter(self):
        value = RequiredPhoneNumberFilter.get_value(self.request, domain=None)
        if isinstance(value, str):
            return apply_leniency(value.strip())

        return None
示例#33
0
 def clean_test_phone_number(self):
     value = self.cleaned_data.get('test_phone_number')
     value = apply_leniency(value)
     validate_phone_number(value,
         error_message=_("Please enter digits only, in international format (country code and phone number)."))
     return value