Example #1
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)
Example #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()
Example #3
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()
Example #4
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()
Example #5
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)
Example #6
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)
Example #7
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()
Example #8
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()
Example #9
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()
Example #10
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)
Example #11
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()
Example #12
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()
Example #13
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()
Example #14
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()
Example #15
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()