Add alerts for suspicious selfserve advertising payments.

This commit is contained in:
Brian Simpson
2014-10-30 15:01:31 -04:00
committed by David Wick
parent 6b3f4b69de
commit b76322f8e4
7 changed files with 98 additions and 16 deletions

View File

@@ -977,18 +977,20 @@ class PromoteApiController(ApiController):
rc = RenderableCampaign.from_campaigns(link, campaign)
jquery.update_campaign(campaign._fullname, rc.render_html())
@validatedForm(VSponsor('link'),
VModhash(),
link=VByName("link"),
campaign=VPromoCampaign("campaign"),
customer_id=VInt("customer_id", min=0),
pay_id=VInt("account", min=0),
edit=VBoolean("edit"),
address=ValidAddress(
["firstName", "lastName", "company", "address",
"city", "state", "zip", "country", "phoneNumber"]),
creditcard=ValidCard(["cardNumber", "expirationDate",
"cardCode"]))
@validatedForm(
VSponsor('link'),
VModhash(),
link=VByName("link"),
campaign=VPromoCampaign("campaign"),
customer_id=VInt("customer_id", min=0),
pay_id=VInt("account", min=0),
edit=VBoolean("edit"),
address=ValidAddress(
["firstName", "lastName", "company", "address", "city", "state",
"zip", "country", "phoneNumber"]
),
creditcard=ValidCard(["cardNumber", "expirationDate", "cardCode"]),
)
def POST_update_pay(self, form, jquery, link, campaign, customer_id, pay_id,
edit, address, creditcard):
if not g.authorizenetapi:
@@ -1033,7 +1035,9 @@ class PromoteApiController(ApiController):
pay_id = edit_profile(c.user, address, creditcard, pay_id)
reason = None
if pay_id:
promote.new_payment_method(c.user, link)
if pay_id:
success, reason = promote.auth_campaign(link, campaign, c.user,
pay_id)
@@ -1041,9 +1045,13 @@ class PromoteApiController(ApiController):
if success:
form.redirect(promote.promo_edit_url(link))
return
msg = reason or _("failed to authenticate card. sorry.")
form.set_text(".status", msg)
else:
promote.failed_payment_method(c.user, link)
msg = reason or _("failed to authenticate card. sorry.")
form.set_text(".status", msg)
else:
promote.failed_payment_method(c.user, link)
form.set_text(".status", _("failed to authenticate card. sorry."))
@validate(VSponsor("link_name"),
VModhash(),

View File

@@ -257,6 +257,15 @@ def void_payment(thing, campaign, reason):
reason=reason)
def suspicious_payment(user, link):
from r2.lib.pages import SuspiciousPaymentEmail
email = "fraud@reddit.com"
body = SuspiciousPaymentEmail(user, link).render(style="email")
kind = Email.Kind.SUSPICIOUS_PAYMENT
_system_email(email, body, kind)
def send_html_email(to_addr, from_addr, subject, html, subtype="html"):
from r2.lib.filters import _force_utf8
msg = MIMEText(_force_utf8(html), subtype)

View File

@@ -2757,6 +2757,12 @@ class VerifyEmail(Templated):
class Promo_Email(Templated):
pass
class SuspiciousPaymentEmail(Templated):
def __init__(self, user, link):
Templated.__init__(self, user=user, link=link)
class ResetPassword(Templated):
"""Form for actually resetting a lost password, after the user has
clicked on the link provided to them in the Password_Reset email

View File

@@ -905,6 +905,29 @@ def get_spent_amount(campaign):
return spent
PAYMENT_METHODS_ALERT_LIMIT = 3
FAILED_PAYMENTS_ALERT_LIMIT = 5
def new_payment_method(user, link):
user._incr('num_payment_methods')
if (user.num_payment_methods > PAYMENT_METHODS_ALERT_LIMIT and
not user.payment_flagged):
payment_flag_user(user, link)
def failed_payment_method(user, link):
user._incr('num_failed_payments')
if (user.num_failed_payments > FAILED_PAYMENTS_ALERT_LIMIT and
not user.payment_flagged):
payment_flag_user(user, link)
def payment_flag_user(user, link):
user.payment_flagged = True
user._commit()
emailer.suspicious_payment(user, link)
def Run(verbose=True):
"""reddit-job-update_promos: Intended to be run hourly to pull in
scheduled changes to ads

View File

@@ -62,6 +62,8 @@ class Account(Thing):
'report_ignored', 'spammer',
'reported', 'gold_creddits',
'inbox_count',
'num_payment_methods',
'num_failed_payments',
)
_int_prop_suffix = '_karma'
_essentials = ('name', )
@@ -136,6 +138,7 @@ class Account(Thing):
num_failed_payments=0,
pref_show_snoovatar=False,
gild_reveal_username=False,
payment_flagged=False,
)
_preference_attrs = tuple(k for k in _defaults.keys()
if k.startswith("pref_"))

View File

@@ -306,6 +306,7 @@ class Email(object):
"REFUNDED_PROMO",
"VOID_PAYMENT",
"GOLD_GIFT_CODE",
"SUSPICIOUS_PAYMENT",
)
# Do not remove anything from this dictionary! See above comment.
@@ -331,6 +332,7 @@ class Email(object):
Kind.REFUNDED_PROMO: _("[reddit] your campaign didn't get enough impressions"),
Kind.VOID_PAYMENT: _("[reddit] your payment has been voided"),
Kind.GOLD_GIFT_CODE: _("[reddit] your reddit gold gift code"),
Kind.SUSPICIOUS_PAYMENT: _("[selfserve] suspicious payment alert"),
}
def __init__(self, user, thing, email, from_name, date, ip,

View File

@@ -0,0 +1,31 @@
## The contents of this file are subject to the Common Public Attribution
## License Version 1.0. (the "License"); you may not use this file except in
## compliance with the License. You may obtain a copy of the License at
## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
## License Version 1.1, but Sections 14 and 15 have been added to cover use of
## software over a computer network and provide for limited attribution for the
## Original Developer. In addition, Exhibit A has been modified to be
## consistent with Exhibit B.
##
## Software distributed under the License is distributed on an "AS IS" basis,
## WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
## the specific language governing rights and limitations under the License.
##
## The Original Code is reddit.
##
## The Original Developer is the Initial Developer. The Initial Developer of
## the Original Code is reddit Inc.
##
## All portions of the code written by reddit are Copyright (c) 2006-2014
## reddit Inc. All Rights Reserved.
###############################################################################
<%!
from r2.lib.promote import promo_edit_url
%>
<%namespace file="utils.html" import="plain_link"/>
There is suspicious payment activity by ${plain_link("/u/%s" % thing.user.name, "/user/%s/promoted" % thing.user.name, _sr_path=False)}.
This report was triggered by the promotion ${plain_link(thing.link.title, promo_edit_url(thing.link), _sr_path=False)}.