Ejemplo n.º 1
0
    def test_done_saves_anonymised_qs(self, mockEvalRow, mockReport):
        self.maxDiff = None

        radio_button_q = RadioButton.objects.create(text="this is a radio button question", page=self.page2)
        for i in range(5):
            Choice.objects.create(text="This is choice %i" % i, question = radio_button_q)
        wizard = EncryptedFormWizard.wizard_factory()()

        PageOneForm = wizard.form_list[0]
        PageTwoForm = wizard.form_list[1]
        KeyForm = wizard.form_list[2]

        page_one = PageOneForm({'question_%i' % self.question1.pk: 'test answer'})
        page_one.is_valid()
        page_two = PageTwoForm({'question_%i' % self.question2.pk: 'another answer to a different question',
                                'question_%i' % radio_button_q.pk: radio_button_q.choice_set.all()[2].pk})
        page_two.is_valid()
        key_form = KeyForm({'key': self.report_key, 'key2': self.report_key})
        key_form.is_valid()

        mock_report = Report()
        mock_report.save = Mock()
        mock_report.owner = self.request.user
        mockReport.return_value = mock_report

        mock_eval_row = EvalRow()
        mock_eval_row.save = Mock()
        mockEvalRow.return_value = mock_eval_row

        self._get_wizard_response(wizard, form_list=[page_one, page_two, key_form], request = self.request)
        mock_eval_row.save.assert_any_call()
Ejemplo n.º 2
0
    def setUp(self):
        super(ExistingRecordTest, self).setUp()

        User.objects.create_user(username='******', password='******')
        self.client.login(username='******', password='******')
        self.request = HttpRequest()
        self.request.GET = {}
        self.request.method = 'GET'
        self.request.user = User.objects.get(username='******')

        self.report_text = """[
    { "answer": "test answer",
      "id": %i,
      "section": 1,
      "question_text": "first question",
      "type": "SingleLineText"
    },
    { "answer": "another answer to a different question",
      "id": %i,
      "section": 1,
      "question_text": "2nd question",
      "type": "SingleLineText"
    }
  ]""" % (self.question1.pk, self.question2.pk)
        self.report = Report(owner=self.request.user)
        self.report_key = 'bananabread! is not my key'
        self.report.encrypt_report(self.report_text, self.report_key)
        self.report.save()
        row = EvalRow()
        row.anonymise_record(action=EvalRow.CREATE, report=self.report, decrypted_text=self.report_text)
        row.save()
Ejemplo n.º 3
0
    def done(self, form_list, **kwargs):
        req = kwargs.get('request') or self.request

        if self.object_to_edit:
            report = self.object_to_edit
        elif self.storage.extra_data.get('report_id'):
            report = Report.objects.get(id=self.storage.extra_data.get('report_id'))
        else:
            report = Report(owner=req.user)

        if not report.owner == req.user:
            self._unauthorized_access(req, report)

        key = list(form_list)[0].cleaned_data['key']

        report_text = json.dumps(self.processed_answers, sort_keys=True)
        report.encrypt_report(report_text, key, self.object_to_edit)
        report.save()

        # save anonymised answers
        if self.object_to_edit:
            EvalRow.store_eval_row(action=EvalRow.EDIT, report=report, decrypted_text=report_text)
        else:
            EvalRow.store_eval_row(action=EvalRow.CREATE, report=report, decrypted_text=report_text)

        return self.wizard_complete(report, **kwargs)
Ejemplo n.º 4
0
    def done(self, form_list, **kwargs):
        req = kwargs.get('request') or self.request
        report = Report(owner=req.user)
        if self.object_to_edit:
            if self.object_to_edit.owner == req.user:
                report = self.object_to_edit
            else:
                return HttpResponseForbidden()

        key = list(form_list)[-1].cleaned_data['key']

        report_text = json.dumps(self.processed_answers, sort_keys=True)
        report.encrypt_report(report_text, key)
        report.save()

        #save anonymised answers
        try:
            if self.object_to_edit:
                action = EvalRow.EDIT
            else:
                action = EvalRow.CREATE
            row = EvalRow()
            row.anonymise_record(action=action, report=report, decrypted_text=report_text)
            row.save()
        except Exception:
            logger.exception("couldn't save evaluation row on record creation")
            pass

        return self.wizard_complete(report, **kwargs)
Ejemplo n.º 5
0
def submit_to_matching(request, report_id, form_template_name="submit_to_matching.html",
                       confirmation_template_name="submit_to_matching_confirmation.html",
                       report_class=PDFMatchReport):
    owner = request.user
    report = Report.objects.get(id=report_id)
    if owner == report.owner:
        if request.method == 'POST':
            form = SubmitToSchoolForm(owner, report, request.POST)
            formset = SubmitToMatchingFormSet(request.POST)
            form.report = report
            if form.is_valid() and formset.is_valid():
                try:
                    match_reports = []
                    for perp_form in formset:
                        #enter into matching
                        match_report = MatchReport(report=report)
                        match_report.contact_name = conditional_escape(form.cleaned_data.get('name'))
                        match_report.contact_email = form.cleaned_data.get('email')
                        match_report.contact_phone = conditional_escape(form.cleaned_data.get('phone_number'))
                        match_report.contact_voicemail = conditional_escape(form.cleaned_data.get('voicemail'))
                        match_report.contact_notes = conditional_escape(form.cleaned_data.get('contact_notes'))
                        match_report.identifier = perp_form.cleaned_data.get('perp')
                        match_report.name = conditional_escape(perp_form.cleaned_data.get('perp_name'))
                        match_reports.append(match_report)
                    MatchReport.objects.bulk_create(match_reports)
                    if settings.MATCH_IMMEDIATELY:
                        find_matches(report_class=report_class)
                except Exception:
                    logger.exception("couldn't submit match report for report {}".format(report_id))
                    return render(request, form_template_name, {'form': form, 'formset': formset,
                                                                'school_name': settings.SCHOOL_SHORTNAME,
                                                                'submit_error': True})

                #record matching submission in anonymous evaluation data
                try:
                    row = EvalRow()
                    row.anonymise_record(action=EvalRow.MATCH, report=report)
                    row.save()
                except Exception:
                    logger.exception("couldn't save evaluation row on match submission")
                    pass

                try:
                    _send_user_notification(form, 'match_confirmation')
                except Exception:
                    # matching was entered even if confirmation email fails, so don't show an error if so
                    logger.exception("couldn't send confirmation to user on match submission")

                return render(request, confirmation_template_name, {'school_name': settings.SCHOOL_SHORTNAME,
                                                                                    'report': report})

        else:
            form = SubmitToSchoolForm(owner, report)
            formset = SubmitToMatchingFormSet()
        return render(request, form_template_name, {'form': form, 'formset': formset,
                                                           'school_name': settings.SCHOOL_SHORTNAME})
    else:
        logger.warning("illegal matching attempt on record {} by user {}".format(report_id, owner.id))
        return HttpResponseForbidden()
