Marketplace/Wood Duck

From MozillaWiki
Jump to: navigation, search
Stop (medium size).png
The Marketplace has been placed into maintenance mode. It is no longer under active development. You can read complete details here.

There are two orthogonal problems related to the woodduck project: a legal problem and a UX problem. Each should be addressed separately.

Legal concerns

We have agreements with some app developers that their trademarks not be used or distributed outside of Marketplace. There are not mechanisms in place that stop API consumers from seeing those apps.

Definitions

  • Non-Marketplace client - any client not explicitly reporting that it is an official Marketplace client via client=marketplace.
  • Marketplace-exclusive app - an app with which Marketplace has signed an exclusivity/nondistribution agreement.

Solution

By default, we will omit exclusive apps from API responses. Those apps should only be included if we can ascertain that the request is being made by an official Marketplace client: the consumer pages, curation tools, etc.

Marketplace-exclusive apps will be denoted by a new is_marketplace_exclusive boolean field on the app model.

Developer agreement changes

The developer agreement should be amended to disallow the use of client=maketplace by third-party clients.

Reviewer tool changes

The reviewer tools will need to be amended to allow admins (not app owners) to edit the is_marketplace_exclusive value.

Client changes

Each official client will need to send client=marketplace with each API request.

API changes

What follows: an extensive list of requirements for the Marketplace API to come into compliance with our exclusivity agreements.

Notes

  • This list assumes the strictest possible interpretation of our obligations: that the API should pretend as if these apps do not exist for non-Marketplace clients, only returning 403 instead of 404 for resource views.
  • It may be that some of these assumptions are too ambitious (i.e. Not returning transaction data if it involves a Marketplace-exclusive app); those details should be worked out with our legal team.
  • To bring us into full legal compliance with these agreements, changes should be applied to all versions of the API.
  • A standard response body should be sent in each case where a 403 is returned for exclusivity reasons.

