Exemplo n.º 1
0
 def test_no_factor_set(self):
     self.user.loadtest_factor = None
     self.user.save()
     case = self.factory.create_case()
     restore_config = RestoreConfig(
         project=self.domain,
         restore_user=self.user.to_ota_restore_user(),
         params=RestoreParams(version=V2))
     payload_string = restore_config.get_payload().as_string()
     caseblocks = extract_caseblocks_from_xml(payload_string)
     self.assertEqual(1, len(caseblocks))
     self.assertEqual(caseblocks[0].get_case_id(), case.case_id)
Exemplo n.º 2
0
def call_fixture_generator(gen, restore_user, project=None, last_sync=None, app=None, device_id=''):
    """
    Convenience function for use in unit tests

    TODO move to MockDevice since most arguments are members of that class
    """
    from casexml.apps.phone.restore import RestoreState
    from casexml.apps.phone.restore import RestoreParams
    from corehq.apps.domain.models import Domain
    params = RestoreParams(version=V2, app=app, device_id=device_id)
    restore_state = RestoreState(
        project or Domain(name=restore_user.domain),
        restore_user,
        params,
        is_async=False,
        overwrite_cache=False
    )
    if last_sync:
        params.sync_log_id = last_sync._id
        restore_state._last_sync_log = last_sync
    return gen(restore_state)
Exemplo n.º 3
0
def get_restore_response(domain,
                         couch_user,
                         app_id=None,
                         since=None,
                         version='1.0',
                         state=None,
                         items=False,
                         force_cache=False,
                         cache_timeout=None,
                         overwrite_cache=False,
                         force_restore_mode=None,
                         as_user=None,
                         has_data_cleanup_privelege=False,
                         openrosa_version=OPENROSA_DEFAULT_VERSION):
    # not a view just a view util
    is_permitted, message = is_permitted_to_restore(
        domain,
        couch_user,
        as_user,
        has_data_cleanup_privelege,
    )
    if not is_permitted:
        return HttpResponse(message, status=401), None

    if couch_user.is_commcare_user() and couch_user.is_demo_user:
        # if user is in demo-mode, return demo restore
        return demo_user_restore_response(couch_user), None

    restore_user = get_restore_user(domain, couch_user, as_user)
    if not restore_user:
        return HttpResponse('Could not find user', status=404), None

    project = Domain.get_by_name(domain)
    app = get_app(domain, app_id) if app_id else None
    async_restore_enabled = (toggles.ASYNC_RESTORE.enabled(domain) and
                             LooseVersion(openrosa_version) >= LooseVersion(
                                 OPENROSA_VERSION_MAP['ASYNC_RESTORE']))
    restore_config = RestoreConfig(
        project=project,
        restore_user=restore_user,
        params=RestoreParams(
            sync_log_id=since,
            version=version,
            state_hash=state,
            include_item_count=items,
            app=app,
        ),
        cache_settings=RestoreCacheSettings(force_cache=force_cache
                                            or async_restore_enabled,
                                            cache_timeout=cache_timeout,
                                            overwrite_cache=overwrite_cache),
        async=async_restore_enabled)
    return restore_config.get_response(), restore_config.timing_context
Exemplo n.º 4
0
 def _restore_config(self, is_async=True, sync_log_id='', overwrite_cache=False):
     restore_config = RestoreConfig(
         project=self.project,
         restore_user=self.user,
         params=RestoreParams(sync_log_id=sync_log_id, version=V2),
         cache_settings=RestoreCacheSettings(
             overwrite_cache=overwrite_cache
         ),
         is_async=is_async
     )
     self.addCleanup(get_redis_default_cache().clear)
     return restore_config
Exemplo n.º 5
0
def call_fixture_generator(gen, restore_user, project=None, last_sync=None, app=None, device_id=''):
    """
    Convenience function for use in unit tests

    TODO move to MockDevice since most arguments are members of that class
    """
    from casexml.apps.phone.restore import RestoreState
    from casexml.apps.phone.restore import RestoreParams
    from corehq.apps.domain.models import Domain
    params = RestoreParams(version=V2, app=app, device_id=device_id)
    restore_state = RestoreState(
        project or Domain(name=restore_user.domain),
        restore_user,
        params,
        async=False,
        overwrite_cache=False
    )
    if last_sync:
        params.sync_log_id = last_sync._id
        restore_state._last_sync_log = last_sync
    return gen(restore_state)
