Checking in permissions rewrite phase 1 (troop deployment in the permission

gulf).  Bug 191380, patch by mvl@exedo.nl (Michiel van Leeuwen),
r=dwitte@stanford.edu, sr=darin.
This commit is contained in:
bzbarsky@mit.edu
2003-03-22 01:24:51 +00:00
parent 805e33c002
commit f20939f657
33 changed files with 1456 additions and 753 deletions

View File

@@ -6,3 +6,4 @@ nsIPermissionManager.idl
nsICookieConsent.idl
nsICookieAcceptDialog.idl
nsICookiePromptService.idl
nsICookiePermission.idl

View File

@@ -61,11 +61,10 @@ CPPSRCS = \
nsPermissionManager.cpp \
nsPopupWindowManager.cpp \
nsCookies.cpp \
nsImages.cpp \
nsPermissions.cpp \
nsUtils.cpp \
nsCookieHTTPNotify.cpp \
nsCookiePromptService.cpp \
nsCookiePermission.cpp \
$(NULL)
SDK_XPIDLSRCS = \
@@ -81,6 +80,7 @@ XPIDLSRCS = \
nsICookieAcceptDialog.idl \
nsICookiePromptService.idl \
nsICookieManager2.idl \
nsICookiePermission.idl \
$(NULL)
EXPORTS = \

View File

@@ -1006,13 +1006,6 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsImages.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsImgManager.cpp</PATH>
@@ -1057,7 +1050,7 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsPermissions.cpp</PATH>
<PATH>nsCookiePermission.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
@@ -1126,11 +1119,6 @@
<PATH>nsCookies.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsImages.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsImgManager.cpp</PATH>
@@ -1163,7 +1151,7 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsPermissions.cpp</PATH>
<PATH>nsCookiePermission.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
@@ -2126,13 +2114,6 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsImages.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsImgManager.cpp</PATH>
@@ -2177,7 +2158,7 @@
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsPermissions.cpp</PATH>
<PATH>nsCookiePermission.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
@@ -2246,11 +2227,6 @@
<PATH>nsCookies.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsImages.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsImgManager.cpp</PATH>
@@ -2283,7 +2259,7 @@
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsPermissions.cpp</PATH>
<PATH>nsCookiePermission.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
@@ -2332,12 +2308,6 @@
<PATH>nsCookieService.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>Cookie.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsImages.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>Cookie.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
@@ -2377,7 +2347,7 @@
<FILEREF>
<TARGETNAME>Cookie.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsPermissions.cpp</PATH>
<PATH>nsCookiePermission.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>

View File

@@ -776,6 +776,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsICookiePermission.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsICookiePromptService.idl</PATH>
@@ -832,6 +839,11 @@
<PATH>nsIPermissionManager.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsICookiePermission.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsICookiePromptService.idl</PATH>
@@ -1567,6 +1579,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsICookiePermission.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsICookiePromptService.idl</PATH>
@@ -1623,6 +1642,11 @@
<PATH>nsIPermissionManager.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsICookiePermission.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsICookiePromptService.idl</PATH>
@@ -1691,6 +1715,12 @@
<PATH>nsIPermissionManager.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>headers</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsICookiePermission.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>headers</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>

View File

