def handle(self, *args, **options):
        pages = Page.objects.filter(deleted=False)
        for page in pages:
            account = stripe.Account.retrieve(page.stripe_account_id)
            status = account['legal_entity']['verification']['status']
            if status == 'verified' or status == 'pending':
                page.stripe_verified = True
            else:
                page.stripe_verified = False

                if page.stripe_verification_requested == False:
                    # email the admins
                    admins = page.admins.all()
                    for admin in admins:
                        if has_notification(
                                admin.user,
                                "notification_email_campaign_created") == True:
                            substitutions = {
                                "-pagename-": page.name,
                                "-pageslug-": page.page_slug,
                            }
                            email(admin.user.email, "blank", "blank",
                                  "page_verification", substitutions)
                    page.stripe_verification_requested = True

            page.save()
예제 #2
0
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        UserProfile.objects.create(user=instance)

        date = timezone.now().strftime("%Y-%m-%d %I:%M:%S %Z")
        email("*****@*****.**", "blank", "blank", "admin_new_user_signup", {
            '-email-': instance.email,
            '-date-': date,
        })
예제 #3
0
def change_password_request(request):
    invitation = models.ForgotPasswordRequest.objects.create(email=request.user.email)

    # send an email for the reset
    substitutions = {
        "-passwordreseturl-": "{}/password/reset/{}/{}/".format(config.settings['site'], invitation.pk, invitation.key),
    }
    email(request.user.email, "blank", "blank", "reset_password", substitutions)
    messages.success(request, 'Password reset email sent', fail_silently=True)
    return redirect('userprofile:userprofile')
예제 #4
0
    def send_mail(self, template_prefix, email, context):
        template = template_prefix.split('/')[2]

        user = context['user']
        user = User.objects.get(username=user)

        # email the user
        substitutions = {
            "-key-": context['key'],
        }
        utils.email(user.email, "blank", "blank", template, substitutions)
예제 #5
0
def error_email(error):
    user = error["user"]
    page = error["page"]
    campaign = error["campaign"]
    message = error["e"]
    date = timezone.now()

    body = "We got a Stripe error for user pk:{} on page pk:{} ".format(
        user, page)
    if campaign is not None:
        body += "campaign pk:{} ".format(campaign)
    body += "at {}. Full message: {}".format(date, message)
    email("*****@*****.**", "ERROR: Stripe", body)
예제 #6
0
def create_error(error, request):
    err = Note.objects.create(
        date=timezone.now(),
        message=str(error),
        user=request.user,
        type='error',
    )

    substitutions = {
        '-pk-': str(err.pk),
        '-user-': err.user.email,
        '-message-': err.message,
    }
    email("*****@*****.**", "blank", "blank", "note_error", substitutions)

    return err
예제 #7
0
def create_note(request, obj, type):
    details = ""
    fields = [f.name for f in obj._meta.get_fields()]
    for field in fields:
        details += "{}: {};\n".format(field, getattr(obj, field))

    note = Note.objects.create(
        date=timezone.now(),
        details=details,
        message=request.POST.get('note'),
        user=request.user,
        type=type,
    )

    subject = "[{}] PageFund note".format(type.upper())
    body = "Note {} from user {} at {}; Message: {}; Details: {}".format(
        note.pk, note.user.email, note.date, note.message, note.details)
    email("*****@*****.**", subject, body, "note_abuse", {})
예제 #8
0
def forgot_password_request(request):
    form = forms.ForgotPasswordRequestForm()
    if request.method == "POST":
        form = forms.ForgotPasswordRequestForm(request.POST)
        if form.is_valid():
            user_email = form.cleaned_data['email']
            if User.objects.filter(email=user_email).exists():
                invitation = models.ForgotPasswordRequest.objects.create(email=user_email)

                # send an email for the reset
                substitutions = {
                    "-passwordreseturl-": "{}/password/reset/{}/{}/".format(config.settings['site'], invitation.pk, invitation.key),
                }
                email(user_email, "blank", "blank", "reset_password", substitutions)

                messages.success(request, 'Password reset email sent', fail_silently=True)
            else:
                messages.error(request, 'No user with that email exists', fail_silently=True)
    return render(request, 'forgot_password_request.html', {'form': form})
