@@ -21,6 +21,8 @@ package org.ossreviewtoolkit.utils.ort
21
21
22
22
import io.kotest.core.spec.style.WordSpec
23
23
import io.kotest.engine.spec.tempdir
24
+ import io.kotest.matchers.nulls.beNull
25
+ import io.kotest.matchers.nulls.shouldNotBeNull
24
26
import io.kotest.matchers.result.shouldBeFailure
25
27
import io.kotest.matchers.should
26
28
import io.kotest.matchers.shouldBe
@@ -34,13 +36,21 @@ import io.mockk.mockkStatic
34
36
import io.mockk.unmockkAll
35
37
36
38
import java.io.IOException
39
+ import java.net.HttpURLConnection
40
+ import java.net.PasswordAuthentication
41
+ import java.net.URI
37
42
import java.time.Duration
38
43
44
+ import kotlin.reflect.KFunction
45
+
46
+ import okhttp3.Authenticator as OkAuthenticator
39
47
import okhttp3.HttpUrl.Companion.toHttpUrl
40
48
import okhttp3.OkHttpClient
49
+ import okhttp3.Protocol
41
50
import okhttp3.Request
42
51
import okhttp3.Response
43
52
import okhttp3.ResponseBody
53
+ import okhttp3.Route
44
54
45
55
import okio.BufferedSource
46
56
@@ -135,4 +145,92 @@ class OkHttpClientHelperTest : WordSpec({
135
145
}
136
146
}
137
147
}
148
+
149
+ " JavaNetAuthenticatorWrapper" should {
150
+ " delegate to the default authenticator if the response code is not 401" {
151
+ val authenticator = mockk<OkAuthenticator >()
152
+ val route = mockk<Route >()
153
+ val response = createResponse(HttpURLConnection .HTTP_FORBIDDEN )
154
+ val modifiedRequest = mockk<Request >()
155
+ every { authenticator.authenticate(route, response) } returns modifiedRequest
156
+
157
+ val lenientAuthenticator = JavaNetAuthenticatorWrapper (authenticator)
158
+
159
+ lenientAuthenticator.authenticate(route, response) shouldBe modifiedRequest
160
+ }
161
+
162
+ " query the Java authenticator" {
163
+ val response = createResponse()
164
+ preparePasswordAuthentication(success = true)
165
+
166
+ val lenientAuthenticator = JavaNetAuthenticatorWrapper (mockk())
167
+
168
+ lenientAuthenticator.authenticate(mockk(), response) shouldNotBeNull {
169
+ header("Authorization ") shouldBe " Basic c2NvdHQ6dGlnZXI="
170
+ url shouldBe AUTH_URL .toHttpUrl()
171
+ }
172
+ }
173
+
174
+ " return null if the Java authenticator does not return a password authentication" {
175
+ val response = createResponse()
176
+ preparePasswordAuthentication(success = false)
177
+
178
+ val lenientAuthenticator = JavaNetAuthenticatorWrapper (mockk())
179
+
180
+ lenientAuthenticator.authenticate(mockk(), response) should beNull()
181
+ }
182
+
183
+ " return null if the request already has an Authorization header" {
184
+ val requestWithAuth = Request .Builder ()
185
+ .url(AUTH_URL )
186
+ .header("Authorization ", "Basic wrong-credentials")
187
+ .build()
188
+ val response = createResponse(originalRequest = requestWithAuth)
189
+ preparePasswordAuthentication(success = true)
190
+
191
+ val lenientAuthenticator = JavaNetAuthenticatorWrapper (mockk())
192
+
193
+ lenientAuthenticator.authenticate(mockk(), response) should beNull()
194
+ }
195
+ }
138
196
})
197
+
198
+ private const val USERNAME = " scott"
199
+ private const val PASSWORD = " tiger"
200
+ private const val AUTH_URL = " https://example.org/auth"
201
+
202
+ /* *
203
+ * Create a [Response] object with the given response [code]. The request of this response is set to [originalRequest]
204
+ * if it is provided; otherwise, a default request to [AUTH_URL] is created.
205
+ */
206
+ private fun createResponse (
207
+ code : Int = HttpURLConnection .HTTP_UNAUTHORIZED ,
208
+ originalRequest : Request ? = null
209
+ ): Response {
210
+ val request = originalRequest ? : Request .Builder ()
211
+ .url(AUTH_URL )
212
+ .build()
213
+ return Response .Builder ()
214
+ .request(request)
215
+ .code(code)
216
+ .protocol(Protocol .HTTP_2 )
217
+ .message(" Unauthorized" )
218
+ .build()
219
+ }
220
+
221
+ /* *
222
+ * Mock the [requestPasswordAuthentication] function to return a [PasswordAuthentication] object for the test URI
223
+ * based on the given [success] flag.
224
+ */
225
+ private fun preparePasswordAuthentication (success : Boolean ) {
226
+ val result = if (success) {
227
+ PasswordAuthentication (USERNAME , PASSWORD .toCharArray())
228
+ } else {
229
+ null
230
+ }
231
+
232
+ val resolveFunc: (URI ) -> PasswordAuthentication ? = ::requestPasswordAuthentication
233
+ mockkStatic(resolveFunc as KFunction <* >)
234
+
235
+ every { requestPasswordAuthentication(URI .create(AUTH_URL )) } returns result
236
+ }
0 commit comments