Exemplo n.º 6
0
 def test_return_412_between_bug_dates(self):
     log = SimplifiedSyncLog(user_id=self.restore_user.user_id,
                             date=datetime(2016, 7, 19, 19, 20))
     log.save()
     restore_config = RestoreConfig(project=self.project,
                                    restore_user=self.restore_user,
                                    params=RestoreParams(
                                        sync_log_id=log._id,
                                        version="2.0",
                                    ),
                                    cache_settings=RestoreCacheSettings())
     response = restore_config.get_response()
     self.assertEqual(response.status_code, 412)
Exemplo n.º 7
0
def generate_restore_response(project,
                              user,
                              restore_id="",
                              version=V1,
                              state_hash="",
                              items=False):
    config = RestoreConfig(project=project,
                           restore_user=user,
                           params=RestoreParams(sync_log_id=restore_id,
                                                version=version,
                                                state_hash=state_hash,
                                                include_item_count=items))
    return config.get_response()
Exemplo n.º 8
0
 def test_build_id(self):
     app = Application(domain=self.domain)
     app.save()
     config = RestoreConfig(
         project=self.project,
         restore_user=self.restore_user,
         params=RestoreParams(app=app, ),
     )
     config.get_payload()  # this generates the sync log
     sync_log = SyncLog.last_for_user(self.restore_user.user_id)
     self.assertEqual(self.restore_user.user_id, sync_log.user_id)
     self.assertEqual(self.restore_user.domain, sync_log.domain)
     self.assertEqual(app._id, sync_log.build_id)
     self.addCleanup(app.delete)
Exemplo n.º 9
0
    def test_synced_before_and_after_bug_resolution_200(self):
        before = SimplifiedSyncLog(
            user_id=self.restore_user.user_id,
            date=datetime(2016, 7, 19, 18, 0)  # synced before bug was introduced
        )
        before.save()
        restore_config = RestoreConfig(
            project=self.project,
            restore_user=self.restore_user,
            params=RestoreParams(
                sync_log_id=before._id,
                version="2.0",
            ),
            cache_settings=RestoreCacheSettings()
        )
        response = restore_config.get_response()
        self.assertEqual(response.status_code, 200)

        after = SimplifiedSyncLog(
            user_id=self.restore_user.user_id,
            previous_log_id=before._id,
            date=datetime(2016, 7, 21, 19, 0)  # after resolution
        )
        after.save()

        restore_config = RestoreConfig(
            project=self.project,
            restore_user=self.restore_user,
            params=RestoreParams(
                sync_log_id=after._id,
                version="2.0",
            ),
            cache_settings=RestoreCacheSettings()
        )
        response = restore_config.get_response()
        self.assertEqual(response.status_code, 200)
 def test_simple_factor(self):
     self.user.loadtest_factor = 3
     self.user.save()
     case1 = self.factory.create_case(case_name='case1')
     case2 = self.factory.create_case(case_name='case2')
     restore_config = RestoreConfig(
         project=self.domain,
         restore_user=self.user.to_ota_restore_user(),
         params=RestoreParams(version=V2),
     )
     payload_string = restore_config.get_payload().as_string()
     caseblocks = extract_caseblocks_from_xml(payload_string)
     self.assertEqual(6, len(caseblocks))
     self.assertEqual(1, len(filter(lambda cb: cb.get_case_id() == case1.case_id, caseblocks)))
     self.assertEqual(1, len(filter(lambda cb: cb.get_case_id() == case2.case_id, caseblocks)))
     self.assertEqual(3, len(filter(lambda cb: case1.name in cb.get_case_name(), caseblocks)))
     self.assertEqual(3, len(filter(lambda cb: case2.name in cb.get_case_name(), caseblocks)))
Exemplo n.º 11
0
 def test_new_then_old_sync(self):
     OWNERSHIP_CLEANLINESS_RESTORE.set(self.domain,
                                       enabled=True,
                                       namespace='domain')
     restore_config = RestoreConfig(self.project, user=self.user)
     sync_log = synclog_from_restore_payload(
         restore_config.get_payload().as_string())
     self.assertEqual(SimplifiedSyncLog, type(sync_log))
     OWNERSHIP_CLEANLINESS_RESTORE.set(self.domain,
                                       enabled=False,
                                       namespace='domain')
     restore_config = RestoreConfig(
         self.project,
         user=self.user,
         params=RestoreParams(sync_log_id=sync_log._id))
     with self.assertRaises(IncompatibleSyncLogType):
         restore_config.get_payload()
Exemplo n.º 12
0
def get_restore_config(project, user, restore_id="", version=V1, state_hash="",
                       items=False, overwrite_cache=False, force_cache=False, device_id=None):
    return RestoreConfig(
        project=project,
        restore_user=user,
        params=RestoreParams(
            sync_log_id=restore_id,
            version=version,
            state_hash=state_hash,
            include_item_count=items,
            device_id=device_id,
        ),
        cache_settings=RestoreCacheSettings(
            overwrite_cache=overwrite_cache,
            force_cache=force_cache,
        )
    )