Ejemplo n.º 6
0
 def clean_key(self):
     key = self.cleaned_data.get('key')
     report = self.report
     try:
         decrypted_report = report.decrypted_report(key)
         self.decrypted_report = decrypted_report
         #save anonymous row if one wasn't saved on creation
         try:
             row = EvalRow()
             row.set_identifiers(report)
             if (EvalRow.objects.filter(
                     record_identifier=row.record_identifier).count() == 0):
                 row.action = EvalRow.FIRST
                 row.add_report_data(decrypted_report)
                 row.save()
         except Exception:
             logger.exception(
                 "couldn't save anonymous row on catch-up save")
             pass
     except CryptoError:
         self.decrypted_report = None
         logger.info("decryption failure on report {}".format(report.id))
         raise forms.ValidationError(
             self.error_messages['wrong_key'],
             code='wrong_key',
         )
     return key
Ejemplo n.º 7
0
 def clean_key(self):
     key = self.cleaned_data.get('key')
     report = self.report
     try:
         decrypted_report = report.decrypted_report(key)
         self.decrypted_report = decrypted_report
         #save anonymous row if one wasn't saved on creation
         try:
             row = EvalRow()
             row.set_identifiers(report)
             if (EvalRow.objects.filter(
                     record_identifier=row.record_identifier).count() == 0):
                 row.action = EvalRow.FIRST
                 row.add_report_data(decrypted_report)
                 row.save()
         except Exception as e:
             #TODO: real logging
             bugsnag.notify(e)
             pass
     except CryptoError:
         self.decrypted_report = None
         raise forms.ValidationError(
             self.error_messages['wrong_key'],
             code='wrong_key',
         )
     return key
Ejemplo n.º 8
0
 def test_can_encrypt_a_row(self):
     user = User.objects.create_user(username="******", password="******")
     report = Report.objects.create(owner=user, encrypted=b'first report')
     row = EvalRow(action=EvalRow.CREATE)
     row.set_identifiers(report)
     test_row = "{'test_field': 'test_answer'}"
     row._encrypt_eval_row(test_row)
     row.save()
     row.full_clean()
     self.assertEqual(EvalRow.objects.count(), 1)
     self.assertIsNotNone(EvalRow.objects.get(id=row.pk).row)
     self.assertNotEqual(EvalRow.objects.get(id=row.pk).row, test_row)
Ejemplo n.º 9
0
 def test_can_decrypt_a_row(self):
     gpg = gnupg.GPG()
     test_key = gpg.import_keys(private_test_key)
     self.addCleanup(delete_test_key, gpg, test_key.fingerprints[0])
     user = User.objects.create_user(username="******", password="******")
     report = Report.objects.create(owner=user, encrypted=b'first report')
     row = EvalRow(action=EvalRow.CREATE)
     row.set_identifiers(report)
     test_row = "{'test_field': 'test_answer'}"
     row._encrypt_eval_row(test_row, key=public_test_key)
     row.save()
     row.full_clean()
     self.assertEqual(str(gpg.decrypt(EvalRow.objects.get(id=row.pk).row)),
                      test_row)
Ejemplo n.º 10
0
 def clean_key(self):
     key = self.cleaned_data.get('key')
     report = self.report
     try:
         decrypted_report = report.decrypted_report(key)
         self.decrypted_report = decrypted_report
         #save anonymous row if one wasn't saved on creation
         try:
             row = EvalRow()
             row.set_identifiers(report)
             if (EvalRow.objects.filter(record_identifier = row.record_identifier).count() == 0):
                 row.action = EvalRow.FIRST
                 row.add_report_data(decrypted_report)
                 row.save()
         except Exception as e:
             #TODO: real logging
             bugsnag.notify(e)
             pass
     except CryptoError:
         self.decrypted_report = None
         raise forms.ValidationError(
             self.error_messages['wrong_key'],
             code='wrong_key',
         )
     return key
Ejemplo n.º 11
0
 def clean_key(self):
     key = self.cleaned_data.get('key')
     report = self.report
     try:
         decrypted_report = report.decrypted_report(key)
         self.decrypted_report = decrypted_report
         #save anonymous row if one wasn't saved on creation
         try:
             row = EvalRow()
             row.set_identifiers(report)
             if (EvalRow.objects.filter(record_identifier = row.record_identifier).count() == 0):
                 row.action = EvalRow.FIRST
                 row.add_report_data(decrypted_report)
                 row.save()
         except Exception:
             logger.exception("couldn't save anonymous row on catch-up save")
             pass
     except CryptoError:
         self.decrypted_report = None
         logger.info("decryption failure on report {}".format(report.id))
         raise forms.ValidationError(
             self.error_messages['wrong_key'],
             code='wrong_key',
         )
     return key
Ejemplo n.º 12
0
 def test_can_encrypt_a_row(self):
     user = User.objects.create_user(username="******", password="******")
     report = Report.objects.create(owner=user, encrypted=b'first report')
     row = EvalRow(action=EvalRow.CREATE)
     row.set_identifiers(report)
     test_row = "{'test_field': 'test_answer'}"
     row._encrypt_eval_row(test_row)
     row.save()
     row.full_clean()
     self.assertEqual(EvalRow.objects.count(), 1)
     self.assertIsNotNone(EvalRow.objects.get(id=row.pk).row)
     self.assertNotEqual(EvalRow.objects.get(id=row.pk).row, test_row)
Ejemplo n.º 13
0
 def test_can_decrypt_a_row(self):
     gpg = gnupg.GPG()
     test_key = gpg.import_keys(private_test_key)
     self.addCleanup(delete_test_key, gpg, test_key.fingerprints[0])
     user = User.objects.create_user(username="******", password="******")
     report = Report.objects.create(owner=user, encrypted=b'first report')
     row = EvalRow(action=EvalRow.CREATE)
     row.set_identifiers(report)
     test_row = "{'test_field': 'test_answer'}"
     row._encrypt_eval_row(test_row, key = public_test_key)
     row.save()
     row.full_clean()
     self.assertEqual(six.text_type(gpg.decrypt(six.binary_type(EvalRow.objects.get(id=row.pk).row))), test_row)
