aboutsummaryrefslogtreecommitdiff
path: root/WordPress/src/main/java/org/wordpress/android/ui/WPWebViewActivity.java
diff options
context:
space:
mode:
Diffstat (limited to 'WordPress/src/main/java/org/wordpress/android/ui/WPWebViewActivity.java')
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/WPWebViewActivity.java363
1 files changed, 363 insertions, 0 deletions
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/WPWebViewActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/WPWebViewActivity.java
new file mode 100644
index 000000000..1e95dc4b2
--- /dev/null
+++ b/WordPress/src/main/java/org/wordpress/android/ui/WPWebViewActivity.java
@@ -0,0 +1,363 @@
+package org.wordpress.android.ui;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.webkit.WebViewClient;
+import android.widget.ProgressBar;
+import android.widget.Toast;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+import org.wordpress.android.R;
+import org.wordpress.android.WordPress;
+import org.wordpress.android.models.AccountHelper;
+import org.wordpress.android.models.Blog;
+import org.wordpress.android.models.Post;
+import org.wordpress.android.ui.reader.ReaderActivityLauncher;
+import org.wordpress.android.util.AppLog;
+import org.wordpress.android.util.StringUtils;
+import org.wordpress.android.util.URLFilteredWebViewClient;
+import org.wordpress.android.util.UrlUtils;
+import org.wordpress.android.util.WPMeShortlinks;
+import org.wordpress.android.util.WPUrlUtils;
+import org.wordpress.android.util.WPWebViewClient;
+import org.wordpress.android.util.helpers.WPWebChromeClient;
+
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Type;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Activity for opening external WordPress links in a webview.
+ *
+ * Try to use one of the methods below to open the webview:
+ * - openURL
+ * - openUrlByUsingMainWPCOMCredentials
+ * - openUrlByUsingWPCOMCredentials
+ * - openUrlByUsingBlogCredentials (for self hosted sites)
+ *
+ * If you need to start the activity with delay, start activity with result, or none of the methods above are enough for your needs,
+ * you can start the activity by passing the required parameters, depending on what you need to do.
+ *
+ * 1. Load a simple URL (without any kind of authentication)
+ * - Start the activity with the parameter URL_TO_LOAD set to the URL to load.
+ *
+ * 2. Load a WordPress.com URL
+ * Start the activity with the following parameters:
+ * - URL_TO_LOAD: target URL to load in the webview.
+ * - AUTHENTICATION_URL: The address of the WordPress.com authentication endpoint. Please use WPCOM_LOGIN_URL.
+ * - AUTHENTICATION_USER: username.
+ * - AUTHENTICATION_PASSWD: password.
+ *
+ * 3. Load a WordPress.org URL with authentication
+ * - URL_TO_LOAD: target URL to load in the webview.
+ * - AUTHENTICATION_URL: The address of the authentication endpoint. Please use the value of getBlogLoginUrl()
+ * to retrieve the correct address of the authentication endpoint.
+ * - AUTHENTICATION_USER: username.
+ * - AUTHENTICATION_PASSWD: password.
+ * - LOCAL_BLOG_ID: local id of the blog in the app database. This is required since some blogs could have HTTP Auth,
+ * or self-signed certs in place.
+ * - REFERRER_URL: url to add as an HTTP referrer header, currently only used for non-authed reader posts
+ *
+ */
+public class WPWebViewActivity extends WebViewActivity {
+ public static final String AUTHENTICATION_URL = "authenticated_url";
+ public static final String AUTHENTICATION_USER = "authenticated_user";
+ public static final String AUTHENTICATION_PASSWD = "authenticated_passwd";
+ public static final String URL_TO_LOAD = "url_to_load";
+ public static final String WPCOM_LOGIN_URL = "https://wordpress.com/wp-login.php";
+ public static final String LOCAL_BLOG_ID = "local_blog_id";
+ public static final String SHARABLE_URL = "sharable_url";
+ public static final String REFERRER_URL = "referrer_url";
+ public static final String DISABLE_LINKS_ON_PAGE = "DISABLE_LINKS_ON_PAGE";
+
+ private static final String ENCODING_UTF8 = "UTF-8";
+
+ public static void openUrlByUsingWPCOMCredentials(Context context, String url, String user) {
+ openWPCOMURL(context, url, user);
+ }
+
+ // Note: The webview has links disabled!!
+ public static void openUrlByUsingBlogCredentials(Context context, Blog blog, Post post, String url) {
+ if (context == null) {
+ AppLog.e(AppLog.T.UTILS, "Context is null");
+ return;
+ }
+
+ if (blog == null) {
+ AppLog.e(AppLog.T.UTILS, "Blog obj is null");
+ return;
+ }
+
+ if (TextUtils.isEmpty(url)) {
+ AppLog.e(AppLog.T.UTILS, "Empty or null URL");
+ Toast.makeText(context, context.getResources().getText(R.string.invalid_site_url_message),
+ Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ String authURL = WPWebViewActivity.getBlogLoginUrl(blog);
+ Intent intent = new Intent(context, WPWebViewActivity.class);
+ intent.putExtra(WPWebViewActivity.AUTHENTICATION_USER, blog.getUsername());
+ intent.putExtra(WPWebViewActivity.AUTHENTICATION_PASSWD, blog.getPassword());
+ intent.putExtra(WPWebViewActivity.URL_TO_LOAD, url);
+ intent.putExtra(WPWebViewActivity.AUTHENTICATION_URL, authURL);
+ intent.putExtra(WPWebViewActivity.LOCAL_BLOG_ID, blog.getLocalTableBlogId());
+ intent.putExtra(WPWebViewActivity.DISABLE_LINKS_ON_PAGE, true);
+ if (post != null) {
+ intent.putExtra(WPWebViewActivity.SHARABLE_URL, WPMeShortlinks.getPostShortlink(blog, post));
+ }
+ context.startActivity(intent);
+ }
+
+ public static void openURL(Context context, String url) {
+ openURL(context, url, null);
+ }
+ public static void openURL(Context context, String url, String referrer) {
+ if (context == null) {
+ AppLog.e(AppLog.T.UTILS, "Context is null");
+ return;
+ }
+
+ if (TextUtils.isEmpty(url)) {
+ AppLog.e(AppLog.T.UTILS, "Empty or null URL");
+ Toast.makeText(context, context.getResources().getText(R.string.invalid_site_url_message),
+ Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ Intent intent = new Intent(context, WPWebViewActivity.class);
+ intent.putExtra(WPWebViewActivity.URL_TO_LOAD, url);
+ if (!TextUtils.isEmpty(referrer)) {
+ intent.putExtra(REFERRER_URL, referrer);
+ }
+ context.startActivity(intent);
+ }
+
+ private static void openWPCOMURL(Context context, String url, String user) {
+ if (context == null) {
+ AppLog.e(AppLog.T.UTILS, "Context is null");
+ return;
+ }
+
+ if (TextUtils.isEmpty(url)) {
+ AppLog.e(AppLog.T.UTILS, "Empty or null URL passed to openUrlByUsingMainWPCOMCredentials");
+ Toast.makeText(context, context.getResources().getText(R.string.invalid_site_url_message),
+ Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ if (TextUtils.isEmpty(user)) {
+ AppLog.e(AppLog.T.UTILS, "Username empty/null");
+ return;
+ }
+
+ Intent intent = new Intent(context, WPWebViewActivity.class);
+ intent.putExtra(WPWebViewActivity.AUTHENTICATION_USER, user);
+ intent.putExtra(WPWebViewActivity.URL_TO_LOAD, url);
+ intent.putExtra(WPWebViewActivity.AUTHENTICATION_URL, WPCOM_LOGIN_URL);
+ context.startActivity(intent);
+ }
+
+
+ @SuppressLint("SetJavaScriptEnabled")
+ @Override
+ protected void configureWebView() {
+ mWebView.getSettings().setJavaScriptEnabled(true);
+ mWebView.getSettings().setDomStorageEnabled(true);
+
+ WebViewClient webViewClient;
+ Bundle extras = getIntent().getExtras();
+
+ // Configure the allowed URLs if available
+ ArrayList<String> allowedURL = null;
+ if (extras.getBoolean(DISABLE_LINKS_ON_PAGE, false)) {
+ String addressToLoad = extras.getString(URL_TO_LOAD);
+ String authURL = extras.getString(AUTHENTICATION_URL);
+ allowedURL = new ArrayList<>();
+ if (!TextUtils.isEmpty(addressToLoad)) {
+ allowedURL.add(addressToLoad);
+ }
+ if (!TextUtils.isEmpty(authURL)) {
+ allowedURL.add(authURL);
+ }
+ }
+
+ if (getIntent().hasExtra(LOCAL_BLOG_ID)) {
+ Blog blog = WordPress.getBlog(getIntent().getIntExtra(LOCAL_BLOG_ID, -1));
+ if (blog == null) {
+ AppLog.e(AppLog.T.UTILS, "No valid blog passed to WPWebViewActivity");
+ finish();
+ }
+ webViewClient = new WPWebViewClient(blog, allowedURL);
+ } else {
+ webViewClient = new URLFilteredWebViewClient(allowedURL);
+ }
+
+ mWebView.setWebViewClient(webViewClient);
+ mWebView.setWebChromeClient(new WPWebChromeClient(this, (ProgressBar) findViewById(R.id.progress_bar)));
+ }
+
+ @Override
+ protected void loadContent() {
+ Bundle extras = getIntent().getExtras();
+
+ if (extras == null) {
+ AppLog.e(AppLog.T.UTILS, "No valid parameters passed to WPWebViewActivity");
+ finish();
+ return;
+ }
+
+ String addressToLoad = extras.getString(URL_TO_LOAD);
+ String username = extras.getString(AUTHENTICATION_USER, "");
+ String password = extras.getString(AUTHENTICATION_PASSWD, "");
+ String authURL = extras.getString(AUTHENTICATION_URL);
+
+ if (TextUtils.isEmpty(addressToLoad) || !UrlUtils.isValidUrlAndHostNotNull(addressToLoad)) {
+ AppLog.e(AppLog.T.UTILS, "Empty or null or invalid URL passed to WPWebViewActivity");
+ Toast.makeText(this, getText(R.string.invalid_site_url_message),
+ Toast.LENGTH_SHORT).show();
+ finish();
+ }
+
+ if (TextUtils.isEmpty(authURL) && TextUtils.isEmpty(username) && TextUtils.isEmpty(password)) {
+ // Only the URL to load is passed to this activity. Use the normal un-authenticated
+ // loader, optionally with our referrer header
+ String referrerUrl = extras.getString(REFERRER_URL);
+ if (!TextUtils.isEmpty(referrerUrl)) {
+ Map<String, String> headers = new HashMap<>();
+ headers.put("Referer", referrerUrl);
+ loadUrl(addressToLoad, headers);
+ } else {
+ loadUrl(addressToLoad);
+ }
+ } else {
+ if (TextUtils.isEmpty(authURL) || !UrlUtils.isValidUrlAndHostNotNull(authURL)) {
+ AppLog.e(AppLog.T.UTILS, "Empty or null or invalid auth URL passed to WPWebViewActivity");
+ Toast.makeText(this, getText(R.string.invalid_site_url_message),
+ Toast.LENGTH_SHORT).show();
+ finish();
+ }
+
+ if (TextUtils.isEmpty(username)) {
+ AppLog.e(AppLog.T.UTILS, "Username empty/null");
+ Toast.makeText(this, getText(R.string.incorrect_credentials), Toast.LENGTH_SHORT).show();
+ finish();
+ }
+
+ loadAuthenticatedUrl(authURL, addressToLoad, username, password);
+ }
+ }
+
+ /**
+ * Login to the WordPress.com and load the specified URL.
+ *
+ */
+ protected void loadAuthenticatedUrl(String authenticationURL, String urlToLoad, String username, String password) {
+ String postData = getAuthenticationPostData(authenticationURL, urlToLoad, username, password,
+ AccountHelper.getDefaultAccount().getAccessToken());
+
+ mWebView.postUrl(authenticationURL, postData.getBytes());
+ }
+
+ public static String getAuthenticationPostData(String authenticationUrl, String urlToLoad, String username, String password, String token) {
+ if (TextUtils.isEmpty(authenticationUrl)) return "";
+
+ try {
+ String postData = String.format("log=%s&pwd=%s&redirect_to=%s",
+ URLEncoder.encode(StringUtils.notNullStr(username), ENCODING_UTF8),
+ URLEncoder.encode(StringUtils.notNullStr(password), ENCODING_UTF8),
+ URLEncoder.encode(StringUtils.notNullStr(urlToLoad), ENCODING_UTF8)
+ );
+
+ // Add token authorization when signing in to WP.com
+ if (WPUrlUtils.safeToAddWordPressComAuthToken(authenticationUrl)
+ && authenticationUrl.contains("wordpress.com/wp-login.php") && !TextUtils.isEmpty(token)) {
+ postData += "&authorization=Bearer " + URLEncoder.encode(token, ENCODING_UTF8);
+ }
+
+ return postData;
+ } catch (UnsupportedEncodingException e) {
+ AppLog.e(AppLog.T.UTILS, e);
+ }
+
+ return "";
+ }
+
+ /**
+ * Get the URL of the WordPress login page.
+ *
+ * @return URL of the login page.
+ */
+ public static String getBlogLoginUrl(Blog blog) {
+ String loginURL = null;
+ Gson gson = new Gson();
+ Type type = new TypeToken<Map<?, ?>>() {}.getType();
+ Map<?, ?> blogOptions = gson.fromJson(blog.getBlogOptions(), type);
+ if (blogOptions != null) {
+ Map<?, ?> homeURLMap = (Map<?, ?>) blogOptions.get("login_url");
+ if (homeURLMap != null) {
+ loginURL = homeURLMap.get("value").toString();
+ }
+ }
+ // Try to guess the login URL if blogOptions is null (blog not added to the app), or WP version is < 3.6
+ if (loginURL == null) {
+ if (blog.getUrl().lastIndexOf("/") != -1) {
+ return blog.getUrl().substring(0, blog.getUrl().lastIndexOf("/"))
+ + "/wp-login.php";
+ } else {
+ return blog.getUrl().replace("xmlrpc.php", "wp-login.php");
+ }
+ }
+
+ return loginURL;
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.webview, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(final MenuItem item) {
+ if (mWebView == null) {
+ return false;
+ }
+
+ int itemID = item.getItemId();
+ if (itemID == R.id.menu_refresh) {
+ mWebView.reload();
+ return true;
+ } else if (itemID == R.id.menu_share) {
+ Intent share = new Intent(Intent.ACTION_SEND);
+ share.setType("text/plain");
+ // Use the preferred sharable URL or the default webview URL
+ Bundle extras = getIntent().getExtras();
+ String sharableUrl = extras.getString(SHARABLE_URL, null);
+ if (sharableUrl == null) {
+ sharableUrl = mWebView.getUrl();
+ }
+ share.putExtra(Intent.EXTRA_TEXT, sharableUrl);
+ startActivity(Intent.createChooser(share, getText(R.string.share_link)));
+ return true;
+ } else if (itemID == R.id.menu_browser) {
+ ReaderActivityLauncher.openUrl(this, mWebView.getUrl(), ReaderActivityLauncher.OpenUrlType.EXTERNAL);
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+}