Exemplo n.º 13
0
    def test_should_sync_when_changed(self, *args):
        self.user._couch_user.add_to_assigned_locations(self.locations['Boston'])
        last_sync_time = datetime.utcnow()
        sync_log = SimplifiedSyncLog(date=last_sync_time)
        locations_queryset = SQLLocation.objects.filter(pk=self.locations['Boston'].pk)

        restore_state = MockRestoreState(self.user, RestoreParams())

        self.assertFalse(should_sync_locations(sync_log, locations_queryset, restore_state))
        self.assertEqual(
            len(call_fixture_generator(related_locations_fixture_generator, self.user, last_sync=sync_log)), 0)

        LocationRelation.objects.create(location_a=self.locations["Revere"], location_b=self.locations["Boston"])
        self.assertTrue(should_sync_locations(SimplifiedSyncLog(date=last_sync_time), locations_queryset, restore_state))

        # length 2 for index definition + data
        self.assertEqual(
            len(call_fixture_generator(related_locations_fixture_generator, self.user, last_sync=sync_log)), 2)
Exemplo n.º 14
0
def reset_demo_user_restore(commcare_user, domain):
    """
    Updates demo restore for the demo commcare_user
    """
    assert commcare_user.domain == domain

    # if there is a restore already, delete it
    delete_demo_restore_for_user(commcare_user)
    # get latest restore
    restore = RestoreConfig(
        project=Domain.get_by_name(domain),
        restore_user=commcare_user.to_ota_restore_user(),
        params=RestoreParams(version=V2),
    ).get_payload().as_file()
    demo_restore = DemoUserRestore.create(commcare_user._id, restore)

    # set reference to new restore
    commcare_user.demo_restore_id = demo_restore.id
    commcare_user.save()
Exemplo n.º 15
0
def prime_restore(username_or_id, domain, version, cache_timeout_hours,
                  overwrite_cache, check_cache_only):
    couch_user = get_user(username_or_id, domain)

    try:
        project = couch_user.project
        restore_config = RestoreConfig(
            project=project,
            restore_user=couch_user.to_ota_restore_user(),
            params=RestoreParams(
                version=version,
                include_item_count=True,
            ),
            cache_settings=RestoreCacheSettings(
                force_cache=True,
                cache_timeout=cache_timeout_hours * 60 * 60,
                overwrite_cache=overwrite_cache
            )
        )

        if check_cache_only:
            cached_payload = _get_cached_payload(restore_config)
            ret = u'Restore cache {} for user: {}'.format(
                'EXISTS' if cached_payload else 'does not exist',
                couch_user.human_friendly_name,
            )
        else:
            restore_config.get_payload()

            cached_payload = _get_cached_payload(restore_config)
            if cached_payload:
                ret = u'Restore cached successfully for user: {}'.format(
                    couch_user.human_friendly_name,
                )
            else:
                raise PrimeRestoreException(u"Restore completed by cache still empty")

    except Exception as e:
        raise PrimeRestoreException(u'Error processing user: {}. Error was: {}'.format(
            couch_user.human_friendly_name, str(e)
        ))

    return {"messages": ret}
Exemplo n.º 16
0
    def handle(self, username, **options):
        couch_user = CommCareUser.get_by_username(username)
        project = couch_user.project

        restore_config = RestoreConfig(
            project=project,
            restore_user=couch_user.to_ota_restore_user(),
            params=RestoreParams(
                version=V2,
                include_item_count=True,
            ),
            cache_settings=RestoreCacheSettings(
                force_cache=True,
                cache_timeout=1,
                overwrite_cache=False,
            ))

        with resident_set_size():
            restore_config.get_payload()
Exemplo n.º 17
0
    def setUp(self):
        super(CommTrackSyncTest, self).setUp()
        self.group = Group(domain=util.TEST_DOMAIN, name='commtrack-folks',
                           users=[self.user._id], case_sharing=True)
        self.group._id = self.sp.owner_id
        self.group.save()

        self.restore_user = self.user.to_ota_restore_user()
        self.sp_block = CaseBlock(
            case_id=self.sp.case_id,
        ).as_xml()

        # get initial restore token
        restore_config = RestoreConfig(
            project=self.domain,
            restore_user=self.restore_user,
            params=RestoreParams(version=V2),
        )
        self.sync_log_id = synclog_id_from_restore_payload(restore_config.get_payload().as_string())