Ejemplo n.º 14
0
def submit_to_school(request, report_id, form_template_name="submit_to_school.html",
                     confirmation_template_name="submit_to_school_confirmation.html",
                     report_class=PDFFullReport):
    owner = request.user
    report = Report.objects.get(id=report_id)
    if owner == report.owner:
        if request.method == 'POST':
            form = SubmitToSchoolForm(owner, report, request.POST)
            form.report = report
            if form.is_valid():
                try:
                    report.contact_name = conditional_escape(form.cleaned_data.get('name'))
                    report.contact_email = form.cleaned_data.get('email')
                    report.contact_phone = conditional_escape(form.cleaned_data.get('phone_number'))
                    report.contact_voicemail = conditional_escape(form.cleaned_data.get('voicemail'))
                    report.contact_notes = conditional_escape(form.cleaned_data.get('contact_notes'))
                    report_class(report=report, decrypted_report=form.decrypted_report).send_report_to_school()
                    report.save()
                except Exception:
                    logger.exception("couldn't submit report for report {}".format(report_id))
                    return render(request, form_template_name, {'form': form, 'school_name': settings.SCHOOL_SHORTNAME,
                                                                                  'submit_error': True})

                #record submission in anonymous evaluation data
                try:
                    row = EvalRow()
                    row.anonymise_record(action=EvalRow.SUBMIT, report=report)
                    row.save()
                except Exception:
                    logger.exception("couldn't save evaluation row on submission")
                    pass

                try:
                    _send_user_notification(form, 'submit_confirmation')
                except Exception:
                    # report was sent even if confirmation email fails, so don't show an error if so
                    logger.exception("couldn't send confirmation to user on submission")

                return render(request, confirmation_template_name, {'form': form, 'school_name': settings.SCHOOL_SHORTNAME,
                                                                                  'report': report})
        else:
            form = SubmitToSchoolForm(owner, report)
        return render(request, form_template_name, {'form': form, 'school_name': settings.SCHOOL_SHORTNAME})
    else:
        logger.warning("illegal submit attempt on record {} by user {}".format(report_id, owner.id))
        return HttpResponseForbidden()
Ejemplo n.º 15
0
    def test_anonymise_record_end_to_end(self):
        self.maxDiff = None

        self.set_up_simple_report_scenario()

        user = User.objects.create_user(username="******", password="******")
        report = Report.objects.create(owner=user, encrypted=b'dummy report')

        gpg = gnupg.GPG()
        test_key = gpg.import_keys(private_test_key)
        self.addCleanup(delete_test_key, gpg, test_key.fingerprints[0])

        row = EvalRow()
        row.anonymise_record(action=EvalRow.CREATE, report=report, decrypted_text=self.json_report,
                             key = public_test_key)
        row.save()

        self.assertEqual(json.loads(six.text_type(gpg.decrypt(six.binary_type(EvalRow.objects.get(id=row.pk).row)))), self.expected)
Ejemplo n.º 16
0
    def test_tracking_of_answered_questions(self):
        self.maxDiff = None

        page1 = QuestionPage.objects.create()
        question1 = SingleLineText.objects.create(text="first question",
                                                  page=page1)
        question2 = SingleLineText.objects.create(text="2nd question",
                                                  page=page1)
        radio_button_q = RadioButton.objects.create(
            text="this is a radio button question", page=page1)
        for i in range(5):
            Choice.objects.create(text="This is choice %i" % i,
                                  question=radio_button_q)

        choice_ids = [choice.pk for choice in radio_button_q.choice_set.all()]
        object_ids = [
            question1.pk,
            question2.pk,
            radio_button_q.pk,
        ] + choice_ids

        json_report = json.loads("""[
    { "answer": "test answer",
      "id": %i,
      "section": 1,
      "question_text": "first question",
      "type": "SingleLineText"
    },
    { "answer": " ",
      "id": %i,
      "section": 1,
      "question_text": "2nd question",
      "type": "SingleLineText"
    },
    { "answer": "",
      "id": %i,
      "section": 1,
      "question_text": "this is a radio button question",
            "choices": [{"id": %i, "choice_text": "This is choice 0"},
                  {"id": %i, "choice_text": "This is choice 1"},
                  {"id": %i, "choice_text": "This is choice 2"},
                  {"id": %i, "choice_text": "This is choice 3"},
                  {"id": %i, "choice_text": "This is choice 4"}],
      "type": "RadioButton"
    }
  ]""" % tuple(object_ids))

        expected = {
            "answered": [question1.pk],
            "unanswered": [question2.pk, radio_button_q.pk]
        }

        anonymised = EvalRow()._extract_answers(json_report)
        self.assertEqual(anonymised, expected)
Ejemplo n.º 17
0
 def auto_save(self, **kwargs):
     """
     Automatically save what's been entered so far before rendering the next step.
     We only do this on steps after the first non-key form because we can only save completed steps
     https://github.com/SexualHealthInnovations/callisto-core/issues/89
     """
     if not self.object_to_edit and int(self.steps.current) > 1:
         if self.storage.extra_data.get('report_id'):
             report = Report.objects.get(id=self.storage.extra_data.get('report_id'))
         else:
             req = kwargs.get('request') or self.request
             report = Report(owner=req.user)
         forms_so_far = self._get_forms_with_data()
         report_text = json.dumps(self.process_answers(forms_so_far.values(), form_dict=forms_so_far),
                                  sort_keys=True)
         key = forms_so_far['0'].cleaned_data['key']
         report.encrypt_report(report_text, key, edit=self.object_to_edit, autosave=True)
         report.save()
         self.storage.extra_data['report_id'] = report.id
         EvalRow.store_eval_row(action=EvalRow.AUTOSAVE, report=report, decrypted_text=report_text)