예제 #9
0
def email_confirmed_(request, email_address, **kwargs):
    email_address = str(email_address)
    email_address = email_address.split(' ')[0]
    if not settings.TESTING:
        user = User.objects.get(email=email_address)
        metadata = {'user_pk': user.pk}
        customer = stripe.Customer.create(
            email=user.email,
            metadata=metadata
        )

        user.userprofile.stripe_customer_id = customer.id
        user.save()

        data = [
          {
            'email': user.email,
            'source': 'signup',
          }
        ]
        sg = sendgrid.SendGridAPIClient(apikey=config.settings["sendgrid_api_key"])
        response = sg.client.contactdb.recipients.post(request_body=data)

    email(user.email, "blank", "blank", "new_user_signup", {})
예제 #10
0
def charge_succeeded(request):
    event_json = json.loads(request.body.decode('utf-8'))
    date = datetime.datetime.utcfromtimestamp(
        event_json['data']['object']['created']).replace(tzinfo=pytz.utc)
    tz = pytz.timezone('America/Chicago')
    date = date.astimezone(tz)

    if not event_json['data']['object']['metadata']:
        invoice = stripe.Invoice.retrieve(
            event_json['data']['object']['invoice'])
        subscription = stripe.Subscription.retrieve(invoice['subscription'])
        anonymous_amount = subscription['plan']['metadata']['anonymous_amount']
        anonymous_donor = subscription['plan']['metadata']['anonymous_donor']
        try:
            campaign_pk = subscription['plan']['metadata']['campaign']
            campaign = get_object_or_404(Campaign, pk=campaign_pk)
        except KeyError:
            campaign = None
        page_pk = subscription['plan']['metadata']['page']
        try:
            comment = subscription['plan']['metadata']['comment']
        except KeyError:
            comment = ''
        pf_user_pk = subscription['plan']['metadata']['pf_user_pk']
        vote_participant = None
    else:
        anonymous_amount = event_json['data']['object']['metadata'][
            'anonymous_amount']
        anonymous_donor = event_json['data']['object']['metadata'][
            'anonymous_donor']
        try:
            campaign_pk = event_json['data']['object']['metadata']['campaign']
            campaign = get_object_or_404(Campaign, pk=campaign_pk)
        except KeyError:
            campaign = None
        page_pk = event_json['data']['object']['metadata']['page']
        try:
            comment = event_json['data']['object']['metadata']['comment']
        except KeyError:
            comment = ''
        # get the user's pk if this was a donation from a logged-in user
        try:
            pf_user_pk = event_json['data']['object']['metadata']['pf_user_pk']
        # get the donor's first/last name if they weren't logged in when they donated
        except KeyError:
            pf_user_pk = None
            first_name = event_json['data']['object']['metadata']['first_name']
            last_name = event_json['data']['object']['metadata']['last_name']
        try:
            vote_participant_pk = event_json['data']['object']['metadata'][
                'vote_participant']
            vote_participant = get_object_or_404(VoteParticipant,
                                                 pk=vote_participant_pk)
        except KeyError:
            vote_participant = None

    amount = event_json['data']['object']['amount']
    page = get_object_or_404(Page, pk=page_pk)
    stripe_charge_id = event_json['data']['object']['id']
    # get the user object if this was a donation from a logged-in user
    if pf_user_pk is not None:
        user = get_object_or_404(User, pk=pf_user_pk)
        if vote_participant is not None:
            Donation.objects.create(
                amount=amount,
                anonymous_amount=anonymous_amount,
                anonymous_donor=anonymous_donor,
                comment=comment,
                date=date,
                page=page,
                campaign=campaign,
                campaign_participant=vote_participant,
                stripe_charge_id=stripe_charge_id,
                user=user,
            )
        else:
            Donation.objects.create(
                amount=amount,
                anonymous_amount=anonymous_amount,
                anonymous_donor=anonymous_donor,
                comment=comment,
                date=date,
                page=page,
                campaign=campaign,
                stripe_charge_id=stripe_charge_id,
                user=user,
            )

        substitutions = {
            "-amount-": "${}".format(int(amount / 100)),
        }

        if campaign:
            substitutions['-recipient-'] = campaign.name
        else:
            substitutions['-recipient-'] = page.name

        if has_notification(user, "notification_email_donation") == True:
            email(user.email, "blank", "blank", "donation", substitutions)

        substitutions['-user-'] = user.email
        date = timezone.now().strftime("%Y-%m-%d %I:%M:%S %Z")
        substitutions['-date-'] = date
        email("*****@*****.**", "blank", "blank", "admin_new_donation",
              substitutions)

    # user is not logged in
    else:
        if vote_participant is not None:
            Donation.objects.create(
                amount=amount,
                anonymous_amount=anonymous_amount,
                anonymous_donor=anonymous_donor,
                comment=comment,
                date=date,
                page=page,
                campaign=campaign,
                campaign_participant=vote_participant,
                stripe_charge_id=stripe_charge_id,
                donor_first_name=first_name,
                donor_last_name=last_name,
            )
        else:
            Donation.objects.create(
                amount=amount,
                anonymous_amount=anonymous_amount,
                anonymous_donor=anonymous_donor,
                comment=comment,
                date=date,
                page=page,
                campaign=campaign,
                stripe_charge_id=stripe_charge_id,
                donor_first_name=first_name,
                donor_last_name=last_name,
            )

        substitutions = {
            "-amount-": "${}".format(int(amount / 100)),
            '-user-':
            "unauthenticated user '{} {}'".format(first_name, last_name),
        }

        if campaign:
            substitutions['-recipient-'] = campaign.name
        else:
            substitutions['-recipient-'] = page.name

        date = timezone.now().strftime("%Y-%m-%d %I:%M:%S %Z")
        substitutions['-date-'] = date
        email("*****@*****.**", "blank", "blank", "admin_new_donation",
              substitutions)

    return HttpResponse(status=200)