Exemplo n.º 18
0
    def test_cross_domain_assignments(self):
        good_domain = 'main-domain'
        domain = create_domain(good_domain)
        bad_domain = 'bad-domain'
        create_domain(bad_domain)
        user = CommCareUser.create(good_domain,
                                   format_username('user', good_domain),
                                   'secret', None, None)

        def _submit_case(domain):
            case_id = uuid.uuid4().hex
            case_block = CaseBlock(
                create=True,
                case_id=case_id,
                case_name='donald',
                case_type='duck',
                user_id=user._id,
                owner_id=user._id,
            ).as_xml()
            _, [case] = post_case_blocks([case_block], {'domain': domain})
            return case

        good_case = _submit_case(good_domain)

        # create a case in the "wrong" domain
        # in the future this should actually fail completely
        bad_case = _submit_case(bad_domain)

        self.assertEqual(good_domain, good_case.domain)
        self.assertEqual(bad_domain, bad_case.domain)
        for case in (good_case, bad_case):
            self.assertEqual(user._id, case.user_id)
            self.assertEqual(user._id, case.owner_id)

        restore_config = RestoreConfig(
            project=domain,
            restore_user=user.to_ota_restore_user(),
            params=RestoreParams(version=V2),
        )
        payload = restore_config.get_payload().as_string().decode('utf-8')
        self.assertIn(good_case.case_id, payload)
        self.assertNotIn(bad_case.case_id, payload)
 def test_parent_child(self):
     self.user.loadtest_factor = 3
     self.user.save()
     child, parent = self.factory.create_or_update_case(
         CaseStructure(attrs={
             'case_name': 'parent',
             'create': True
         },
                       indices=[
                           CaseIndex(
                               CaseStructure(attrs={
                                   'case_name': 'child',
                                   'create': True
                               })),
                       ]))
     restore_config = RestoreConfig(
         project=self.domain,
         restore_user=self.user.to_ota_restore_user(),
         params=RestoreParams(version=V2))
     payload_string = restore_config.get_payload().as_string()
     caseblocks = extract_caseblocks_from_xml(payload_string)
     self.assertEqual(6, len(caseblocks))
     self.assertEqual(
         1,
         len(
             filter(lambda cb: cb.get_case_id() == child.case_id,
                    caseblocks)))
     self.assertEqual(
         1,
         len(
             filter(lambda cb: cb.get_case_id() == parent.case_id,
                    caseblocks)))
     self.assertEqual(
         3,
         len(filter(lambda cb: child.name in cb.get_case_name(),
                    caseblocks)))
     self.assertEqual(
         3,
         len(
             filter(lambda cb: parent.name in cb.get_case_name(),
                    caseblocks)))
Exemplo n.º 20
0
    def test_should_sync_locations_change_location_type(self):
        """
        When location_type gets changed, we should resync locations
        """
        yesterday = datetime.today() - timedelta(1)
        day_before_yesterday = yesterday - timedelta(1)
        LocationType.objects.all().update(last_modified=day_before_yesterday
                                          )  # Force update because of auto_now
        self.location_type = LocationType.objects.last()

        location = SQLLocation(
            domain=self.domain,
            name="Meereen",
            location_type=self.location_type,
            metadata={
                'queen': "Daenerys Targaryen",
                'rebels': "Sons of the Harpy"
            },
        )
        location.save()

        SQLLocation.objects.filter(pk=location.pk).update(
            last_modified=day_before_yesterday)
        location = SQLLocation.objects.last()
        locations_queryset = SQLLocation.objects.filter(pk=location.pk)

        restore_state = MockRestoreState(self.user.to_ota_restore_user(),
                                         RestoreParams())
        self.assertFalse(
            should_sync_locations(SyncLog(date=yesterday), locations_queryset,
                                  restore_state))

        self.location_type.shares_cases = True
        self.location_type.save()

        location = SQLLocation.objects.last()
        locations_queryset = SQLLocation.objects.filter(pk=location.pk)

        self.assertTrue(
            should_sync_locations(SyncLog(date=yesterday), locations_queryset,
                                  restore_state))
Exemplo n.º 21
0
def get_restore_config(project, user, restore_id="", version=V1, state_hash="",
                       items=False, overwrite_cache=False, force_cache=False,
                       device_id=None, case_sync=None):
    from casexml.apps.phone.restore import (
        RestoreCacheSettings, RestoreConfig, RestoreParams)

    return RestoreConfig(
        project=project,
        restore_user=user,
        case_sync=case_sync,
        params=RestoreParams(
            sync_log_id=restore_id,
            version=version,
            state_hash=state_hash,
            include_item_count=items,
            device_id=device_id,
        ),
        cache_settings=RestoreCacheSettings(
            overwrite_cache=overwrite_cache,
            force_cache=force_cache,
        )
    )
