Related discussion on Capabilities container at mozilla-labs.
Doug Turner is also pondering how to do Device API permission management. Added a Capability-based Security inspired proposal.
Initial version of the demo.
This demo implements the Permissions interface with some changes. The demo should work with any modern browser. Click Run buttons in Examples to experiment. Contacts, Calendar and System Information are used as placeholders only, and may not be applicable for this model.
This document is merely a W3C-internal document. It has no official standing of any kind and does not represent consensus of the W3C Membership. Feel free to join the discussion on public-device-apis.
...
E.g. FoobarSensor implements Permissions
, where FoobarSensor is any applicable Device API:
interface FoobarSensor : Permissions { // ... }
Each interface that implements Permissions has a unique feature
id.
console.log(navigator.foobar.feature); // returns "foobar"
requestPermission()
can drop its first feature
argument.
If requestPermission()
is invoked with undefined arguments the user interaction
(such as displaying an infobar) is deferred until requestPermission()
is invoked
with a non-null callback (similar to the proxy design pattern):
navigator.foobar.requestPermission(); // returns nothing
If the callback
is non-null in requestPermission(callback)
, a user interface
is shown to the user from where the user is able to change feature permission settings or dismiss the UI.
The UI includes all feature requests, including those deferred (callback is undefined)
in the browsing context. The callback is invoked only after user's explicit consent is received. If the
user chooses to dismiss the UI the callback is not invoked. For example, to ask for foobar and baz feature permissions:
navigator.foobar.requestPermission(); navigator.baz.requestPermission(function(response) { console.log(response); });
The callback response
returned is an object. The property names of the response
object map to feature
identifiers, the property values to feature's properties such as permission_level
.
System default permission levels are used, if the user does not explicitly set the permission permission level.
For example, if the user allows access to foobar
feature but leaves the baz
feature
permission level to default the following response
is returned:
{ 'foobar': {'permission_level': 2}, // USER_ALLOWED 'baz': {'permission_level': -1} // DEFAULT_DENIED }
If feature
parameter passed to permissionLevel(feature)
getter is undefined (i.e. not defined),
the permission level of the interface that implements Permissions
is returned:
navigator.foobar.permissionLevel(); // returns foobar's permission_level, e.g. 2 for USER_ALLOWED
The API objects are exposed only if the user has given permission. The objects are passed by reference to the success callback:
function success(response) { // case 1: the API is exposed only if the user has given permission if (response.foobar !== 'undefined') { response.foobar.doSomething(); // do something with the API } // case 2: the entry point is known e.g. navigator.baz, an equality comparison works if (navigator.baz === response.baz) { response.baz.doSomethingElse(); } } function error(response) { // example response: // { // 'foobar': {'permission_level': -2}, // USER_DENIED // 'baz': {'permission_level': -1} // DEFAULT_DENIED // } console.log(response.foobar.permission_level); // logs '-2' } // the feature factory navigator.requestPermissions(['foobar', 'baz'], success, error);