Re: [w3c/permissions] Model temporary permissions better (#86)

I see browsers doing 3 distinct things with a series of calls to `navigator.geolocation.watchPosition()`.

1. The user is prompted on the first call from an origin, and either by default (Chrome) or if they select an option in that prompt (Firefox and Safari), they aren't prompted again on subsequent calls from any tab visiting that origin. Each call produces a series of position callbacks that ends if the site drops the capability using `clearWatch()`.
2. The user is prompted on the first call from a tab, and they aren't prompted again on subsequent calls from that tab, but they are prompted again from other tabs visiting the same origin. Each call produces a series of position callbacks until the site drops the capability using `clearWatch()`. (Safari)
3. The user is prompted on every single call to `navigator.geolocation.watchPosition()`, even within the same tab, but each accepted call produces an unbounded series of position callbacks while the site holds onto the resulting capability. (Firefox)

I'd like to specify algorithms in each capability for updating its permission storage, and have that work for all of the above behaviors.

Right now, the spec asks each capability to define a "[permission request algorithm](https://w3c.github.io/permissions/#permission-request-algorithm)", which shows any necessary prompt and if the user accepts updates the stored permission data. You can see an example of this in [`"bluetooth"`](https://webbluetoothcg.github.io/web-bluetooth/#request-the-bluetooth-permission). The surrounding "[request a permission](https://w3c.github.io/permissions/#request-a-permission)" algorithm handles actually reading and writing the permission data to storage. Having the surrounding algorithm handle reading and writing storage is good for generalizing to tab-specific storage, and there's actually a straightforward path to get geolocation generalized (just write the updated permission data to a UA-dependent list of storages), but this doesn't work for more complex permissions like `"bluetooth"` and probably `"camera"`.

With `"bluetooth"`, each prompt results in adding one or more devices to a list of allowed devices. If we have both tab-specific and origin-wide storages, a tab could wind up with a superset of the origin's devices in its storage, and a prompt that's set to "always allow" a device will need to result in adding that device to two different starting lists. Because the current [permission request algorithm](https://w3c.github.io/permissions/#permission-request-algorithm) both shows the prompt and updates the list, we can't call it multiple times, once for each permission store. We need to separate it into "prompt" and "modify storage" steps.

My current guess at the right way to structure that is to define «**update the permission storage** *storage* for `"permission name"` using the following steps: 1. …» so that it runs the steps multiple times on a UA-dependent set of permission-stores. Then the [permission request algorithm](https://w3c.github.io/permissions/#permission-request-algorithm) and [permission revocation algorithm](https://w3c.github.io/permissions/#permission-revocation-algorithm) would call that to grant or revoke any permissions they need to, rather than modifying their input storage.

--------

It's possible this is all over-complicated. I thought of having the storage for each capability just hold a set of "things", so that "add thing-1" could add it to multiple permission stores if the UA wants, and "remove all things matching this predicate" could do the same. However, I don't think that works well: if the user grants `{name:"push", userVisibleOnly: false}` locally to one tab, and then `{name:"push", userVisibleOnly: true}` globally from another one, we don't want to overwrite the first tab's invisible-push permission. (Don't object that we wouldn't write a global grant to other tab-local stores; then we just grant `{name:"push", userVisibleOnly: false}` globally and get the same problem on the global store.) We could treat the two `userVisibleOnly` values as separate "things", but that just pushes the complexity down into the capability specs: they start having to search for all the relevant "things" and merge overlapping ones.

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/permissions/issues/86#issuecomment-213857053

Received on Sunday, 24 April 2016 00:21:15 UTC