Skip to content

Commit 0d71743

Browse files
authored
Kotlin wrapper fix: use File direct access to fix the FileNotFound exception (#810)
* Using a more straightforward kotlin way to prevent access issues * Adding more file checks * Adding full path to test media file * Adding a FileResover injection approach * detekt * PR suggestions. Making the fileResolver an interface and extracting some conditions
1 parent 1ae11b4 commit 0d71743

File tree

4 files changed

+50
-9
lines changed

4 files changed

+50
-9
lines changed

native/kotlin/api/kotlin/src/integrationTest/kotlin/MediaEndpointTest.kt

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ import org.junit.jupiter.api.Test
66
import uniffi.wp_api.MediaCreateParams
77
import uniffi.wp_api.MediaListParams
88
import uniffi.wp_api.SparseMediaFieldWithEditContext
9+
import uniffi.wp_api.WpAuthenticationProvider
10+
import java.io.File
911
import kotlin.test.assertEquals
1012
import kotlin.test.assertNotNull
1113

1214
private const val MEDIA_ID_611: Long = 611
1315

1416
class MediaEndpointTest {
15-
private val client = defaultApiClient()
17+
private val client = mediaApiClient()
1618

1719
@Test
1820
fun testMediaListRequest() = runTest {
@@ -74,4 +76,29 @@ class MediaEndpointTest {
7476
assertEquals(title, response.title.rendered)
7577
restoreTestServer()
7678
}
79+
80+
fun mediaApiClient(): WpApiClient {
81+
val testCredentials = TestCredentials.INSTANCE
82+
val authProvider = WpAuthenticationProvider.staticWithUsernameAndPassword(
83+
username = testCredentials.adminUsername, password = testCredentials.adminPassword
84+
)
85+
val requestExecutor = WpRequestExecutor(
86+
fileResolver = FileResolverMock()
87+
)
88+
return WpApiClient(
89+
wpOrgSiteApiRootUrl = testCredentials.apiRootUrl,
90+
authProvider = authProvider,
91+
requestExecutor = requestExecutor
92+
)
93+
}
94+
95+
class FileResolverMock: FileResolver {
96+
// in order to properly resolve the file from the test assets, we need to do it in the following way
97+
override fun getFile(path: String): File? =
98+
WpAuthenticationProvider::class.java.classLoader?.getResource(path)?.file?.let {
99+
File(
100+
it
101+
)
102+
}
103+
}
77104
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package rs.wordpress.api.kotlin
2+
3+
import java.io.File
4+
5+
class DefaultFileResolver : FileResolver {
6+
override fun getFile(path: String): File? = File(path)
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package rs.wordpress.api.kotlin
2+
3+
import java.io.File
4+
5+
interface FileResolver {
6+
fun getFile(path: String): File?
7+
}

native/kotlin/api/kotlin/src/main/kotlin/rs/wordpress/api/kotlin/WpRequestExecutor.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ const val USER_AGENT_HEADER_NAME = "User-Agent"
3232

3333
class WpRequestExecutor(
3434
private val httpClient: WpHttpClient = WpHttpClient.DefaultHttpClient(),
35-
private val dispatcher: CoroutineDispatcher = Dispatchers.IO
35+
private val dispatcher: CoroutineDispatcher = Dispatchers.IO,
36+
private val fileResolver: FileResolver = DefaultFileResolver()
3637
) : RequestExecutor {
3738
override suspend fun execute(request: WpNetworkRequest): WpNetworkResponse =
3839
withContext(dispatcher) {
@@ -88,13 +89,10 @@ class WpRequestExecutor(
8889
mediaUploadRequest.mediaParams().forEach { (k, v) ->
8990
multipartBodyBuilder.addFormDataPart(k, v)
9091
}
91-
val filePath = mediaUploadRequest.filePath()
92-
val file =
93-
WpRequestExecutor::class.java.classLoader?.getResource(filePath)?.file?.let {
94-
File(
95-
it
96-
)
97-
} ?: throw MediaUploadRequestExecutionException.MediaFileNotFound(filePath)
92+
val file = fileResolver.getFile(mediaUploadRequest.filePath())
93+
if (file == null || !file.canBeUploaded()) {
94+
throw MediaUploadRequestExecutionException.MediaFileNotFound(mediaUploadRequest.filePath())
95+
}
9896
multipartBodyBuilder.addFormDataPart(
9997
name = "file",
10098
filename = file.name,
@@ -124,6 +122,8 @@ class WpRequestExecutor(
124122
override suspend fun sleep(millis: ULong) {
125123
delay(millis.toLong())
126124
}
125+
126+
private fun File.canBeUploaded() = exists() && isFile && canRead()
127127
}
128128

129129
private fun RequestExecutionErrorReason.Companion.unknownHost(e: UnknownHostException) =

0 commit comments

Comments
 (0)