Exemplo n.º 22
0
    def test_synced_during_and_after_bug_resolution_returns_200(self):
        during = SimplifiedSyncLog(
            user_id=self.restore_user.user_id,
            date=datetime(2016, 7, 19, 20, 0)  # during bug
        )
        during.save()

        after = SimplifiedSyncLog(
            user_id=self.restore_user.user_id,
            previous_log_id=during._id,
            date=datetime(2016, 7, 21, 19, 0)  # after resolution
        )
        after.save()

        restore_config = RestoreConfig(project=self.project,
                                       restore_user=self.restore_user,
                                       params=RestoreParams(
                                           sync_log_id=after._id,
                                           version="2.0",
                                       ),
                                       cache_settings=RestoreCacheSettings())
        response = restore_config.get_response()
        self.assertEqual(response.status_code, 200)
Exemplo n.º 23
0
def _cached_restore(testcase, user, restore_id="", version=V2,
                   purge_restore_cache=False):
    """DEPRECATED use <MockDevice>.sync().cases"""
    assert not hasattr(testcase, 'restore_config'), testcase
    assert not hasattr(testcase, 'payload_string'), testcase

    if restore_id and purge_restore_cache:
        RestorePayloadPathCache(
            domain=user.domain,
            user_id=user.user_id,
            sync_log_id=restore_id,
            device_id=None,
        ).invalidate()

    testcase.restore_config = RestoreConfig(
        project=user.project,
        restore_user=user, params=RestoreParams(restore_id, version=version),
        **getattr(testcase, 'restore_options', {})
    )
    testcase.payload_string = testcase.restore_config.get_payload().as_string()
    try:
        yield
    finally:
        del testcase.restore_config, testcase.payload_string
Exemplo n.º 24
0
def check_user_has_case(testcase,
                        user,
                        case_blocks,
                        should_have=True,
                        line_by_line=True,
                        restore_id="",
                        version=V2,
                        purge_restore_cache=False,
                        return_single=False):

    if not isinstance(case_blocks, list):
        case_blocks = [case_blocks]
        return_single = True

    XMLNS = NS_VERSION_MAP.get(version, 'http://openrosa.org/http/response')

    if restore_id and purge_restore_cache:
        SyncLog.get(restore_id).invalidate_cached_payloads()

    restore_config = RestoreConfig(project=user.project,
                                   restore_user=user,
                                   params=RestoreParams(restore_id,
                                                        version=version))
    payload_string = restore_config.get_payload().as_string()
    blocks_from_restore = extract_caseblocks_from_xml(payload_string, version)

    def check_block(case_block):
        case_block.set('xmlns', XMLNS)
        case_block = RestoreCaseBlock(ElementTree.fromstring(
            ElementTree.tostring(case_block)),
                                      version=version)
        case_id = case_block.get_case_id()
        n = 0

        def extra_info():
            return "\n%s\n%s" % (case_block.to_string(),
                                 map(lambda b: b.to_string(),
                                     blocks_from_restore))

        match = None
        for block in blocks_from_restore:
            if block.get_case_id() == case_id:
                if should_have:
                    if line_by_line:
                        check_xml_line_by_line(
                            testcase,
                            case_block.to_string(),
                            block.to_string(),
                        )
                    match = block
                    n += 1
                    if n == 2:
                        testcase.fail("Block for case_id '%s' appears twice"
                                      " in ota restore for user '%s':%s" %
                                      (case_id, user.username, extra_info()))
                else:
                    testcase.fail("User '%s' gets case '%s' "
                                  "but shouldn't:%s" %
                                  (user.username, case_id, extra_info()))
        if not n and should_have:
            testcase.fail(
                "Block for case_id '%s' doesn't appear in ota restore for user '%s':%s"
                % (case_id, user.username, extra_info()))

        return match

    matches = [check_block(case_block) for case_block in case_blocks]
    return restore_config, matches[0] if return_single else matches