Requirements

  • If a non-Marketplace client attempts to report abuse for a Marketplace-exclusive app, it should 403. (GET /api/abuse/app/)
  • If a non-Marketplace client attempts to return a list of apps the authenticating user has developed, Marketplace-exclusive apps should be excluded. (GET /api/apps/app/)
  • If a non-Marketplace client attempts to return a detail of a Marketplace-exclusive app, it should 403. (GET /api/apps/app/<id>/)
  • If a non-Marketplace client attempts to return a privacy policya of a Marketplace-exclusive app, it should 403. (GET /api/apps/app/<id>/privacy/)
  • If a non-Marketplace client attempts to delete a Marketplace-exclusive app, it should 403. (DELETE /api/apps/app/<id>/)
  • If a non-Marketplace client attempts to update a Marketplace-exclusive app, it should 403. (PUT /api/apps/app/<id>/)
  • If a non-Marketplace client attempts to update the icon of a Marketplace-exclusive app, it should 403. (PUT /api/apps/app/<id>/icon/)
  • If a non-Marketplace client attempts to retrieve a version of a Marketplace-exclusive app, it should 403. (GET /api/apps/versions/<id>/)
  • If a non-Marketplace client attempts to update a version of a Marketplace-exclusive app, it should 403. (PATCH /api/apps/versions/<id>/)
  • If a non-Marketplace client attempts to get the payment information of a Marketplace-exclusive app, it should 403. (GET /api/apps/app/<id>/payments/)
  • If a non-Marketplace client attempts to get the payment status of a Marketplace-exclusive app, it should 403. (POST /api/apps/app/<id>/payments/status)
  • If a non-Marketplace client attempts to get payments debug information of a Marketplace-exclusive app, it should 403. (GET /api/apps/app/<id>/payments/debug)
  • If a non-Marketplace client attempts to update the manifest of a Marketplace-exclusive app, it should 403. (GET /api/apps/app/<id>/refresh-manifest/)
  • If a non-Marketplace client attempts to update the manifest of a Marketplace-exclusive app, it should 403. (GET /api/apps/app/<id>/refresh-manifest/)
  • If a non-Marketplace client attempts to retrieve a list of commbadge threads of a Marketplace-exclusive app, it should 403. (GET /api/comm/app/<id>/)
  • If a non-Marketplace client attempts to retrieve a list of commbadge threads for the authenticating user, it should exclude those for Marketplace-exclusive apps. (GET /api/comm/thread/)
  • If a non-Marketplace client attempts to retrieve the detail of a commbadge thread for a Marketplace-exclusive app, it should 403. (GET /api/comm/thread/<id>/)
  • If a non-Marketplace client attempts to create a commbadge thread for a version of a Marketplace-exclusive app, it should 403. (POST /api/comm/thread/)
  • If a non-Marketplace client attempts to retrieve a list of notes a commbadge thread for a Marketplace-exclusive app contains, it should 403. (GET /api/comm/thread/<id>/note/)
  • If a non-Marketplace client attempts to view a note on a commbadge thread for a Marketplace-exclusive app, it should 403. (GET /api/comm/thread/<id>/note/<id>/)
  • If a non-Marketplace client attempts to create a note on a commbadge thread for a version of a Marketplace-exclusive app, it should 403. (POST /api/comm/thread/<id>/note/)
  • If a non-Marketplace client attempts to create an attachment on a note on a commbadge thread for a version of a Marketplace-exclusive app, it should 403. (POST /api/comm/thread/<id>/attachment/)
  • If a non-Marketplace client attempts to return the list of content ratings for a Marketplace-exclusive app, it should 403. (POST /api/apps/app/<id>/content_ratings/)
  • Marketplace-exclusive apps should be excluded from the export (i.e. cdn/dumped-apps)
  • Dumps from before the date in which Marketplace-exclusive apps are excluded from the export should be deleted.
  • If a non-Marketplace client attempts to access a feed API, it should 403. (/api/feed/)
  • If a non-Marketplace client attempts to access a Fireplace API, it should 403. (/api/fireplace/)
  • If a non-Marketplace client attempts to access a Langpack API, it should 403. (/api/langpacks/)
  • If a non-Marketplace client attempts to create an upsell between one or more Marketplace-exclusive apps, it should 403. (POST /api/payments/upsell)
  • If a non-Marketplace client attempts to create an upsell between one or more Marketplace-exclusive apps, it should 403. (GET /api/payments/upsell/<id>)
  • If a non-Marketplace client attempts to update an upsell between one or more Marketplace-exclusive apps, it should 403. (PATCH /api/payments/upsell/<id>)
  • If a non-Marketplace client attempts to delete an upsell relationship between one or more Marketplace-exclusive apps, it should 403. (DELETE /api/payments/upsell/<id>)
  • If a non-Marketplace client attempts to create an in-app product for a Marketplace-exclusive app, it should 403. (POST /api/payments/upsell/<id>/in-app/)
  • If a non-Marketplace client attempts to list in-app products for a Marketplace-exclusive app, it should 403. (GET /api/payments/upsell/<id>/in-app/)
  • If a non-Marketplace client attempts to get the details of an in-app product for a Marketplace-exclusive app, it should 403. (GET /api/payments/upsell/<id>/in-app/<id>)
  • If a non-Marketplace client attempts to update an in-app product for a Marketplace-exclusive app, it should 403. (PUT /api/payments/upsell/<id>/in-app/<id>)
  • If a non-Marketplace client attempts to produce a JWT for purchase of a Marketplace-exclusive app, it should 403. (POST /api/webpay/prepare)
  • If a non-Marketplace client attempts to produce a JWT for purchase of an in-app product for a Marketplace-exclusive app, it should 403. (POST /api/webpay/inapp/prepare)
  • If a non-Marketplace client attempts to access the status of a payment for a Marketplace-exclusive app, it should 403 (GET /api/webpay/status/<id>)
  • If a non-Marketplace client attempts to record the installation of a Marketplace-exclusive app, it should 403 (/api/installs/record/)
  • If a non-Marketplace client attempts to return the receipt of a Marketplace-exclusive app, it should 403 (/api/receipts/install/)
  • If a non-Marketplace client attempts to reissue the receipt of a Marketplace-exclusive app, it should 403 (/api/receipts/reissue/)
  • If a non-Marketplace client attempts to list ratings of a Marketplace-exclusive app, it should 403. (GET /api/apps/rating?app=<id>)
  • If a non-Marketplace client attempts to list ratings posted by a specific user, it should exclude ratings for Marketplace-exclusive apps. (GET /api/apps/rating?user=<id>)
  • If a non-Marketplace client attempts to get the detail of a rating for a Marketplace-exclusive app, it should 403. (GET /api/apps/rating/<id>)
  • If a non-Marketplace client attempts to create a rating for a Marketplace-exclusive app, it should 403. (POST /api/apps/rating/)
  • If a non-Marketplace client attempts to update the rating of a Marketplace-exclusive app, it should 403. (PUT /api/apps/rating/<id>)
  • If a non-Marketplace client attempts to delete the rating of a Marketplace-exclusive app, it should 403. (DELETE /api/apps/rating/<id>)
  • If a non-Marketplace client attempts to flag as spam the rating of a Marketplace-exclusive app, it should 403. (DELETE /api/apps/rating/<id>/flag)
  • If a non-Marketplace client attempts to access a Reviewers API, it should 403. (/api/reviewers/)
  • If a non-Marketplace client attempts to access a Rocketfuel API, it should 403. (/api/rocketfuel/)
  • If a non-Marketplace client searches apps, the results should exclude Marketplace-exclusive apps. (GET /api/apps/search/)
  • If a non-Marketplace client attempts to retrieve metrics for a Marketplace-exclusive app, it should 403 (GET /api/stats/app/<id>/totals/)
  • If a non-Marketplace client attempts to retrieve information about a transaction for a Marketplace-exclusive app, it should 403 (GET /api/v2/transactions/<id>)

