Skip to content

Commit 6c5ab2e

Browse files
oheger-boschsschuberth
authored andcommitted
feat(gradle): Support authentication for repositories
Extend the repository model to contain credential information. This allows the Gradle package manager to pass this information to Maven when resolving packages. So, package metadata can now be downloaded from private repositories. Signed-off-by: Oliver Heger <[email protected]>
1 parent 08cef9b commit 6c5ab2e

File tree

6 files changed

+77
-16
lines changed

6 files changed

+77
-16
lines changed

plugins/package-managers/gradle-model/src/main/kotlin/GradleModel.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ interface OrtDependencyTreeModel {
2727
val name: String
2828
val version: String
2929
val configurations: List<OrtConfiguration>
30-
val repositories: List<String>
30+
val repositories: List<OrtRepository>
3131
val errors: List<String>
3232
val warnings: List<String>
3333
}
@@ -64,3 +64,9 @@ interface OrtVcsModel {
6464
val tag: String
6565
val browsableUrl: String
6666
}
67+
68+
interface OrtRepository {
69+
val url: String
70+
val username: String?
71+
val password: String?
72+
}

plugins/package-managers/gradle-plugin/src/main/kotlin/GradleModelExtensions.kt

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,12 @@
1919

2020
package org.ossreviewtoolkit.plugins.packagemanagers.gradleplugin
2121

22+
import OrtRepository
23+
2224
import org.gradle.api.artifacts.Configuration
2325
import org.gradle.api.artifacts.dsl.RepositoryHandler
26+
import org.gradle.api.artifacts.repositories.ArtifactRepository
27+
import org.gradle.api.artifacts.repositories.AuthenticationSupported
2428
import org.gradle.api.artifacts.repositories.UrlArtifactRepository
2529
import org.gradle.api.attributes.AttributeContainer
2630
import org.gradle.internal.deprecation.DeprecatableConfiguration
@@ -58,7 +62,21 @@ internal fun Configuration.isRelevant(): Boolean {
5862
}
5963

6064
/**
61-
* Return a map that associates names of artifact repositories to their URLs.
65+
* Return a map that associates names of artifact repositories to their model representations.
66+
*/
67+
internal fun RepositoryHandler.associateNamesWithUrlsTo(repositories: MutableMap<String, OrtRepository?>) =
68+
associateTo(repositories) { it.name to it.toOrtRepository() }
69+
70+
/**
71+
* Convert this [ArtifactRepository] to an [OrtRepository] if it possesses the relevant properties. Return *null* for
72+
* an unsupported repository type.
6273
*/
63-
internal fun RepositoryHandler.associateNamesWithUrlsTo(repositories: MutableMap<String, String?>) =
64-
associateTo(repositories) { it.name to (it as? UrlArtifactRepository)?.url?.toString() }
74+
private fun ArtifactRepository.toOrtRepository(): OrtRepository? =
75+
(this as? UrlArtifactRepository)?.let { urlRepository ->
76+
val credentials = (urlRepository as? AuthenticationSupported)?.credentials
77+
OrtRepositoryImpl(
78+
url = urlRepository.url.toString(),
79+
username = credentials?.username,
80+
password = credentials?.password
81+
)
82+
}

plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelBuilder.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ package org.ossreviewtoolkit.plugins.packagemanagers.gradleplugin
2121

2222
import OrtDependency
2323
import OrtDependencyTreeModel
24+
import OrtRepository
2425

2526
import org.apache.maven.model.building.FileModelSource
2627
import org.apache.maven.model.building.ModelBuildingResult
@@ -48,7 +49,7 @@ import org.gradle.tooling.provider.model.ToolingModelBuilder
4849
import org.gradle.util.GradleVersion
4950

