-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hook into Permissions API to get permission #68
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,7 +44,7 @@ | |
}; | ||
</script> | ||
</head> | ||
<body data-cite="secure-contexts permissions-policy"> | ||
<body data-cite="secure-contexts permissions-policy permissions"> | ||
<section id="abstract"> | ||
<p> | ||
This specification defines an API that provides scripted access to | ||
|
@@ -254,27 +254,23 @@ <h2> | |
The API defined in this specification is used to retrieve the | ||
geographic location of a hosting device. In almost all cases, this | ||
information also discloses the location of the user of the device, | ||
thereby potentially compromising the user's privacy. A conforming | ||
implementation of this specification MUST provide a mechanism that | ||
protects the user's privacy and this mechanism SHOULD ensure that no | ||
location information is made available through this API without the | ||
user's express permission. | ||
thereby potentially compromising the user's privacy. User agents MUST | ||
NOT send location information to Web sites without the express | ||
permission of the user. | ||
</p> | ||
<section id="privacy_for_uas"> | ||
<h3> | ||
Privacy considerations for implementers of the Geolocation API | ||
Privacy considerations for geolocation permission UI | ||
</h3> | ||
<p> | ||
User agents MUST NOT send location information to Web sites without | ||
the express permission of the user. User agents MUST acquire | ||
permission through a user interface, unless they have prearranged | ||
trust relationships with users, as described below. The user | ||
interface MUST include the {{URL/host}} component of the document's | ||
URL. Those permissions that are acquired through the user interface | ||
and that are preserved beyond the current browsing session (i.e. | ||
beyond the time when the <a>browsing context</a> is navigated to | ||
another URL) MUST be revocable and user agents MUST respect revoked | ||
permissions. | ||
User agents MUST acquire permission through a user interface, unless | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to be covered by https://www.w3.org/TR/permissions/#request-permission-to-use. At least, I'm not sure how to "Ask the user’s permission" without a user interface. The "unless they have prearranged trust relationships" bit then softens it to almost exactly the model in the permissions spec, where browsers are expected to infer the user's intent based on all the information they have. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agree... this whole section can go. |
||
they have prearranged trust relationships with users, as described | ||
below. The user interface MUST include the {{URL/host}} component of | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there anything special about geolocation that requires the host to be visible, or should that move to the permissions spec? Must it be the whole host, or could a UA emphasize a suffix in the case of a very long host? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it should move to the permissions spec, tbh. There is nothing special about Geo. I think Geolocation was the first permission prompt to show the origin (2010) and why this is here... it's legacy stuff. |
||
the document's URL. Those permissions that are acquired through the | ||
user interface and that are preserved beyond the current browsing | ||
session (i.e. beyond the time when the <a>browsing context</a> is | ||
navigated to another URL) MUST be revocable and user agents MUST | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The idea that users MUST be able to revoke permissions they've granted belongs in the generic Permissions spec, and I think we're missing some wording about it from there. However, we have to be a bit more subtle than this to accommodate device policy, where users might not be able to revoke all permissions. This might be part of the question to answer in https://github.com/w3c/permissions/issues/231. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree. |
||
respect revoked permissions. | ||
</p> | ||
<p> | ||
Some user agents will have prearranged trust relationships that do | ||
|
@@ -396,49 +392,37 @@ <h3> | |
</h3> | ||
<p data-tests= | ||
"getCurrentPosition_IDL.https.html, getCurrentPosition_TypeError.html"> | ||
The <dfn>getCurrentPosition()</dfn> method takes one, two or three | ||
arguments. When called, it MUST immediately return and then | ||
asynchronously attempt to obtain the current location of the | ||
device. If the attempt is successful, the | ||
|successCallback:PositionCallback| MUST be invoked with a new | ||
{{GeolocationPosition}} object, reflecting the current location of | ||
the device. If the attempt fails, the | ||
|errorCallback:PositionErrorCallback| MUST be invoked with a new | ||
{{GeolocationPositionError}} object, reflecting the reason for the | ||
failure. | ||
</p> | ||
<p> | ||
The implementation of the {{Geolocation/getCurrentPosition()}} | ||
method MUST execute the following set of steps: | ||
When {{Geolocation/getCurrentPosition()}} is invoked, the user | ||
agent MUST: | ||
</p> | ||
<ol> | ||
<li>Return and continue asynchronously. | ||
<li>Return and continue [=in parallel=]. | ||
</li> | ||
<li>If the <a>environment settings object</a> is a <a>non-secure | ||
context</a> or the <a>current settings object</a>'s [=environment | ||
settings object / responsible document=] is not [=allowed to use=] | ||
the "geolocation" feature: | ||
<ol> | ||
<li>If |errorCallback| is not null, invoke the |errorCallback| | ||
with a newly created {{GeolocationPositionError}} object whose | ||
{{GeolocationPositionError/code}} attribute is initialized to | ||
{{GeolocationPositionError/PERMISSION_DENIED}}. | ||
</li> | ||
<li>Terminate this algorithm. | ||
</li> | ||
</ol> | ||
context</a>, then [=call back with error=] |errorCallback| and | ||
{{GeolocationPositionError/PERMISSION_DENIED}} and terminate this | ||
algorithm. | ||
</li> | ||
<li>[=Request permission to use=] "geolocation" (see | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You need to capture the result of this call, which will be "granted" or "denied", and fail if it returns "denied". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I was trying to be clever and just let "allowed to use" deal with it. I'll do as you suggest. |
||
[[[#privacy_for_uas]]] for permissions UI requirements). | ||
</li> | ||
<li data-tests= | ||
"getCurrentPosition_permission_allow.https.html, getCurrentPosition_permission_deny.https.html"> | ||
If the <a>current settings object</a>'s [=environment settings | ||
object / responsible document=] is not [=allowed to use=] the | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is covered when https://www.w3.org/TR/permissions/#request-permission-to-use looks at the permission state. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree... fixing. |
||
"geolocation" feature, then [=call back with error=] | ||
|errorCallback| and {{GeolocationPositionError/PERMISSION_DENIED}} | ||
and terminate this algorithm. | ||
</li> | ||
<li>If a cached {{GeolocationPosition}} object, whose age is no | ||
greater than the value of the {{PositionOptions/maximumAge}} | ||
variable, is available, invoke the |successCallback| with the | ||
cached {{GeolocationPosition}} object as a parameter and exit this | ||
set of steps. | ||
cached {{GeolocationPosition}} object as a parameter and terminate | ||
this algorithm. | ||
</li> | ||
<li>If the value of the timeout variable is 0, invoke the | ||
|errorCallback| (if present) with a new | ||
{{GeolocationPositionError}} object whose | ||
{{GeolocationPositionError/code}} attribute is set to | ||
{{GeolocationPositionError.TIMEOUT}} and exit this set of steps. | ||
<li>If the value of the timeout variable is 0, [=call back with | ||
error=] |errorCallback| and {{GeolocationPositionError/TIMEOUT}} | ||
and terminate this algorithm. | ||
</li> | ||
<li>Start a location acquisition operation (e.g. by invoking a | ||
platform-specific API), possibly taking into account the value of | ||
|
@@ -447,21 +431,17 @@ <h3> | |
<li>Start a timer that will fire after the number of milliseconds | ||
denoted by the value of the timeout variable. When the timer fires, | ||
cancel any ongoing location acquisition operations associated with | ||
this instance of the steps, invoke the |errorCallback| (if present) | ||
with a new {{GeolocationPositionError}} object whose | ||
{{GeolocationPositionError/code}} attribute is set to | ||
{{GeolocationPositionError.TIMEOUT}}, and exit this set of steps. | ||
this instance of the steps, [=call back with error=] | ||
|errorCallback| and {{GeolocationPositionError/TIMEOUT}}. | ||
</li> | ||
<li>If the operation completes successfully before the timeout | ||
expires, cancel the pending timer, invoke the |successCallback| | ||
with a new {{GeolocationPosition}} object that reflects the result | ||
of the acquisition operation and exit this set of steps. | ||
of the acquisition operation and terminate this algorithm. | ||
</li> | ||
<li>If the operation fails before the timeout expires, cancel the | ||
pending timer and invoke the |errorCallback| (if present) with a | ||
new {{GeolocationPositionError}} object whose | ||
{{GeolocationPositionError/code}} is set to | ||
{{GeolocationPositionError.POSITION_UNAVAILABLE}}. | ||
pending timer and [=call back with error=] |errorCallback| and | ||
{{GeolocationPositionError/POSITION_UNAVAILABLE}}. | ||
</li> | ||
</ol> | ||
</section> | ||
|
@@ -470,40 +450,42 @@ <h3> | |
`watchPosition()` method | ||
</h3> | ||
<p> | ||
The <dfn>watchPosition()</dfn> method takes one, two or three | ||
arguments. When called, immediately return a long value that | ||
uniquely identifies a <a>watch process</a> and continue | ||
asynchronously. | ||
When <dfn>watchPosition()</dfn> is invoked, the user agent MUST: | ||
</p> | ||
<ol> | ||
<li>Let |watchId:long| be {{long}} that uniquely identifies a | ||
<a>watch process</a>. | ||
</li> | ||
<li>Return |watchId| and continue [=in parallel=]. | ||
</li> | ||
<li>If the <a>environment settings object</a> is a <a>non-secure | ||
context</a> or the <a>current settings object</a>'s [=environment | ||
settings object / responsible document=] is not [=allowed to use=] | ||
the "geolocation" feature: | ||
<ol> | ||
<li>If |errorCallback| is not null, invoke the |errorCallback| | ||
with a newly created {{GeolocationPositionError}} object whose | ||
{{GeolocationPositionError/code}} attribute is initialized to | ||
{{GeolocationPositionError/PERMISSION_DENIED}}. | ||
</li> | ||
<li>Terminate this algorithm. | ||
</li> | ||
</ol> | ||
context</a>, then [=call back with error=] |errorCallback| and | ||
{{GeolocationPositionError/PERMISSION_DENIED}} and terminate this | ||
algorithm. | ||
</li> | ||
<li>[=Request permission to use=] "geolocation" (see | ||
[[[#privacy_for_uas]]] for permissions UI requirements). | ||
</li> | ||
<li data-tests="watchPosition_permission_deny.https.html">If the | ||
<a>current settings object</a>'s [=environment settings object / | ||
responsible document=] is not [=allowed to use=] the "geolocation" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similarly here, "request permission to use" will return "denied" if the current settings object isn't allowed to use geolocation. |
||
feature, then [=call back with error=] |errorCallback| and | ||
{{GeolocationPositionError/PERMISSION_DENIED}} and terminate this | ||
algorithm. | ||
</li> | ||
<li> | ||
<p> | ||
Otherwise, start the watch operation. This operation MUST first | ||
attempt to obtain the current location of the device. If the | ||
attempt is successful, the |successCallback| MUST be invoked | ||
with a new {{GeolocationPosition}} object, reflecting the | ||
current location of the device. If the attempt fails, the | ||
|errorCallback| MUST be invoked with a new | ||
{{GeolocationPositionError}} object, reflecting the reason for | ||
the failure. The <a>watch process</a> then MUST continue to | ||
monitor the position of the device and invoke the appropriate | ||
callback every time this position changes. The <a>watch | ||
process</a> MUST continue until the | ||
{{Geolocation/clearWatch()}} method is called with the | ||
current location of the device. If the attempt fails, [=call | ||
back with error=], |errorCallback| and a {{unsigned short}} | ||
code that reflects the reason for the failure. The <a>watch | ||
process</a> then MUST continue to monitor the position of the | ||
device and invoke the appropriate callback every time this | ||
position changes. The <a>watch process</a> MUST continue until | ||
the {{Geolocation/clearWatch()}} method is called with the | ||
corresponding identifier. | ||
</p> | ||
</li> | ||
|
@@ -531,11 +513,9 @@ <h3> | |
<ol> | ||
<li>If the timer is not already running, start a timer that | ||
will fire after the number of milliseconds denoted by the value | ||
of the timeout variable. When the timer fires, invoke the | ||
|errorCallback| (if present) with a new | ||
{{GeolocationPositionError}} object whose | ||
{{GeolocationPositionError/code}} attribute is set to | ||
{{GeolocationPositionError.TIMEOUT}} and jump to the <a>wait | ||
of the timeout variable. When the timer fires, [=call back with | ||
error=] |errorCallback| and | ||
{{GeolocationPositionError/TIMEOUT}} and jump to the <a>wait | ||
for a system event to be received</a> step. | ||
</li> | ||
<li>If the location acquisition operation successfully yields a | ||
|
@@ -555,11 +535,9 @@ <h3> | |
</ol> | ||
</li> | ||
<li>Else, if the location acquisition operation reports an | ||
error before the {{PositionOptions/timeout}} expires, invoke | ||
the |errorCallback| (if present) with a new | ||
{{GeolocationPositionError}} object whose | ||
{{GeolocationPositionError/code}} is set to | ||
{{GeolocationPositionError.POSITION_UNAVAILABLE}}. This step | ||
error before the {{PositionOptions/timeout}} expires, [=call | ||
back with error=] |errorCallback| and | ||
{{GeolocationPositionError/POSITION_UNAVAILABLE}}. This step | ||
MAY be subject to callback [=rate limitation=]. | ||
</li> | ||
</ol> | ||
|
@@ -580,25 +558,12 @@ <h3> | |
limit</dfn> on the frequency of callbacks so as to avoid | ||
inadvertently consuming a disproportionate amount of resources. | ||
</p> | ||
<p data-tests= | ||
"getCurrentPosition_permission_allow.https.html, getCurrentPosition_permission_deny.https.html, watchPosition_permission_deny.https.html"> | ||
For both {{Geolocation/getCurrentPosition()}} and | ||
{{Geolocation/watchPosition()}}, the implementation MUST never | ||
invoke the |successCallback| without having first obtained | ||
permission from the user to share location. Furthermore, the | ||
implementation SHOULD always obtain the user's permission to share | ||
location before executing any of the | ||
{{Geolocation/getCurrentPosition()}} or | ||
{{Geolocation/watchPosition()}} steps described above. If the user | ||
grants permission, the appropriate callback MUST be invoked as | ||
described above. If the user denies permission, the |errorCallback| | ||
(if present) MUST be invoked with {{GeolocationPositionError/code}} | ||
set to {{GeolocationPositionError.PERMISSION_DENIED}}, irrespective | ||
of any other errors encountered in the above steps. The time that | ||
is spent obtaining the user permission MUST NOT be included in the | ||
period covered by the {{PositionOptions/timeout}} attribute of the | ||
{{PositionOptions}} parameter. The {{PositionOptions/timeout}} | ||
attribute MUST only apply to the location acquisition operation. | ||
<p> | ||
The time that is spent obtaining the user permission MUST NOT be | ||
included in the period covered by the {{PositionOptions/timeout}} | ||
attribute of the {{PositionOptions}} parameter. The | ||
{{PositionOptions/timeout}} attribute MUST only apply to the | ||
location acquisition operation. | ||
</p> | ||
</section> | ||
<section> | ||
|
@@ -615,6 +580,26 @@ <h3> | |
immediately stopped and no further callbacks MUST be invoked. | ||
</p> | ||
</section> | ||
<section> | ||
<h3> | ||
Callback with error | ||
</h3> | ||
<p> | ||
When instructed to <dfn>call back with error</dfn>, given an | ||
{{PositionErrorCallback}}? |callback:PositionErrorCallback?| and | ||
{{unsigned short}} |code:unsigned short|: | ||
</p> | ||
<ol class="algorithm"> | ||
<li>If |callback| is null, return. | ||
</li> | ||
<li>Let |error| be a a newly created {{GeolocationPositionError}} | ||
object whose {{GeolocationPositionError/code}} attribute is | ||
initialized to |code|. | ||
</li> | ||
<li>Call |callback| with |error|. | ||
</li> | ||
</ol> | ||
</section> | ||
<section data-dfn-for="PositionCallBack"> | ||
<h3> | ||
`PositionCallBack` callback | ||
|
@@ -695,7 +680,7 @@ <h3> | |
timeout elapses, and no other errors have occurred in this | ||
interval, then the corresponding |errorCallback| MUST be invoked | ||
with a {{GeolocationPositionError}} object whose code attribute is | ||
set to {{GeolocationPositionError.TIMEOUT}}. Note that the time | ||
set to {{GeolocationPositionError/TIMEOUT}}. Note that the time | ||
that is spent obtaining the user permission is not included in the | ||
period covered by the {{PositionOptions/timeout}} attribute. The | ||
{{PositionOptions/timeout}} attribute only applies to the location | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is mostly redundant with the "Ask the user’s permission for the calling algorithm" step in https://www.w3.org/TR/permissions/#request-permission-to-use and the "reflects the user’s intent" bit of https://www.w3.org/TR/permissions/#permission-state.
To the extent that you're trying to tighten the UA's ability to infer the user's intent, that seems like something that needs more discussion in #54: I don't agree that "the express permission of the user" includes permission by the device owner, who might not be the user or have even disclosed their permission grant to the user. It probably does make sense to say that a UA mustn't infer a user's intent to give away geolocation information based on other users' behavior, but a UA should still be able to infer that a user might want to not give away that information based on other users revoking permission, as is allowed by https://www.w3.org/TR/permissions/#new-information-about-the-users-intent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a whole other level of discussion. Basically, if a user willingly takes a device that they don't administer, there is zero privacy assurances. I really don't want to go down that rabbit hole.