diff options
Diffstat (limited to 'plugins/cordova-plugin-whitelist/src')
3 files changed, 281 insertions, 0 deletions
diff --git a/plugins/cordova-plugin-whitelist/src/android/WhitelistPlugin.java b/plugins/cordova-plugin-whitelist/src/android/WhitelistPlugin.java new file mode 100644 index 00000000..4e4f57e1 --- /dev/null +++ b/plugins/cordova-plugin-whitelist/src/android/WhitelistPlugin.java @@ -0,0 +1,161 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +package org.apache.cordova.whitelist; + +import org.apache.cordova.CordovaPlugin; +import org.apache.cordova.ConfigXmlParser; +import org.apache.cordova.Whitelist; +import org.xmlpull.v1.XmlPullParser; + +import android.content.Context; +import android.util.Log; + +public class WhitelistPlugin extends CordovaPlugin { + private static final String LOG_TAG = "WhitelistPlugin"; + private Whitelist allowedNavigations; + private Whitelist allowedIntents; + private Whitelist allowedRequests; + + // Used when instantiated via reflection by PluginManager + public WhitelistPlugin() { + } + // These can be used by embedders to allow Java-configuration of whitelists. + public WhitelistPlugin(Context context) { + this(new Whitelist(), new Whitelist(), null); + new CustomConfigXmlParser().parse(context); + } + public WhitelistPlugin(XmlPullParser xmlParser) { + this(new Whitelist(), new Whitelist(), null); + new CustomConfigXmlParser().parse(xmlParser); + } + public WhitelistPlugin(Whitelist allowedNavigations, Whitelist allowedIntents, Whitelist allowedRequests) { + if (allowedRequests == null) { + allowedRequests = new Whitelist(); + allowedRequests.addWhiteListEntry("file:///*", false); + allowedRequests.addWhiteListEntry("data:*", false); + } + this.allowedNavigations = allowedNavigations; + this.allowedIntents = allowedIntents; + this.allowedRequests = allowedRequests; + } + @Override + public void pluginInitialize() { + if (allowedNavigations == null) { + allowedNavigations = new Whitelist(); + allowedIntents = new Whitelist(); + allowedRequests = new Whitelist(); + new CustomConfigXmlParser().parse(webView.getContext()); + } + } + + private class CustomConfigXmlParser extends ConfigXmlParser { + @Override + public void handleStartTag(XmlPullParser xml) { + String strNode = xml.getName(); + if (strNode.equals("content")) { + String startPage = xml.getAttributeValue(null, "src"); + allowedNavigations.addWhiteListEntry(startPage, false); + } else if (strNode.equals("allow-navigation")) { + String origin = xml.getAttributeValue(null, "href"); + if ("*".equals(origin)) { + allowedNavigations.addWhiteListEntry("http://*/*", false); + allowedNavigations.addWhiteListEntry("https://*/*", false); + allowedNavigations.addWhiteListEntry("data:*", false); + } else { + allowedNavigations.addWhiteListEntry(origin, false); + } + } else if (strNode.equals("allow-intent")) { + String origin = xml.getAttributeValue(null, "href"); + allowedIntents.addWhiteListEntry(origin, false); + } else if (strNode.equals("access")) { + String origin = xml.getAttributeValue(null, "origin"); + String subdomains = xml.getAttributeValue(null, "subdomains"); + boolean external = (xml.getAttributeValue(null, "launch-external") != null); + if (origin != null) { + if (external) { + Log.w(LOG_TAG, "Found <access launch-external> within config.xml. Please use <allow-intent> instead."); + allowedIntents.addWhiteListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase("true") == 0)); + } else { + if ("*".equals(origin)) { + allowedRequests.addWhiteListEntry("http://*/*", false); + allowedRequests.addWhiteListEntry("https://*/*", false); + } else { + allowedRequests.addWhiteListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase("true") == 0)); + } + } + } + } + } + @Override + public void handleEndTag(XmlPullParser xml) { + } + } + + @Override + public Boolean shouldAllowNavigation(String url) { + if (allowedNavigations.isUrlWhiteListed(url)) { + return true; + } + return null; // Default policy + } + + @Override + public Boolean shouldAllowRequest(String url) { + if (Boolean.TRUE == shouldAllowNavigation(url)) { + return true; + } + if (allowedRequests.isUrlWhiteListed(url)) { + return true; + } + return null; // Default policy + } + + @Override + public Boolean shouldOpenExternalUrl(String url) { + if (allowedIntents.isUrlWhiteListed(url)) { + return true; + } + return null; // Default policy + } + + public Whitelist getAllowedNavigations() { + return allowedNavigations; + } + + public void setAllowedNavigations(Whitelist allowedNavigations) { + this.allowedNavigations = allowedNavigations; + } + + public Whitelist getAllowedIntents() { + return allowedIntents; + } + + public void setAllowedIntents(Whitelist allowedIntents) { + this.allowedIntents = allowedIntents; + } + + public Whitelist getAllowedRequests() { + return allowedRequests; + } + + public void setAllowedRequests(Whitelist allowedRequests) { + this.allowedRequests = allowedRequests; + } +} diff --git a/plugins/cordova-plugin-whitelist/src/ios/CDVNavigationWhitelistPlugin.h b/plugins/cordova-plugin-whitelist/src/ios/CDVNavigationWhitelistPlugin.h new file mode 100644 index 00000000..d0b93654 --- /dev/null +++ b/plugins/cordova-plugin-whitelist/src/ios/CDVNavigationWhitelistPlugin.h @@ -0,0 +1,31 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +#import <UIKit/UIKit.h> +#import <Cordova/CDVPlugin.h> +#import <Cordova/CDVWhitelist.h> + +@interface CDVNavigationWhitelistPlugin : CDVPlugin {} + +@property (nonatomic, readonly, strong) CDVWhitelist* whitelist; // readonly for public + +- (BOOL)shouldAllowNavigationToURL:(NSURL *)url; +- (BOOL)shouldAllowRequestForURL:(NSURL *)url; + +@end diff --git a/plugins/cordova-plugin-whitelist/src/ios/CDVNavigationWhitelistPlugin.m b/plugins/cordova-plugin-whitelist/src/ios/CDVNavigationWhitelistPlugin.m new file mode 100644 index 00000000..5895e89b --- /dev/null +++ b/plugins/cordova-plugin-whitelist/src/ios/CDVNavigationWhitelistPlugin.m @@ -0,0 +1,89 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +#import "CDVNavigationWhitelistPlugin.h" +#import <Cordova/CDVViewController.h> + +#pragma mark CDVNavigationWhitelistConfigParser + +@interface CDVNavigationWhitelistConfigParser : NSObject <NSXMLParserDelegate> {} + +@property (nonatomic, strong) NSMutableArray* whitelistHosts; + +@end + +@implementation CDVNavigationWhitelistConfigParser + +@synthesize whitelistHosts; + +- (id)init +{ + self = [super init]; + if (self != nil) { + self.whitelistHosts = [[NSMutableArray alloc] initWithCapacity:30]; + [self.whitelistHosts addObject:@"file:///*"]; + [self.whitelistHosts addObject:@"content:///*"]; + [self.whitelistHosts addObject:@"data:///*"]; + } + return self; +} + +- (void)parser:(NSXMLParser*)parser didStartElement:(NSString*)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString*)qualifiedName attributes:(NSDictionary*)attributeDict +{ + if ([elementName isEqualToString:@"allow-navigation"]) { + [whitelistHosts addObject:attributeDict[@"href"]]; + } +} + +- (void)parser:(NSXMLParser*)parser didEndElement:(NSString*)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString*)qualifiedName +{ +} + +- (void)parser:(NSXMLParser*)parser parseErrorOccurred:(NSError*)parseError +{ + NSAssert(NO, @"config.xml parse error line %ld col %ld", (long)[parser lineNumber], (long)[parser columnNumber]); +} + + +@end + +#pragma mark CDVNavigationWhitelistPlugin + +@interface CDVNavigationWhitelistPlugin () {} +@property (nonatomic, strong) CDVWhitelist* whitelist; +@end + +@implementation CDVNavigationWhitelistPlugin + +@synthesize whitelist; + +- (void)setViewController:(UIViewController *)viewController +{ + if ([viewController isKindOfClass:[CDVViewController class]]) { + CDVWhitelistConfigParser *whitelistConfigParser = [[CDVWhitelistConfigParser alloc] init]; + [(CDVViewController *)viewController parseSettingsWithParser:whitelistConfigParser]; + self.whitelist = [[CDVWhitelist alloc] initWithArray:whitelistConfigParser.whitelistHosts]; + } +} + +- (BOOL)shouldAllowNavigationToURL:(NSURL *)url +{ + return [self.whitelist URLIsAllowed:url]; +} +@end |
