def admin_setfriend(): """ Start a user update background task """ uid = request.args.get("uid", "") state = request.args.get("state", "1") # Default: set as friend try: state = bool(int(state)) except: return "<html><body><p>Invalid state string: '{0}'</p></body></html>".format(state) u = User.load_if_exists(uid) if uid else None if u is None: return "<html><body><p>Unknown user id '{0}'</p></body></html>".format(uid) was_friend = u.friend() u.set_friend(state) u.set_has_paid(state) u.update() logging.info("Friend state of user {0} manually set to {1}".format(uid, state)) return "<html><body><p>User '{0}': friend state was '{2}', set to '{1}'</p></body></html>".format(uid, state, was_friend)
def handle(request): """ Handle an incoming request to the /billing URL path """ if request.method != "POST": # This is probably an incoming redirect from the SalesCloud IFRAME # after completing a payment form xsc_key = request.args.get("salescloud_access_key", "")[0:256] xsc_date = request.args.get("salescloud_date", "")[0:256] xsc_digest = request.args.get("salescloud_signature", "")[0:256] uid = User.current_id() or "" # pylint: disable=bad-continuation if not request_valid( request.method, request.base_url, uid.encode("ascii"), # Payload xsc_date, xsc_key, xsc_digest, max_time=300.0): # Wrong signature: probably not coming from SalesCloud logging.warning( "Invalid signature in incoming redirect GET - url {0}".format( request.base_url)) # !!! The signature from SalesCloud in this case does # !!! not agree with our calculation, so we leave it at that # return "<html><body>Invalid signature</body></html>", 403 # Forbidden return redirect(url_for("friend", action=0)) # Redirect to a thank-you page # Begin by validating the request by checking its signature xsc_key = request.headers.get("X-SalesCloud-Access-Key", "")[0:256] xsc_date = request.headers.get("X-SalesCloud-Date", "")[0:256] xsc_digest = request.headers.get("X-SalesCloud-Signature", "")[0:256] payload = b"" try: # Do not accept request bodies larger than 2K if int(request.headers.get("Content-length", 0)) < 2048: payload = request.get_data(cache=False, as_text=False) except Exception as ex: # Something wrong with the Content-length header or the request body logging.error("Exception when obtaining payload: {0}".format(ex)) # pylint: disable=bad-continuation if not request_valid(request.method, request.url, payload, xsc_date, xsc_key, xsc_digest): logging.error("Invalid signature received") return jsonify(ok=False, reason="Invalid signature"), 403 # Forbidden # The request looks legit # Note: We can't use request.get_json() because we already read the data stream # using get_data() above j = json.loads(payload.decode("utf-8")) if payload else None # logging.info("/billing json is {0}".format(j)) # Example billing POST: # {u'customer_label': u'', u'subscription_status': u'true', u'customer_id': u'34724', # u'after_renewal': u'2017-01-14T18:34:42+00:00', # u'before_renewal': u'2016-12-14T18:34:42+00:00', # u'product_id': u'479', u'type': u'subscription_updated'} if j is None: logging.error("Empty or illegal JSON") return jsonify(ok=False, reason="Empty or illegal JSON"), 400 # Bad request handled = False _FRIEND_OF_NETSKRAFL = "479" # Product id for friend subscription # pylint: disable=bad-continuation if (j.get("type") in ("subscription_updated", "subscription_created") and j.get("product_id") == _FRIEND_OF_NETSKRAFL): # Updating the subscription status of a user uid = j.get("customer_label") if uid and not isinstance(uid, str): uid = None if uid: uid = uid[0:32] # Sanity cut-off user = User.load_if_exists(uid) if user is None: logging.error("Unknown or illegal user id: '{0}'".format( "[None]" if uid is None else uid)) return jsonify(ok=False, reason="Unknown or illegal user id (customer_label)" ), 400 # Bad request status = j.get("subscription_status") if status == "true": # Enable subscription, mark as friend user.set_friend(True) user.set_has_paid(True) user.update() logging.info("Set user {0} as friend".format(uid)) handled = True elif status == "false": # Disable subscription, remove friend status user.set_friend(False) user.set_has_paid(False) user.update() logging.info("Removed user {0} as friend".format(uid)) handled = True if not handled: logging.warning( "/billing unknown request '{0}', did not handle".format( j.get("type"))) return jsonify(ok=True, handled=handled)
def handle(request): """ Handle an incoming request to the /billing URL path """ if request.method != 'POST': # This is probably an incoming redirect from the SalesCloud IFRAME # after completing a payment form xsc_key = request.args.get("salescloud_access_key", "")[0:256] xsc_date = request.args.get("salescloud_date", "")[0:256] xsc_digest = request.args.get("salescloud_signature", "")[0:256].encode('utf-8') # Required uid = User.current_id() or "" if not request_valid(request.method, request.base_url, uid, xsc_date, xsc_key, xsc_digest, max_time = 300.0): # Wrong signature: probably not coming from SalesCloud logging.warning("Invalid signature in incoming redirect GET - url {0}".format(request.base_url)) # return "<html><body>Invalid signature</body></html>", 403 # Forbidden return redirect(url_for("friend", action=0)) # Redirect to a thank-you page # Begin by validating the request by checking its signature xsc_key = request.headers.get("X-SalesCloud-Access-Key", "")[0:256] xsc_date = request.headers.get("X-SalesCloud-Date", "")[0:256] xsc_digest = request.headers.get("X-SalesCloud-Signature", "")[0:256].encode('utf-8') # Required payload = "" try: # Do not accept request bodies larger than 2K if int(request.headers.get("Content-length", 0)) < 2048: payload = request.get_data(cache=False, as_text=False) except Exception as ex: # Something wrong with the Content-length header or the request body logging.error("Exception when obtaining payload: {0}".format(ex)) if not request_valid(request.method, request.url, payload, xsc_date, xsc_key, xsc_digest): logging.error("Invalid signature received") return jsonify(ok = False, reason = "Invalid signature"), 403 # Forbidden # The request looks legit # Note: We can't use request.get_json() because we already read the data stream # using get_data() above j = json.loads(payload.decode('utf-8')) if payload else None # logging.info("/billing json is {0}".format(j)) # Example billing POST: # {u'customer_label': u'', u'subscription_status': u'true', u'customer_id': u'34724', u'after_renewal': u'2017-01-14T18:34:42+00:00', # u'before_renewal': u'2016-12-14T18:34:42+00:00', u'product_id': u'479', u'type': u'subscription_updated'} if j is None: return jsonify(ok = False, reason = u"Empty or illegal JSON") handled = False _FRIEND_OF_NETSKRAFL = u"479" # Product id for friend subscription if j.get(u"type") in (u"subscription_updated", u"subscription_created") \ and j.get(u"product_id") == _FRIEND_OF_NETSKRAFL: # Updating the subscription status of a user uid = j.get(u"customer_label") if uid and not isinstance(uid, basestring): uid = None if uid: uid = uid[0:32] # Sanity cut-off user = User.load_if_exists(uid) if uid else None if user is None: return jsonify(ok = False, reason = u"Unknown or illegal user id") if j.get(u"subscription_status") == u"true": # Enable subscription, mark as friend user.set_friend(True) user.set_has_paid(True) user.update() logging.info("Set user {0} as friend".format(uid)) handled = True elif j.get(u"subscription_status") == u"false": # Disable subscription, remove friend status user.set_friend(False) user.set_has_paid(False) user.update() logging.info("Removed user {0} as friend".format(uid)) handled = True if not handled: logging.warning("/billing unknown request '{0}', did not handle".format(j.get(u"type"))) return jsonify(ok = True, handled = handled)