Ejemplo n.º 1
0
    def _forgotten_password(self):
        """Action to let the user request a password change.

        GET returns a form for emailing them the password change
        confirmation.

        POST checks the form and then creates a confirmation record:
        date, email_address, and a url_hash that is a hash of a
        combination of date, email_address, and a random nonce.

        The email address must exist in the person database.

        The second half of the password change operation happens in
        the ``confirm`` action.
        """
        c.email = self.form_result['email_address']
        c.person = Person.find_by_email(c.email)

        if c.person is not None:
            # Check if there is already a password recovery in progress
            reset = PasswordResetConfirmation.find_by_email(c.email)
            if reset is not None:
                return render('person/in_progress.mako')

            # Ok kick one off
            c.conf_rec = PasswordResetConfirmation(email_address=c.email)
            meta.Session.add(c.conf_rec)
            meta.Session.commit()

        email(c.email, render('person/confirmation_email.mako'))

        return render('person/password_confirmation_sent.mako')
Ejemplo n.º 2
0
    def _new(self):
        # Do we allow account creation?
        if lca_info['account_creation']:
            """Create a new person submit.
            """

            # Remove fields not in class
            results = self.form_result['person']
            del results['password_confirm']
            del results['email_address2']
            c.person = Person(**results)
            c.person.email_address = c.person.email_address.lower()
            meta.Session.add(c.person)

            #for sn in self.form_result['social_network']:
            #   network = SocialNetwork.find_by_name(sn['name'])
            #   if sn['account_name']:
            #       c.person.social_networks[network] = sn['account_name']

            meta.Session.commit()

            if lca_rego['confirm_email_address'] == 'no':
                redirect_to(controller='person',
                            action='confirm',
                            confirm_hash=c.person.url_hash)
            else:
                email(c.person.email_address,
                      render('/person/new_person_email.mako'))
                return render('/person/thankyou.mako')
        else:
            return render('/not_allowed.mako')
Ejemplo n.º 3
0
    def _new(self):
        # Do we allow account creation?
        if lca_info['account_creation']:
            """Create a new person submit.
            """

            # Remove fields not in class
            results = self.form_result['person']
            del results['password_confirm']
            del results['email_address2']
            c.person = Person(**results)
            c.person.email_address = c.person.email_address.lower()
            meta.Session.add(c.person)

            #for sn in self.form_result['social_network']:
            #   network = SocialNetwork.find_by_name(sn['name'])
            #   if sn['account_name']:
            #       c.person.social_networks[network] = sn['account_name']

            meta.Session.commit()

            if lca_rego['confirm_email_address'] == 'no':
                redirect_to(controller='person', action='confirm', confirm_hash=c.person.url_hash)
            else:
                email(c.person.email_address, render('/person/new_person_email.mako'))
                return render('/person/thankyou.mako')
        else:
            return render('/not_allowed.mako')
Ejemplo n.º 4
0
    def void(self, id):
        if not h.auth.authorized(
                h.auth.Or(h.auth.is_same_zookeepr_attendee(id),
                          h.auth.has_organiser_role)):
            # Raise a no_auth error
            h.auth.no_role()

        c.invoice = Invoice.find_by_id(id, True)
        if c.invoice.is_void():
            h.flash("Invoice was already voided.")
            return redirect_to(action='view', id=c.invoice.id)

        if h.auth.authorized(h.auth.has_organiser_role):
            c.invoice.void = "Administration Change"
            meta.Session.commit()
            h.flash("Invoice was voided.")
            return redirect_to(action='view', id=c.invoice.id)
        else:
            if c.invoice.paid():
                h.flash("Cannot void a paid invoice.")
                return redirect_to(action='view', id=c.invoice.id)
            c.invoice.void = "User cancellation"
            c.person = c.invoice.person
            meta.Session.commit()
            email(lca_info['contact_email'],
                  render('/invoice/user_voided.mako'))
            h.flash("Previous invoice was voided.")
            return redirect_to(controller='registration',
                               action='pay',
                               id=c.person.registration.id)