예제 #11
0
def webhooks_test(request):
    # send test email
    email("*****@*****.**", "blank", "blank", "admin_webhook_test", {})
    return HttpResponse(status=200)
예제 #12
0
    def post(self, request, page_slug):
        page = get_object_or_404(Page, page_slug=page_slug)
        # if the page is a nonprofit,
        # we need their EIN
        if page.type == 'nonprofit':
            if page.stripe_verified == True:
                form = forms.PageEditBankEINForm(request.POST)
            else:
                form = forms.PageUnverifiedEditBankEINForm(request.POST)
        else:
            if page.stripe_verified == True:
                form = forms.PageEditBankForm(request.POST)
            else:
                form = forms.PageUnverifiedEditBankForm(request.POST)
        if page.deleted == False:
            if utils.has_dashboard_access(request.user, page, 'manager_edit'):
                if form.is_valid():
                    if not settings.TESTING:

                        # set the stripe type to determine if we need EIN
                        if page.type == 'nonprofit':
                            stripe_type = 'company'
                        else:
                            stripe_type = 'individual'

                        # retrieve account from stripe
                        account = stripe.Account.retrieve(
                            page.stripe_account_id)
                        # update stripe information
                        if page.stripe_verified == True:
                            if account['legal_entity'][
                                    'ssn_last_4_provided'] == False:
                                account.legal_entity.ssn_last_4 = form.cleaned_data[
                                    'ssn']
                        else:
                            account.legal_entity.personal_id_number = form.cleaned_data[
                                'ssn']
                        if page.type == 'nonprofit':
                            account.legal_entity.business_tax_id = form.cleaned_data[
                                'ein']

                        # save the account or redirect for an exception
                        try:
                            account.save()
                        except stripe.error.InvalidRequestError as e:
                            print("e = {}".format(e))
                            error = create_error(e, request)
                            return redirect(
                                'notes:error_stripe_invalid_request')

                        # create the bank account
                        external_account = {
                            'object': 'bank_account',
                            'country': 'US',
                            'currency': 'usd',
                            'account_number':
                            form.cleaned_data['account_number'],
                            'account_holder_type': stripe_type,
                            'routing_number':
                            form.cleaned_data['routing_number'],
                            'default_for_currency': 'true',
                        }
                        try:
                            ext_account = account.external_accounts.create(
                                external_account=external_account)
                        except Exception as e:
                            print("exception = {}".format(e))

                        # delete the old account here
                        # so that we can set the new one as default first
                        try:
                            account.external_accounts.retrieve(
                                page.stripe_bank_account_id).delete()
                        except:
                            pass

                        page.stripe_bank_account_id = ext_account.id
                    page.save()

                    # email the user
                    substitutions = {
                        "-pagename-": page.name,
                    }
                    utils.email(request.user.email, "blank", "blank",
                                "page_bank_information_updated", substitutions)
                    # add message
                    messages.success(request,
                                     'Bank information updated',
                                     fail_silently=True)
                    return redirect('page_dashboard_admin',
                                    page_slug=page.page_slug)
            else:
                return redirect('notes:error_permissions')
        else:
            return redirect('notes:error_page_does_not_exist')
