mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1058433 - nsPermissionManager now records the mod-time of a permission and allows removal of ones modified since a specified time. r=ehsan
This commit is contained in:
parent
d37d2ef50a
commit
f9a0630114
@ -303,7 +303,7 @@ class Automation(object):
|
||||
permDB = sqlite3.connect(os.path.join(profileDir, "permissions.sqlite"))
|
||||
cursor = permDB.cursor();
|
||||
|
||||
cursor.execute("PRAGMA user_version=3");
|
||||
cursor.execute("PRAGMA user_version=4");
|
||||
|
||||
# SQL copied from nsPermissionManager.cpp
|
||||
cursor.execute("""CREATE TABLE IF NOT EXISTS moz_hosts (
|
||||
@ -313,13 +313,14 @@ class Automation(object):
|
||||
permission INTEGER,
|
||||
expireType INTEGER,
|
||||
expireTime INTEGER,
|
||||
modificationTime INTEGER,
|
||||
appId INTEGER,
|
||||
isInBrowserElement INTEGER)""")
|
||||
|
||||
# Insert desired permissions
|
||||
for perm in permissions.keys():
|
||||
for host,allow in permissions[perm]:
|
||||
cursor.execute("INSERT INTO moz_hosts values(NULL, ?, ?, ?, 0, 0, 0, 0)",
|
||||
cursor.execute("INSERT INTO moz_hosts values(NULL, ?, ?, ?, 0, 0, 0, 0, 0)",
|
||||
(host, perm, 1 if allow else 2))
|
||||
|
||||
# Commit and close
|
||||
|
@ -1714,12 +1714,16 @@ ContentChild::RecvAddPermission(const IPC::Permission& permission)
|
||||
getter_AddRefs(principal));
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
|
||||
// child processes don't care about modification time.
|
||||
int64_t modificationTime = 0;
|
||||
|
||||
permissionManager->AddInternal(principal,
|
||||
nsCString(permission.type),
|
||||
permission.capability,
|
||||
0,
|
||||
permission.expireType,
|
||||
permission.expireTime,
|
||||
modificationTime,
|
||||
nsPermissionManager::eNotify,
|
||||
nsPermissionManager::eNoDBOperation);
|
||||
#endif
|
||||
|
@ -357,7 +357,7 @@ nsPermissionManager::AppClearDataObserverInit()
|
||||
// nsPermissionManager Implementation
|
||||
|
||||
static const char kPermissionsFileName[] = "permissions.sqlite";
|
||||
#define HOSTS_SCHEMA_VERSION 3
|
||||
#define HOSTS_SCHEMA_VERSION 4
|
||||
|
||||
static const char kHostpermFileName[] = "hostperm.1";
|
||||
|
||||
@ -432,8 +432,12 @@ nsPermissionManager::Init()
|
||||
rv = GetPrincipal(perm.host, perm.appId, perm.isInBrowserElement, getter_AddRefs(principal));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// The child process doesn't care about modification times - it neither
|
||||
// reads nor writes, nor removes them based on the date - so 0 (which
|
||||
// will end up as now()) is fine.
|
||||
uint64_t modificationTime = 0;
|
||||
AddInternal(principal, perm.type, perm.capability, 0, perm.expireType,
|
||||
perm.expireTime, eNotify, eNoDBOperation);
|
||||
perm.expireTime, modificationTime, eNotify, eNoDBOperation);
|
||||
}
|
||||
|
||||
// Stop here; we don't need the DB in the child process
|
||||
@ -546,6 +550,23 @@ nsPermissionManager::InitDB(bool aRemoveFile)
|
||||
|
||||
// fall through to the next upgrade
|
||||
|
||||
// Version 3->4 is the creation of the modificationTime field.
|
||||
case 3:
|
||||
{
|
||||
rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"ALTER TABLE moz_hosts ADD modificationTime INTEGER"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// We leave the modificationTime at zero for all existing records; using
|
||||
// now() would mean, eg, that doing "remove all from the last hour"
|
||||
// within the first hour after migration would remove all permissions.
|
||||
|
||||
rv = mDBConn->SetSchemaVersion(HOSTS_SCHEMA_VERSION);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// fall through to the next upgrade
|
||||
|
||||
// current version.
|
||||
case HOSTS_SCHEMA_VERSION:
|
||||
break;
|
||||
@ -561,7 +582,7 @@ nsPermissionManager::InitDB(bool aRemoveFile)
|
||||
// check if all the expected columns exist
|
||||
nsCOMPtr<mozIStorageStatement> stmt;
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT host, type, permission, expireType, expireTime, appId, isInBrowserElement FROM moz_hosts"),
|
||||
"SELECT host, type, permission, expireType, expireTime, modificationTime, appId, isInBrowserElement FROM moz_hosts"),
|
||||
getter_AddRefs(stmt));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
break;
|
||||
@ -583,8 +604,8 @@ nsPermissionManager::InitDB(bool aRemoveFile)
|
||||
// cache frequently used statements (for insertion, deletion, and updating)
|
||||
rv = mDBConn->CreateAsyncStatement(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO moz_hosts "
|
||||
"(id, host, type, permission, expireType, expireTime, appId, isInBrowserElement) "
|
||||
"VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)"), getter_AddRefs(mStmtInsert));
|
||||
"(id, host, type, permission, expireType, expireTime, modificationTime, appId, isInBrowserElement) "
|
||||
"VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9)"), getter_AddRefs(mStmtInsert));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDBConn->CreateAsyncStatement(NS_LITERAL_CSTRING(
|
||||
@ -594,7 +615,7 @@ nsPermissionManager::InitDB(bool aRemoveFile)
|
||||
|
||||
rv = mDBConn->CreateAsyncStatement(NS_LITERAL_CSTRING(
|
||||
"UPDATE moz_hosts "
|
||||
"SET permission = ?2, expireType= ?3, expireTime = ?4 WHERE id = ?1"),
|
||||
"SET permission = ?2, expireType= ?3, expireTime = ?4, modificationTime = ?5 WHERE id = ?1"),
|
||||
getter_AddRefs(mStmtUpdate));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@ -626,6 +647,7 @@ nsPermissionManager::CreateTable()
|
||||
",permission INTEGER"
|
||||
",expireType INTEGER"
|
||||
",expireTime INTEGER"
|
||||
",modificationTime INTEGER"
|
||||
",appId INTEGER"
|
||||
",isInBrowserElement INTEGER"
|
||||
")"));
|
||||
@ -679,8 +701,11 @@ nsPermissionManager::AddFromPrincipal(nsIPrincipal* aPrincipal,
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// A modificationTime of zero will cause AddInternal to use now().
|
||||
int64_t modificationTime = 0;
|
||||
|
||||
return AddInternal(aPrincipal, nsDependentCString(aType), aPermission, 0,
|
||||
aExpireType, aExpireTime, eNotify, eWriteToDB);
|
||||
aExpireType, aExpireTime, modificationTime, eNotify, eWriteToDB);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -690,6 +715,7 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
|
||||
int64_t aID,
|
||||
uint32_t aExpireType,
|
||||
int64_t aExpireTime,
|
||||
int64_t aModificationTime,
|
||||
NotifyOperationType aNotifyOperation,
|
||||
DBOperationType aDBOperation)
|
||||
{
|
||||
@ -760,15 +786,27 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
|
||||
// even if the new permission is UNKNOWN_ACTION (which means a "logical
|
||||
// remove" of the default)
|
||||
op = eOperationReplacingDefault;
|
||||
else if (aID == cIDPermissionIsDefault)
|
||||
// We are adding a default permission but a "real" permission already
|
||||
// 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)
|
||||
op = eOperationRemoving;
|
||||
else
|
||||
op = eOperationChanging;
|
||||
}
|
||||
|
||||
// child processes should *always* be passed a modificationTime of zero.
|
||||
MOZ_ASSERT(!IsChildProcess() || aModificationTime == 0);
|
||||
|
||||
// do the work for adding, deleting, or changing a permission:
|
||||
// update the in-memory list, write to the db, and notify consumers.
|
||||
int64_t id;
|
||||
if (aModificationTime == 0) {
|
||||
aModificationTime = PR_Now() / 1000;
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case eOperationNone:
|
||||
{
|
||||
@ -786,7 +824,9 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
|
||||
id = aID;
|
||||
}
|
||||
|
||||
entry->GetPermissions().AppendElement(PermissionEntry(id, typeIndex, aPermission, aExpireType, aExpireTime));
|
||||
entry->GetPermissions().AppendElement(PermissionEntry(id, typeIndex, aPermission,
|
||||
aExpireType, aExpireTime,
|
||||
aModificationTime));
|
||||
|
||||
if (aDBOperation == eWriteToDB && aExpireType != nsIPermissionManager::EXPIRE_SESSION) {
|
||||
uint32_t appId;
|
||||
@ -797,7 +837,7 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
|
||||
rv = aPrincipal->GetIsInBrowserElement(&isInBrowserElement);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
UpdateDB(op, mStmtInsert, id, host, aType, aPermission, aExpireType, aExpireTime, appId, isInBrowserElement);
|
||||
UpdateDB(op, mStmtInsert, id, host, aType, aPermission, aExpireType, aExpireTime, aModificationTime, appId, isInBrowserElement);
|
||||
}
|
||||
|
||||
if (aNotifyOperation == eNotify) {
|
||||
@ -824,7 +864,7 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
|
||||
// We care only about the id here so we pass dummy values for all other
|
||||
// parameters.
|
||||
UpdateDB(op, mStmtDelete, id, EmptyCString(), EmptyCString(), 0,
|
||||
nsIPermissionManager::EXPIRE_NEVER, 0, 0, false);
|
||||
nsIPermissionManager::EXPIRE_NEVER, 0, 0, 0, false);
|
||||
|
||||
if (aNotifyOperation == eNotify) {
|
||||
NotifyObserversWithPermission(host,
|
||||
@ -866,12 +906,13 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
|
||||
entry->GetPermissions()[index].mPermission = aPermission;
|
||||
entry->GetPermissions()[index].mExpireType = aExpireType;
|
||||
entry->GetPermissions()[index].mExpireTime = aExpireTime;
|
||||
entry->GetPermissions()[index].mModificationTime = aModificationTime;
|
||||
|
||||
if (aDBOperation == eWriteToDB && aExpireType != nsIPermissionManager::EXPIRE_SESSION)
|
||||
// We care only about the id, the permission and expireType/expireTime here.
|
||||
// We care only about the id, the permission and expireType/expireTime/modificationTime here.
|
||||
// We pass dummy values for all other parameters.
|
||||
UpdateDB(op, mStmtUpdate, id, EmptyCString(), EmptyCString(),
|
||||
aPermission, aExpireType, aExpireTime, 0, false);
|
||||
aPermission, aExpireType, aExpireTime, aModificationTime, 0, false);
|
||||
|
||||
if (aNotifyOperation == eNotify) {
|
||||
NotifyObserversWithPermission(host,
|
||||
@ -915,6 +956,7 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
|
||||
entry->GetPermissions()[index].mPermission = aPermission;
|
||||
entry->GetPermissions()[index].mExpireType = aExpireType;
|
||||
entry->GetPermissions()[index].mExpireTime = aExpireTime;
|
||||
entry->GetPermissions()[index].mModificationTime = aModificationTime;
|
||||
|
||||
// If requested, create the entry in the DB.
|
||||
if (aDBOperation == eWriteToDB) {
|
||||
@ -926,7 +968,8 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
|
||||
rv = aPrincipal->GetIsInBrowserElement(&isInBrowserElement);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
UpdateDB(eOperationAdding, mStmtInsert, id, host, aType, aPermission, aExpireType, aExpireTime, appId, isInBrowserElement);
|
||||
UpdateDB(eOperationAdding, mStmtInsert, id, host, aType, aPermission,
|
||||
aExpireType, aExpireTime, aModificationTime, appId, isInBrowserElement);
|
||||
}
|
||||
|
||||
if (aNotifyOperation == eNotify) {
|
||||
@ -983,6 +1026,7 @@ nsPermissionManager::RemoveFromPrincipal(nsIPrincipal* aPrincipal,
|
||||
0,
|
||||
nsIPermissionManager::EXPIRE_NEVER,
|
||||
0,
|
||||
0,
|
||||
eNotify,
|
||||
eWriteToDB);
|
||||
}
|
||||
@ -994,6 +1038,13 @@ nsPermissionManager::RemoveAll()
|
||||
return RemoveAllInternal(true);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPermissionManager::RemoveAllSince(int64_t aSince)
|
||||
{
|
||||
ENSURE_NOT_CHILD_PROCESS;
|
||||
return RemoveAllModifiedSince(aSince);
|
||||
}
|
||||
|
||||
void
|
||||
nsPermissionManager::CloseDB(bool aRebuildOnSuccess)
|
||||
{
|
||||
@ -1323,12 +1374,16 @@ nsPermissionManager::GetPermissionHashKey(const nsACString& aHost,
|
||||
// helper struct for passing arguments into hash enumeration callback.
|
||||
struct nsGetEnumeratorData
|
||||
{
|
||||
nsGetEnumeratorData(nsCOMArray<nsIPermission> *aArray, const nsTArray<nsCString> *aTypes)
|
||||
nsGetEnumeratorData(nsCOMArray<nsIPermission> *aArray,
|
||||
const nsTArray<nsCString> *aTypes,
|
||||
int64_t aSince = 0)
|
||||
: array(aArray)
|
||||
, types(aTypes) {}
|
||||
, types(aTypes)
|
||||
, since(aSince) {}
|
||||
|
||||
nsCOMArray<nsIPermission> *array;
|
||||
const nsTArray<nsCString> *types;
|
||||
int64_t since;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
@ -1395,6 +1450,76 @@ NS_IMETHODIMP nsPermissionManager::Observe(nsISupports *aSubject, const char *aT
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
AddPermissionsModifiedSinceToList(
|
||||
nsPermissionManager::PermissionHashKey* entry, void* arg)
|
||||
{
|
||||
nsGetEnumeratorData* data = static_cast<nsGetEnumeratorData *>(arg);
|
||||
|
||||
for (size_t i = 0; i < entry->GetPermissions().Length(); ++i) {
|
||||
const nsPermissionManager::PermissionEntry& permEntry = entry->GetPermissions()[i];
|
||||
|
||||
if (data->since > permEntry.mModificationTime) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsPermission* perm = new nsPermission(entry->GetKey()->mHost,
|
||||
entry->GetKey()->mAppId,
|
||||
entry->GetKey()->mIsInBrowserElement,
|
||||
data->types->ElementAt(permEntry.mType),
|
||||
permEntry.mPermission,
|
||||
permEntry.mExpireType,
|
||||
permEntry.mExpireTime);
|
||||
|
||||
data->array->AppendObject(perm);
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPermissionManager::RemoveAllModifiedSince(int64_t aModificationTime)
|
||||
{
|
||||
ENSURE_NOT_CHILD_PROCESS;
|
||||
|
||||
// roll an nsCOMArray of all our permissions, then hand out an enumerator
|
||||
nsCOMArray<nsIPermission> array;
|
||||
nsGetEnumeratorData data(&array, &mTypeArray, aModificationTime);
|
||||
|
||||
mPermissionTable.EnumerateEntries(AddPermissionsModifiedSinceToList, &data);
|
||||
|
||||
for (int32_t i = 0; i<array.Count(); ++i) {
|
||||
nsAutoCString host;
|
||||
bool isInBrowserElement = false;
|
||||
nsAutoCString type;
|
||||
uint32_t appId = 0;
|
||||
|
||||
array[i]->GetHost(host);
|
||||
array[i]->GetIsInBrowserElement(&isInBrowserElement);
|
||||
array[i]->GetType(type);
|
||||
array[i]->GetAppId(&appId);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
if (NS_FAILED(GetPrincipal(host, appId, isInBrowserElement,
|
||||
getter_AddRefs(principal)))) {
|
||||
NS_ERROR("GetPrincipal() failed!");
|
||||
continue;
|
||||
}
|
||||
// AddInternal handles removal, so let it do the work...
|
||||
AddInternal(
|
||||
principal,
|
||||
type,
|
||||
nsIPermissionManager::UNKNOWN_ACTION,
|
||||
0,
|
||||
nsIPermissionManager::EXPIRE_NEVER, 0, 0,
|
||||
nsPermissionManager::eNotify,
|
||||
nsPermissionManager::eWriteToDB);
|
||||
}
|
||||
// now re-import any defaults as they may now be required if we just deleted
|
||||
// an override.
|
||||
ImportDefaults();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
nsPermissionManager::GetPermissionsForApp(nsPermissionManager::PermissionHashKey* entry, void* arg)
|
||||
{
|
||||
@ -1475,6 +1600,7 @@ nsPermissionManager::RemovePermissionsForApp(uint32_t aAppId, bool aBrowserOnly)
|
||||
0,
|
||||
nsIPermissionManager::EXPIRE_NEVER,
|
||||
0,
|
||||
0,
|
||||
nsPermissionManager::eNotify,
|
||||
nsPermissionManager::eNoDBOperation);
|
||||
}
|
||||
@ -1646,7 +1772,7 @@ nsPermissionManager::Read()
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> stmt;
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT id, host, type, permission, expireType, expireTime, appId, isInBrowserElement "
|
||||
"SELECT id, host, type, permission, expireType, expireTime, modificationTime, appId, isInBrowserElement "
|
||||
"FROM moz_hosts"), getter_AddRefs(stmt));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@ -1655,6 +1781,7 @@ nsPermissionManager::Read()
|
||||
uint32_t permission;
|
||||
uint32_t expireType;
|
||||
int64_t expireTime;
|
||||
int64_t modificationTime;
|
||||
uint32_t appId;
|
||||
bool isInBrowserElement;
|
||||
bool hasResult;
|
||||
@ -1682,15 +1809,17 @@ nsPermissionManager::Read()
|
||||
permission = stmt->AsInt32(3);
|
||||
expireType = stmt->AsInt32(4);
|
||||
|
||||
// convert into int64_t value (milliseconds)
|
||||
// convert into int64_t values (milliseconds)
|
||||
expireTime = stmt->AsInt64(5);
|
||||
modificationTime = stmt->AsInt64(6);
|
||||
|
||||
if (stmt->AsInt64(6) < 0) {
|
||||
if (stmt->AsInt64(7) < 0) {
|
||||
readError = true;
|
||||
continue;
|
||||
}
|
||||
appId = static_cast<uint32_t>(stmt->AsInt64(6));
|
||||
isInBrowserElement = static_cast<bool>(stmt->AsInt32(7));
|
||||
|
||||
appId = static_cast<uint32_t>(stmt->AsInt64(7));
|
||||
isInBrowserElement = static_cast<bool>(stmt->AsInt32(8));
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsresult rv = GetPrincipal(host, appId, isInBrowserElement, getter_AddRefs(principal));
|
||||
@ -1700,7 +1829,7 @@ nsPermissionManager::Read()
|
||||
}
|
||||
|
||||
rv = AddInternal(principal, type, permission, id, expireType, expireTime,
|
||||
eDontNotify, eNoDBOperation);
|
||||
modificationTime, eDontNotify, eNoDBOperation);
|
||||
if (NS_FAILED(rv)) {
|
||||
readError = true;
|
||||
continue;
|
||||
@ -1848,8 +1977,14 @@ nsPermissionManager::_DoImport(nsIInputStream *inputStream, mozIStorageConnectio
|
||||
nsresult rv = GetPrincipal(lineArray[3], getter_AddRefs(principal));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// 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, lineArray[1], permission, id,
|
||||
nsIPermissionManager::EXPIRE_NEVER, 0, eDontNotify, operation);
|
||||
nsIPermissionManager::EXPIRE_NEVER, 0,
|
||||
modificationTime,
|
||||
eDontNotify, operation);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
@ -1880,6 +2015,7 @@ nsPermissionManager::UpdateDB(OperationType aOp,
|
||||
uint32_t aPermission,
|
||||
uint32_t aExpireType,
|
||||
int64_t aExpireTime,
|
||||
int64_t aModificationTime,
|
||||
uint32_t aAppId,
|
||||
bool aIsInBrowserElement)
|
||||
{
|
||||
@ -1912,10 +2048,13 @@ nsPermissionManager::UpdateDB(OperationType aOp,
|
||||
rv = aStmt->BindInt64ByIndex(5, aExpireTime);
|
||||
if (NS_FAILED(rv)) break;
|
||||
|
||||
rv = aStmt->BindInt64ByIndex(6, aAppId);
|
||||
rv = aStmt->BindInt64ByIndex(6, aModificationTime);
|
||||
if (NS_FAILED(rv)) break;
|
||||
|
||||
rv = aStmt->BindInt64ByIndex(7, aIsInBrowserElement);
|
||||
rv = aStmt->BindInt64ByIndex(7, aAppId);
|
||||
if (NS_FAILED(rv)) break;
|
||||
|
||||
rv = aStmt->BindInt64ByIndex(8, aIsInBrowserElement);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1937,6 +2076,9 @@ nsPermissionManager::UpdateDB(OperationType aOp,
|
||||
if (NS_FAILED(rv)) break;
|
||||
|
||||
rv = aStmt->BindInt64ByIndex(3, aExpireTime);
|
||||
if (NS_FAILED(rv)) break;
|
||||
|
||||
rv = aStmt->BindInt64ByIndex(4, aModificationTime);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -37,12 +37,14 @@ public:
|
||||
{
|
||||
public:
|
||||
PermissionEntry(int64_t aID, uint32_t aType, uint32_t aPermission,
|
||||
uint32_t aExpireType, int64_t aExpireTime)
|
||||
uint32_t aExpireType, int64_t aExpireTime,
|
||||
int64_t aModificationTime)
|
||||
: mID(aID)
|
||||
, mType(aType)
|
||||
, mPermission(aPermission)
|
||||
, mExpireType(aExpireType)
|
||||
, mExpireTime(aExpireTime)
|
||||
, mModificationTime(aModificationTime)
|
||||
, mNonSessionPermission(aPermission)
|
||||
, mNonSessionExpireType(aExpireType)
|
||||
, mNonSessionExpireTime(aExpireTime)
|
||||
@ -53,6 +55,7 @@ public:
|
||||
uint32_t mPermission;
|
||||
uint32_t mExpireType;
|
||||
int64_t mExpireTime;
|
||||
int64_t mModificationTime;
|
||||
uint32_t mNonSessionPermission;
|
||||
uint32_t mNonSessionExpireType;
|
||||
uint32_t mNonSessionExpireTime;
|
||||
@ -154,7 +157,7 @@ public:
|
||||
|
||||
// unknown permission... return relevant data
|
||||
return PermissionEntry(-1, aType, nsIPermissionManager::UNKNOWN_ACTION,
|
||||
nsIPermissionManager::EXPIRE_NEVER, 0);
|
||||
nsIPermissionManager::EXPIRE_NEVER, 0, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -200,6 +203,7 @@ public:
|
||||
int64_t aID,
|
||||
uint32_t aExpireType,
|
||||
int64_t aExpireTime,
|
||||
int64_t aModificationTime,
|
||||
NotifyOperationType aNotifyOperation,
|
||||
DBOperationType aDBOperation);
|
||||
|
||||
@ -260,6 +264,7 @@ private:
|
||||
uint32_t aPermission,
|
||||
uint32_t aExpireType,
|
||||
int64_t aExpireTime,
|
||||
int64_t aModificationTime,
|
||||
uint32_t aAppId,
|
||||
bool aIsInBrowserElement);
|
||||
|
||||
@ -299,6 +304,13 @@ private:
|
||||
RemoveExpiredPermissionsForAppEnumerator(PermissionHashKey* entry,
|
||||
void* nonused);
|
||||
|
||||
|
||||
/**
|
||||
* This method removes all permissions modified after the specified time.
|
||||
*/
|
||||
nsresult
|
||||
RemoveAllModifiedSince(int64_t aModificationTime);
|
||||
|
||||
nsCOMPtr<nsIObserverService> mObserverService;
|
||||
nsCOMPtr<nsIIDNService> mIDNService;
|
||||
|
||||
|
@ -3,8 +3,15 @@
|
||||
|
||||
// The origin we use in most of the tests.
|
||||
const TEST_ORIGIN = "example.org";
|
||||
const TEST_ORIGIN_2 = "example.com";
|
||||
const TEST_PERMISSION = "test-permission";
|
||||
|
||||
function promiseTimeout(delay) {
|
||||
let deferred = Promise.defer();
|
||||
do_timeout(delay, deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
@ -28,6 +35,7 @@ add_task(function* do_test() {
|
||||
conv.writeString("# this is a comment\n");
|
||||
conv.writeString("\n"); // a blank line!
|
||||
conv.writeString("host\t" + TEST_PERMISSION + "\t1\t" + TEST_ORIGIN + "\n");
|
||||
conv.writeString("host\t" + TEST_PERMISSION + "\t1\t" + TEST_ORIGIN_2 + "\n");
|
||||
ostream.close();
|
||||
|
||||
// Set the preference used by the permission manager so the file is read.
|
||||
@ -92,6 +100,47 @@ add_task(function* do_test() {
|
||||
do_check_eq(Ci.nsIPermissionManager.PROMPT_ACTION, findCapabilityViaEnum());
|
||||
yield checkCapabilityViaDB(Ci.nsIPermissionManager.PROMPT_ACTION);
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// check default permissions and removeAllSince work as expected.
|
||||
pm.removeAll(); // ensure only defaults are there.
|
||||
|
||||
let permURI2 = NetUtil.newURI("http://" + TEST_ORIGIN_2);
|
||||
let principal2 = Services.scriptSecurityManager.getNoAppCodebasePrincipal(permURI2);
|
||||
|
||||
// default for both principals is allow.
|
||||
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
pm.testPermissionFromPrincipal(principal, TEST_PERMISSION));
|
||||
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
pm.testPermissionFromPrincipal(principal2, TEST_PERMISSION));
|
||||
|
||||
// Add a default override for TEST_ORIGIN_2 - this one should *not* be
|
||||
// restored in removeAllSince()
|
||||
pm.addFromPrincipal(principal2, TEST_PERMISSION, Ci.nsIPermissionManager.DENY_ACTION);
|
||||
do_check_eq(Ci.nsIPermissionManager.DENY_ACTION,
|
||||
pm.testPermissionFromPrincipal(principal2, TEST_PERMISSION));
|
||||
yield promiseTimeout(20);
|
||||
|
||||
let since = Number(Date.now());
|
||||
yield promiseTimeout(20);
|
||||
|
||||
// explicitly add a permission which overrides the default for the first
|
||||
// principal - this one *should* be removed by removeAllSince.
|
||||
pm.addFromPrincipal(principal, TEST_PERMISSION, Ci.nsIPermissionManager.DENY_ACTION);
|
||||
do_check_eq(Ci.nsIPermissionManager.DENY_ACTION,
|
||||
pm.testPermissionFromPrincipal(principal, TEST_PERMISSION));
|
||||
|
||||
// do a removeAllSince.
|
||||
pm.removeAllSince(since);
|
||||
|
||||
// the default for the first principal should re-appear as we modified it
|
||||
// later then |since|
|
||||
do_check_eq(Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||
pm.testPermissionFromPrincipal(principal, TEST_PERMISSION));
|
||||
|
||||
// but the permission for principal2 should remain as we added that before |since|.
|
||||
do_check_eq(Ci.nsIPermissionManager.DENY_ACTION,
|
||||
pm.testPermissionFromPrincipal(principal2, TEST_PERMISSION));
|
||||
|
||||
// remove the temp file we created.
|
||||
file.remove(false);
|
||||
});
|
||||
|
@ -113,13 +113,25 @@ function run_test() {
|
||||
);
|
||||
}
|
||||
|
||||
let earliestNow = Number(Date.now());
|
||||
// Initialize the permission manager service
|
||||
var pm = Cc["@mozilla.org/permissionmanager;1"]
|
||||
.getService(Ci.nsIPermissionManager);
|
||||
let latestNow = Number(Date.now());
|
||||
|
||||
// The schema should still be 3. We want this test to be updated for each
|
||||
// schema update.
|
||||
do_check_eq(connection.schemaVersion, 3);
|
||||
// The schema should be upgraded to 4, and a 'modificationTime' column should
|
||||
// exist with all records having a value of 0.
|
||||
do_check_eq(connection.schemaVersion, 4);
|
||||
|
||||
let select = connection.createStatement("SELECT modificationTime FROM moz_hosts")
|
||||
let numMigrated = 0;
|
||||
while (select.executeStep()) {
|
||||
let thisModTime = select.getInt64(0);
|
||||
do_check_true(thisModTime == 0, "new modifiedTime field is correct");
|
||||
numMigrated += 1;
|
||||
}
|
||||
// check we found at least 1 record that was migrated.
|
||||
do_check_true(numMigrated > 0, "we found at least 1 record that was migrated");
|
||||
|
||||
// This permission should always be there.
|
||||
let principal = Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
|
69
extensions/cookie/test/unit/test_permmanager_removesince.js
Normal file
69
extensions/cookie/test/unit/test_permmanager_removesince.js
Normal file
@ -0,0 +1,69 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that removing permissions since a specified time behaves as expected.
|
||||
|
||||
let test_generator = do_run_test();
|
||||
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
test_generator.next();
|
||||
}
|
||||
|
||||
function continue_test()
|
||||
{
|
||||
do_run_generator(test_generator);
|
||||
}
|
||||
|
||||
function do_run_test() {
|
||||
// Set up a profile.
|
||||
let profile = do_get_profile();
|
||||
|
||||
let pm = Services.perms;
|
||||
|
||||
// to help with testing edge-cases, we will arrange for .removeAllSince to
|
||||
// remove *all* permissions from one principal and one permission from another.
|
||||
let permURI1 = NetUtil.newURI("http://example.com");
|
||||
let principal1 = Services.scriptSecurityManager.getNoAppCodebasePrincipal(permURI1);
|
||||
|
||||
let permURI2 = NetUtil.newURI("http://example.org");
|
||||
let principal2 = Services.scriptSecurityManager.getNoAppCodebasePrincipal(permURI2);
|
||||
|
||||
// add a permission now - this isn't going to be removed.
|
||||
pm.addFromPrincipal(principal1, "test/remove-since", 1);
|
||||
|
||||
// sleep briefly, then record the time - we'll remove all since then.
|
||||
do_timeout(20, continue_test);
|
||||
yield;
|
||||
|
||||
let since = Number(Date.now());
|
||||
|
||||
// *sob* - on Windows at least, the now recorded by nsPermissionManager.cpp
|
||||
// might be a couple of ms *earlier* than what JS sees. So another sleep
|
||||
// to ensure our |since| is greater than the time of the permissions we
|
||||
// are now adding. Sadly this means we'll never be able to test when since
|
||||
// exactly equals the modTime, but there you go...
|
||||
do_timeout(20, continue_test);
|
||||
yield;
|
||||
|
||||
// add another item - this second one should get nuked.
|
||||
pm.addFromPrincipal(principal1, "test/remove-since-2", 1);
|
||||
|
||||
// add 2 items for the second principal - both will be removed.
|
||||
pm.addFromPrincipal(principal2, "test/remove-since", 1);
|
||||
pm.addFromPrincipal(principal2, "test/remove-since-2", 1);
|
||||
|
||||
// do the removal.
|
||||
pm.removeAllSince(since);
|
||||
|
||||
// principal1 - the first one should remain.
|
||||
do_check_eq(1, pm.testPermissionFromPrincipal(principal1, "test/remove-since"));
|
||||
// but the second should have been removed.
|
||||
do_check_eq(0, pm.testPermissionFromPrincipal(principal1, "test/remove-since-2"));
|
||||
|
||||
// principal2 - both should have been removed.
|
||||
do_check_eq(0, pm.testPermissionFromPrincipal(principal2, "test/remove-since"));
|
||||
do_check_eq(0, pm.testPermissionFromPrincipal(principal2, "test/remove-since-2"));
|
||||
|
||||
do_finish_generator_test(test_generator);
|
||||
}
|
@ -23,6 +23,7 @@ support-files =
|
||||
[test_permmanager_getPermissionObject.js]
|
||||
[test_permmanager_notifications.js]
|
||||
[test_permmanager_removeall.js]
|
||||
[test_permmanager_removesince.js]
|
||||
[test_permmanager_load_invalid_entries.js]
|
||||
skip-if = debug == true
|
||||
[test_permmanager_idn.js]
|
||||
|
@ -37,7 +37,7 @@ interface nsIDOMWindow;
|
||||
interface nsIPermission;
|
||||
interface nsISimpleEnumerator;
|
||||
|
||||
[scriptable, uuid(c9fec678-f194-43c9-96b0-7bd9dbdd6bb0)]
|
||||
[scriptable, uuid(620d9b61-8997-4d13-aa64-ec03341dd75b)]
|
||||
interface nsIPermissionManager : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -132,6 +132,11 @@ interface nsIPermissionManager : nsISupports
|
||||
*/
|
||||
void removeAll();
|
||||
|
||||
/**
|
||||
* Clear all permission information added since the specified time.
|
||||
*/
|
||||
void removeAllSince(in int64_t since);
|
||||
|
||||
/**
|
||||
* Test whether a website has permission to perform the given action.
|
||||
* @param uri the uri to be tested
|
||||
|
@ -241,8 +241,12 @@ class Permissions(object):
|
||||
rows = cursor.execute("PRAGMA table_info(moz_hosts)")
|
||||
count = len(rows.fetchall())
|
||||
|
||||
# if the db contains 9 columns, we're using user_version 4
|
||||
if count == 9:
|
||||
statement = "INSERT INTO moz_hosts values(NULL, ?, ?, ?, 0, 0, 0, 0, 0)"
|
||||
cursor.execute("PRAGMA user_version=4;")
|
||||
# if the db contains 8 columns, we're using user_version 3
|
||||
if count == 8:
|
||||
elif count == 8:
|
||||
statement = "INSERT INTO moz_hosts values(NULL, ?, ?, ?, 0, 0, 0, 0)"
|
||||
cursor.execute("PRAGMA user_version=3;")
|
||||
else:
|
||||
|
@ -40,7 +40,18 @@ http://127.0.0.1:8888 privileged
|
||||
|
||||
cursor.execute("PRAGMA user_version=%d;" % version)
|
||||
|
||||
if version == 3:
|
||||
if version == 4:
|
||||
cursor.execute("""CREATE TABLE IF NOT EXISTS moz_hosts (
|
||||
id INTEGER PRIMARY KEY,
|
||||
host TEXT,
|
||||
type TEXT,
|
||||
permission INTEGER,
|
||||
expireType INTEGER,
|
||||
expireTime INTEGER,
|
||||
modificationTime INTEGER,
|
||||
appId INTEGER,
|
||||
isInBrowserElement INTEGER)""")
|
||||
elif version == 3:
|
||||
cursor.execute("""CREATE TABLE IF NOT EXISTS moz_hosts (
|
||||
id INTEGER PRIMARY KEY,
|
||||
host TEXT,
|
||||
@ -59,7 +70,7 @@ http://127.0.0.1:8888 privileged
|
||||
expireType INTEGER,
|
||||
expireTime INTEGER)""")
|
||||
else:
|
||||
raise Exception("version must be 2 or 3")
|
||||
raise Exception("version must be 2, 3 or 4")
|
||||
|
||||
permDB.commit()
|
||||
cursor.close()
|
||||
@ -149,7 +160,7 @@ http://127.0.0.1:8888 privileged
|
||||
|
||||
self.assertEqual(len(entries), 3)
|
||||
|
||||
columns = 8 if version == 3 else 6
|
||||
columns = 9 if version == 4 else (8 if version == 3 else 6)
|
||||
self.assertEqual(len(entries[0]), columns)
|
||||
for x in range(4, columns):
|
||||
self.assertEqual(entries[0][x], 0)
|
||||
@ -160,6 +171,8 @@ http://127.0.0.1:8888 privileged
|
||||
def test_existing_permissions_db_v3(self):
|
||||
self.verify_user_version(3)
|
||||
|
||||
def test_existing_permissions_db_v4(self):
|
||||
self.verify_user_version(4)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
Reference in New Issue
Block a user