Ejemplo n.º 5
0
    def _edit(self, id):
        # We need to recheck auth in here so we can pass in the id
        if not h.auth.authorized(h.auth.Or(h.auth.is_same_zookeepr_submitter(id), h.auth.has_organiser_role)):
            # Raise a no_auth error
            h.auth.no_role()

        if not h.auth.authorized(h.auth.has_organiser_role):
            if c.paper_editing == 'closed' and not h.auth.authorized(h.auth.has_late_submitter_role):
                return render("proposal/editing_closed.mako")
            elif c.paper_editing == 'not_open':
                return render("proposal/editing_not_open.mako")

        c.proposal = Proposal.find_by_id(id)
        for key in self.form_result['proposal']:
            setattr(c.proposal, key, self.form_result['proposal'][key])

        c.proposal.abstract = self.clean_abstract(c.proposal.abstract)

        c.person = self.form_result['person_to_edit']
        if (c.person.id == h.signed_in_person().id or
                             h.auth.authorized(h.auth.has_organiser_role)):
            for key in self.form_result['person']:
                setattr(c.person, key, self.form_result['person'][key])
            p_edit = "and author"
        else:
            p_edit = "(but not author)"

        meta.Session.commit()

        if lca_info['proposal_update_email'] != '':
            body = "Subject: %s Proposal Updated\n\nID:    %d\nTitle: %s\nType:  %s\nURL:   %s" % (h.lca_info['event_name'], c.proposal.id, c.proposal.title, c.proposal.type.name.lower(), "http://" + h.host_name() + h.url_for(action="view"))
            email(lca_info['proposal_update_email'], body)

        h.flash("Proposal %s edited!"%p_edit)
        return redirect_to('/proposal')
Ejemplo n.º 6
0
    def void(self, id):
        if not h.auth.authorized(h.auth.Or(h.auth.is_same_zookeepr_attendee(id), h.auth.has_organiser_role)):
            # Raise a no_auth error
            h.auth.no_role()

        c.invoice = Invoice.find_by_id(id, True)
        if c.invoice.is_void():
            h.flash("Invoice was already voided.")
            return redirect_to(action='view', id=c.invoice.id)

        if h.auth.authorized(h.auth.has_organiser_role):
            c.invoice.void = "Administration Change"
            meta.Session.commit()
            h.flash("Invoice was voided.")
            return redirect_to(action='view', id=c.invoice.id)
        else:
            if c.invoice.paid():
                h.flash("Cannot void a paid invoice.")
                return redirect_to(action='view', id=c.invoice.id)
            c.invoice.void = "User cancellation"
            c.person = c.invoice.person
            meta.Session.commit()
            email(lca_info['contact_email'], render('/invoice/user_voided.mako'))
            h.flash("Previous invoice was voided.")
            return redirect_to(controller='registration', action='pay', id=c.person.registration.id)
Ejemplo n.º 7
0
    def _new(self):
        person_results = self.form_result['person']
        proposal_results = self.form_result['proposal']
        attachment_results = self.form_result['attachment']

        proposal_results['status'] = ProposalStatus.find_by_name('Pending')

        c.proposal = Proposal(**proposal_results)
        meta.Session.add(c.proposal)

        if not h.signed_in_person():
            c.person = model.Person(**person_results)
            meta.Session.add(c.person)
            email(c.person.email_address, render('/person/new_person_email.mako'))
        else:
            c.person = h.signed_in_person()
            for key in person_results:
                setattr(c.person, key, self.form_result['person'][key])

        c.person.proposals.append(c.proposal)

        if attachment_results is not None:
            c.attachment = Attachment(**attachment_results)
            c.proposal.attachments.append(c.attachment)
            meta.Session.add(c.attachment)

        meta.Session.commit()
        email(c.person.email_address, render('proposal/thankyou_mini_email.mako'))

        h.flash("Proposal submitted!")
        return redirect_to(controller='proposal', action="index", id=None)
