Exemple #1
0
def advantage_shop_view():
    account = previous_purchase_id = None
    is_test_backend = flask.request.args.get("test_backend", False)

    stripe_publishable_key = os.getenv("STRIPE_LIVE_PUBLISHABLE_KEY",
                                       "pk_live_68aXqowUeX574aGsVck8eiIE")
    api_url = flask.current_app.config["CONTRACTS_LIVE_API_URL"]

    if is_test_backend:
        stripe_publishable_key = os.getenv(
            "STRIPE_TEST_PUBLISHABLE_KEY",
            "pk_test_yndN9H0GcJffPe0W58Nm64cM00riYG4N46",
        )
        api_url = flask.current_app.config["CONTRACTS_TEST_API_URL"]

    if user_info(flask.session):
        advantage = AdvantageContracts(
            session,
            flask.session["authentication_token"],
            api_url=api_url,
        )
        if flask.session.get("guest_authentication_token"):
            flask.session.pop("guest_authentication_token")

        try:
            account = advantage.get_purchase_account()
        except HTTPError as err:
            code = err.response.status_code
            if code == 401:
                # We got an unauthorized request, so we likely
                # need to re-login to refresh the macaroon
                flask.current_app.extensions["sentry"].captureException(
                    extra={
                        "session_keys": flask.session.keys(),
                        "request_url": err.request.url,
                        "request_headers": err.request.headers,
                        "response_headers": err.response.headers,
                        "response_body": err.response.json(),
                        "response_code": err.response.json()["code"],
                        "response_message": err.response.json()["message"],
                    })

                empty_session(flask.session)

                return flask.render_template(
                    "advantage/subscribe/index.html",
                    account=None,
                    previous_purchase_id=None,
                    product_listings=[],
                    stripe_publishable_key=stripe_publishable_key,
                    is_test_backend=is_test_backend,
                )
            if code != 404:
                raise
            # There is no purchase account yet for this user.
            # One will need to be created later, but this is an expected
            # condition.
    else:
        advantage = AdvantageContracts(session, None, api_url=api_url)

    if account is not None:
        resp = advantage.get_account_subscriptions_for_marketplace(
            account["id"], "canonical-ua")
        subs = resp.get("subscriptions")
        if subs:
            previous_purchase_id = subs[0].get("lastPurchaseID")

    listings_response = advantage.get_marketplace_product_listings(
        "canonical-ua")
    product_listings = listings_response.get("productListings")
    if not product_listings:
        # For the time being, no product listings means the shop has not been
        # activated, so fallback to shopify. This should become an error later.
        return flask.redirect("https://buy.ubuntu.com/")

    products = {pr["id"]: pr for pr in listings_response["products"]}
    listings = []
    for listing in product_listings:
        if "price" not in listing:
            continue
        listing["product"] = products[listing["productID"]]
        listings.append(listing)

    return flask.render_template(
        "advantage/subscribe/index.html",
        account=account,
        previous_purchase_id=previous_purchase_id,
        product_listings=listings,
        stripe_publishable_key=stripe_publishable_key,
        is_test_backend=is_test_backend,
    )
Exemple #2
0
def post_advantage_subscriptions(preview):
    is_test_backend = flask.request.args.get("test_backend", False)

    api_url = flask.current_app.config["CONTRACTS_LIVE_API_URL"]

    if is_test_backend:
        api_url = flask.current_app.config["CONTRACTS_TEST_API_URL"]

    user_token = flask.session.get("authentication_token")
    guest_token = flask.session.get("guest_authentication_token")

    if user_info(flask.session) or guest_token:
        advantage = AdvantageContracts(
            session,
            user_token or guest_token,
            token_type=("Macaroon" if user_token else "Bearer"),
            api_url=api_url,
        )
    else:
        return flask.jsonify({"error": "authentication required"}), 401

    payload = flask.request.json
    if not payload:
        return flask.jsonify({}), 400

    account_id = payload.get("account_id")
    previous_purchase_id = payload.get("previous_purchase_id")
    last_subscription = {}

    if not guest_token:
        try:
            subscriptions = (
                advantage.get_account_subscriptions_for_marketplace(
                    account_id=account_id, marketplace="canonical-ua"))
        except HTTPError:
            flask.current_app.extensions["sentry"].captureException(
                extra={"payload": payload})
            return (
                flask.jsonify(
                    {"error": "could not retrieve account subscriptions"}),
                500,
            )

        if subscriptions:
            last_subscription = subscriptions["subscriptions"][0]

    # If there is a subscription we get the current metric
    # value for each product listing so we can generate a
    # purchase request with updated quantities later.
    subscribed_quantities = {}
    if "purchasedProductListings" in last_subscription:
        for item in last_subscription["purchasedProductListings"]:
            product_listing_id = item["productListing"]["id"]
            subscribed_quantities[product_listing_id] = item["value"]

    purchase_items = []
    for product in payload.get("products"):
        product_listing_id = product["product_listing_id"]
        metric_value = product["quantity"] + subscribed_quantities.get(
            product_listing_id, 0)

        purchase_items.append({
            "productListingID": product_listing_id,
            "metric": "active-machines",
            "value": metric_value,
        })

    purchase_request = {
        "accountID": account_id,
        "purchaseItems": purchase_items,
        "previousPurchaseID": previous_purchase_id,
    }

    try:
        if not preview:
            purchase = advantage.purchase_from_marketplace(
                marketplace="canonical-ua", purchase_request=purchase_request)
        else:
            purchase = advantage.preview_purchase_from_marketplace(
                marketplace="canonical-ua", purchase_request=purchase_request)
    except HTTPError as http_error:
        flask.current_app.extensions["sentry"].captureException(
            extra={
                "purchase_request": purchase_request,
                "api_response": http_error.response.json(),
            })
        return (
            flask.jsonify({"error": "could not complete this purchase"}),
            500,
        )

    return flask.jsonify(purchase), 200