Skip to content

Commit

Permalink
GH-1828 Support deeper calls through local loopback (Resolve #1828)
Browse files Browse the repository at this point in the history
  • Loading branch information
dzikoysk committed Jun 21, 2023
1 parent ebd29a3 commit 2c32df5
Show file tree
Hide file tree
Showing 12 changed files with 301 additions and 246 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,24 @@ import java.io.InputStream
class MavenFacade internal constructor(
private val journalist: Journalist,
private val repositorySecurityProvider: RepositorySecurityProvider,
private val repositoryService: RepositoryService,
private val mavenService: MavenService,
private val repositoryProvider: RepositoryProvider,
private val metadataService: MetadataService,
private val latestService: LatestService,
) : Journalist, Facade {

private val repositoryService = repositoryProvider.repositoryService

fun findDetails(lookupRequest: LookupRequest): Result<out FileDetails, ErrorResponse> =
mavenService.findDetails(lookupRequest)
repositoryService.findDetails(lookupRequest)

fun findFile(lookupRequest: LookupRequest): Result<Pair<DocumentInfo, InputStream>, ErrorResponse> =
mavenService.findFile(lookupRequest)
repositoryService.findFile(lookupRequest)

fun deployFile(deployRequest: DeployRequest): Result<Unit, ErrorResponse> =
mavenService.deployFile(deployRequest)
repositoryService.deployFile(deployRequest)

fun deleteFile(deleteRequest: DeleteRequest): Result<Unit, ErrorResponse> =
mavenService.deleteFile(deleteRequest)
repositoryService.deleteFile(deleteRequest)

fun saveMetadata(saveMetadataRequest: SaveMetadataRequest): Result<Metadata, ErrorResponse> =
metadataService.saveMetadata(saveMetadataRequest)
Expand Down Expand Up @@ -95,10 +96,10 @@ class MavenFacade internal constructor(
repositoryService.getRootDirectory(accessToken)

fun getRepository(name: String) =
repositoryService.getRepository(name)
repositoryService.repositoryProvider.getRepository(name)

fun getRepositories(): Collection<Repository> =
repositoryService.getRepositories()
repositoryService.repositoryProvider.getRepositories()

override fun getLogger(): Logger =
journalist.logger
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.reposilite.maven

import com.reposilite.auth.AuthenticationFacade
import com.reposilite.maven.application.MirroredRepositorySettings
import com.reposilite.maven.application.RepositorySettings
import com.reposilite.shared.http.RemoteClientProvider
Expand All @@ -28,8 +29,9 @@ import java.util.UUID

internal class RepositoryFactory(
private val workingDirectory: Path,
private val authenticationFacade: AuthenticationFacade,
private val remoteClientProvider: RemoteClientProvider,
private val repositoryProvider: RepositoryProvider,
private val repositoryService: RepositoryService,
private val failureFacade: FailureFacade,
private val storageFacade: StorageFacade,
private val repositoriesNames: Collection<String>,
Expand Down Expand Up @@ -65,11 +67,17 @@ internal class RepositoryFactory(
}

val remoteClient = when {
repositoriesNames.contains(host) -> RepositoryLoopbackClient(lazy { repositoryProvider.getRepositories()[host]!! })
else -> configurationSource.httpProxy
.takeIf { it.isNotEmpty() }
?.let { createHttpProxy(it) }
.let { remoteClientProvider.createClient(failureFacade, it) }
repositoriesNames.contains(host) ->
RepositoryLoopbackClient(
authenticationFacade = authenticationFacade,
repositoryService = repositoryService,
repositoryName = host
)
else ->
configurationSource.httpProxy
.takeIf { it.isNotEmpty() }
?.let { createHttpProxy(it) }
.let { remoteClientProvider.createClient(failureFacade, it) }
}

return MirrorHost(host, configurationSource, remoteClient)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,58 @@

package com.reposilite.maven

import com.reposilite.auth.AuthenticationFacade
import com.reposilite.auth.api.Credentials
import com.reposilite.maven.api.LookupRequest
import com.reposilite.shared.ErrorResponse
import com.reposilite.shared.http.AuthenticationMethod.LOOPBACK_LINK
import com.reposilite.shared.http.RemoteClient
import com.reposilite.shared.http.RemoteCredentials
import com.reposilite.shared.notFound
import com.reposilite.shared.toErrorResponse
import com.reposilite.storage.api.FileDetails
import com.reposilite.storage.api.Location
import com.reposilite.storage.api.toLocation
import com.reposilite.token.AccessTokenIdentifier
import io.javalin.http.HttpStatus.UNAUTHORIZED
import panda.std.Option
import panda.std.Result
import java.io.InputStream

internal class RepositoryLoopbackClient(private val repository: Lazy<Repository>) : RemoteClient {
internal class RepositoryLoopbackClient(
private val authenticationFacade: AuthenticationFacade,
private val repositoryService: RepositoryService,
private val repositoryName: String
) : RemoteClient {

override fun head(uri: String, credentials: RemoteCredentials?, connectTimeoutInSeconds: Int, readTimeoutInSeconds: Int): Result<FileDetails, ErrorResponse> =
repository.value.storageProvider.getFileDetails(toGav(uri))
.`is`(FileDetails::class.java) { notFound("Requested file is a directory") }
override fun head(uri: String, credentials: RemoteCredentials?, connectTimeoutInSeconds: Int, readTimeoutInSeconds: Int): Result<out FileDetails, ErrorResponse> =
repositoryService.findDetails(
LookupRequest(
accessToken = credentials.toAccessToken(),
repository = repositoryName,
gav = toGav(uri)
)
)

override fun get(uri: String, credentials: RemoteCredentials?, connectTimeoutInSeconds: Int, readTimeoutInSeconds: Int): Result<InputStream, ErrorResponse> =
repository.value.storageProvider.getFile(toGav(uri))
repositoryService.findFile(
LookupRequest(
accessToken = credentials.toAccessToken(),
repository = repositoryName,
gav = toGav(uri)
)
).map { (_, content) -> content }

private fun RemoteCredentials?.toAccessToken(): AccessTokenIdentifier? =
Option.of(this)
.toResult(UNAUTHORIZED.toErrorResponse("Missing credentials"))
.filter({ it.method == LOOPBACK_LINK }, { UNAUTHORIZED.toErrorResponse("") })
.flatMap { authenticationFacade.authenticateByCredentials(Credentials(it.login, it.password)) }
.fold(
{ it.identifier },
{ null }
)

private fun toGav(uri: String): Location =
uri.substring(repository.value.name.length + 1).toLocation()
uri.substring(repositoryName.length + 1).toLocation()

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,44 @@

package com.reposilite.maven

import com.reposilite.auth.AuthenticationFacade
import com.reposilite.journalist.Journalist
import com.reposilite.maven.application.RepositorySettings
import com.reposilite.plugin.Extensions
import com.reposilite.shared.ErrorResponse
import com.reposilite.shared.http.RemoteClientProvider
import com.reposilite.shared.notFoundError
import com.reposilite.statistics.StatisticsFacade
import com.reposilite.status.FailureFacade
import com.reposilite.storage.StorageFacade
import panda.std.Result
import panda.std.asSuccess
import panda.std.reactive.Reference
import java.nio.file.Path

internal class RepositoryProvider(
private val journalist: Journalist,
private val workingDirectory: Path,
private val remoteClientProvider: RemoteClientProvider,
private val authenticationFacade: AuthenticationFacade,
private val extensions: Extensions,
private val failureFacade: FailureFacade,
private val statisticsFacade: StatisticsFacade,
private val storageFacade: StorageFacade,
private val mirrorService: MirrorService,
private val repositorySecurityProvider: RepositorySecurityProvider,
repositoriesSource: Reference<List<RepositorySettings>>,
) {

val repositoryService = RepositoryService(
journalist = journalist,
repositoryProvider = this,
securityProvider = repositorySecurityProvider,
mirrorService = mirrorService,
statisticsFacade = statisticsFacade,
extensions = extensions
)

private var repositories: Map<String, Repository> = createRepositories(repositoriesSource.get())

init {
Expand All @@ -43,10 +66,11 @@ internal class RepositoryProvider(
private fun createRepositories(repositoriesConfiguration: List<RepositorySettings>): Map<String, Repository> {
val factory = RepositoryFactory(
workingDirectory = workingDirectory,
authenticationFacade = authenticationFacade,
remoteClientProvider = remoteClientProvider,
repositoryProvider = this,
failureFacade = failureFacade,
storageFacade = storageFacade,
repositoryService = repositoryService,
repositoriesNames = repositoriesConfiguration.map { it.id }
)

Expand All @@ -59,7 +83,16 @@ internal class RepositoryProvider(
.associateBy { it.name }
}

fun getRepositories(): Map<String, Repository> =
repositories

fun findRepository(name: String): Result<Repository, ErrorResponse> =
getRepository(name)
?.asSuccess()
?: notFoundError("Repository $name not found")

fun getRepository(name: String): Repository? =
repositories[name]

fun getRepositories(): Collection<Repository> =
repositories.values

}
Loading

0 comments on commit 2c32df5

Please sign in to comment.