mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-26 20:33:07 +08:00
White list support. Pull request https://github.com/phonegap/phonegap-android/pull/211 from imhotep would not merge, so combined it with enhancements for this commit.
This commit is contained in:
parent
bb777c096c
commit
80df4a8fb2
@ -79,6 +79,16 @@ App.prototype.exitApp = function() {
|
|||||||
return PhoneGap.exec(null, null, "App", "exitApp", []);
|
return PhoneGap.exec(null, null, "App", "exitApp", []);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add entry to approved list of URLs (whitelist) that will be loaded into PhoneGap container instead of default browser.
|
||||||
|
*
|
||||||
|
* @param origin URL regular expression to allow
|
||||||
|
* @param subdomains T=include all subdomains under origin
|
||||||
|
*/
|
||||||
|
App.prototype.addWhiteListEntry = function(origin, subdomains) {
|
||||||
|
return PhoneGap.exec(null, null, "App", "addWhiteListEntry", [origin, subdomains]);
|
||||||
|
};
|
||||||
|
|
||||||
PhoneGap.addConstructor(function() {
|
PhoneGap.addConstructor(function() {
|
||||||
navigator.app = new App();
|
navigator.app = new App();
|
||||||
});
|
});
|
||||||
|
4
framework/res/xml/phonegap.xml
Executable file
4
framework/res/xml/phonegap.xml
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<phonegap>
|
||||||
|
<access origin="http://127.0.0.1*"/>
|
||||||
|
</phonegap>
|
@ -54,6 +54,9 @@ public class App extends Plugin {
|
|||||||
else if (action.equals("exitApp")) {
|
else if (action.equals("exitApp")) {
|
||||||
this.exitApp();
|
this.exitApp();
|
||||||
}
|
}
|
||||||
|
else if (action.equals("addWhiteListEntry")) {
|
||||||
|
this.addWhiteListEntry(args.getString(0), args.optBoolean(1));
|
||||||
|
}
|
||||||
return new PluginResult(status, result);
|
return new PluginResult(status, result);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
|
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
|
||||||
@ -172,4 +175,13 @@ public class App extends Plugin {
|
|||||||
((DroidGap)this.ctx).finish();
|
((DroidGap)this.ctx).finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add entry to approved list of URLs (whitelist)
|
||||||
|
*
|
||||||
|
* @param origin URL regular expression to allow
|
||||||
|
* @param subdomains T=include all subdomains under origin
|
||||||
|
*/
|
||||||
|
public void addWhiteListEntry(String origin, boolean subdomains) {
|
||||||
|
((DroidGap)this.ctx).addWhiteListEntry(origin, subdomains);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,11 @@ package com.phonegap;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
@ -23,6 +28,7 @@ import android.content.pm.ApplicationInfo;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.content.res.XmlResourceParser;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
@ -52,6 +58,7 @@ import android.widget.LinearLayout;
|
|||||||
import com.phonegap.api.PhonegapActivity;
|
import com.phonegap.api.PhonegapActivity;
|
||||||
import com.phonegap.api.IPlugin;
|
import com.phonegap.api.IPlugin;
|
||||||
import com.phonegap.api.PluginManager;
|
import com.phonegap.api.PluginManager;
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is the main Android activity that represents the PhoneGap
|
* This class is the main Android activity that represents the PhoneGap
|
||||||
@ -124,6 +131,8 @@ public class DroidGap extends PhonegapActivity {
|
|||||||
// The webview for our app
|
// The webview for our app
|
||||||
protected WebView appView;
|
protected WebView appView;
|
||||||
protected WebViewClient webViewClient;
|
protected WebViewClient webViewClient;
|
||||||
|
private ArrayList<Pattern> whiteList = new ArrayList<Pattern>();
|
||||||
|
private HashMap<String, Boolean> whiteListCache = new HashMap<String,Boolean>();
|
||||||
|
|
||||||
protected LinearLayout root;
|
protected LinearLayout root;
|
||||||
public boolean bound = false;
|
public boolean bound = false;
|
||||||
@ -195,6 +204,9 @@ public class DroidGap extends PhonegapActivity {
|
|||||||
root.setBackgroundColor(this.backgroundColor);
|
root.setBackgroundColor(this.backgroundColor);
|
||||||
root.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
|
root.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
|
||||||
ViewGroup.LayoutParams.FILL_PARENT, 0.0F));
|
ViewGroup.LayoutParams.FILL_PARENT, 0.0F));
|
||||||
|
|
||||||
|
// Load white list of allowed URLs
|
||||||
|
this.loadWhiteList();
|
||||||
|
|
||||||
// If url was passed in to intent, then init webview, which will load the url
|
// If url was passed in to intent, then init webview, which will load the url
|
||||||
Bundle bundle = this.getIntent().getExtras();
|
Bundle bundle = this.getIntent().getExtras();
|
||||||
@ -882,7 +894,7 @@ public class DroidGap extends PhonegapActivity {
|
|||||||
// Security check to make sure any requests are coming from the page initially
|
// Security check to make sure any requests are coming from the page initially
|
||||||
// loaded in webview and not another loaded in an iframe.
|
// loaded in webview and not another loaded in an iframe.
|
||||||
boolean reqOk = false;
|
boolean reqOk = false;
|
||||||
if (url.indexOf(this.ctx.baseUrl) == 0) {
|
if (url.indexOf(this.ctx.baseUrl) == 0 || isUrlWhiteListed(url)) {
|
||||||
reqOk = true;
|
reqOk = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1119,7 +1131,7 @@ public class DroidGap extends PhonegapActivity {
|
|||||||
|
|
||||||
// If our app or file:, then load into a new phonegap webview container by starting a new instance of our activity.
|
// If our app or file:, then load into a new phonegap webview container by starting a new instance of our activity.
|
||||||
// Our app continues to run. When BACK is pressed, our app is redisplayed.
|
// Our app continues to run. When BACK is pressed, our app is redisplayed.
|
||||||
if (this.ctx.loadInWebView || url.startsWith("file://") || url.indexOf(this.ctx.baseUrl) == 0) {
|
if (this.ctx.loadInWebView || url.startsWith("file://") || url.indexOf(this.ctx.baseUrl) == 0 || isUrlWhiteListed(url)) {
|
||||||
try {
|
try {
|
||||||
// Init parameters to new DroidGap activity and propagate existing parameters
|
// Init parameters to new DroidGap activity and propagate existing parameters
|
||||||
HashMap<String, Object> params = new HashMap<String, Object>();
|
HashMap<String, Object> params = new HashMap<String, Object>();
|
||||||
@ -1509,4 +1521,83 @@ public class DroidGap extends PhonegapActivity {
|
|||||||
oldWidth = width;
|
oldWidth = width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load approved list of URLs that can be loaded into DroidGap.
|
||||||
|
* This list is loaded from res/xml/phonegap.xml
|
||||||
|
* <access origin="http://server regexp" subdomains="true" />
|
||||||
|
*/
|
||||||
|
private void loadWhiteList() {
|
||||||
|
int id = getResources().getIdentifier("phonegap", "xml", getPackageName());
|
||||||
|
if (id == 0) {
|
||||||
|
Log.i("PhoneGapLog", "phonegap.xml missing. Ignoring...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
XmlResourceParser xml = getResources().getXml(id);
|
||||||
|
int eventType = -1;
|
||||||
|
while (eventType != XmlResourceParser.END_DOCUMENT) {
|
||||||
|
if (eventType == XmlResourceParser.START_TAG) {
|
||||||
|
String strNode = xml.getName();
|
||||||
|
if (strNode.equals("access")) {
|
||||||
|
String origin = xml.getAttributeValue(null, "origin");
|
||||||
|
String subdomains = xml.getAttributeValue(null, "subdomains");
|
||||||
|
if (origin != null) {
|
||||||
|
this.addWhiteListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase("true") == 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
eventType = xml.next();
|
||||||
|
} catch (XmlPullParserException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add entry to approved list of URLs (whitelist)
|
||||||
|
*
|
||||||
|
* @param origin URL regular expression to allow
|
||||||
|
* @param subdomains T=include all subdomains under origin
|
||||||
|
*/
|
||||||
|
public void addWhiteListEntry(String origin, boolean subdomains) {
|
||||||
|
if (subdomains) {
|
||||||
|
Log.d("PhoneGapLog", "Origin to allow with subdomains: "+origin);
|
||||||
|
whiteList.add(Pattern.compile(origin.replaceFirst("https{0,1}://", "^https{0,1}://.*")));
|
||||||
|
} else {
|
||||||
|
Log.d("PhoneGapLog", "Origin to allow: "+origin);
|
||||||
|
whiteList.add(Pattern.compile(origin.replaceFirst("https{0,1}://", "^https{0,1}://")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if URL is in approved list of URLs to load.
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean isUrlWhiteListed(String url) {
|
||||||
|
|
||||||
|
// Check to see if we have matched url previously
|
||||||
|
if (whiteListCache.get(url) != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for match in white list
|
||||||
|
Iterator<Pattern> pit = whiteList.iterator();
|
||||||
|
while (pit.hasNext()) {
|
||||||
|
Pattern p = pit.next();
|
||||||
|
Matcher m = p.matcher(url);
|
||||||
|
|
||||||
|
// If match found, then cache it to speed up subsequent comparisons
|
||||||
|
if (m.find()) {
|
||||||
|
whiteListCache.put(url, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user