Пример #1
0
    def dispatch(self, request, *args, **kwargs):

        participant_code = kwargs.pop(constants.participant_code)

        if otree.common_internal.USE_REDIS:
            lock = redis_lock.Lock(otree.common_internal.get_redis_conn(),
                                   participant_code,
                                   expire=60,
                                   auto_renewal=True)
        else:
            lock = participant_lock(participant_code)

        with lock, otree.db.idmap.use_cache():
            try:
                participant = Participant.objects.get(code=participant_code)
            except Participant.DoesNotExist:
                msg = ("This user ({}) does not exist in the database. "
                       "Maybe the database was recreated."
                       ).format(participant_code)
                raise Http404(msg)

            # if the player tried to skip past a part of the subsession
            # (e.g. by typing in a future URL)
            # or if they hit the back button to a previous subsession
            # in the sequence.
            url_should_be_on = participant._url_i_should_be_on()
            if not self.request.path == url_should_be_on:
                return HttpResponseRedirect(url_should_be_on)

            self.set_attributes(participant)

            self.participant._current_page_name = self.__class__.__name__
            response = super(FormPageOrInGameWaitPageMixin,
                             self).dispatch(request, *args, **kwargs)
            self.participant._last_request_timestamp = time.time()

            # need to render the response before saving objects,
            # because the template might call a method that modifies
            # player/group/etc.
            if hasattr(response, 'render'):
                response.render()
            self.save_objects()
            if (self.session.use_browser_bots and 'browser-bot-auto-submit'
                    in response.content.decode('utf-8')):
                bot = EphemeralBrowserBot(self)
                bot.prepare_next_submit(response.content.decode('utf-8'))
            return response
Пример #2
0
    def post(self, request, *args, **kwargs):

        self.object = self.get_object()

        if request.POST.get(constants.auto_submit):
            self.timeout_happened = True  # for public API
            self._set_auto_submit_values()
        else:
            self.timeout_happened = False
            if self.session.use_browser_bots:
                bot = EphemeralBrowserBot(self)
                try:
                    submission = bot.get_next_post_data()
                except StopIteration:
                    bot.send_completion_message()
                    return HttpResponse('Bot completed')
                else:
                    post_data = dict(request.POST)
                    post_data.update(submission)
            else:
                post_data = request.POST

            form = self.get_form(data=post_data,
                                 files=request.FILES,
                                 instance=self.object)
            is_bot = self.participant._is_bot
            if form.is_valid():
                if is_bot and post_data.get('must_fail'):
                    # clean up noise in post data
                    post_data.pop('csrfmiddlewaretoken', None)
                    post_data.pop('origin_url', None)
                    post_data.pop('must_fail', None)
                    raise AssertionError(
                        'Bot tried to submit intentionally invalid data with '
                        'SubmissionMustFail, but it passed validation anyway:'
                        ' {}.'.format(dict(post_data)))
                self.form = form
                self.object = form.save()
            else:
                if is_bot and not post_data.get('must_fail'):
                    errors = [
                        "{}: {}".format(k, repr(v))
                        for k, v in form.errors.items()
                    ]
                    raise AssertionError(
                        'Bot submission failed form validation: {} '
                        'Check your bot in tests.py, '
                        'then create a new session.'.format(errors))
                return self.form_invalid(form)
        self.before_next_page()
        if self.session.use_browser_bots:
            if self._index_in_pages == self.participant._max_page_index:
                bot = EphemeralBrowserBot(self)
                try:
                    bot.prepare_next_submit(html='')
                    submission = bot.get_next_post_data()
                except StopIteration:
                    bot.send_completion_message()
                    return HttpResponse('Bot completed')
                else:
                    raise AssertionError(
                        'Finished the last page, '
                        'but the bot is still trying '
                        'to submit more data ({}).'.format(submission))
        self._increment_index_in_pages()
        return self._redirect_to_page_the_user_should_be_on()
Пример #3
0
    def post(self, request, *args, **kwargs):

        self.object = self.get_object()

        auto_submitted = request.POST.get(constants.auto_submit)

        # if the page doesn't have a timeout_seconds, only the timeoutworker
        # should be able to auto-submit it.
        # otherwise users could append auto_submit to the URL to skip pages
        has_secret_code = (request.POST.get(
            constants.admin_secret_code) == ADMIN_SECRET_CODE)

        if auto_submitted and (self.has_timeout() or has_secret_code):
            self.timeout_happened = True  # for public API
            self._set_auto_submit_values()
        else:
            self.timeout_happened = False
            if self.session.use_browser_bots:
                bot = EphemeralBrowserBot(self)
                try:
                    submission = bot.get_next_post_data()
                except StopIteration:
                    bot.send_completion_message()
                    return HttpResponse('Bot completed')
                else:
                    # convert MultiValueKeyDict to regular dict
                    # so that we can add entries to it in a simple way
                    # before, we used dict(request.POST), but that caused
                    # errors with BooleanFields with blank=True that were
                    # submitted empty...it said [''] is not a valid value
                    post_data = request.POST.dict()
                    post_data.update(submission)
            else:
                post_data = request.POST

            form = self.get_form(data=post_data,
                                 files=request.FILES,
                                 instance=self.object)
            is_bot = self.participant._is_bot
            if form.is_valid():
                if is_bot and post_data.get('must_fail'):
                    raise AssertionError(
                        'Page "{}": Bot tried to submit intentionally invalid '
                        'data with '
                        'SubmissionMustFail, but it passed validation anyway:'
                        ' {}.'.format(self.__class__.__name__,
                                      bot_prettify_post_data(post_data)))
                self.form = form
                self.object = form.save()
            else:
                if is_bot and not post_data.get('must_fail'):
                    errors = [
                        "{}: {}".format(k, repr(v))
                        for k, v in form.errors.items()
                    ]
                    raise AssertionError(
                        'Page "{}": Bot submission failed form validation: {} '
                        'Check your bot in tests.py, '
                        'then create a new session. '
                        'Data submitted was: {}'.format(
                            self.__class__.__name__,
                            errors,
                            bot_prettify_post_data(post_data),
                        ))
                return self.form_invalid(form)
        self.before_next_page()
        if self.session.use_browser_bots:
            if self._index_in_pages == self.participant._max_page_index:
                bot = EphemeralBrowserBot(self)
                try:
                    bot.prepare_next_submit(html='')
                    submission = bot.get_next_post_data()
                except StopIteration:
                    bot.send_completion_message()
                    return HttpResponse('Bot completed')
                else:
                    raise AssertionError(
                        'Finished the last page, '
                        'but the bot is still trying '
                        'to submit more data ({}).'.format(submission))
        self._increment_index_in_pages()
        return self._redirect_to_page_the_user_should_be_on()