Exemplo n.º 25
0
def get_restore_response(domain,
                         couch_user,
                         app_id=None,
                         since=None,
                         version='1.0',
                         state=None,
                         items=False,
                         force_cache=False,
                         cache_timeout=None,
                         overwrite_cache=False,
                         as_user=None,
                         device_id=None,
                         user_id=None,
                         openrosa_version=None,
                         case_sync=None):
    """
    :param domain: Domain being restored from
    :param couch_user: User performing restore
    :param app_id: App ID of the app making the request
    :param since: ID of current sync log used to generate incremental sync
    :param version: Version of the sync response required
    :param state: Hash value of the current database of cases on the device for consistency checking
    :param items: Include item count if True
    :param force_cache: Force response to be cached
    :param cache_timeout: Override the default cache timeout of 1 hour.
    :param overwrite_cache: Ignore cached response if True
    :param as_user: Username of user to generate restore for (if different from current user)
    :param device_id: ID of device performing restore
    :param user_id: ID of user performing restore (used in case of deleted user with same username)
    :param openrosa_version:
    :param case_sync: Override default case sync algorithm
    :return: Tuple of (http response, timing context or None)
    """

    if user_id and user_id != couch_user.user_id:
        # sync with a user that has been deleted but a new
        # user was created with the same username and password
        from couchforms.openrosa_response import get_simple_response_xml
        from couchforms.openrosa_response import ResponseNature
        response = get_simple_response_xml(
            'Attempt to sync with invalid user.',
            ResponseNature.OTA_RESTORE_ERROR)
        return HttpResponse(response,
                            content_type="text/xml; charset=utf-8",
                            status=412), None

    is_demo_restore = couch_user.is_commcare_user() and couch_user.is_demo_user
    if is_demo_restore:
        # if user is in demo-mode, return demo restore
        return demo_user_restore_response(couch_user), None

    uses_login_as = bool(as_user)
    as_user_obj = CouchUser.get_by_username(as_user) if uses_login_as else None
    if uses_login_as and not as_user_obj:
        msg = _('Invalid restore as user {}').format(as_user)
        return HttpResponse(msg, status=401), None
    is_permitted, message = is_permitted_to_restore(
        domain,
        couch_user,
        as_user_obj,
    )
    if not is_permitted:
        return HttpResponse(message, status=401), None

    restore_user = get_restore_user(domain, couch_user, as_user_obj)
    if not restore_user:
        return HttpResponse('Could not find user', status=404), None

    project = Domain.get_by_name(domain)
    async_restore_enabled = (toggles.ASYNC_RESTORE.enabled(domain)
                             and openrosa_version and
                             LooseVersion(openrosa_version) >= LooseVersion(
                                 OPENROSA_VERSION_MAP['ASYNC_RESTORE']))

    app = get_app_cached(domain, app_id) if app_id else None
    restore_config = RestoreConfig(
        project=project,
        restore_user=restore_user,
        params=RestoreParams(
            sync_log_id=since,
            version=version,
            state_hash=state,
            include_item_count=items,
            app=app,
            device_id=device_id,
            openrosa_version=openrosa_version,
        ),
        cache_settings=RestoreCacheSettings(force_cache=force_cache
                                            or async_restore_enabled,
                                            cache_timeout=cache_timeout,
                                            overwrite_cache=overwrite_cache),
        is_async=async_restore_enabled,
        case_sync=case_sync,
    )
    return restore_config.get_response(), restore_config.timing_context
Exemplo n.º 26
0
    @classmethod
    def tearDownClass(cls):
        cls.project.delete()
        delete_all_cases()
        delete_all_sync_logs()
        delete_all_users()
        super(BaseAsyncRestoreTest, cls).tearDownClass()

    def _restore_config(self,
                        async=True,
                        sync_log_id='',
                        overwrite_cache=False):
        restore_config = RestoreConfig(
            project=self.project,
            restore_user=self.user,
            params=RestoreParams(sync_log_id=sync_log_id, version=V2),
            cache_settings=RestoreCacheSettings(
                overwrite_cache=overwrite_cache),
            is_async=async)
        self.addCleanup(get_redis_default_cache().clear)
        return restore_config


class AsyncRestoreTestCouchOnly(BaseAsyncRestoreTest):
    @mock.patch('casexml.apps.phone.restore.get_async_restore_payload')
    def test_regular_restore_doesnt_start_task(self, task):
        """
        when the feature flag is off, the celery task does not get called
        """
        self._restore_config(async=False).get_payload()
        self.assertFalse(task.delay.called)
Exemplo n.º 27
0
def _dummy_restore_state(force_restore_mode=None):
    return RestoreState(
        project=Domain(name='clean'),
        user=CommCareUser(username='******'),
        params=RestoreParams(force_restore_mode=force_restore_mode))
