From 2bffee0a14aedbe0b4e507327f52ebf971506905 Mon Sep 17 00:00:00 2001 From: "stuart.morgan%alumni.case.edu" Date: Sat, 9 Jun 2007 02:44:37 +0000 Subject: [PATCH] Camino only - Bug 379326: Cocoa wrapper for nsIPermissionManager. r=josh sr=pink --- camino/Camino.xcode/project.pbxproj | 50 +++- camino/src/application/MainController.mm | 7 +- camino/src/browser/BrowserWrapper.mm | 15 +- camino/src/embedding/CHPermissionManager.h | 108 ++++++++ camino/src/embedding/CHPermissionManager.mm | 279 ++++++++++++++++++++ 5 files changed, 442 insertions(+), 17 deletions(-) create mode 100644 camino/src/embedding/CHPermissionManager.h create mode 100644 camino/src/embedding/CHPermissionManager.mm diff --git a/camino/Camino.xcode/project.pbxproj b/camino/Camino.xcode/project.pbxproj index 82bda6fbc16..bba68d8d260 100644 --- a/camino/Camino.xcode/project.pbxproj +++ b/camino/Camino.xcode/project.pbxproj @@ -4141,6 +4141,7 @@ DEE9EBA50AF5C379002BC511, DEB968190B0D8E0B0023F8B1, DEE34A550B84F5C600BCD687, + DE6D27E50C1A013800292043, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -5246,6 +5247,7 @@ DEE9EBA80AF5C390002BC511, DEB968160B0D8DF70023F8B1, DEE34A580B84F5E100BCD687, + DE6D27E80C1A014D00292043, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -8009,6 +8011,7 @@ DEE9EBA40AF5C379002BC511, DEB968180B0D8E0B0023F8B1, DEE34A540B84F5C600BCD687, + DE6D27E40C1A013800292043, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -9115,6 +9118,7 @@ DEE9EBA70AF5C390002BC511, DEB968150B0D8DF70023F8B1, DEE34A570B84F5E100BCD687, + DE6D27E70C1A014D00292043, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; @@ -13795,6 +13799,48 @@ settings = { }; }; + DE6D27E30C1A013800292043 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = CHPermissionManager.h; + path = src/embedding/CHPermissionManager.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + DE6D27E40C1A013800292043 = { + fileRef = DE6D27E30C1A013800292043; + isa = PBXBuildFile; + settings = { + }; + }; + DE6D27E50C1A013800292043 = { + fileRef = DE6D27E30C1A013800292043; + isa = PBXBuildFile; + settings = { + }; + }; + DE6D27E60C1A014D00292043 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.objcpp; + name = CHPermissionManager.mm; + path = src/embedding/CHPermissionManager.mm; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + DE6D27E70C1A014D00292043 = { + fileRef = DE6D27E60C1A014D00292043; + isa = PBXBuildFile; + settings = { + }; + }; + DE6D27E80C1A014D00292043 = { + fileRef = DE6D27E60C1A014D00292043; + isa = PBXBuildFile; + settings = { + }; + }; DE74F7470AB25E7D00FD1D5B = { fileEncoding = 30; isa = PBXFileReference; @@ -15424,9 +15470,11 @@ F632AF8302B9AEBB01000103, F5AE04B20206A34801A967DF, F5125A110202064D01FAFD9F, + F529788A0371820B01026DCE, F558B1F0030F6E470166970F, F5DE10E80209DC0601A967DF, F5DE10E70209DC0601A967DF, + DE6D27E30C1A013800292043, 0FC4B33D08941B4F009C5F41, F5C8D55203A2A42401A8016F, F566BD1202EFA9AD01A967F3, @@ -16382,11 +16430,11 @@ }; F558B1F603107E4A0166970F = { children = ( - F529788A0371820B01026DCE, F529788B0371820B01026DCE, F5DE10EB0209DC0601A967DF, F558B1F1030F6E470166970F, F5DE10EA0209DC0601A967DF, + DE6D27E60C1A014D00292043, DEA548490A251FA900186C93, ); isa = PBXGroup; diff --git a/camino/src/application/MainController.mm b/camino/src/application/MainController.mm index 3d800d4b07f..32d07b28388 100644 --- a/camino/src/application/MainController.mm +++ b/camino/src/application/MainController.mm @@ -72,6 +72,7 @@ #import "SharedMenusObj.h" #import "SiteIconProvider.h" #import "SessionManager.h" +#import "CHPermissionManager.h" #include "nsBuildID.h" #include "nsCOMPtr.h" @@ -87,7 +88,6 @@ #include "nsIObserverService.h" #include "nsIGenericFactory.h" #include "nsNetCID.h" -#include "nsIPermissionManager.h" #include "nsICookieManager.h" #include "nsIBrowserHistory.h" #include "nsICacheService.h" @@ -965,10 +965,7 @@ NSString* const kPreviousSessionTerminatedNormallyKey = @"PreviousSessionTermina mCookieManager->RemoveAll(); // remove site permissions - nsCOMPtr pm(do_GetService(NS_PERMISSIONMANAGER_CONTRACTID)); - nsIPermissionManager* mPermissionManager = pm.get(); - if (mPermissionManager) - mPermissionManager->RemoveAll(); + [[CHPermissionManager permissionManager] removeAllPermissions]; // remove history nsCOMPtr hist (do_GetService("@mozilla.org/browser/global-history;2")); diff --git a/camino/src/browser/BrowserWrapper.mm b/camino/src/browser/BrowserWrapper.mm index 18af17ab57b..de8487499ac 100644 --- a/camino/src/browser/BrowserWrapper.mm +++ b/camino/src/browser/BrowserWrapper.mm @@ -51,12 +51,12 @@ #import "KeychainService.h" #import "AutoCompleteTextField.h" #import "RolloverImageButton.h" +#import "CHPermissionManager.h" #include "CHBrowserService.h" #include "ContentClickListener.h" #include "nsCOMPtr.h" -#include "nsIServiceManager.h" #ifdef MOZILLA_1_8_BRANCH #include "nsIArray.h" @@ -80,7 +80,6 @@ #include "nsIDOMEventTarget.h" #include "nsIWebProgressListener.h" #include "nsIBrowserDOMWindow.h" -#include "nsIPermissionManager.h" #include "nsIScriptSecurityManager.h" class nsIDOMPopupBlockedEvent; @@ -1140,15 +1139,9 @@ enum StatusPriority { - (BOOL)popupsAreBlacklistedForURL:(NSString*)inURL { - nsCOMPtr uri; - NS_NewURI(getter_AddRefs(uri), [inURL UTF8String]); - nsCOMPtr pm(do_GetService(NS_PERMISSIONMANAGER_CONTRACTID)); - if (pm && uri) { - PRUint32 permission; - pm->TestPermission(uri, "popup", &permission); - return (permission == nsIPermissionManager::DENY_ACTION); - } - return NO; + int policy = [[CHPermissionManager permissionManager] policyForURI:inURL + type:CHPermissionTypePopup]; + return (policy == CHPermissionDeny); } // diff --git a/camino/src/embedding/CHPermissionManager.h b/camino/src/embedding/CHPermissionManager.h new file mode 100644 index 00000000000..e9c61352eba --- /dev/null +++ b/camino/src/embedding/CHPermissionManager.h @@ -0,0 +1,108 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** 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 Camino code. +* +* The Initial Developer of the Original Code is +* Stuart Morgan +* Portions created by the Initial Developer are Copyright (C) 2007 +* the Initial Developer. All Rights Reserved. +* +* Contributor(s): +* Stuart Morgan +* +* 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 ***** */ + +#import + +class nsIPermission; +class nsIPermissionManager; + +// Policy constants. +extern const int CHPermissionUnknown; +extern const int CHPermissionAllow; +extern const int CHPermissionDeny; +extern const int CHPermissionAllowForSession; // meaningful for cookies only + +// Permission type constants. +extern NSString* const CHPermissionTypeCookie; +extern NSString* const CHPermissionTypePopup; + +// An object encompasing a specific permission entry. Used only for enumerating +// existing permissions; to check or set the permissions for a single host, +// use CHPermissionManager directly. +@interface CHPermission : NSObject { + @private + NSString* mHost; // strong + NSString* mType; // strong + int mPolicy; +} + +// The host the permission applies to. +- (NSString*)host; + +// The type of the permission. May be an arbitrary value, but common values +// are defined in the CHPermissionType* constants. +- (NSString*)type; + +// The policy for the permission. May be an arbitrary value, but common values +// are defined in the CHPermission* constants. +- (int)policy; +- (void)setPolicy:(int)policy; + +@end + +#pragma mark - + +// The object responsible for querying and setting the permissions (cookies, +// popups, etc.) of specific hosts. Wraps the Gecko nsIPermissionManager. +@interface CHPermissionManager : NSObject { + @private + nsIPermissionManager* mManager; // strong +} + +// Returns the shared CHPermissionManager instance. ++ (CHPermissionManager*)permissionManager; + +// Gets all permissions of the given type. |type| can be an arbitrary value, +// but common types are defined in the CHPermissionType* constants. +- (NSArray*)permissionsOfType:(NSString*)type; + +// Removes a specific permission for host |host| +- (void)removePermissionForHost:(NSString*)host type:(NSString*)type; + +// Clears all permissions, of all types, far all hosts. Handle with care. +- (void)removeAllPermissions; + +// Getters and setters for individual site policies. Sites can be specified +// either by host (www.foo.com) or full URI. Policy and type may be arbitrary +// values, but common values are defined as constants above. +- (int)policyForHost:(NSString*)host type:(NSString*)type; +- (int)policyForURI:(NSString*)uri type:(NSString*)type; +- (void)setPolicy:(int)policy forHost:(NSString*)host type:(NSString*)type; +- (void)setPolicy:(int)policy forURI:(NSString*)uri type:(NSString*)type; + +@end diff --git a/camino/src/embedding/CHPermissionManager.mm b/camino/src/embedding/CHPermissionManager.mm new file mode 100644 index 00000000000..1d3463ce3aa --- /dev/null +++ b/camino/src/embedding/CHPermissionManager.mm @@ -0,0 +1,279 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** 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 Camino code. +* +* The Initial Developer of the Original Code is +* Stuart Morgan +* Portions created by the Initial Developer are Copyright (C) 2007 +* the Initial Developer. All Rights Reserved. +* +* Contributor(s): +* Stuart Morgan +* +* 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 ***** */ + +// TODO: re-vend PERM_CHANGE_NOTIFICATIONs in a Cocoa-y way. + +#import "CHPermissionManager.h" + +// For shutdown notification names. +#import "CHBrowserService.h" + +#include "nsCOMPtr.h" +#include "nsString.h" +#include "nsServiceManagerUtils.h" +#include "nsIPermission.h" +#include "nsIPermissionManager.h" +#include "nsICookiePermission.h" +#include "nsISimpleEnumerator.h" +#include "nsIURI.h" +#include "nsNetUtil.h" + +#pragma mark Policy Definitions + +const int CHPermissionUnknown = nsIPermissionManager::UNKNOWN_ACTION; +const int CHPermissionAllow = nsIPermissionManager::ALLOW_ACTION; +const int CHPermissionDeny = nsIPermissionManager::DENY_ACTION; +const int CHPermissionAllowForSession = nsICookiePermission::ACCESS_SESSION; + +#pragma mark Permission Type Definitions + +NSString* const CHPermissionTypeCookie = @"cookie"; +NSString* const CHPermissionTypePopup = @"popup"; + +#pragma mark - + +@interface CHPermission (CHPermissionManagerMethods) +- (id)initWithGeckoPermission:(nsIPermission*)geckoPermission; +@end + +@implementation CHPermission + +// Creates an autoreleased Cocoa-ized version of the given gecko permission +// object. Note that it has its own copy of the data, and doesn't actually +// hold a ref to the gecko permission. ++ (id)permissionWithGeckoPermission:(nsIPermission*)geckoPermission +{ + return [[[self alloc] initWithGeckoPermission:geckoPermission] autorelease]; +} + +- (id)initWithGeckoPermission:(nsIPermission*)geckoPermission +{ + if ((self = [super init])) { + if (!geckoPermission) { + [self release]; + return nil; + } + // nsIPermission is just a glorified struct, so there's no reason to keep it + // around; just convert it into a Cocoa-y data store. + nsCAutoString host; + geckoPermission->GetHost(host); + mHost = [[NSString alloc] initWithCString:host.get()]; + nsCAutoString type; + geckoPermission->GetType(type); + mType = [[NSString alloc] initWithCString:type.get()]; + PRUint32 policy; + geckoPermission->GetCapability(&policy); + mPolicy = policy; + } + return self; +} + +- (void)delloc +{ + [mHost release]; + [mType release]; + + [super dealloc]; +} + +- (NSString*)host +{ + return mHost; +} + +- (NSString*)type +{ + return mType; +} + +- (int)policy +{ + return mPolicy; +} + +// Convenience method allowing Permission objects to act like they are +// mutable and work correctly, even though they aren't hooked up to anything. +- (void)setPolicy:(int)policy +{ + mPolicy = policy; + [[CHPermissionManager permissionManager] setPolicy:policy forHost:mHost type:mType]; +} + +- (NSString*)description +{ + return [NSString stringWithFormat:@"", + self, [self host], [self type], [self policy]]; +} + +@end + +#pragma mark - + +static CHPermissionManager* sPermissionManager = nil; + +@implementation CHPermissionManager + ++ (CHPermissionManager*)permissionManager +{ + if (!sPermissionManager) + sPermissionManager = [[self alloc] init]; + return sPermissionManager; +} + +- (id)init +{ + if ((self = [super init])) { + nsCOMPtr pm(do_GetService(NS_PERMISSIONMANAGER_CONTRACTID)); + mManager = pm.get(); + if (!mManager) { + [self release]; + return nil; + } + NS_ADDREF(mManager); + + // Register for xpcom shutdown so that we can release the manager. + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(xpcomShutdown:) + name:XPCOMShutDownNotificationName + object:nil]; + } + return self; +} + +- (void)dealloc +{ + sPermissionManager = nil; + NS_IF_RELEASE(mManager); + + [super dealloc]; +} + +- (void)xpcomShutdown:(NSNotification*)notification +{ + // This nulls out the pointer + NS_IF_RELEASE(mManager); +} + +- (NSArray*)permissionsOfType:(NSString*)type +{ + if (!mManager) + return nil; + const char* typeCString = [type UTF8String]; + + nsCOMPtr permEnumerator; + mManager->GetEnumerator(getter_AddRefs(permEnumerator)); + + if (!permEnumerator) + return nil; + + NSMutableArray* permissions = [NSMutableArray array]; + + // There's no corresponding accessor for nsIPermissionManager, so we have + // to walk all permissions and check the type of each one. + PRBool hasMoreElements; + permEnumerator->HasMoreElements(&hasMoreElements); + while (hasMoreElements) { + nsCOMPtr curr; + permEnumerator->GetNext(getter_AddRefs(curr)); + nsCOMPtr currPerm(do_QueryInterface(curr)); + if (currPerm) { + nsCAutoString type; + currPerm->GetType(type); + if (type.Equals(typeCString)) { + CHPermission* perm = [CHPermission permissionWithGeckoPermission:currPerm.get()]; + [permissions addObject:perm]; + } + } + permEnumerator->HasMoreElements(&hasMoreElements); + } + return permissions; +} + +- (void)removePermissionForHost:(NSString*)host type:(NSString*)type +{ + if (!mManager) + return; + mManager->Remove(nsDependentCString([host UTF8String]), [type UTF8String]); +} + +- (void)removeAllPermissions +{ + if (!mManager) + return; + mManager->RemoveAll(); +} + +- (int)policyForHost:(NSString*)host type:(NSString*)type +{ + // Even though the permissons are host-based, the Gecko API requires an + // nsIURI, so we have to construct a dummy URI and look it up that way. + return [self policyForURI:[NSString stringWithFormat:@"http://%@", host] type:type]; +} + +- (int)policyForURI:(NSString*)uri type:(NSString*)type +{ + if (!mManager) + return CHPermissionUnknown; + nsCOMPtr geckoURI; + NS_NewURI(getter_AddRefs(geckoURI), [uri UTF8String]); + if (!geckoURI) + return CHPermissionUnknown; + PRUint32 policy; + mManager->TestPermission(geckoURI, [type UTF8String], &policy); + return policy; +} + +- (void)setPolicy:(int)policy forHost:(NSString*)host type:(NSString*)type +{ + // Even though the permissons are host-based, the Gecko API requires an + // nsIURI, so we have to construct a dummy URI and look it up that way. + [self setPolicy:policy forURI:[NSString stringWithFormat:@"http://%@", host] type:type]; +} + +- (void)setPolicy:(int)policy forURI:(NSString*)uri type:(NSString*)type +{ + if (!mManager) + return; + nsCOMPtr geckoURI; + NS_NewURI(getter_AddRefs(geckoURI), [uri UTF8String]); + if (!geckoURI) + return; + mManager->Add(geckoURI, [type UTF8String], policy); +} + +@end