File 8652.patch of Package rclone

From b3d240d9aa3037b4ac53d9a673533923086855e3 Mon Sep 17 00:00:00 2001
From: Klaas Freitag <k.freitag@opencloud.eu>
Date: Mon, 30 Jun 2025 17:37:34 +0200
Subject: [PATCH 1/6] Add vendor OpenCloud to webdav backend

OpenCloud is a fork of ownCloud Infinite Scale
---
 backend/webdav/tus.go    |  1 +
 backend/webdav/webdav.go |  5 ++++-
 docs/content/webdav.md   | 10 ++++++++++
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/backend/webdav/tus.go b/backend/webdav/tus.go
index 3f6a843bbbd73..d88d80b370b4d 100644
--- a/backend/webdav/tus.go
+++ b/backend/webdav/tus.go
@@ -2,6 +2,7 @@ package webdav
 
 /*
    Chunked upload based on the tus protocol for ownCloud Infinite Scale
+   and OpenCloud
    See https://tus.io/protocols/resumable-upload
 */
 
diff --git a/backend/webdav/webdav.go b/backend/webdav/webdav.go
index 32d8842579462..74f1527a3da75 100644
--- a/backend/webdav/webdav.go
+++ b/backend/webdav/webdav.go
@@ -90,6 +90,9 @@ func init() {
 			}, {
 				Value: "infinitescale",
 				Help:  "ownCloud Infinite Scale",
+			}, {
+				Value: "opencloud",
+				Help:  "OpenCloud",
 			}, {
 				Value: "sharepoint",
 				Help:  "Sharepoint Online, authenticated by Microsoft account",
@@ -642,7 +645,7 @@ func (f *Fs) setQuirks(ctx context.Context, vendor string) error {
 		f.propsetMtime = true
 		f.hasOCMD5 = true
 		f.hasOCSHA1 = true
-	case "infinitescale":
+	case "opencloud", "infinitescale":
 		f.precision = time.Second
 		f.useOCMtime = true
 		f.propsetMtime = true
diff --git a/docs/content/webdav.md b/docs/content/webdav.md
index e30ef76cba9e9..611f5a6de2595 100644
--- a/docs/content/webdav.md
+++ b/docs/content/webdav.md
@@ -391,6 +391,16 @@ settings of the user through a checkbox there.
 Infinite Scale works with the chunking [tus](https://tus.io) upload protocol.
 The chunk size is currently fixed 10 MB.
 
+### OpenCloud
+
+The WebDAV URL for OpenCloud can be found in the details panel of
+any space in OpenCloud if the display was enabled in the personal
+settings of the user through a checkbox there.
+
+OpenCloud works with the chunking [tus](https://tus.io) upload protocol.
+The chunk size is currently fixed 10 MB. With that, files of any size
+can be uploaded to the cloud.
+
 ### Sharepoint Online
 
 Rclone can be used with Sharepoint provided by OneDrive for Business

From ddc290658c032290cb4a6937d5c777ab7c8321b2 Mon Sep 17 00:00:00 2001
From: Klaas Freitag <k.freitag@opencloud.eu>
Date: Mon, 30 Jun 2025 17:38:12 +0200
Subject: [PATCH 2/6] test_all: Add test infrastructure for Webdav vendor
 OpenCloud

---
 backend/webdav/webdav_test.go | 38 ++++++++++++++++++++++++-----------
 fstest/fstests/fstests.go     |  4 ++--
 fstest/test_all/config.yaml   | 11 ++++++++++
 3 files changed, 39 insertions(+), 14 deletions(-)

diff --git a/backend/webdav/webdav_test.go b/backend/webdav/webdav_test.go
index 1949a41c60fc7..20f3f45766eeb 100644
--- a/backend/webdav/webdav_test.go
+++ b/backend/webdav/webdav_test.go
@@ -22,20 +22,34 @@ func TestIntegration(t *testing.T) {
 
 // TestIntegration runs integration tests against the remote
 func TestIntegration2(t *testing.T) {
-	if *fstest.RemoteName != "" {
-		t.Skip("skipping as -remote is set")
-	}
-	fstests.Run(t, &fstests.Opt{
-		RemoteName: "TestWebdavOwncloud:",
-		NilObject:  (*Object)(nil),
-		ChunkedUpload: fstests.ChunkedUploadConfig{
-			Skip: true,
-		},
-	})
+        if *fstest.RemoteName != "" {
+                t.Skip("skipping as -remote is set")
+        }
+        fstests.Run(t, &fstests.Opt{
+                RemoteName: "TestWebdavOwncloud:",
+                NilObject:  (*Object)(nil),
+                ChunkedUpload: fstests.ChunkedUploadConfig{
+                        Skip: true,
+                },
+        })
 }
 
-// TestIntegration runs integration tests against the remote
 func TestIntegration3(t *testing.T) {
+        if *fstest.RemoteName != "" {
+                t.Skip("skipping as -remote is set")
+        }
+        fstests.Run(t, &fstests.Opt{
+                RemoteName: "TestWebdavOpenCloud:",
+                NilObject:  (*Object)(nil),
+                ChunkedUpload: fstests.ChunkedUploadConfig{
+                        Skip: true,
+                },
+        })
+}
+
+
+// TestIntegration runs integration tests against the remote
+func TestIntegration4(t *testing.T) {
 	if *fstest.RemoteName != "" {
 		t.Skip("skipping as -remote is set")
 	}
@@ -49,7 +63,7 @@ func TestIntegration3(t *testing.T) {
 }
 
 // TestIntegration runs integration tests against the remote
-func TestIntegration4(t *testing.T) {
+func TestIntegration5(t *testing.T) {
 	if *fstest.RemoteName != "" {
 		t.Skip("skipping as -remote is set")
 	}
diff --git a/fstest/fstests/fstests.go b/fstest/fstests/fstests.go
index 5e1105cfc61ef..f005408e7c48d 100644
--- a/fstest/fstests/fstests.go
+++ b/fstest/fstests/fstests.go
@@ -459,11 +459,11 @@ func Run(t *testing.T, opt *Opt) {
 		t.Logf("Didn't find %q in config file - skipping tests", remoteName)
 		return
 	}
-	require.NoError(t, err, fmt.Sprintf("unexpected error: %v", err))
+	require.NoError(t, err, fmt.Sprintf(" 1 unexpected error: %v", err))
 
 	// Get fsInfo which contains type, etc. of the fs
 	fsInfo, _, _, _, err := fs.ConfigFs(subRemoteName)
-	require.NoError(t, err, fmt.Sprintf("unexpected error: %v", err))
+	require.NoError(t, err, fmt.Sprintf(" 2 unexpected error: %v", err))
 
 	// Skip the rest if it failed
 	skipIfNotOk(t)
diff --git a/fstest/test_all/config.yaml b/fstest/test_all/config.yaml
index f24cc6cc8cc4f..7f03b7ae92e31 100644
--- a/fstest/test_all/config.yaml
+++ b/fstest/test_all/config.yaml
@@ -487,6 +487,17 @@ backends:
    ignoretests:
      - cmd/bisync
      - cmd/gitannex
+ - backend:  "webdav"
+   remote:   "TestWebdavOpenCloud:"
+   ignore:
+     - TestIntegration/FsMkdir/FsEncoding/punctuation
+     - TestIntegration/FsMkdir/FsEncoding/invalid_UTF-8
+   env:
+      - RCLONE_NO_CHECK_CERTIFICATE=true
+   fastlist: false
+   ignoretests:
+     - cmd/bisync
+     - cmd/gitannex
  - backend:  "webdav"
    remote:   "TestWebdavRclone:"
    ignore:

From d5e641ff71aad26890b9aac1f29c933dc7b11296 Mon Sep 17 00:00:00 2001
From: Klaas Freitag <k.freitag@opencloud.eu>
Date: Wed, 2 Jul 2025 16:32:29 +0200
Subject: [PATCH 3/6] Add OpenCloud testserver start script

---
 fstest/testserver/init.d/TestWebdavOpenCloud | 52 ++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100755 fstest/testserver/init.d/TestWebdavOpenCloud

diff --git a/fstest/testserver/init.d/TestWebdavOpenCloud b/fstest/testserver/init.d/TestWebdavOpenCloud
new file mode 100755
index 0000000000000..ce93de18d39d6
--- /dev/null
+++ b/fstest/testserver/init.d/TestWebdavOpenCloud
@@ -0,0 +1,52 @@
+#!/usr/bin/env bash
+
+set -e
+
+NAME=opencloud
+USER=admin
+PASS=admin
+PORT=9200
+
+CONF_DIR=/tmp/opencloud-config
+install -d -m 0777 ${CONF_DIR}
+
+. $(dirname "$0")/docker.bash
+
+start() {
+    echo "*************************** init"
+    docker run --rm --name $NAME \
+           -v ${CONF_DIR}:/etc/opencloud \
+           -e "OC_INSECURE=true" \
+           -e "IDM_ADMIN_PASSWORD=$PASS" \
+           -e "OC_FORCE_CONFIG_OVERWRITE=true" \
+           -e "OC_URL=https://127.0.0.1:$PORT" \
+           opencloudeu/opencloud-rolling \
+           init
+
+    docker run --rm -d --name $NAME \
+           -e "OC_LOG_LEVEL=debug" \
+           -e "OC_LOG_PRETTY=true" \
+           -e "OC_URL=https://127.0.0.1:$PORT" \
+           -e "IDM_ADMIN_PASSWORD=$PASS" \
+           -e "OC_INSECURE=true" \
+           -e "PROXY_ENABLE_BASIC_AUTH=true" \
+           -v ${CONF_DIR}:/etc/opencloud \
+           -p 127.0.0.1:${PORT}:9200 \
+           opencloudeu/opencloud-rolling 
+    
+    echo type=webdav
+    echo url=https://127.0.0.1:${PORT}/dav/spaces/some-admin-user-id-0000-100000000000
+    echo user=$USER
+    echo pass=$(rclone obscure $PASS)
+    echo vendor=opencloud
+    echo _connect=127.0.0.1:${PORT}
+    echo _connect_delay=5s
+}
+
+stop() {
+    # Clean up the mess
+    docker stop opencloud 
+    rm -r ${CONF_DIR}
+}
+
+. $(dirname "$0")/run.bash

From 726c5d4e270116e0bf5e511b22524725b8840629 Mon Sep 17 00:00:00 2001
From: Klaas Freitag <k.freitag@opencloud.eu>
Date: Thu, 10 Jul 2025 18:25:08 +0200
Subject: [PATCH 4/6] Fix some startup parameters and retrieve the correct
 WebDAV Url

OpenCloud needs a so called storage provider ID (mount id) and
the final WebDAV Url for the test has to be queried
---
 fstest/testserver/init.d/TestWebdavOpenCloud | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/fstest/testserver/init.d/TestWebdavOpenCloud b/fstest/testserver/init.d/TestWebdavOpenCloud
index ce93de18d39d6..87c907130f377 100755
--- a/fstest/testserver/init.d/TestWebdavOpenCloud
+++ b/fstest/testserver/init.d/TestWebdavOpenCloud
@@ -20,24 +20,32 @@ start() {
            -e "IDM_ADMIN_PASSWORD=$PASS" \
            -e "OC_FORCE_CONFIG_OVERWRITE=true" \
            -e "OC_URL=https://127.0.0.1:$PORT" \
+	   -e "OC_ADMIN_USER_ID=some-admin-user-id-0000-100000000000" \
+	   -e "GATEWAY_STORAGE_USERS_MOUNT_ID=storage-users-1" \
+           -e "STORAGE_USERS_MOUNT_ID=storage-users-1" \
            opencloudeu/opencloud-rolling \
            init
 
-    docker run --rm -d --name $NAME \
+    docker run -d --name $NAME \
            -e "OC_LOG_LEVEL=debug" \
            -e "OC_LOG_PRETTY=true" \
            -e "OC_URL=https://127.0.0.1:$PORT" \
            -e "IDM_ADMIN_PASSWORD=$PASS" \
+           -e "OC_ADMIN_USER_ID=some-admin-user-id-0000-100000000000" \
+           -e "GATEWAY_STORAGE_USERS_MOUNT_ID=storage-users-1" \
+           -e "STORAGE_USERS_MOUNT_ID=storage-users-1" \
            -e "OC_INSECURE=true" \
            -e "PROXY_ENABLE_BASIC_AUTH=true" \
            -v ${CONF_DIR}:/etc/opencloud \
            -p 127.0.0.1:${PORT}:9200 \
            opencloudeu/opencloud-rolling 
-    
+
+    sleep 10
     echo type=webdav
-    echo url=https://127.0.0.1:${PORT}/dav/spaces/some-admin-user-id-0000-100000000000
+    url=$(curl -f -s -k -u admin:${PASS} "https://127.0.0.1:${PORT}/graph/v1.0/me/drive"   -H 'accept: application/json' | jq -r '.root.webDavUrl' - )
+    echo url=${url}
     echo user=$USER
-    echo pass=$(rclone obscure $PASS)
+    echo pass=$(/home/kf/git/rclone/rclone obscure $PASS)
     echo vendor=opencloud
     echo _connect=127.0.0.1:${PORT}
     echo _connect_delay=5s

From 8b9a3848c33c820fd38c1370daa9ca8dcef8200b Mon Sep 17 00:00:00 2001
From: Klaas Freitag <k.freitag@opencloud.eu>
Date: Thu, 10 Jul 2025 18:26:48 +0200
Subject: [PATCH 5/6] OpenCloud can not set the modification time via PROPSET

Adjusted the config parameters accordingly
---
 backend/webdav/webdav.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/backend/webdav/webdav.go b/backend/webdav/webdav.go
index 74f1527a3da75..e7ea740d5b551 100644
--- a/backend/webdav/webdav.go
+++ b/backend/webdav/webdav.go
@@ -648,7 +648,7 @@ func (f *Fs) setQuirks(ctx context.Context, vendor string) error {
 	case "opencloud", "infinitescale":
 		f.precision = time.Second
 		f.useOCMtime = true
-		f.propsetMtime = true
+		f.propsetMtime = false
 		f.hasOCMD5 = false
 		f.hasOCSHA1 = true
 		f.canChunk = false

From 04a979b07daa01fcd237fb93882b870a01601436 Mon Sep 17 00:00:00 2001
From: Klaas Freitag <k.freitag@opencloud.eu>
Date: Wed, 10 Sep 2025 10:05:24 +0200
Subject: [PATCH 6/6] Fix formatting, makes linter hopefully happy

---
 backend/webdav/webdav_test.go | 41 +++++++++++++++++------------------
 1 file changed, 20 insertions(+), 21 deletions(-)

diff --git a/backend/webdav/webdav_test.go b/backend/webdav/webdav_test.go
index 20f3f45766eeb..6f06956537596 100644
--- a/backend/webdav/webdav_test.go
+++ b/backend/webdav/webdav_test.go
@@ -22,32 +22,31 @@ func TestIntegration(t *testing.T) {
 
 // TestIntegration runs integration tests against the remote
 func TestIntegration2(t *testing.T) {
-        if *fstest.RemoteName != "" {
-                t.Skip("skipping as -remote is set")
-        }
-        fstests.Run(t, &fstests.Opt{
-                RemoteName: "TestWebdavOwncloud:",
-                NilObject:  (*Object)(nil),
-                ChunkedUpload: fstests.ChunkedUploadConfig{
-                        Skip: true,
-                },
-        })
+	if *fstest.RemoteName != "" {
+		t.Skip("skipping as -remote is set")
+	}
+	fstests.Run(t, &fstests.Opt{
+		RemoteName: "TestWebdavOwncloud:",
+		NilObject:  (*Object)(nil),
+		ChunkedUpload: fstests.ChunkedUploadConfig{
+			Skip: true,
+		},
+	})
 }
 
 func TestIntegration3(t *testing.T) {
-        if *fstest.RemoteName != "" {
-                t.Skip("skipping as -remote is set")
-        }
-        fstests.Run(t, &fstests.Opt{
-                RemoteName: "TestWebdavOpenCloud:",
-                NilObject:  (*Object)(nil),
-                ChunkedUpload: fstests.ChunkedUploadConfig{
-                        Skip: true,
-                },
-        })
+	if *fstest.RemoteName != "" {
+		t.Skip("skipping as -remote is set")
+	}
+	fstests.Run(t, &fstests.Opt{
+		RemoteName: "TestWebdavOpenCloud:",
+		NilObject:  (*Object)(nil),
+		ChunkedUpload: fstests.ChunkedUploadConfig{
+			Skip: true,
+		},
+	})
 }
 
-
 // TestIntegration runs integration tests against the remote
 func TestIntegration4(t *testing.T) {
 	if *fstest.RemoteName != "" {
openSUSE Build Service is sponsored by