Exemplo n.º 28
0
def get_restore_response(domain,
                         couch_user,
                         app_id=None,
                         since=None,
                         version='1.0',
                         state=None,
                         items=False,
                         force_cache=False,
                         cache_timeout=None,
                         overwrite_cache=False,
                         force_restore_mode=None,
                         as_user=None,
                         device_id=None,
                         user_id=None,
                         has_data_cleanup_privelege=False,
                         openrosa_version=OPENROSA_DEFAULT_VERSION):

    if user_id and user_id != couch_user.user_id:
        # sync with a user that has been deleted but a new
        # user was created with the same username and password
        from couchforms.openrosa_response import get_simple_response_xml
        from couchforms.openrosa_response import ResponseNature
        response = get_simple_response_xml(
            'Attempt to sync with invalid user.',
            ResponseNature.OTA_RESTORE_ERROR)
        return HttpResponse(response,
                            content_type="text/xml; charset=utf-8",
                            status=412), None

    # not a view just a view util
    is_permitted, message = is_permitted_to_restore(
        domain,
        couch_user,
        as_user,
        has_data_cleanup_privelege,
    )
    if not is_permitted:
        return HttpResponse(message, status=401), None

    is_demo_restore = couch_user.is_commcare_user() and couch_user.is_demo_user
    is_enikshay = toggles.ENIKSHAY.enabled(domain)
    if is_enikshay:
        couch_restore_user = couch_user
        if not is_demo_restore and as_user is not None:
            couch_restore_user = CouchUser.get_by_username(as_user)
        update_device_id(couch_restore_user, device_id)

    if is_demo_restore:
        # if user is in demo-mode, return demo restore
        return demo_user_restore_response(couch_user), None

    restore_user = get_restore_user(domain, couch_user, as_user)
    if not restore_user:
        return HttpResponse('Could not find user', status=404), None

    project = Domain.get_by_name(domain)
    app = get_app(domain, app_id) if app_id else None
    async_restore_enabled = (toggles.ASYNC_RESTORE.enabled(domain) and
                             LooseVersion(openrosa_version) >= LooseVersion(
                                 OPENROSA_VERSION_MAP['ASYNC_RESTORE']))
    restore_config = RestoreConfig(
        project=project,
        restore_user=restore_user,
        params=RestoreParams(
            sync_log_id=since,
            version=version,
            state_hash=state,
            include_item_count=items,
            app=app,
            device_id=device_id,
        ),
        cache_settings=RestoreCacheSettings(force_cache=force_cache
                                            or async_restore_enabled,
                                            cache_timeout=cache_timeout,
                                            overwrite_cache=overwrite_cache),
        async=async_restore_enabled)
    return restore_config.get_response(), restore_config.timing_context
Exemplo n.º 29
0
    def testUserRestoreWithCase(self):
        file_path = os.path.join(os.path.dirname(__file__),
                                 "data", "create_short.xml")
        with open(file_path, "rb") as f:
            xml_data = f.read()
        form = post_xform_to_couch(xml_data, domain=self.project.name)
        # implicit length assertion
        [newcase] = process_cases(form)
        user = dummy_user()

        self.assertEqual(1, len(list(
            BatchedCaseSyncOperation(RestoreState(self.project, user, RestoreParams())).get_all_case_updates()
        )))
        expected_case_block = """
        <case>
            <case_id>asdf</case_id>
            <date_modified>2010-06-29T13:42:50.000000Z</date_modified>
            <create>
                <case_type_id>test_case_type</case_type_id>
                <user_id>foo</user_id>
                <case_name>test case name</case_name>
                <external_id>someexternal</external_id>
            </create>
        </case>"""
        check_xml_line_by_line(self, expected_case_block, xml.get_case_xml(newcase, [case_const.CASE_ACTION_CREATE,
                                                                                     case_const.CASE_ACTION_UPDATE]))

        # check v2
        expected_v2_case_block = """
        <case case_id="asdf" date_modified="2010-06-29T13:42:50.000000Z" user_id="foo" xmlns="http://commcarehq.org/case/transaction/v2" >
            <create>
                <case_type>test_case_type</case_type>
                <case_name>test case name</case_name>
                <owner_id>foo</owner_id>
            </create>
            <update>
                <external_id>someexternal</external_id>
            </update>
        </case>"""
        check_xml_line_by_line(
            self,
            expected_v2_case_block,
            xml.get_case_xml(
                newcase,
                [case_const.CASE_ACTION_CREATE, case_const.CASE_ACTION_UPDATE],
                version="2.0",
            ),
        )

        restore_payload = generate_restore_payload(
            project=self.project,
            user=dummy_user(),
            items=True,
        )
        sync_log_id = SyncLog.view(
            "phone/sync_logs_by_user",
            include_docs=True,
            reduce=False,
        ).one().get_id
        check_xml_line_by_line(
            self,
            dummy_restore_xml(sync_log_id, expected_case_block, items=4),
            restore_payload
        )
