CB-7291: Add external-launch-whitelist and use it for filtering intent launches
Project: http://git-wip-us.apache.org/repos/asf/cordova-amazon-fireos/repo Commit: http://git-wip-us.apache.org/repos/asf/cordova-amazon-fireos/commit/bb2029db Tree: http://git-wip-us.apache.org/repos/asf/cordova-amazon-fireos/tree/bb2029db Diff: http://git-wip-us.apache.org/repos/asf/cordova-amazon-fireos/diff/bb2029db Branch: refs/heads/master Commit: bb2029db21e78bc307e9fefb4eb1e6761e3ba2b4 Parents: e5e5c5e Author: Ian Clelland <[email protected]> Authored: Tue Aug 12 11:02:55 2014 -0400 Committer: Archana Naik <[email protected]> Committed: Thu Aug 28 11:38:47 2014 -0700 ---------------------------------------------------------------------- framework/src/org/apache/cordova/Config.java | 24 +++++++++++++++++--- .../src/org/apache/cordova/ConfigXmlParser.java | 12 +++++++--- .../src/org/apache/cordova/CordovaActivity.java | 12 ++++++---- .../org/apache/cordova/CordovaUriHelper.java | 15 ++++++++---- .../src/org/apache/cordova/CordovaWebView.java | 24 +++++++++++++------- 5 files changed, 64 insertions(+), 23 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cordova-amazon-fireos/blob/bb2029db/framework/src/org/apache/cordova/Config.java ---------------------------------------------------------------------- diff --git a/framework/src/org/apache/cordova/Config.java b/framework/src/org/apache/cordova/Config.java index 39108ed..caf3f44 100644 --- a/framework/src/org/apache/cordova/Config.java +++ b/framework/src/org/apache/cordova/Config.java @@ -58,7 +58,7 @@ public class Config { Log.e(TAG, "Config was not initialised. Did you forget to Config.init(this)?"); return; } - parser.getWhitelist().addWhiteListEntry(origin, subdomains); + parser.getInternalWhitelist().addWhiteListEntry(origin, subdomains); } /** @@ -72,7 +72,21 @@ public class Config { Log.e(TAG, "Config was not initialised. Did you forget to Config.init(this)?"); return false; } - return parser.getWhitelist().isUrlWhiteListed(url); + return parser.getInternalWhitelist().isUrlWhiteListed(url); + } + + /** + * Determine if URL is in approved list of URLs to launch external applications. + * + * @param url + * @return true if whitelisted + */ + public static boolean isUrlExternallyWhiteListed(String url) { + if (parser == null) { + Log.e(TAG, "Config was not initialised. Did you forget to Config.init(this)?"); + return false; + } + return parser.getExternalWhitelist().isUrlWhiteListed(url); } public static String getStartUrl() { @@ -87,7 +101,11 @@ public class Config { } public static Whitelist getWhitelist() { - return parser.getWhitelist(); + return parser.getInternalWhitelist(); + } + + public static Whitelist getExternalWhitelist() { + return parser.getExternalWhitelist(); } public static List<PluginEntry> getPluginEntries() { http://git-wip-us.apache.org/repos/asf/cordova-amazon-fireos/blob/bb2029db/framework/src/org/apache/cordova/ConfigXmlParser.java ---------------------------------------------------------------------- diff --git a/framework/src/org/apache/cordova/ConfigXmlParser.java b/framework/src/org/apache/cordova/ConfigXmlParser.java index cc5b2fa..1ada1af 100644 --- a/framework/src/org/apache/cordova/ConfigXmlParser.java +++ b/framework/src/org/apache/cordova/ConfigXmlParser.java @@ -37,11 +37,16 @@ public class ConfigXmlParser { private String launchUrl = "file:///android_asset/www/index.html"; private CordovaPreferences prefs = new CordovaPreferences(); - private Whitelist whitelist = new Whitelist(); + private Whitelist internalWhitelist = new Whitelist(); + private Whitelist externalWhitelist = new Whitelist(); private ArrayList<PluginEntry> pluginEntries = new ArrayList<PluginEntry>(20); - public Whitelist getWhitelist() { - return whitelist; + public Whitelist getInternalWhitelist() { + return internalWhitelist; + } + + public Whitelist getExternalWhitelist() { + return externalWhitelist; } public CordovaPreferences getPreferences() { @@ -109,6 +114,7 @@ public class ConfigXmlParser { 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) { externalWhitelist.addWhiteListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase("true") == 0)); http://git-wip-us.apache.org/repos/asf/cordova-amazon-fireos/blob/bb2029db/framework/src/org/apache/cordova/CordovaActivity.java ---------------------------------------------------------------------- diff --git a/framework/src/org/apache/cordova/CordovaActivity.java b/framework/src/org/apache/cordova/CordovaActivity.java index d3dc793..2da39cb 100755 --- a/framework/src/org/apache/cordova/CordovaActivity.java +++ b/framework/src/org/apache/cordova/CordovaActivity.java @@ -144,7 +144,8 @@ public class CordovaActivity extends Activity implements CordovaInterface { private static final String ERROR_DIALOG_OK_BUTTON = "OK"; // Read from config.xml: protected CordovaPreferences preferences; - protected Whitelist whitelist; + protected Whitelist internalWhitelist; + protected Whitelist externalWhitelist; protected String launchUrl; protected ArrayList<PluginEntry> pluginEntries; @@ -232,7 +233,8 @@ public class CordovaActivity extends Activity implements CordovaInterface { preferences = parser.getPreferences(); preferences.setPreferencesBundle(getIntent().getExtras()); preferences.copyIntoIntentExtras(this); - whitelist = parser.getWhitelist(); + internalWhitelist = parser.getInternalWhitelist(); + externalWhitelist = parser.getExternalWhitelist(); launchUrl = parser.getLaunchUrl(); pluginEntries = parser.getPluginEntries(); Config.parser = parser; @@ -415,7 +417,7 @@ public class CordovaActivity extends Activity implements CordovaInterface { if (appView.pluginManager == null) { appView.init(this, webViewClient != null ? webViewClient : makeWebViewClient(appView), webChromeClient != null ? webChromeClient : makeChromeClient(appView), - pluginEntries, whitelist, preferences); + pluginEntries, internalWhitelist, externalWhitelist, preferences); } // TODO: Have the views set this themselves. @@ -902,7 +904,7 @@ public class CordovaActivity extends Activity implements CordovaInterface { // If errorUrl specified, then load it final String errorUrl = preferences.getString("errorUrl", null); - if ((errorUrl != null) && (errorUrl.startsWith("file://") || whitelist.isUrlWhiteListed(errorUrl)) && (!failingUrl.equals(errorUrl))) { + if ((errorUrl != null) && (errorUrl.startsWith("file://") || internalWhitelist.isUrlWhiteListed(errorUrl)) && (!failingUrl.equals(errorUrl))) { // Load URL on UI thread me.runOnUiThread(new Runnable() { @@ -962,7 +964,7 @@ public class CordovaActivity extends Activity implements CordovaInterface { */ @Deprecated // Use whitelist object directly. public boolean isUrlWhiteListed(String url) { - return whitelist.isUrlWhiteListed(url); + return internalWhitelist.isUrlWhiteListed(url); } /* http://git-wip-us.apache.org/repos/asf/cordova-amazon-fireos/blob/bb2029db/framework/src/org/apache/cordova/CordovaUriHelper.java ---------------------------------------------------------------------- diff --git a/framework/src/org/apache/cordova/CordovaUriHelper.java b/framework/src/org/apache/cordova/CordovaUriHelper.java index 66818cb..340f03a 100644 --- a/framework/src/org/apache/cordova/CordovaUriHelper.java +++ b/framework/src/org/apache/cordova/CordovaUriHelper.java @@ -58,8 +58,10 @@ class CordovaUriHelper { } } // Give plugins the chance to handle the url - else if (this.appView.pluginManager.onOverrideUrlLoading(url)) { - + if (this.appView.pluginManager.onOverrideUrlLoading(url)) { + // Do nothing other than what the plugins wanted. + // If any returned true, then the request was handled. + return true; } else if(url.startsWith("file://") | url.startsWith("data:")) { @@ -67,7 +69,11 @@ class CordovaUriHelper { //DON'T CHANGE THIS UNLESS YOU KNOW WHAT YOU'RE DOING! return url.contains("app_webview"); } - else + else if (appView.getWhitelist().isUrlWhiteListed(url)) { + // Allow internal navigation + return false; + } + else if (appView.getExternalWhitelist().isUrlWhiteListed(url)) { try { Intent intent = new Intent(Intent.ACTION_VIEW); @@ -78,11 +84,12 @@ class CordovaUriHelper { intent.setSelector(null); } this.cordova.getActivity().startActivity(intent); + return true; } catch (android.content.ActivityNotFoundException e) { LOG.e(TAG, "Error loading url " + url, e); } } - //Default behaviour should be to load the default intent, let's see what happens! + // Intercept the request and do nothing with it -- block it return true; } } http://git-wip-us.apache.org/repos/asf/cordova-amazon-fireos/blob/bb2029db/framework/src/org/apache/cordova/CordovaWebView.java ---------------------------------------------------------------------- diff --git a/framework/src/org/apache/cordova/CordovaWebView.java b/framework/src/org/apache/cordova/CordovaWebView.java index fbc1932..b15de97 100755 --- a/framework/src/org/apache/cordova/CordovaWebView.java +++ b/framework/src/org/apache/cordova/CordovaWebView.java @@ -89,7 +89,9 @@ public class CordovaWebView extends AmazonWebView { private AmazonWebChromeClient.CustomViewCallback mCustomViewCallback; private CordovaResourceApi resourceApi; - private Whitelist whitelist; + private Whitelist internalWhitelist; + private Whitelist externalWhitelist; + // The URL passed to loadUrl(), not necessarily the URL of the current page. String loadedUrl; private CordovaPreferences preferences; @@ -199,7 +201,8 @@ public class CordovaWebView extends AmazonWebView { */ // Use two-phase init so that the control will work with XML layouts. public void init(CordovaInterface cordova, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient, - List<PluginEntry> pluginEntries, Whitelist whitelist, CordovaPreferences preferences) { + List<PluginEntry> pluginEntries, Whitelist internalWhitelist, Whitelist externalWhitelist, + CordovaPreferences preferences) { if (this.cordova != null) { throw new IllegalStateException(); } @@ -207,7 +210,8 @@ public class CordovaWebView extends AmazonWebView { //this.cordova.getFactory().initializeWebView(this, 0xFFFFFF, false, null); this.viewClient = webViewClient; this.chromeClient = webChromeClient; - this.whitelist = whitelist; + this.internalWhitelist = internalWhitelist; + this.externalWhitelist = externalWhitelist; this.preferences = preferences; super.setWebChromeClient(webChromeClient); super.setWebViewClient(webViewClient); @@ -230,7 +234,7 @@ public class CordovaWebView extends AmazonWebView { if (!Config.isInitialized()) { Config.init(cdv.getActivity()); } - init(cdv, makeWebViewClient(cdv), makeWebChromeClient(cdv), Config.getPluginEntries(), Config.getWhitelist(), Config.getPreferences()); + init(cdv, makeWebViewClient(cdv), makeWebChromeClient(cdv), Config.getPluginEntries(), Config.getWhitelist(), Config.getExternalWhitelist(), Config.getPreferences()); } } @@ -430,9 +434,13 @@ public class CordovaWebView extends AmazonWebView { public Whitelist getWhitelist() { - return this.whitelist; + return this.internalWhitelist; } - + + public Whitelist getExternalWhitelist() { + return this.externalWhitelist; + } + /** * Load the url into the webview. * @@ -506,7 +514,7 @@ public class CordovaWebView extends AmazonWebView { if (LOG.isLoggable(LOG.DEBUG) && !url.startsWith("javascript:")) { LOG.d(TAG, ">>> loadUrlNow()"); } - if (url.startsWith("file://") || url.startsWith("javascript:") || whitelist.isUrlWhiteListed(url)) { + if (url.startsWith("file://") || url.startsWith("javascript:") || internalWhitelist.isUrlWhiteListed(url)) { super.loadUrl(url); } } @@ -641,7 +649,7 @@ public class CordovaWebView extends AmazonWebView { if (!openExternal) { // Make sure url is in whitelist - if (url.startsWith("file://") || whitelist.isUrlWhiteListed(url)) { + if (url.startsWith("file://") || internalWhitelist.isUrlWhiteListed(url)) { // TODO: What about params? // Load new URL this.loadUrl(url);
