From 00b10ed048cc1f6490e7ca3e0530dd4471ca5a40 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Wed, 27 May 2020 13:39:55 +0200 Subject: Implement internal webview for authenticating when OPEN_URL is used --- .../blinkt/openvpn/activities/CredentialsPopup.kt | 2 + .../blinkt/openvpn/activities/InternalWebView.kt | 99 ++++++++++++++++++++++ .../java/de/blinkt/openvpn/core/VariantConfig.java | 18 ++++ .../blinkt/openvpn/fragments/VPNProfileList.java | 31 ++++--- 4 files changed, 136 insertions(+), 14 deletions(-) create mode 100644 main/src/ui/java/de/blinkt/openvpn/activities/InternalWebView.kt create mode 100644 main/src/ui/java/de/blinkt/openvpn/core/VariantConfig.java (limited to 'main/src/ui/java/de/blinkt/openvpn') diff --git a/main/src/ui/java/de/blinkt/openvpn/activities/CredentialsPopup.kt b/main/src/ui/java/de/blinkt/openvpn/activities/CredentialsPopup.kt index f5d836b9..6c59ca88 100644 --- a/main/src/ui/java/de/blinkt/openvpn/activities/CredentialsPopup.kt +++ b/main/src/ui/java/de/blinkt/openvpn/activities/CredentialsPopup.kt @@ -5,9 +5,11 @@ package de.blinkt.openvpn.activities import android.content.Intent +import android.net.VpnService import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.DialogFragment +import de.blinkt.openvpn.core.OpenVPNService import de.blinkt.openvpn.core.PasswordDialogFragment.Companion.newInstance class CredentialsPopup : AppCompatActivity() { diff --git a/main/src/ui/java/de/blinkt/openvpn/activities/InternalWebView.kt b/main/src/ui/java/de/blinkt/openvpn/activities/InternalWebView.kt new file mode 100644 index 00000000..2bad9e81 --- /dev/null +++ b/main/src/ui/java/de/blinkt/openvpn/activities/InternalWebView.kt @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2012-2020 Arne Schwabe + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt + */ + +package de.blinkt.openvpn.activities + +import android.annotation.SuppressLint +import android.annotation.TargetApi +import android.content.Intent +import android.os.Build +import android.os.Bundle +import android.util.Log +import android.webkit.JavascriptInterface +import android.webkit.WebResourceRequest +import android.webkit.WebView +import android.webkit.WebViewClient +import android.widget.TextView +import androidx.annotation.RequiresApi +import androidx.appcompat.app.AppCompatActivity +import de.blinkt.openvpn.R +import de.blinkt.openvpn.VpnProfile +import org.json.JSONObject + +class InternalWebView : AppCompatActivity() { + + lateinit var webView: WebView + lateinit var urlTextView: TextView + + @SuppressLint("SetJavaScriptEnabled") + override fun onCreate(savedInstanceState: Bundle?) { + + super.onCreate(savedInstanceState) + setContentView(R.layout.webview_internal) + + webView = findViewById(R.id.internal_webview) + urlTextView = findViewById(R.id.url_textview) + + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) + attachMessageHandler() + + webView.loadUrl(intent.data.toString()) + + webView.settings.javaScriptEnabled = true + webView.settings.userAgentString = VpnProfile.getVersionEnvString(this) + + webView.webViewClient = object: WebViewClient() { + @RequiresApi(Build.VERSION_CODES.LOLLIPOP) + override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean { + urlTextView.text = request?.url?.toString(); + return super.shouldOverrideUrlLoading(view, request) + } + + } + urlTextView.text = intent.data.toString() + + setTitle(R.string.internal_web_view) + + } + + @JavascriptInterface + fun postMessage(json: String?, transferList: String?): Boolean { + val jObejct = JSONObject(json) + + val action = jObejct.getString("type") + Log.i("OpenVPN,InternalWebview", json + " ---- " + transferList) + + if (action == "ACTION_REQUIRED") { + // Should show the hidden webview, nothing for us to do + return true + } + + if (action == "CONNECT_SUCCESS" || action == "CONNECT_FAILED") { + runOnUiThread({finish()}) + } + + /* runOnUiThread({ + Toast.makeText(this, json + " ---- " + transferList, Toast.LENGTH_LONG).show() + }) */ + return true + } + + + @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) + private fun attachMessageHandler() { + webView.addJavascriptInterface(this, "appEvent") + } + + override fun onResume() { + super.onResume() + + } + + override fun onNewIntent(intent: Intent?) { + super.onNewIntent(intent) + + } +} \ No newline at end of file diff --git a/main/src/ui/java/de/blinkt/openvpn/core/VariantConfig.java b/main/src/ui/java/de/blinkt/openvpn/core/VariantConfig.java new file mode 100644 index 00000000..5db8382c --- /dev/null +++ b/main/src/ui/java/de/blinkt/openvpn/core/VariantConfig.java @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2012-2020 Arne Schwabe + * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt + */ + +package de.blinkt.openvpn.core; + +import android.content.Context; +import android.content.Intent; + +import de.blinkt.openvpn.activities.InternalWebView; + +public class VariantConfig { + /** Return the normal webview or internal webview depending what is available */ + static Intent getOpenUrlIntent(Context c) { + return new Intent(c, InternalWebView.class); + } +} diff --git a/main/src/ui/java/de/blinkt/openvpn/fragments/VPNProfileList.java b/main/src/ui/java/de/blinkt/openvpn/fragments/VPNProfileList.java index 629d65da..3804926f 100644 --- a/main/src/ui/java/de/blinkt/openvpn/fragments/VPNProfileList.java +++ b/main/src/ui/java/de/blinkt/openvpn/fragments/VPNProfileList.java @@ -60,6 +60,7 @@ import de.blinkt.openvpn.core.VpnStatus; import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT; import static de.blinkt.openvpn.core.OpenVPNService.DISCONNECT_VPN; +import static de.blinkt.openvpn.core.OpenVPNService.EXTRA_CHALLENGE_TXT; public class VPNProfileList extends ListFragment implements OnClickListener, VpnStatus.StateListener { @@ -80,23 +81,28 @@ public class VPNProfileList extends ListFragment implements OnClickListener, Vpn protected VpnProfile mEditProfile = null; private String mLastStatusMessage; private ArrayAdapter mArrayadapter; + private Intent mLastIntent; @Override public void updateState(String state, String logmessage, final int localizedResId, ConnectionStatus level, Intent intent) { requireActivity().runOnUiThread(() -> { mLastStatusMessage = VpnStatus.getLastCleanLogMessage(getActivity()); + mLastIntent = intent; mArrayadapter.notifyDataSetChanged(); showUserRequestDialogIfNeeded(level, intent); }); } - private void showUserRequestDialogIfNeeded(ConnectionStatus level, Intent intent) { + private boolean showUserRequestDialogIfNeeded(ConnectionStatus level, Intent intent) { if (level == LEVEL_WAITING_FOR_USER_INPUT) { - PasswordDialogFragment pwInputFrag = PasswordDialogFragment.Companion.newInstance(intent, false); - - pwInputFrag.show(requireFragmentManager(), "dialog"); + if (intent.getStringExtra(EXTRA_CHALLENGE_TXT) != null) { + PasswordDialogFragment pwInputFrag = PasswordDialogFragment.Companion.newInstance(intent, false); + pwInputFrag.show(getParentFragmentManager(), "dialog"); + return true; + } } + return false; } @Override @@ -105,8 +111,12 @@ public class VPNProfileList extends ListFragment implements OnClickListener, Vpn private void startOrStopVPN(VpnProfile profile) { if (VpnStatus.isVPNActive() && profile.getUUIDString().equals(VpnStatus.getLastConnectedVPNProfile())) { - Intent disconnectVPN = new Intent(getActivity(), DisconnectVPN.class); - startActivity(disconnectVPN); + if (mLastIntent != null) { + startActivity(mLastIntent); + } else { + Intent disconnectVPN = new Intent(getActivity(), DisconnectVPN.class); + startActivity(disconnectVPN); + } } else { startVPN(profile); } @@ -600,14 +610,7 @@ public class VPNProfileList extends ListFragment implements OnClickListener, Vpn }); View settingsview = v.findViewById(R.id.quickedit_settings); - settingsview.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - editVPN(profile); - - } - }); + settingsview.setOnClickListener(view -> editVPN(profile)); TextView subtitle = (TextView) v.findViewById(R.id.vpn_item_subtitle); if (profile.getUUIDString().equals(VpnStatus.getLastConnectedVPNProfile())) { -- cgit v1.2.3