Ejemplo n.º 8
0
    def _forgotten_password(self):
        """Action to let the user request a password change.

        GET returns a form for emailing them the password change
        confirmation.

        POST checks the form and then creates a confirmation record:
        date, email_address, and a url_hash that is a hash of a
        combination of date, email_address, and a random nonce.

        The email address must exist in the person database.

        The second half of the password change operation happens in
        the ``confirm`` action.
        """
        c.email = self.form_result['email_address']
        c.person = Person.find_by_email(c.email)

        if c.person is not None:
            # Check if there is already a password recovery in progress
            reset = PasswordResetConfirmation.find_by_email(c.email)
            if reset is not None:
                return render('person/in_progress.mako')

            # Ok kick one off
            c.conf_rec = PasswordResetConfirmation(email_address=c.email)
            meta.Session.add(c.conf_rec)
            meta.Session.commit()

        email(c.email, render('person/confirmation_email.mako'))

        return render('person/password_confirmation_sent.mako')
Ejemplo n.º 9
0
    def _new(self):
        person_results = self.form_result['person']
        proposal_results = self.form_result['proposal']
        attachment_results = self.form_result['attachment']

        proposal_results['status'] = ProposalStatus.find_by_name('Pending')

        c.proposal = Proposal(**proposal_results)
        meta.Session.add(c.proposal)

        if not h.signed_in_person():
            c.person = model.Person(**person_results)
            meta.Session.add(c.person)
            email(c.person.email_address,
                  render('/person/new_person_email.mako'))
        else:
            c.person = h.signed_in_person()
            for key in person_results:
                setattr(c.person, key, self.form_result['person'][key])

        c.person.proposals.append(c.proposal)

        if attachment_results is not None:
            c.attachment = Attachment(**attachment_results)
            c.proposal.attachments.append(c.attachment)
            meta.Session.add(c.attachment)

        meta.Session.commit()
        email(c.person.email_address,
              render('proposal/thankyou_mini_email.mako'))

        h.flash("Proposal submitted!")
        return redirect_to(controller='proposal', action="index", id=None)
Ejemplo n.º 10
0
 def _remind(self):
     results = self.form_result
     for i in results['invoices']:
         c.invoice = i
         c.recipient = i.person
         email(c.recipient.email_address, render('invoice/remind_email.mako'))
         h.flash('Email sent to ' + c.recipient.firstname + ' ' + c.recipient.lastname + ' <' + c.recipient.email_address + '>')
     redirect_to(action='remind')
Ejemplo n.º 11
0
 def reject(self, id):
     volunteer = Volunteer.find_by_id(id)
     volunteer.accepted = False
     volunteer.ticket_type = None
     meta.Session.commit()
     c.volunteer = volunteer
     c.person = volunteer.person
     email(c.person.email_address, render("volunteer/response.mako"))
     h.flash("Status Updated and Rejection Email Sent")
     redirect_to(action="index", id=None)
Ejemplo n.º 12
0
 def reject(self, id):
     volunteer = Volunteer.find_by_id(id)
     volunteer.accepted = False
     volunteer.ticket_type = None
     meta.Session.commit()
     c.volunteer = volunteer
     c.person = volunteer.person
     email(c.person.email_address, render('volunteer/response.mako'))
     h.flash('Status Updated and Rejection Email Sent')
     redirect_to(action='index', id=None)
Ejemplo n.º 13
0
 def _accept(self, id):
     results = self.form_result
     volunteer = Volunteer.find_by_id(id)
     volunteer.ticket_type = results['ticket_type']
     volunteer.accepted = True
     meta.Session.commit()
     c.volunteer = volunteer
     c.person = volunteer.person
     email(c.person.email_address, render('volunteer/response.mako'))
     h.flash('Status Updated and Acceptance Email Sent')
     redirect_to(action='index', id=None)