Ejemplo n.º 18
0
    def test_tracking_of_answered_questions_checkbox(self):
        self.maxDiff = None

        page1 = QuestionPage.objects.create()
        checkbox_q_1 = Checkbox.objects.create(
            text="this is a checkbox question", page=page1)
        for i in range(5):
            Choice.objects.create(text="This is choice %i" % i,
                                  question=checkbox_q_1)
        checkbox_q_2 = Checkbox.objects.create(
            text="this is another checkbox question", page=page1)
        for i in range(5):
            Choice.objects.create(text="This is choice %i" % i,
                                  question=checkbox_q_2)

        choice_ids_1 = [choice.pk for choice in checkbox_q_1.choice_set.all()]
        choice_ids_2 = [choice.pk for choice in checkbox_q_2.choice_set.all()]
        object_ids = [checkbox_q_1.pk] + choice_ids_1 + [
            choice_ids_2[1], choice_ids_2[3], checkbox_q_2.pk
        ] + choice_ids_2

        json_report = json.loads("""[
    { "answer": [],
      "id": %i,
      "section": 1,
      "question_text": "this is a checkbox question",
            "choices": [{"id": %i, "choice_text": "This is choice 0"},
                  {"id": %i, "choice_text": "This is choice 1"},
                  {"id": %i, "choice_text": "This is choice 2"},
                  {"id": %i, "choice_text": "This is choice 3"},
                  {"id": %i, "choice_text": "This is choice 4"}],
      "type": "Checkbox"
    },
    { "answer": ["%i", "%i"],
      "id": %i,
      "section": 1,
      "question_text": "this is another checkbox question",
            "choices": [{"id": %i, "choice_text": "This is choice 0"},
                  {"id": %i, "choice_text": "This is choice 1"},
                  {"id": %i, "choice_text": "This is choice 2"},
                  {"id": %i, "choice_text": "This is choice 3"},
                  {"id": %i, "choice_text": "This is choice 4"}],
      "type": "Checkbox"
    }
  ]""" % tuple(object_ids))

        expected = {
            "answered": [checkbox_q_2.pk],
            "unanswered": [checkbox_q_1.pk]
        }

        anonymised = EvalRow()._extract_answers(json_report)
        self.assertEqual(anonymised, expected)
Ejemplo n.º 19
0
    def test_done_saves_anonymised_qs(self, mockEvalRow, mockReport):
        self.maxDiff = None

        radio_button_q = RadioButton.objects.create(
            text="this is a radio button question", page=self.page2)
        for i in range(5):
            Choice.objects.create(text="This is choice %i" % i,
                                  question=radio_button_q)
        wizard = EncryptedFormWizard.wizard_factory()()

        PageOneForm = wizard.form_list[0]
        PageTwoForm = wizard.form_list[1]
        KeyForm = wizard.form_list[2]

        page_one = PageOneForm(
            {'question_%i' % self.question1.pk: 'test answer'})
        page_one.is_valid()
        page_two = PageTwoForm({
            'question_%i' % self.question2.pk:
            'another answer to a different question',
            'question_%i' % radio_button_q.pk:
            radio_button_q.choice_set.all()[2].pk
        })
        page_two.is_valid()
        key_form = KeyForm({'key': self.report_key, 'key2': self.report_key})
        key_form.is_valid()

        mock_report = Report()
        mock_report.save = Mock()
        mock_report.owner = self.request.user
        mockReport.return_value = mock_report

        mock_eval_row = EvalRow()
        mock_eval_row.save = Mock()
        mockEvalRow.return_value = mock_eval_row

        self._get_wizard_response(wizard,
                                  form_list=[page_one, page_two, key_form],
                                  request=self.request)
        mock_eval_row.save.assert_any_call()
Ejemplo n.º 20
0
    def done(self, form_list, **kwargs):
        req = kwargs.get('request') or self.request
        report = Report(owner=req.user)
        if self.object_to_edit:
            if self.object_to_edit.owner == req.user:
                report = self.object_to_edit
            else:
                return HttpResponseForbidden()

        key = list(form_list)[-1].cleaned_data['key']

        report_text = json.dumps(self.processed_answers, sort_keys=True)
        report.encrypt_report(report_text, key)
        report.save()

        #save anonymised answers
        try:
            if self.object_to_edit:
                action = EvalRow.EDIT
            else:
                action = EvalRow.CREATE
            row = EvalRow()
            row.anonymise_record(action=action, report=report, decrypted_text=report_text)
            row.save()
        except Exception as e:
            #TODO: real logging
            bugsnag.notify(e)
            pass

        #TODO: check if valid?
        return self.wizard_complete(report, **kwargs)
Ejemplo n.º 21
0
    def setUp(self):
        super(ExistingRecordTest, self).setUp()

        User.objects.create_user(username='******', password='******')
        self.client.login(username='******', password='******')
        self.request = HttpRequest()
        self.request.GET = {}
        self.request.method = 'GET'
        self.request.user = User.objects.get(username='******')

        self.report_text = """[
    { "answer": "test answer",
      "id": %i,
      "section": 1,
      "question_text": "first question",
      "type": "SingleLineText"
    },
    { "answer": "another answer to a different question",
      "id": %i,
      "section": 1,
      "question_text": "2nd question",
      "type": "SingleLineText"
    }
  ]""" % (self.question1.pk, self.question2.pk)
        self.report = Report(owner=self.request.user)
        self.report_key = 'bananabread! is not my key'
        self.report.encrypt_report(self.report_text, self.report_key)
        self.report.save()
        row = EvalRow()
        row.anonymise_record(action=EvalRow.CREATE,
                             report=self.report,
                             decrypted_text=self.report_text)
        row.save()
Ejemplo n.º 22
0
    def test_anonymise_record_end_to_end(self):
        self.maxDiff = None

        self.set_up_simple_report_scenario()

        user = User.objects.create_user(username="******", password="******")
        report = Report.objects.create(owner=user, encrypted=b'dummy report')

        gpg = gnupg.GPG()
        test_key = gpg.import_keys(private_test_key)
        self.addCleanup(delete_test_key, gpg, test_key.fingerprints[0])

        row = EvalRow()
        row.anonymise_record(action=EvalRow.CREATE,
                             report=report,
                             decrypted_text=self.json_report,
                             key=public_test_key)
        row.save()

        self.assertEqual(
            json.loads(
                six.text_type(
                    gpg.decrypt(
                        six.binary_type(EvalRow.objects.get(id=row.pk).row)))),
            self.expected)
Ejemplo n.º 23
0
def withdraw_from_matching(request, report_id, template_name):
    owner = request.user
    report = Report.objects.get(id=report_id)
    if owner == report.owner:
        report.withdraw_from_matching()
        report.save()

        # record match withdrawal in anonymous evaluation data
        try:
            row = EvalRow()
            row.anonymise_record(action=EvalRow.WITHDRAW, report=report)
            row.save()
        except Exception:
            logger.exception(
                "couldn't save evaluation row on match withdrawal")
            pass

        return render(
            request, template_name, {
                'owner': request.user,
                'school_name': settings.SCHOOL_SHORTNAME,
                'coordinator_name': settings.COORDINATOR_NAME,
                'coordinator_email': settings.COORDINATOR_EMAIL,
                'match_report_withdrawn': True
            })
    else:
        logger.warning(
            "illegal matching withdrawal attempt on record {} by user {}".
            format(report_id, owner.id))
        return HttpResponseForbidden()
