[db] support adding repos protected with basic auth

This commit is contained in:
Torsten Grote
2023-09-27 11:39:08 +02:00
committed by Michael Pöhn
parent 413d9fcfba
commit 7d64492d92
7 changed files with 163 additions and 86 deletions

View File

@@ -126,17 +126,12 @@ public class RepoManager @JvmOverloads constructor(
*/
@AnyThread
@JvmOverloads
public fun fetchRepositoryPreview(
url: String,
username: String? = null,
password: String? = null,
proxy: Proxy? = null,
) {
repoAdder.fetchRepository(url, username, password, proxy)
public fun fetchRepositoryPreview(url: String, proxy: Proxy? = null) {
repoAdder.fetchRepository(url, proxy)
}
/**
* When [addRepoState] is in [org.fdroid.repo.Fetched],
* When [addRepoState] is in [org.fdroid.repo.Fetching.done],
* you can call this to actually add the repo to the DB.
* @throws IllegalStateException if [addRepoState] is currently in any other state.
*/

View File

@@ -110,9 +110,9 @@ internal class RepoAdder(
private var fetchJob: Job? = null
internal fun fetchRepository(url: String, username: String?, password: String?, proxy: Proxy?) {
internal fun fetchRepository(url: String, proxy: Proxy?) {
fetchJob = GlobalScope.launch(coroutineContext) {
fetchRepositoryInt(url, username, password, proxy)
fetchRepositoryInt(url, proxy)
}
}
@@ -120,8 +120,6 @@ internal class RepoAdder(
@VisibleForTesting
internal suspend fun fetchRepositoryInt(
url: String,
username: String? = null,
password: String? = null,
proxy: Proxy? = null,
) {
if (hasDisallowInstallUnknownSources(context)) {
@@ -159,14 +157,16 @@ internal class RepoAdder(
// try fetching repo with v2 format first and fallback to v1
try {
try {
val repo = getTempRepo(nUri.uri, IndexFormatVersion.TWO, username, password)
val repo =
getTempRepo(nUri.uri, IndexFormatVersion.TWO, nUri.username, nUri.password)
val repoFetcher =
RepoV2Fetcher(tempFileProvider, downloaderFactory, httpManager, proxy)
repoFetcher.fetchRepo(nUri.uri, repo, receiver, nUri.fingerprint)
} catch (e: NotFoundException) {
log.warn(e) { "Did not find v2 repo, trying v1 now." }
// try to fetch v1 repo
val repo = getTempRepo(nUri.uri, IndexFormatVersion.ONE, username, password)
val repo =
getTempRepo(nUri.uri, IndexFormatVersion.ONE, nUri.username, nUri.password)
val repoFetcher = RepoV1Fetcher(tempFileProvider, downloaderFactory)
repoFetcher.fetchRepo(nUri.uri, repo, receiver, nUri.fingerprint)
}

View File

@@ -30,7 +30,19 @@ internal object RepoUriGetter {
?: uri.getQueryParameter("FINGERPRINT")?.lowercase()
val pathSegments = uri.pathSegments
var username: String? = null
var password: String? = null
val normalizedUri = uri.buildUpon().apply {
// extract and remove userInfo, if available
val userInfo = uri.userInfo
val authority = uri.authority
if (userInfo != null && authority != null) {
val host = authority.split('@')[1]
val usernamePassword = userInfo.split(':')
if (usernamePassword.isNotEmpty()) username = usernamePassword[0]
if (usernamePassword.size > 1) password = usernamePassword[1]
authority(host) // remove userInfo from URI
}
clearQuery() // removes fingerprint and other query params
fragment("") // remove # hash fragment
if (pathSegments.size >= 2 &&
@@ -57,7 +69,7 @@ internal object RepoUriGetter {
newUri
}
}
return NormalizedUri(normalizedUri, fingerprint)
return NormalizedUri(normalizedUri, fingerprint, username, password)
}
fun isSwapUri(uri: Uri): Boolean {
@@ -71,8 +83,14 @@ internal object RepoUriGetter {
}
/**
* A class for normalizing the [Repository] URI and holding an optional fingerprint.
* A class for normalizing the [Repository] URI and holding an optional fingerprint
* as well as username/password for basic authentication.
*/
data class NormalizedUri(val uri: Uri, val fingerprint: String?)
data class NormalizedUri(
val uri: Uri,
val fingerprint: String?,
val username: String? = null,
val password: String? = null,
)
}