UX Concerns

We might include apps in API responses that are not installable by users browsing third-party app stores due to the installs_allowed_from setting in their manifest.

We should equip app stores with the information and mechanisms they need to exclude or deal with apps that their users are unable to install. I propose doing this in two ways:

Augmented filtering

An installs_allowed_from querystring filter exists on our public search API. This filter currently accepts one value: *. When set, results exclude all apps that do not have installs_allowed_from: ['*'] in their manifest.

This is helpful to non-Marketplace app stores, but it doesn't cover all situations. An app developer may only want their app installable by Firefox Marketplace and Miremox Farketplace, a third-party app store. Their manifest would include:

'installs_allowed_from': [
    'https://marketplace.firefox.com',
    'https://farketplace.miremox.com'
]

This app would be excluded from any requests made by Miremox Farketplace with installs_allowed_from=* in the querystring, even though their users would be allowed to install it. We should allow Miremox Farketplace to include installs_allowed_from=https://farketplace.miremox.com in their queries, which would include both apps with * or https://farketplace.miremox.com in their manifest's installs_allowed_from.

This change would be somewhat wide-sweeping; it would also, for example, cause GET /api/v2/apps/app/fooapp/?installs_allowed_from=* to return 404 if * is not in fooapp's manifest's installs_allowed_from.

Additional metadata

In the event that third-party app stores want to include apps that their users cannot install from their app store, but treat them separately, we should include the installs_allowed_from value from each app's manifest in our API responses.

A scenario where this might be helpful: if Miremox Farketplace wants to change their INSTALL button to say INSTALL ON FIREFOX MARKETPLACE (with a corresponding link to Firefox Marketplace) if the app is not installable from their site, but is on Firefox Marketplace.

We already store this value; it would be trivial to start including it in API responses.