Ejemplo n.º 14
0
 def _remind(self):
     results = self.form_result
     for i in results['invoices']:
         c.invoice = i
         c.recipient = i.person
         email(c.recipient.email_address,
               render('invoice/remind_email.mako'))
         h.flash('Email sent to ' + c.recipient.firstname + ' ' +
                 c.recipient.lastname + ' <' + c.recipient.email_address +
                 '>')
     redirect_to(action='remind')
Ejemplo n.º 15
0
 def _accept(self, id):
     results = self.form_result
     volunteer = Volunteer.find_by_id(id)
     volunteer.ticket_type = results["ticket_type"]
     volunteer.accepted = True
     meta.Session.commit()
     c.volunteer = volunteer
     c.person = volunteer.person
     email(c.person.email_address, render("volunteer/response.mako"))
     h.flash("Status Updated and Acceptance Email Sent")
     redirect_to(action="index", id=None)
Ejemplo n.º 16
0
    def _new(self):
        results = self.form_result["volunteer"]

        c.volunteer = Volunteer(**results)
        c.volunteer.person = h.signed_in_person()
        c.person = c.volunteer.person
        meta.Session.add(c.volunteer)
        meta.Session.commit()

        h.flash("Thank you for volunteering. We will contact you shortly regarding your application")
        email(c.person.email_address, render("volunteer/response.mako"))
        redirect_to(action="view", id=c.volunteer.id)
Ejemplo n.º 17
0
    def _new(self):
        results = self.form_result['volunteer']

        c.volunteer = Volunteer(**results)
        c.volunteer.person = h.signed_in_person()
        c.person = c.volunteer.person
        meta.Session.add(c.volunteer)
        meta.Session.commit()

        h.flash(
            "Thank you for volunteering. We will contact you shortly regarding your application"
        )
        email(c.person.email_address, render('volunteer/response.mako'))
        redirect_to(action='view', id=c.volunteer.id)
Ejemplo n.º 18
0
    def _withdraw(self, id):
        if not h.auth.authorized(h.auth.Or(h.auth.is_same_zookeepr_submitter(id), h.auth.has_organiser_role)):
            # Raise a no_auth error
            h.auth.no_role()

        c.proposal = Proposal.find_by_id(id)
        status = ProposalStatus.find_by_name('Withdrawn')
        c.proposal.status = status
        meta.Session.commit()

        c.person = h.signed_in_person()

        # Make sure the organisers are notified of this
        c.email_address = h.lca_info['emails'][c.proposal.type.name.lower()]
        email(c.email_address, render('/proposal/withdraw_email.mako'))

        h.flash("Proposal withdrawn. The organisers have been notified.")
        return redirect_to(controller='proposal', action="index", id=None)
Ejemplo n.º 19
0
    def _withdraw(self, id):
        if not h.auth.authorized(
                h.auth.Or(h.auth.is_same_zookeepr_submitter(id),
                          h.auth.has_organiser_role)):
            # Raise a no_auth error
            h.auth.no_role()

        c.proposal = Proposal.find_by_id(id)
        status = ProposalStatus.find_by_name('Withdrawn')
        c.proposal.status = status
        meta.Session.commit()

        c.person = h.signed_in_person()

        # Make sure the organisers are notified of this
        c.email_address = h.lca_info['emails'][c.proposal.type.name.lower()]
        email(c.email_address, render('/proposal/withdraw_email.mako'))

        h.flash("Proposal withdrawn. The organisers have been notified.")
        return redirect_to(controller='proposal', action="index", id=None)
