Discovery: consider also the "shared by me" as shared
authorOlivier Goffart <ogoffart@woboq.com>
Mon, 14 Nov 2016 17:47:58 +0000 (18:47 +0100)
committerOlivier Goffart <olivier@woboq.com>
Tue, 15 Nov 2016 13:32:20 +0000 (14:32 +0100)
The "S" in the permission is only for the "Shared with me" files.
It is only used to show the shared status in the overlay icons.
But we also wish to show the shared status for files that are shared
"by" the users. We can find that out using the 'share-types' webdav
property. If set, then we are sharing the object.
We fake a 'S' in the permission as for our purpose, they mean the same.

Issue #4788

src/libsync/discoveryphase.cpp
test/syncenginetestutils.h
test/testsyncfilestatustracker.cpp

index bb35f1f97f8a58ddb30a202be4ce6931f5787dba..d11749d59bee602ae1b39e13720d243103cd34e7 100644 (file)
@@ -20,6 +20,7 @@
 #include <QUrl>
 #include "account.h"
 #include <QFileInfo>
+#include <cstring>
 
 namespace OCC {
 
@@ -236,7 +237,8 @@ void DiscoverySingleDirectoryJob::start()
     QList<QByteArray> props;
     props << "resourcetype" << "getlastmodified" << "getcontentlength" << "getetag"
           << "http://owncloud.org/ns:id" << "http://owncloud.org/ns:downloadURL"
-          << "http://owncloud.org/ns:dDC" << "http://owncloud.org/ns:permissions";
+          << "http://owncloud.org/ns:dDC" << "http://owncloud.org/ns:permissions"
+          << "http://owncloud.org/ns:share-types";
     if (_isRootPath)
         props << "http://owncloud.org/ns:data-fingerprint";
 
@@ -308,9 +310,25 @@ static csync_vio_file_stat_t* propertyMapToFileStat(const QMap<QString,QString>
             } else {
                 qWarning() << "permissions too large" << v;
             }
+        } else if (property == "share-types" && !value.isEmpty()) {
+            // Since QMap is sorted, "share-types" is always "permissions".
+            if (file_stat->remotePerm[0] == '\0' || !(file_stat->fields & CSYNC_VIO_FILE_STAT_FIELDS_PERM)) {
+                qWarning() << "Server returned a share type, but no permissions?";
+            } else {
+                // S means shared with me.
+                // But for our purpose, we want to know if the file is shared. It does not matter
+                // if we are the owner or not.
+                // Piggy back on the persmission field 'S'
+                if (!std::strchr(file_stat->remotePerm, 'S')) {
+                    if (std::strlen(file_stat->remotePerm) < sizeof(file_stat->remotePerm)-1) {
+                        std::strcat(file_stat->remotePerm, "S");
+                    } else {
+                        qWarning() << "permissions too large" << file_stat->remotePerm;
+                    }
+                }
+            }
         }
     }
-
     return file_stat;
 }
 
index 9f38fc680f7fcd20ac6c16792aefa6fedcdf1240..471bfee5d226cde7dca8c22a9780f46729554531 100644 (file)
@@ -244,6 +244,7 @@ public:
     QDateTime lastModified = QDateTime::currentDateTime().addDays(-7);
     QString etag = generateEtag();
     QByteArray fileId = generateFileId();
+    QByteArray extraDavProperties;
     qint64 size = 0;
     char contentChar = 'W';
 
@@ -314,6 +315,7 @@ public:
             xml.writeTextElement(davUri, QStringLiteral("getetag"), fileInfo.etag);
             xml.writeTextElement(ocUri, QStringLiteral("permissions"), fileInfo.isShared ? QStringLiteral("SRDNVCKW") : QStringLiteral("RDNVCKW"));
             xml.writeTextElement(ocUri, QStringLiteral("id"), fileInfo.fileId);
+            buffer.write(fileInfo.extraDavProperties);
             xml.writeEndElement(); // prop
             xml.writeTextElement(davUri, QStringLiteral("status"), "HTTP/1.1 200 OK");
             xml.writeEndElement(); // propstat
@@ -648,7 +650,7 @@ public:
     OCC::SyncEngine &syncEngine() const { return *_syncEngine; }
 
     FileModifier &localModifier() { return _localModifier; }
-    FileModifier &remoteModifier() { return _fakeQnam->currentRemoteState(); }
+    FileInfo &remoteModifier() { return _fakeQnam->currentRemoteState(); }
     FileInfo currentLocalState() {
         QDir rootDir{_tempDir.path()};
         FileInfo rootTemplate;
index cb66ad3a8a25ad5761e67c32b58909268a32ced0..32cba399d6f69b3f51ae0e7bf21cc9d607afa9b8 100644 (file)
@@ -376,6 +376,10 @@ private slots:
         FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};
         fakeFolder.remoteModifier().insert("S/s0");
         fakeFolder.remoteModifier().appendByte("S/s1");
+        fakeFolder.remoteModifier().insert("B/b3");
+        fakeFolder.remoteModifier().find("B/b3")->extraDavProperties
+            = "<oc:share-types><oc:share-type>0</oc:share-type></oc:share-types>";
+
         StatusPushSpy statusSpy(fakeFolder.syncEngine());
 
         fakeFolder.scheduleSync();
@@ -395,6 +399,8 @@ private slots:
         QEXPECT_FAIL("", "We currently only know if a new file is shared on the second sync, after a PROPFIND.", Continue);
         QCOMPARE(statusSpy.statusOf("S/s0"), sharedUpToDateStatus);
         QCOMPARE(statusSpy.statusOf("S/s1"), sharedUpToDateStatus);
+        QCOMPARE(statusSpy.statusOf("B/b1").sharedWithMe(), false);
+        QCOMPARE(statusSpy.statusOf("B/b3"), sharedUpToDateStatus);
 
         QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
     }