Loading app/src/main/java/at/bitfire/davdroid/ui/setup/DefaultLoginCredentialsFragment.kt +8 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ package at.bitfire.davdroid.ui.setup import android.content.Intent import android.net.MailTo import android.os.Bundle import android.os.Handler Loading Loading @@ -145,4 +146,11 @@ class DefaultLoginCredentialsFragment: Fragment() { return valid } class Factory: ILoginCredentialsFragment { override fun getFragment(intent: Intent) = DefaultLoginCredentialsFragment() } } app/src/main/java/at/bitfire/davdroid/ui/setup/ILoginCredentialsFragment.kt 0 → 100644 +18 −0 Original line number Diff line number Diff line /* * Copyright © Ricki Hirner (bitfire web engineering). * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ package at.bitfire.davdroid.ui.setup import android.content.Intent import androidx.fragment.app.Fragment interface ILoginCredentialsFragment { fun getFragment(intent: Intent): Fragment? } No newline at end of file app/src/main/java/at/bitfire/davdroid/ui/setup/LoginActivity.kt +16 −4 Original line number Diff line number Diff line Loading @@ -12,8 +12,10 @@ import android.os.Bundle import android.view.Menu import android.view.MenuItem import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import at.bitfire.davdroid.App import at.bitfire.davdroid.R import at.bitfire.davdroid.log.Logger import at.bitfire.davdroid.ui.UiUtils import java.util.* Loading Loading @@ -42,15 +44,25 @@ class LoginActivity: AppCompatActivity() { const val EXTRA_PASSWORD = "password" } private val loginFragmentLoader = ServiceLoader.load(ILoginCredentialsFragment::class.java)!! override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (savedInstanceState == null) if (savedInstanceState == null) { // first call, add first login fragment var fragment: Fragment? = null for (factory in loginFragmentLoader) fragment = fragment ?: factory.getFragment(intent) if (fragment != null) { supportFragmentManager.beginTransaction() .replace(android.R.id.content, DefaultLoginCredentialsFragment()) .replace(android.R.id.content, fragment) .commit() } else Logger.log.severe("Couldn't create LoginFragment") } } override fun onCreateOptionsMenu(menu: Menu): Boolean { Loading app/src/main/java/at/bitfire/davdroid/ui/setup/NextcloudLoginFlowFragment.kt 0 → 100644 +96 −0 Original line number Diff line number Diff line package at.bitfire.davdroid.ui.setup import android.annotation.SuppressLint import android.content.Intent import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.webkit.CookieManager import android.webkit.WebView import android.webkit.WebViewClient import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProviders import at.bitfire.davdroid.BuildConfig import at.bitfire.davdroid.log.Logger import at.bitfire.davdroid.model.Credentials import okhttp3.HttpUrl import java.util.logging.Level class NextcloudLoginFlowFragment: Fragment() { companion object { const val EXTRA_LOGIN_FLOW = "loginFlow" const val EXTRA_DAV_PATH = "davPath" } lateinit var loginModel: LoginModel @SuppressLint("SetJavaScriptEnabled") override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { loginModel = ViewModelProviders.of(requireActivity()).get(LoginModel::class.java) val webView = WebView(requireActivity()) webView.settings.apply { javaScriptEnabled = true userAgentString = BuildConfig.userAgent } webView.loadUrl( requireActivity().intent.data.toString(), // https://nextcloud.example.com/index.php/login/flow mapOf(Pair("OCS-APIREQUEST", "true")) ) webView.webViewClient = object: WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView, url: String) = if (url.startsWith("nc://login")) { onReceivedNcUrl(url) true } else { Logger.log.info("Didn't handle $url") false } } return webView } private fun onReceivedNcUrl(url: String) { val format = Regex("^nc://login/server:(.+)&user:(.+)&password:(.+)$") val match = format.find(url) if (match != null) { // determine DAV URL from root URL try { val serverUrl = HttpUrl.get(match.groupValues[1]) val davPath = requireActivity().intent.getStringExtra(EXTRA_DAV_PATH) loginModel.baseURI = if (davPath != null) serverUrl.resolve(davPath)!!.uri() else serverUrl.uri() loginModel.credentials = Credentials( userName = match.groupValues[2], password = match.groupValues[3] ) // continue to next fragment requireFragmentManager().beginTransaction() .replace(android.R.id.content, DetectConfigurationFragment(), null) .addToBackStack(null) .commit() } catch (e: IllegalArgumentException) { Logger.log.log(Level.SEVERE, "Couldn't parse server argument of nc URL: $url", e) } } else Logger.log.severe("Unknown format of nc URL: $url") } class Factory : ILoginCredentialsFragment { override fun getFragment(intent: Intent) = if (intent.hasExtra(EXTRA_LOGIN_FLOW)) NextcloudLoginFlowFragment() else null } } No newline at end of file app/src/main/resources/META-INF/services/at.bitfire.davdroid.ui.setup.ILoginCredentialsFragment 0 → 100644 +2 −0 Original line number Diff line number Diff line at.bitfire.davdroid.ui.setup.NextcloudLoginFlowFragment$Factory at.bitfire.davdroid.ui.setup.DefaultLoginCredentialsFragment$Factory No newline at end of file Loading
app/src/main/java/at/bitfire/davdroid/ui/setup/DefaultLoginCredentialsFragment.kt +8 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ package at.bitfire.davdroid.ui.setup import android.content.Intent import android.net.MailTo import android.os.Bundle import android.os.Handler Loading Loading @@ -145,4 +146,11 @@ class DefaultLoginCredentialsFragment: Fragment() { return valid } class Factory: ILoginCredentialsFragment { override fun getFragment(intent: Intent) = DefaultLoginCredentialsFragment() } }
app/src/main/java/at/bitfire/davdroid/ui/setup/ILoginCredentialsFragment.kt 0 → 100644 +18 −0 Original line number Diff line number Diff line /* * Copyright © Ricki Hirner (bitfire web engineering). * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ package at.bitfire.davdroid.ui.setup import android.content.Intent import androidx.fragment.app.Fragment interface ILoginCredentialsFragment { fun getFragment(intent: Intent): Fragment? } No newline at end of file
app/src/main/java/at/bitfire/davdroid/ui/setup/LoginActivity.kt +16 −4 Original line number Diff line number Diff line Loading @@ -12,8 +12,10 @@ import android.os.Bundle import android.view.Menu import android.view.MenuItem import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import at.bitfire.davdroid.App import at.bitfire.davdroid.R import at.bitfire.davdroid.log.Logger import at.bitfire.davdroid.ui.UiUtils import java.util.* Loading Loading @@ -42,15 +44,25 @@ class LoginActivity: AppCompatActivity() { const val EXTRA_PASSWORD = "password" } private val loginFragmentLoader = ServiceLoader.load(ILoginCredentialsFragment::class.java)!! override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (savedInstanceState == null) if (savedInstanceState == null) { // first call, add first login fragment var fragment: Fragment? = null for (factory in loginFragmentLoader) fragment = fragment ?: factory.getFragment(intent) if (fragment != null) { supportFragmentManager.beginTransaction() .replace(android.R.id.content, DefaultLoginCredentialsFragment()) .replace(android.R.id.content, fragment) .commit() } else Logger.log.severe("Couldn't create LoginFragment") } } override fun onCreateOptionsMenu(menu: Menu): Boolean { Loading
app/src/main/java/at/bitfire/davdroid/ui/setup/NextcloudLoginFlowFragment.kt 0 → 100644 +96 −0 Original line number Diff line number Diff line package at.bitfire.davdroid.ui.setup import android.annotation.SuppressLint import android.content.Intent import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.webkit.CookieManager import android.webkit.WebView import android.webkit.WebViewClient import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProviders import at.bitfire.davdroid.BuildConfig import at.bitfire.davdroid.log.Logger import at.bitfire.davdroid.model.Credentials import okhttp3.HttpUrl import java.util.logging.Level class NextcloudLoginFlowFragment: Fragment() { companion object { const val EXTRA_LOGIN_FLOW = "loginFlow" const val EXTRA_DAV_PATH = "davPath" } lateinit var loginModel: LoginModel @SuppressLint("SetJavaScriptEnabled") override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { loginModel = ViewModelProviders.of(requireActivity()).get(LoginModel::class.java) val webView = WebView(requireActivity()) webView.settings.apply { javaScriptEnabled = true userAgentString = BuildConfig.userAgent } webView.loadUrl( requireActivity().intent.data.toString(), // https://nextcloud.example.com/index.php/login/flow mapOf(Pair("OCS-APIREQUEST", "true")) ) webView.webViewClient = object: WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView, url: String) = if (url.startsWith("nc://login")) { onReceivedNcUrl(url) true } else { Logger.log.info("Didn't handle $url") false } } return webView } private fun onReceivedNcUrl(url: String) { val format = Regex("^nc://login/server:(.+)&user:(.+)&password:(.+)$") val match = format.find(url) if (match != null) { // determine DAV URL from root URL try { val serverUrl = HttpUrl.get(match.groupValues[1]) val davPath = requireActivity().intent.getStringExtra(EXTRA_DAV_PATH) loginModel.baseURI = if (davPath != null) serverUrl.resolve(davPath)!!.uri() else serverUrl.uri() loginModel.credentials = Credentials( userName = match.groupValues[2], password = match.groupValues[3] ) // continue to next fragment requireFragmentManager().beginTransaction() .replace(android.R.id.content, DetectConfigurationFragment(), null) .addToBackStack(null) .commit() } catch (e: IllegalArgumentException) { Logger.log.log(Level.SEVERE, "Couldn't parse server argument of nc URL: $url", e) } } else Logger.log.severe("Unknown format of nc URL: $url") } class Factory : ILoginCredentialsFragment { override fun getFragment(intent: Intent) = if (intent.hasExtra(EXTRA_LOGIN_FLOW)) NextcloudLoginFlowFragment() else null } } No newline at end of file
app/src/main/resources/META-INF/services/at.bitfire.davdroid.ui.setup.ILoginCredentialsFragment 0 → 100644 +2 −0 Original line number Diff line number Diff line at.bitfire.davdroid.ui.setup.NextcloudLoginFlowFragment$Factory at.bitfire.davdroid.ui.setup.DefaultLoginCredentialsFragment$Factory No newline at end of file