mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 04:41:11 +00:00
Backed out 8 changesets (bug 1919558
, bug 1816449) for causing mochitest failures @ test_refresh_firefox.py
Backed out changeset a194f41588e9 (bug 1816449) Backed out changeset 10643d7c7a78 (bug1919558
) Backed out changeset b346a2a2bfdc (bug1919558
) Backed out changeset 507f18e7103d (bug1919558
) Backed out changeset 4d0d9f72bc2a (bug1919558
) Backed out changeset 65d9270f0991 (bug1919558
) Backed out changeset fe95b9e6ff13 (bug1919558
) Backed out changeset ea6ffcb0e334 (bug1919558
)
This commit is contained in:
parent
21d92fc36f
commit
8c75b7c054
@ -6,9 +6,6 @@
|
||||
|
||||
#include "mozilla/AbstractThread.h"
|
||||
#include "mozilla/AppShutdown.h"
|
||||
#ifdef MOZ_BACKGROUNDTASKS
|
||||
# include "mozilla/BackgroundTasks.h"
|
||||
#endif
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/ContentPrincipal.h"
|
||||
@ -406,10 +403,8 @@ nsresult UpgradeHostToOriginAndInsert(
|
||||
// subdomain of this host), and try to add it as a principal.
|
||||
bool foundHistory = false;
|
||||
|
||||
nsCOMPtr<nsINavHistoryService> histSrv = nullptr;
|
||||
if (NS_IsMainThread()) {
|
||||
histSrv = do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID);
|
||||
}
|
||||
nsCOMPtr<nsINavHistoryService> histSrv =
|
||||
do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID);
|
||||
|
||||
if (histSrv) {
|
||||
nsCOMPtr<nsINavHistoryQuery> histQuery;
|
||||
@ -1709,68 +1704,6 @@ PermissionManager::AddFromPrincipalAndPersistInPrivateBrowsing(
|
||||
/* aAllowPersistInPrivateBrowsing */ true);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PermissionManager::AddDefaultFromPrincipal(nsIPrincipal* aPrincipal,
|
||||
const nsACString& aType,
|
||||
uint32_t aPermission) {
|
||||
ENSURE_NOT_CHILD_PROCESS;
|
||||
MOZ_ASSERT(mState == eReady);
|
||||
|
||||
bool isValidPermissionPrincipal = false;
|
||||
nsresult rv = ShouldHandlePrincipalForPermission(aPrincipal,
|
||||
isValidPermissionPrincipal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!isValidPermissionPrincipal) {
|
||||
// return early if the principal is invalid for permissions
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCString origin;
|
||||
rv = GetOriginFromPrincipal(aPrincipal, IsOAForceStripPermission(aType),
|
||||
origin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
DefaultEntry entry;
|
||||
{
|
||||
// Lock for mDefaultEntriesForImport
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
// Try to update existing entry in mDefaultEntriesForImport, which will
|
||||
// later be used to restore the default permissions when permissions are
|
||||
// cleared
|
||||
bool updatedExistingEntry = false;
|
||||
nsTArray<DefaultEntry>::iterator defaultEntry =
|
||||
mDefaultEntriesForImport.begin();
|
||||
while (defaultEntry != mDefaultEntriesForImport.end()) {
|
||||
if (defaultEntry->mType == aType && defaultEntry->mOrigin == origin) {
|
||||
defaultEntry->mPermission = aPermission;
|
||||
entry = *defaultEntry;
|
||||
if (aPermission == nsIPermissionManager::UNKNOWN_ACTION) {
|
||||
mDefaultEntriesForImport.RemoveElementAt(defaultEntry);
|
||||
}
|
||||
updatedExistingEntry = true;
|
||||
break;
|
||||
}
|
||||
++defaultEntry;
|
||||
}
|
||||
|
||||
// Or add a new entry if there wasn't already one and we aren't deleting the
|
||||
// default permission
|
||||
if (!updatedExistingEntry) {
|
||||
entry.mOrigin = origin;
|
||||
entry.mPermission = aPermission;
|
||||
entry.mType = aType;
|
||||
if (aPermission != nsIPermissionManager::UNKNOWN_ACTION) {
|
||||
mDefaultEntriesForImport.AppendElement(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// So far, we have only updated mDefaultEntriesForImport for later recovery.
|
||||
// Now, we actually need to import this change into the permission manager.
|
||||
return ImportDefaultEntry(entry);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PermissionManager::AddFromPrincipal(nsIPrincipal* aPrincipal,
|
||||
const nsACString& aType,
|
||||
@ -1836,9 +1769,6 @@ nsresult PermissionManager::AddInternal(
|
||||
const bool aAllowPersistInPrivateBrowsing) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// If this is a default permission, no changes should not be written to disk.
|
||||
MOZ_ASSERT((aID != cIDPermissionIsDefault) || (aDBOperation != eWriteToDB));
|
||||
|
||||
EnsureReadCompleted();
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
@ -1949,27 +1879,24 @@ nsresult PermissionManager::AddInternal(
|
||||
if (aPermission == oldPermissionEntry.mPermission &&
|
||||
aExpireType == oldPermissionEntry.mExpireType &&
|
||||
(aExpireType == nsIPermissionManager::EXPIRE_NEVER ||
|
||||
aExpireTime == oldPermissionEntry.mExpireTime)) {
|
||||
aExpireTime == oldPermissionEntry.mExpireTime))
|
||||
op = eOperationNone;
|
||||
} else if (oldPermissionEntry.mID == cIDPermissionIsDefault &&
|
||||
aID != cIDPermissionIsDefault) {
|
||||
// An existing default permission already exists, but the new permission
|
||||
// isn't a default permission. This case requires some special handing.
|
||||
else if (oldPermissionEntry.mID == cIDPermissionIsDefault)
|
||||
// The existing permission is one added as a default and the new
|
||||
// permission doesn't exactly match so we are replacing the default. This
|
||||
// is true even if the new permission is UNKNOWN_ACTION (which means a
|
||||
// "logical remove" of the default)
|
||||
op = eOperationReplacingDefault;
|
||||
} else if (oldPermissionEntry.mID != cIDPermissionIsDefault &&
|
||||
aID == cIDPermissionIsDefault) {
|
||||
else if (aID == cIDPermissionIsDefault)
|
||||
// We are adding a default permission but a "real" permission already
|
||||
// exists. This means we don't have to do anything here.
|
||||
// exists. This almost-certainly means we just did a removeAllSince and
|
||||
// are re-importing defaults - so we can ignore this.
|
||||
op = eOperationNone;
|
||||
} else if (aPermission == nsIPermissionManager::UNKNOWN_ACTION) {
|
||||
// At this point, both the old and new permission are either both default
|
||||
// permissions, or both not default permissions. Now we only need to check
|
||||
// wether to change or remove the old permission.
|
||||
else if (aPermission == nsIPermissionManager::UNKNOWN_ACTION)
|
||||
op = eOperationRemoving;
|
||||
} else {
|
||||
else
|
||||
op = eOperationChanging;
|
||||
}
|
||||
}
|
||||
|
||||
// child processes should *always* be passed a modificationTime of zero.
|
||||
MOZ_ASSERT(!IsChildProcess() || aModificationTime == 0);
|
||||
@ -2046,20 +1973,6 @@ nsresult PermissionManager::AddInternal(
|
||||
mPermissionTable.RemoveEntry(entry);
|
||||
}
|
||||
|
||||
// If the entry we are removing is not a default, restore the potential
|
||||
// default entry in-memory
|
||||
if (oldPermissionEntry.mID != cIDPermissionIsDefault) {
|
||||
for (const DefaultEntry& defaultEntry : mDefaultEntriesForImport) {
|
||||
if (defaultEntry.mType == aType && defaultEntry.mOrigin == origin &&
|
||||
defaultEntry.mPermission !=
|
||||
nsIPermissionManager::UNKNOWN_ACTION) {
|
||||
rv = ImportDefaultEntry(defaultEntry);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2290,6 +2203,9 @@ nsresult PermissionManager::RemovePermissionEntries(T aCondition) {
|
||||
PermissionManager::eWriteToDB, false, &std::get<2>(i));
|
||||
}
|
||||
|
||||
// now re-import any defaults as they may now be required if we just deleted
|
||||
// an override.
|
||||
ImportLatestDefaults();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2798,13 +2714,10 @@ NS_IMETHODIMP PermissionManager::Observe(nsISupports* aSubject,
|
||||
const char16_t* someData) {
|
||||
ENSURE_NOT_CHILD_PROCESS;
|
||||
|
||||
if (!nsCRT::strcmp(aTopic, "profile-do-change")) {
|
||||
if (!mPermissionsFile) {
|
||||
if (!nsCRT::strcmp(aTopic, "profile-do-change") && !mPermissionsFile) {
|
||||
// profile startup is complete, and we didn't have the permissions file
|
||||
// before; init the db from the new location
|
||||
InitDB(false);
|
||||
}
|
||||
InitRemotePermissionService();
|
||||
} else if (!nsCRT::strcmp(aTopic, "testonly-reload-permissions-from-disk")) {
|
||||
// Testing mechanism to reload all permissions from disk. Because the
|
||||
// permission manager automatically initializes itself at startup, tests
|
||||
@ -2816,7 +2729,6 @@ NS_IMETHODIMP PermissionManager::Observe(nsISupports* aSubject,
|
||||
RemoveAllFromMemory();
|
||||
CloseDB(eNone);
|
||||
InitDB(false);
|
||||
InitRemotePermissionService();
|
||||
} else if (!nsCRT::strcmp(aTopic, OBSERVER_TOPIC_IDLE_DAILY)) {
|
||||
PerformIdleDailyMaintenance();
|
||||
}
|
||||
@ -3263,33 +3175,6 @@ void PermissionManager::CompleteRead() {
|
||||
}
|
||||
}
|
||||
|
||||
void PermissionManager::InitRemotePermissionService() {
|
||||
// Check if this service is disabled by pref, and abort if it is.
|
||||
if (!StaticPrefs::permissions_manager_remote_enabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Also abort if we are in a background task. We do not want to call remote
|
||||
// settings there, because we do not want to pollute the background task
|
||||
// profile, and because we don't need the remote permissions there anyways.
|
||||
#ifdef MOZ_BACKGROUNDTASKS
|
||||
if (BackgroundTasks::IsBackgroundTaskMode()) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_DispatchToCurrentThreadQueue(
|
||||
NS_NewRunnableFunction(
|
||||
"RemotePermissionService::Init",
|
||||
[&] {
|
||||
nsCOMPtr<nsIRemotePermissionService> remotePermissionService =
|
||||
do_GetService(NS_REMOTEPERMISSIONSERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE_VOID(remotePermissionService);
|
||||
remotePermissionService->Init();
|
||||
}),
|
||||
EventQueuePriority::Idle);
|
||||
}
|
||||
|
||||
void PermissionManager::MaybeAddReadEntryFromMigration(
|
||||
const nsACString& aOrigin, const nsCString& aType, uint32_t aPermission,
|
||||
uint32_t aExpireType, int64_t aExpireTime, int64_t aModificationTime,
|
||||
@ -3785,7 +3670,7 @@ void PermissionManager::ConsumeDefaultsInputStream(
|
||||
constexpr char kMatchTypeHost[] = "host";
|
||||
constexpr char kMatchTypeOrigin[] = "origin";
|
||||
|
||||
mDefaultEntriesForImport.Clear();
|
||||
mDefaultEntries.Clear();
|
||||
|
||||
if (!aInputStream) {
|
||||
return;
|
||||
@ -3829,99 +3714,128 @@ void PermissionManager::ConsumeDefaultsInputStream(
|
||||
continue;
|
||||
}
|
||||
|
||||
const nsCString& hostOrOrigin = lineArray[3];
|
||||
const nsCString& type = lineArray[1];
|
||||
DefaultEntry::Op op;
|
||||
|
||||
if (lineArray[0].EqualsLiteral(kMatchTypeHost)) {
|
||||
UpgradeHostToOriginAndInsert(
|
||||
hostOrOrigin, type, permission, nsIPermissionManager::EXPIRE_NEVER, 0,
|
||||
0,
|
||||
[&](const nsACString& aOrigin, const nsCString& aType,
|
||||
uint32_t aPermission, uint32_t aExpireType, int64_t aExpireTime,
|
||||
int64_t aModificationTime) {
|
||||
AddDefaultEntryForImport(aOrigin, aType, aPermission, aProofOfLock);
|
||||
return NS_OK;
|
||||
});
|
||||
op = DefaultEntry::eImportMatchTypeHost;
|
||||
} else if (lineArray[0].EqualsLiteral(kMatchTypeOrigin)) {
|
||||
AddDefaultEntryForImport(hostOrOrigin, type, permission, aProofOfLock);
|
||||
op = DefaultEntry::eImportMatchTypeOrigin;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
DefaultEntry* entry = mDefaultEntries.AppendElement();
|
||||
MOZ_ASSERT(entry);
|
||||
|
||||
entry->mOp = op;
|
||||
entry->mPermission = permission;
|
||||
entry->mHostOrOrigin = lineArray[3];
|
||||
entry->mType = lineArray[1];
|
||||
} while (isMore);
|
||||
}
|
||||
|
||||
void PermissionManager::AddDefaultEntryForImport(
|
||||
const nsACString& aOrigin, const nsCString& aType, uint32_t aPermission,
|
||||
const MonitorAutoLock& aProofOfLock) {
|
||||
DefaultEntry* entry = mDefaultEntriesForImport.AppendElement();
|
||||
MOZ_ASSERT(entry);
|
||||
// ImportLatestDefaults will import the latest default cookies read during the
|
||||
// last DB initialization.
|
||||
nsresult PermissionManager::ImportLatestDefaults() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mState == eReady);
|
||||
|
||||
entry->mPermission = aPermission;
|
||||
entry->mOrigin = aOrigin;
|
||||
entry->mType = aType;
|
||||
nsresult rv;
|
||||
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
for (const DefaultEntry& entry : mDefaultEntries) {
|
||||
if (entry.mOp == DefaultEntry::eImportMatchTypeHost) {
|
||||
// the import file format doesn't handle modification times, so we use
|
||||
// 0, which AddInternal will convert to now()
|
||||
int64_t modificationTime = 0;
|
||||
|
||||
rv = UpgradeHostToOriginAndInsert(
|
||||
entry.mHostOrOrigin, entry.mType, entry.mPermission,
|
||||
nsIPermissionManager::EXPIRE_NEVER, 0, modificationTime,
|
||||
[&](const nsACString& aOrigin, const nsCString& aType,
|
||||
uint32_t aPermission, uint32_t aExpireType, int64_t aExpireTime,
|
||||
int64_t aModificationTime) {
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsresult rv =
|
||||
GetPrincipalFromOrigin(aOrigin, IsOAForceStripPermission(aType),
|
||||
getter_AddRefs(principal));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv =
|
||||
AddInternal(principal, aType, aPermission,
|
||||
cIDPermissionIsDefault, aExpireType, aExpireTime,
|
||||
aModificationTime, PermissionManager::eDontNotify,
|
||||
PermissionManager::eNoDBOperation, false, &aOrigin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (StaticPrefs::permissions_isolateBy_privateBrowsing()) {
|
||||
// Also import the permission for private browsing.
|
||||
OriginAttributes attrs =
|
||||
OriginAttributes(principal->OriginAttributesRef());
|
||||
attrs.mPrivateBrowsingId = 1;
|
||||
nsCOMPtr<nsIPrincipal> pbPrincipal =
|
||||
BasePrincipal::Cast(principal)->CloneForcingOriginAttributes(
|
||||
attrs);
|
||||
|
||||
rv = AddInternal(
|
||||
pbPrincipal, aType, aPermission, cIDPermissionIsDefault,
|
||||
aExpireType, aExpireTime, aModificationTime,
|
||||
PermissionManager::eDontNotify,
|
||||
PermissionManager::eNoDBOperation, false, &aOrigin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsresult PermissionManager::ImportDefaultEntry(
|
||||
const DefaultEntry& aDefaultEntry) {
|
||||
return NS_OK;
|
||||
});
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("There was a problem importing a host permission");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(entry.mOp == DefaultEntry::eImportMatchTypeOrigin);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsresult rv = GetPrincipalFromOrigin(
|
||||
aDefaultEntry.mOrigin, IsOAForceStripPermission(aDefaultEntry.mType),
|
||||
rv = GetPrincipalFromOrigin(entry.mHostOrOrigin,
|
||||
IsOAForceStripPermission(entry.mType),
|
||||
getter_AddRefs(principal));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Couldn't import an origin permission - malformed origin");
|
||||
return rv;
|
||||
continue;
|
||||
}
|
||||
|
||||
// the import file format doesn't handle modification times, so we use
|
||||
// 0, which AddInternal will convert to now()
|
||||
int64_t modificationTime = 0;
|
||||
|
||||
rv = AddInternal(principal, aDefaultEntry.mType, aDefaultEntry.mPermission,
|
||||
rv = AddInternal(principal, entry.mType, entry.mPermission,
|
||||
cIDPermissionIsDefault, nsIPermissionManager::EXPIRE_NEVER,
|
||||
0, modificationTime, eDontNotify, eNoDBOperation);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("There was a problem importing an origin permission");
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (StaticPrefs::permissions_isolateBy_privateBrowsing() &&
|
||||
!IsOAForceStripPermission(aDefaultEntry.mType)) {
|
||||
if (StaticPrefs::permissions_isolateBy_privateBrowsing()) {
|
||||
// Also import the permission for private browsing.
|
||||
OriginAttributes attrs = OriginAttributes(principal->OriginAttributesRef());
|
||||
OriginAttributes attrs =
|
||||
OriginAttributes(principal->OriginAttributesRef());
|
||||
attrs.mPrivateBrowsingId = 1;
|
||||
nsCOMPtr<nsIPrincipal> pbPrincipal =
|
||||
BasePrincipal::Cast(principal)->CloneForcingOriginAttributes(attrs);
|
||||
// May return nullptr if clone fails.
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
NS_ENSURE_TRUE(pbPrincipal, NS_ERROR_FAILURE);
|
||||
|
||||
rv =
|
||||
AddInternal(pbPrincipal, aDefaultEntry.mType, aDefaultEntry.mPermission,
|
||||
cIDPermissionIsDefault, nsIPermissionManager::EXPIRE_NEVER,
|
||||
0, modificationTime, eDontNotify, eNoDBOperation);
|
||||
rv = AddInternal(pbPrincipal, entry.mType, entry.mPermission,
|
||||
cIDPermissionIsDefault,
|
||||
nsIPermissionManager::EXPIRE_NEVER, 0, modificationTime,
|
||||
eDontNotify, eNoDBOperation);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
"There was a problem importing an origin permission for private "
|
||||
"browsing");
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// ImportLatestDefaults will import the latest default permissions read during
|
||||
// the last DB initialization.
|
||||
nsresult PermissionManager::ImportLatestDefaults() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mState == eReady);
|
||||
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
for (const DefaultEntry& entry : mDefaultEntriesForImport) {
|
||||
Unused << ImportDefaultEntry(entry);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsIAsyncShutdown.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIRemotePermissionService.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIURI.h"
|
||||
@ -621,35 +620,29 @@ class PermissionManager final : public nsIPermissionManager,
|
||||
|
||||
// A single entry from the defaults URL.
|
||||
struct DefaultEntry {
|
||||
nsCString mOrigin;
|
||||
DefaultEntry() : mOp(eImportMatchTypeHost), mPermission(0) {}
|
||||
|
||||
enum Op {
|
||||
eImportMatchTypeHost,
|
||||
eImportMatchTypeOrigin,
|
||||
};
|
||||
|
||||
Op mOp;
|
||||
|
||||
nsCString mHostOrOrigin;
|
||||
nsCString mType;
|
||||
uint32_t mPermission = 0;
|
||||
uint32_t mPermission;
|
||||
};
|
||||
|
||||
// List of entries read from the default settings.
|
||||
// This array is protected by the monitor.
|
||||
nsTArray<DefaultEntry> mDefaultEntriesForImport;
|
||||
// Adds a default permission entry to AddDefaultEntryForImport for given
|
||||
// origin, type and value
|
||||
void AddDefaultEntryForImport(const nsACString& aOrigin,
|
||||
const nsCString& aType, uint32_t aPermission,
|
||||
const MonitorAutoLock& aProofOfLock);
|
||||
// Given a default entry, import it as a default permission (id = -1) into the
|
||||
// permission manager without storing it to disk. If permission isolation for
|
||||
// private browsing is enabled (which is the default), and the permission type
|
||||
// is not exempt from it, this will also create a separate default permission
|
||||
// for private browsing
|
||||
nsresult ImportDefaultEntry(const DefaultEntry& aDefaultEntry);
|
||||
nsTArray<DefaultEntry> mDefaultEntries;
|
||||
|
||||
nsresult Read(const MonitorAutoLock& aProofOfLock);
|
||||
void CompleteRead();
|
||||
|
||||
void CompleteMigrations();
|
||||
|
||||
// Initialize service used for importing default permissions from remote
|
||||
// settings
|
||||
void InitRemotePermissionService();
|
||||
|
||||
bool mMemoryOnlyDB;
|
||||
|
||||
nsTHashtable<PermissionHashKey> mPermissionTable;
|
||||
|
@ -1,191 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
import { RemoteSettings } from "resource://services-settings/remote-settings.sys.mjs";
|
||||
|
||||
const COLLECTION_NAME = "remote-permissions";
|
||||
|
||||
/**
|
||||
* Allowlist of permission types and values allowed to be set through remote
|
||||
* settings. In this map, the key is the permission type, while the value is an
|
||||
* array of allowed permission values/capabilities allowed to be set. Possible
|
||||
* values for most permissions are:
|
||||
*
|
||||
* - Ci.nsIPermissionManager.ALLOW_ACTION
|
||||
* - Ci.nsIPermissionManager.DENY_ACTION
|
||||
* - Ci.nsIPermissionManager.PROMPT_ACTION
|
||||
* - "*" (Allows all values)
|
||||
*
|
||||
* Permission types with custom permission values (like
|
||||
* https-only-load-insecure) may include different values. Only change this
|
||||
* value with a review from #permissions-reviewers.
|
||||
*/
|
||||
const ALLOWED_PERMISSION_VALUES = {
|
||||
"https-only-load-insecure": [
|
||||
Ci.nsIHttpsOnlyModePermission.HTTPSFIRST_LOAD_INSECURE_ALLOW,
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* See nsIRemotePermissionService.idl
|
||||
*/
|
||||
export class RemotePermissionService {
|
||||
classId = Components.ID("{a4b1b3b1-b68a-4129-aa2f-eb086162a8c7}");
|
||||
QueryInterface = ChromeUtils.generateQI(["nsIRemotePermissionService"]);
|
||||
|
||||
#rs = RemoteSettings(COLLECTION_NAME);
|
||||
#onSyncCallback = null;
|
||||
#initialized = Promise.withResolvers();
|
||||
#allowedPermissionValues = ALLOWED_PERMISSION_VALUES;
|
||||
|
||||
/**
|
||||
* Asynchonously import all default permissions from remote settings into the
|
||||
* permission manager. Also, if not already done, set up remote settings event
|
||||
* listener to keep remote permissions in sync.
|
||||
*/
|
||||
async init() {
|
||||
try {
|
||||
if (Services.startup.shuttingDown) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
!Services.prefs.getBoolPref("permissions.manager.remote.enabled", false)
|
||||
) {
|
||||
throw Error(
|
||||
"Tried to initialize remote permission service despite being disabled by pref"
|
||||
);
|
||||
}
|
||||
|
||||
let remotePermissions = await this.#rs.get();
|
||||
for (const permission of remotePermissions) {
|
||||
this.#addDefaultPermission(permission);
|
||||
}
|
||||
|
||||
// Init could be called multiple times if the permission manager is
|
||||
// reinitializing itself due to "testonly-reload-permissions-from-disk"
|
||||
// being emitted. In that case, we don't shouldn't set up the RS listener
|
||||
// again. We may also land in that situtation when "profile-do-change" is
|
||||
// emitted.
|
||||
if (!this.#onSyncCallback) {
|
||||
this.#onSyncCallback = this.#onSync.bind(this);
|
||||
this.#rs.on("sync", this.#onSyncCallback);
|
||||
}
|
||||
|
||||
this.#initialized.resolve();
|
||||
} catch (e) {
|
||||
this.#initialized.reject(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
get isInitialized() {
|
||||
return this.#initialized.promise;
|
||||
}
|
||||
|
||||
get testAllowedPermissionValues() {
|
||||
return this.#allowedPermissionValues;
|
||||
}
|
||||
|
||||
set testAllowedPermissionValues(allowedPermissionValues) {
|
||||
Cu.crashIfNotInAutomation();
|
||||
this.#allowedPermissionValues = allowedPermissionValues;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line jsdoc/require-param
|
||||
/**
|
||||
* Callback for the "sync" event from remote settings. This function will
|
||||
* receive the created, updated and deleted permissions from remote settings,
|
||||
* and will update the permission manager accordingly.
|
||||
*/
|
||||
#onSync({ data: { created = [], updated = [], deleted = [] } }) {
|
||||
const toBeDeletedPermissions = [
|
||||
// Delete permissions that got deleted in remote settings.
|
||||
...deleted,
|
||||
// If an existing entry got updated in remote settings, but the origin or
|
||||
// type changed, we can not just update it, as permissions are identified
|
||||
// by origin and type in the permission manager. Instead, we need to
|
||||
// remove the old permission and add a new one.
|
||||
...updated
|
||||
.filter(
|
||||
({
|
||||
old: { origin: oldOrigin, type: oldType },
|
||||
new: { origin: newOrigin, type: newType },
|
||||
}) => oldOrigin != newOrigin || oldType != newType
|
||||
)
|
||||
.map(({ old }) => old),
|
||||
];
|
||||
|
||||
const toBeAddedPermissions = [
|
||||
// Add newly created permissions.
|
||||
...created,
|
||||
// "Add" permissions updated in remote settings (the permission manager
|
||||
// will automatically update the existing default permission instead of
|
||||
// creating a new one if the permission origin and type match).
|
||||
...updated.map(({ new: newPermission }) => newPermission),
|
||||
// Delete permissions by "adding" them with value UNKNOWN_ACTION.
|
||||
...toBeDeletedPermissions.map(({ origin, type }) => ({
|
||||
origin,
|
||||
type,
|
||||
capability: Ci.nsIPermissionManager.UNKNOWN_ACTION,
|
||||
})),
|
||||
];
|
||||
|
||||
for (const permission of toBeAddedPermissions) {
|
||||
this.#addDefaultPermission(permission);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a permission type and value is allowed to be set through remote
|
||||
* settings, based on the ALLOWED_PERMISSION_VALUES allowlist.
|
||||
*
|
||||
* @param {string} type Permission type to check
|
||||
* @param {string} capability Permission capability to check
|
||||
* @returns {boolean}
|
||||
*/
|
||||
#isAllowed(type, capability) {
|
||||
if (!this.#allowedPermissionValues[type]) {
|
||||
if (this.#allowedPermissionValues["*"]) {
|
||||
this.#allowedPermissionValues[type] =
|
||||
this.#allowedPermissionValues["*"];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
this.#allowedPermissionValues[type].includes("*") ||
|
||||
this.#allowedPermissionValues[type].includes(capability) ||
|
||||
capability === Ci.nsIPermissionManager.UNKNOWN_ACTION
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a default permission to the permission manager.
|
||||
*
|
||||
* @param {object} permission The permission to add
|
||||
* @param {string} permission.origin Origin string of the permission
|
||||
* @param {string} permission.type Type of the permission
|
||||
* @param {number} permission.capability Capability of the permission
|
||||
*/
|
||||
#addDefaultPermission({ origin, type, capability }) {
|
||||
if (!this.#isAllowed(type, capability)) {
|
||||
console.error(
|
||||
`Remote Settings contain default permission of disallowed type '${type}' with value '${capability}' for origin '${origin}', skipping import`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
let principal = Services.scriptSecurityManager.createContentPrincipal(
|
||||
Services.io.newURI(origin),
|
||||
{}
|
||||
);
|
||||
Services.perms.addDefaultFromPrincipal(principal, type, capability);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -22,12 +22,4 @@ Classes = [
|
||||
'type': 'PermissionDelegateHandler',
|
||||
'headers': ['/extensions/permissions/PermissionDelegateHandler.h'],
|
||||
},
|
||||
{
|
||||
'cid': '{a4b1b3b1-b68a-4129-aa2f-eb086162a8c7}',
|
||||
'contract_ids': ['@mozilla.org/remote-permission-service;1'],
|
||||
'esModule': 'resource://gre/modules/RemotePermissionService.sys.mjs',
|
||||
'constructor': 'RemotePermissionService',
|
||||
'singleton': True,
|
||||
'processes': ProcessSelector.MAIN_PROCESS_ONLY,
|
||||
},
|
||||
]
|
||||
|
@ -27,16 +27,6 @@ XPCOM_MANIFESTS += [
|
||||
"components.conf",
|
||||
]
|
||||
|
||||
XPIDL_MODULE = "permissions"
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
"nsIRemotePermissionService.idl",
|
||||
]
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
"RemotePermissionService.sys.mjs",
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
"/caps",
|
||||
]
|
||||
|
@ -1,41 +0,0 @@
|
||||
/* 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 "nsISupports.idl"
|
||||
|
||||
interface nsIPrincipal;
|
||||
|
||||
/**
|
||||
* Service to import default permissions from Remote Settings. Will be
|
||||
* initialized by permission manager after it itself has completed its
|
||||
* initialization, and will then import default permissions from Remote Settings
|
||||
* asynchronously. This also means default permissions aren't guranteed to be
|
||||
* available directly after startup.
|
||||
*/
|
||||
[scriptable, uuid(a4b1b3b1-b68a-4129-aa2f-eb086162a8c7)]
|
||||
interface nsIRemotePermissionService : nsISupports {
|
||||
/**
|
||||
* Asynchonously import all default permissions from remote settings into
|
||||
* the permission manager. Also, if not already done, set up remote settings
|
||||
* event listener to keep remote permissions in sync.
|
||||
*/
|
||||
void init();
|
||||
/**
|
||||
* Promise that is resolved when the remote permission service has been
|
||||
* fully initialized, meaning all intial permissions have been imported and
|
||||
* the remote settings sync event listener has been set up. If any errors
|
||||
* are encountered during inizialization, this promise will be rejected.
|
||||
*/
|
||||
readonly attribute Promise isInitialized;
|
||||
/**
|
||||
* Allowed permission types and values to be set through remote settings.
|
||||
* See RemotePermissionService.sys.mjs for further documentation. Exposed
|
||||
* only for testing purposes.
|
||||
*/
|
||||
attribute jsval testAllowedPermissionValues;
|
||||
};
|
||||
|
||||
%{C++
|
||||
#define NS_REMOTEPERMISSIONSERVICE_CONTRACTID "@mozilla.org/remote-permission-service;1"
|
||||
%}
|
@ -1,480 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
https://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
ChromeUtils.defineESModuleGetters(this, {
|
||||
RemoteSettings: "resource://services-settings/remote-settings.sys.mjs",
|
||||
});
|
||||
|
||||
const COLLECTION_NAME = "remote-permissions";
|
||||
const ORIGIN_1 = "https://example.com";
|
||||
const PRINCIPAL_1 = Services.scriptSecurityManager.createContentPrincipal(
|
||||
Services.io.newURI(ORIGIN_1),
|
||||
{}
|
||||
);
|
||||
const PRINCIPAL_1_PB = Services.scriptSecurityManager.createContentPrincipal(
|
||||
Services.io.newURI(ORIGIN_1),
|
||||
{ privateBrowsingId: 1 }
|
||||
);
|
||||
const ORIGIN_2 = "https://example.org";
|
||||
const PRINCIPAL_2 = Services.scriptSecurityManager.createContentPrincipal(
|
||||
Services.io.newURI(ORIGIN_2),
|
||||
{}
|
||||
);
|
||||
const PRINCIPAL_2_PB = Services.scriptSecurityManager.createContentPrincipal(
|
||||
Services.io.newURI(ORIGIN_2),
|
||||
{ privateBrowsingId: 1 }
|
||||
);
|
||||
const ORIGIN_INVALID = "not a valid origin";
|
||||
const TEST_PERMISSION_1 = "test-permission-1";
|
||||
const TEST_PERMISSION_2 = "test-permission-2";
|
||||
|
||||
let rs = RemoteSettings(COLLECTION_NAME);
|
||||
let pm = Services.perms;
|
||||
let rps = Cc["@mozilla.org/remote-permission-service;1"].getService(
|
||||
Ci.nsIRemotePermissionService
|
||||
);
|
||||
|
||||
async function remoteSettingsSync({ created, updated, deleted }) {
|
||||
await rs.emit("sync", {
|
||||
data: {
|
||||
created,
|
||||
updated,
|
||||
deleted,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function expectPermissions(perms) {
|
||||
Assert.deepEqual(
|
||||
pm.all
|
||||
.map(({ principal, type, capability }) => ({
|
||||
principal: principal.siteOrigin,
|
||||
type,
|
||||
capability,
|
||||
}))
|
||||
.sort((a, b) => a.principal.localeCompare(b.principal)),
|
||||
perms
|
||||
.map(({ principal, type, capability }) => ({
|
||||
principal: principal.siteOrigin,
|
||||
type,
|
||||
capability,
|
||||
}))
|
||||
.sort((a, b) => a.principal.localeCompare(b.principal)),
|
||||
"Permission manager should have expected permissions"
|
||||
);
|
||||
}
|
||||
|
||||
add_setup(async function () {
|
||||
do_get_profile();
|
||||
|
||||
// This needs to be restored on cleanup
|
||||
let originalPermissionValues = structuredClone(
|
||||
rps.testAllowedPermissionValues
|
||||
);
|
||||
|
||||
// Initialize remote permission service
|
||||
let permObserver = Services.perms.QueryInterface(Ci.nsIObserver);
|
||||
permObserver.observe(null, "profile-do-change", "");
|
||||
await rps.isInitialized;
|
||||
|
||||
registerCleanupFunction(async () => {
|
||||
info("Cleaning up");
|
||||
rps.testAllowedPermissionValues = originalPermissionValues;
|
||||
Services.prefs.clearUserPref("permissions.manager.defaultsUrl");
|
||||
Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
|
||||
Services.perms.removeAll();
|
||||
});
|
||||
|
||||
// Allow setting everything
|
||||
rps.testAllowedPermissionValues = {
|
||||
"*": ["*"],
|
||||
};
|
||||
});
|
||||
|
||||
add_task(async function test_create_permission() {
|
||||
info("Creating permission");
|
||||
|
||||
await remoteSettingsSync({
|
||||
created: [
|
||||
{
|
||||
origin: ORIGIN_1,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expectPermissions([
|
||||
{
|
||||
principal: PRINCIPAL_1,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
},
|
||||
{
|
||||
principal: PRINCIPAL_1_PB,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(async function test_update_permission_value() {
|
||||
info("Updating permission value");
|
||||
|
||||
await remoteSettingsSync({
|
||||
updated: [
|
||||
{
|
||||
old: {
|
||||
origin: ORIGIN_1,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
},
|
||||
new: {
|
||||
origin: ORIGIN_1,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expectPermissions([
|
||||
{
|
||||
principal: PRINCIPAL_1,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
||||
},
|
||||
{
|
||||
principal: PRINCIPAL_1_PB,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(async function test_update_permission_origin() {
|
||||
info("Updating permission origin");
|
||||
|
||||
await remoteSettingsSync({
|
||||
updated: [
|
||||
{
|
||||
old: {
|
||||
origin: ORIGIN_1,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
||||
},
|
||||
new: {
|
||||
origin: ORIGIN_2,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expectPermissions([
|
||||
{
|
||||
principal: PRINCIPAL_2,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
||||
},
|
||||
{
|
||||
principal: PRINCIPAL_2_PB,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(async function test_user_permission_restoration() {
|
||||
info("Overriding with user permission");
|
||||
|
||||
pm.addFromPrincipal(
|
||||
PRINCIPAL_2,
|
||||
TEST_PERMISSION_1,
|
||||
Ci.nsIPermissionManager.ALLOW_ACTION
|
||||
);
|
||||
|
||||
expectPermissions([
|
||||
{
|
||||
principal: PRINCIPAL_2,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
},
|
||||
{
|
||||
principal: PRINCIPAL_2_PB,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
||||
},
|
||||
]);
|
||||
|
||||
info("Removing user permission");
|
||||
|
||||
pm.removeFromPrincipal(PRINCIPAL_2, TEST_PERMISSION_1);
|
||||
|
||||
expectPermissions([
|
||||
{
|
||||
principal: PRINCIPAL_2,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
||||
},
|
||||
{
|
||||
principal: PRINCIPAL_2_PB,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(async function test_remove_all_restoration() {
|
||||
info("Overriding with user permission and adding new user permission");
|
||||
|
||||
pm.addFromPrincipal(
|
||||
PRINCIPAL_1,
|
||||
TEST_PERMISSION_1,
|
||||
Ci.nsIPermissionManager.ALLOW_ACTION
|
||||
);
|
||||
pm.addFromPrincipal(
|
||||
PRINCIPAL_2,
|
||||
TEST_PERMISSION_1,
|
||||
Ci.nsIPermissionManager.ALLOW_ACTION
|
||||
);
|
||||
|
||||
expectPermissions([
|
||||
{
|
||||
principal: PRINCIPAL_1,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
},
|
||||
{
|
||||
principal: PRINCIPAL_2,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
},
|
||||
{
|
||||
principal: PRINCIPAL_2_PB,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
||||
},
|
||||
]);
|
||||
|
||||
info("Removing all permissions");
|
||||
|
||||
pm.removeAll();
|
||||
|
||||
expectPermissions([
|
||||
{
|
||||
principal: PRINCIPAL_2,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
||||
},
|
||||
{
|
||||
principal: PRINCIPAL_2_PB,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(async function test_delete_permission() {
|
||||
info("Deleting permission");
|
||||
|
||||
await remoteSettingsSync({
|
||||
deleted: [
|
||||
{
|
||||
origin: ORIGIN_2,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expectPermissions([]);
|
||||
});
|
||||
|
||||
add_task(async function test_allowlist() {
|
||||
info("Only allowing TEST_PERMISSION_1 with value ALLOW_ACTION");
|
||||
|
||||
rps.testAllowedPermissionValues = {
|
||||
[TEST_PERMISSION_1]: [Ci.nsIPermissionManager.ALLOW_ACTION],
|
||||
};
|
||||
|
||||
info("Trying to add all sorts of default permissions");
|
||||
|
||||
await remoteSettingsSync({
|
||||
created: [ORIGIN_1, ORIGIN_2].flatMap(origin =>
|
||||
[TEST_PERMISSION_1, TEST_PERMISSION_2].flatMap(type =>
|
||||
[
|
||||
Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
Ci.nsIPermissionManager.DENY_ACTION,
|
||||
Ci.nsIPermissionManager.PROMPT_ACTION,
|
||||
].flatMap(capability => ({ origin, type, capability }))
|
||||
)
|
||||
),
|
||||
});
|
||||
|
||||
expectPermissions([
|
||||
{
|
||||
principal: PRINCIPAL_1,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
},
|
||||
{
|
||||
principal: PRINCIPAL_1_PB,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
},
|
||||
{
|
||||
principal: PRINCIPAL_2,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
},
|
||||
{
|
||||
principal: PRINCIPAL_2_PB,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
},
|
||||
]);
|
||||
|
||||
rps.testAllowedPermissionValues = {
|
||||
"*": ["*"],
|
||||
};
|
||||
});
|
||||
|
||||
add_task(async function test_defaults_url() {
|
||||
info("Testing interaction with permissions.manager.defaultsUrl");
|
||||
|
||||
info("Setting up permissions.manager.defaultsUrl");
|
||||
|
||||
let file = do_get_tempdir();
|
||||
file.append("test_default_permissions");
|
||||
let ostream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
|
||||
Ci.nsIFileOutputStream
|
||||
);
|
||||
ostream.init(file, -1, 0o666, 0);
|
||||
let conv = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(
|
||||
Ci.nsIConverterOutputStream
|
||||
);
|
||||
conv.init(ostream, "UTF-8");
|
||||
conv.writeString(
|
||||
[
|
||||
"host",
|
||||
TEST_PERMISSION_1,
|
||||
Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
ORIGIN_1,
|
||||
].join("\t") + "\n"
|
||||
);
|
||||
conv.writeString(
|
||||
[
|
||||
"host",
|
||||
TEST_PERMISSION_2,
|
||||
Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
ORIGIN_1,
|
||||
].join("\t") + "\n"
|
||||
);
|
||||
ostream.close();
|
||||
|
||||
Services.prefs.setCharPref(
|
||||
"permissions.manager.defaultsUrl",
|
||||
"file://" + file.path
|
||||
);
|
||||
|
||||
info("Re-initializing permission manager");
|
||||
|
||||
// Start from a clean slate with our new default permissions from
|
||||
// permissions.manager.defaultsUrl
|
||||
Services.obs.notifyObservers(null, "testonly-reload-permissions-from-disk");
|
||||
Services.perms.removeAll();
|
||||
|
||||
expectPermissions([
|
||||
{
|
||||
principal: PRINCIPAL_1,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
},
|
||||
{
|
||||
principal: PRINCIPAL_1_PB,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
},
|
||||
{
|
||||
principal: PRINCIPAL_1,
|
||||
type: TEST_PERMISSION_2,
|
||||
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
},
|
||||
{
|
||||
principal: PRINCIPAL_1_PB,
|
||||
type: TEST_PERMISSION_2,
|
||||
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
},
|
||||
]);
|
||||
|
||||
info("Overriding permissions from permissions.manager.defaultsUrl");
|
||||
|
||||
await remoteSettingsSync({
|
||||
created: [
|
||||
{
|
||||
origin: ORIGIN_1,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
||||
},
|
||||
{
|
||||
origin: ORIGIN_1,
|
||||
type: TEST_PERMISSION_2,
|
||||
capability: Ci.nsIPermissionManager.UNKNOWN_ACTION,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expectPermissions([
|
||||
{
|
||||
principal: PRINCIPAL_1,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
||||
},
|
||||
{
|
||||
principal: PRINCIPAL_1_PB,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.DENY_ACTION,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(async function test_malformed_origin() {
|
||||
info(
|
||||
"Testing that import will continue after encountering a malformed origin"
|
||||
);
|
||||
|
||||
await remoteSettingsSync({
|
||||
created: [
|
||||
{
|
||||
origin: ORIGIN_INVALID,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
},
|
||||
// TEST_PERMISSION_1 still exists for ORIGIN_1 from the previous step, but
|
||||
// for simplicity we act like it is new here. We will see if the value has
|
||||
// changed from deny to allow.
|
||||
{
|
||||
origin: ORIGIN_1,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expectPermissions([
|
||||
{
|
||||
principal: PRINCIPAL_1,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
},
|
||||
{
|
||||
principal: PRINCIPAL_1_PB,
|
||||
type: TEST_PERMISSION_1,
|
||||
capability: Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
},
|
||||
]);
|
||||
});
|
@ -77,8 +77,6 @@ skip-if = ["os == 'android'"] # Android doesn't use places
|
||||
|
||||
["test_permmanager_oa_strip.js"]
|
||||
|
||||
["test_permmanager_remote.js"]
|
||||
|
||||
["test_permmanager_removeAllExceptTypes.js"]
|
||||
|
||||
["test_permmanager_removeAllSinceWithTypeExceptions.js"]
|
||||
|
@ -14565,13 +14565,6 @@
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
# Whether default permissions should be imported from remote settings in
|
||||
# addition to importing them from browser/app/permissions.
|
||||
- name: permissions.manager.remote.enabled
|
||||
type: bool
|
||||
value: @IS_EARLY_BETA_OR_EARLIER@
|
||||
mirror: always
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Prefs starting with "places."
|
||||
#---------------------------------------------------------------------------
|
||||
|
@ -155,20 +155,6 @@ interface nsIPermissionManager : nsISupports
|
||||
in ACString type,
|
||||
in uint32_t permission);
|
||||
|
||||
/**
|
||||
* Add temporary default permission information for a given principal.
|
||||
* This permission will be cleared at the end of the session, will not be
|
||||
* stored on disk, and will not be set if a conflicting (non-default)
|
||||
* permission already exists.
|
||||
*
|
||||
* This function shouldn't be used by regular permission manager consumers and
|
||||
* is only expected to be called by the RemotePermissionService.sys.mjs for
|
||||
* the purpose of importing default permissions from remote settings.
|
||||
*/
|
||||
void addDefaultFromPrincipal(in nsIPrincipal principal,
|
||||
in ACString type,
|
||||
in uint32_t permission);
|
||||
|
||||
/**
|
||||
* Remove permission information for a given principal.
|
||||
* This is internally calling remove() with the host from the principal's URI.
|
||||
|
@ -1,4 +0,0 @@
|
||||
{
|
||||
"data": [],
|
||||
"timestamp": 1730278443662
|
||||
}
|
Loading…
Reference in New Issue
Block a user