Bladeren bron

fix failing operations (create folder, download file) due to user agent change
fix upload of fresh ones into folders where parent does not exist yet

Signed-off-by: tobiasKaminsky <tobias@kaminsky.me>

tobiasKaminsky 7 jaren geleden
bovenliggende
commit
3ce4280931

+ 1 - 1
build.gradle

@@ -195,7 +195,7 @@ dependencies {
     // dependencies for app building
     implementation 'com.android.support:multidex:1.0.2'
 //    implementation project('nextcloud-android-library')
-    implementation 'com.github.nextcloud:android-library:1.0.38'
+    implementation 'com.github.nextcloud:android-library:1.0.39'
     versionDevImplementation 'com.github.nextcloud:android-library:master-SNAPSHOT' // use always latest master
     implementation "com.android.support:support-v4:${supportLibraryVersion}"
     implementation "com.android.support:design:${supportLibraryVersion}"

+ 3 - 2
src/main/java/com/owncloud/android/operations/CreateFolderOperation.java

@@ -62,11 +62,11 @@ public class CreateFolderOperation extends SyncOperation implements OnRemoteOper
     @Override
     protected RemoteOperationResult run(OwnCloudClient client) {
         CreateRemoteFolderOperation operation = new CreateRemoteFolderOperation(mRemotePath, mCreateFullPath);
-        RemoteOperationResult result =  operation.execute(client);
+        RemoteOperationResult result = operation.execute(client, true);
         
         if (result.isSuccess()) {
             ReadRemoteFolderOperation remoteFolderOperation = new ReadRemoteFolderOperation(mRemotePath);
-            RemoteOperationResult remoteFolderOperationResult = remoteFolderOperation.execute(client);
+            RemoteOperationResult remoteFolderOperationResult = remoteFolderOperation.execute(client, true);
 
             createdRemoteFolder = (RemoteFile) remoteFolderOperationResult.getData().get(0);
             saveFolderInDB();
@@ -118,6 +118,7 @@ public class CreateFolderOperation extends SyncOperation implements OnRemoteOper
             newDir.setParentId(parentId);
             newDir.setRemoteId(createdRemoteFolder.getRemoteId());
             newDir.setModificationTimestamp(System.currentTimeMillis());
+            newDir.setEncrypted(FileStorageUtils.checkEncryptionStatus(newDir, getStorageManager()));
             getStorageManager().saveFile(newDir);
 
             Log_OC.d(TAG, "Create directory " + mRemotePath + " in Database");

+ 1 - 1
src/main/java/com/owncloud/android/operations/DownloadFileOperation.java

@@ -175,7 +175,7 @@ public class DownloadFileOperation extends RemoteOperation {
         while (listener.hasNext()) {
             mDownloadOperation.addDatatransferProgressListener(listener.next());
         }
-        result = mDownloadOperation.execute(client);
+        result = mDownloadOperation.execute(client, client.useNextcloudUserAgent());
         
         if (result.isSuccess()) {
             mModificationTimestamp = mDownloadOperation.getModificationTimestamp();

+ 27 - 59
src/main/java/com/owncloud/android/operations/UploadFileOperation.java

@@ -366,26 +366,37 @@ public class UploadFileOperation extends SyncOperation {
             }
         }
 
-        // check the existence of the parent folder for the file to upload
         String remoteParentPath = new File(getRemotePath()).getParent();
         remoteParentPath = remoteParentPath.endsWith(OCFile.PATH_SEPARATOR) ?
                 remoteParentPath : remoteParentPath + OCFile.PATH_SEPARATOR;
 
-        RemoteOperationResult result = grantFolderExistence(remoteParentPath, client);
+        OCFile parent = getStorageManager().getFileByPath(remoteParentPath);
+
+        // in case of a fresh upload with subfolder, where parent does not exist yet
+        if (parent == null && mFolderUnlockToken.isEmpty()) {
+            // try to create folder
+            RemoteOperationResult result = grantFolderExistence(remoteParentPath, client);
+
+            if (!result.isSuccess()) {
+                return result;
+            }
 
-        if (!result.isSuccess()) {
-            return result;
+            parent = getStorageManager().getFileByPath(remoteParentPath);
+
+            if (parent == null) {
+                return new RemoteOperationResult(false, "Parent folder not found", HttpStatus.SC_NOT_FOUND);
+            }
         }
 
-        OCFile parent = getStorageManager().getFileByPath(remoteParentPath);
+        // parent file is not null anymore:
+        // - it was created on fresh upload or
+        // - resume of encrypted upload, then parent file exists already as unlock is only for direct parent
+        
         mFile.setParentId(parent.getFileId());
 
-        // check if any parent is encrypted
-        encryptedAncestor = FileStorageUtils.checkEncryptionStatus(parent, getStorageManager());
-        mFile.setEncrypted(encryptedAncestor);
-
         // try to unlock folder with stored token, e.g. when upload needs to be resumed or app crashed
-        if (encryptedAncestor && !mFolderUnlockToken.isEmpty()) {
+        // the parent folder should exist as it is a resume of a broken upload
+        if (!mFolderUnlockToken.isEmpty()) {
             UnlockFileOperation unlockFileOperation = new UnlockFileOperation(parent.getLocalId(), mFolderUnlockToken);
             RemoteOperationResult unlockFileOperationResult = unlockFileOperation.execute(client, true);
 
@@ -394,6 +405,10 @@ public class UploadFileOperation extends SyncOperation {
             }
         }
 
+        // check if any parent is encrypted
+        encryptedAncestor = FileStorageUtils.checkEncryptionStatus(parent, getStorageManager());
+        mFile.setEncrypted(encryptedAncestor);
+
         if (encryptedAncestor) {
             Log_OC.d(TAG, "encrypted upload");
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
@@ -583,60 +598,13 @@ public class UploadFileOperation extends SyncOperation {
                 throw new OperationCancelledException();
             }
 
-//            FileChannel channel = null;
-//            try {
-//                channel = new RandomAccessFile(ocFile.getStoragePath(), "rw").getChannel();
-//                fileLock = channel.tryLock();
-//            } catch (FileNotFoundException e) {
-//                if (temporalFile == null) {
-//                    String temporalPath = FileStorageUtils.getTemporalPath(account.name) + ocFile.getRemotePath();
-//                    ocFile.setStoragePath(temporalPath);
-//                    temporalFile = new File(temporalPath);
-//
-//                    result = copy(originalFile, temporalFile);
-//
-//                    if (result != null) {
-//                        return result;
-//                    } else {
-//                        if (temporalFile.length() == originalFile.length()) {
-//                            channel = new RandomAccessFile(temporalFile.getAbsolutePath(), "rw").getChannel();
-//                            fileLock = channel.tryLock();
-//                        } else {
-//                            while (temporalFile.length() != originalFile.length()) {
-//                                Files.deleteIfExists(Paths.get(temporalPath));
-//                                result = copy(originalFile, temporalFile);
-//
-//                                if (result != null) {
-//                                    return result;
-//                                } else {
-//                                    channel = new RandomAccessFile(temporalFile.getAbsolutePath(), "rw").
-//                                            getChannel();
-//                                    fileLock = channel.tryLock();
-//                                }
-//                            }
-//                        }
-//                    }
-//                } else {
-//                    channel = new RandomAccessFile(temporalFile.getAbsolutePath(), "rw").getChannel();
-//                    fileLock = channel.tryLock();
-//                }
-//            }
-
-//            boolean test = true;
-//            if (test) {
-//                throw new Exception("test");
-//            }
-
-            result = mUploadOperation.execute(client);
-//            if (result == null || result.isSuccess() && mUploadOperation != null) {
-//                result = mUploadOperation.execute(client);
+            result = mUploadOperation.execute(client, true);
 
             /// move local temporal file or original file to its corresponding
             // location in the Nextcloud local folder
             if (!result.isSuccess() && result.getHttpCode() == HttpStatus.SC_PRECONDITION_FAILED) {
                 result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);
             }
-//            }
 
             if (result.isSuccess()) {
                 // upload metadata
@@ -1038,7 +1006,7 @@ public class UploadFileOperation extends SyncOperation {
      */
     private RemoteOperationResult grantFolderExistence(String pathToGrant, OwnCloudClient client) {
         RemoteOperation operation = new ExistenceCheckRemoteOperation(pathToGrant, mContext, false);
-        RemoteOperationResult result = operation.execute(client, mFile.isEncrypted());
+        RemoteOperationResult result = operation.execute(client, true);
         if (!result.isSuccess() && result.getCode() == ResultCode.FILE_NOT_FOUND && mRemoteFolderToBeCreated) {
             SyncOperation syncOp = new CreateFolderOperation(pathToGrant, true);
             result = syncOp.execute(client, getStorageManager());

+ 4 - 3
src/main/java/com/owncloud/android/utils/EncryptionUtils.java

@@ -475,10 +475,11 @@ public class EncryptionUtils {
 
         Cipher cipher = Cipher.getInstance(AES_CIPHER);
 
-        String[] strings = string.split(ivDelimiter);
-        String cipherString = strings[0];
+        int delimiterPosition = string.lastIndexOf(ivDelimiter);
+        String cipherString = string.substring(0, delimiterPosition);
+        String ivString = string.substring(delimiterPosition + ivDelimiter.length(), string.length());
 
-        byte[] iv = new IvParameterSpec(decodeStringToBase64Bytes(strings[1])).getIV();
+        byte[] iv = new IvParameterSpec(decodeStringToBase64Bytes(ivString)).getIV();
 
         Key key = new SecretKeySpec(encryptionKeyBytes, AES);