Exemplo n.º 30
0
def prime_restore(domain, usernames_or_ids, version=V1, cache_timeout_hours=None,
                  overwrite_cache=False, check_cache_only=False):
    """
    Task to generate and cache a restore payload for each user passed in.

    :param domain:              The domain name for the users
    :param usernames_or_ids:    List of usernames or user IDs
    :param version:             Restore format version
    :param cache_timeout_hours: Hours to cache the payload
    :param overwrite_cache:     If True overwrite any existing cache
    :param check_cache_only:    Don't generate the payload, just check if it is already cached
    """
    total = len(usernames_or_ids)
    DownloadBase.set_progress(prime_restore, 0, total)

    ret = {'messages': []}
    for i, username_or_id in enumerate(usernames_or_ids):
        couch_user = get_user(username_or_id, domain)
        if not couch_user:
            ret['messages'].append('WARNING: User not found: {}'.format(username_or_id))
            continue
        elif couch_user.domain != domain:
            ret['messages'].append("WARNING: User '{}' not from domain '{}'".format(
                username_or_id,
                domain
            ))
            continue

        try:
            project = couch_user.project
            restore_config = RestoreConfig(
                project=project,
                user=couch_user.to_casexml_user(),
                params=RestoreParams(
                    version=version,
                    include_item_count=True,
                ),
                cache_settings=RestoreCacheSettings(
                    force_cache=True,
                    cache_timeout=cache_timeout_hours * 60 * 60,
                    overwrite_cache=overwrite_cache
                )
            )

            if check_cache_only:
                cached_payload = _get_cached_payload(restore_config)
                ret['messages'].append(u'Restore cache {} for user: {}'.format(
                    'EXISTS' if cached_payload else 'does not exist',
                    couch_user.human_friendly_name,
                ))
            else:
                restore_config.get_payload()

                cached_payload = _get_cached_payload(restore_config)
                if cached_payload:
                    ret['messages'].append('SUCCESS: Restore cached successfully for user: {}'.format(
                        couch_user.human_friendly_name,
                    ))
                else:
                    ret['messages'].append('ERROR: Restore completed by cache still empty for user: {}'.format(
                        couch_user.human_friendly_name,
                    ))
        except Exception as e:
            ret['messages'].append('ERROR: Error processing user: {}'.format(str(e)))

        DownloadBase.set_progress(prime_restore, i + 1, total)

    return ret
Exemplo n.º 31
0
def get_restore_response(domain,
                         couch_user,
                         app_id=None,
                         since=None,
                         version='1.0',
                         state=None,
                         items=False,
                         force_cache=False,
                         cache_timeout=None,
                         overwrite_cache=False,
                         as_user=None,
                         device_id=None,
                         user_id=None,
                         openrosa_version=None,
                         case_sync=None):

    if user_id and user_id != couch_user.user_id:
        # sync with a user that has been deleted but a new
        # user was created with the same username and password
        from couchforms.openrosa_response import get_simple_response_xml
        from couchforms.openrosa_response import ResponseNature
        response = get_simple_response_xml(
            'Attempt to sync with invalid user.',
            ResponseNature.OTA_RESTORE_ERROR)
        return HttpResponse(response,
                            content_type="text/xml; charset=utf-8",
                            status=412), None

    is_demo_restore = couch_user.is_commcare_user() and couch_user.is_demo_user
    if is_demo_restore:
        # if user is in demo-mode, return demo restore
        return demo_user_restore_response(couch_user), None

    uses_login_as = bool(as_user)
    as_user_obj = CouchUser.get_by_username(as_user) if uses_login_as else None
    if uses_login_as and not as_user_obj:
        msg = _('Invalid restore as user {}').format(as_user)
        return HttpResponse(msg, status=401), None
    is_permitted, message = is_permitted_to_restore(
        domain,
        couch_user,
        as_user_obj,
    )
    if not is_permitted:
        return HttpResponse(message, status=401), None

    restore_user = get_restore_user(domain, couch_user, as_user_obj)
    if not restore_user:
        return HttpResponse('Could not find user', status=404), None

    project = Domain.get_by_name(domain)
    async_restore_enabled = (toggles.ASYNC_RESTORE.enabled(domain)
                             and openrosa_version and
                             LooseVersion(openrosa_version) >= LooseVersion(
                                 OPENROSA_VERSION_MAP['ASYNC_RESTORE']))

    app = get_app_cached(domain, app_id) if app_id else None
    restore_config = RestoreConfig(
        project=project,
        restore_user=restore_user,
        params=RestoreParams(
            sync_log_id=since,
            version=version,
            state_hash=state,
            include_item_count=items,
            app=app,
            device_id=device_id,
            openrosa_version=openrosa_version,
        ),
        cache_settings=RestoreCacheSettings(force_cache=force_cache
                                            or async_restore_enabled,
                                            cache_timeout=cache_timeout,
                                            overwrite_cache=overwrite_cache),
        async=async_restore_enabled,
        case_sync=case_sync,
    )
    return restore_config.get_response(), restore_config.timing_context