예제 #13
0
    def done(self, form_list, **kwargs):
        # put the form results into a dict
        form = self.get_all_cleaned_data()

        # make the Page object but don't save it
        # until we make the stripe transaction
        page = Page(
            address_line1=form['address_line1'],
            address_line2=form['address_line2'],
            city=form['city'],
            description=form['description'],
            name=form['name'],
            stripe_account_id='',
            stripe_bank_account_id='',
            tos_accepted=form['tos_accepted'],
            zipcode=form['zipcode'],
            category=form['category'],
            state=form['state'],
            type=form['type'],
        )

        # only make the stripe account if we're live
        if not settings.TESTING:

            # create stripe data for the account
            legal_entity = {
                "business_name": page.name,
                "address": {
                    "city": page.city,
                    "line1": page.address_line1,
                    "line2": page.address_line2,
                    "postal_code": page.zipcode,
                    "state": page.state
                },
                'ssn_last_4': form['ssn'],
                'first_name': form['first_name'],
                'last_name': form['last_name'],
                "dob": {
                    "day": form['birthday'].day,
                    "month": form['birthday'].month,
                    "year": form['birthday'].year,
                },
            }

            # set the stripe type based on page type
            if page.type == 'nonprofit':
                stripe_type = 'company'
                legal_entity['business_tax_id'] = form['ein']
            else:
                stripe_type = 'individual'

            legal_entity["type"] = stripe_type

            user_ip = get_client_ip(self.request)
            tos_acceptance = {"date": timezone.now(), "ip": user_ip}

            payout_schedule = {
                'delay_days': 'minimum',
                'interval': 'weekly',
                'weekly_anchor': 'monday',
            }

            # create the stripe account
            # and save the page if all goes well
            try:
                account = stripe.Account.create(
                    business_name=page.name,
                    country="US",
                    email=self.request.user.email,
                    legal_entity=legal_entity,
                    type="custom",
                    tos_acceptance=tos_acceptance,
                    payout_schedule=payout_schedule,
                    statement_descriptor='PageFund',
                )

                external_account = {
                    "object":
                    "bank_account",
                    "country":
                    "US",
                    "account_number":
                    form['account_number'],
                    "account_holder_name":
                    "{} {}".format(form['first_name'], form['last_name']),
                    "account_holder_type":
                    stripe_type,
                    "routing_number":
                    form['routing_number'],
                    "default_for_currency":
                    "true",
                }
                ext_account = account.external_accounts.create(
                    external_account=external_account)

                page.stripe_account_id = account.id
                page.stripe_bank_account_id = ext_account.id

                # give them the benefit of the doubt and let them accept donations right away
                # it'll get fixed within 2 minutes if it's unverified
                page.stripe_verified = True

                # stripe processed it so we can save the page now
                page.save()

                # update the stripe metadata for the url
                metadata = {
                    'url': 'https://page.fund/{}/'.format(page.page_slug),
                }
                account.metadata = metadata
                account.save()

                # add the user as an admin and subscriber
                page.admins.add(self.request.user.userprofile)
                page.subscribers.add(self.request.user.userprofile)

            # catch stripe exceptions
            # and alert the user and me about it
            # note that the page doesn't get created if this happens
            except stripe.error.InvalidRequestError as e:
                create_error(e, self.request)
                return redirect('notes:error_stripe_invalid_request')

            # send emails
            # placed outside of stripe try block because it's ok if these fail
            try:
                substitutions = {
                    "-pagename-": page.name,
                }
                utils.email(self.request.user.email, "blank", "blank",
                            "new_page_created", substitutions)

                date = timezone.now().strftime("%Y-%m-%d %I:%M:%S %Z")
                utils.email(
                    "*****@*****.**", "blank", "blank", "admin_new_page", {
                        '-user-': self.request.user.email,
                        '-page-': page.name,
                        '-date-': date,
                    })
            except:
                pass

        # so tests will pass
        else:
            page.save()
            # add the user as an admin and subscriber
            page.admins.add(self.request.user.userprofile)
            page.subscribers.add(self.request.user.userprofile)

        return HttpResponseRedirect(page.get_absolute_url())