Ejemplo n.º 24
0
def process_new_matches(matches, identifier, report_class):
    """Sends a report to the receiving authority and notifies the reporting users. Each user should only be notified
    one time when a match is found.

    Args:
      matches (list of MatchReports): the MatchReports that correspond to this identifier
      identifier (str): identifier associated with the MatchReports
      report_class(report generator class, optional): Must have `send_matching_report_to_school` method. (Default
      value = PDFMatchReport)
    """
    logger.info("new match found")
    owners_notified = []
    for match_report in matches:
        EvalRow.store_eval_row(action=EvalRow.MATCH_FOUND, report=match_report.report)
        owner = match_report.report.owner
        # only send notification emails to new matches
        if owner not in owners_notified and not match_report.report.match_found \
                and not match_report.report.submitted_to_school:
            send_notification_email(owner, match_report)
            owners_notified.append(owner)
    # send report to school
    report_class(matches, identifier).send_matching_report_to_school()
Ejemplo n.º 25
0
def withdraw_from_matching(request, report_id, template_name):
    owner = request.user
    report = Report.objects.get(id=report_id)
    if owner == report.owner:
        report.withdraw_from_matching()
        report.save()

        # record match withdrawal in anonymous evaluation data
        try:
            row = EvalRow()
            row.anonymise_record(action=EvalRow.WITHDRAW, report=report)
            row.save()
        except Exception:
            logger.exception("couldn't save evaluation row on match withdrawal")
            pass

        return render(request, template_name, {'owner': request.user, 'school_name': settings.SCHOOL_SHORTNAME,
                                                        'coordinator_name': settings.COORDINATOR_NAME,
                                                       'coordinator_email': settings.COORDINATOR_EMAIL,
                                                       'match_report_withdrawn': True})
    else:
        logger.warning("illegal matching withdrawal attempt on record {} by user {}".format(report_id, owner.id))
        return HttpResponseForbidden()
Ejemplo n.º 26
0
 def test_report_hashes_correctly(self):
     user1 = User.objects.create_user(username="******", password="******")
     report1 = Report.objects.create(owner=user1, encrypted=b'first report')
     user2 = User.objects.create_user(username="******", password="******")
     report2 = Report.objects.create(owner=user2, encrypted=b'second report')
     report3 = Report.objects.create(owner=user1, encrypted=b'third report')
     row1 = self.save_row_for_report(report1)
     row2 = self.save_row_for_report(report2)
     row3 = self.save_row_for_report(report3)
     row3_edit = EvalRow(action=EvalRow.EDIT)
     row3_edit.set_identifiers(report3)
     row3_edit.save()
     row3_edit.full_clean()
     self.assertEqual(EvalRow.objects.count(), 4)
     self.assertNotEqual(EvalRow.objects.get(id=row2.pk).record_identifier, EvalRow.objects.get(id=row3.pk).record_identifier)
     self.assertNotEqual(EvalRow.objects.get(id=row1.pk).record_identifier, EvalRow.objects.get(id=row2.pk).record_identifier)
     self.assertEqual(EvalRow.objects.get(id=row3.pk).record_identifier, EvalRow.objects.get(id=row3_edit.pk).record_identifier)
Ejemplo n.º 27
0
def submit_to_school(request, report_id):
    owner = request.user
    report = Report.objects.get(id=report_id)
    if owner == report.owner:
        if request.method == 'POST':
            form = SubmitToSchoolForm(owner, report, request.POST)
            form.report = report
            if form.is_valid():
                try:
                    report.contact_name = conditional_escape(form.cleaned_data.get('name'))
                    report.contact_email = form.cleaned_data.get('email')
                    report.contact_phone = conditional_escape(form.cleaned_data.get('phone_number'))
                    report.contact_voicemail = conditional_escape(form.cleaned_data.get('voicemail'))
                    report.contact_notes = conditional_escape(form.cleaned_data.get('contact_notes'))
                    PDFFullReport(owner, report, form.decrypted_report).send_report_to_school()
                    report.save()
                except Exception as e:
                    #TODO: real logging
                    bugsnag.notify(e)
                    return render(request, 'submit_to_school.html', {'form': form, 'school_name': settings.SCHOOL_SHORTNAME,
                                                                                  'submit_error': True})

                #record submission in anonymous evaluation data
                try:
                    row = EvalRow()
                    row.anonymise_record(action=EvalRow.SUBMIT, report=report)
                    row.save()
                except Exception as e:
                    #TODO: real logging
                    bugsnag.notify(e)
                    pass

                try:
                    if form.cleaned_data.get('email_confirmation') == "True":
                        notification = EmailNotification.objects.get(name='submit_confirmation')
                        preferred_email = form.cleaned_data.get('email')
                        to_email = set([owner.account.school_email, preferred_email])
                        from_email = '"Callisto Confirmation" <confirmation@{0}>'.format(settings.APP_URL)
                        notification.send(to=to_email, from_email=from_email)
                except Exception as e:
                    #TODO: real logging
                    # report was sent even if confirmation email fails, so don't show an error if so
                    bugsnag.notify(e)

                return render(request, 'submit_to_school_confirmation.html', {'form': form, 'school_name': settings.SCHOOL_SHORTNAME,
                                                                                  'report': report})
        else:
            form = SubmitToSchoolForm(owner, report)
        return render(request, 'submit_to_school.html', {'form': form, 'school_name': settings.SCHOOL_SHORTNAME})
    else:
        return HttpResponseForbidden()
Ejemplo n.º 28
0
 def test_report_hashes_correctly(self):
     user1 = User.objects.create_user(username="******", password="******")
     report1 = Report.objects.create(owner=user1, encrypted=b'first report')
     user2 = User.objects.create_user(username="******", password="******")
     report2 = Report.objects.create(owner=user2,
                                     encrypted=b'second report')
     report3 = Report.objects.create(owner=user1, encrypted=b'third report')
     row1 = self.save_row_for_report(report1)
     row2 = self.save_row_for_report(report2)
     row3 = self.save_row_for_report(report3)
     row3_edit = EvalRow(action=EvalRow.EDIT)
     row3_edit.set_identifiers(report3)
     row3_edit.save()
     row3_edit.full_clean()
     self.assertEqual(EvalRow.objects.count(), 4)
     self.assertNotEqual(
         EvalRow.objects.get(id=row2.pk).record_identifier,
         EvalRow.objects.get(id=row3.pk).record_identifier)
     self.assertNotEqual(
         EvalRow.objects.get(id=row1.pk).record_identifier,
         EvalRow.objects.get(id=row2.pk).record_identifier)
     self.assertEqual(
         EvalRow.objects.get(id=row3.pk).record_identifier,
         EvalRow.objects.get(id=row3_edit.pk).record_identifier)