Ejemplo n.º 20
0
    def _new(self):
        if c.funding_status == 'closed':
            return render("funding/closed.mako")
        elif c.funding_status == 'not_open':
            return render("funding/not_open.mako")

        if self.form_result['funding']['male'] == 1:
            self.form_result['funding']['male'] = True
        elif self.form_result['funding']['male'] == 0:
            self.form_result['funding']['male'] = False

        funding_results = self.form_result['funding']
        attachment_results1 = self.form_result['attachment1']
        attachment_results2 = self.form_result['attachment2']

        c.person = h.signed_in_person()

        c.funding = Funding(**funding_results)
        c.funding.status = FundingStatus.find_by_name('Pending')
        c.funding.person = c.person

        if not c.funding.type.available():
            return render("funding/type_unavailable.mako")

        meta.Session.add(c.funding)

        if attachment_results1 is not None:
            attachment = FundingAttachment(**attachment_results1)
            c.funding.attachments.append(attachment)
            meta.Session.add(attachment)
        if attachment_results2 is not None:
            attachment = FundingAttachment(**attachment_results2)
            c.funding.attachments.append(attachment)
            meta.Session.add(attachment)

        meta.Session.commit()
        email(c.funding.person.email_address,
              render('funding/thankyou_email.mako'))

        h.flash("Funding submitted!")
        return redirect_to(controller='funding', action="index", id=None)
Ejemplo n.º 21
0
    def _new(self):
        if c.cfp_status == 'closed':
            if not h.auth.authorized(
                    h.auth.Or(h.auth.has_organiser_role,
                              h.auth.has_late_submitter_role)):
                return render("proposal/closed.mako")
        elif c.cfp_status == 'not_open':
            return render("proposal/not_open.mako")

        person_results = self.form_result['person']
        proposal_results = self.form_result['proposal']
        attachment_results = self.form_result['attachment']

        proposal_results['status'] = ProposalStatus.find_by_name('Pending')

        c.proposal = Proposal(**proposal_results)
        c.proposal.abstract = self.clean_abstract(c.proposal.abstract)
        meta.Session.add(c.proposal)

        if not h.signed_in_person():
            c.person = model.Person(**person_results)
            meta.Session.add(c.person)
            email(c.person.email_address,
                  render('/person/new_person_email.mako'))
        else:
            c.person = h.signed_in_person()
            for key in person_results:
                setattr(c.person, key, self.form_result['person'][key])

        c.person.proposals.append(c.proposal)

        if attachment_results is not None:
            attachment = Attachment(**attachment_results)
            c.proposal.attachments.append(attachment)
            meta.Session.add(attachment)

        meta.Session.commit()
        email(c.person.email_address, render('proposal/thankyou_email.mako'))

        h.flash("Proposal submitted!")
        return redirect_to(controller='proposal', action="index", id=None)
Ejemplo n.º 22
0
    def _edit(self, id):
        # We need to recheck auth in here so we can pass in the id
        if not h.auth.authorized(
                h.auth.Or(h.auth.is_same_zookeepr_submitter(id),
                          h.auth.has_organiser_role)):
            # Raise a no_auth error
            h.auth.no_role()

        if not h.auth.authorized(h.auth.has_organiser_role):
            if c.paper_editing == 'closed' and not h.auth.authorized(
                    h.auth.has_late_submitter_role):
                return render("proposal/editing_closed.mako")
            elif c.paper_editing == 'not_open':
                return render("proposal/editing_not_open.mako")

        c.proposal = Proposal.find_by_id(id)
        for key in self.form_result['proposal']:
            setattr(c.proposal, key, self.form_result['proposal'][key])

        c.proposal.abstract = self.clean_abstract(c.proposal.abstract)

        c.person = self.form_result['person_to_edit']
        if (c.person.id == h.signed_in_person().id
                or h.auth.authorized(h.auth.has_organiser_role)):
            for key in self.form_result['person']:
                setattr(c.person, key, self.form_result['person'][key])
            p_edit = "and author"
        else:
            p_edit = "(but not author)"

        meta.Session.commit()

        if lca_info['proposal_update_email'] != '':
            body = "Subject: %s Proposal Updated\n\nID:    %d\nTitle: %s\nType:  %s\nURL:   %s" % (
                h.lca_info['event_name'], c.proposal.id, c.proposal.title,
                c.proposal.type.name.lower(),
                "http://" + h.host_name() + h.url_for(action="view"))
            email(lca_info['proposal_update_email'], body)

        h.flash("Proposal %s edited!" % p_edit)
        return redirect_to('/proposal')
