Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 226583f1 authored by Sunik Kupfer's avatar Sunik Kupfer Committed by GitHub
Browse files

Don't remove port from URI of nextcloud login intent (#1242)



* Test loginFromIntent

* Fix given URI

* Add test

* Use URI authority directly

* Add test for implicit intents

* Add URI port only if not -1

* Modify URI using Java URI

---------

Co-authored-by: default avatarRicki Hirner <hirner@bitfire.at>
parent f3333b7b
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
package at.bitfire.davdroid.ui.setup

import android.content.Intent
import android.net.Uri
import org.junit.Assert.assertEquals
import org.junit.Test

class LoginActivityTest {

    @Test
    fun loginInfoFromIntent() {
        val intent = Intent().apply {
            data = Uri.parse("https://example.com/nextcloud")
            putExtra(LoginActivity.EXTRA_USERNAME, "user")
            putExtra(LoginActivity.EXTRA_PASSWORD, "password")
        }
        val loginInfo = LoginActivity.loginInfoFromIntent(intent)
        assertEquals("https://example.com/nextcloud", loginInfo.baseUri.toString())
        assertEquals("user", loginInfo.credentials!!.username)
        assertEquals("password", loginInfo.credentials.password)
    }

    @Test
    fun loginInfoFromIntent_withPort() {
        val intent = Intent().apply {
            data = Uri.parse("https://example.com:444/nextcloud")
            putExtra(LoginActivity.EXTRA_USERNAME, "user")
            putExtra(LoginActivity.EXTRA_PASSWORD, "password")
        }
        val loginInfo = LoginActivity.loginInfoFromIntent(intent)
        assertEquals("https://example.com:444/nextcloud", loginInfo.baseUri.toString())
        assertEquals("user", loginInfo.credentials!!.username)
        assertEquals("password", loginInfo.credentials.password)
    }

    @Test
    fun loginInfoFromIntent_implicit() {
        val intent = Intent(Intent.ACTION_VIEW, Uri.parse("davx5://user:password@example.com/path"))
        val loginInfo = LoginActivity.loginInfoFromIntent(intent)
        assertEquals("https://example.com/path", loginInfo.baseUri.toString())
        assertEquals("user", loginInfo.credentials!!.username)
        assertEquals("password", loginInfo.credentials.password)
    }

    @Test
    fun loginInfoFromIntent_implicit_withPort() {
        val intent = Intent(Intent.ACTION_VIEW, Uri.parse("davx5://user:password@example.com:0/path"))
        val loginInfo = LoginActivity.loginInfoFromIntent(intent)
        assertEquals("https://example.com:0/path", loginInfo.baseUri.toString())
        assertEquals("user", loginInfo.credentials!!.username)
        assertEquals("password", loginInfo.credentials.password)
    }
}
 No newline at end of file
+27 −21
Original line number Diff line number Diff line
@@ -5,7 +5,6 @@
package at.bitfire.davdroid.ui.setup

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
@@ -13,6 +12,8 @@ import at.bitfire.davdroid.db.Credentials
import at.bitfire.davdroid.ui.account.AccountActivity
import dagger.hilt.android.AndroidEntryPoint
import java.net.URI
import java.net.URISyntaxException
import java.util.logging.Logger
import javax.inject.Inject

/**
@@ -59,9 +60,10 @@ class LoginActivity @Inject constructor(): AppCompatActivity() {
            var givenPassword: String? = null

            // extract URI and optionally username/password from Intent data
            val logger = Logger.getGlobal()
            intent.data?.normalizeScheme()?.let { uri ->
                // We've got initial login data from the Intent.
                // We can't use uri.buildUpon() because this keeps the user info (it's readable, but not writable).
                try {
                    // replace caldav[s]:// and carddav[s]:// with http[s]://
                    val realScheme = when (uri.scheme) {
                        "caldav", "carddav" -> "http"
                        "caldavs", "carddavs", "davx5" -> "https"
@@ -69,18 +71,22 @@ class LoginActivity @Inject constructor(): AppCompatActivity() {
                        else -> null
                    }
                    if (realScheme != null) {
                    val realUri = Uri.Builder()
                        .scheme(realScheme)
                        .authority(uri.host)
                        .path(uri.path)
                        .query(uri.query)
                    givenUri = realUri.build().toString()

                        // extract user info
                        uri.userInfo?.split(':')?.let { userInfo ->
                            givenUsername = userInfo.getOrNull(0)
                            givenPassword = userInfo.getOrNull(1)
                        }

                        // use real scheme, drop user info and fragment
                        givenUri = try {
                            URI(realScheme, null, uri.host, uri.port, uri.path, uri.query, null).toString()
                        } catch (_: URISyntaxException) {
                            logger.warning("Couldn't construct URI from login Intent data: $uri")
                            null
                        }
                    }
                } catch (_: URISyntaxException) {
                    logger.warning("Got invalid URI from login Intent: $uri")
                }
            }