diff --git a/extensions/permissions/PermissionManager.cpp b/extensions/permissions/PermissionManager.cpp index 85b6647ef401..a443a6b2a1fe 100644 --- a/extensions/permissions/PermissionManager.cpp +++ b/extensions/permissions/PermissionManager.cpp @@ -2471,6 +2471,20 @@ NS_IMETHODIMP PermissionManager::GetAllWithTypePrefix( aResult); } +NS_IMETHODIMP PermissionManager::GetAllByTypes( + const nsTArray& aTypes, + nsTArray>& aResult) { + if (aTypes.IsEmpty()) { + return NS_OK; + } + + return GetPermissionEntries( + [&](const PermissionEntry& aPermEntry) { + return aTypes.Contains(mTypeArray[aPermEntry.mType]); + }, + aResult); +} + nsresult PermissionManager::GetAllForPrincipalHelper( nsIPrincipal* aPrincipal, bool aSiteScopePermissions, nsTArray>& aResult) { diff --git a/extensions/permissions/test/unit/test_permmanager_getAllByTypes.js b/extensions/permissions/test/unit/test_permmanager_getAllByTypes.js new file mode 100644 index 000000000000..8353ed2282f9 --- /dev/null +++ b/extensions/permissions/test/unit/test_permmanager_getAllByTypes.js @@ -0,0 +1,121 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +function check_enumerator(permissionTypes, expectedPermissions) { + const permissions = Services.perms.getAllByTypes(permissionTypes); + + Assert.equal( + permissions.length, + expectedPermissions.length, + `getAllByTypes returned the expected number of permissions for ${JSON.stringify( + permissionTypes + )}` + ); + + permissions.forEach((perm, i) => { + info(`Checking permission #${i}`); + const [ + expectedPrincipal, + expectedType, + expectedCapability, + ] = expectedPermissions[i]; + + Assert.ok(perm != null); + Assert.ok(perm.principal.equals(expectedPrincipal)); + Assert.equal(perm.type, expectedType); + Assert.equal(perm.capability, expectedCapability); + Assert.equal(perm.expireType, Services.perms.EXPIRE_NEVER); + }); +} + +function run_test() { + let pm = Services.perms; + + let principal = Services.scriptSecurityManager.createContentPrincipalFromOrigin( + "http://example.com" + ); + let subPrincipal = Services.scriptSecurityManager.createContentPrincipalFromOrigin( + "http://sub.example.com" + ); + + const PERM_TYPE_1 = "test/getallbytypes_1"; + const PERM_TYPE_2 = "test/getallbytypes_2"; + + info("check default state"); + check_enumerator([], []); + check_enumerator([PERM_TYPE_1], []); + check_enumerator([PERM_TYPE_2], []); + check_enumerator([PERM_TYPE_1, PERM_TYPE_2], []); + + info("check that expected permissions are retrieved"); + pm.addFromPrincipal(principal, PERM_TYPE_1, pm.ALLOW_ACTION); + pm.addFromPrincipal( + subPrincipal, + "other-test/getallbytypes_1", + pm.PROMPT_ACTION + ); + check_enumerator([PERM_TYPE_1], [[principal, PERM_TYPE_1, pm.ALLOW_ACTION]]); + check_enumerator( + [PERM_TYPE_1, PERM_TYPE_2], + [[principal, PERM_TYPE_1, pm.ALLOW_ACTION]] + ); + check_enumerator([], []); + check_enumerator([PERM_TYPE_2], []); + + pm.addFromPrincipal(subPrincipal, PERM_TYPE_1, pm.PROMPT_ACTION); + check_enumerator( + [PERM_TYPE_1], + [ + [subPrincipal, PERM_TYPE_1, pm.PROMPT_ACTION], + [principal, PERM_TYPE_1, pm.ALLOW_ACTION], + ] + ); + check_enumerator( + [PERM_TYPE_1, PERM_TYPE_2], + [ + [subPrincipal, PERM_TYPE_1, pm.PROMPT_ACTION], + [principal, PERM_TYPE_1, pm.ALLOW_ACTION], + ] + ); + check_enumerator([], []); + check_enumerator([PERM_TYPE_2], []); + + pm.addFromPrincipal(principal, PERM_TYPE_2, pm.PROMPT_ACTION); + check_enumerator( + [PERM_TYPE_1, PERM_TYPE_2], + [ + [subPrincipal, PERM_TYPE_1, pm.PROMPT_ACTION], + [principal, PERM_TYPE_1, pm.ALLOW_ACTION], + [principal, PERM_TYPE_2, pm.PROMPT_ACTION], + ] + ); + check_enumerator([], []); + check_enumerator([PERM_TYPE_2], [[principal, PERM_TYPE_2, pm.PROMPT_ACTION]]); + + info("check that UNKNOWN_ACTION permissions are ignored"); + pm.addFromPrincipal(subPrincipal, PERM_TYPE_2, pm.UNKNOWN_ACTION); + check_enumerator([PERM_TYPE_2], [[principal, PERM_TYPE_2, pm.PROMPT_ACTION]]); + + info("check that permission updates are reflected"); + pm.addFromPrincipal(subPrincipal, PERM_TYPE_2, pm.PROMPT_ACTION); + check_enumerator( + [PERM_TYPE_2], + [ + [subPrincipal, PERM_TYPE_2, pm.PROMPT_ACTION], + [principal, PERM_TYPE_2, pm.PROMPT_ACTION], + ] + ); + + info("check that permission removals are reflected"); + pm.removeFromPrincipal(principal, PERM_TYPE_1); + check_enumerator( + [PERM_TYPE_1], + [[subPrincipal, PERM_TYPE_1, pm.PROMPT_ACTION]] + ); + + pm.removeAll(); + check_enumerator([], []); + check_enumerator([PERM_TYPE_1], []); + check_enumerator([PERM_TYPE_2], []); + check_enumerator([PERM_TYPE_1, PERM_TYPE_2], []); +} diff --git a/extensions/permissions/test/unit/xpcshell.ini b/extensions/permissions/test/unit/xpcshell.ini index 47456e59fc5a..4a29a3cbf88f 100644 --- a/extensions/permissions/test/unit/xpcshell.ini +++ b/extensions/permissions/test/unit/xpcshell.ini @@ -5,6 +5,7 @@ head = head.js [test_permmanager_defaults.js] [test_permmanager_expiration.js] skip-if = win10_2004 # Bug 1718292 +[test_permmanager_getAllByTypes.js] [test_permmanager_getAllByTypeSince.js] [test_permmanager_getAllForPrincipal.js] [test_permmanager_getAllWithTypePrefix.js] diff --git a/netwerk/base/nsIPermissionManager.idl b/netwerk/base/nsIPermissionManager.idl index db71e2188157..32f75f241d20 100644 --- a/netwerk/base/nsIPermissionManager.idl +++ b/netwerk/base/nsIPermissionManager.idl @@ -82,6 +82,17 @@ interface nsIPermissionManager : nsISupports */ Array getAllWithTypePrefix(in ACString prefix); + + /** + * Get all custom permissions whose type exactly match one of the types defined + * in the passed array argument. + * This will return an array of all permissions which are not set to default. + * + * @param types an array of case-sensitive ASCII strings, identifying the + * permissions to be matched. + */ + Array getAllByTypes(in Array types); + /** * Get all custom permissions of a specific type and that were modified after * the specified date. This will return an array of all permissions which are