Skip to content

Commit a20c3cc

Browse files
johannhofannevk
andauthored
Use the Permissions API (closes #121, #32) (#138)
This is building on top of w3c/permissions#390 to integrate SAA with permissions. It's deleting a lot of old manual state management but doesn't get rid of the (global) storage access map altogether, since that is done in #141. Co-authored-by: Anne van Kesteren <[email protected]>
1 parent 54caceb commit a20c3cc

File tree

1 file changed

+54
-41
lines changed

1 file changed

+54
-41
lines changed

storage-access.bs

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ urlPrefix: https://fetch.spec.whatwg.org/; spec: Fetch
3434
spec: RFC6265; urlPrefix: https://tools.ietf.org/html/rfc6265
3535
type: dfn
3636
text: cookie store; url: section-5.3
37+
urlPrefix: https://w3c.github.io/permissions/; spec: permissions
38+
text: permissions task source; url: #permissions-task-source; type: dfn
3739
urlPrefix: https://w3c.github.io/webdriver/webdriver-spec.html#; spec: webdriver
3840
type: dfn
3941
text: current browsing context; url: dfn-current-browsing-context
@@ -148,8 +150,6 @@ A <dfn>storage access flag set</dfn> is a set of zero or more of the following f
148150

149151
: The <dfn for="storage access flag set" id=has-storage-access-flag>has storage access flag</dfn>
150152
:: When set, this flag indicates |embedded origin| has access to its [=unpartitioned data=] when it's loaded in a [=third party context=] on |top-level site|.
151-
: The <dfn for="storage access flag set" id=was-expressly-denied-storage-access-flag>was expressly denied storage access flag</dfn>
152-
:: When set, this flag indicates that the user expressly denied |embedded origin| access to its [=unpartitioned data=] when it's loaded in a [=third party context=] on |top-level site|.
153153

154154
To <dfn type="abstract-op">obtain a storage access flag set</dfn> for a [=partitioned storage key=] |key| from a [=/storage access map=] |map|, run the following steps:
155155

@@ -158,10 +158,6 @@ To <dfn type="abstract-op">obtain a storage access flag set</dfn> for a [=partit
158158
1. [=map/Set=] |map|[|key|] to |flags|.
159159
1. Return |map|[|key|].
160160

161-
To <dfn type="abstract-op">save the storage access flag set</dfn> for a [=partitioned storage key=] |key| in a [=/storage access map=] |map|, run the following steps:
162-
163-
1. [=map/Set=] [=global storage access map=][|key|] to |map|[|key|].
164-
165161
<h3 id="the-document-object">Changes to {{Document}}</h3>
166162

167163
<pre class="idl">
@@ -187,14 +183,8 @@ When invoked on {{Document}} |doc|, the <dfn export method for=Document><code>ha
187183
1. If |doc|'s [=Document/origin=] is [=same origin=] with the [=top-level origin=] of |doc|'s [=relevant settings object=], [=/resolve=] |p| with true and return |p|.
188184
1. Let |key| be the result of [=generate a partitioned storage key|generating a partitioned storage key=] from |doc|.
189185
1. If |key| is failure, [=resolve=] |p| with false and return |p|.
190-
1. Run these steps [=in parallel=]:
191-
1. Let |map| be the result of [=obtain the storage access map|obtaining the storage access map=] for |doc|.
192-
1. Let |flag set| be the result of [=obtain a storage access flag set|obtaining the storage access flag set=] with |key| from |map|.
193-
1. If |flag set|'s [=was expressly denied storage access flag=] is set, [=queue a global task=] on the [=permission task source=] given |global| to [=/resolve=] |p| with false, and abort these steps.
194-
1. If |flag set|'s [=has storage access flag=] is set, [=queue a global task=] on the [=permission task source=] given |global| to [=/resolve=] |p| with true, and abort these steps.
195-
1. Let |hasAccess| be [=a new promise=].
196-
1. [=Determine the storage access policy=] with |key|, |doc| and |hasAccess|.
197-
1. [=Queue a global task=] on the [=permission task source=] given |global| to [=/resolve=] |p| with the result of |hasAccess|.
186+
1. Let |hasAccess| be the result of running [=determine if a site has storage access=] with |key| and |doc|.
187+
1. [=Queue a global task=] on the [=permissions task source=] given |global| to [=/resolve=] |p| with |hasAccess|.
198188
1. Return |p|.
199189

200190
ISSUE: Shouldn't step 8 be [=same site=]?
@@ -220,17 +210,18 @@ When invoked on {{Document}} |doc|, the <dfn export method for=Document><code>re
220210
1. If |key| is failure, [=reject=] |p| with a "{{NotAllowedError}}" {{DOMException}} and return |p|.
221211
1. Let |map| be the result of [=obtain the storage access map|obtaining the storage access map=] for |doc|.
222212
1. Let |flag set| be the result of [=obtain a storage access flag set|obtaining the storage access flag set=] with |key| from |map|.
223-
1. If |flag set|'s [=was expressly denied storage access flag=] is set, [=reject=] |p| with a "{{NotAllowedError}}" {{DOMException}} and return |p|.
224213
1. If |flag set|'s [=has storage access flag=] is set, [=/resolve=] and return |p|.
225214
1. Otherwise, run these steps [=in parallel=]:
226215
1. Let |hasAccess| be [=a new promise=].
227216
1. [=Determine the storage access policy=] with |key|, |doc| and |hasAccess|.
228-
1. [=Queue a global task=] on the [=permission task source=] given |global| to
217+
1. [=Queue a global task=] on the [=permissions task source=] given |global| to
229218
1. Set |flag set|'s [=has storage access flag=].
230-
1. Resolve or reject |p| based on the result of |hasAccess|.
231-
1. [=Save the storage access flag set=] for |key| in |map|.
219+
1. If |hasAccess| is true, resolve |p|.
220+
1. Reject |p| with a "{{NotAllowedError}}" {{DOMException}}.
232221
1. Return |p|.
233222

223+
ISSUE(privacycg/storage-access#144): We shouldn't use the permissions task source here.
224+
234225
ISSUE: Shouldn't step 9 be [=same site=]?
235226

236227
<h4 id="ua-policy">User Agent storage access policies</h4>
@@ -242,36 +233,21 @@ To <dfn type="abstract-op">determine if a site has storage access</dfn> with [=p
242233
1. Let |map| be the result of [=obtain the storage access map|obtaining the storage access map=] for |doc|.
243234
1. Let |flag set| be the result of [=obtain a storage access flag set|obtaining the storage access flag set=] with |key| from |map|.
244235
1. If |flag set|'s [=has storage access flag=] is set, return true.
245-
1. Let |has storage access| (a [=boolean=]) be the result of running an [=implementation-defined=] set of steps to determine if |key|'s [=partitioned storage key/embedded origin=] has access to its [=unpartitioned data=] on |key|'s [=partitioned storage key/top-level site=].
246-
1. If |has storage access| is true, set |flag set|'s [=has storage access flag=].
247-
1. [=Save the storage access flag set=] for |key| in |map|.
248-
1. Return |has storage access|.
236+
1. Return false.
249237

250238
To <dfn type="abstract-op">determine the storage access policy</dfn> for [=partitioned storage key=] |key| with {{Document}} |doc| and {{Promise}} |p|, run these steps:
251239

252240
1. Let |map| be the result of [=obtain the storage access map|obtaining the storage access map=] for |doc|.
253241
1. Let |flag set| be the result of [=obtain a storage access flag set|obtaining the storage access flag set=] with |key| from |map|.
254242
1. Let |implicitly granted| and |implicitly denied| (each a [=boolean=]) be the result of running an [=implementation-defined=] set of steps to determine if |key|'s [=partitioned storage key/embedded origin=]'s request for storage access on |key|'s [=partitioned storage key/top-level site=] should be granted or denied without prompting the user.
255-
256-
Note: These [=implementation-defined=] set of steps might result in |flag set|'s [=has storage access flag=] and [=was expressly denied storage access flag=] changing, since the User Agent could have relevant out-of-band information (e.g. a user preference that changed) that this specification is unaware of.
257243
1. Let |global| be |doc|'s [=relevant global object=].
258-
1. If |implicitly granted| is true, [=queue a global task=] on the [=permission task source=] given |global| to [=/resolve=] |p|, and return.
259-
1. If |implicitly denied| is true, [=queue a global task=] on the [=permission task source=] given |global| to [=/reject=] |p| with a "{{NotAllowedError}}" {{DOMException}}, and return |p|.
260-
1. Ask the user if they would like to grant |key|'s [=partitioned storage key/embedded origin=] access to its [=unpartitioned data=] when it's loaded in a [=third party context=] on |key|'s [=partitioned storage key/top-level site=], and wait for an answer. Let |expressly granted| and |expressly denied| (both [=booleans=]) be the result.
261-
262-
Note: While |expressly granted| and |expressly denied| cannot both be true, they could both be false in User Agents which allow users to dismiss the prompt without choosing to allow or deny the request. (Such a dismissal is interpreted in this algorithm as a denial.)
263-
1. If |expressly granted| is true, run these steps:
264-
1. Unset |flag set|'s [=was expressly denied storage access flag=].
265-
1. [=Save the storage access flag set=] for |key| in |map|.
266-
1. [=Queue a global task=] on the [=permission task source=] given |global| to [=/resolve=] |p|, and return.
244+
1. If |implicitly granted| is true, [=queue a global task=] on the [=permissions task source=] given |global| to [=/resolve=] |p|, and return.
245+
1. If |implicitly denied| is true, [=queue a global task=] on the [=permissions task source=] given |global| to [=/reject=] |p| with a "{{NotAllowedError}}" {{DOMException}}, and return.
246+
1. Let |permissionState| be the result of [=requesting permission to use=] "<a permission><code>storage-access</code></a>".
247+
1. If |permissionState| is "granted", [=queue a global task=] on the [=permissions task source=] given |global| to [=/resolve=] |p|, and return.
267248
1. Unset |flag set|'s [=has storage access flag=].
268-
1. If |expressly denied| is true, run these steps:
269-
1. If |doc|'s {{Window}} object has [=transient activation=], [=consume user activation=] with it.
270-
1. Set |flag set|'s [=was expressly denied storage access flag=].
271-
1. [=Save the storage access flag set=] for |key| in |map|.
272-
1. [=Queue a global task=] on the [=permission task source=] given |global| to [=/reject=] |p| with a "{{NotAllowedError}}" {{DOMException}}.
273-
274-
ISSUE: [since this is UA-defined, does it make sense to follow-up separately with a user prompt?](https://github.com/privacycg/storage-access/pull/24#discussion_r408784492)
249+
1. If |doc|'s {{Window}} object has [=transient activation=], [=consume user activation=] with it.
250+
1. [=Queue a global task=] on the [=permissions task source=] given |global| to [=/reject=] |p| with a "{{NotAllowedError}}" {{DOMException}}.
275251

276252
<h3 id="navigation">Changes to navigation</h3>
277253

@@ -283,7 +259,6 @@ Before changing the current entry of a session history, run the following steps:
283259
1. If |key| is failure, abort these steps.
284260
1. Let |flag set| be the result of [=obtain a storage access flag set|obtaining the storage access flag set=] with |key| from |map|.
285261
1. Unset |flag set|'s [=has storage access flag=].
286-
1. [=Save the storage access flag set=] for |key| in |map|.
287262

288263
ISSUE(privacycg/storage-access#3): What this section should look like ultimately hinges on
289264

@@ -313,6 +288,44 @@ To the [=parse a sandboxing directive=] algorithm, add the following under step
313288
<li>The [=sandbox storage access by user activation flag=], unless <var ignore>tokens</var> contains the <dfn export attr-value for=iframe/sandbox>allow-storage-access-by-user-activation</dfn> keyword.
314289
</ul>
315290

291+
<h2 id="permissions-integration">Permissions Integration</h2>
292+
293+
The Storage Access API defines a [=powerful feature=] identified by the [=powerful feature/name=] "<dfn export permission><code>storage-access</code></dfn>". It defines the following permission-related algorithms:
294+
295+
<dl>
296+
<dt>[=powerful feature/permission query algorithm=]</dt>
297+
<dd>
298+
To query the "<a permission><code>storage-access</code></a>" permission, given a {{PermissionDescriptor}} |permissionDesc| and a {{PermissionStatus}} |status|:
299+
300+
1. Set |status|'s {{PermissionStatus/state}} to |permissionDesc|'s [=permission state=].
301+
1. If |status|'s {{PermissionStatus/state}} is [=permission/denied=], set |status|'s {{PermissionStatus/state}} to [=permission/prompt=].
302+
303+
Note: The "denied" permission state is not revealed to avoid exposing the user's decision to developers. This is done to prevent retaliation against the user and repeated prompting to the detriment of the user experience.
304+
</dd>
305+
<dt>[=powerful feature/permission key type=]</dt>
306+
<dd>
307+
A [=permission key=] of the "<a permission><code>storage-access</code></a>" feature is a [=tuple=] consisting of a [=site=] <dfn for="permission key">top-level</dfn> and an [=/origin=] <dfn for="permission key">requester</dfn>.
308+
309+
ISSUE(privacycg/storage-access#147): Note that this will likely change to a (site, site) keying.
310+
</dd>
311+
<dt>[=powerful feature/permission key generation algorithm=]</dt>
312+
<dd>
313+
To generate a new [=permission key=] for the "<a permission><code>storage-access</code></a>" feature, given an [=environment settings object=] |settings|, run the following steps:
314+
315+
1. Let |topLevelSite| be |settings|' [=top-level site=].
316+
1. Let |embeddedOrigin| be |settings|' [=environment settings object/origin=].
317+
1. Return (|topLevelSite|, |embeddedOrigin|).
318+
</dd>
319+
<dt>[=powerful feature/permission key comparison algorithm=]</dt>
320+
<dd>
321+
To compare the [=permission keys=] |key1| and |key2| for the "<a permission><code>storage-access</code></a>" feature, run the following steps:
322+
323+
1. If |key1|'s [=permission key/top-level=] is not [=same site=] with |key2|'s [=permission key/top-level=], return false.
324+
1. If |key1|'s [=permission key/requester=] is not [=same origin=] with |key2|'s [=permission key/requester=], return false.
325+
1. Return true.
326+
</dd>
327+
</dl>
328+
316329
<h2 id="permissions-policy-integration">Permissions Policy Integration</h2>
317330

318331
The Storage Access API defines a [=policy-controlled feature=] identified by the string `"storage-access"`. Its [=default allowlist=] is `"*"`.

0 commit comments

Comments
 (0)