Ejemplo n.º 29
0
def withdraw_from_matching(request, report_id):
    owner = request.user
    report = Report.objects.get(id=report_id)
    if owner == report.owner:
        report.withdraw_from_matching()
        report.save()

        #record match withdrawal in anonymous evaluation data
        try:
            row = EvalRow()
            row.anonymise_record(action=EvalRow.WITHDRAW, report=report)
            row.save()
        except Exception as e:
            #TODO: real logging
            bugsnag.notify(e)
            pass

        return render(request, 'dashboard.html', {'owner': request.user, 'school_name': settings.SCHOOL_SHORTNAME,
                                                        'coordinator_name': settings.COORDINATOR_NAME,
                                                       'coordinator_email': settings.COORDINATOR_EMAIL,
                                                       'match_report_withdrawn': True})
    else:
        return HttpResponseForbidden()
Ejemplo n.º 30
0
def submit_to_matching(request, report_id):
    owner = request.user
    report = Report.objects.get(id=report_id)
    if owner == report.owner:
        if request.method == 'POST':
            form = SubmitToSchoolForm(owner, report, request.POST)
            formset = SubmitToMatchingFormSet(request.POST)
            form.report = report
            if form.is_valid() and formset.is_valid():
                try:
                    match_reports = []
                    for perp_form in formset:
                        #enter into matching
                        match_report = MatchReport(report=report)
                        match_report.contact_name = conditional_escape(form.cleaned_data.get('name'))
                        match_report.contact_email = form.cleaned_data.get('email')
                        match_report.contact_phone = conditional_escape(form.cleaned_data.get('phone_number'))
                        match_report.contact_voicemail = conditional_escape(form.cleaned_data.get('voicemail'))
                        match_report.contact_notes = conditional_escape(form.cleaned_data.get('contact_notes'))
                        match_report.identifier = perp_form.cleaned_data.get('perp')
                        match_report.name = conditional_escape(perp_form.cleaned_data.get('perp_name'))
                        match_reports.append(match_report)
                    MatchReport.objects.bulk_create(match_reports)
                    if settings.MATCH_IMMEDIATELY:
                        find_matches()
                except Exception as e:
                    #TODO: real logging
                    bugsnag.notify(e)
                    return render(request, 'submit_to_matching.html', {'form': form, 'formset': formset,
                                                                       'school_name': settings.SCHOOL_SHORTNAME,
                                                                                  'submit_error': True})

                #record matching submission in anonymous evaluation data
                try:
                    row = EvalRow()
                    row.anonymise_record(action=EvalRow.MATCH, report=report)
                    row.save()
                except Exception as e:
                    #TODO: real logging
                    bugsnag.notify(e)
                    pass

                try:
                    if form.cleaned_data.get('email_confirmation') == "True":
                        notification = EmailNotification.objects.get(name='match_confirmation')
                        preferred_email = form.cleaned_data.get('email')
                        to_email = set([owner.account.school_email, preferred_email])
                        from_email = '"Callisto Confirmation" <confirmation@{0}>'.format(settings.APP_URL)
                        notification.send(to=to_email, from_email=from_email)
                except Exception as e:
                    #TODO: real logging
                    # matching was entered even if confirmation email fails, so don't show an error if so
                    bugsnag.notify(e)

                return render(request, 'submit_to_matching_confirmation.html', {'school_name': settings.SCHOOL_SHORTNAME,
                                                                                    'report': report})

        else:
            form = SubmitToSchoolForm(owner, report)
            formset = SubmitToMatchingFormSet()
        return render(request, 'submit_to_matching.html', {'form': form, 'formset': formset,
                                                           'school_name': settings.SCHOOL_SHORTNAME})
    else:
        return HttpResponseForbidden()
Ejemplo n.º 31
0
    def test_extract_answers_with_multiple(self):
        self.maxDiff = None

        page1 = QuestionPage.objects.create()
        single_question = SingleLineText.objects.create(text="single question",
                                                        page=page1)
        EvaluationField.objects.create(question=single_question,
                                       label="single_q")

        page2 = QuestionPage.objects.create(multiple=True,
                                            name_for_multiple="form")
        question1 = SingleLineText.objects.create(text="first question",
                                                  page=page2)
        question2 = SingleLineText.objects.create(text="2nd question",
                                                  page=page2)
        EvaluationField.objects.create(question=question2, label="q2")
        radio_button_q = RadioButton.objects.create(
            text="this is a radio button question", page=page2)
        for i in range(5):
            Choice.objects.create(text="This is choice %i" % i,
                                  question=radio_button_q)
        EvaluationField.objects.create(question=radio_button_q, label="radio")

        choice_ids = [choice.pk for choice in radio_button_q.choice_set.all()]
        selected_id_1 = choice_ids[1]
        selected_id_2 = choice_ids[4]
        object_ids = [
            question1.pk,
            question2.pk,
            radio_button_q.pk,
        ] + choice_ids

        answer_set_template = """[
    { "answer": "test answer <PREFIX> answer",
      "id": %i,
      "section": 1,
      "question_text": "first question",
      "type": "SingleLineText"
    },
    { "answer": "<PREFIX> answer to a different question",
      "id": %i,
      "section": 1,
      "question_text": "2nd question",
      "type": "SingleLineText"
    },
    { "answer": "<SELECTED>",
      "id": %i,
      "section": 1,
      "question_text": "this is a radio button question",
            "choices": [{"id": %i, "choice_text": "This is choice 0"},
                  {"id": %i, "choice_text": "This is choice 1"},
                  {"id": %i, "choice_text": "This is choice 2"},
                  {"id": %i, "choice_text": "This is choice 3"},
                  {"id": %i, "choice_text": "This is choice 4"}],
      "type": "RadioButton"
    }
  ]""" % tuple(object_ids)

        answer_set_one = answer_set_template.replace("<PREFIX>",
                                                     "first").replace(
                                                         "<SELECTED>",
                                                         str(selected_id_1))
        answer_set_two = answer_set_template.replace("<PREFIX>",
                                                     "second").replace(
                                                         "<SELECTED>",
                                                         str(selected_id_2))

        json_report = json.loads(
            """
      [ { "answer": "single answer",
          "id": %i,
          "section": 1,
          "question_text": "single question",
          "type": "SingleLineText"
        },
        { "answers" : [ %s, %s],
            "page_id" : %i,
            "prompt" : "form",
            "section" : 1,
            "type" : "FormSet"
        } ]""" %
            (single_question.pk, answer_set_one, answer_set_two, page2.pk))

        expected = {
            'single_q':
            'single answer',
            "answered": [single_question.pk],
            "unanswered": [],
            'form_multiple': [{
                "q2":
                "first answer to a different question",
                "radio":
                str(selected_id_1),
                "radio_choices": [{
                    "id": choice_ids[0],
                    "choice_text": "This is choice 0"
                }, {
                    "id": choice_ids[1],
                    "choice_text": "This is choice 1"
                }, {
                    "id": choice_ids[2],
                    "choice_text": "This is choice 2"
                }, {
                    "id": choice_ids[3],
                    "choice_text": "This is choice 3"
                }, {
                    "id": choice_ids[4],
                    "choice_text": "This is choice 4"
                }],
                "answered": [question1.pk, question2.pk, radio_button_q.pk],
                "unanswered": []
            }, {
                "q2":
                "second answer to a different question",
                "radio":
                str(selected_id_2),
                "radio_choices": [{
                    "id": choice_ids[0],
                    "choice_text": "This is choice 0"
                }, {
                    "id": choice_ids[1],
                    "choice_text": "This is choice 1"
                }, {
                    "id": choice_ids[2],
                    "choice_text": "This is choice 2"
                }, {
                    "id": choice_ids[3],
                    "choice_text": "This is choice 3"
                }, {
                    "id": choice_ids[4],
                    "choice_text": "This is choice 4"
                }],
                "answered": [question1.pk, question2.pk, radio_button_q.pk],
                "unanswered": []
            }]
        }
        anonymised = EvalRow()._extract_answers(json_report)
        self.assertEqual(anonymised, expected)