예제 #14
0
def invite(data):
    form = data["form"]
    request = data["request"]
    page = data["page"]
    campaign = data["campaign"]

    # check if the person we are inviting is already a manager
    try:
        user = User.objects.get(email=form.cleaned_data["email"])
        if user:
            if page:
                if user.userprofile in page.managers.all():
                    status = True
            elif campaign:
                if user.userprofile in campaign.campaign_managers.all():
                    status = True
    except User.DoesNotExist:
        pass

    # check if the user has already been invited by this admin/manager for this page
    # expired should be False, otherwise the previous invitation has expired and we are OK with them getting a new one
    # accepted/declined are irrelevant if the invite has expired, so we don't check these
    if page:
        try:
            invitation = ManagerInvitation.objects.get(
                invite_to=form.cleaned_data['email'],
                invite_from=request.user,
                page=page,
                expired=False)
        except ManagerInvitation.DoesNotExist:
            invitation = None
    elif campaign:
        try:
            invitation = ManagerInvitation.objects.get(
                invite_to=form.cleaned_data['email'],
                invite_from=request.user,
                campaign=campaign,
                expired=False)
        except ManagerInvitation.DoesNotExist:
            invitation = None

    # if this user has already been invited, redirect the admin/manager
    # need to notify the admin/manager that the person has already been invited
    if invitation:
        # this user has already been invited, so do nothing
        status = True
    # if the user hasn't been invited already, create the invite and send it to them
    else:
        substitutions = {}
        # create the invitation object and set the permissions
        if page:
            invitation = ManagerInvitation.objects.create(
                invite_to=form.cleaned_data['email'],
                invite_from=request.user,
                page=page,
                manager_edit=form.cleaned_data['manager_edit'],
                manager_delete=form.cleaned_data['manager_delete'],
                manager_invite=form.cleaned_data['manager_invite'],
                manager_image_edit=form.cleaned_data['manager_image_edit'],
                manager_view_dashboard=form.
                cleaned_data['manager_view_dashboard'],
            )

            # send an email for the invitation
            substitutions = {
                "-pagename-":
                page.name,
                "-invitationurl-":
                "{}/invite/manager/accept/{}/{}/".format(
                    config.settings['site'], invitation.pk, invitation.key),
            }
            email(form.cleaned_data['email'], "blank", "blank",
                  "page_manager_invitation", substitutions)

        elif campaign:
            invitation = ManagerInvitation.objects.create(
                invite_to=form.cleaned_data['email'],
                invite_from=request.user,
                campaign=campaign,
                manager_edit=form.cleaned_data['manager_edit'],
                manager_delete=form.cleaned_data['manager_delete'],
                manager_invite=form.cleaned_data['manager_invite'],
                manager_image_edit=form.cleaned_data['manager_image_edit'],
                manager_view_dashboard=form.
                cleaned_data['manager_view_dashboard'],
            )

            # send an email for the invitation
            substitutions = {
                "-campaignname-":
                campaign.name,
                "-invitationurl-":
                "{}/invite/manager/accept/{}/{}/".format(
                    config.settings['site'], invitation.pk, invitation.key),
            }
            email(form.cleaned_data['email'], "blank", "blank",
                  "campaign_manager_invitation", substitutions)

        # redirect the admin/manager to the Page
        status = True
    return status