Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
Signed-off-by: tobiasKaminsky <[email protected]>
  • Loading branch information
tobiasKaminsky authored and ZetaTom committed Mar 11, 2024
1 parent 392e7d5 commit 8fbd487
Show file tree
Hide file tree
Showing 24 changed files with 570 additions and 165 deletions.
1 change: 0 additions & 1 deletion dav4jvm
Submodule dav4jvm deleted from c61e4b
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ public static void beforeAll() throws InterruptedException,
String userId = loginName; // for test same as userId
String credentials = Credentials.basic(loginName, password);
nextcloudClient = new NextcloudClient(url, userId, credentials, context);
nextcloudClient.setUserId(userId);

waitForServer(client, url);
testConnection();
Expand Down
65 changes: 56 additions & 9 deletions library/src/androidTest/java/com/owncloud/android/Dav4JVM.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,13 @@ package com.owncloud.android
import at.bitfire.dav4jvm.DavResource
import at.bitfire.dav4jvm.Response
import com.nextcloud.common.NextcloudAuthenticator
import com.nextcloud.operations.PropFindMethod
import com.nextcloud.test.RandomStringGenerator
import com.owncloud.android.lib.common.network.WebdavUtils
import com.owncloud.android.lib.common.utils.WebDavFileUtils
import com.owncloud.android.lib.resources.files.CreateFolderRemoteOperation
import com.owncloud.android.lib.resources.files.ReadFolderRemoteOperation
import com.owncloud.android.lib.resources.files.ReadFolderRemoteOperationIT
import com.owncloud.android.lib.resources.files.SearchRemoteOperation
import com.owncloud.android.lib.resources.files.ToggleFavoriteRemoteOperation
import com.owncloud.android.lib.resources.files.UploadFileRemoteOperation
Expand All @@ -42,6 +45,9 @@ import com.owncloud.android.lib.resources.shares.CreateShareRemoteOperation
import com.owncloud.android.lib.resources.shares.OCShare
import com.owncloud.android.lib.resources.shares.ShareType
import com.owncloud.android.lib.resources.status.OCCapability
import com.owncloud.android.lib.resources.tags.CreateTagRemoteOperation
import com.owncloud.android.lib.resources.tags.GetTagsRemoteOperation
import com.owncloud.android.lib.resources.tags.PutTagRemoteOperation
import okhttp3.HttpUrl.Companion.toHttpUrl
import org.apache.jackrabbit.webdav.DavConstants
import org.junit.Assert.assertEquals
Expand All @@ -57,7 +63,7 @@ class Dav4JVM : AbstractIT() {
@Throws(IOException::class)
fun singlePropfind() {
val path = "/testFolder/"
val subFolder = "$path subfolder/"
val subFolder = path + "subfolder/"

// create folder
CreateFolderRemoteOperation(
Expand Down Expand Up @@ -96,14 +102,35 @@ class Dav4JVM : AbstractIT() {
assertTrue(ReadFolderRemoteOperation(subFolder).execute(client).isSuccess)

// do old read folder operation to compare data against it
val result = ReadFolderRemoteOperation(path).execute(client).data as List<RemoteFile>
var result = ReadFolderRemoteOperation(path).execute(client).data as List<RemoteFile>
assertEquals(2, result.size)
val oldRemoteFile = result[0]
val oldSubFolderFile = result[1]
var oldRemoteFile = result[0]
var oldSubFolderFile = result[1]

assertEquals(path, oldRemoteFile.remotePath)
assertEquals(subFolder, oldSubFolderFile.remotePath)

// create tag
val tag1 = "a" + RandomStringGenerator.make(ReadFolderRemoteOperationIT.TAG_LENGTH)
assertTrue(CreateTagRemoteOperation(tag1).execute(nextcloudClient).isSuccess)

// list tags
val tags = GetTagsRemoteOperation().execute(client).resultData

// add tag
assertTrue(
PutTagRemoteOperation(
tags[0].id,
oldRemoteFile.localId
).execute(nextcloudClient).isSuccess
)

// do old read folder operation to compare data against it
result = ReadFolderRemoteOperation(path).execute(client).data as List<RemoteFile>
assertEquals(2, result.size)
oldRemoteFile = result[0]
oldSubFolderFile = result[1]

// new
val httpUrl = (nextcloudClient.filesDavUri.toString() + path).toHttpUrl()

Expand All @@ -116,14 +143,14 @@ class Dav4JVM : AbstractIT() {
val client = nextcloudClient.client
.newBuilder()
.followRedirects(false)
.authenticator(NextcloudAuthenticator(nextcloudClient.credentials, "Authorization"))
.authenticator(NextcloudAuthenticator(nextcloudClient.credentials))
.build()

// register custom property
// TODO check how to do it in a central way
WebdavUtils.registerCustomFactories()

// TODO use DavResource().propfind in ReadFileRemoteOperation/ReadFolderRemoteOperation
// TODO extract in own class for convenient use
// TODO test all properties on server!
DavResource(client, httpUrl)
.propfind(
Expand All @@ -144,8 +171,20 @@ class Dav4JVM : AbstractIT() {
assertEquals(1, memberElements.size)

val remoteFile = WebDavFileUtils().parseResponse(rootElement, nextcloudClient.filesDavUri)

assertTrue(oldRemoteFile == remoteFile)

val subfolderFile =
WebDavFileUtils().parseResponse(memberElements[0], nextcloudClient.filesDavUri)
assertTrue(oldSubFolderFile == subfolderFile)

// new propfind
val newResult = nextcloudClient.execute(PropFindMethod(httpUrl))

assertTrue(newResult.success)
assertTrue(oldRemoteFile == newResult.root)

assertEquals(1, newResult.children.size)
assertTrue(oldSubFolderFile == newResult.children[0])
}

@Test
Expand Down Expand Up @@ -182,7 +221,11 @@ class Dav4JVM : AbstractIT() {
"test",
SearchRemoteOperation.SearchType.FILE_SEARCH,
false,
OCCapability(23, 0, 0)
OCCapability().apply {
versionMayor = 23
versionMinor = 0
versionMicro = 0
}
).execute(
client
)
Expand All @@ -201,7 +244,11 @@ class Dav4JVM : AbstractIT() {
"test",
SearchRemoteOperation.SearchType.FILE_SEARCH,
false,
OCCapability(23, 0, 0)
OCCapability().apply {
versionMayor = 23
versionMinor = 0
versionMicro = 0
}
).execute(
nextcloudClient
)
Expand Down
38 changes: 38 additions & 0 deletions library/src/main/java/com/nextcloud/common/DavMethod.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
*
* Nextcloud Android client application
*
* @author Tobias Kaminsky
* Copyright (C) 2023 Tobias Kaminsky
* Copyright (C) 2023 Nextcloud GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.nextcloud.common

import android.net.Uri
import com.owncloud.android.lib.common.network.WebdavUtils
import okhttp3.HttpUrl
import okhttp3.OkHttpClient

abstract class DavMethod<T>(private val httpUrl: HttpUrl) {
fun execute(nextcloudClient: NextcloudClient): T {
// register custom property
WebdavUtils.registerCustomFactories()

return apply(nextcloudClient.disabledRedirectClient(), httpUrl, nextcloudClient.filesDavUri)
}

abstract fun apply(client: OkHttpClient, httpUrl: HttpUrl, filesDavUri: Uri): T
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,17 @@
import okhttp3.Route;

public class NextcloudAuthenticator implements Authenticator {
private String credentials;
private String authenticatorType;
private final String credentials;

public NextcloudAuthenticator(@NonNull String credentials, @NonNull String authenticatorType) {
public NextcloudAuthenticator(@NonNull String credentials) {
this.credentials = credentials;
this.authenticatorType = authenticatorType;
}

@Nullable
@Override
public Request authenticate(@Nullable Route route, @NonNull Response response) {
String authenticatorType = "Authorization";

if (response.request().header(authenticatorType) != null) {
return null;
}
Expand Down
12 changes: 12 additions & 0 deletions library/src/main/java/com/nextcloud/common/NextcloudClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,18 @@ class NextcloudClient private constructor(
return httpStatus
}

fun <T> execute(method: DavMethod<T>): T {
return method.execute(this)
}

fun disabledRedirectClient(): OkHttpClient {
return client
.newBuilder()
.followRedirects(false)
.authenticator(NextcloudAuthenticator(credentials))
.build()
}

internal fun execute(request: Request): ResponseOrError {
return try {
val response = client.newCall(request).execute()
Expand Down
61 changes: 61 additions & 0 deletions library/src/main/java/com/nextcloud/operations/PropFindMethod.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
*
* Nextcloud Android client application
*
* @author Tobias Kaminsky
* Copyright (C) 2023 Tobias Kaminsky
* Copyright (C) 2023 Nextcloud GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.nextcloud.operations

import android.net.Uri
import at.bitfire.dav4jvm.DavResource
import at.bitfire.dav4jvm.Response
import com.nextcloud.common.DavMethod
import com.owncloud.android.lib.common.network.WebdavUtils
import com.owncloud.android.lib.common.utils.WebDavFileUtils
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
import org.apache.jackrabbit.webdav.DavConstants

class PropFindMethod(httpUrl: HttpUrl) : DavMethod<PropFindResult>(httpUrl) {
override fun apply(client: OkHttpClient, httpUrl: HttpUrl, filesDavUri: Uri): PropFindResult {
val webDavFileUtils = WebDavFileUtils()
val result = PropFindResult()

DavResource(client, httpUrl)
.propfind(
DavConstants.DEPTH_1,
*WebdavUtils.getAllPropertiesList()
) { response: Response, hrefRelation: Response.HrefRelation? ->
result.success = response.isSuccess()

when (hrefRelation) {
Response.HrefRelation.MEMBER -> result.children.add(
webDavFileUtils.parseResponse(response, filesDavUri)
)

Response.HrefRelation.SELF -> result.root =
webDavFileUtils.parseResponse(response, filesDavUri)

Response.HrefRelation.OTHER -> {}
else -> {}
}
}

return result
}
}
32 changes: 32 additions & 0 deletions library/src/main/java/com/nextcloud/operations/PropFindResult.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
*
* Nextcloud Android client application
*
* @author Tobias Kaminsky
* Copyright (C) 2023 Tobias Kaminsky
* Copyright (C) 2023 Nextcloud GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.nextcloud.operations

import com.owncloud.android.lib.resources.files.model.RemoteFile

data class PropFindResult(
var success: Boolean = false,
var root: RemoteFile = RemoteFile(),
val children: MutableList<RemoteFile> = mutableListOf()
)

Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ class WebdavEntry constructor(ms: MultiStatusResponse, splitElement: String) {
}

val isDirectory: Boolean
get() = "DIR" == contentType
get() = DIR_TYPE == contentType

private fun resetData() {
permissions = null
Expand All @@ -592,6 +592,8 @@ class WebdavEntry constructor(ms: MultiStatusResponse, splitElement: String) {

companion object {
private val TAG = WebdavEntry::class.java.simpleName
private const val IS_ENCRYPTED = "1"
private const val CODE_PROP_NOT_FOUND = 404
const val NAMESPACE_OC = "http://owncloud.org/ns"
const val NAMESPACE_NC = "http://nextcloud.org/ns"
const val EXTENDED_PROPERTY_NAME_PERMISSIONS = "permissions"
Expand Down Expand Up @@ -637,7 +639,6 @@ class WebdavEntry constructor(ms: MultiStatusResponse, splitElement: String) {
const val SHAREES_SHARE_TYPE = "type"
const val PROPERTY_QUOTA_USED_BYTES = "quota-used-bytes"
const val PROPERTY_QUOTA_AVAILABLE_BYTES = "quota-available-bytes"
private const val IS_ENCRYPTED = "1"
private const val CODE_PROP_NOT_FOUND = 404
const val DIR_TYPE = "DIR"
}
}
Loading

0 comments on commit 8fbd487

Please sign in to comment.