@@ -0,0 +1,122 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is cookie manager code.
*
* The Initial Developer of the Original Code is
* Michiel van Leeuwen (mvl@exedo.nl).
* Portions created by the Initial Developer are Copyright (C) 2003
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsCookiePermission.h"
#include "nsCookie.h"
#include "nsICookieAcceptDialog.h"
#include "nsIWindowWatcher.h"
#include "nsIServiceManager.h"
#include "nsString.h"
#include "nsIDialogParamBlock.h"
#include "nsArray.h"
#include "nsCookiePromptService.h"
/****************************************************************
************************ nsCookiePermission ********************
****************************************************************/
static const PRUint32 kDefaultPolicy = nsIPermissionManager::ALLOW_ACTION;
NS_IMPL_ISUPPORTS1(nsCookiePermission, nsICookiePermission);
nsCookiePermission::nsCookiePermission()
: mPermissionManager(nsnull)
{
}
nsCookiePermission::~nsCookiePermission()
{
}
nsresult
nsCookiePermission::Init()
{
// Continue on an error. We can do a few things without a permission manager
mPermissionManager = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
return NS_OK;
}
NS_IMETHODIMP
nsCookiePermission::TestPermission(nsIURI *aURI,
nsICookie *aCookie,
nsIDOMWindow *aParent,
PRInt32 aCookiesFromHost,
PRBool aChangingCookie,
PRBool aShowDialog,
PRBool *aPermission)
{
NS_ASSERTION(aURI, "could not get uri");
nsresult rv;
*aPermission = kDefaultPolicy;
nsCAutoString hostPort;
aURI->GetHostPort(hostPort);
if (hostPort.IsEmpty())
return NS_OK;
PRUint32 listPermission = nsIPermissionManager::UNKNOWN_ACTION;
if (mPermissionManager) {
mPermissionManager->TestPermission(aURI, nsIPermissionManager::COOKIE_TYPE, &listPermission);
}
if (listPermission == nsIPermissionManager::UNKNOWN_ACTION) {
if (aShowDialog && aCookie) {
// we don't cache the cookiePromptService - it's not used often, so not worth the memory
nsCOMPtr<nsICookiePromptService> cookiePromptService = do_GetService(NS_COOKIEPROMPTSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
PRBool rememberDecision = PR_FALSE;
rv = cookiePromptService->
CookieDialog(nsnull, aCookie, hostPort,
aCookiesFromHost, aChangingCookie, &rememberDecision,
aPermission);
if (NS_FAILED(rv)) return rv;
if (rememberDecision && mPermissionManager) {
// Remember this decision
mPermissionManager->Add(aURI, nsIPermissionManager::COOKIE_TYPE, *aPermission);
}
}
} else {
*aPermission = (listPermission == nsIPermissionManager::ALLOW_ACTION);
}
return NS_OK;
}

View File

@@ -0,0 +1,65 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is cookie manager code.
*
* The Initial Developer of the Original Code is
* Michiel van Leeuwen (mvl@exedo.nl).
* Portions created by the Initial Developer are Copyright (C) 2003
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsCookiePermission_h__
#define nsCookiePermission_h__
#include "nsICookiePermission.h"
#include "nsIDOMWindow.h"
#include "nsCOMPtr.h"
#include "nsIPermissionManager.h"
#include "nsIURI.h"
class nsCookiePermission : public nsICookiePermission
{
public:
nsCookiePermission();
virtual ~nsCookiePermission();
nsresult Init();
NS_DECL_ISUPPORTS
NS_DECL_NSICOOKIEPERMISSION
private:
nsCOMPtr<nsIPermissionManager> mPermissionManager;
};
// {CE002B28-92B7-4701-8621-CC925866FB87}
#define NS_COOKIEPERMISSION_CID \
{0xEF565D0A, 0xAB9A, 0x4A13, {0x91, 0x60, 0x06, 0x44, 0xcd, 0xfd, 0x85, 0x9a }}
#endif

View File

@@ -63,7 +63,7 @@ nsCookiePromptService::CookieDialog(nsIDOMWindow *aParent,
const nsACString &aHostname,
PRInt32 aCookiesFromHost,
PRBool aChangingCookie,
PRBool *aCheckValue,
PRBool *aRememberDecision,
PRBool *aAccept)
{
nsresult rv;
@@ -74,7 +74,6 @@ nsCookiePromptService::CookieDialog(nsIDOMWindow *aParent,
// since we're setting PRInt32's here, we have to sanitize the PRBool's first.
// (myBool != PR_FALSE) is guaranteed to return either 1 or 0.
block->SetInt(nsICookieAcceptDialog::ACCEPT_COOKIE, 1);
block->SetInt(nsICookieAcceptDialog::REMEMBER_DECISION, *aCheckValue != PR_FALSE);
block->SetString(nsICookieAcceptDialog::HOSTNAME, NS_ConvertUTF8toUCS2(aHostname).get());
block->SetInt(nsICookieAcceptDialog::COOKIESFROMHOST, aCookiesFromHost);
block->SetInt(nsICookieAcceptDialog::CHANGINGCOOKIE, aChangingCookie != PR_FALSE);
@@ -111,7 +110,7 @@ nsCookiePromptService::CookieDialog(nsIDOMWindow *aParent,
*aAccept = (tempValue == 1);
block->GetInt(nsICookieAcceptDialog::REMEMBER_DECISION, &tempValue);
*aCheckValue = (tempValue == 1);
*aRememberDecision = (tempValue == 1);
return rv;
}

View File

@@ -49,11 +49,19 @@
#include "nsIObserverService.h"
#include "nsIPrefBranch.h"
#include "nsIPrefBranchInternal.h"
#include "nsPermissions.h"
#include "nsXPIDLString.h"
////////////////////////////////////////////////////////////////////////////////
// nsCookiePrefObserver
// enumerated type, used to specify default cookie behavior
typedef enum {
PERMISSION_Accept,
PERMISSION_DontAcceptForeign,
PERMISSION_DontUse,
PERMISSION_P3P
} PERMISSION_BehaviorEnum;
class nsCookiePrefObserver : public nsIObserver
, public nsSupportsWeakReference
{

View File

@@ -40,7 +40,8 @@
#include "nsCookies.h"
#include "nsCookieService.h"
#include "nsPermissions.h"
#include "nsICookiePermission.h"
#include "nsIPermissionManager.h"
#include "nsIIOService.h"
#include "prprf.h"
#include "nsReadableUtils.h"
@@ -681,18 +682,27 @@ COOKIE_Remove(const nsACString &host,
if (cookieInList->path.Equals(path) &&
cookieInList->host.Equals(host) &&
cookieInList->name.Equals(name)) {
// check if we need to add the host to the permissions blacklist
if (blocked && NS_SUCCEEDED(PERMISSION_Read())) {
// remove leading dot from host
// we need this trickery since Permission_AddHost wants an nsAFlatCString
// (and we want to avoid PromiseFlatCString()).
// check if we need to add the host to the permissions blacklist.
// we should push this portion into the UI, it shouldn't live here in the backend.
nsDependentCString hostWithoutDot(cookieInList->host.get(), cookieInList->host.Length());
if (blocked) {
nsresult rv;
nsCOMPtr<nsIPermissionManager> permissionManager = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIURI> uri;
NS_NAMED_LITERAL_CSTRING(httpPrefix, "http://");
// remove leading dot from host
if (!cookieInList->host.IsEmpty() && cookieInList->host.First() == '.') {
hostWithoutDot.Rebind(cookieInList->host.get() + 1, cookieInList->host.Length() - 1);
rv = NS_NewURI(getter_AddRefs(uri), PromiseFlatCString(httpPrefix + Substring(cookieInList->host, 1, cookieInList->host.Length() - 1)));
} else {
rv = NS_NewURI(getter_AddRefs(uri), PromiseFlatCString(httpPrefix + cookieInList->host));
}
Permission_AddHost(hostWithoutDot, PR_FALSE, COOKIEPERMISSION, PR_TRUE);
if (NS_SUCCEEDED(rv))
permissionManager->Add(uri,
nsIPermissionManager::COOKIE_TYPE,
nsIPermissionManager::DENY_ACTION);
}
}
sCookieList->RemoveElementAt(i);
@@ -1653,12 +1663,12 @@ COOKIE_ChangeFormat(cookie_CookieStruct *aCookie)
// to be processed
PRIVATE PRBool
cookie_SetCookieInternal(nsIURI *aHostURI,
nsIPrompt *aPrompt,
nsDependentCString &aCookieHeader,
nsInt64 aServerTime,
nsCookieStatus aStatus,
nsCookiePolicy aPolicy)
{
nsresult rv;
// keep a |const char*| version of the unmodified aCookieHeader,
// for logging purposes
const char *cookieHeader = aCookieHeader.get();
@@ -1666,6 +1676,9 @@ cookie_SetCookieInternal(nsIURI *aHostURI,
nsInt64 expiryTime, currentTime = nsTime() / PR_USEC_PER_SEC;
PRBool isSession, foundCookie;
nsCOMPtr<nsICookie> thisCookie;
nsCOMPtr<nsICookiePermission> cookiePermission;
// cookie stores all the attributes parsed from the cookie;
// expires and maxage are separate, because we have to process them to find the expiry.
// create a new cookie to store the attributes
@@ -1723,23 +1736,29 @@ cookie_SetCookieInternal(nsIURI *aHostURI,
goto failure;
}
// create a new nsICookie and copy the cookie data,
// for passing to the permission manager
thisCookie = COOKIE_ChangeFormat(cookie);
// we want to cache this ptr when we merge everything into nsCookieService
cookiePermission = do_GetService(NS_COOKIEPERMISSION_CONTRACTID, &rv);
// check permissions from site permission list, or ask the user,
// to determine if we can set the cookie
if (NS_SUCCEEDED(PERMISSION_Read())) {
// create a new nsICookie and copy the cookie data
nsCOMPtr<nsICookie> thisCookie = COOKIE_ChangeFormat(cookie);
if (!thisCookie ||
!Permission_Check(aPrompt, cookie->host.get(), COOKIEPERMISSION,
if (NS_SUCCEEDED(rv)) {
PRBool permission;
// we need to think about prompters/parent windows here - TestPermission
// needs one to prompt, so right now it has to fend for itself to get one
rv = cookiePermission->TestPermission(aHostURI, thisCookie, nsnull,
countFromHost, foundCookie,
gCookiePrefObserver->mCookiesAskPermission,
thisCookie, countFromHost, foundCookie)) {
&permission);
if (!permission) {
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, cookieHeader, "cookies are blocked for this site");
goto failure;
}
}
// add the cookie to the list
nsresult rv;
rv = COOKIE_Add(cookie, nsTime() / PR_USEC_PER_SEC, aHostURI, cookieHeader);
if (NS_FAILED(rv)) {
// no need to log a failure here, Add() does it for us
@@ -1809,7 +1828,7 @@ COOKIE_SetCookie(nsIURI *aHostURI,
// switch to a nice string type now, and process each cookie in the header
nsDependentCString cookieHeader(aCookieHeader);
while (cookie_SetCookieInternal(aHostURI, aPrompt,
while (cookie_SetCookieInternal(aHostURI,
cookieHeader, serverTime,
cookieStatus, cookiePolicy));
}

View File

@@ -0,0 +1,70 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is cookie manager code.
*
* The Initial Developer of the Original Code is
* Michiel van Leeuwen (mvl@exedo.nl).
* Portions created by the Initial Developer are Copyright (C) 2003
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
/**
* An interface to test for cookie permissions
*/
interface nsICookie;
interface nsIURI;
interface nsIDOMWindow;
[scriptable, uuid(EF565D0A-AB9A-4A13-9160-0644CDFD859A)]
interface nsICookiePermission : nsISupports
{
/**
* Test if a cookie from the given host should be accepted or denied
* @param uri the website to be tested
* @param cookie the cookie that wants to be set
* @param parent the parant window
* @param cookiesFromHost number of cookies this host already has set
* @param changingCookie are we changing this cookie?
* @param showDialog show a prompt to the user?
* @return whether the cookie has permission to be loaded
*/
boolean testPermission(in nsIURI uri,
in nsICookie cookie,
in nsIDOMWindow parent,
in long cookiesFromHost,
in boolean changingCookie,
in boolean showDialog);
};
%{ C++
#define NS_COOKIEPERMISSION_CONTRACTID "@mozilla.org/cookie/permission;1"
%}

View File

@@ -65,7 +65,7 @@ interface nsICookiePromptService : nsISupports
in ACString hostname,
in long cookiesFromHost,
in boolean changingCookie,
inout boolean checkValue);
out boolean rememberDecision);
};
%{C++

View File

@@ -36,10 +36,9 @@
*
* ***** END LICENSE BLOCK ***** */
/*
This file contains an interface to the Image Manager.
/**
* This file contains an interface to the Image Manager,
* used for blocking images from user-specified sites.
*/
#include "nsISupports.idl"
@@ -49,12 +48,16 @@ interface nsIURI;
[scriptable, uuid(D60B3710-166D-11d5-A542-0010A401EB10)]
interface nsIImgManager : nsISupports
{
void block(in nsIURI imageURL);
/**
* Test if the given image from URI can be loaded
* @param uri the uri of the image which wants to be loaded
* @param firstUri the uri of the document which tried to load the image
* @return whether the image has permission to be loaded
*/
boolean testPermission(in nsIURI uri,
in nsIURI firstUri);
};
%{ C++
// {D60B3710-166D-11d5-A542-0010A401EB10}
#define NS_IMGMANAGER_CID \
{ 0xd60b3710, 0x166d, 0x11d5, { 0xa5, 0x42, 0x0, 0x10, 0xa4, 0x1, 0xeb, 0x10 } }
#define NS_IMGMANAGER_CONTRACTID "@mozilla.org/imgmanager;1"
%}

View File

@@ -24,24 +24,30 @@
[scriptable, uuid(28F16D80-157B-11d5-A542-0010A401EB10)]
/**
This interface represents a "permission" object.
* This interface defines a "permission" object,
* used to specify allowed/blocked objects from
* user-specified sites (cookies, images etc).
*/
interface nsIPermission : nsISupports {
interface nsIPermission : nsISupports
{
/**
* The name of the host for which the permission is set
*/
readonly attribute AUTF8String host;
/* the name of the host */
readonly attribute string host;
/**
* The type of permission (e.g., cookie, image, etc)
* (see nsIPermissionManager.idl for allowed values)
*/
readonly attribute PRUint32 type;
/* the type of permission (e.g., cookie, image, etc) */
readonly attribute PRInt32 type;
/* the permission */
readonly attribute boolean capability;
/**
* The permission (see nsIPermissionManager.idl for allowed values)
*/
readonly attribute PRUint32 capability;
};
%{ C++
// {28F16D80-157B-11d5-A542-0010A401EB10}
#define NS_PERMISSION_CID \
{ 0x28f16d80, 0x157b, 0x11d5, { 0xa5, 0x42, 0x0, 0x10, 0xa4, 0x1, 0xeb, 0x10 } }
#define NS_PERMISSION_CONTRACTID "@mozilla.org/permission;1"
%}

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -36,28 +36,81 @@
*
* ***** END LICENSE BLOCK ***** */
/*
This file contains an interface to the Permission Manager.
/**
* This file contains an interface to the Permission Manager,
* used for blocking objects (cookies, images etc) from
* used-defined sites
*
* This service broadcasts a PERM_CHANGE_NOTIFICATION notification
* when any permission changes. You can add yourself as an observer.
*/
#include "nsISupports.idl"
#include "nsISimpleEnumerator.idl"
interface nsIURI;
interface nsIObserver;
[scriptable, uuid(4F6B5E00-0C36-11d5-A535-0010A401EB10)]
interface nsIPermissionManager : nsISupports
{
void add(in AUTF8String objectURL, in boolean permission, in PRInt32 type);
boolean testForBlocking(in AUTF8String objectURL, in PRInt32 type);
/**
* Allowed return values from the testPermission method
*/
const PRUint32 UNKNOWN_ACTION = 0;
const PRUint32 ALLOW_ACTION = 1;
const PRUint32 DENY_ACTION = 2;
/**
* These values are the different types of permissions supported
*/
const PRUint32 COOKIE_TYPE = 0;
const PRUint32 IMAGE_TYPE = 1;
const PRUint32 POPUP_TYPE = 2;
/**
* Add permission information for a given URI and permission type.
* @param uri is the website to add the permission for
* @param permission is one of the enumerated permission actions above
* @param type is one of the enumerated permission types above
*/
void add(in nsIURI uri,
in PRUint32 type,
in PRUint32 permission);
/**
* Remove permission information for a given URI and permission type.
* Note that this method takes a host string, not an nsIURI.
* @param host is the host to remove the permission for
* @param type is one of the enumerated permission types above
*/
void remove(in AUTF8String host,
in PRUint32 type);
/**
* Clear permission information for all websites.
*/
void removeAll();
/**
* Test whether a website has permission to perform the given action.
* @param uri the website to be tested
* @param type one of the enumerated types above
* @return one of the enumerated permission actions above
*/
PRUint32 testPermission(in nsIURI uri,
in PRUint32 type);
/**
* Allows enumeration of all stored permissions
* @return an nsISimpleEnumerator interface that allows access to
* nsIPermission objects
*/
readonly attribute nsISimpleEnumerator enumerator;
void remove(in AUTF8String host, in PRInt32 type);
};
%{ C++
// {4F6B5E00-0C36-11d5-A535-0010A401EB10}
#define NS_PERMISSIONMANAGER_CID \
{ 0x4f6b5e00, 0xc36, 0x11d5, { 0xa5, 0x35, 0x0, 0x10, 0xa4, 0x1, 0xeb, 0x10 } }
#define NS_PERMISSIONMANAGER_CONTRACTID "@mozilla.org/permissionmanager;1"
#define PERM_CHANGE_NOTIFICATION "perm-changed"
%}

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -37,7 +37,6 @@
* ***** END LICENSE BLOCK ***** */
#include "nsImgManager.h"
#include "nsImages.h"
#include "nsIDocument.h"
#include "nsIContent.h"
#include "nsCOMPtr.h"
@@ -48,60 +47,89 @@
#include "nsIScriptGlobalObject.h"
#include "nsIDOMWindow.h"
#include "nsIDocShellTreeItem.h"
#include "nsCRT.h"
#include "nsIPrefBranchInternal.h"
#include "nsIObserverService.h"
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
// Possible behavior pref values
#define IMAGE_ACCEPT 0
#define IMAGE_NOFOREIGN 1
#define IMAGE_DENY 2
////////////////////////////////////////////////////////////////////////////////
static const char kImageBehaviorPrefName[] = "network.image.imageBehavior";
static const char kImageWarningPrefName[] = "network.image.warnAboutImages";
static const char kImageBlockerPrefName[] = "imageblocker.enabled";
static const char kImageBlockImageInMailNewsPrefName[] = "mailnews.message_display.disable_remote_image";
static const PRInt32 kImageBehaviorPrefDefault = IMAGE_ACCEPT;
static const PRBool kImageWarningPrefDefault = PR_FALSE;
static const PRBool kImageBlockerPrefDefault = PR_FALSE;
static const PRBool kImageBlockImageInMailNewsPrefDefault = PR_FALSE;
////////////////////////////////////////////////////////////////////////////////
// nsImgManager Implementation
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS2(nsImgManager,
NS_IMPL_ISUPPORTS4(nsImgManager,
nsIImgManager,
nsIContentPolicy);
nsIContentPolicy,
nsIObserver,
nsSupportsWeakReference);
nsImgManager::nsImgManager()
{
}
nsImgManager::~nsImgManager(void)
nsImgManager::~nsImgManager()
{
}
nsresult nsImgManager::Init()
{
IMAGE_RegisterPrefCallbacks();
nsresult rv;
mIOService = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
return rv;
// On error, just don't use the host based lookup anymore. We can do the
// other things, like mailnews blocking
mPermissionManager = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
mPrefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIPrefBranchInternal> prefInternal = do_QueryInterface(mPrefBranch, &rv);
if (NS_SUCCEEDED(rv)) {
prefInternal->AddObserver(kImageBehaviorPrefName, this, PR_TRUE);
// We don't do anything with it yet, but let it be. (bug 110112, 146513)
prefInternal->AddObserver(kImageWarningPrefName, this, PR_TRUE);
// What is this pref, and how do you set it?
prefInternal->AddObserver(kImageBlockerPrefName, this, PR_TRUE);
prefInternal->AddObserver(kImageBlockImageInMailNewsPrefName, this, PR_TRUE);
}
}
rv = ReadPrefs();
NS_ASSERTION(NS_SUCCEEDED(rv), "Error occured reading image preferences");
NS_IMETHODIMP nsImgManager::Block(nsIURI* imageURI)
{
::IMAGE_Block(imageURI);
return NS_OK;
}
// nsIContentPolicy Implementation
NS_IMETHODIMP nsImgManager::ShouldLoad(PRInt32 aContentType,
nsIURI *aContentLoc,
nsISupports *aContext,
nsIDOMWindow *aWindow,
PRBool *_retval)
PRBool *aShouldLoad)
{
*_retval = PR_TRUE;
*aShouldLoad = PR_TRUE;
nsresult rv = NS_OK;
// we can't do anything w/ out these.
if (!aContentLoc || !aContext) return rv;
switch (aContentType) {
case nsIContentPolicy::IMAGE:
{
if (aContentType == nsIContentPolicy::IMAGE) {
// First, let be sure we are processing an HTTP or HTTPS images.
// We should not waste time with chrome url...
PRBool httpType;
@@ -114,8 +142,8 @@ NS_IMETHODIMP nsImgManager::ShouldLoad(PRInt32 aContentType,
nsCOMPtr<nsIURI> baseURI;
nsCOMPtr<nsIDocument> doc;
nsCOMPtr<nsIContent> content(do_QueryInterface(aContext));
NS_ASSERTION(content, "no content avail");
nsCOMPtr<nsIContent> content = do_QueryInterface(aContext);
NS_ASSERTION(content, "no content available");
if (content) {
rv = content->GetDocument(*getter_AddRefs(doc));
if (NS_FAILED(rv) || !doc) return rv;
@@ -124,7 +152,7 @@ NS_IMETHODIMP nsImgManager::ShouldLoad(PRInt32 aContentType,
if (NS_FAILED(rv) || !baseURI) return rv;
// Let check if we are running a mail window, doesn't matter if mail images are allowed
if (IMAGE_BlockedInMail()) {
if (mBlockInMailNewsPref) {
nsCOMPtr<nsIDocShell> docshell;
rv = GetRootDocShell(aWindow, getter_AddRefs(docshell));
if (docshell) {
@@ -132,26 +160,16 @@ NS_IMETHODIMP nsImgManager::ShouldLoad(PRInt32 aContentType,
rv = docshell->GetAppType(&appType);
if (NS_SUCCEEDED(rv) && appType == nsIDocShell::APP_TYPE_MAIL) {
//we are dealing with an mail or newsgroup window, let's block the image
*_retval = PR_FALSE;
*aShouldLoad = PR_FALSE;
return NS_OK;
}
}
}
nsCAutoString baseHost;
rv = baseURI->GetAsciiHost(baseHost);
rv = TestPermission(aContentLoc, baseURI, aShouldLoad);
if (NS_FAILED(rv)) return rv;
nsCAutoString host;
rv = aContentLoc->GetAsciiHost(host);
if (NS_FAILED(rv)) return rv;
return ::IMAGE_CheckForPermission(host.get(), baseHost.get(),
_retval);
}
}
break;
}
return NS_OK;
}
@@ -159,11 +177,165 @@ NS_IMETHODIMP nsImgManager::ShouldProcess(PRInt32 aContentType,
nsIURI *aDocumentLoc,
nsISupports *aContext,
nsIDOMWindow *aWindow,
PRBool *_retval) {
PRBool *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsImgManager::GetRootDocShell(nsIDOMWindow *aWindow, nsIDocShell **result)
NS_IMETHODIMP
nsImgManager::TestPermission(nsIURI *aCurrentURI,
nsIURI *aFirstURI,
PRBool *aPermission)
{
nsresult rv;
*aPermission = PR_TRUE;
// return if imageblocker is not enabled
// TODO: Why? Where is the pref set?
if (!mBlockerPref) {
*aPermission = (mBehaviorPref != IMAGE_DENY);
return NS_OK;
}
if (mBehaviorPref == IMAGE_DENY) {
*aPermission = PR_FALSE;
return NS_OK;
}
// Third party checking
if (mBehaviorPref == IMAGE_NOFOREIGN) {
// compare tails of names checking to see if they have a common domain
// we do this by comparing the tails of both names where each tail
// includes at least one dot
// A more generic method somewhere would be nice
nsCAutoString currentHost;
rv = aCurrentURI->GetAsciiHost(currentHost);
if (NS_FAILED(rv)) return rv;
// Search for two dots, starting at the end.
// If there are no two dots found, ++dot will turn to zero,
// that will return the entire string.
PRInt32 dot = currentHost.RFindChar('.');
dot = currentHost.RFindChar('.', dot-1);
++dot;
// Get the domain, ie the last part of the host (www.domain.com -> domain.com)
// This will break on co.uk
const nsACString &tail = Substring(currentHost, dot, currentHost.Length() - dot);
nsCAutoString firstHost;
rv = aFirstURI->GetAsciiHost(firstHost);
if (NS_FAILED(rv)) return rv;
// Get the last part of the firstUri with the same length as |tail|
const nsACString &firstTail = Substring(firstHost, dot, firstHost.Length() - dot);
// Check that both tails are the same, and that just before the tail in
// |firstUri| there is a dot. That means both url are in the same domain
if ((dot > 0 && firstHost.CharAt(dot-1) != '.') || !tail.Equals(firstTail)) {
*aPermission = PR_FALSE;
return NS_OK;
}
}
if (mPermissionManager) {
PRUint32 temp;
mPermissionManager->TestPermission(aCurrentURI, nsIPermissionManager::IMAGE_TYPE, &temp);
// Blacklist for now
*aPermission = (temp != nsIPermissionManager::DENY_ACTION);
} else {
// no premission manager, return ok
*aPermission = PR_TRUE;
}
return NS_OK;
}
NS_IMETHODIMP
nsImgManager::Observe(nsISupports *aSubject,
const char *aTopic,
const PRUnichar *aData)
{
nsresult rv;
// check the topic, and the cached prefservice
if (!mPrefBranch) {
NS_ERROR("No prefbranch");
return NS_ERROR_FAILURE;
}
if (!nsCRT::strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
// which pref changed?
NS_ConvertUCS2toUTF8 pref(aData);
if (pref.Equals(kImageBehaviorPrefName)) {
rv = mPrefBranch->GetIntPref(kImageBehaviorPrefName, &mBehaviorPref);
if (NS_FAILED(rv) || mBehaviorPref < 0 || mBehaviorPref > 2) {
mBehaviorPref = kImageBehaviorPrefDefault;
}
} else if (pref.Equals(kImageWarningPrefName)) {
rv = mPrefBranch->GetIntPref(kImageWarningPrefName, &mWarningPref);
if (NS_FAILED(rv)) {
mWarningPref = kImageWarningPrefDefault;
}
} else if (pref.Equals(kImageBlockerPrefName)) {
rv = mPrefBranch->GetIntPref(kImageBlockerPrefName, &mBlockerPref);
if (NS_FAILED(rv)) {
mBlockerPref = kImageBlockerPrefDefault;
}
} else if (pref.Equals(kImageBlockImageInMailNewsPrefName)) {
rv = mPrefBranch->GetIntPref(kImageBlockImageInMailNewsPrefName, &mBlockInMailNewsPref);
if (NS_FAILED(rv)) {
mBlockInMailNewsPref = kImageBlockImageInMailNewsPrefDefault;
}
}
}
return NS_OK;
}
nsresult
nsImgManager::ReadPrefs()
{
nsresult rv, rv2 = NS_OK;
// check the prefservice is cached
if (!mPrefBranch) {
NS_ERROR("No prefbranch");
return NS_ERROR_FAILURE;
}
rv = mPrefBranch->GetIntPref(kImageBehaviorPrefName, &mBehaviorPref);
if (NS_FAILED(rv) || mBehaviorPref < 0 || mBehaviorPref > 2) {
rv2 = rv;
mBehaviorPref = kImageBehaviorPrefDefault;
}
rv = mPrefBranch->GetBoolPref(kImageBlockerPrefName, &mBlockerPref);
if (NS_FAILED(rv)) {
rv2 = rv;
mBlockerPref = kImageWarningPrefDefault;
}
rv = mPrefBranch->GetBoolPref(kImageWarningPrefName, &mWarningPref);
if (NS_FAILED(rv)) {
rv2 = rv;
mWarningPref = kImageBlockerPrefDefault;
}
rv = mPrefBranch->GetBoolPref(kImageBlockImageInMailNewsPrefName, &mBlockInMailNewsPref);
if (NS_FAILED(rv)) {
rv2 = rv;
mBlockInMailNewsPref = kImageBlockImageInMailNewsPrefDefault;
}
return rv2;
}
NS_IMETHODIMP
nsImgManager::GetRootDocShell(nsIDOMWindow *aWindow, nsIDocShell **result)
{
nsresult rv;

View File

@@ -44,11 +44,19 @@
#include "nsCOMPtr.h"
#include "nsIIOService.h"
#include "nsIDocShell.h"
#include "nsIObserver.h"
#include "nsWeakReference.h"
#include "nsIPermissionManager.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
////////////////////////////////////////////////////////////////////////////////
class nsImgManager : public nsIImgManager,
public nsIContentPolicy
public nsIContentPolicy,
public nsIObserver,
public nsSupportsWeakReference
{
public:
@@ -56,17 +64,32 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSIIMGMANAGER
NS_DECL_NSICONTENTPOLICY
NS_DECL_NSIOBSERVER
nsImgManager();
virtual ~nsImgManager(void);
virtual ~nsImgManager();
nsresult Init();
private:
nsresult ReadPrefs();
PRBool mBlockerPref;
PRInt32 mBehaviorPref;
PRBool mWarningPref;
PRBool mBlockInMailNewsPref;
PRBool mPolicy;
protected:
NS_IMETHOD GetRootDocShell(nsIDOMWindow *aWindow, nsIDocShell **result);
// cached IOService
nsCOMPtr<nsIIOService> mIOService;
nsCOMPtr<nsIPermissionManager> mPermissionManager;
nsCOMPtr<nsIPrefBranch> mPrefBranch;
};
// {D60B3710-166D-11d5-A542-0010A401EB10}
#define NS_IMGMANAGER_CID \
{ 0xd60b3710, 0x166d, 0x11d5, { 0xa5, 0x42, 0x0, 0x10, 0xa4, 0x1, 0xeb, 0x10 } }
#endif /* nsImgManager_h__ */

View File

@@ -53,6 +53,7 @@
#include "nsICategoryManager.h"
#include "nsXPIDLString.h"
#include "nsCookiePromptService.h"
#include "nsCookiePermission.h"
// Define the constructor function for the objects
NS_GENERIC_FACTORY_CONSTRUCTOR(nsCookie)
@@ -64,6 +65,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPermissionManager, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPopupWindowManager, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCookieHTTPNotify, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsCookiePromptService)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCookiePermission, Init)
static NS_METHOD
RegisterContentPolicy(nsIComponentManager *aCompMgr, nsIFile *aPath,
@@ -140,6 +142,11 @@ static const nsModuleComponentInfo components[] = {
NS_COOKIEPROMPTSERVICE_CONTRACTID,
nsCookiePromptServiceConstructor
},
{ "CookiePermission",
NS_COOKIEPERMISSION_CID,
NS_COOKIEPERMISSION_CONTRACTID,
nsCookiePermissionConstructor
},
{ NS_COOKIEHTTPNOTIFY_CLASSNAME,
NS_COOKIEHTTPNOTIFY_CID,
NS_COOKIEHTTPNOTIFY_CONTRACTID,

View File

@@ -45,38 +45,33 @@
NS_IMPL_ISUPPORTS2(nsPermission, nsIPermission, nsISupportsWeakReference);
nsPermission::nsPermission()
: permissionHost(0)
{
}
nsPermission::nsPermission
(char * host,
PRInt32 type,
PRBool capability) {
permissionHost = host;
permissionType = type;
permissionCapability = capability;
(const nsACString &aHost,
PRUint32 aType,
PRUint32 aCapability)
: mHost(aHost),
mType(aType),
mCapability(aCapability)
{
}
nsPermission::~nsPermission(void) {
if (permissionHost)
PL_strfree(permissionHost);
nsPermission::~nsPermission() {
}
NS_IMETHODIMP nsPermission::GetHost(char * *aHost) {
if (permissionHost) {
*aHost = (char *) nsMemory::Clone(permissionHost, strlen(permissionHost) + 1);
return NS_OK;
}
return NS_ERROR_NULL_POINTER;
}
NS_IMETHODIMP nsPermission::GetType(PRInt32 *aType) {
*aType = permissionType;
NS_IMETHODIMP nsPermission::GetHost(nsACString& aHost) {
aHost = mHost;
return NS_OK;
}
NS_IMETHODIMP nsPermission::GetCapability(PRBool *aCapability) {
*aCapability = permissionCapability;
NS_IMETHODIMP nsPermission::GetType(PRUint32 *aType) {
*aType = mType;
return NS_OK;
}
NS_IMETHODIMP nsPermission::GetCapability(PRUint32 *aCapability) {
*aCapability = mCapability;
return NS_OK;
}

View File

@@ -41,27 +41,30 @@
#include "nsIPermission.h"
#include "nsWeakReference.h"
#include "nsString.h"
////////////////////////////////////////////////////////////////////////////////
class nsPermission : public nsIPermission,
public nsSupportsWeakReference {
public nsSupportsWeakReference
{
public:
// nsISupports
NS_DECL_ISUPPORTS
NS_DECL_NSIPERMISSION
// Note: following constructor takes ownership of the host string so the caller
// of the constructor must not free them
nsPermission(char * host, PRInt32 type, PRBool capability);
nsPermission(const nsACString &aHost, PRUint32 aType, PRUint32 aCapability);
nsPermission();
virtual ~nsPermission(void);
virtual ~nsPermission();
protected:
char * permissionHost;
PRInt32 permissionType;
PRBool permissionCapability;
nsCString mHost;
PRUint32 mType;
PRUint32 mCapability;
};
// {28F16D80-157B-11d5-A542-0010A401EB10}
#define NS_PERMISSION_CID \
{ 0x28f16d80, 0x157b, 0x11d5, { 0xa5, 0x42, 0x0, 0x10, 0xa4, 0x1, 0xeb, 0x10 } }
#endif /* nsPermission_h__ */

View File

@@ -38,70 +38,99 @@
#include "nsIServiceManager.h"
#include "nsPermissionManager.h"
#include "nsPermission.h"
#include "nsCRT.h"
#include "nsPermissions.h"
#include "nsIGenericFactory.h"
#include "nsXPIDLString.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDOMWindowInternal.h"
#include "nsIPrompt.h"
#include "nsIObserverService.h"
#include "nsPermission.h"
#include "nsNetUtil.h"
#include "nsILineInputStream.h"
#include "nsIPrefBranch.h"
#include "nsIPrefBranchInternal.h"
#include "nsIPrefService.h"
#include "nsAppDirectoryServiceDefs.h"
#include "prprf.h"
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_NAMED_LITERAL_CSTRING(kPermissionsFileName, "cookperm.txt");
static const char kPermissionChangeNotification[] = PERM_CHANGE_NOTIFICATION;
typedef struct {
nsCString host;
nsVoidArray permissionList;
} permission_HostStruct;
typedef struct {
PRUint32 type;
PRUint32 permission;
} permission_TypeStruct;
////////////////////////////////////////////////////////////////////////////////
class nsPermissionEnumerator : public nsISimpleEnumerator
{
public:
NS_DECL_ISUPPORTS
nsPermissionEnumerator() : mHostCount(0), mTypeCount(0)
nsPermissionEnumerator(const nsVoidArray &aPermissionList)
: mHostCount(aPermissionList.Count()),
mHostIndex(0),
mTypeIndex(0),
mPermissionList(aPermissionList)
{
}
NS_IMETHOD HasMoreElements(PRBool *result)
NS_IMETHOD GetNext(nsISupports **result);
NS_IMETHOD HasMoreElements(PRBool *aResult)
{
*result = PERMISSION_HostCount() > mHostCount;
*aResult = mHostCount > mHostIndex;
return NS_OK;
}
NS_IMETHOD GetNext(nsISupports **result)
{
char *host;
PRBool capability;
PRInt32 type;
nsresult rv = PERMISSION_Enumerate
(mHostCount, mTypeCount++, &host, &type, &capability);
if (NS_SUCCEEDED(rv)) {
if (mTypeCount == PERMISSION_TypeCount(mHostCount)) {
mTypeCount = 0;
mHostCount++;
}
nsIPermission *permission =
new nsPermission(host, type, capability);
*result = permission;
NS_ADDREF(*result);
} else {
*result = nsnull;
}
return rv;
}
virtual ~nsPermissionEnumerator()
{
}
protected:
PRInt32 mHostCount;
PRInt32 mTypeCount;
PRInt32 mHostIndex;
PRInt32 mTypeIndex;
const nsVoidArray &mPermissionList;
};
NS_IMPL_ISUPPORTS1(nsPermissionEnumerator, nsISimpleEnumerator);
NS_IMETHODIMP
nsPermissionEnumerator::GetNext(nsISupports **aResult)
{
if (mHostIndex >= mHostCount) {
*aResult = nsnull;
return NS_ERROR_FAILURE;
}
permission_HostStruct *hostStruct = NS_STATIC_CAST(permission_HostStruct*, mPermissionList.ElementAt(mHostIndex));
NS_ASSERTION(hostStruct, "corrupt permission list");
permission_TypeStruct *typeStruct = NS_STATIC_CAST(permission_TypeStruct*, hostStruct->permissionList.ElementAt(mTypeIndex++));
if (mTypeIndex == hostStruct->permissionList.Count()) {
mTypeIndex = 0;
mHostIndex++;
}
nsIPermission *permission =
new nsPermission(hostStruct->host, typeStruct->type, typeStruct->permission);
if (!permission) {
*aResult = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
*aResult = permission;
NS_ADDREF(permission);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsPermissionManager Implementation
@@ -111,65 +140,239 @@ nsPermissionManager::nsPermissionManager()
{
}
nsPermissionManager::~nsPermissionManager(void)
nsPermissionManager::~nsPermissionManager()
{
PERMISSION_RemoveAll();
RemoveAllFromMemory();
}
nsresult nsPermissionManager::Init()
{
PERMISSION_Read();
nsresult rv;
nsCOMPtr<nsIObserverService> observerService =
do_GetService("@mozilla.org/observer-service;1", &rv);
if (observerService) {
observerService->AddObserver(this, "profile-before-change", PR_FALSE);
observerService->AddObserver(this, "profile-do-change", PR_FALSE);
// Cache the permissions file
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(mPermissionsFile));
if (NS_SUCCEEDED(rv)) {
rv = mPermissionsFile->AppendNative(kPermissionsFileName);
}
mIOService = do_GetIOService();
return rv;
// Ignore an error. That is not a problem. No cookperm.txt usually.
Read();
mObserverService = do_GetService("@mozilla.org/observer-service;1", &rv);
if (NS_SUCCEEDED(rv)) {
mObserverService->AddObserver(this, "profile-before-change", PR_TRUE);
mObserverService->AddObserver(this, "profile-do-change", PR_TRUE);
}
NS_IMETHODIMP nsPermissionManager::Add
(const nsACString & objectURI, PRBool permission, PRInt32 type) {
// XXX ideally we should change this interface to pass nsIURI
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), objectURI, nsnull, nsnull, mIOService);
::PERMISSION_Add(uri, permission, type);
return NS_OK;
}
NS_IMETHODIMP nsPermissionManager::TestForBlocking
(const nsACString &objectURI, PRInt32 type, PRBool* blocked) {
// XXX ideally we should change this interface to pass nsIURI
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), objectURI, nsnull, nsnull, mIOService);
::PERMISSION_TestForBlocking(uri, blocked, type);
return NS_OK;
}
NS_IMETHODIMP nsPermissionManager::RemoveAll(void) {
::PERMISSION_RemoveAll();
::PERMISSION_DeletePersistentUserData();
return NS_OK;
}
NS_IMETHODIMP nsPermissionManager::GetEnumerator(nsISimpleEnumerator * *entries)
NS_IMETHODIMP
nsPermissionManager::Add(nsIURI *aURI,
PRUint32 aType,
PRUint32 aPermission)
{
*entries = nsnull;
NS_ASSERTION(aURI, "could not get uri");
nsresult rv;
nsPermissionEnumerator* permissionEnum = new nsPermissionEnumerator();
if (permissionEnum == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(permissionEnum);
*entries = permissionEnum;
nsCAutoString hostPort;
aURI->GetHostPort(hostPort);
if (hostPort.IsEmpty()) {
// Nothing to add
return NS_OK;
}
NS_IMETHODIMP nsPermissionManager::Remove(const nsACString & host, PRInt32 type) {
::PERMISSION_Remove(host, type);
rv = AddInternal(hostPort, aType, aPermission);
if (NS_FAILED(rv)) return rv;
// Notify permission manager dialog to update its display
//
// This used to be conditional, but now we use AddInternal
// for cases when no notification is needed
NotifyObservers(hostPort);
mChangedList = PR_TRUE;
return Write();
}
//Only add to memory, don't save. That's up to the caller.
nsresult
nsPermissionManager::AddInternal(const nsACString &aHost,
PRUint32 aType,
PRUint32 aPermission)
{
// find existing entry for host
permission_HostStruct *hostStruct;
PRBool hostFound = PR_FALSE;
PRInt32 hostCount = mPermissionList.Count();
PRInt32 hostIndex;
for (hostIndex = 0; hostIndex < hostCount; ++hostIndex) {
hostStruct = NS_STATIC_CAST(permission_HostStruct*, mPermissionList.ElementAt(hostIndex));
NS_ASSERTION(hostStruct, "corrupt permission list");
if (aHost.Equals(hostStruct->host)) {
// host found in list
hostFound = PR_TRUE;
break;
} else if (aHost < hostStruct->host) {
// Need to insert new entry here for alphabetized list
break;
}
}
if (!hostFound) {
// create a host structure for the host
hostStruct = new permission_HostStruct;
if (!hostStruct) {
return NS_ERROR_OUT_OF_MEMORY;
}
hostStruct->host = aHost;
// Insert host structure into the list
if (hostIndex < hostCount) {
mPermissionList.InsertElementAt(hostStruct, hostIndex);
} else {
mPermissionList.AppendElement(hostStruct);
}
}
// See if host already has an entry for this type
permission_TypeStruct *typeStruct;
PRInt32 typeCount = hostStruct->permissionList.Count();
for (PRInt32 typeIndex=0; typeIndex < typeCount; ++typeIndex) {
typeStruct = NS_STATIC_CAST(permission_TypeStruct*, hostStruct->permissionList.ElementAt(typeIndex));
NS_ASSERTION(typeStruct, "corrupt permission list");
if (typeStruct->type == aType) {
// Type found. Modify the corresponding permission
typeStruct->permission = aPermission;
return NS_OK;
}
}
// Create a type structure and attach it to the host structure
typeStruct = new permission_TypeStruct;
typeStruct->type = aType;
typeStruct->permission = aPermission;
hostStruct->permissionList.AppendElement(typeStruct);
return NS_OK;
}
NS_IMETHODIMP
nsPermissionManager::Remove(const nsACString &aHost,
PRUint32 aType)
{
nsresult rv;
// Find existing entry for host
permission_HostStruct *hostStruct;
PRInt32 hostCount = mPermissionList.Count();
for (PRInt32 hostIndex = 0; hostIndex < hostCount; ++hostIndex) {
hostStruct = NS_STATIC_CAST(permission_HostStruct*, mPermissionList.ElementAt(hostIndex));
NS_ASSERTION(hostStruct, "corrupt permission list");
if (aHost.Equals(hostStruct->host)) {
// Host found in list, see if it has an entry for this type
permission_TypeStruct *typeStruct;
PRInt32 typeCount = hostStruct->permissionList.Count();
for (PRInt32 typeIndex = 0; typeIndex < typeCount; ++typeIndex) {
typeStruct = NS_STATIC_CAST(permission_TypeStruct*, hostStruct->permissionList.ElementAt(typeIndex));
NS_ASSERTION(typeStruct, "corrupt permission list");
if (typeStruct->type == aType) {
delete typeStruct;
hostStruct->permissionList.RemoveElementAt(typeIndex);
--typeCount;
// If no more types are present, remove the entry
if (typeCount == 0) {
mPermissionList.RemoveElementAt(hostIndex);
delete hostStruct;
}
mChangedList = PR_TRUE;
Write();
// Notify Observers
NotifyObservers(aHost);
return NS_OK;
}
}
break;
}
}
return NS_OK;
}
NS_IMETHODIMP
nsPermissionManager::RemoveAll()
{
RemoveAllFromMemory();
Write();
return NS_OK;
}
NS_IMETHODIMP
nsPermissionManager::TestPermission(nsIURI *aURI,
PRUint32 aType,
PRUint32 *aPermission)
{
NS_ASSERTION(aURI, "could not get uri");
NS_ASSERTION(aPermission, "no permission pointer");
// set the default
*aPermission = nsIPermissionManager::UNKNOWN_ACTION;
nsCAutoString hostPort;
aURI->GetHostPort(hostPort);
// Don't error on no host. Just return UNKNOWN_ACTION as permission.
if (hostPort.IsEmpty()) {
return NS_OK;
}
permission_HostStruct *hostStruct;
permission_TypeStruct *typeStruct;
//TODO: Look for the specific host, if not found check its domains
// Do we want that? Currenty, it is not actually done
// find host name within list
PRInt32 hostCount = mPermissionList.Count();
for (PRInt32 i = 0; i < hostCount; ++i) {
hostStruct = NS_STATIC_CAST(permission_HostStruct*, mPermissionList.ElementAt(i));
NS_ASSERTION(hostStruct, "corrupt permission list");
if (hostStruct->host.Equals(hostPort)) {
// search for type in the permission list for this host
PRInt32 typeCount = hostStruct->permissionList.Count();
for (PRInt32 typeIndex = 0; typeIndex < typeCount; ++typeIndex) {
typeStruct = NS_STATIC_CAST(permission_TypeStruct*, hostStruct->permissionList.ElementAt(typeIndex));
NS_ASSERTION(typeStruct, "corrupt permission list");
if (typeStruct->type == aType) {
// type found. Obtain the corresponding permission
*aPermission = typeStruct->permission;
return NS_OK;
}
}
}
}
return NS_OK;
}
NS_IMETHODIMP nsPermissionManager::GetEnumerator(nsISimpleEnumerator **aEnum)
{
nsPermissionEnumerator* permissionEnum = new nsPermissionEnumerator(mPermissionList);
if (!permissionEnum) {
*aEnum = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(permissionEnum);
*aEnum = permissionEnum;
return NS_OK;
}
@@ -188,15 +391,228 @@ NS_IMETHODIMP nsPermissionManager::Observe(nsISupports *aSubject, const char *aT
// was accepted). If this condition ever changes, the permission
// file would need to be updated here.
PERMISSION_RemoveAll();
RemoveAllFromMemory();
if (!nsCRT::strcmp(someData, NS_LITERAL_STRING("shutdown-cleanse").get()))
PERMISSION_DeletePersistentUserData();
if (mPermissionsFile) {
mPermissionsFile->Remove(PR_FALSE);
}
}
else if (!nsCRT::strcmp(aTopic, "profile-do-change")) {
// The profile has aleady changed.
// Now just read them from the new profile location.
PERMISSION_Read();
// Re-get the permissions file
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(mPermissionsFile));
if (NS_SUCCEEDED(rv)) {
rv = mPermissionsFile->AppendNative(kPermissionsFileName);
}
Read();
}
return rv;
}
//*****************************************************************************
//*** nsPermissionManager private methods
//*****************************************************************************
nsresult
nsPermissionManager::RemoveAllFromMemory()
{
permission_HostStruct *hostStruct;
permission_TypeStruct *typeStruct;
PRInt32 hostCount = mPermissionList.Count();
for (PRInt32 hostIndex = hostCount-1; hostIndex >= 0; --hostIndex) {
hostStruct = NS_STATIC_CAST(permission_HostStruct*, mPermissionList.ElementAt(hostIndex));
NS_ASSERTION(hostStruct, "corrupt permission list");
PRInt32 typeCount = hostStruct->permissionList.Count();
for (PRInt32 typeIndex = typeCount-1; typeIndex >= 0; --typeIndex) {
typeStruct = NS_STATIC_CAST(permission_TypeStruct*, hostStruct->permissionList.ElementAt(typeIndex));
delete typeStruct;
hostStruct->permissionList.RemoveElementAt(typeIndex);
}
// no more types are present, remove the entry
mPermissionList.RemoveElementAt(hostIndex);
delete hostStruct;
}
return NS_OK;
}
// broadcast a notification that a permission pref has changed
nsresult
nsPermissionManager::NotifyObservers(const nsACString &aHost)
{
if (mObserverService) {
return mObserverService->NotifyObservers(NS_STATIC_CAST(nsIPermissionManager *, this),
kPermissionChangeNotification,
NS_ConvertUTF8toUCS2(aHost).get());
}
return NS_ERROR_FAILURE;
}
// Note:
// We don't do checkbox states here anymore.
// When a consumer wants it back, that is up to the consumer, not this backend
// For cookies, it is now done with a persist in the dialog xul file.
nsresult
nsPermissionManager::Read()
{
nsresult rv;
if (!mPermissionsFile) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIInputStream> fileInputStream;
rv = NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream), mPermissionsFile);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsILineInputStream> lineInputStream = do_QueryInterface(fileInputStream, &rv);
if (NS_FAILED(rv)) return rv;
/* format is:
* host \t number permission \t number permission ... \n
* if this format isn't respected we move onto the next line in the file.
*/
nsAutoString bufferUnicode;
nsCAutoString buffer;
PRBool isMore = PR_TRUE;
while (isMore && NS_SUCCEEDED(lineInputStream->ReadLine(bufferUnicode, &isMore))) {
CopyUCS2toASCII(bufferUnicode, buffer);
if (buffer.IsEmpty() || buffer.First() == '#') {
continue;
}
PRInt32 hostIndex, permissionIndex;
PRUint32 nextPermissionIndex = 0;
hostIndex = 0;
if ((permissionIndex = buffer.FindChar('\t', hostIndex) + 1) == 0) {
continue;
}
// ignore leading periods in host name
while (hostIndex < permissionIndex && (buffer.CharAt(hostIndex) == '.')) {
++hostIndex;
}
nsDependentCSubstring host(buffer, hostIndex, permissionIndex - hostIndex - 1);
for (;;) {
if (nextPermissionIndex == buffer.Length()+1) {
break;
}
if ((nextPermissionIndex = buffer.FindChar('\t', permissionIndex)+1) == 0) {
nextPermissionIndex = buffer.Length()+1;
}
const nsASingleFragmentCString &permissionString = Substring(buffer, permissionIndex, nextPermissionIndex - permissionIndex - 1);
permissionIndex = nextPermissionIndex;
PRUint32 type = 0;
PRUint32 index = 0;
if (permissionString.IsEmpty()) {
continue; // empty permission entry -- should never happen
}
// Parse "2T"
char c = permissionString.CharAt(index);
while (index < permissionString.Length() && c >= '0' && c <= '9') {
type = 10*type + (c-'0');
c = permissionString.CharAt(++index);
}
if (index >= permissionString.Length()) {
continue; // bad format for this permission entry
}
PRUint32 permission = (permissionString.CharAt(index) == 'T') ? nsIPermissionManager::ALLOW_ACTION : nsIPermissionManager::DENY_ACTION;
// Ignore @@@ as host. Old style checkbox status
if (!permissionString.IsEmpty() && !host.Equals(NS_LITERAL_CSTRING("@@@@"))) {
rv = AddInternal(host, type, permission);
if (NS_FAILED(rv)) return rv;
}
}
}
mChangedList = PR_FALSE;
return NS_OK;
}
nsresult
nsPermissionManager::Write()
{
nsresult rv;
if (!mChangedList) {
return NS_OK;
}
if (!mPermissionsFile) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIOutputStream> fileOutputStream;
rv = NS_NewLocalFileOutputStream(getter_AddRefs(fileOutputStream), mPermissionsFile);
if (NS_FAILED(rv)) return rv;
// get a buffered output stream 4096 bytes big, to optimize writes
nsCOMPtr<nsIOutputStream> bufferedOutputStream;
rv = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream), fileOutputStream, 4096);
if (NS_FAILED(rv)) return rv;
permission_HostStruct *hostStruct;
permission_TypeStruct *typeStruct;
static const char kHeader[] =
"# HTTP Permission File\n"
"# http://www.netscape.com/newsref/std/cookie_spec.html\n"
"# This is a generated file! Do not edit.\n\n";
bufferedOutputStream->Write(kHeader, sizeof(kHeader) - 1, &rv);
/* format shall be:
* host \t permission \t permission ... \n
*/
static const char kTab[] = "\t";
static const char kNew[] = "\n";
static const char kTrue[] = "F";
static const char kFalse[] = "T";
PRInt32 hostCount = mPermissionList.Count();
for (PRInt32 i = 0; i < hostCount; ++i) {
hostStruct = NS_STATIC_CAST(permission_HostStruct*, mPermissionList.ElementAt(i));
NS_ASSERTION(hostStruct, "corrupt permission list");
bufferedOutputStream->Write(hostStruct->host.get(), hostStruct->host.Length(), &rv);
PRUint32 typeCount = hostStruct->permissionList.Count();
for (PRUint32 typeIndex = 0; typeIndex < typeCount; ++typeIndex) {
typeStruct = NS_STATIC_CAST(permission_TypeStruct*, hostStruct->permissionList.ElementAt(typeIndex));
NS_ASSERTION(typeStruct, "corrupt permission list");
bufferedOutputStream->Write(kTab, sizeof(kTab) - 1, &rv);
char typeString[5];
PRUint32 len = PR_snprintf(typeString, sizeof(typeString), "%u", typeStruct->type);
bufferedOutputStream->Write(typeString, len, &rv);
if (typeStruct->permission == nsIPermissionManager::ALLOW_ACTION) {
bufferedOutputStream->Write(kTrue, sizeof(kTrue) - 1, &rv);
} else if (typeStruct->permission == nsIPermissionManager::DENY_ACTION) {
bufferedOutputStream->Write(kFalse, sizeof(kFalse) - 1, &rv);
}
}
bufferedOutputStream->Write(kNew, sizeof(kNew) - 1, &rv);
}
mChangedList = PR_FALSE;
return NS_OK;
}

View File

@@ -41,15 +41,19 @@
#include "nsIPermissionManager.h"
#include "nsIObserver.h"
#include "nsIObserverService.h"
#include "nsWeakReference.h"
#include "nsCOMPtr.h"
#include "nsIIOService.h"
#include "nsVoidArray.h"
#include "nsIFile.h"
////////////////////////////////////////////////////////////////////////////////
class nsPermissionManager : public nsIPermissionManager,
public nsIObserver,
public nsSupportsWeakReference {
public nsSupportsWeakReference
{
public:
// nsISupports
@@ -58,13 +62,29 @@ public:
NS_DECL_NSIOBSERVER
nsPermissionManager();
virtual ~nsPermissionManager(void);
virtual ~nsPermissionManager();
nsresult Init();
protected:
// cached IOService
nsCOMPtr<nsIIOService> mIOService;
private:
nsresult AddInternal(const nsACString &aHost,
PRUint32 aType,
PRUint32 aPermission);
nsresult Read();
nsresult Write();
nsresult NotifyObservers(const nsACString &aHost);
nsresult RemoveAllFromMemory();
nsCOMPtr<nsIObserverService> mObserverService;
nsCOMPtr<nsIFile> mPermissionsFile;
nsVoidArray mPermissionList;
PRBool mChangedList;
};
// {4F6B5E00-0C36-11d5-A535-0010A401EB10}
#define NS_PERMISSIONMANAGER_CID \
{ 0x4f6b5e00, 0xc36, 0x11d5, { 0xa5, 0x35, 0x0, 0x10, 0xa4, 0x1, 0xeb, 0x10 } }
#endif /* nsPermissionManager_h__ */

View File

@@ -39,8 +39,8 @@
#include "nsCOMPtr.h"
#include "nsCRT.h"
#include "nsPermissions.h"
#include "nsPermission.h"
#include "nsIPermissionManager.h"
#include "nsIObserverService.h"
#include "nsIPrefBranch.h"
@@ -49,69 +49,11 @@
#include "nsIServiceManagerUtils.h"
#include "nsIURI.h"
/*
The Popup Window Manager maintains popup window permissions by website.
/**
* The Popup Window Manager maintains popup window permissions by website.
*/
#define POPUP_PREF "dom.disable_open_during_load"
static const char sPopupDisablePref[] = POPUP_PREF;
static const char sPermissionChangeNotification[] = PPM_CHANGE_NOTIFICATION;
static const char sXPCOMShutdownTopic[] = NS_XPCOM_SHUTDOWN_OBSERVER_ID;
static const char sPrefChangedTopic[] = NS_PREFBRANCH_PREFCHANGE_TOPIC_ID;
class nsPopupEnumerator : public nsISimpleEnumerator
{
public:
NS_DECL_ISUPPORTS
nsPopupEnumerator() : mHostCurrent(0), mTypeCurrent(0), mHostsFound(0)
{
mHostCount = PERMISSION_HostCountForType(WINDOWPERMISSION);
}
NS_IMETHOD HasMoreElements(PRBool *result)
{
*result = mHostCount > mHostsFound;
return NS_OK;
}
NS_IMETHOD GetNext(nsISupports **result)
{
char *host;
PRBool capability;
PRInt32 type;
*result = nsnull;
while (NS_SUCCEEDED(PERMISSION_Enumerate(mHostCurrent, mTypeCurrent++, &host, &type, &capability))) {
if ((mTypeCurrent == PERMISSION_TypeCount(mHostCurrent)) || (type == WINDOWPERMISSION)) {
mTypeCurrent = 0;
mHostCurrent++;
}
if (type == WINDOWPERMISSION) {
nsIPermission *permission = new nsPermission(host, type, capability);
*result = permission;
NS_ADDREF(*result);
mHostsFound++;
break;
}
}
return NS_OK;
}
virtual ~nsPopupEnumerator()
{
}
protected:
PRInt32 mHostCurrent;
PRInt32 mTypeCurrent;
PRInt32 mHostCount;
PRInt32 mHostsFound;
};
NS_IMPL_ISUPPORTS1(nsPopupEnumerator, nsISimpleEnumerator);
static const char kPopupDisablePref[] = "dom.disable_open_during_load";
//*****************************************************************************
//*** nsPopupWindowManager object management and nsISupports
@@ -124,31 +66,35 @@ nsPopupWindowManager::nsPopupWindowManager() :
nsPopupWindowManager::~nsPopupWindowManager(void)
{
StopObservingThings();
}
NS_IMPL_ISUPPORTS2(nsPopupWindowManager,
NS_IMPL_ISUPPORTS3(nsPopupWindowManager,
nsIPopupWindowManager,
nsIObserver);
nsIObserver,
nsSupportsWeakReference);
nsresult
nsPopupWindowManager::Init()
{
mOS = do_GetService("@mozilla.org/observer-service;1");
// we bypass the permission manager API's but it still owns the underlying
// list--we need to let it do the initializing to avoid conflict.
mPermManager = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
nsCOMPtr<nsIPrefService> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
if (prefs)
prefs->GetBranch("", getter_AddRefs(mPopupPrefBranch));
nsresult rv;
mPermissionManager = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
if (mOS && mPermManager && mPopupPrefBranch) {
// initialize our local copy of the pref
Observe(NS_STATIC_CAST(nsIPopupWindowManager *, this),
sPrefChangedTopic, NS_LITERAL_STRING(POPUP_PREF).get());
return ObserveThings();
mPrefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
PRBool permission;
rv = mPrefBranch->GetBoolPref(kPopupDisablePref, &permission);
if (NS_FAILED(rv)) {
permission = PR_FALSE;
}
return NS_ERROR_FAILURE;
mPolicy = permission ? DENY_POPUP : ALLOW_POPUP;
nsCOMPtr<nsIPrefBranchInternal> prefInternal = do_QueryInterface(mPrefBranch, &rv);
if (NS_SUCCEEDED(rv)) {
prefInternal->AddObserver(kPopupDisablePref, this, PR_TRUE);
}
}
return NS_OK;
}
//*****************************************************************************
@@ -166,210 +112,56 @@ nsPopupWindowManager::GetDefaultPermission(PRUint32 *aDefaultPermission)
NS_IMETHODIMP
nsPopupWindowManager::SetDefaultPermission(PRUint32 aDefaultPermission)
{
mPolicy = (aDefaultPermission == DENY_POPUP) ? DENY_POPUP : ALLOW_POPUP;
mPolicy = aDefaultPermission;
return NS_OK;
}
NS_IMETHODIMP
nsPopupWindowManager::Add(nsIURI *aURI, PRBool aPermit)
nsPopupWindowManager::TestPermission(nsIURI *aURI, PRUint32 *aPermission)
{
NS_ENSURE_ARG_POINTER(aURI);
if (!mPermManager)
// if we couldn't initialize the permission manager Permission_AddHost()
// will create a new list that could stomp an existing cookperm.txt
return NS_ERROR_FAILURE;
NS_ENSURE_ARG_POINTER(aPermission);
nsCAutoString uri;
aURI->GetHostPort(uri);
if (uri.IsEmpty())
return NS_ERROR_FAILURE;
if (NS_SUCCEEDED(Permission_AddHost(uri, aPermit, WINDOWPERMISSION, PR_TRUE)))
return NotifyObservers(aURI);
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsPopupWindowManager::Remove(nsIURI *aURI)
{
NS_ENSURE_ARG_POINTER(aURI);
nsCAutoString uri;
aURI->GetHostPort(uri);
if (uri.IsEmpty())
return NS_ERROR_FAILURE;
PERMISSION_Remove(uri, WINDOWPERMISSION);
return NotifyObservers(aURI);
}
NS_IMETHODIMP
nsPopupWindowManager::RemoveAll()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* The underlying manager, nsPermissionManager, won't store permissions
for an url lacking a host. It's good to know these things up front.
*/
NS_IMETHODIMP
nsPopupWindowManager::TestSuitability(nsIURI *aURI, PRBool *_retval)
{
NS_ENSURE_ARG_POINTER(aURI);
NS_ENSURE_ARG_POINTER(_retval);
nsCAutoString hostPort;
aURI->GetHostPort(hostPort);
*_retval = hostPort.IsEmpty() ? PR_FALSE : PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsPopupWindowManager::TestPermission(nsIURI *aURI, PRUint32 *_retval)
{
NS_ENSURE_ARG_POINTER(aURI);
NS_ENSURE_ARG_POINTER(_retval);
*_retval = mPolicy;
nsCAutoString uri;
aURI->GetHostPort(uri);
if (uri.IsEmpty())
return NS_OK;
/* Look for the specific host, if not found check its domains */
nsresult rv;
PRBool permission;
PRInt32 offset = 0;
const char* host = uri.get();
do {
rv = permission_CheckFromList(host+offset, permission, WINDOWPERMISSION);
if (NS_SUCCEEDED(rv)) {
/* found a value for the host/domain */
*_retval = permission ? ALLOW_POPUP : DENY_POPUP;
break;
PRUint32 permit;
if (mPermissionManager) {
rv = mPermissionManager->TestPermission(aURI,
nsIPermissionManager::POPUP_TYPE,
&permit);
// Share some constants between interfaces?
if (permit == nsIPermissionManager::ALLOW_ACTION) {
*aPermission = ALLOW_POPUP;
} else if (permit == nsIPermissionManager::DENY_ACTION) {
*aPermission = DENY_POPUP;
} else {
*aPermission = mPolicy;
}
} else {
*aPermission = mPolicy;
}
/* try the parent domain */
offset = uri.FindChar('.', offset) + 1;
} while (offset > 0 );
return NS_OK;
}
NS_IMETHODIMP
nsPopupWindowManager::GetEnumerator(nsISimpleEnumerator **_retval)
{
*_retval = nsnull;
nsPopupEnumerator* popupEnum = new nsPopupEnumerator();
if (popupEnum == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(popupEnum);
*_retval = popupEnum;
return NS_OK;
}
NS_IMETHODIMP
nsPopupWindowManager::AddObserver(nsIObserver *aObserver)
{
if (mOS)
return mOS->AddObserver(aObserver, sPermissionChangeNotification, PR_FALSE);
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsPopupWindowManager::RemoveObserver(nsIObserver *aObserver)
{
if (mOS)
return mOS->RemoveObserver(aObserver, sPermissionChangeNotification);
return NS_ERROR_FAILURE;
}
//*****************************************************************************
//*** nsPopupWindowManager::nsIObserver
//*****************************************************************************
NS_IMETHODIMP
nsPopupWindowManager::Observe(nsISupports *aSubject, const char *aTopic,
nsPopupWindowManager::Observe(nsISupports *aSubject,
const char *aTopic,
const PRUnichar *aData)
{
if (nsCRT::strcmp(aTopic, sPrefChangedTopic) == 0 &&
NS_LITERAL_STRING(POPUP_PREF).Equals(aData)) {
NS_ConvertUCS2toUTF8 pref(aData);
if (pref.Equals(kPopupDisablePref)) {
// refresh our local copy of the "disable popups" pref
PRBool permission = PR_FALSE;
if (mPopupPrefBranch) {
mPopupPrefBranch->GetBoolPref(sPopupDisablePref, &permission);
if (mPrefBranch) {
mPrefBranch->GetBoolPref(kPopupDisablePref, &permission);
}
mPolicy = permission ? DENY_POPUP : ALLOW_POPUP;
} else if (nsCRT::strcmp(aTopic, sXPCOMShutdownTopic) == 0) {
// unhook cyclical references
StopObservingThings();
DeInitialize();
}
return NS_OK;
}
//*****************************************************************************
//*** nsPopupWindowManager private methods
//*****************************************************************************
/* Register for notifications of interest. That's a change in the pref
we're watching and XPCOM shutdown. */
nsresult
nsPopupWindowManager::ObserveThings()
{
nsresult rv = NS_ERROR_FAILURE;
if (mOS)
rv = mOS->AddObserver(this, sXPCOMShutdownTopic, PR_FALSE);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIPrefBranchInternal> ibranch(do_QueryInterface(mPopupPrefBranch));
if (ibranch) {
ibranch->AddObserver(sPopupDisablePref, this, PR_FALSE);
}
}
return rv;
}
// undo ObserveThings
nsresult
nsPopupWindowManager::StopObservingThings()
{
nsCOMPtr<nsIPrefBranchInternal> ibranch(do_QueryInterface(mPopupPrefBranch));
if (ibranch) {
ibranch->RemoveObserver(sPopupDisablePref, this);
}
if (mOS)
mOS->RemoveObserver(this, sXPCOMShutdownTopic);
return NS_OK;
}
// broadcast a notification that a popup pref has changed
nsresult
nsPopupWindowManager::NotifyObservers(nsIURI *aURI)
{
if (mOS) {
nsCAutoString uri;
aURI->GetSpec(uri);
return mOS->NotifyObservers(NS_STATIC_CAST(nsIPopupWindowManager *, this),
sPermissionChangeNotification, NS_ConvertUTF8toUCS2(uri).get());
}
return NS_ERROR_FAILURE;
}
// unhook cyclical references so we can be properly shut down
void
nsPopupWindowManager::DeInitialize()
{
mOS = 0;
mPermManager = 0;
mPopupPrefBranch = 0;
}

View File

@@ -45,11 +45,13 @@
#include "nsIPermissionManager.h"
#include "nsIPopupWindowManager.h"
#include "nsIPrefBranch.h"
#include "nsWeakReference.h"
class nsIURI;
class nsPopupWindowManager : public nsIPopupWindowManager,
public nsIObserver {
public nsIObserver,
public nsSupportsWeakReference {
public:
NS_DECL_ISUPPORTS
@@ -61,15 +63,9 @@ public:
nsresult Init();
private:
nsresult ObserveThings();
nsresult StopObservingThings();
nsresult NotifyObservers(nsIURI *aURI);
void DeInitialize();
PRUint32 mPolicy;
nsCOMPtr<nsIObserverService> mOS;
nsCOMPtr<nsIPermissionManager> mPermManager;
nsCOMPtr<nsIPrefBranch> mPopupPrefBranch;
nsCOMPtr<nsIPermissionManager> mPermissionManager;
nsCOMPtr<nsIPrefBranch> mPrefBranch;
};
// {4275d3f4-752a-427a-b432-14d5dda1c20b}

View File

@@ -126,7 +126,8 @@ function onload()
messageParent.appendChild(descriptionNode);
}
document.getElementById('persistDomainAcceptance').checked = params.GetInt(nsICookieAcceptDialog.REMEMBER_DECISION) > 0;
// Must we remember the decision?
params.SetInt(nsICookieAcceptDialog.REMEMBER_DECISION, document.getElementById('persistDomainAcceptance').checked);
if (cookie) {
document.getElementById('ifl_name').setAttribute("value",cookie.name);
@@ -166,7 +167,7 @@ function showhideinfo()
sizeToContent();
}
function onChangePersitence()
function onChangePersistence()
{
params.SetInt(nsICookieAcceptDialog.REMEMBER_DECISION, document.getElementById('persistDomainAcceptance').checked);
}

View File

@@ -70,8 +70,9 @@
</vbox>
<hbox id="checkboxContainer">
<checkbox id="persistDomainAcceptance" oncommand="onChangePersitence();"
label="&dialog.remember.label;" accesskey="&dialog.remember.accesskey;"/>
<checkbox id="persistDomainAcceptance" oncommand="onChangePersistence();"
label="&dialog.remember.label;" accesskey="&dialog.remember.accesskey;"
persist="checked"/>
</hbox>
</vbox>

View File

@@ -34,6 +34,7 @@
// both are necessary. popupmanager is just a special case
// of permissionmanager but does extra work on add/remove
const nsIPermissionManager = Components.interfaces.nsIPermissionManager;
var permissionmanager;
var popupmanager;
@@ -54,6 +55,7 @@
// determine which items we need to hide or disable from the task menu
function CheckForVisibility()
{
var uri = getBrowser().currentURI;
// obtain access to permissionmanager and popupmanager
// (popup manager is a wrapper around permission that does extra work)
@@ -69,17 +71,17 @@
}
// determine current state (blocked or unblocked) and hide appropriate menu item
var blocked;
var blocked = nsIPermissionManager.UNKNOWN_ACTION;
blocked =
permissionmanager.testForBlocking(window._content.location, COOKIEPERMISSION);
enableElement("AllowCookies", blocked);
enableElement("BlockCookies", !blocked);
permissionmanager.testPermission(uri, nsIPermissionManager.COOKIE_TYPE);
enableElement("AllowCookies", blocked != nsIPermissionManager.ALLOW_ACTION);
enableElement("BlockCookies", blocked != nsIPermissionManager.DENY_ACTION);
blocked =
permissionmanager.testForBlocking(window._content.location, IMAGEPERMISSION);
enableElement("AllowImages", blocked);
enableElement("BlockImages", !blocked);
permissionmanager.testPermission(uri, nsIPermissionManager.IMAGE_TYPE);
enableElement("AllowImages", blocked != nsIPermissionManager.ALLOW_ACTION);
enableElement("BlockImages", blocked != nsIPermissionManager.DENY_ACTION);
SetPopupMenuEnabledState();
@@ -104,30 +106,13 @@
}
function SetPopupMenuEnabledState() {
var suitable = false;
var blocked = false;
var blocked = nsIPermissionManager.UNKNOWN_ACTION;
var policy = pref.getBoolPref("dom.disable_open_during_load");
suitable = popupmanager.testSuitability(getBrowser().currentURI);
if (suitable) {
if (!policy) // blacklist, test if there is a permission set
blocked = (popupmanager.testPermission(getBrowser().currentURI) == Components.interfaces.nsIPopupWindowManager.DENY_POPUP);
else { // whitelist, check if it is on list
blocked = true;
var enumerator = popupmanager.getEnumerator();
while (enumerator.hasMoreElements()) {
var permission = enumerator.getNext()
.QueryInterface(Components.interfaces.nsIPermission);
if (permission.capability && getBrowser().currentURI.host == permission.host) {
blocked = false;
break;
}
}
}
}
blocked = permissionmanager.testPermission(getBrowser().currentURI, nsIPermissionManager.POPUP_TYPE);
enableElement("BlockPopups", suitable && !blocked);
enableElement("AllowPopups", suitable && blocked);
enableElement("BlockPopups", blocked != nsIPermissionManager.DENY_ACTION);
enableElement("AllowPopups", blocked != nsIPermissionManager.ALLOW_ACTION);
enableElement("ManagePopups", true);
}
@@ -147,24 +132,25 @@
return;
}
var element;
var uri = getBrowser().currentURI;
switch (action) {
case "cookieAllow":
permissionmanager.add(window._content.location, true, COOKIEPERMISSION);
permissionmanager.add(uri, nsIPermissionManager.COOKIE_TYPE, nsIPermissionManager.ALLOW_ACTION);
element = document.getElementById("AllowCookies");
alert(element.getAttribute("msg"));
break;
case "cookieBlock":
permissionmanager.add(window._content.location, false, COOKIEPERMISSION);
permissionmanager.add(uri, nsIPermissionManager.COOKIE_TYPE, nsIPermissionManager.DENY_ACTION);
element = document.getElementById("BlockCookies");
alert(element.getAttribute("msg"));
break;
case "imageAllow":
permissionmanager.add(window._content.location, true, IMAGEPERMISSION);
permissionmanager.add(uri, nsIPermissionManager.IMAGE_TYPE, nsIPermissionManager.ALLOW_ACTION);
element = document.getElementById("AllowImages");
alert(element.getAttribute("msg"));
break;
case "imageBlock":
permissionmanager.add(window._content.location, false, IMAGEPERMISSION);
permissionmanager.add(uri, nsIPermissionManager.IMAGE_TYPE, nsIPermissionManager.DENY_ACTION);
element = document.getElementById("BlockImages");
alert(element.getAttribute("msg"));
break;
@@ -178,18 +164,12 @@
switch (action) {
case "block":
if (!policy)
popupmanager.add(uri, policy);
else
popupmanager.remove(uri);
permissionmanager.add(uri, nsIPermissionManager.POPUP_TYPE, nsIPermissionManager.DENY_ACTION);
break;
case "allow":
var browsers = getBrowser().browsers;
var popupIcon = document.getElementById("popupIcon");
if (!policy)
popupmanager.remove(uri);
else
popupmanager.add(uri, policy);
permissionmanager.add(uri, nsIPermissionManager.POPUP_TYPE, nsIPermissionManager.ALLOW_ACTION);
for (var i = 0; i < browsers.length; i++) {
if (browsers[i].popupDomain == uri.host) {
browsers[i].popupDomain = null;

View File

@@ -126,7 +126,8 @@ function onload()
messageParent.appendChild(descriptionNode);
}
document.getElementById('persistDomainAcceptance').checked = params.GetInt(nsICookieAcceptDialog.REMEMBER_DECISION) > 0;
// Must we remember the decision?
params.SetInt(nsICookieAcceptDialog.REMEMBER_DECISION, document.getElementById('persistDomainAcceptance').checked);
if (cookie) {
document.getElementById('ifl_name').setAttribute("value",cookie.name);
@@ -166,7 +167,7 @@ function showhideinfo()
sizeToContent();
}
function onChangePersitence()
function onChangePersistence()
{
params.SetInt(nsICookieAcceptDialog.REMEMBER_DECISION, document.getElementById('persistDomainAcceptance').checked);
}

View File

@@ -70,8 +70,9 @@
</vbox>
<hbox id="checkboxContainer">
<checkbox id="persistDomainAcceptance" oncommand="onChangePersitence();"
label="&dialog.remember.label;" accesskey="&dialog.remember.accesskey;"/>
<checkbox id="persistDomainAcceptance" oncommand="onChangePersistence();"
label="&dialog.remember.label;" accesskey="&dialog.remember.accesskey;"
persist="checked"/>
</hbox>
</vbox>

View File

@@ -62,61 +62,12 @@ interface nsIPopupWindowManager : nsISupports {
*/
attribute PRUint32 defaultPermission;
/**
* Add permission information for a website.
* @param aURI the website to be blocked
* @param aPermit true to grant permission to the website
* false to refuse permission
*/
void add(in nsIURI aURI, in boolean aPermit);
/**
* Remove permission information for a website. Popups will be permitted
* or not depending on whether this is a white- or black-list.
* is permitted to show popups.)
* @param aURI the website to be unblocked
*/
void remove(in nsIURI aURI);
/**
* Clear permission information for all websites.
*/
void removeAll();
/**
* Test whether a website is suitable for popup permission storage.
* @param aURI the website to be tested
* @return true if permission can be stored for the website
*/
boolean testSuitability(in nsIURI aURI);
/**
* Test whether a website has permission to show a popup window.
* @param aURI the website to be tested
* @return one of the ALLOW/DENY consts defined above
* @param uri is the URI to be tested
* @return one of the enumerated permission actions defined above
*/
PRUint32 testPermission(in nsIURI aURI);
/**
* Enumerates all stored permissions
* @return an enumerator which itself returns nsISupports objects which
* can be QIed to an nsIPermission
*/
nsISimpleEnumerator getEnumerator();
/**
* This service broadcasts a PPM_CHANGE_NOTIFICATION notification
* when any popup permission changes. Add yourself as an observer.
* @param observer the observer
*/
void addObserver(in nsIObserver aObserver);
/**
* This service broadcasts a PPM_CHANGE_NOTIFICATION notification
* when any popup permission changes. Remove yourself as an observer.
* @param observer the observer
*/
void removeObserver(in nsIObserver aObserver);
PRUint32 testPermission(in nsIURI uri);
};
%{ C++

View File

@@ -462,8 +462,6 @@ nsContextMenu.prototype = {
// but cancel if it's an unsuitable URL
const PM = Components.classes["@mozilla.org/PopupWindowManager;1"]
.getService(CI.nsIPopupWindowManager);
if (!PM.testSuitability(this.popupURL))
this.popupURL = null;
}
} catch(e) {
}

View File

@@ -21,7 +21,11 @@
*
* ***** END LICENSE BLOCK ***** */
const nsIPermissionManager = Components.interfaces.nsIPermissionManager;
const popupType = nsIPermissionManager.POPUP_TYPE;
var popupManager = null;
var permissionManager = null;
var permissions = [];
@@ -31,8 +35,6 @@ var listCapability; // the capability of sites on the currently viewed list
// FALSE: current popup policy is ALLOW ALL WITH EXCEPTIONS - sites on
// the blacklist are blocked and have permission.capability = false
const POPUP_TYPE = 2;
var additions = [];
var removals = [];
@@ -66,6 +68,8 @@ var popupStringBundle;
function Startup() {
popupManager = Components.classes["@mozilla.org/PopupWindowManager;1"]
.getService(Components.interfaces.nsIPopupWindowManager);
permissionManager = Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
permissionsTree = document.getElementById("permissionsTree");
@@ -204,18 +208,21 @@ function Permission(host, number) {
}
function loadPermissions(table) {
var enumerator = popupManager.getEnumerator();
var enumerator = permissionManager.enumerator;
var count = 0;
while (enumerator.hasMoreElements()) {
var permission = enumerator.getNext()
.QueryInterface(Components.interfaces.nsIPermission);
if (permission.capability == listCapability) {
var permission = enumerator.getNext();
if (permission) {
permission = permission.QueryInterface(Components.interfaces.nsIPermission);
if ((permission.type == popupType) &&
(permission.capability == listCapability)) {
var host = permission.host;
table[count] = new Permission(host,count++);
}
}
}
}
function loadTree() {
var rowCount = permissions.length;
@@ -297,7 +304,7 @@ function deleteAllPermissions() {
}
function updatePendingRemovals(host) {
if (additions[host] != null)
if (additions[host])
additions[host] = null;
else
removals[host] = host;
@@ -317,23 +324,26 @@ function finalizeChanges() {
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var uri;
var host;
var i;
var perm = (listCapability == true) ? nsIPermissionManager.ALLOW_ACTION : nsIPermissionManager.DENY_ACTION
//note: the scheme will be taken off later, it is being added now only to
//create the uri for add/remove
for (var i in additions) {
var host = additions[i];
for (i in additions) {
host = additions[i];
if (host != null) {
host = "http://" + host;
var uri = ioService.newURI(host, null, null);
popupManager.add(uri, listCapability);
uri = ioService.newURI(host, null, null);
permissionManager.add(uri, popupType, listCapability);
}
}
for (var i in removals) {
var host = removals[i];
for (i in removals) {
host = removals[i];
if (host != null) {
host = "http://" + host;
var uri = ioService.newURI(host, null, null);
popupManager.remove(uri);
permissionManager.remove(host, popupType);
}
}

View File

@@ -21,7 +21,11 @@
*
* ***** END LICENSE BLOCK ***** */
const nsIPermissionManager = Components.interfaces.nsIPermissionManager;
const popupType = nsIPermissionManager.POPUP_TYPE;
var popupManager = null;
var permissionManager = null;
var permissions = [];
@@ -31,8 +35,6 @@ var listCapability; // the capability of sites on the currently viewed list
// FALSE: current popup policy is ALLOW ALL WITH EXCEPTIONS - sites on
// the blacklist are blocked and have permission.capability = false
const POPUP_TYPE = 2;
var additions = [];
var removals = [];
@@ -66,6 +68,8 @@ var popupStringBundle;
function Startup() {
popupManager = Components.classes["@mozilla.org/PopupWindowManager;1"]
.getService(Components.interfaces.nsIPopupWindowManager);
permissionManager = Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
permissionsTree = document.getElementById("permissionsTree");
@@ -204,18 +208,21 @@ function Permission(host, number) {
}
function loadPermissions(table) {
var enumerator = popupManager.getEnumerator();
var enumerator = permissionManager.enumerator;
var count = 0;
while (enumerator.hasMoreElements()) {
var permission = enumerator.getNext()
.QueryInterface(Components.interfaces.nsIPermission);
if (permission.capability == listCapability) {
var permission = enumerator.getNext();
if (permission) {
permission = permission.QueryInterface(Components.interfaces.nsIPermission);
if ((permission.type == popupType) &&
(permission.capability == listCapability)) {
var host = permission.host;
table[count] = new Permission(host,count++);
}
}
}
}
function loadTree() {
var rowCount = permissions.length;
@@ -297,7 +304,7 @@ function deleteAllPermissions() {
}
function updatePendingRemovals(host) {
if (additions[host] != null)
if (additions[host])
additions[host] = null;
else
removals[host] = host;
@@ -317,23 +324,26 @@ function finalizeChanges() {
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var uri;
var host;
var i;
var perm = (listCapability == true) ? nsIPermissionManager.ALLOW_ACTION : nsIPermissionManager.DENY_ACTION
//note: the scheme will be taken off later, it is being added now only to
//create the uri for add/remove
for (var i in additions) {
var host = additions[i];
for (i in additions) {
host = additions[i];
if (host != null) {
host = "http://" + host;
var uri = ioService.newURI(host, null, null);
popupManager.add(uri, listCapability);
uri = ioService.newURI(host, null, null);
permissionManager.add(uri, popupType, listCapability);
}
}
for (var i in removals) {
var host = removals[i];
for (i in removals) {
host = removals[i];
if (host != null) {
host = "http://" + host;
var uri = ioService.newURI(host, null, null);
popupManager.remove(uri);
permissionManager.remove(host, popupType);
}
}

View File

@@ -34,6 +34,7 @@
// both are necessary. popupmanager is just a special case
// of permissionmanager but does extra work on add/remove
const nsIPermissionManager = Components.interfaces.nsIPermissionManager;
var permissionmanager;
var popupmanager;
@@ -54,6 +55,7 @@
// determine which items we need to hide or disable from the task menu
function CheckForVisibility()
{
var uri = getBrowser().currentURI;
// obtain access to permissionmanager and popupmanager
// (popup manager is a wrapper around permission that does extra work)
@@ -69,17 +71,17 @@
}
// determine current state (blocked or unblocked) and hide appropriate menu item
var blocked;
var blocked = nsIPermissionManager.UNKNOWN_ACTION;
blocked =
permissionmanager.testForBlocking(window._content.location, COOKIEPERMISSION);
enableElement("AllowCookies", blocked);
enableElement("BlockCookies", !blocked);
permissionmanager.testPermission(uri, nsIPermissionManager.COOKIE_TYPE);
enableElement("AllowCookies", blocked != nsIPermissionManager.ALLOW_ACTION);
enableElement("BlockCookies", blocked != nsIPermissionManager.DENY_ACTION);
blocked =
permissionmanager.testForBlocking(window._content.location, IMAGEPERMISSION);
enableElement("AllowImages", blocked);
enableElement("BlockImages", !blocked);
permissionmanager.testPermission(uri, nsIPermissionManager.IMAGE_TYPE);
enableElement("AllowImages", blocked != nsIPermissionManager.ALLOW_ACTION);
enableElement("BlockImages", blocked != nsIPermissionManager.DENY_ACTION);
SetPopupMenuEnabledState();
@@ -104,30 +106,13 @@
}
function SetPopupMenuEnabledState() {
var suitable = false;
var blocked = false;
var blocked = nsIPermissionManager.UNKNOWN_ACTION;
var policy = pref.getBoolPref("dom.disable_open_during_load");
suitable = popupmanager.testSuitability(getBrowser().currentURI);
if (suitable) {
if (!policy) // blacklist, test if there is a permission set
blocked = (popupmanager.testPermission(getBrowser().currentURI) == Components.interfaces.nsIPopupWindowManager.DENY_POPUP);
else { // whitelist, check if it is on list
blocked = true;
var enumerator = popupmanager.getEnumerator();
while (enumerator.hasMoreElements()) {
var permission = enumerator.getNext()
.QueryInterface(Components.interfaces.nsIPermission);
if (permission.capability && getBrowser().currentURI.host == permission.host) {
blocked = false;
break;
}
}
}
}
blocked = permissionmanager.testPermission(getBrowser().currentURI, nsIPermissionManager.POPUP_TYPE);
enableElement("BlockPopups", suitable && !blocked);
enableElement("AllowPopups", suitable && blocked);
enableElement("BlockPopups", blocked != nsIPermissionManager.DENY_ACTION);
enableElement("AllowPopups", blocked != nsIPermissionManager.ALLOW_ACTION);
enableElement("ManagePopups", true);
}
@@ -147,24 +132,25 @@
return;
}
var element;
var uri = getBrowser().currentURI;
switch (action) {
case "cookieAllow":
permissionmanager.add(window._content.location, true, COOKIEPERMISSION);
permissionmanager.add(uri, nsIPermissionManager.COOKIE_TYPE, nsIPermissionManager.ALLOW_ACTION);
element = document.getElementById("AllowCookies");
alert(element.getAttribute("msg"));
break;
case "cookieBlock":
permissionmanager.add(window._content.location, false, COOKIEPERMISSION);
permissionmanager.add(uri, nsIPermissionManager.COOKIE_TYPE, nsIPermissionManager.DENY_ACTION);
element = document.getElementById("BlockCookies");
alert(element.getAttribute("msg"));
break;
case "imageAllow":
permissionmanager.add(window._content.location, true, IMAGEPERMISSION);
permissionmanager.add(uri, nsIPermissionManager.IMAGE_TYPE, nsIPermissionManager.ALLOW_ACTION);
element = document.getElementById("AllowImages");
alert(element.getAttribute("msg"));
break;
case "imageBlock":
permissionmanager.add(window._content.location, false, IMAGEPERMISSION);
permissionmanager.add(uri, nsIPermissionManager.IMAGE_TYPE, nsIPermissionManager.DENY_ACTION);
element = document.getElementById("BlockImages");
alert(element.getAttribute("msg"));
break;
@@ -178,18 +164,12 @@
switch (action) {
case "block":
if (!policy)
popupmanager.add(uri, policy);
else
popupmanager.remove(uri);
permissionmanager.add(uri, nsIPermissionManager.POPUP_TYPE, nsIPermissionManager.DENY_ACTION);
break;
case "allow":
var browsers = getBrowser().browsers;
var popupIcon = document.getElementById("popupIcon");
if (!policy)
popupmanager.remove(uri);
else
popupmanager.add(uri, policy);
permissionmanager.add(uri, nsIPermissionManager.POPUP_TYPE, nsIPermissionManager.ALLOW_ACTION);
for (var i = 0; i < browsers.length; i++) {
if (browsers[i].popupDomain == uri.host) {
browsers[i].popupDomain = null;