From c9a15ccfba0f78ee3de77536ce9286d4cdbc2443 Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Fri, 11 Nov 2022 12:54:03 +0000 Subject: [PATCH 01/20] WIP: Define a permission store (closes #384) --- index.html | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 111 insertions(+), 6 deletions(-) diff --git a/index.html b/index.html index b38cafd..12b266c 100644 --- a/index.html +++ b/index.html @@ -278,6 +278,93 @@

reset because its [=permission/lifetime=] has expired.

+
+

+ Permission Store +

+

+ The user agent maintains a single global permission store which is a list of [=permission store entries=]. + The user agent removes [=entries=] from the list when their respective [=permission=]'s [=permission/lifetime=] has expired. +

+

+ We should still allow UAs flexibility in giving out permissions with smaller scope and lifetime (e.g. per-tab) in some form. There should generally still be enough room for exploration here. +

+

+ A permission store entry is a [=tuple=] of [=powerful feature/name=] name, [=permission store key=] key, {{PermissionDescriptor}} descriptor, and [=permission/state=] state. +

+

+ To get a permission store entry from the [=global permission store=] given a |name|, [=permission store key=] key and descriptor, run these steps: +

    +
  1. + If the [=global permission store=] [=list/contains=] an [=entry=] with the name |name|, the key |key| and the descriptor |descriptor|, return that entry. +
  2. +
  3. + Return null. +
  4. +
+

+

+ To set a permission store entry in the [=global permission store=] given a [=powerful feature/name=] |name|, a [=permission store key=] |key|, a {{PermissionDescriptor}} |descriptor|, and a [=permission/state=] |state|, run these steps: +

    +
  1. + Let |newEntry| be a new [=permission store entry=] with |name|, |key|, |descriptor|, and |state|. +
  2. +
  3. + If the [=global permission store=] [=list/contains=] an [=entry=] with the name |name|, the key |key| and the descriptor |descriptor|, [=list/replace=] that entry with |newEntry| and abort these steps. +
  4. +
  5. + Otherwise, [=list/append=] |newEntry| to the [=global permission store=]. +
  6. +
+

+

+ To remove a permission store entry from the [=global permission store=] given a name, key and descriptor, run these steps: +

    +
  1. + [=list/Remove=] the [=entry=] with the name |name|, key |key| and descriptor |descriptor| from the [=global permission store=]. +
  2. +
+

+

+ A permission store key is a [=tuple=] of ([=origin=] top-level origin, [=origin=] embedded origin). +

+ +

+ To generate a permission store key `key` given [=environment settings object=] |settings|, run these steps: +

    +
  1. + Let |top-level origin| be |settings|' [=environment/top-level origin=]. +
  2. +
  3. + Return (|top-level origin|, null) +
  4. +

    + How do we ensure that other specs can override this? Should we add all key deviations as new steps to this algorithm or have a different override mechanism? +

    +

    + Most permissions will want to key on the top-level origin and delegate access via Permissions Policy. + However, others, like the Storage Access API, explicitly describe a embeddee relationship and need to use the + embedded origin field. +

    +

    + This assumes that passed in settings is from the embedded document. +

    +
+

+ +

+ To compare [=permission store keys=] |key1| and |key2|, run these steps: +

    +
  1. +
  2. +
+

+ Do we have to define this? If we can compare origins we can probably implicitly compare a tuple of origins? +

+

+ +

+

Powerful features @@ -509,7 +596,7 @@

Takes no arguments. Updates any other parts of the implementation that need to be kept in sync with changes in the results of permission states or [=powerful - feature/extra permission data=], and then [=react to the user revoking permission=]. + feature/extra permission data=].

If unspecified, this defaults to running [=react to the user revoking permission=]. @@ -628,9 +715,11 @@

