mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 519263 - Session and time-based expiration for permissions in permissions manager. r=dwitte,
sr=mrbkap. First patch! Yay!!
This commit is contained in:
parent
fb285fa757
commit
fb4694efc4
@ -884,7 +884,9 @@ nsOperaCookieMigrator::AddCookieOverride(nsIPermissionManager* aManager)
|
||||
rv = aManager->Add(uri, "cookie",
|
||||
(mCurrHandlingInfo == 1 || mCurrHandlingInfo == 3)
|
||||
? (PRUint32) nsIPermissionManager::ALLOW_ACTION
|
||||
: (PRUint32) nsIPermissionManager::DENY_ACTION);
|
||||
: (PRUint32) nsIPermissionManager::DENY_ACTION,
|
||||
nsIPermissionManager::EXPIRE_NEVER,
|
||||
0);
|
||||
|
||||
mCurrHandlingInfo = 0;
|
||||
|
||||
|
@ -189,7 +189,8 @@ nsCookiePermission::SetAccess(nsIURI *aURI,
|
||||
// the permission codes used by nsIPermissionManager.
|
||||
// this is nice because it avoids conversion code.
|
||||
//
|
||||
return mPermMgr->Add(aURI, kPermissionType, aAccess);
|
||||
return mPermMgr->Add(aURI, kPermissionType, aAccess,
|
||||
nsIPermissionManager::EXPIRE_NEVER, 0);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -361,13 +362,16 @@ nsCookiePermission::CanSetCookie(nsIURI *aURI,
|
||||
if (rememberDecision) {
|
||||
switch (*aResult) {
|
||||
case nsICookiePromptService::DENY_COOKIE:
|
||||
mPermMgr->Add(aURI, kPermissionType, (PRUint32) nsIPermissionManager::DENY_ACTION);
|
||||
mPermMgr->Add(aURI, kPermissionType, (PRUint32) nsIPermissionManager::DENY_ACTION,
|
||||
nsIPermissionManager::EXPIRE_NEVER, 0);
|
||||
break;
|
||||
case nsICookiePromptService::ACCEPT_COOKIE:
|
||||
mPermMgr->Add(aURI, kPermissionType, (PRUint32) nsIPermissionManager::ALLOW_ACTION);
|
||||
mPermMgr->Add(aURI, kPermissionType, (PRUint32) nsIPermissionManager::ALLOW_ACTION,
|
||||
nsIPermissionManager::EXPIRE_NEVER, 0);
|
||||
break;
|
||||
case nsICookiePromptService::ACCEPT_SESSION_COOKIE:
|
||||
mPermMgr->Add(aURI, kPermissionType, nsICookiePermission::ACCESS_SESSION);
|
||||
mPermMgr->Add(aURI, kPermissionType, nsICookiePermission::ACCESS_SESSION,
|
||||
nsIPermissionManager::EXPIRE_NEVER, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -43,10 +43,14 @@ NS_IMPL_ISUPPORTS1(nsPermission, nsIPermission)
|
||||
|
||||
nsPermission::nsPermission(const nsACString &aHost,
|
||||
const nsACString &aType,
|
||||
PRUint32 aCapability)
|
||||
PRUint32 aCapability,
|
||||
PRUint32 aExpireType,
|
||||
PRInt64 aExpireTime)
|
||||
: mHost(aHost)
|
||||
, mType(aType)
|
||||
, mCapability(aCapability)
|
||||
, mExpireType(aExpireType)
|
||||
, mExpireTime(aExpireTime)
|
||||
{
|
||||
}
|
||||
|
||||
@ -74,3 +78,17 @@ nsPermission::GetCapability(PRUint32 *aCapability)
|
||||
*aCapability = mCapability;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPermission::GetExpireType(PRUint32 *aExpireType)
|
||||
{
|
||||
*aExpireType = mExpireType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPermission::GetExpireTime(PRInt64 *aExpireTime)
|
||||
{
|
||||
*aExpireTime = mExpireTime;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -50,13 +50,20 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPERMISSION
|
||||
|
||||
nsPermission(const nsACString &aHost, const nsACString &aType, PRUint32 aCapability);
|
||||
nsPermission(const nsACString &aHost,
|
||||
const nsACString &aType,
|
||||
PRUint32 aCapability,
|
||||
PRUint32 aExpireType,
|
||||
PRInt64 aExpireTime);
|
||||
|
||||
virtual ~nsPermission();
|
||||
|
||||
protected:
|
||||
nsCString mHost;
|
||||
nsCString mType;
|
||||
PRUint32 mCapability;
|
||||
PRUint32 mExpireType;
|
||||
PRInt64 mExpireTime;
|
||||
};
|
||||
|
||||
#endif // nsPermission_h__
|
||||
|
@ -95,7 +95,7 @@ nsHostEntry::nsHostEntry(const nsHostEntry& toCopy)
|
||||
// nsPermissionManager Implementation
|
||||
|
||||
static const char kPermissionsFileName[] = "permissions.sqlite";
|
||||
#define HOSTS_SCHEMA_VERSION 1
|
||||
#define HOSTS_SCHEMA_VERSION 2
|
||||
|
||||
static const char kHostpermFileName[] = "hostperm.1";
|
||||
|
||||
@ -198,6 +198,24 @@ nsPermissionManager::InitDB(PRBool aRemoveFile)
|
||||
// the upgrading code from the previous version to the new one.
|
||||
// fall through to current version
|
||||
|
||||
case 1:
|
||||
{
|
||||
// previous non-expiry version of database. Upgrade it by adding the
|
||||
// expiration columns
|
||||
rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"ALTER TABLE moz_hosts ADD expireType INTEGER"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"ALTER TABLE moz_hosts ADD expireTime INTEGER"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDBConn->SetSchemaVersion(HOSTS_SCHEMA_VERSION);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// fall through to the next upgrade
|
||||
|
||||
// current version.
|
||||
case HOSTS_SCHEMA_VERSION:
|
||||
break;
|
||||
@ -227,7 +245,8 @@ nsPermissionManager::InitDB(PRBool aRemoveFile)
|
||||
// check if all the expected columns exist
|
||||
nsCOMPtr<mozIStorageStatement> stmt;
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT host, type, permission FROM moz_hosts"), getter_AddRefs(stmt));
|
||||
"SELECT host, type, permission, expireType, expireTime FROM moz_hosts"),
|
||||
getter_AddRefs(stmt));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
break;
|
||||
|
||||
@ -248,8 +267,8 @@ nsPermissionManager::InitDB(PRBool aRemoveFile)
|
||||
// cache frequently used statements (for insertion, deletion, and updating)
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO moz_hosts "
|
||||
"(id, host, type, permission) "
|
||||
"VALUES (?1, ?2, ?3, ?4)"), getter_AddRefs(mStmtInsert));
|
||||
"(id, host, type, permission, expireType, expireTime) "
|
||||
"VALUES (?1, ?2, ?3, ?4, ?5, ?6)"), getter_AddRefs(mStmtInsert));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
@ -259,7 +278,8 @@ nsPermissionManager::InitDB(PRBool aRemoveFile)
|
||||
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"UPDATE moz_hosts "
|
||||
"SET permission = ?2 WHERE id = ?1"), getter_AddRefs(mStmtUpdate));
|
||||
"SET permission = ?2, expireType= ?3, expireTime = ?4 WHERE id = ?1"),
|
||||
getter_AddRefs(mStmtUpdate));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// check whether to import or just read in the db
|
||||
@ -284,24 +304,38 @@ nsPermissionManager::CreateTable()
|
||||
",host TEXT"
|
||||
",type TEXT"
|
||||
",permission INTEGER"
|
||||
",expireType INTEGER"
|
||||
",expireTime INTEGER"
|
||||
")"));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPermissionManager::Add(nsIURI *aURI,
|
||||
const char *aType,
|
||||
PRUint32 aPermission)
|
||||
PRUint32 aPermission,
|
||||
PRUint32 aExpireType,
|
||||
PRInt64 aExpireTime)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
NS_ENSURE_ARG_POINTER(aType);
|
||||
NS_ENSURE_TRUE(aExpireType == nsIPermissionManager::EXPIRE_NEVER ||
|
||||
aExpireType == nsIPermissionManager::EXPIRE_TIME ||
|
||||
aExpireType == nsIPermissionManager::EXPIRE_SESSION,
|
||||
NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// Skip addition if the permission is already expired.
|
||||
if (aExpireType == nsIPermissionManager::EXPIRE_TIME &&
|
||||
aExpireTime < PR_Now() / 1000)
|
||||
return NS_OK;
|
||||
|
||||
nsCAutoString host;
|
||||
rv = GetHost(aURI, host);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return AddInternal(host, nsDependentCString(aType), aPermission, 0, eNotify, eWriteToDB);
|
||||
return AddInternal(host, nsDependentCString(aType), aPermission, 0,
|
||||
aExpireType, aExpireTime, eNotify, eWriteToDB);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -309,6 +343,8 @@ nsPermissionManager::AddInternal(const nsAFlatCString &aHost,
|
||||
const nsAFlatCString &aType,
|
||||
PRUint32 aPermission,
|
||||
PRInt64 aID,
|
||||
PRUint32 aExpireType,
|
||||
PRInt64 aExpireTime,
|
||||
NotifyOperationType aNotifyOperation,
|
||||
DBOperationType aDBOperation)
|
||||
{
|
||||
@ -335,7 +371,6 @@ nsPermissionManager::AddInternal(const nsAFlatCString &aHost,
|
||||
// figure out the transaction type, and get any existing permission value
|
||||
OperationType op;
|
||||
PRInt32 index = entry->GetPermissionIndex(typeIndex);
|
||||
PRUint32 oldPermission;
|
||||
if (index == -1) {
|
||||
if (aPermission == nsIPermissionManager::UNKNOWN_ACTION)
|
||||
op = eOperationNone;
|
||||
@ -343,9 +378,17 @@ nsPermissionManager::AddInternal(const nsAFlatCString &aHost,
|
||||
op = eOperationAdding;
|
||||
|
||||
} else {
|
||||
oldPermission = entry->GetPermissions()[index].mPermission;
|
||||
nsPermissionEntry oldPermissionEntry = entry->GetPermissions()[index];
|
||||
|
||||
if (aPermission == oldPermission)
|
||||
// remove the permission if the permission is UNKNOWN, update the
|
||||
// permission if its value or expire type have changed OR if the time has
|
||||
// changed and the expire type is time, otherwise, don't modify. There's
|
||||
// no need to modify a permission that doesn't expire with time when the
|
||||
// only thing changed is the expire time.
|
||||
if (aPermission == oldPermissionEntry.mPermission &&
|
||||
aExpireType == oldPermissionEntry.mExpireType &&
|
||||
(aExpireType != nsIPermissionManager::EXPIRE_TIME ||
|
||||
aExpireTime == oldPermissionEntry.mExpireTime))
|
||||
op = eOperationNone;
|
||||
else if (aPermission == nsIPermissionManager::UNKNOWN_ACTION)
|
||||
op = eOperationRemoving;
|
||||
@ -373,15 +416,17 @@ nsPermissionManager::AddInternal(const nsAFlatCString &aHost,
|
||||
id = aID;
|
||||
}
|
||||
|
||||
entry->GetPermissions().AppendElement(nsPermissionEntry(typeIndex, aPermission, id));
|
||||
entry->GetPermissions().AppendElement(nsPermissionEntry(typeIndex, aPermission, id, aExpireType, aExpireTime));
|
||||
|
||||
if (aDBOperation == eWriteToDB)
|
||||
UpdateDB(op, mStmtInsert, id, aHost, aType, aPermission);
|
||||
if (aDBOperation == eWriteToDB && aExpireType != nsIPermissionManager::EXPIRE_SESSION)
|
||||
UpdateDB(op, mStmtInsert, id, aHost, aType, aPermission, aExpireType, aExpireTime);
|
||||
|
||||
if (aNotifyOperation == eNotify) {
|
||||
NotifyObserversWithPermission(aHost,
|
||||
mTypeArray[typeIndex],
|
||||
aPermission,
|
||||
aExpireType,
|
||||
aExpireTime,
|
||||
NS_LITERAL_STRING("added").get());
|
||||
}
|
||||
|
||||
@ -390,7 +435,8 @@ nsPermissionManager::AddInternal(const nsAFlatCString &aHost,
|
||||
|
||||
case eOperationRemoving:
|
||||
{
|
||||
id = entry->GetPermissions()[index].mID;
|
||||
nsPermissionEntry oldPermissionEntry = entry->GetPermissions()[index];
|
||||
id = oldPermissionEntry.mID;
|
||||
entry->GetPermissions().RemoveElementAt(index);
|
||||
|
||||
// If no more types are present, remove the entry
|
||||
@ -398,12 +444,15 @@ nsPermissionManager::AddInternal(const nsAFlatCString &aHost,
|
||||
mHostTable.RawRemoveEntry(entry);
|
||||
|
||||
if (aDBOperation == eWriteToDB)
|
||||
UpdateDB(op, mStmtDelete, id, EmptyCString(), EmptyCString(), 0);
|
||||
UpdateDB(op, mStmtDelete, id, EmptyCString(), EmptyCString(), 0,
|
||||
nsIPermissionManager::EXPIRE_NEVER, 0);
|
||||
|
||||
if (aNotifyOperation == eNotify) {
|
||||
NotifyObserversWithPermission(aHost,
|
||||
mTypeArray[typeIndex],
|
||||
oldPermission,
|
||||
oldPermissionEntry.mPermission,
|
||||
oldPermissionEntry.mExpireType,
|
||||
oldPermissionEntry.mExpireTime,
|
||||
NS_LITERAL_STRING("deleted").get());
|
||||
}
|
||||
|
||||
@ -415,13 +464,15 @@ nsPermissionManager::AddInternal(const nsAFlatCString &aHost,
|
||||
id = entry->GetPermissions()[index].mID;
|
||||
entry->GetPermissions()[index].mPermission = aPermission;
|
||||
|
||||
if (aDBOperation == eWriteToDB)
|
||||
UpdateDB(op, mStmtUpdate, id, EmptyCString(), EmptyCString(), aPermission);
|
||||
if (aDBOperation == eWriteToDB && aExpireType != nsIPermissionManager::EXPIRE_SESSION)
|
||||
UpdateDB(op, mStmtUpdate, id, EmptyCString(), EmptyCString(), aPermission, aExpireType, aExpireTime);
|
||||
|
||||
if (aNotifyOperation == eNotify) {
|
||||
NotifyObserversWithPermission(aHost,
|
||||
mTypeArray[typeIndex],
|
||||
aPermission,
|
||||
aExpireType,
|
||||
aExpireTime,
|
||||
NS_LITERAL_STRING("changed").get());
|
||||
}
|
||||
|
||||
@ -443,6 +494,8 @@ nsPermissionManager::Remove(const nsACString &aHost,
|
||||
nsDependentCString(aType),
|
||||
nsIPermissionManager::UNKNOWN_ACTION,
|
||||
0,
|
||||
nsIPermissionManager::EXPIRE_NEVER,
|
||||
0,
|
||||
eNotify,
|
||||
eWriteToDB);
|
||||
}
|
||||
@ -516,7 +569,7 @@ nsPermissionManager::CommonTestPermission(nsIURI *aURI,
|
||||
|
||||
nsHostEntry *entry = GetHostEntry(host, typeIndex, aExactHostMatch);
|
||||
if (entry)
|
||||
*aPermission = entry->GetPermission(typeIndex);
|
||||
*aPermission = entry->GetPermission(typeIndex).mPermission;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -531,10 +584,18 @@ nsPermissionManager::GetHostEntry(const nsAFlatCString &aHost,
|
||||
{
|
||||
PRUint32 offset = 0;
|
||||
nsHostEntry *entry;
|
||||
PRInt64 now = PR_Now() / 1000;
|
||||
|
||||
do {
|
||||
entry = mHostTable.GetEntry(aHost.get() + offset);
|
||||
if (entry) {
|
||||
if (entry->GetPermission(aType) != nsIPermissionManager::UNKNOWN_ACTION)
|
||||
nsPermissionEntry permEntry = entry->GetPermission(aType);
|
||||
|
||||
// if the entry is expired, remove and keep looking for others.
|
||||
if (permEntry.mExpireType == nsIPermissionManager::EXPIRE_TIME &&
|
||||
permEntry.mExpireTime < now)
|
||||
Remove(aHost, mTypeArray[aType].get());
|
||||
else if (permEntry.mPermission != nsIPermissionManager::UNKNOWN_ACTION)
|
||||
break;
|
||||
|
||||
// reset entry, to be able to return null on failure
|
||||
@ -572,7 +633,9 @@ AddPermissionsToList(nsHostEntry *entry, void *arg)
|
||||
|
||||
nsPermission *perm = new nsPermission(entry->GetHost(),
|
||||
data->types->ElementAt(permEntry.mType),
|
||||
permEntry.mPermission);
|
||||
permEntry.mPermission,
|
||||
permEntry.mExpireType,
|
||||
permEntry.mExpireTime);
|
||||
|
||||
data->array->AppendObject(perm);
|
||||
}
|
||||
@ -653,15 +716,18 @@ nsPermissionManager::GetTypeIndex(const char *aType,
|
||||
return mTypeArray.Length() - 1;
|
||||
}
|
||||
|
||||
// wrapper function for mangling (host,type,perm) triplet into an nsIPermission.
|
||||
// wrapper function for mangling (host,type,perm,expireType,expireTime)
|
||||
// set into an nsIPermission.
|
||||
void
|
||||
nsPermissionManager::NotifyObserversWithPermission(const nsACString &aHost,
|
||||
const nsCString &aType,
|
||||
PRUint32 aPermission,
|
||||
PRUint32 aExpireType,
|
||||
PRInt64 aExpireTime,
|
||||
const PRUnichar *aData)
|
||||
{
|
||||
nsCOMPtr<nsIPermission> permission =
|
||||
new nsPermission(aHost, aType, aPermission);
|
||||
new nsPermission(aHost, aType, aPermission, aExpireType, aExpireTime);
|
||||
if (permission)
|
||||
NotifyObservers(permission, aData);
|
||||
}
|
||||
@ -687,15 +753,37 @@ nsPermissionManager::Read()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// delete expired permissions before we read in the db
|
||||
{
|
||||
// this deletion has its own scope so the write lock is released when done.
|
||||
nsCOMPtr<mozIStorageStatement> stmtDeleteExpired;
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"DELETE FROM moz_hosts WHERE expireType = ?1 AND expireTime < ?2"),
|
||||
getter_AddRefs(stmtDeleteExpired));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = stmtDeleteExpired->BindInt32Parameter(0, nsIPermissionManager::EXPIRE_TIME);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = stmtDeleteExpired->BindInt64Parameter(1, PR_Now() / 1000);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool hasResult;
|
||||
rv = stmtDeleteExpired->ExecuteStep(&hasResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> stmt;
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT id, host, type, permission "
|
||||
"SELECT id, host, type, permission, expireType, expireTime "
|
||||
"FROM moz_hosts"), getter_AddRefs(stmt));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt64 id;
|
||||
nsCAutoString host, type;
|
||||
PRUint32 permission;
|
||||
PRUint32 expireType;
|
||||
PRInt64 expireTime;
|
||||
PRBool hasResult;
|
||||
while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
|
||||
// explicitly set our entry id counter for use in AddInternal(),
|
||||
@ -711,8 +799,13 @@ nsPermissionManager::Read()
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
permission = stmt->AsInt32(3);
|
||||
expireType = stmt->AsInt32(4);
|
||||
|
||||
rv = AddInternal(host, type, permission, id, eDontNotify, eNoDBOperation);
|
||||
// convert into PRInt64 value (milliseconds)
|
||||
expireTime = stmt->AsInt64(5);
|
||||
|
||||
rv = AddInternal(host, type, permission, id, expireType, expireTime,
|
||||
eDontNotify, eNoDBOperation);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
@ -779,7 +872,8 @@ nsPermissionManager::Import()
|
||||
continue;
|
||||
}
|
||||
|
||||
rv = AddInternal(lineArray[3], lineArray[1], permission, 0, eDontNotify, eWriteToDB);
|
||||
rv = AddInternal(lineArray[3], lineArray[1], permission, 0,
|
||||
nsIPermissionManager::EXPIRE_NEVER, 0, eDontNotify, eWriteToDB);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
@ -823,7 +917,9 @@ nsPermissionManager::UpdateDB(OperationType aOp,
|
||||
PRInt64 aID,
|
||||
const nsACString &aHost,
|
||||
const nsACString &aType,
|
||||
PRUint32 aPermission)
|
||||
PRUint32 aPermission,
|
||||
PRUint32 aExpireType,
|
||||
PRInt64 aExpireTime)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
@ -844,6 +940,12 @@ nsPermissionManager::UpdateDB(OperationType aOp,
|
||||
if (NS_FAILED(rv)) break;
|
||||
|
||||
rv = aStmt->BindInt32Parameter(3, aPermission);
|
||||
if (NS_FAILED(rv)) break;
|
||||
|
||||
rv = aStmt->BindInt32Parameter(4, aExpireType);
|
||||
if (NS_FAILED(rv)) break;
|
||||
|
||||
rv = aStmt->BindInt64Parameter(5, aExpireTime);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -859,6 +961,12 @@ nsPermissionManager::UpdateDB(OperationType aOp,
|
||||
if (NS_FAILED(rv)) break;
|
||||
|
||||
rv = aStmt->BindInt32Parameter(1, aPermission);
|
||||
if (NS_FAILED(rv)) break;
|
||||
|
||||
rv = aStmt->BindInt32Parameter(2, aExpireType);
|
||||
if (NS_FAILED(rv)) break;
|
||||
|
||||
rv = aStmt->BindInt64Parameter(3, aExpireTime);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -60,14 +60,19 @@ class mozIStorageStatement;
|
||||
class nsPermissionEntry
|
||||
{
|
||||
public:
|
||||
nsPermissionEntry(PRUint32 aType, PRUint32 aPermission, PRInt64 aID)
|
||||
nsPermissionEntry(PRUint32 aType, PRUint32 aPermission, PRInt64 aID,
|
||||
PRUint32 aExpireType, PRInt64 aExpireTime)
|
||||
: mType(aType)
|
||||
, mPermission(aPermission)
|
||||
, mID(aID) {}
|
||||
, mID(aID)
|
||||
, mExpireType(aExpireType)
|
||||
, mExpireTime(aExpireTime) {}
|
||||
|
||||
PRUint32 mType;
|
||||
PRUint32 mPermission;
|
||||
PRInt64 mID;
|
||||
PRUint32 mExpireType;
|
||||
PRInt64 mExpireTime;
|
||||
};
|
||||
|
||||
class nsHostEntry : public PLDHashEntryHdr
|
||||
@ -130,13 +135,16 @@ public:
|
||||
return -1;
|
||||
}
|
||||
|
||||
inline PRUint32 GetPermission(PRUint32 aType) const
|
||||
inline nsPermissionEntry GetPermission(PRUint32 aType) const
|
||||
{
|
||||
for (PRUint32 i = 0; i < mPermissions.Length(); ++i)
|
||||
if (mPermissions[i].mType == aType)
|
||||
return mPermissions[i].mPermission;
|
||||
return mPermissions[i];
|
||||
|
||||
return nsIPermissionManager::UNKNOWN_ACTION;
|
||||
// unknown permission... return relevant data
|
||||
nsPermissionEntry unk = nsPermissionEntry(aType, nsIPermissionManager::UNKNOWN_ACTION,
|
||||
-1, nsIPermissionManager::EXPIRE_NEVER, 0);
|
||||
return unk;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -184,6 +192,8 @@ private:
|
||||
const nsAFlatCString &aType,
|
||||
PRUint32 aPermission,
|
||||
PRInt64 aID,
|
||||
PRUint32 aExpireType,
|
||||
PRInt64 aExpireTime,
|
||||
NotifyOperationType aNotifyOperation,
|
||||
DBOperationType aDBOperation);
|
||||
|
||||
@ -206,6 +216,8 @@ private:
|
||||
void NotifyObserversWithPermission(const nsACString &aHost,
|
||||
const nsCString &aType,
|
||||
PRUint32 aPermission,
|
||||
PRUint32 aExpireType,
|
||||
PRInt64 aExpireTime,
|
||||
const PRUnichar *aData);
|
||||
void NotifyObservers(nsIPermission *aPermission, const PRUnichar *aData);
|
||||
nsresult RemoveAllInternal();
|
||||
@ -217,7 +229,9 @@ private:
|
||||
PRInt64 aID,
|
||||
const nsACString &aHost,
|
||||
const nsACString &aType,
|
||||
PRUint32 aPermission);
|
||||
PRUint32 aPermission,
|
||||
PRUint32 aExpireType,
|
||||
PRInt64 aExpireTime);
|
||||
|
||||
nsCOMPtr<nsIObserverService> mObserverService;
|
||||
nsCOMPtr<nsIIDNService> mIDNService;
|
||||
|
54
extensions/cookie/test/unit/test_permmanager_expiration.js
Normal file
54
extensions/cookie/test/unit/test_permmanager_expiration.js
Normal file
@ -0,0 +1,54 @@
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
// setup a profile directory
|
||||
var dir = do_get_profile();
|
||||
|
||||
// initialize the permission manager service
|
||||
var pm = Cc["@mozilla.org/permissionmanager;1"]
|
||||
.getService(Ci.nsIPermissionManager);
|
||||
|
||||
var ios = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService);
|
||||
var permURI = ios.newURI("http://example.com", null, null);
|
||||
|
||||
function run_test() {
|
||||
|
||||
// add a permission with *now* expiration
|
||||
pm.add(permURI, "test/expiration-perm-exp", 1, pm.EXPIRE_TIME, (new Date()).getTime());
|
||||
|
||||
// add a permission with future expiration (100 milliseconds)
|
||||
pm.add(permURI, "test/expiration-perm-exp2", 1, pm.EXPIRE_TIME, (new Date()).getTime() + 100);
|
||||
|
||||
// add a permission with future expiration (10000 milliseconds)
|
||||
pm.add(permURI, "test/expiration-perm-exp3", 1, pm.EXPIRE_TIME, (new Date()).getTime() + 10000);
|
||||
|
||||
// add a permission without expiration
|
||||
pm.add(permURI, "test/expiration-perm-nexp", 1, pm.EXPIRE_NEVER, 0);
|
||||
|
||||
// check that the permission expired
|
||||
do_check_eq(0, pm.testPermission(permURI, "test/expiration-perm-exp"));
|
||||
|
||||
// ... and that the others didn't
|
||||
do_check_eq(1, pm.testPermission(permURI, "test/expiration-perm-exp3"));
|
||||
do_check_eq(1, pm.testPermission(permURI, "test/expiration-perm-nexp"));
|
||||
|
||||
// ... and that the short-term one will
|
||||
do_test_pending();
|
||||
do_timeout(200, "verifyExpiration();");
|
||||
|
||||
// clean up
|
||||
do_test_pending();
|
||||
do_timeout(300, "end_test();");
|
||||
}
|
||||
|
||||
function verifyExpiration() {
|
||||
do_check_eq(0, pm.testPermission(permURI, "test/expiration-perm-exp2"));
|
||||
do_test_finished();
|
||||
}
|
||||
|
||||
function end_test() {
|
||||
// clean up
|
||||
pm.removeAll();
|
||||
do_test_finished();
|
||||
}
|
122
extensions/cookie/test/unit/test_permmanager_notifications.js
Normal file
122
extensions/cookie/test/unit/test_permmanager_notifications.js
Normal file
@ -0,0 +1,122 @@
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
// setup a profile directory
|
||||
var dir = do_get_profile();
|
||||
|
||||
// initialize the permission manager service
|
||||
var pm = Cc["@mozilla.org/permissionmanager;1"]
|
||||
.getService(Ci.nsIPermissionManager);
|
||||
|
||||
var ios = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService);
|
||||
var permURI = ios.newURI("http://example.com", null, null);
|
||||
|
||||
var theTime = (new Date()).getTime();
|
||||
|
||||
var numadds = 0;
|
||||
var numchanges = 0;
|
||||
var numdeletes = 0;
|
||||
var needsToClear = true;
|
||||
|
||||
// will listen for stuff.
|
||||
var observer = {
|
||||
QueryInterface:
|
||||
function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIObserver))
|
||||
return this;
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
observe:
|
||||
function(subject, topic, data) {
|
||||
if (topic !== "perm-changed")
|
||||
return;
|
||||
|
||||
// "deleted" means a permission was deleted. aPermission is the deleted permission.
|
||||
// "added" means a permission was added. aPermission is the added permission.
|
||||
// "changed" means a permission was altered. aPermission is the new permission.
|
||||
// "cleared" means the entire permission list was cleared. aPermission is null.
|
||||
if (data == "added") {
|
||||
var perm = subject.QueryInterface(Ci.nsIPermission);
|
||||
numadds++;
|
||||
switch (numadds) {
|
||||
case 1: /* first add */
|
||||
do_check_eq(pm.EXPIRE_TIME, perm.expireType);
|
||||
do_check_eq(theTime + 10000, perm.expireTime);
|
||||
break;
|
||||
case 2: /* second add (permission-notify) */
|
||||
do_check_eq(pm.EXPIRE_NEVER, perm.expireType);
|
||||
do_check_eq(pm.DENY_ACTION, perm.capability);
|
||||
break;
|
||||
default:
|
||||
do_throw("too many add notifications posted.");
|
||||
}
|
||||
do_test_finished();
|
||||
|
||||
} else if (data == "changed") {
|
||||
var perm = subject.QueryInterface(Ci.nsIPermission);
|
||||
numchanges++;
|
||||
switch (numchanges) {
|
||||
case 1:
|
||||
do_check_eq(pm.EXPIRE_TIME, perm.expireType);
|
||||
do_check_eq(theTime + 20000, perm.expireTime);
|
||||
break;
|
||||
default:
|
||||
do_throw("too many change notifications posted.");
|
||||
}
|
||||
do_test_finished();
|
||||
|
||||
} else if (data == "deleted") {
|
||||
var perm = subject.QueryInterface(Ci.nsIPermission);
|
||||
numdeletes++;
|
||||
switch (numdeletes) {
|
||||
case 1:
|
||||
do_check_eq("test/permission-notify", perm.type);
|
||||
break;
|
||||
default:
|
||||
do_throw("too many delete notifications posted.");
|
||||
}
|
||||
do_test_finished();
|
||||
|
||||
} else if (data == "cleared") {
|
||||
// only clear once: at the end
|
||||
do_check_true(needsToClear);
|
||||
needsToClear = false;
|
||||
do_test_finished();
|
||||
} else {
|
||||
dump("subject: " + subject + " data: " + data + "\n");
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function run_test() {
|
||||
|
||||
var obs = Cc["@mozilla.org/observer-service;1"].getService()
|
||||
.QueryInterface(Ci.nsIObserverService);
|
||||
|
||||
obs.addObserver(observer, "perm-changed", false);
|
||||
|
||||
// add a permission
|
||||
do_test_pending(); // for 'add' notification
|
||||
pm.add(permURI, "test/expiration-perm", pm.ALLOW_ACTION, pm.EXPIRE_TIME, theTime + 10000);
|
||||
|
||||
do_test_pending(); // for 'change' notification
|
||||
pm.add(permURI, "test/expiration-perm", pm.ALLOW_ACTION, pm.EXPIRE_TIME, theTime + 20000);
|
||||
|
||||
do_test_pending(); // for 'add' notification
|
||||
pm.add(permURI, "test/permission-notify", pm.DENY_ACTION);
|
||||
|
||||
do_test_pending(); // for 'deleted' notification
|
||||
pm.remove(permURI.asciiHost, "test/permission-notify");
|
||||
|
||||
do_test_pending(); // for 'cleared' notification
|
||||
pm.removeAll();
|
||||
|
||||
do_timeout(100, "cleanup();");
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
obs.removeObserver(observer, "perm-changed");
|
||||
}
|
@ -38,8 +38,7 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(28F16D80-157B-11d5-A542-0010A401EB10)]
|
||||
|
||||
[scriptable, uuid(5036f0f6-f77b-4168-9d57-a1c0dd66cf02)]
|
||||
/**
|
||||
* This interface defines a "permission" object,
|
||||
* used to specify allowed/blocked objects from
|
||||
@ -66,4 +65,17 @@ interface nsIPermission : nsISupports
|
||||
* The permission (see nsIPermissionManager.idl for allowed values)
|
||||
*/
|
||||
readonly attribute PRUint32 capability;
|
||||
|
||||
/**
|
||||
* The expiration type of the permission (session, time-based or none).
|
||||
* Constants are EXPIRE_*, defined in nsIPermissionManager.
|
||||
* @see nsIPermissionManager
|
||||
*/
|
||||
readonly attribute PRUint32 expireType;
|
||||
|
||||
/**
|
||||
* The expiration time of the permission (milliseconds since Jan 1 1970
|
||||
* 0:00:00).
|
||||
*/
|
||||
readonly attribute PRInt64 expireTime;
|
||||
};
|
||||
|
@ -66,7 +66,7 @@
|
||||
interface nsIURI;
|
||||
interface nsIObserver;
|
||||
|
||||
[scriptable, uuid(00708302-684c-42d6-a5a3-995d51b1d17c)]
|
||||
[scriptable, uuid(0b83f9d5-3f96-41b6-91aa-ff3a7e4880d7)]
|
||||
interface nsIPermissionManager : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -80,6 +80,15 @@ interface nsIPermissionManager : nsISupports
|
||||
const PRUint32 ALLOW_ACTION = 1;
|
||||
const PRUint32 DENY_ACTION = 2;
|
||||
|
||||
/**
|
||||
* Predefined expiration types for permissions. Permissions can be permanent
|
||||
* (never expire), expire at the end of the session, or expire at a specified
|
||||
* time.
|
||||
*/
|
||||
const PRUint32 EXPIRE_NEVER = 0;
|
||||
const PRUint32 EXPIRE_SESSION = 1;
|
||||
const PRUint32 EXPIRE_TIME = 2;
|
||||
|
||||
/**
|
||||
* Add permission information for a given URI and permission type. This
|
||||
* operation will cause the type string to be registered if it does not
|
||||
@ -98,10 +107,18 @@ interface nsIPermissionManager : nsISupports
|
||||
* NOTE: UNKNOWN_ACTION (0) is reserved to represent the
|
||||
* default permission when no entry is found for a host, and
|
||||
* should not be used by consumers to indicate otherwise.
|
||||
* @param expiretype a constant defining whether this permission should
|
||||
* never expire (EXPIRE_NEVER), expire at the end of the
|
||||
* session (EXPIRE_SESSION), or expire at a specified time
|
||||
* (EXPIRE_TIME).
|
||||
* @param expiretime an integer representation of when this permission
|
||||
* should be forgotten (milliseconds since Jan 1 1970 0:00:00).
|
||||
*/
|
||||
void add(in nsIURI uri,
|
||||
in string type,
|
||||
in PRUint32 permission);
|
||||
in PRUint32 permission,
|
||||
[optional] in PRUint32 expireType,
|
||||
[optional] in PRInt64 expireTime);
|
||||
|
||||
/**
|
||||
* Remove permission information for a given host string and permission type.
|
||||
|
@ -300,7 +300,8 @@ static void updatePermissions( const char* aPref,
|
||||
rv = NS_NewURI(getter_AddRefs(uri), host);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
aPermissionManager->Add( uri, XPI_PERMISSION, aPermission );
|
||||
aPermissionManager->Add( uri, XPI_PERMISSION, aPermission,
|
||||
nsIPermissionManager::EXPIRE_NEVER, 0 );
|
||||
}
|
||||
start = match+1;
|
||||
} while ( match > 0 );
|
||||
|
Loading…
Reference in New Issue
Block a user