Bug 1954522 - Add support for data collection permissions in browser.permissions.getAll(). r=rpl
Differential Revision: https://phabricator.services.mozilla.com/D242830
This commit is contained in:
@@ -1380,6 +1380,10 @@ export class ExtensionData {
|
||||
apis: [...this.apiNames],
|
||||
};
|
||||
|
||||
if (lazy.dataCollectionPermissionsEnabled) {
|
||||
result.data_collection = Array.from(this.dataCollectionPermissions);
|
||||
}
|
||||
|
||||
const EXP_PATTERN = /^experiments\.\w+/;
|
||||
result.permissions = [...this.permissions].filter(
|
||||
p => !result.origins.includes(p) && !EXP_PATTERN.test(p)
|
||||
@@ -2010,7 +2014,7 @@ export class ExtensionData {
|
||||
if (lazy.dataCollectionPermissionsEnabled) {
|
||||
const { required } = this.getDataCollectionPermissions(manifest);
|
||||
|
||||
for (const permission of required) {
|
||||
for (const permission of required.filter(perm => perm !== "none")) {
|
||||
dataCollectionPermissions.add(permission);
|
||||
}
|
||||
}
|
||||
@@ -2032,6 +2036,9 @@ export class ExtensionData {
|
||||
for (let origin of perms.origins) {
|
||||
originPermissions.add(origin);
|
||||
}
|
||||
for (let perm of perms.data_collection) {
|
||||
dataCollectionPermissions.add(perm);
|
||||
}
|
||||
}
|
||||
|
||||
for (let api of apiNames) {
|
||||
@@ -3272,6 +3279,9 @@ export class Extension extends ExtensionData {
|
||||
for (let perm of permissions.permissions) {
|
||||
this.permissions.add(perm);
|
||||
}
|
||||
for (let perm of permissions.data_collection) {
|
||||
this.dataCollectionPermissions.add(perm);
|
||||
}
|
||||
this.policy.permissions = Array.from(this.permissions);
|
||||
|
||||
updateAllowedOrigins(this.policy, permissions.origins, /* isAdd */ true);
|
||||
@@ -3296,6 +3306,9 @@ export class Extension extends ExtensionData {
|
||||
for (let perm of permissions.permissions) {
|
||||
this.permissions.delete(perm);
|
||||
}
|
||||
for (let perm of permissions.data_collection) {
|
||||
this.dataCollectionPermissions.delete(perm);
|
||||
}
|
||||
this.policy.permissions = Array.from(this.permissions);
|
||||
|
||||
updateAllowedOrigins(this.policy, permissions.origins, /* isAdd */ false);
|
||||
@@ -3478,6 +3491,7 @@ export class Extension extends ExtensionData {
|
||||
pat => pat.pattern
|
||||
);
|
||||
manifestData.permissions = this.permissions;
|
||||
manifestData.dataCollectionPermissions = this.dataCollectionPermissions;
|
||||
return StartupCache.manifests.set(this.manifestCacheKey, manifestData);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,11 @@ this.permissions = class extends ExtensionAPIPersistent {
|
||||
let callback = (event, change) => {
|
||||
if (change.extensionId == extension.id && change.added) {
|
||||
let perms = normalizePermissions(change.added);
|
||||
if (perms.permissions.length || perms.origins.length) {
|
||||
if (
|
||||
perms.permissions.length ||
|
||||
perms.origins.length ||
|
||||
(dataCollectionPermissionsEnabled && perms.data_collection.length)
|
||||
) {
|
||||
fire.async(perms);
|
||||
}
|
||||
}
|
||||
@@ -73,7 +77,11 @@ this.permissions = class extends ExtensionAPIPersistent {
|
||||
let callback = (event, change) => {
|
||||
if (change.extensionId == extension.id && change.removed) {
|
||||
let perms = normalizePermissions(change.removed);
|
||||
if (perms.permissions.length || perms.origins.length) {
|
||||
if (
|
||||
perms.permissions.length ||
|
||||
perms.origins.length ||
|
||||
(dataCollectionPermissionsEnabled && perms.data_collection.length)
|
||||
) {
|
||||
fire.async(perms);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,12 @@
|
||||
"items": { "$ref": "manifest.MatchPattern" },
|
||||
"optional": true,
|
||||
"default": []
|
||||
},
|
||||
"data_collection": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "manifest.OptionalDataCollectionPermission" },
|
||||
"optional": true,
|
||||
"default": []
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -45,6 +51,12 @@
|
||||
"items": { "$ref": "manifest.MatchPattern" },
|
||||
"optional": true,
|
||||
"default": []
|
||||
},
|
||||
"data_collection": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "manifest.OptionalDataCollectionPermission" },
|
||||
"optional": true,
|
||||
"default": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,3 +536,182 @@ add_task(
|
||||
await extension.unload();
|
||||
}
|
||||
);
|
||||
|
||||
add_task(
|
||||
{ pref_set: [["extensions.dataCollectionPermissions.enabled", true]] },
|
||||
async function test_getAll_with_data_collection() {
|
||||
async function background() {
|
||||
browser.test.onMessage.addListener(async msg => {
|
||||
browser.test.assertEq("getAll", msg, "expected correct message");
|
||||
const permissions = await browser.permissions.getAll();
|
||||
browser.test.sendMessage("all", permissions);
|
||||
});
|
||||
|
||||
browser.permissions.onAdded.addListener(details => {
|
||||
browser.test.sendMessage("added", details);
|
||||
});
|
||||
|
||||
browser.permissions.onRemoved.addListener(details => {
|
||||
browser.test.sendMessage("removed", details);
|
||||
});
|
||||
|
||||
browser.test.sendMessage("ready");
|
||||
}
|
||||
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
permissions: ["bookmarks"],
|
||||
browser_specific_settings: {
|
||||
gecko: {
|
||||
data_collection_permissions: {
|
||||
// "none" shouldn't be added to the list of data collection
|
||||
// permissions returned by `getAll()`.
|
||||
required: ["none"],
|
||||
optional: ["technicalAndInteraction", "locationInfo"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
background,
|
||||
});
|
||||
await extension.startup();
|
||||
await extension.awaitMessage("ready");
|
||||
|
||||
const getAllAndVerifyDataCollection = async expected => {
|
||||
extension.sendMessage("getAll");
|
||||
const permissions = await extension.awaitMessage("all");
|
||||
Assert.deepEqual(
|
||||
permissions,
|
||||
{
|
||||
permissions: ["bookmarks"],
|
||||
origins: [],
|
||||
data_collection: expected,
|
||||
},
|
||||
"expected permissions with data collection"
|
||||
);
|
||||
};
|
||||
|
||||
// Pretend the T&I permission was granted at install time.
|
||||
let perms = {
|
||||
permissions: [],
|
||||
origins: [],
|
||||
data_collection: ["technicalAndInteraction"],
|
||||
};
|
||||
await ExtensionPermissions.add(extension.id, perms, extension.extension);
|
||||
let added = await extension.awaitMessage("added");
|
||||
Assert.deepEqual(
|
||||
added,
|
||||
{
|
||||
permissions: [],
|
||||
origins: [],
|
||||
data_collection: ["technicalAndInteraction"],
|
||||
},
|
||||
"expected new permissions granted"
|
||||
);
|
||||
await getAllAndVerifyDataCollection(["technicalAndInteraction"]);
|
||||
|
||||
// Grant another optional data collection permission.
|
||||
perms = {
|
||||
permissions: [],
|
||||
origins: [],
|
||||
data_collection: ["technicalAndInteraction", "locationInfo"],
|
||||
};
|
||||
await ExtensionPermissions.add(extension.id, perms, extension.extension);
|
||||
added = await extension.awaitMessage("added");
|
||||
Assert.deepEqual(
|
||||
added,
|
||||
{
|
||||
permissions: [],
|
||||
origins: [],
|
||||
data_collection: ["locationInfo"],
|
||||
},
|
||||
"expected new permissions granted"
|
||||
);
|
||||
await getAllAndVerifyDataCollection([
|
||||
"technicalAndInteraction",
|
||||
"locationInfo",
|
||||
]);
|
||||
|
||||
// Revoke all optional data collection permissions.
|
||||
await ExtensionPermissions.remove(extension.id, perms, extension.extension);
|
||||
const removed = await extension.awaitMessage("removed");
|
||||
Assert.deepEqual(
|
||||
removed,
|
||||
{
|
||||
permissions: [],
|
||||
origins: [],
|
||||
data_collection: ["technicalAndInteraction", "locationInfo"],
|
||||
},
|
||||
"expected permissions revoked"
|
||||
);
|
||||
await getAllAndVerifyDataCollection([]);
|
||||
|
||||
await extension.unload();
|
||||
}
|
||||
);
|
||||
|
||||
add_task(
|
||||
{ pref_set: [["extensions.dataCollectionPermissions.enabled", true]] },
|
||||
async function test_getAll_with_required_data_collection() {
|
||||
async function background() {
|
||||
browser.test.onMessage.addListener(async msg => {
|
||||
browser.test.assertEq("getAll", msg, "expected correct message");
|
||||
const permissions = await browser.permissions.getAll();
|
||||
browser.test.sendMessage("all", permissions);
|
||||
});
|
||||
|
||||
browser.test.sendMessage("ready");
|
||||
}
|
||||
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
permissions: ["bookmarks"],
|
||||
browser_specific_settings: {
|
||||
gecko: {
|
||||
data_collection_permissions: {
|
||||
required: ["bookmarksInfo"],
|
||||
optional: ["technicalAndInteraction", "locationInfo"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
background,
|
||||
});
|
||||
await extension.startup();
|
||||
await extension.awaitMessage("ready");
|
||||
|
||||
extension.sendMessage("getAll");
|
||||
let permissions = await extension.awaitMessage("all");
|
||||
Assert.deepEqual(
|
||||
permissions,
|
||||
{
|
||||
permissions: ["bookmarks"],
|
||||
origins: [],
|
||||
data_collection: ["bookmarksInfo"],
|
||||
},
|
||||
"expected permissions with required data collection"
|
||||
);
|
||||
|
||||
let perms = {
|
||||
permissions: [],
|
||||
origins: [],
|
||||
data_collection: ["technicalAndInteraction"],
|
||||
};
|
||||
await ExtensionPermissions.add(extension.id, perms, extension.extension);
|
||||
extension.sendMessage("getAll");
|
||||
permissions = await extension.awaitMessage("all");
|
||||
Assert.deepEqual(
|
||||
permissions,
|
||||
{
|
||||
permissions: ["bookmarks"],
|
||||
origins: [],
|
||||
data_collection: ["bookmarksInfo", "technicalAndInteraction"],
|
||||
},
|
||||
"expected permissions with newly added data collection"
|
||||
);
|
||||
|
||||
await extension.unload();
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user