Exemplo n.º 1
0
 def test_cache_clearing(self):
     self.addCleanup(self._cleanup_cache_test)
     domain = self.domains1[0].name
     self.assertTrue(
         EnterpriseMobileWorkerSettings.is_domain_using_custom_deactivation(
             domain))
     self.emw_settings1.allow_custom_deactivation = False
     self.emw_settings1.save()
     self.assertTrue(
         EnterpriseMobileWorkerSettings.is_domain_using_custom_deactivation(
             domain))
     EnterpriseMobileWorkerSettings.clear_domain_caches(domain)
     self.assertFalse(
         EnterpriseMobileWorkerSettings.is_domain_using_custom_deactivation(
             domain))
Exemplo n.º 2
0
def check_headers(user_specs, domain, is_web_upload=False):
    messages = []
    headers = set(user_specs.fieldnames)

    # Backwards warnings
    for (old_name, new_name) in old_headers.items():
        if old_name in headers:
            messages.append(
                _("'The column header '{old_name}' is deprecated, please use '{new_name}' instead."
                  ).format(old_name=old_name, new_name=new_name))
            headers.discard(old_name)

    if DOMAIN_PERMISSIONS_MIRROR.enabled(domain):
        allowed_headers.add('domain')

    if not is_web_upload and EnterpriseMobileWorkerSettings.is_domain_using_custom_deactivation(
            domain):
        allowed_headers.add('deactivate_after')

    illegal_headers = headers - allowed_headers

    if is_web_upload:
        missing_headers = web_required_headers - headers
    else:
        missing_headers = required_headers - headers

    for header_set, label in (missing_headers, 'required'), (illegal_headers,
                                                             'illegal'):
        if header_set:
            messages.append(
                _('The following are {label} column headers: {headers}.').
                format(label=label, headers=', '.join(header_set)))
    if messages:
        raise UserUploadError('\n'.join(messages))