5051
internal class OrtModelBuilder : ToolingModelBuilder {
51-
private val repositories = mutableMapOf<String, String?>()
52+
private val repositories = mutableMapOf<String, OrtRepository?>()
5253

5354
private val platformCategories = setOf("platform", "enforced-platform")
5455

@@ -186,10 +187,10 @@ internal class OrtModelBuilder : ToolingModelBuilder {
186187
if (it == "26c913274550a0b2221f47a0fe2d2358") "MavenRepo" else it
187188
}.getOrNull()
188189

189-
repositories[repositoryId]?.let { repositoryUrl ->
190+
repositories[repositoryId]?.let { repository ->
190191
// Note: Only Maven-style layout is supported for now.
191192
buildString {
192-
append(repositoryUrl.removeSuffix("/"))
193+
append(repository.url.removeSuffix("/"))
193194
append('/')
194195
append(id.group.replace('.', '/'))
195196
append('/')

plugins/package-managers/gradle-plugin/src/main/kotlin/OrtModelImpl.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import OrtConfiguration
2323
import OrtDependency
2424
import OrtDependencyTreeModel
2525
import OrtMavenModel
26+
import OrtRepository
2627
import OrtVcsModel
2728

2829
import java.io.Serializable
@@ -33,7 +34,7 @@ internal class OrtDependencyTreeModelImpl(
3334
override val name: String,
3435
override val version: String,
3536
override val configurations: List<OrtConfiguration>,
36-
override val repositories: List<String>,
37+
override val repositories: List<OrtRepository>,
3738
override val errors: List<String>,
3839
override val warnings: List<String>
3940
) : OrtDependencyTreeModel, Serializable
@@ -74,3 +75,10 @@ internal class OrtVcsModelImpl(
7475
override val tag: String,
7576
override val browsableUrl: String
7677
) : OrtVcsModel, Serializable
78+
79+
@Suppress("SerialVersionUIDInSerializableClass")
80+
internal class OrtRepositoryImpl(
81+
override val url: String,
82+
override val username: String?,
83+
override val password: String?
84+
) : OrtRepository, Serializable

plugins/package-managers/gradle/src/main/kotlin/Gradle.kt

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
package org.ossreviewtoolkit.plugins.packagemanagers.gradle
2121

2222
import OrtDependencyTreeModel
23+
import OrtRepository
2324

2425
import java.io.ByteArrayOutputStream
2526
import java.io.File
@@ -32,6 +33,7 @@ import org.eclipse.aether.artifact.Artifact
3233
import org.eclipse.aether.repository.RemoteRepository
3334
import org.eclipse.aether.repository.WorkspaceReader
3435
import org.eclipse.aether.repository.WorkspaceRepository
36+
import org.eclipse.aether.util.repository.AuthenticationBuilder
3537

3638
import org.gradle.tooling.GradleConnector
3739
import org.gradle.tooling.events.ProgressListener
@@ -262,10 +264,7 @@ class Gradle(
262264

263265
initScriptFile.parentFile.safeDeleteRecursively()
264266

265-
val repositories = dependencyTreeModel.repositories.map {
266-
// TODO: Also handle authentication and snapshot policy.
267-
RemoteRepository.Builder(it, "default", it).build()
268-
}
267+
val repositories = dependencyTreeModel.repositories.map { it.toRemoteRepository() }
269268

270269
dependencyHandler.repositories = repositories
271270

@@ -326,3 +325,19 @@ private fun getGradleProperties(): Map<String, String> =
326325
}
327326
?.toMap()
328327
.orEmpty()
328+
329+
/**
330+
* Convert this [OrtRepository] to a [RemoteRepository] taking the known properties into account.
331+
* TODO: Also handle snapshot policy.
332+
*/
333+
private fun OrtRepository.toRemoteRepository(): RemoteRepository =
334+
RemoteRepository.Builder(url, "default", url).apply {
335+
if (username != null) {
336+
setAuthentication(
337+
AuthenticationBuilder().apply {
338+
addUsername(username)
339+
password?.also(::addPassword)
340+
}.build()
341+
)
342+
}
343+
}.build()

plugins/package-managers/gradle/src/main/resources/init.gradle

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ interface OrtDependencyTreeModel {
5656
String getName()
5757
String getVersion()
5858
List<OrtConfiguration> getConfigurations()
59-
List<String> getRepositories()
59+
List<OrtRepository> getRepositories()
6060
List<String> getErrors()
6161
List<String> getWarnings()
6262
}
@@ -79,14 +79,20 @@ interface OrtDependency {
7979
String getLocalPath()
8080
}
8181

82+
interface OrtRepository {
83+
String getUrl()
84+
String getUsername()
85+
String getPassword()
86+
}
87+
8288
@ToString(includeNames = true)
8389
@TupleConstructor
8490
class OrtDependencyTreeModelImpl implements OrtDependencyTreeModel, Serializable {
8591
String group
8692
String name
8793
String version
8894
List<OrtConfiguration> configurations
89-
List<String> repositories
95+
List<OrtRepository> repositories
9096
List<String> errors
9197
List<String> warnings
9298
}
@@ -113,6 +119,13 @@ class OrtDependencyImpl implements OrtDependency, Serializable {
113119
String localPath
114120
}
115121

122+
@TupleConstructor
123+
class OrtRepositoryImpl implements OrtRepository, Serializable {
124+
String url = ''
125+
String username = null
126+
String password = null
127+
}
128+
116129
class OrtDependencyTreeGradlePlugin extends AbstractOrtDependencyTreePlugin<Gradle> {
117130
@Inject
118131
OrtDependencyTreeGradlePlugin(ToolingModelBuilderRegistry registry) {
@@ -221,9 +234,9 @@ class AbstractOrtDependencyTreePlugin<T> implements Plugin<T> {
221234
}
222235
}
223236

224-
List<String> repositories = project.repositories.findResults {
237+
List<OrtRepository> repositories = project.repositories.findResults {
225238
if (it instanceof DefaultMavenArtifactRepository) {
226-
it.url.toString()
239+
new OrtRepositoryImpl(it.url.toString(), it.credentials?.username, it.credentials?.password)
227240
} else if (it instanceof DefaultFlatDirArtifactRepository) {
228241
warnings.add('Project uses a flat dir repository which is not supported by the analyzer. ' +
229242
"Dependencies from this repository will be ignored: ${it.dirs}".toString())

0 commit comments

Comments
 (0)