Ejemplo n.º 32
0
 def save_row_for_report(self, report):
     row = EvalRow(action=EvalRow.SUBMIT)
     row.set_identifiers(report)
     row.full_clean()
     row.save()
     return row
Ejemplo n.º 33
0
    def test_extract_answers_with_extra(self):
        self.maxDiff = None
        page1 = QuestionPage.objects.create()

        question1 = RadioButton.objects.create(
            text="this is a radio button question", page=page1)
        for i in range(5):
            choice = Choice.objects.create(text="This is choice %i" % i,
                                           question=question1)
            if i == 0:
                choice.extra_info_placeholder = "extra box for choice %i" % i
                choice.save()
        EvaluationField.objects.create(question=question1, label="q1")

        question2 = RadioButton.objects.create(
            text="this is another radio button question", page=page1)
        for i in range(5):
            choice = Choice.objects.create(text="This is choice %i" % i,
                                           question=question2)
            if i % 2 == 1:
                choice.extra_info_placeholder = "extra box for choice %i" % i
                choice.save()
        EvaluationField.objects.create(question=question2, label="q2")

        question3 = RadioButton.objects.create(
            text="this is a radio button question too", page=page1)
        for i in range(5):
            choice = Choice.objects.create(text="This is choice %i" % i,
                                           question=question3)
            if i == 0:
                choice.extra_info_placeholder = "extra box for choice %i" % i
                choice.save()
        EvaluationField.objects.create(question=question3, label="q3")

        q1_choice_ids = [choice.pk for choice in question1.choice_set.all()]
        q1_selected_id = q1_choice_ids[1]
        first_q_object_ids = [q1_selected_id, question1.pk] + q1_choice_ids
        first_q_output = """{
          "answer": "%i",
          "id": %i,
          "question_text": "this is a radio button question",
                "choices": [{"id": %i, "choice_text": "This is choice 0"},
                      {"id": %i, "choice_text": "This is choice 1"},
                      {"id": %i, "choice_text": "This is choice 2"},
                      {"id": %i, "choice_text": "This is choice 3"},
                      {"id": %i, "choice_text": "This is choice 4"}],
          "type": "RadioButton",
          "section": 1
         }""" % tuple(first_q_object_ids)

        q2_choice_ids = [choice.pk for choice in question2.choice_set.all()]
        q2_selected_id = q2_choice_ids[3]
        second_q_object_ids = [q2_selected_id, question2.pk] + q2_choice_ids
        second_q_output = """{
          "answer": "%i",
          "id": %i,
          "question_text": "this is another radio button question",
                "choices": [{"id": %i, "choice_text": "This is choice 0"},
                      {"id": %i, "choice_text": "This is choice 1"},
                      {"id": %i, "choice_text": "This is choice 2"},
                      {"id": %i, "choice_text": "This is choice 3"},
                      {"id": %i, "choice_text": "This is choice 4"}],
          "type": "RadioButton",
          "section": 1,
          "extra": {
                    "extra_text": "extra box for choice 3",
                    "answer": "this should be in the report"
                    }
         }""" % tuple(second_q_object_ids)

        q3_choice_ids = [choice.pk for choice in question3.choice_set.all()]
        q3_selected_id = q3_choice_ids[0]
        third_q_object_ids = [q3_selected_id, question3.pk] + q3_choice_ids
        third_q_output = """{
          "answer": "%i",
          "id": %i,
          "section": 1,
          "question_text": "this is a radio button question too",
                "choices": [{"id": %i, "choice_text": "This is choice 0"},
                      {"id": %i, "choice_text": "This is choice 1"},
                      {"id": %i, "choice_text": "This is choice 2"},
                      {"id": %i, "choice_text": "This is choice 3"},
                      {"id": %i, "choice_text": "This is choice 4"}],
          "type": "RadioButton",
          "extra": {
                    "extra_text": "extra box for choice 0",
                    "answer": ""
                    }
         }""" % tuple(third_q_object_ids)

        json_report = json.loads(
            "[%s, %s, %s]" % (first_q_output, second_q_output, third_q_output))

        expected = {
            "q1":
            str(q1_selected_id),
            "q1_choices": [{
                "id": q1_choice_ids[0],
                "choice_text": "This is choice 0"
            }, {
                "id": q1_choice_ids[1],
                "choice_text": "This is choice 1"
            }, {
                "id": q1_choice_ids[2],
                "choice_text": "This is choice 2"
            }, {
                "id": q1_choice_ids[3],
                "choice_text": "This is choice 3"
            }, {
                "id": q1_choice_ids[4],
                "choice_text": "This is choice 4"
            }],
            "q2":
            str(q2_selected_id),
            "q2_choices": [{
                "id": q2_choice_ids[0],
                "choice_text": "This is choice 0"
            }, {
                "id": q2_choice_ids[1],
                "choice_text": "This is choice 1"
            }, {
                "id": q2_choice_ids[2],
                "choice_text": "This is choice 2"
            }, {
                "id": q2_choice_ids[3],
                "choice_text": "This is choice 3"
            }, {
                "id": q2_choice_ids[4],
                "choice_text": "This is choice 4"
            }],
            "q2_extra":
            "this should be in the report",
            "q3":
            str(q3_selected_id),
            "q3_choices": [{
                "id": q3_choice_ids[0],
                "choice_text": "This is choice 0"
            }, {
                "id": q3_choice_ids[1],
                "choice_text": "This is choice 1"
            }, {
                "id": q3_choice_ids[2],
                "choice_text": "This is choice 2"
            }, {
                "id": q3_choice_ids[3],
                "choice_text": "This is choice 3"
            }, {
                "id": q3_choice_ids[4],
                "choice_text": "This is choice 4"
            }],
            "q3_extra":
            "",
            "answered": [question1.pk, question2.pk, question3.pk],
            "unanswered": []
        }
        anonymised = EvalRow()._extract_answers(json_report)
        self.assertEqual(anonymised, expected)