Ejemplo n.º 23
0
    def _new(self):
        if c.funding_status == 'closed':
            return render("funding/closed.mako")
        elif c.funding_status == 'not_open':
            return render("funding/not_open.mako")

        if self.form_result['funding']['male'] == 1:
            self.form_result['funding']['male'] = True
        elif self.form_result['funding']['male'] == 0:
            self.form_result['funding']['male'] = False

        funding_results = self.form_result['funding']
        attachment_results1 = self.form_result['attachment1']
        attachment_results2 = self.form_result['attachment2']

        c.person = h.signed_in_person()

        c.funding = Funding(**funding_results)
        c.funding.status = FundingStatus.find_by_name('Pending')
        c.funding.person = c.person

        if not c.funding.type.available():
            return render("funding/type_unavailable.mako")

        meta.Session.add(c.funding)

        if attachment_results1 is not None:
            attachment = FundingAttachment(**attachment_results1)
            c.funding.attachments.append(attachment)
            meta.Session.add(attachment)
        if attachment_results2 is not None:
            attachment = FundingAttachment(**attachment_results2)
            c.funding.attachments.append(attachment)
            meta.Session.add(attachment)

        meta.Session.commit()
        email(c.funding.person.email_address, render('funding/thankyou_email.mako'))

        h.flash("Funding submitted!")
        return redirect_to(controller='funding', action="index", id=None)
Ejemplo n.º 24
0
    def _new(self):
        if c.cfp_status == 'closed':
           if not h.auth.authorized(h.auth.Or(h.auth.has_organiser_role, h.auth.has_late_submitter_role)):
              return render("proposal/closed.mako")
        elif c.cfp_status == 'not_open':
           return render("proposal/not_open.mako")

        person_results = self.form_result['person']
        proposal_results = self.form_result['proposal']
        attachment_results = self.form_result['attachment']

        proposal_results['status'] = ProposalStatus.find_by_name('Pending')

        c.proposal = Proposal(**proposal_results)
        c.proposal.abstract = self.clean_abstract(c.proposal.abstract)
        meta.Session.add(c.proposal)

        if not h.signed_in_person():
            c.person = model.Person(**person_results)
            meta.Session.add(c.person)
            email(c.person.email_address, render('/person/new_person_email.mako'))
        else:
            c.person = h.signed_in_person()
            for key in person_results:
                setattr(c.person, key, self.form_result['person'][key])

        c.person.proposals.append(c.proposal)

        if attachment_results is not None:
            attachment = Attachment(**attachment_results)
            c.proposal.attachments.append(attachment)
            meta.Session.add(attachment)

        meta.Session.commit()
        email(c.person.email_address, render('proposal/thankyou_email.mako'))

        h.flash("Proposal submitted!")
        return redirect_to(controller='proposal', action="index", id=None)
