def password_email(user): """ For resetting a user's password. """ from r2.lib.pages import PasswordReset reset_count_key = "email-reset_count_%s" % user._id g.cache.add(reset_count_key, 0, time=3600 * 12) if g.cache.incr(reset_count_key) > 3: return False reset_count_global = "email-reset_count_global" g.cache.add(reset_count_global, 0, time=3600) if g.cache.incr(reset_count_global) > 1000: raise ValueError("Somebody's beating the hell out of the password reset box") key = passhash(randstr(64, reallyrandom = True), user.email) passlink = 'http://' + g.domain + '/resetpassword/' + key g.log.info("Generated password reset link: " + passlink) g.hardcache.set("email-reset_%s" % key, user._id, time=3600 * 12) _system_email(user.email, PasswordReset(user=user, passlink=passlink).render(style='email'), Email.Kind.RESET_PASSWORD) return True
def generate_blob(data): passthrough = randstr(15) g.hardcache.set("payment_blob-" + passthrough, data, 86400 * 30) g.log.info("just set payment_blob-%s", passthrough) return passthrough
def password_email(user): """ For resetting a user's password. """ from r2.lib.pages import PasswordReset reset_count_key = "email-reset_count_%s" % user._id g.cache.add(reset_count_key, 0, time=3600 * 12) if g.cache.incr(reset_count_key) > 3: return False reset_count_global = "email-reset_count_global" g.cache.add(reset_count_global, 0, time=3600) if g.cache.incr(reset_count_global) > 1000: raise ValueError( "Somebody's beating the hell out of the password reset box") key = passhash(randstr(64, reallyrandom=True), user.email) passlink = 'http://' + g.domain + '/resetpassword/' + key g.log.info("Generated password reset link: " + passlink) g.hardcache.set("email-reset_%s" % key, user._id, time=3600 * 12) _system_email( user.email, PasswordReset(user=user, passlink=passlink).render(style='email'), Email.Kind.RESET_PASSWORD) return True
def valid_url(prop,value,report): """ checks url(...) arguments in CSS, ensuring that the contents are officially sanctioned. Sanctioned urls include: * anything in /static/ * image labels %%..%% for images uploaded on /about/stylesheet * urls with domains in g.allowed_css_linked_domains """ url = value.getStringValue() # local urls are allowed if local_urls.match(url): pass # custom urls are allowed, but need to be transformed into a real path elif custom_img_urls.match(url): name = custom_img_urls.match(url).group(1) # the label -> image number lookup is stored on the subreddit if c.site.images.has_key(name): num = c.site.images[name] value._setCssText("url(http:/%s%s_%d.png?v=%s)" % (g.s3_thumb_bucket, c.site._fullname, num, randstr(36))) else: # unknown image label -> error report.append(ValidationError(msgs['broken_url'] % dict(brokenurl = value.cssText), value)) # allowed domains are ok elif domain(url) in g.allowed_css_linked_domains: pass else: report.append(ValidationError(msgs['broken_url'] % dict(brokenurl = value.cssText), value))
def valid_url(prop, value, report): """ checks url(...) arguments in CSS, ensuring that the contents are officially sanctioned. Sanctioned urls include: * anything in /static/ * image labels %%..%% for images uploaded on /about/stylesheet * urls with domains in g.allowed_css_linked_domains """ url = value.getStringValue() # local urls are allowed if local_urls.match(url): pass # custom urls are allowed, but need to be transformed into a real path elif custom_img_urls.match(url): name = custom_img_urls.match(url).group(1) # the label -> image number lookup is stored on the subreddit if c.site.images.has_key(name): num = c.site.images[name] value._setCssText( "url(http:/%s%s_%d.png?v=%s)" % (g.s3_thumb_bucket, c.site._fullname, num, randstr(36))) else: # unknown image label -> error report.append( ValidationError( msgs['broken_url'] % dict(brokenurl=value.cssText), value)) # allowed domains are ok elif domain(url) in g.allowed_css_linked_domains: pass else: report.append( ValidationError(msgs['broken_url'] % dict(brokenurl=value.cssText), value))
def process_google_transaction(trans_id): trans = _google_ordernum_request(trans_id) # get the financial details auth = trans.find("authorization-amount-notification") if not auth: # see if the payment was declinded status = trans.findAll('financial-order-state') if 'PAYMENT_DECLINED' in [x.contents[0] for x in status]: g.log.error("google declined transaction found: '%s'" % trans_id) rp = gold_table.update( sa.and_(gold_table.c.status == 'uncharged', gold_table.c.trans_id == 'g' + str(trans_id)), values = { gold_table.c.status : "declined" }).execute() elif 'REVIEWING' not in [x.contents[0] for x in status]: g.log.error("google transaction not found: '%s', status: %s" % (trans_id, [x.contents[0] for x in status])) elif auth.find("financial-order-state").contents[0] == "CHARGEABLE": email = str(auth.find("email").contents[0]) payer_id = str(auth.find('buyer-id').contents[0]) days = None try: pennies = int(float(auth.find("order-total").contents[0])*100) if pennies == 2999: secret = "ys_" days = 366 elif pennies == 399: secret = "m_" days = 31 else: g.log.error("Got %d pennies via Google?" % pennies) rp = gold_table.update( sa.and_(gold_table.c.status == 'uncharged', gold_table.c.trans_id == 'g' + str(trans_id)), values = { gold_table.c.status : "strange", gold_table.c.pennies : pennies, gold_table.c.payer_email : email, gold_table.c.paying_id : payer_id }).execute() return except ValueError: g.log.error("no amount in google checkout for transid %s" % trans_id) return secret += randstr(10) # no point charging twice. If we are in this func, the db doesn't # know it was already charged so we still have to update and email charged = trans.find("charge-amount-notification") if not charged: _google_charge_and_ship(trans_id) create_unclaimed_gold("g" + str(trans_id), email, payer_id, pennies, days, str(secret), datetime.now(g.tz)) notify_unclaimed_gold(trans_id, secret, email, "Google")
def passhash(username, password, salt=''): if salt is True: salt = randstr(3) tohash = '%s%s %s' % (salt, username, password) if isinstance(tohash, unicode): # Force tohash to be a byte string so it can be hashed tohash = tohash.encode('utf8') return salt + hashlib.sha1(tohash).hexdigest()
def passhash(username, password, salt = ''): if salt is True: salt = randstr(3) tohash = '%s%s %s' % (salt, username, password) if isinstance(tohash, unicode): # Force tohash to be a byte string so it can be hashed tohash = tohash.encode('utf8') return salt + hashlib.sha1(tohash).hexdigest()
def create_gift_gold (giver_id, recipient_id, days, date, signed): trans_id = "X%d%s-%s" % (int(time()), randstr(2), 'S' if signed else 'A') gold_table.insert().execute(trans_id=trans_id, status="gift", paying_id=giver_id, payer_email='', pennies=0, days=days, account_id=recipient_id, date=date)
def create_gift_gold(giver_id, recipient_id, days, date, signed): trans_id = "X%d%s-%s" % (int(time()), randstr(2), 'S' if signed else 'A') gold_table.insert().execute(trans_id=trans_id, status="gift", paying_id=giver_id, payer_email='', pennies=0, days=days, account_id=recipient_id, date=date)
def password_email(user): """ For resetting a user's password. """ from r2.lib.pages import PasswordReset key = passhash(randstr(64, reallyrandom = True), user.email) passlink = 'http://' + g.domain + '/resetpassword/' + key print "Generated password reset link: " + passlink g.cache.set("reset_%s" %key, user._id, time=1800) _system_email(user.email, PasswordReset(user=user, passlink=passlink).render(style='email'), Email.Kind.RESET_PASSWORD)
def GET_gold(self, goldtype, period, months, signed, recipient_name, giftmessage): start_over = False recipient = None if goldtype == "autorenew": if period is None: start_over = True elif goldtype in ("onetime", "creddits"): if months is None or months < 1: start_over = True elif goldtype == "gift": if months is None or months < 1: start_over = True try: recipient = Account._by_name(recipient_name or "") except NotFound: start_over = True else: goldtype = "" start_over = True if start_over: return BoringPage(_("reddit gold"), show_sidebar=False, content=Gold(goldtype, period, months, signed, recipient, recipient_name)).render() else: payment_blob = dict(goldtype=goldtype, account_id=c.user._id, account_name=c.user.name, status="initialized") if goldtype == "gift": payment_blob["signed"] = signed payment_blob["recipient"] = recipient_name payment_blob["giftmessage"] = giftmessage passthrough = randstr(15) g.hardcache.set("payment_blob-" + passthrough, payment_blob, 86400 * 30) g.log.info("just set payment_blob-%s" % passthrough) return BoringPage(_("reddit gold"), show_sidebar=False, content=GoldPayment(goldtype, period, months, signed, recipient, giftmessage, passthrough)).render()
def create_gold_code(trans_id, payer_email, paying_id, pennies, days, date): if not trans_id: trans_id = "GC%d%s" % (int(time()), randstr(2)) valid_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" # keep picking new codes until we find an unused one while True: code = randstr(10, alphabet=valid_chars) s = sa.select([gold_table], sa.and_(gold_table.c.secret == code.lower(), gold_table.c.status == "unclaimed")) res = s.execute().fetchall() if not res: gold_table.insert().execute( trans_id=trans_id, status="unclaimed", payer_email=payer_email, paying_id=paying_id, pennies=pennies, days=days, secret=code.lower(), date=date, ) return code
def create_gift_gold(giver_id, recipient_id, days, date, signed, note=None): trans_id = "X%d%s-%s" % (int(time()), randstr(2), "S" if signed else "A") gold_table.insert().execute( trans_id=trans_id, status="gift", paying_id=giver_id, payer_email="", pennies=0, days=days, account_id=recipient_id, date=date, secret=note, )
def valid_url(prop,value,report): """ checks url(...) arguments in CSS, ensuring that the contents are officially sanctioned. Sanctioned urls include: * anything in /static/ * image labels %%..%% for images uploaded on /about/stylesheet * urls with domains in g.allowed_css_linked_domains """ try: url = value.getStringValue() except IndexError: g.log.error("Problem validating [%r]" % value) raise # local urls are allowed if local_urls.match(url): t_url = None while url != t_url: t_url, url = url, filters.url_unescape(url) # disallow path trickery if "../" in url: report.append(ValidationError(msgs['broken_url'] % dict(brokenurl = value.cssText), value)) # custom urls are allowed, but need to be transformed into a real path elif custom_img_urls.match(url): name = custom_img_urls.match(url).group(1) # the label -> image number lookup is stored on the subreddit if c.site.images.has_key(name): num = c.site.images[name] value._setCssText("url(http://%s/%s_%d.png?v=%s)" % (g.s3_thumb_bucket, c.site._fullname, num, randstr(36))) else: # unknown image label -> error report.append(ValidationError(msgs['broken_url'] % dict(brokenurl = value.cssText), value)) else: try: u = urlparse(url) valid_scheme = u.scheme and u.scheme in valid_url_schemes valid_domain = strip_www(u.netloc) in g.allowed_css_linked_domains except ValueError: u = False # allowed domains are ok if not (u and valid_scheme and valid_domain): report.append(ValidationError(msgs['broken_url'] % dict(brokenurl = value.cssText), value))
def GET_gold(self, goldtype, period, months, signed, recipient_name, giftmessage): start_over = False recipient = None if goldtype == "autorenew": if period is None: start_over = True elif goldtype in ("onetime", "creddits"): if months is None or months < 1: start_over = True elif goldtype == "gift": if months is None or months < 1: start_over = True try: recipient = Account._by_name(recipient_name or "") except NotFound: start_over = True else: goldtype = "" start_over = True if start_over: return BoringPage(_("reddit gold"), show_sidebar = False, content=Gold(goldtype, period, months, signed, recipient, recipient_name)).render() else: payment_blob = dict(goldtype = goldtype, account_id = c.user._id, account_name = c.user.name, status = "initialized") if goldtype == "gift": payment_blob["signed"] = signed payment_blob["recipient"] = recipient_name payment_blob["giftmessage"] = giftmessage passthrough = randstr(15) g.hardcache.set("payment_blob-" + passthrough, payment_blob, 86400 * 30) g.log.info("just set payment_blob-%s" % passthrough) return BoringPage(_("reddit gold"), show_sidebar = False, content=GoldPayment(goldtype, period, months, signed, recipient, giftmessage, passthrough) ).render()
def create_gold_code(trans_id, payer_email, paying_id, pennies, days, date): if not trans_id: trans_id = "GC%d%s" % (int(time()), randstr(2)) valid_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' # keep picking new codes until we find an unused one while True: code = randstr(10, alphabet=valid_chars) s = sa.select([gold_table], sa.and_(gold_table.c.secret == code.lower(), gold_table.c.status == 'unclaimed')) res = s.execute().fetchall() if not res: gold_table.insert().execute(trans_id=trans_id, status='unclaimed', payer_email=payer_email, paying_id=paying_id, pennies=pennies, days=days, secret=code.lower(), date=date) return code
def send_claim_message(username, postcard_url): # this is ripped off from the gold-record.py code in reddit-private timestamp = int(time.time()) now = datetime.datetime.now(g.tz) transaction_id = "M%d" % timestamp secret = "p_%d%s" % (timestamp, randstr(5)) create_unclaimed_gold(transaction_id, "", "manual-unclaimed", 0, REWARD, secret, now, None) claim_url = "http://www.reddit.com/thanks/" + secret user = Account._by_name(username) message = TEMPLATE % dict(postcard_url=postcard_url, claim_url=claim_url, gold_support_email=g.goldthanks_email) send_system_message(user, "we got that postcard you sent us!", message)
def passhash(username, password, salt = ''): if salt is True: salt = randstr(3) tohash = '%s%s %s' % (salt, username, password) return salt + hashlib.sha1(tohash).hexdigest()
def process_google_transaction(trans_id): trans = _google_ordernum_request(trans_id) # get the financial details auth = trans.find("authorization-amount-notification") # creddits? is_creddits = False cart = trans.find("shopping-cart") if cart: for item in cart.findAll("item-name"): if "creddit" in item.contents[0]: is_creddits = True break if not auth: # see if the payment was declinded status = trans.findAll("financial-order-state") if "PAYMENT_DECLINED" in [x.contents[0] for x in status]: g.log.error("google declined transaction found: '%s'" % trans_id) rp = gold_table.update( sa.and_(gold_table.c.status == "uncharged", gold_table.c.trans_id == "g" + str(trans_id)), values={gold_table.c.status: "declined"}, ).execute() elif "REVIEWING" not in [x.contents[0] for x in status]: g.log.error("google transaction not found: '%s', status: %s" % (trans_id, [x.contents[0] for x in status])) elif auth.find("financial-order-state").contents[0] == "CHARGEABLE": email = str(auth.find("email").contents[0]) payer_id = str(auth.find("buyer-id").contents[0]) days = None try: pennies = int(float(auth.find("order-total").contents[0]) * 100) if is_creddits: secret = "cr_" if pennies >= g.gold_year_price.pennies: days = 12 * 31 * int(pennies / g.gold_year_price.pennies) else: days = 31 * int(pennies / g.gold_month_price.pennies) elif pennies == g.gold_year_price.pennies: secret = "ys_" days = 366 elif pennies == g.gold_month_price.pennies: secret = "m_" days = 31 else: g.log.error("Got %d pennies via Google?" % pennies) rp = gold_table.update( sa.and_(gold_table.c.status == "uncharged", gold_table.c.trans_id == "g" + str(trans_id)), values={ gold_table.c.status: "strange", gold_table.c.pennies: pennies, gold_table.c.payer_email: email, gold_table.c.paying_id: payer_id, }, ).execute() return except ValueError: g.log.error("no amount in google checkout for transid %s" % trans_id) return secret += randstr(10) # no point charging twice. If we are in this func, the db doesn't # know it was already charged so we still have to update and email charged = trans.find("charge-amount-notification") if not charged: _google_charge_and_ship(trans_id) create_unclaimed_gold("g" + str(trans_id), email, payer_id, pennies, days, str(secret), datetime.now(g.tz)) notify_unclaimed_gold(trans_id, secret, email, "Google")
def passhash(username, password, salt=''): if salt is True: salt = randstr(3) tohash = '%s%s %s' % (salt, username, password) return salt + hashlib.sha1(tohash).hexdigest()
def process_google_transaction(trans_id): trans = _google_ordernum_request(trans_id) # get the financial details auth = trans.find("authorization-amount-notification") # creddits? is_creddits = False cart = trans.find("shopping-cart") if cart: for item in cart.findAll("item-name"): if "creddit" in item.contents[0]: is_creddits = True break if not auth: # see if the payment was declinded status = trans.findAll('financial-order-state') if 'PAYMENT_DECLINED' in [x.contents[0] for x in status]: g.log.error("google declined transaction found: '%s'" % trans_id) rp = gold_table.update(sa.and_( gold_table.c.status == 'uncharged', gold_table.c.trans_id == 'g' + str(trans_id)), values={ gold_table.c.status: "declined" }).execute() elif 'REVIEWING' not in [x.contents[0] for x in status]: g.log.error("google transaction not found: '%s', status: %s" % (trans_id, [x.contents[0] for x in status])) elif auth.find("financial-order-state").contents[0] == "CHARGEABLE": email = str(auth.find("email").contents[0]) payer_id = str(auth.find('buyer-id').contents[0]) days = None try: pennies = int(float(auth.find("order-total").contents[0]) * 100) if is_creddits: secret = "cr_" if pennies >= 2999: days = 12 * 31 * int(pennies / 2999) else: days = 31 * int(pennies / 399) elif pennies == 2999: secret = "ys_" days = 366 elif pennies == 399: secret = "m_" days = 31 else: g.log.error("Got %d pennies via Google?" % pennies) rp = gold_table.update(sa.and_( gold_table.c.status == 'uncharged', gold_table.c.trans_id == 'g' + str(trans_id)), values={ gold_table.c.status: "strange", gold_table.c.pennies: pennies, gold_table.c.payer_email: email, gold_table.c.paying_id: payer_id }).execute() return except ValueError: g.log.error("no amount in google checkout for transid %s" % trans_id) return secret += randstr(10) # no point charging twice. If we are in this func, the db doesn't # know it was already charged so we still have to update and email charged = trans.find("charge-amount-notification") if not charged: _google_charge_and_ship(trans_id) create_unclaimed_gold("g" + str(trans_id), email, payer_id, pennies, days, str(secret), datetime.now(g.tz)) notify_unclaimed_gold(trans_id, secret, email, "Google")
def passhash(username, password, salt=""): if salt is True: salt = randstr(3) tohash = "%s%s %s" % (salt, username, password) return salt + sha.new(tohash).hexdigest()