-
  • If there was a previous invocation of this algorithm with the same |descriptor| and - |settings|, returning |previousResult|, and the user agent has not received new - information about the user's intent since that invocation, return |previousResult|. +
  • Let |key| be the result of [=generate a permission store key|generating a permission store key=] with |settings|. +
  • +
  • Let |entry| be the result of [=get a permission store entry|getting a permission store entry=] with |feature|, |descriptor| and |key|. +
  • +
  • If |entry| is not null, return a {{PermissionState}} enum value from |entry|'s state and name.
  • Return the {{PermissionState}} enum value that represents the permission state of |feature|, taking into account any [=powerful feature/permission state constraints=] for @@ -662,8 +751,8 @@

  • Ask the user for express permission for the calling algorithm to use the powerful feature described by |descriptor|.
  • -
  • If the user gives [=express permission=] to use the powerful feature, return - {{PermissionState/"granted"}}; otherwise return {{PermissionState/"denied"}}. The user's +
  • If the user gives [=express permission=] to use the powerful feature, set |current state| to + {{PermissionState/"granted"}}; otherwise to {{PermissionState/"denied"}}. The user's interaction may provide new information about the user's intent for the [=origin=].

    @@ -672,6 +761,16 @@

    this framework.

  • +
  • + Let |key| be the result of [=generate a permission store key|generating a permission store key=] with the [=current settings object=]. +
  • +
  • + [=Queue a task=] on the [=current settings object=]'s [=environment settings + object/responsible event loop=] to [=set a permission store entry=] with |descriptor|'s name, |key|, |descriptor|, and |current state|. +
  • +
  • + Return |current state|. +
  • As a shorthand, requesting permission to use a {{DOMString}} |name|, is the same @@ -741,6 +840,12 @@

    Queue a global task on the [=user interaction task source=] to run that feature's [=powerful feature/permission revocation algorithm=].

  • +
  • + Let |key| be the result of [=generate a permission store key|generating a permission store key=] with the Realm's [=Realm/settings object=]. +
  • +
  • + TODO: How do I get the feature descriptor to remove the feature here? +
  • From 8f73063d9205f2a2aa95ef77ffed80158f417973 Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Fri, 18 Nov 2022 10:20:15 +0100 Subject: [PATCH 02/20] Apply suggestions from code review Co-authored-by: Anne van Kesteren --- index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.html b/index.html index 12b266c..f7d6dcf 100644 --- a/index.html +++ b/index.html @@ -283,7 +283,7 @@

    Permission Store

    - The user agent maintains a single global permission store which is a list of [=permission store entries=]. + The user agent maintains a single permission store which is a [=/list=] of [=permission store entries=]. The user agent removes [=entries=] from the list when their respective [=permission=]'s [=permission/lifetime=] has expired.

    @@ -330,13 +330,13 @@

    - To generate a permission store key `key` given [=environment settings object=] |settings|, run these steps: + To generate a permission store key given [=environment settings object=] |settings|, run these steps:

    1. Let |top-level origin| be |settings|' [=environment/top-level origin=].
    2. - Return (|top-level origin|, null) + Return (|top-level origin|, null).
    3. How do we ensure that other specs can override this? Should we add all key deviations as new steps to this algorithm or have a different override mechanism? From 0c9cfa5def7468b12154fdf1e2a024c55c1fec5c Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Fri, 18 Nov 2022 11:10:25 +0000 Subject: [PATCH 03/20] Address more review comments --- index.html | 58 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/index.html b/index.html index f7d6dcf..ad2b38a 100644 --- a/index.html +++ b/index.html @@ -283,20 +283,25 @@

      Permission Store

      - The user agent maintains a single permission store which is a [=/list=] of [=permission store entries=]. - The user agent removes [=entries=] from the list when their respective [=permission=]'s [=permission/lifetime=] has expired. + The user agent maintains a single permission store which is a [=/list=] of [=permission store entries=].

      -

      - We should still allow UAs flexibility in giving out permissions with smaller scope and lifetime (e.g. per-tab) in some form. There should generally still be enough room for exploration here. +

      + The user agent MAY remove [=entries=] from the [=permission store=] when their respective [=permission=]'s [=permission/lifetime=] has expired.

      - A permission store entry is a [=tuple=] of [=powerful feature/name=] name, [=permission store key=] key, {{PermissionDescriptor}} descriptor, and [=permission/state=] state. + The user agent MAY maintain additional permission stores with [=implementation-defined=] scope and eviction rules. Which permission store is adressed in a given moment is [=implementation-defined=]. +

      + This is intended to allow a user agent to experiment with user-friendly permission concepts such as per-tab grants. +

      - To get a permission store entry from the [=global permission store=] given a |name|, [=permission store key=] key and descriptor, run these steps: + A permission store entry is a [=tuple=] of [=powerful feature/name=] name, [=permission store key=] key, {{PermissionDescriptor}} descriptor, and [=permission/state=] state. +

      +

      + To get a permission store entry from the user agent's permission store given a |name|, [=permission store key=] key and descriptor, run these steps:

      1. - If the [=global permission store=] [=list/contains=] an [=entry=] with the name |name|, the key |key| and the descriptor |descriptor|, return that entry. + If the permission store [=list/contains=] an [=entry=] with the [=name=] |name|, [=key=] |key| and [=descriptor=] |descriptor|, return that entry.
      2. Return null. @@ -304,50 +309,43 @@

      - To set a permission store entry in the [=global permission store=] given a [=powerful feature/name=] |name|, a [=permission store key=] |key|, a {{PermissionDescriptor}} |descriptor|, and a [=permission/state=] |state|, run these steps: + To set a permission store entry in the user agent's permission store given a [=powerful feature/name=] |name|, a [=permission store key=] |key|, a {{PermissionDescriptor}} |descriptor|, and a [=permission/state=] |state|, run these steps:

      1. - Let |newEntry| be a new [=permission store entry=] with |name|, |key|, |descriptor|, and |state|. + Let |newEntry| be a new [=permission store entry=] with the [=name=] |name|, [=key=] |key|, [=descriptor=] |descriptor|, and [=state=] |state|.
      2. - If the [=global permission store=] [=list/contains=] an [=entry=] with the name |name|, the key |key| and the descriptor |descriptor|, [=list/replace=] that entry with |newEntry| and abort these steps. + If the permission store [=list/contains=] an [=entry=] with the [=name=] |name|, the [=key=] |key| and the [=descriptor=] |descriptor|, [=list/replace=] that entry with |newEntry| and abort these steps.
      3. - Otherwise, [=list/append=] |newEntry| to the [=global permission store=]. + [=list/append=] |newEntry| to the permission store.

      - To remove a permission store entry from the [=global permission store=] given a name, key and descriptor, run these steps: + To remove a permission store entry from the permission store given a name, key and descriptor, run these steps:

      1. - [=list/Remove=] the [=entry=] with the name |name|, key |key| and descriptor |descriptor| from the [=global permission store=]. + [=list/Remove=] the [=entry=] with the [=name=] |name|, [=key=] |key| and [=descriptor=] |descriptor| from the permission store.

      - A permission store key is a [=tuple=] of ([=origin=] top-level origin, [=origin=] embedded origin). + A permission store key is a [=tuple=] of ([=origin=] top-level origin, [=origin=] granted origin).

      To generate a permission store key given [=environment settings object=] |settings|, run these steps:

      1. - Let |top-level origin| be |settings|' [=environment/top-level origin=]. + Let |topLevelOrigin| be |settings|' [=environment/top-level origin=].
      2. - Return (|top-level origin|, null). + Return (|topLevelOrigin|, |topLevelOrigin|).
      3. -

        - How do we ensure that other specs can override this? Should we add all key deviations as new steps to this algorithm or have a different override mechanism? -

        - Most permissions will want to key on the top-level origin and delegate access via Permissions Policy. - However, others, like the Storage Access API, explicitly describe a embeddee relationship and need to use the - embedded origin field. -

        -

        - This assumes that passed in settings is from the embedded document. + Most permissions will want to set the permission grant on the top-level origin and delegate access via Permissions Policy. + However, others, like the Storage Access API, explicitly describe an embeddee relationship and could set a different granted origin.

      @@ -356,11 +354,15 @@

      To compare [=permission store keys=] |key1| and |key2|, run these steps:
      1. + If |key1|'s [=permission store key/top-level origin=] is not [=same origin=] with |key2|'s [=permission store key/top-level origin=], return false. +
      2. +
      3. + If |key1|'s [=permission store key/granted origin=] is not [=same origin=] with |key2|'s [=permission store key/granted origin=], return false. +
      4. +
      5. + Return true.
      -

      - Do we have to define this? If we can compare origins we can probably implicitly compare a tuple of origins? -

      From e3285ed7485b6d7e49a93c72288e00c17257fa30 Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Fri, 18 Nov 2022 11:16:40 +0000 Subject: [PATCH 04/20] Some cleanup/indentation --- index.html | 106 ++++++++++++++++++++++++++--------------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/index.html b/index.html index ad2b38a..71555b5 100644 --- a/index.html +++ b/index.html @@ -290,79 +290,79 @@

      The user agent MAY maintain additional permission stores with [=implementation-defined=] scope and eviction rules. Which permission store is adressed in a given moment is [=implementation-defined=]. -

      +

      - To compare [=permission store keys=] |key1| and |key2|, run these steps: -

        -
      1. - If |key1|'s [=permission store key/top-level origin=] is not [=same origin=] with |key2|'s [=permission store key/top-level origin=], return false. -
      2. -
      3. - If |key1|'s [=permission store key/granted origin=] is not [=same origin=] with |key2|'s [=permission store key/granted origin=], return false. -
      4. -
      5. - Return true. -
      6. -
      + To compare [=permission store keys=] |key1| and |key2|, run these steps: +
        +
      1. + If |key1|'s [=permission store key/top-level origin=] is not [=same origin=] with |key2|'s [=permission store key/top-level origin=], return false. +
      2. +
      3. + If |key1|'s [=permission store key/granted origin=] is not [=same origin=] with |key2|'s [=permission store key/granted origin=], return false. +
      4. +
      5. + Return true. +
      6. +

      From d6ae7335d8a37a0204b623d85b43062aad1ef5c7 Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Fri, 18 Nov 2022 13:15:44 +0000 Subject: [PATCH 05/20] Forgot to close aside --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 71555b5..f7b923b 100644 --- a/index.html +++ b/index.html @@ -292,7 +292,7 @@

      The user agent MAY maintain additional permission stores with [=implementation-defined=] scope and eviction rules. Which permission store is adressed in a given moment is [=implementation-defined=].

      A permission store entry is a [=tuple=] of [=powerful feature/name=] name, [=permission store key=] key, {{PermissionDescriptor}} descriptor, and [=permission/state=] state. From 37915a65a7d64e82bd3e9319f16ae18dc3066e73 Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Wed, 23 Nov 2022 10:52:56 +0000 Subject: [PATCH 06/20] Move key generation & key comparison to powerful feature --- index.html | 85 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 33 deletions(-) diff --git a/index.html b/index.html index f7b923b..debf0fd 100644 --- a/index.html +++ b/index.html @@ -331,40 +331,14 @@

    - A permission store key is a [=tuple=] of ([=origin=] top-level origin, [=origin=] granted origin). -

    - -

    - To generate a permission store key given [=environment settings object=] |settings|, run these steps: -

      -
    1. - Let |topLevelOrigin| be |settings|' [=environment/top-level origin=]. -
    2. -
    3. - Return (|topLevelOrigin|, |topLevelOrigin|). -
    4. -
    + A permission store key has the type returned by the feature's [=powerful feature/permission key generation algorithm=].

    -

    - To compare [=permission store keys=] |key1| and |key2|, run these steps: -

      -
    1. - If |key1|'s [=permission store key/top-level origin=] is not [=same origin=] with |key2|'s [=permission store key/top-level origin=], return false. -
    2. -
    3. - If |key1|'s [=permission store key/granted origin=] is not [=same origin=] with |key2|'s [=permission store key/granted origin=], return false. -
    4. -
    5. - Return true. -
    6. -
    -

    -

    @@ -590,6 +564,51 @@

    +
    + A permission key generation algorithm: +
    +
    +

    + Takes an [=environment settings object=], and returns a new [=permission store key=]. + If unspecified, this defaults to the default permission key generation algorithm. + A feature that specifies a custom [=powerful feature/permission key generation algorithm=] MUST also specify a + [=powerful feature/permission key comparison algorithm=]. +

    +

    + The default permission key generation algorithm, + given an [=environment settings object=] |settings|, runs the following steps: +

    +
      +
    1. + Return |settings|' [=environment/top-level origin=]. +
    2. +
    + +
    +
    + A permission key comparison algorithm: +
    +
    +

    + Takes two [=permission store keys=] and returns a boolean that shows whether the two keys are equal. + If unspecified, this defaults to the default permission key comparison algorithm. +

    +

    + The default permission key comparison algorithm, + given [=permission store keys=] |key1| and |key2| (both [=origins=]), runs the following steps: +

    +
      +
    1. + If |key1| is not [=same origin=] with |key2| return false. +
    2. +
    3. + Return true. +
    4. +
    +
    A permission revocation algorithm: @@ -717,7 +736,7 @@

    -
  • Let |key| be the result of [=generate a permission store key|generating a permission store key=] with |settings|. +
  • Let |key| be the result of [=powerful feature/permission key generation algorithm|generating a permission store key=] with |settings|.
  • Let |entry| be the result of [=get a permission store entry|getting a permission store entry=] with |feature|, |descriptor| and |key|.
  • @@ -764,7 +783,7 @@

  • - Let |key| be the result of [=generate a permission store key|generating a permission store key=] with the [=current settings object=]. + Let |key| be the result of [=powerful feature/permission key generation algorithm|generating a permission store key=] with the [=current settings object=].
  • [=Queue a task=] on the [=current settings object=]'s [=environment settings @@ -843,7 +862,7 @@

    feature's [=powerful feature/permission revocation algorithm=].

  • - Let |key| be the result of [=generate a permission store key|generating a permission store key=] with the Realm's [=Realm/settings object=]. + Let |key| be the result of [=powerful feature/permission key generation algorithm|generating a permission store key=] with the Realm's [=Realm/settings object=].
  • TODO: How do I get the feature descriptor to remove the feature here? From 8fbadba3321f7a7806db2bb0a4f76e0b3799434f Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Tue, 29 Nov 2022 13:15:59 +0000 Subject: [PATCH 07/20] Rename to permission key, address various feedback by Anne and Marcos --- index.html | 65 +++++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/index.html b/index.html index debf0fd..fbe75a2 100644 --- a/index.html +++ b/index.html @@ -289,19 +289,13 @@

    The user agent MAY remove [=entries=] from the [=permission store=] when their respective [=permission=]'s [=permission/lifetime=] has expired.

    - The user agent MAY maintain additional permission stores with [=implementation-defined=] scope and eviction rules. Which permission store is adressed in a given moment is [=implementation-defined=]. -

    -

    -

    - A permission store entry is a [=tuple=] of [=powerful feature/name=] name, [=permission store key=] key, {{PermissionDescriptor}} descriptor, and [=permission/state=] state. + A permission store entry is a [=tuple=] of {{PermissionDescriptor}} descriptor, [=permission key=] key, and [=permission/state=] state.

    - To get a permission store entry from the user agent's permission store given a |name|, [=permission store key=] key and descriptor, run these steps: + To get a permission store entry given a {{PermissionDescriptor}} |descriptor| and [=permission key=] |key|, run these steps:

    1. - If the permission store [=list/contains=] an [=entry=] with the [=name=] |name|, [=key=] |key| and [=descriptor=] |descriptor|, return that entry. + If the user agent's [=permission store=] [=list/contains=] an [=entry=] whose [=permission store entry/descriptor=] is |descriptor|, and whose [=permission store entry/key=] [=permission key/is equal to=] |key| given |descriptor|, return that entry.
    2. Return null. @@ -309,35 +303,43 @@

    - To set a permission store entry in the user agent's permission store given a [=powerful feature/name=] |name|, a [=permission store key=] |key|, a {{PermissionDescriptor}} |descriptor|, and a [=permission/state=] |state|, run these steps: + To set a permission store entry given a {{PermissionDescriptor}} |descriptor|, a [=permission key=] |key|, and a [=permission/state=] |state|, run these steps:

    1. - Let |newEntry| be a new [=permission store entry=] with the [=name=] |name|, [=key=] |key|, [=descriptor=] |descriptor|, and [=state=] |state|. + Let |newEntry| be a new [=permission store entry=] whose [=permission store entry/descriptor=] is |descriptor|, and whose [=permission store entry/key=] [=permission key/is equal to=] |key| given |descriptor|, and whose [=permission store entry/state=] is |state|.
    2. - If the permission store [=list/contains=] an [=entry=] with the [=name=] |name|, the [=key=] |key| and the [=descriptor=] |descriptor|, [=list/replace=] that entry with |newEntry| and abort these steps. + If the user agent's [=permission store=] [=list/contains=] an [=entry=] whose [=permission store entry/descriptor=] is |descriptor|, and whose [=permission store entry/key=] [=permission key/is equal to=] |key| given |descriptor|, [=list/replace=] that entry with |newEntry| and abort these steps.
    3. - [=list/append=] |newEntry| to the permission store. + [=list/Append=] |newEntry| to the user agent's [=permission store=].

    - To remove a permission store entry from the permission store given a name, key and descriptor, run these steps: + To remove a permission store entry given a {{PermissionDescriptor}} |descriptor| and [=permission key=] |key|, run these steps:

    1. - [=list/Remove=] the [=entry=] with the [=name=] |name|, [=key=] |key| and [=descriptor=] |descriptor| from the permission store. + [=list/Remove=] the [=entry=] whose [=permission store entry/descriptor=] is |descriptor|, and whose [=permission store entry/key=] [=permission key/is equal to=] |key| given |descriptor|, from the user agent's [=permission store=].

    - A permission store key has the type returned by the feature's [=powerful feature/permission key generation algorithm=]. + A permission key has the type returned by the feature's [=powerful feature/permission key generation algorithm=].

    +

    + To determine whether a [=permission key=] |key1| is equal to a [=permission key=] |key2|, given a {{PermissionDescriptor}} |descriptor|, run the following steps: +

      +
    1. + Return the result of running |descriptor|'s {{PermissionDescriptor/name}}'s [=powerful feature/permission key comparison algorithm=], passing |key1| and |key2|. +
    2. +
    +

  • @@ -569,23 +571,23 @@

    - Takes an [=environment settings object=], and returns a new [=permission store key=]. + Takes an [=environment settings object=], and returns a new [=permission key=]. If unspecified, this defaults to the default permission key generation algorithm. A feature that specifies a custom [=powerful feature/permission key generation algorithm=] MUST also specify a [=powerful feature/permission key comparison algorithm=].

    - The default permission key generation algorithm, + The default permission key generation algorithm, given an [=environment settings object=] |settings|, runs the following steps:

    1. - Return |settings|' [=environment/top-level origin=]. + Return |settings|'s [=environment/top-level origin=].
    @@ -593,14 +595,17 @@

    - Takes two [=permission store keys=] and returns a boolean that shows whether the two keys are equal. + Takes two [=permission keys=] and returns a boolean that shows whether the two keys are equal. If unspecified, this defaults to the default permission key comparison algorithm.

    - The default permission key comparison algorithm, - given [=permission store keys=] |key1| and |key2| (both [=origins=]), runs the following steps: + The default permission key comparison algorithm, + given [=permission keys=] |key1| and |key2|, runs the following steps:

      +
    1. + If |key1| is not an [=origin=] or |key2| is not an [=origin=] return false. +
    2. If |key1| is not [=same origin=] with |key2| return false.
    3. @@ -736,11 +741,11 @@

    -
  • Let |key| be the result of [=powerful feature/permission key generation algorithm|generating a permission store key=] with |settings|. +
  • Let |key| be the result of [=powerful feature/permission key generation algorithm|generating a permission key=] with |settings|.
  • -
  • Let |entry| be the result of [=get a permission store entry|getting a permission store entry=] with |feature|, |descriptor| and |key|. +
  • Let |entry| be the result of [=get a permission store entry|getting a permission store entry=] with |descriptor| and |key|.
  • -
  • If |entry| is not null, return a {{PermissionState}} enum value from |entry|'s state and name. +
  • If |entry| is not null, return a {{PermissionState}} enum value from |entry|'s [=permission store entry/state=] and |entry|'s [=permission store entry/descriptor=]'s {{PermissionDescriptor/name}}.
  • Return the {{PermissionState}} enum value that represents the permission state of |feature|, taking into account any [=powerful feature/permission state constraints=] for @@ -783,11 +788,11 @@

  • - Let |key| be the result of [=powerful feature/permission key generation algorithm|generating a permission store key=] with the [=current settings object=]. + Let |key| be the result of [=powerful feature/permission key generation algorithm|generating a permission key=] with the [=current settings object=].
  • [=Queue a task=] on the [=current settings object=]'s [=environment settings - object/responsible event loop=] to [=set a permission store entry=] with |descriptor|'s name, |key|, |descriptor|, and |current state|. + object/responsible event loop=] to [=set a permission store entry=] with |descriptor|, |key|, and |current state|.
  • Return |current state|. @@ -862,7 +867,7 @@

    feature's [=powerful feature/permission revocation algorithm=].

  • - Let |key| be the result of [=powerful feature/permission key generation algorithm|generating a permission store key=] with the Realm's [=Realm/settings object=]. + Let |key| be the result of [=powerful feature/permission key generation algorithm|generating a permission key=] with the Realm's [=Realm/settings object=].
  • TODO: How do I get the feature descriptor to remove the feature here? From 1dfe4fd147bb0fabdc3739fbe9cbf9f629f93317 Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Tue, 29 Nov 2022 13:35:38 +0000 Subject: [PATCH 08/20] Actually do something for revocation --- index.html | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/index.html b/index.html index fbe75a2..3cbf69c 100644 --- a/index.html +++ b/index.html @@ -859,18 +859,21 @@

    When the user agent learns that the user no longer intends to grant permission to use a - feature, react to the user revoking permission by running these steps: + feature described by the {{PermissionDescriptor}} |descriptor| in the context + described by the [=permission key=] |key|, react to the user revoking permission + by running these steps:

    1. - Queue a global task on the [=user interaction task source=] to run that - feature's [=powerful feature/permission revocation algorithm=]. -
    2. -
    3. - Let |key| be the result of [=powerful feature/permission key generation algorithm|generating a permission key=] with the Realm's [=Realm/settings object=]. -
    4. -
    5. - TODO: How do I get the feature descriptor to remove the feature here? + Queue a global task on the [=user interaction task source=] to:. +
        +
      1. + Run |descriptor|'s {{PermissionDescriptor/name}}'s [=powerful feature/permission revocation algorithm=]. +
      2. +
      3. + [=Remove a permission store entry=] with |descriptor| and |key|. +
      4. +
    From 835d536076296a841682856e4a4b5a37b4950d5e Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Wed, 30 Nov 2022 13:24:25 +0000 Subject: [PATCH 09/20] Address some of Jeffrey's feedback --- index.html | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/index.html b/index.html index 3cbf69c..0d3320b 100644 --- a/index.html +++ b/index.html @@ -325,16 +325,20 @@

    - A permission key has the type returned by the feature's [=powerful feature/permission key generation algorithm=]. + A permission key has its type defined by a feature's [=powerful feature/permission key type=].

    To determine whether a [=permission key=] |key1| is equal to a [=permission key=] |key2|, given a {{PermissionDescriptor}} |descriptor|, run the following steps:

      +
    1. + If |key1| is not of |descriptor|'s [=powerful feature/permission key type=] or |key2| is not of |descriptor|'s [=powerful feature/permission key type=], return false. +
    2. Return the result of running |descriptor|'s {{PermissionDescriptor/name}}'s [=powerful feature/permission key comparison algorithm=], passing |key1| and |key2|.
    3. @@ -566,6 +570,16 @@

  • +
    + A permission key type: +
    +
    +

    + The type of [=permission key=] used by the feature. Defaults to [=origin=]. + A feature that specifies a custom [=powerful feature/permission key type=] MUST also specify a + [=powerful feature/permission key generation algorithm=]. +

    +
    A permission key generation algorithm:
    @@ -603,9 +617,6 @@

    given [=permission keys=] |key1| and |key2|, runs the following steps:

      -
    1. - If |key1| is not an [=origin=] or |key2| is not an [=origin=] return false. -
    2. If |key1| is not [=same origin=] with |key2| return false.
    3. @@ -745,7 +756,7 @@

    4. Let |entry| be the result of [=get a permission store entry|getting a permission store entry=] with |descriptor| and |key|.
    5. -
    6. If |entry| is not null, return a {{PermissionState}} enum value from |entry|'s [=permission store entry/state=] and |entry|'s [=permission store entry/descriptor=]'s {{PermissionDescriptor/name}}. +
    7. If |entry| is not null, return a {{PermissionState}} enum value from |entry|'s [=permission store entry/state=].
    8. Return the {{PermissionState}} enum value that represents the permission state of |feature|, taking into account any [=powerful feature/permission state constraints=] for @@ -865,15 +876,10 @@

      1. - Queue a global task on the [=user interaction task source=] to:. -
          -
        1. - Run |descriptor|'s {{PermissionDescriptor/name}}'s [=powerful feature/permission revocation algorithm=]. -
        2. -
        3. - [=Remove a permission store entry=] with |descriptor| and |key|. -
        4. -
        + Run |descriptor|'s {{PermissionDescriptor/name}}'s [=powerful feature/permission revocation algorithm=]. +
      2. +
      3. + [=Remove a permission store entry=] with |descriptor| and |key|.
      From 5824b1bc39149b49e943682416fbafbfa05e241a Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Wed, 30 Nov 2022 14:26:50 +0100 Subject: [PATCH 10/20] Update index.html Co-authored-by: Jeffrey Yasskin --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 0d3320b..4a82d9e 100644 --- a/index.html +++ b/index.html @@ -752,7 +752,7 @@

    -
  • Let |key| be the result of [=powerful feature/permission key generation algorithm|generating a permission key=] with |settings|. +
  • Let |key| be the result of [=powerful feature/permission key generation algorithm|generating a permission key=] for |descriptor| with |settings|.
  • Let |entry| be the result of [=get a permission store entry|getting a permission store entry=] with |descriptor| and |key|.
  • From 13db75cba3b64647b7c424f34a81e97a4706297c Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Wed, 30 Nov 2022 14:27:24 +0100 Subject: [PATCH 11/20] Update index.html Co-authored-by: Jeffrey Yasskin --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 4a82d9e..57b5e02 100644 --- a/index.html +++ b/index.html @@ -600,7 +600,7 @@

    From b8a8d4a097e65f00bac0c6f76f11b3d9a7f77988 Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Wed, 30 Nov 2022 22:41:45 +0000 Subject: [PATCH 12/20] Fix PP reference --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 57b5e02..e47b9b3 100644 --- a/index.html +++ b/index.html @@ -600,7 +600,7 @@

    From d7d4e63619bcdfae0713c3d6b44888a1282d465f Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Wed, 30 Nov 2022 22:55:28 +0000 Subject: [PATCH 13/20] Fix for attribute --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index e47b9b3..b3fd9eb 100644 --- a/index.html +++ b/index.html @@ -334,7 +334,7 @@

    - To determine whether a [=permission key=] |key1| is equal to a [=permission key=] |key2|, given a {{PermissionDescriptor}} |descriptor|, run the following steps: + To determine whether a [=permission key=] |key1| is equal to a [=permission key=] |key2|, given a {{PermissionDescriptor}} |descriptor|, run the following steps:

    1. If |key1| is not of |descriptor|'s [=powerful feature/permission key type=] or |key2| is not of |descriptor|'s [=powerful feature/permission key type=], return false. From 7edd2cc718309ebdfb5edf67fbefa089455642c4 Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Thu, 1 Dec 2022 23:43:12 +0100 Subject: [PATCH 14/20] Update index.html Co-authored-by: Jeffrey Yasskin --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index b3fd9eb..54fdccd 100644 --- a/index.html +++ b/index.html @@ -306,7 +306,7 @@

      To set a permission store entry given a {{PermissionDescriptor}} |descriptor|, a [=permission key=] |key|, and a [=permission/state=] |state|, run these steps:
      1. - Let |newEntry| be a new [=permission store entry=] whose [=permission store entry/descriptor=] is |descriptor|, and whose [=permission store entry/key=] [=permission key/is equal to=] |key| given |descriptor|, and whose [=permission store entry/state=] is |state|. + Let |newEntry| be a new [=permission store entry=] whose [=permission store entry/descriptor=] is |descriptor|, and whose [=permission store entry/key=] is |key|, and whose [=permission store entry/state=] is |state|.
      2. If the user agent's [=permission store=] [=list/contains=] an [=entry=] whose [=permission store entry/descriptor=] is |descriptor|, and whose [=permission store entry/key=] [=permission key/is equal to=] |key| given |descriptor|, [=list/replace=] that entry with |newEntry| and abort these steps. From fde4e36da5e8614a630d6e59ccd33cebb4caf3d0 Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Thu, 1 Dec 2022 23:47:03 +0100 Subject: [PATCH 15/20] Update index.html Co-authored-by: Jeffrey Yasskin --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 54fdccd..d2071cc 100644 --- a/index.html +++ b/index.html @@ -289,7 +289,7 @@

        The user agent MAY remove [=entries=] from the [=permission store=] when their respective [=permission=]'s [=permission/lifetime=] has expired.

        - A permission store entry is a [=tuple=] of {{PermissionDescriptor}} descriptor, [=permission key=] key, and [=permission/state=] state. + A permission store entry is a [=tuple=] of {{PermissionDescriptor}} descriptor, an instance key of the [=permission key type=] of the feature named by [=permission store entry/descriptor=].name, and [=permission/state=] state.

        To get a permission store entry given a {{PermissionDescriptor}} |descriptor| and [=permission key=] |key|, run these steps: From 8bffedb08e4ba5d5fd5d87cd4bc4ecb5839af54c Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Thu, 1 Dec 2022 23:04:19 +0000 Subject: [PATCH 16/20] Address more review comments --- index.html | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/index.html b/index.html index d2071cc..e9750bd 100644 --- a/index.html +++ b/index.html @@ -283,13 +283,13 @@

        Permission Store

        - The user agent maintains a single permission store which is a [=/list=] of [=permission store entries=]. + The user agent maintains a single permission store which is a [=/list=] of [=permission store entries=]. Each particular [=entry=] denoted by its [=permission store entry/descriptor=] and [=permission store entry/key=] can only appear at most once in this list.

        The user agent MAY remove [=entries=] from the [=permission store=] when their respective [=permission=]'s [=permission/lifetime=] has expired.

        - A permission store entry is a [=tuple=] of {{PermissionDescriptor}} descriptor, an instance key of the [=permission key type=] of the feature named by [=permission store entry/descriptor=].name, and [=permission/state=] state. + A permission store entry is a [=tuple=] of {{PermissionDescriptor}} descriptor, an instance key of the [=powerful feature/permission key type=] of the feature named by [=permission store entry/descriptor=].name, and [=permission/state=] state.

        To get a permission store entry given a {{PermissionDescriptor}} |descriptor| and [=permission key=] |key|, run these steps: @@ -340,12 +340,10 @@

        If |key1| is not of |descriptor|'s [=powerful feature/permission key type=] or |key2| is not of |descriptor|'s [=powerful feature/permission key type=], return false.

      3. - Return the result of running |descriptor|'s {{PermissionDescriptor/name}}'s [=powerful feature/permission key comparison algorithm=], passing |key1| and |key2|. + Return the result of running the [=powerful feature/permission key comparison algorithm=] for the feature named by |descriptor|'s {{PermissionDescriptor/name}}, passing |key1| and |key2|.

      - -

      From d66a0dc7875e99b09295f0fb6ef8b6566af24e7b Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Mon, 5 Dec 2022 21:43:07 +0100 Subject: [PATCH 17/20] Update index.html Co-authored-by: Anne van Kesteren --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index e9750bd..8fbada4 100644 --- a/index.html +++ b/index.html @@ -292,7 +292,7 @@

      A permission store entry is a [=tuple=] of {{PermissionDescriptor}} descriptor, an instance key of the [=powerful feature/permission key type=] of the feature named by [=permission store entry/descriptor=].name, and [=permission/state=] state.

      - To get a permission store entry given a {{PermissionDescriptor}} |descriptor| and [=permission key=] |key|, run these steps: + To get a permission store entry given a {{PermissionDescriptor}} |descriptor| and [=permission key=] |key|:

      1. If the user agent's [=permission store=] [=list/contains=] an [=entry=] whose [=permission store entry/descriptor=] is |descriptor|, and whose [=permission store entry/key=] [=permission key/is equal to=] |key| given |descriptor|, return that entry. From 4bf270392da17f74a91dcb3349d104c956c9ffe4 Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Mon, 5 Dec 2022 21:08:08 +0000 Subject: [PATCH 18/20] Address more review comments --- index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 8fbada4..e9278d0 100644 --- a/index.html +++ b/index.html @@ -289,12 +289,13 @@

        The user agent MAY remove [=entries=] from the [=permission store=] when their respective [=permission=]'s [=permission/lifetime=] has expired.

        - A permission store entry is a [=tuple=] of {{PermissionDescriptor}} descriptor, an instance key of the [=powerful feature/permission key type=] of the feature named by [=permission store entry/descriptor=].name, and [=permission/state=] state. + A permission store entry is a [=tuple=] of {{PermissionDescriptor}} descriptor, [=permission key=] key, and [=permission/state=] state.

        To get a permission store entry given a {{PermissionDescriptor}} |descriptor| and [=permission key=] |key|:

        1. + If the user agent's [=permission store=] [=list/contains=] an [=entry=] whose [=permission store entry/descriptor=] is |descriptor|, and whose [=permission store entry/key=] [=permission key/is equal to=] |key| given |descriptor|, return that entry.
        2. From f71988719537f73726f55785fbebe8b3a0016ad2 Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Thu, 8 Dec 2022 09:27:57 +0100 Subject: [PATCH 19/20] Update index.html Co-authored-by: Mike Taylor --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index e9278d0..59be010 100644 --- a/index.html +++ b/index.html @@ -608,7 +608,7 @@

          - Takes two [=permission keys=] and returns a boolean that shows whether the two keys are equal. + Takes two [=permission keys=] and returns a [=boolean=] that shows whether the two keys are equal. If unspecified, this defaults to the default permission key comparison algorithm.

          From 66434eb592d4700c3b5a1a324927d281a9305828 Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Fri, 9 Dec 2022 10:08:22 +0100 Subject: [PATCH 20/20] Update index.html MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marcos Cáceres --- index.html | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/index.html b/index.html index 59be010..430234f 100644 --- a/index.html +++ b/index.html @@ -617,10 +617,7 @@

          1. - If |key1| is not [=same origin=] with |key2| return false. -
          2. -
          3. - Return true. + Return |key1| is [=same origin=] with |key2|.