Ejemplo n.º 34
0
 def test_extract_answers(self):
     self.maxDiff = None
     self.set_up_simple_report_scenario()
     anonymised = EvalRow()._extract_answers(json.loads(self.json_report))
     self.assertEqual(anonymised, self.expected)
Ejemplo n.º 35
0
 def test_make_eval_row(self):
     user = User.objects.create_user(username="******", password="******")
     report = Report.objects.create(owner=user, encrypted=b'first report')
     EvalRow.store_eval_row(EvalRow.CREATE, report=report)
     self.assertEqual(EvalRow.objects.count(), 1)
Ejemplo n.º 36
0
def submit_to_matching(
        request,
        report_id,
        form_template_name="submit_to_matching.html",
        confirmation_template_name="submit_to_matching_confirmation.html",
        report_class=PDFMatchReport):
    owner = request.user
    report = Report.objects.get(id=report_id)
    if owner == report.owner:
        if request.method == 'POST':
            form = SubmitToSchoolForm(owner, report, request.POST)
            formset = SubmitToMatchingFormSet(request.POST)
            form.report = report
            if form.is_valid() and formset.is_valid():
                try:
                    match_reports = []
                    for perp_form in formset:
                        #enter into matching
                        match_report = MatchReport(report=report)
                        match_report.contact_name = conditional_escape(
                            form.cleaned_data.get('name'))
                        match_report.contact_email = form.cleaned_data.get(
                            'email')
                        match_report.contact_phone = conditional_escape(
                            form.cleaned_data.get('phone_number'))
                        match_report.contact_voicemail = conditional_escape(
                            form.cleaned_data.get('voicemail'))
                        match_report.contact_notes = conditional_escape(
                            form.cleaned_data.get('contact_notes'))
                        match_report.identifier = perp_form.cleaned_data.get(
                            'perp')
                        match_report.name = conditional_escape(
                            perp_form.cleaned_data.get('perp_name'))
                        match_reports.append(match_report)
                    MatchReport.objects.bulk_create(match_reports)
                    if settings.MATCH_IMMEDIATELY:
                        find_matches(report_class=report_class)
                except Exception:
                    logger.exception(
                        "couldn't submit match report for report {}".format(
                            report_id))
                    return render(
                        request, form_template_name, {
                            'form': form,
                            'formset': formset,
                            'school_name': settings.SCHOOL_SHORTNAME,
                            'submit_error': True
                        })

                #record matching submission in anonymous evaluation data
                try:
                    row = EvalRow()
                    row.anonymise_record(action=EvalRow.MATCH, report=report)
                    row.save()
                except Exception:
                    logger.exception(
                        "couldn't save evaluation row on match submission")
                    pass

                try:
                    _send_user_notification(form, 'match_confirmation')
                except Exception:
                    # matching was entered even if confirmation email fails, so don't show an error if so
                    logger.exception(
                        "couldn't send confirmation to user on match submission"
                    )

                return render(request, confirmation_template_name, {
                    'school_name': settings.SCHOOL_SHORTNAME,
                    'report': report
                })

        else:
            form = SubmitToSchoolForm(owner, report)
            formset = SubmitToMatchingFormSet()
        return render(
            request, form_template_name, {
                'form': form,
                'formset': formset,
                'school_name': settings.SCHOOL_SHORTNAME
            })
    else:
        logger.warning(
            "illegal matching attempt on record {} by user {}".format(
                report_id, owner.id))
        return HttpResponseForbidden()
Ejemplo n.º 37
0
def submit_to_school(
        request,
        report_id,
        form_template_name="submit_to_school.html",
        confirmation_template_name="submit_to_school_confirmation.html",
        report_class=PDFFullReport):
    owner = request.user
    report = Report.objects.get(id=report_id)
    if owner == report.owner:
        if request.method == 'POST':
            form = SubmitToSchoolForm(owner, report, request.POST)
            form.report = report
            if form.is_valid():
                try:
                    report.contact_name = conditional_escape(
                        form.cleaned_data.get('name'))
                    report.contact_email = form.cleaned_data.get('email')
                    report.contact_phone = conditional_escape(
                        form.cleaned_data.get('phone_number'))
                    report.contact_voicemail = conditional_escape(
                        form.cleaned_data.get('voicemail'))
                    report.contact_notes = conditional_escape(
                        form.cleaned_data.get('contact_notes'))
                    report_class(report=report,
                                 decrypted_report=form.decrypted_report
                                 ).send_report_to_school()
                    report.save()
                except Exception:
                    logger.exception(
                        "couldn't submit report for report {}".format(
                            report_id))
                    return render(
                        request, form_template_name, {
                            'form': form,
                            'school_name': settings.SCHOOL_SHORTNAME,
                            'submit_error': True
                        })

                #record submission in anonymous evaluation data
                try:
                    row = EvalRow()
                    row.anonymise_record(action=EvalRow.SUBMIT, report=report)
                    row.save()
                except Exception:
                    logger.exception(
                        "couldn't save evaluation row on submission")
                    pass

                try:
                    _send_user_notification(form, 'submit_confirmation')
                except Exception:
                    # report was sent even if confirmation email fails, so don't show an error if so
                    logger.exception(
                        "couldn't send confirmation to user on submission")

                return render(
                    request, confirmation_template_name, {
                        'form': form,
                        'school_name': settings.SCHOOL_SHORTNAME,
                        'report': report
                    })
        else:
            form = SubmitToSchoolForm(owner, report)
        return render(request, form_template_name, {
            'form': form,
            'school_name': settings.SCHOOL_SHORTNAME
        })
    else:
        logger.warning("illegal submit attempt on record {} by user {}".format(
            report_id, owner.id))
        return HttpResponseForbidden()
Ejemplo n.º 38
0
 def save_row_for_report(self, report):
     row = EvalRow(action=EvalRow.SUBMIT)
     row.set_identifiers(report)
     row.full_clean()
     row.save()
     return row