Exemplo n.º 3
0
def create_or_update_commcare_users_and_groups(upload_domain,
                                               user_specs,
                                               upload_user,
                                               upload_record_id,
                                               group_memoizer=None,
                                               update_progress=None):
    """"
    Creates and Updates CommCare Users
    For the associated web user username passed, for each CommCareUser
        if corresponding web user is present
            if web user has confirmed account but not a member of domain
                adds them to the domain with same role and primary location as the CommCareUser
            if already a member of domain
                update their role and primary location to be same as that of the CommCareUser
        else creates or updates user invitation
           sets Invitation with the CommCare user's role and primary location
    All changes to users only, are tracked using UserChangeLogger, as an audit trail.
    """
    from corehq.apps.user_importer.helpers import CommCareUserImporter, WebUserImporter

    domain_info_by_domain = {}

    ret = {"errors": [], "rows": []}
    current = 0
    update_deactivate_after_date = EnterpriseMobileWorkerSettings.is_domain_using_custom_deactivation(
        upload_domain)

    for row in user_specs:
        if update_progress:
            update_progress(current)
            current += 1

        username = row.get('username')
        domain = row.get('domain') or upload_domain
        username = normalize_username(str(username),
                                      domain) if username else None
        status_row = {
            'username': username,
            'row': row,
        }

        try:
            domain_info = get_domain_info(domain, upload_domain, user_specs,
                                          domain_info_by_domain,
                                          group_memoizer)

            for validator in domain_info.validators:
                validator(row)
        except UserUploadError as e:
            status_row['flag'] = str(e)
            ret['rows'].append(status_row)
            continue

        data = row.get('data', {})
        email = row.get('email')
        group_names = list(map(str, row.get('group') or []))
        language = row.get('language')
        name = row.get('name')
        password = row.get('password')
        uncategorized_data = row.get('uncategorized_data', {})
        user_id = row.get('user_id')
        location_codes = row.get('location_code',
                                 []) if 'location_code' in row else None
        location_codes = format_location_codes(location_codes)
        role = row.get('role', None)
        profile = row.get('user_profile', None)
        web_user_username = row.get('web_user')
        phone_numbers = row.get('phone-number',
                                []) if 'phone-number' in row else None

        deactivate_after = row.get(
            'deactivate_after', None) if update_deactivate_after_date else None
        if isinstance(deactivate_after, datetime):
            deactivate_after = deactivate_after.strftime("%m-%Y")
            row['deactivate_after'] = deactivate_after

        try:
            password = str(password) if password else None

            is_active = spec_value_to_boolean_or_none(row, 'is_active')
            is_account_confirmed = spec_value_to_boolean_or_none(
                row, 'is_account_confirmed')
            send_account_confirmation_email = spec_value_to_boolean_or_none(
                row, 'send_confirmation_email')
            remove_web_user = spec_value_to_boolean_or_none(
                row, 'remove_web_user')

            user = _get_or_create_commcare_user(domain, user_id, username,
                                                is_account_confirmed,
                                                web_user_username, password,
                                                upload_user)
            commcare_user_importer = CommCareUserImporter(
                upload_domain,
                domain,
                user,
                upload_user,
                is_new_user=not bool(user_id),
                via=USER_CHANGE_VIA_BULK_IMPORTER,
                upload_record_id=upload_record_id)
            if user_id:
                if is_password(password):
                    commcare_user_importer.update_password(password)
                    # overwrite password in results so we do not save it to the db
                    status_row['row']['password'] = '******'
                status_row['flag'] = 'updated'
            else:
                status_row['flag'] = 'created'

            if phone_numbers is not None:
                phone_numbers = clean_phone_numbers(phone_numbers)
                commcare_user_importer.update_phone_numbers(phone_numbers)

            if name:
                commcare_user_importer.update_name(name)

            commcare_user_importer.update_user_data(data, uncategorized_data,
                                                    profile, domain_info)

            if update_deactivate_after_date:
                commcare_user_importer.update_deactivate_after(
                    deactivate_after)

            if language:
                commcare_user_importer.update_language(language)
            if email:
                commcare_user_importer.update_email(email)
            if is_active is not None:
                commcare_user_importer.update_status(is_active)

            # Do this here so that we validate the location code before we
            # save any other information to the user, this way either all of
            # the user's information is updated, or none of it
            # Do not update location info if the column is not included at all
            if domain_info.can_assign_locations and location_codes is not None:
                commcare_user_importer.update_locations(
                    location_codes, domain_info)

            if role:
                role_qualified_id = domain_info.roles_by_name[role]
                commcare_user_importer.update_role(role_qualified_id)
            elif not commcare_user_importer.logger.is_new_user and 'role' in row:
                commcare_user_importer.update_role('none')

            if web_user_username:
                user.update_metadata({'login_as_user': web_user_username})

            user.save()
            log = commcare_user_importer.save_log()

            if web_user_username:
                check_can_upload_web_users(domain, upload_user)
                web_user = CouchUser.get_by_username(web_user_username)
                if web_user:
                    web_user_importer = WebUserImporter(
                        upload_domain,
                        domain,
                        web_user,
                        upload_user,
                        is_new_user=False,
                        via=USER_CHANGE_VIA_BULK_IMPORTER,
                        upload_record_id=upload_record_id)
                    user_change_logger = web_user_importer.logger
                else:
                    web_user_importer = None
                    user_change_logger = None
                if remove_web_user:
                    remove_web_user_from_domain(domain, web_user, username,
                                                upload_user,
                                                user_change_logger)
                else:
                    check_user_role(username, role)
                    if not web_user and is_account_confirmed:
                        raise UserUploadError(
                            _("You can only set 'Is Account Confirmed' to 'True' on an existing Web User. "
                              f"{web_user_username} is a new username.").
                            format(web_user_username=web_user_username))
                    if web_user and not web_user.is_member_of(
                            domain) and is_account_confirmed:
                        # add confirmed account to domain
                        # role_qualified_id would be be present here as confirmed in check_user_role
                        web_user_importer.add_to_domain(
                            role_qualified_id, user.location_id)
                    elif not web_user or not web_user.is_member_of(domain):
                        create_or_update_web_user_invite(
                            web_user_username,
                            domain,
                            role_qualified_id,
                            upload_user,
                            user.location_id,
                            user_change_logger,
                            send_email=send_account_confirmation_email)
                    elif web_user.is_member_of(domain):
                        # edit existing user in the domain
                        web_user_importer.update_role(role_qualified_id)
                        if location_codes is not None:
                            web_user_importer.update_primary_location(
                                user.location_id)
                        web_user.save()
                if web_user_importer:
                    web_user_importer.save_log()
            if send_account_confirmation_email and not web_user_username:
                send_account_confirmation_if_necessary(user)

            if is_password(password):
                # Without this line, digest auth doesn't work.
                # With this line, digest auth works.
                # Other than that, I'm not sure what's going on
                # Passing use_primary_db=True because of https://dimagi-dev.atlassian.net/browse/ICDS-465
                user.get_django_user(
                    use_primary_db=True).check_password(password)

            group_change_message = commcare_user_importer.update_user_groups(
                domain_info, group_names)

            try:
                domain_info.group_memoizer.save_updated()
            except BulkSaveError as e:
                _error_message = (
                    "Oops! We were not able to save some of your group changes. "
                    "Please make sure no one else is editing your groups "
                    "and try again.")
                logging.exception(('BulkSaveError saving groups. '
                                   'User saw error message "%s". Errors: %s') %
                                  (_error_message, e.errors))
                ret['errors'].append(_error_message)

            if log and group_change_message:
                log.change_messages.update(group_change_message)
                log.save()
            elif group_change_message:
                log = commcare_user_importer.logger.save_only_group_changes(
                    group_change_message)

        except ValidationError as e:
            status_row['flag'] = e.message
        except (UserUploadError, CouchUser.Inconsistent) as e:
            status_row['flag'] = str(e)

        ret["rows"].append(status_row)

    return ret
Exemplo n.º 4
0
 def test_domain_has_no_settings_created(self):
     self.assertFalse(
         EnterpriseMobileWorkerSettings.is_domain_using_custom_deactivation(
             self.domains3[0].name))
Exemplo n.º 5
0
 def test_domain_is_disabled_by_toggle(self):
     self.assertFalse(
         EnterpriseMobileWorkerSettings.is_domain_using_custom_deactivation(
             self.domains1[1].name))
Exemplo n.º 6
0
 def test_domain_is_enabled(self):
     self.assertTrue(
         EnterpriseMobileWorkerSettings.is_domain_using_custom_deactivation(
             self.domains1[0].name))
Exemplo n.º 7
0
 def tearDown(self):
     for domains in [self.domains1, self.domains2, self.domains3]:
         for domain in domains:
             EnterpriseMobileWorkerSettings.clear_domain_caches(domain.name)
     super().tearDown()