Ejemplo n.º 25
0
class PaymentController(BaseController):
    """This controller receives payment advice from the payment gateway.

    the url /payment/new receives the advice
    """
    @authorize(h.auth.has_organiser_role)
    def index(self):
        c.payment_collection = Payment.find_all()
        return render('/payment/list.mako')

    @authorize(h.auth.is_valid_user)
    def view(self, id):

        payment = Payment.find_by_id(id, abort_404=True)
        c.person = payment.invoice.person

        if not h.auth.authorized(
                h.auth.Or(h.auth.is_same_zookeepr_user(c.person.id),
                          h.auth.has_organiser_role)):
            # Raise a no_auth error
            h.auth.no_role()

        c.is_organiser = False
        if h.auth.authorized(h.auth.has_organiser_role):
            c.is_organiser = True

        c.payment = PaymentReceived.find_by_payment(payment.id)

        c.validation_errors = []
        if c.payment is not None and c.payment.validation_errors is not None and len(
                c.payment.validation_errors) > 0:
            c.validation_errors = c.payment.validation_errors.split(';')

        same_invoice = PaymentReceived.find_by_invoice(payment.invoice.id)
        same_email = PaymentReceived.find_by_email(c.person.email_address)
        if c.payment is not None:
            same_invoice = same_invoice.filter("payment_id <> " +
                                               str(payment.id))
            same_email = same_email.filter("payment_id <> " + str(payment.id))
        c.related_payments = same_invoice.union(same_email)

        return render('/payment/view.mako')

    # No authentication because it's called directly by the payment gateway
    def new(self):
        schema = SecurePayPingSchema()
        try:
            form_result = schema.to_python(request.params)
        except validators.Invalid, error:
            return 'Invalid: %s' % error

        payment = None
        c.person = None

        fields = form_result
        c.response = {
            'payment_id': fields['payment_id'],
            'invoice_id': fields['invoice_id'],
            'success_code': fields['summary_code'],
            'amount_paid': fields['response_amount'],
            'currency_used': fields['currency'],
            'card_name': fields['card_name'],
            'card_type': fields['card_type'],
            'card_number': fields['card_number'],
            'card_expiry': fields['card_number'],
            'card_mac': fields['card_mac'],
            'auth_code': fields['response_code'],
            'gateway_ref': fields['bank_reference'],
            'response_text': fields['response_text'],
            'client_ip_gateway': fields['remote_ip'],
            'client_ip_zookeepr': request.environ.get('REMOTE_ADDR'),
            'email_address': fields['receipt_address']
        }

        if 'Approved' in c.response['response_text']:
            c.response['approved'] = True
        else:
            c.response['approved'] = False

        validation_errors = []

        if c.response is None:
            abort(500, ''.join(validation_errors))
        else:
            # Make sure the same browser created the zookeepr payment object and paid by credit card
            #if c.response['client_ip_gateway'] != c.response['client_ip_zookeepr']:
            #validation_errors.append('Mismatch in IP addresses: zookeepr=' + c.response['client_ip_zookeepr'] + ' gateway=' + c.response['client_ip_gateway'])

            # Get the payment object associated with this transaction
            payment = Payment.find_by_id(c.response['payment_id'])

        if payment is None:
            validation_errors.append(
                'Invalid payment ID from the payment gateway')
        else:
            c.person = payment.invoice.person

            # Check whether a payment has already been received for this payment object
            received = PaymentReceived.find_by_payment(payment.id)
            if received is not None:
                # Ignore repeat payment
                return redirect_to(action='view', id=payment.id)

            # Extra validation
            if c.response['amount_paid'] != payment.amount:
                validation_errors.append(
                    'Mismatch between amounts paid and invoiced')
            if c.response['invoice_id'] != payment.invoice.id:
                validation_errors.append(
                    'Mismatch between returned invoice ID and payment object')
            #if c.response['email_address'] != pxpay.munge_email(payment.invoice.person.email_address):
            #    validation_errors.append('Mismatch between returned email address and invoice object')
            if not c.person.is_from_common_country():
                validation_errors.append('Uncommon country: ' +
                                         c.person.country)

        c.pr = PaymentReceived(**c.response)
        c.pr.validation_errors = ';'.join(validation_errors)
        meta.Session.add(c.pr)
        meta.Session.commit()

        if len(validation_errors) > 0 and c.response['approved']:
            # Suspiciously approved transaction which needs to be checked manually
            email(lca_info['contact_email'],
                  render('/payment/suspicious_payment.mako'))

        if c.person is not None:
            email(c.person.email_address, render('/payment/response.mako'))

        # OK we now have a valid transaction, we redirect the user to the view page
        # so they can see if their transaction was accepted or declined
        return redirect_to(action='view', id=payment.id)