зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1805860 - Add "storage-access" permission to dom::Permissions - r=anti-tracking-reviewers,webidl,saschanaz,pbz,smaug
Differential Revision: https://phabricator.services.mozilla.com/D182246
This commit is contained in:
Родитель
1ac439a64e
Коммит
035109eef7
|
@ -18,7 +18,8 @@ static const nsLiteralCString kPermissionTypes[] = {
|
|||
"persistent-storage"_ns,
|
||||
// "midi" is the only public permission but internally we have both "midi"
|
||||
// and "midi-sysex" (and yes, this is confusing).
|
||||
"midi"_ns
|
||||
"midi"_ns,
|
||||
"storage-access"_ns
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
@ -39,6 +40,12 @@ Maybe<PermissionName> TypeToPermissionName(const nsACString& aType) {
|
|||
return Some(PermissionName::Midi);
|
||||
}
|
||||
|
||||
// "storage-access" permissions are also annoying and require a special case.
|
||||
if (StringBeginsWith(aType, "3rdPartyStorage^"_ns) ||
|
||||
StringBeginsWith(aType, "3rdPartyFrameStorage^"_ns)) {
|
||||
return Some(PermissionName::Storage_access);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ArrayLength(kPermissionTypes); ++i) {
|
||||
if (kPermissionTypes[i].Equals(aType)) {
|
||||
return Some(static_cast<PermissionName>(i));
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "mozilla/dom/PermissionStatus.h"
|
||||
#include "mozilla/dom/PermissionsBinding.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/StorageAccessPermissionStatus.h"
|
||||
#include "mozilla/Components.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "PermissionUtils.h"
|
||||
|
@ -61,6 +62,8 @@ CreatePermissionStatus(JSContext* aCx, JS::Handle<JSObject*> aPermission,
|
|||
bool sysex = midiPerm.mSysex.WasPassed() && midiPerm.mSysex.Value();
|
||||
return MidiPermissionStatus::Create(aWindow, sysex);
|
||||
}
|
||||
case PermissionName::Storage_access:
|
||||
return StorageAccessPermissionStatus::Create(aWindow);
|
||||
case PermissionName::Geolocation:
|
||||
case PermissionName::Notifications:
|
||||
case PermissionName::Push:
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/StorageAccessPermissionStatus.h"
|
||||
|
||||
#include "mozilla/AntiTrackingUtils.h"
|
||||
#include "mozilla/dom/WindowGlobalChild.h"
|
||||
#include "mozilla/dom/BrowsingContext.h"
|
||||
#include "mozilla/dom/PermissionStatus.h"
|
||||
#include "mozilla/dom/PermissionStatusBinding.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
// static
|
||||
RefPtr<PermissionStatus::CreatePromise> StorageAccessPermissionStatus::Create(
|
||||
nsPIDOMWindowInner* aWindow) {
|
||||
RefPtr<PermissionStatus> status = new StorageAccessPermissionStatus(aWindow);
|
||||
return status->Init()->Then(
|
||||
GetMainThreadSerialEventTarget(), __func__,
|
||||
[status](nsresult aOk) {
|
||||
MOZ_ASSERT(NS_SUCCEEDED(aOk));
|
||||
return MozPromise<RefPtr<PermissionStatus>, nsresult,
|
||||
true>::CreateAndResolve(status, __func__);
|
||||
},
|
||||
[](nsresult aError) {
|
||||
MOZ_ASSERT(NS_FAILED(aError));
|
||||
return MozPromise<RefPtr<PermissionStatus>, nsresult,
|
||||
true>::CreateAndReject(aError, __func__);
|
||||
});
|
||||
}
|
||||
|
||||
StorageAccessPermissionStatus::StorageAccessPermissionStatus(
|
||||
nsPIDOMWindowInner* aWindow)
|
||||
: PermissionStatus(aWindow, PermissionName::Storage_access) {}
|
||||
|
||||
RefPtr<PermissionStatus::SimplePromise>
|
||||
StorageAccessPermissionStatus::UpdateState() {
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
|
||||
if (NS_WARN_IF(!window)) {
|
||||
return SimplePromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
|
||||
WindowGlobalChild* wgc = window->GetWindowGlobalChild();
|
||||
if (NS_WARN_IF(!wgc)) {
|
||||
return SimplePromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
|
||||
RefPtr<StorageAccessPermissionStatus> self(this);
|
||||
return wgc->SendHasStorageAccessPermission()->Then(
|
||||
GetMainThreadSerialEventTarget(), __func__,
|
||||
[self](bool aGranted) {
|
||||
if (aGranted) {
|
||||
self->mState = PermissionState::Granted;
|
||||
} else {
|
||||
self->mState = PermissionState::Prompt;
|
||||
}
|
||||
return SimplePromise::CreateAndResolve(NS_OK, __func__);
|
||||
},
|
||||
[](mozilla::ipc::ResponseRejectReason aError) {
|
||||
return SimplePromise::CreateAndResolve(NS_ERROR_FAILURE, __func__);
|
||||
});
|
||||
}
|
||||
|
||||
bool StorageAccessPermissionStatus::MaybeUpdatedBy(
|
||||
nsIPermission* aPermission) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StorageAccessPermissionStatus::MaybeUpdatedByNotifyOnly(
|
||||
nsPIDOMWindowInner* aInnerWindow) const {
|
||||
nsPIDOMWindowInner* owner = GetOwner();
|
||||
NS_ENSURE_TRUE(owner, false);
|
||||
NS_ENSURE_TRUE(aInnerWindow, false);
|
||||
return owner->WindowID() == aInnerWindow->WindowID();
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
|
@ -0,0 +1,30 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_StorageAccessPermissionStatus_h_
|
||||
#define mozilla_dom_StorageAccessPermissionStatus_h_
|
||||
|
||||
#include "mozilla/dom/PermissionStatus.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
class StorageAccessPermissionStatus final : public PermissionStatus {
|
||||
public:
|
||||
static RefPtr<CreatePromise> Create(nsPIDOMWindowInner* aWindow);
|
||||
|
||||
private:
|
||||
explicit StorageAccessPermissionStatus(nsPIDOMWindowInner* aWindow);
|
||||
|
||||
RefPtr<SimplePromise> UpdateState() override;
|
||||
|
||||
bool MaybeUpdatedBy(nsIPermission* aPermission) const override;
|
||||
bool MaybeUpdatedByNotifyOnly(
|
||||
nsPIDOMWindowInner* aInnerWindow) const override;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
#endif // mozilla_dom_StorageAccessPermissionStatus_h_
|
|
@ -11,6 +11,7 @@ EXPORTS.mozilla.dom += [
|
|||
"MidiPermissionStatus.h",
|
||||
"Permissions.h",
|
||||
"PermissionStatus.h",
|
||||
"StorageAccessPermissionStatus.h",
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
|
@ -19,6 +20,7 @@ UNIFIED_SOURCES += [
|
|||
"Permissions.cpp",
|
||||
"PermissionStatus.cpp",
|
||||
"PermissionUtils.cpp",
|
||||
"StorageAccessPermissionStatus.cpp",
|
||||
]
|
||||
|
||||
MOCHITEST_MANIFESTS += ["tests/mochitest.ini"]
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Helper for Permissions API Test</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||||
<script>
|
||||
'use strict';
|
||||
async function helper() {
|
||||
let status = await navigator.permissions
|
||||
.query({ name: "storage-access" });
|
||||
status.onchange = () => {
|
||||
status.onchange = null;
|
||||
parent.postMessage(status.state, "*")
|
||||
};
|
||||
parent.postMessage("ready", "*");
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="helper()">
|
||||
</body>
|
||||
</html>
|
|
@ -1,6 +1,7 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
file_empty.html
|
||||
file_storage_access_notification_helper.html
|
||||
prefs =
|
||||
dom.security.featurePolicy.header.enabled=true
|
||||
dom.security.featurePolicy.webidl.enabled=true
|
||||
|
@ -9,3 +10,5 @@ prefs =
|
|||
fail-if = xorigin
|
||||
[test_permissions_api.html]
|
||||
skip-if = xorigin # Hangs
|
||||
[test_storage_access_notification.html]
|
||||
skip-if = xorigin # Hangs
|
||||
|
|
|
@ -106,6 +106,13 @@
|
|||
type: 'persistent-storage',
|
||||
expected: 'denied',
|
||||
},
|
||||
{
|
||||
id: 'query storage-access unknown',
|
||||
top: UNKNOWN_ACTION,
|
||||
name: 'storage-access',
|
||||
type: '3rdPartyFrameStorage^https://example.org',
|
||||
expected: 'prompt',
|
||||
},
|
||||
{
|
||||
id: 'query navigation top prompt',
|
||||
top: PROMPT_ACTION,
|
||||
|
@ -134,6 +141,13 @@
|
|||
type: 'persistent-storage',
|
||||
expected: 'denied',
|
||||
},
|
||||
{
|
||||
id: 'query storage-access top prompt',
|
||||
top: PROMPT_ACTION,
|
||||
name: 'storage-access',
|
||||
type: '3rdPartyFrameStorage^https://example.org',
|
||||
expected: 'prompt',
|
||||
},
|
||||
{
|
||||
id: 'query navigation top denied',
|
||||
top: DENY_ACTION,
|
||||
|
@ -162,6 +176,13 @@
|
|||
type: 'persistent-storage',
|
||||
expected: 'denied',
|
||||
},
|
||||
{
|
||||
id: 'query storage-access top denied',
|
||||
top: DENY_ACTION,
|
||||
name: 'storage-access',
|
||||
type: '3rdPartyFrameStorage^https://example.org',
|
||||
expected: 'prompt',
|
||||
},
|
||||
{
|
||||
id: 'query navigation top granted',
|
||||
top: ALLOW_ACTION,
|
||||
|
@ -190,6 +211,13 @@
|
|||
type: 'persistent-storage',
|
||||
expected: 'denied',
|
||||
},
|
||||
{
|
||||
id: 'query storage-access top granted',
|
||||
top: ALLOW_ACTION,
|
||||
name: 'storage-access',
|
||||
type: '3rdPartyFrameStorage^https://example.org',
|
||||
expected: 'granted',
|
||||
},
|
||||
{
|
||||
id: 'query navigation top denied, iframe has allow attribute',
|
||||
top: DENY_ACTION,
|
||||
|
@ -222,7 +250,38 @@
|
|||
type: 'geo',
|
||||
expected: 'prompt',
|
||||
},
|
||||
|
||||
{
|
||||
id: 'query storage-access top denied, iframe has allow none attribute',
|
||||
top: DENY_ACTION,
|
||||
allow: "storage-access 'none'",
|
||||
name: 'storage-access',
|
||||
type: '3rdPartyFrameStorage^https://example.org',
|
||||
expected: 'prompt',
|
||||
},
|
||||
{
|
||||
id: 'query storage-access top granted, iframe has allow none attribute',
|
||||
top: ALLOW_ACTION,
|
||||
allow: "storage-access 'none'",
|
||||
name: 'storage-access',
|
||||
type: '3rdPartyFrameStorage^https://example.org',
|
||||
expected: 'prompt',
|
||||
},
|
||||
{
|
||||
id: 'query storage-access top prompt, iframe has allow none attribute',
|
||||
top: PROMPT_ACTION,
|
||||
allow: "storage-access 'none'",
|
||||
name: 'storage-access',
|
||||
type: '3rdPartyFrameStorage^https://example.org',
|
||||
expected: 'prompt',
|
||||
},
|
||||
{
|
||||
id: 'query storage-access top unknown, iframe has allow none attribute',
|
||||
top: UNKNOWN_ACTION,
|
||||
allow: "storage-access 'none'",
|
||||
name: 'storage-access',
|
||||
type: '3rdPartyFrameStorage^https://example.org',
|
||||
expected: 'prompt',
|
||||
},
|
||||
];
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Permissions API</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||||
<script type="application/javascript">
|
||||
'use strict';
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
async function setPermission(type, allow) {
|
||||
await SpecialPowers.popPermissions();
|
||||
await SpecialPowers.pushPermissions(
|
||||
[{ type, allow, context: document }]
|
||||
);
|
||||
}
|
||||
|
||||
const {
|
||||
UNKNOWN_ACTION,
|
||||
PROMPT_ACTION,
|
||||
ALLOW_ACTION,
|
||||
DENY_ACTION
|
||||
} = SpecialPowers.Ci.nsIPermissionManager;
|
||||
|
||||
window.addEventListener(
|
||||
"message",
|
||||
(event) => {
|
||||
if (event.data == "ready") {
|
||||
setPermission("3rdPartyFrameStorage^https://example.org", ALLOW_ACTION);
|
||||
} else {
|
||||
is(event.data, "granted", "storage-access permission should change to granted after the permission is set");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<iframe id="frame" src="https://example.org/tests/dom/permission/tests/file_storage_access_notification_helper.html"/>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -12,7 +12,8 @@ enum PermissionName {
|
|||
"notifications",
|
||||
"push",
|
||||
"persistent-storage",
|
||||
"midi"
|
||||
"midi",
|
||||
"storage-access" // Defined in https://privacycg.github.io/storage-access/#permissions-integration
|
||||
};
|
||||
|
||||
[GenerateInit]
|
||||
|
|
Загрузка…
Ссылка в новой задаче