Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
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)