mirror of
https://github.com/nextcloud/android.git
synced 2024-11-26 15:15:51 +03:00
Merge pull request #12796 from nextcloud/bugfix/e2e-upload-by-alper
Fix Upload Problems For Encrypted Folder
This commit is contained in:
commit
4592c17df0
4 changed files with 59 additions and 44 deletions
|
@ -235,7 +235,7 @@ class FileUploadWorker(
|
|||
}
|
||||
|
||||
private fun cleanupUploadProcess(result: RemoteOperationResult<Any?>, operation: UploadFileOperation) {
|
||||
if (!(isStopped && result.isCancelled)) {
|
||||
if (!isStopped || !result.isCancelled) {
|
||||
uploadsStorageManager.updateDatabaseUploadResult(result, operation)
|
||||
notifyUploadResult(operation, result)
|
||||
notificationManager.dismissWorkerNotifications()
|
||||
|
@ -288,17 +288,18 @@ class FileUploadWorker(
|
|||
context.resources
|
||||
)
|
||||
|
||||
// FIXME SYNC_CONFLICT passes wrong OCFile, check ConflictsResolveActivity.createIntent usage
|
||||
val conflictResolveIntent = if (uploadResult.code == ResultCode.SYNC_CONFLICT) {
|
||||
intents.conflictResolveActionIntents(context, uploadFileOperation)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
val credentialIntent: PendingIntent? = if (uploadResult.code == ResultCode.UNAUTHORIZED) {
|
||||
intents.credentialIntent(uploadFileOperation)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
notifyForFailedResult(uploadResult.code, conflictResolveIntent, credentialIntent, errorMessage)
|
||||
showNewNotification(uploadFileOperation)
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ package com.owncloud.android.operations;
|
|||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
|
||||
|
@ -98,6 +99,9 @@ import javax.crypto.Cipher;
|
|||
|
||||
import androidx.annotation.CheckResult;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import static com.owncloud.android.ui.activity.FileDisplayActivity.REFRESH_FOLDER_EVENT_RECEIVER;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -455,6 +459,7 @@ public class UploadFileOperation extends SyncOperation {
|
|||
|
||||
boolean metadataExists = false;
|
||||
String token = null;
|
||||
Object object = null;
|
||||
|
||||
ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(getContext());
|
||||
String publicKey = arbitraryDataProvider.getValue(user.getAccountName(), EncryptionUtils.PUBLIC_KEY);
|
||||
|
@ -466,6 +471,7 @@ public class UploadFileOperation extends SyncOperation {
|
|||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/***** E2E *****/
|
||||
// Only on V2+: whenever we change something, increase counter
|
||||
long counter = -1;
|
||||
|
@ -485,13 +491,7 @@ public class UploadFileOperation extends SyncOperation {
|
|||
|
||||
// Update metadata
|
||||
EncryptionUtilsV2 encryptionUtilsV2 = new EncryptionUtilsV2();
|
||||
// kotlin.Pair<Boolean, DecryptedFolderMetadataFile> metadataPair =
|
||||
// encryptionUtilsV2.retrieveMetadata(parentFile,
|
||||
// client,
|
||||
// user,
|
||||
// mContext);
|
||||
|
||||
Object object = EncryptionUtils.downloadFolderMetadata(parentFile, client, mContext, user);
|
||||
object = EncryptionUtils.downloadFolderMetadata(parentFile, client, mContext, user);
|
||||
if (object instanceof DecryptedFolderMetadataFileV1 decrypted && decrypted.getMetadata() != null) {
|
||||
metadataExists = true;
|
||||
}
|
||||
|
@ -703,13 +703,6 @@ public class UploadFileOperation extends SyncOperation {
|
|||
"",
|
||||
arbitraryDataProvider,
|
||||
user);
|
||||
|
||||
// unlock
|
||||
result = EncryptionUtils.unlockFolderV1(parentFile, client, token);
|
||||
|
||||
if (result.isSuccess()) {
|
||||
token = null;
|
||||
}
|
||||
} else {
|
||||
DecryptedFolderMetadataFile metadata = (DecryptedFolderMetadataFile) object;
|
||||
encryptionUtilsV2.addFileToMetadata(
|
||||
|
@ -730,13 +723,6 @@ public class UploadFileOperation extends SyncOperation {
|
|||
mContext,
|
||||
user,
|
||||
getStorageManager());
|
||||
|
||||
// unlock
|
||||
result = EncryptionUtils.unlockFolder(parentFile, client, token);
|
||||
|
||||
if (result.isSuccess()) {
|
||||
token = null;
|
||||
}
|
||||
}
|
||||
|
||||
encryptedTempFile.delete();
|
||||
|
@ -751,6 +737,7 @@ public class UploadFileOperation extends SyncOperation {
|
|||
result = new RemoteOperationResult(e);
|
||||
} finally {
|
||||
mUploadStarted.set(false);
|
||||
sendRefreshFolderEventBroadcast();
|
||||
|
||||
if (fileLock != null) {
|
||||
try {
|
||||
|
@ -768,6 +755,18 @@ public class UploadFileOperation extends SyncOperation {
|
|||
}
|
||||
|
||||
logResult(result, mFile.getStoragePath(), mFile.getRemotePath());
|
||||
|
||||
// Unlock must be done otherwise folder stays locked and user can't upload any file
|
||||
RemoteOperationResult<Void> unlockFolderResult;
|
||||
if (object instanceof DecryptedFolderMetadataFileV1) {
|
||||
unlockFolderResult = EncryptionUtils.unlockFolderV1(parentFile, client, token);
|
||||
} else {
|
||||
unlockFolderResult = EncryptionUtils.unlockFolder(parentFile, client, token);
|
||||
}
|
||||
|
||||
if (unlockFolderResult != null && !unlockFolderResult.isSuccess()) {
|
||||
result = unlockFolderResult;
|
||||
}
|
||||
}
|
||||
|
||||
if (result.isSuccess()) {
|
||||
|
@ -776,17 +775,6 @@ public class UploadFileOperation extends SyncOperation {
|
|||
getStorageManager().saveConflict(mFile, mFile.getEtagInConflict());
|
||||
}
|
||||
|
||||
// unlock must be done always
|
||||
if (token != null) {
|
||||
RemoteOperationResult unlockFolderResult = EncryptionUtils.unlockFolder(parentFile,
|
||||
client,
|
||||
token);
|
||||
|
||||
if (!unlockFolderResult.isSuccess()) {
|
||||
return unlockFolderResult;
|
||||
}
|
||||
}
|
||||
|
||||
// delete temporal file
|
||||
if (temporalFile != null && temporalFile.exists() && !temporalFile.delete()) {
|
||||
Log_OC.e(TAG, "Could not delete temporal file " + temporalFile.getAbsolutePath());
|
||||
|
@ -795,6 +783,11 @@ public class UploadFileOperation extends SyncOperation {
|
|||
return result;
|
||||
}
|
||||
|
||||
private void sendRefreshFolderEventBroadcast() {
|
||||
Intent intent = new Intent(REFRESH_FOLDER_EVENT_RECEIVER);
|
||||
LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
|
||||
}
|
||||
|
||||
private RemoteOperationResult checkConditions(File originalFile) {
|
||||
RemoteOperationResult remoteOperationResult = null;
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ import com.nextcloud.client.jobs.download.FileDownloadHelper;
|
|||
import com.nextcloud.client.jobs.download.FileDownloadWorker;
|
||||
import com.nextcloud.client.jobs.upload.FileUploadHelper;
|
||||
import com.nextcloud.client.jobs.upload.FileUploadWorker;
|
||||
import com.nextcloud.client.jobs.upload.UploadNotificationManager;
|
||||
import com.nextcloud.client.media.PlayerServiceConnection;
|
||||
import com.nextcloud.client.network.ClientFactory;
|
||||
import com.nextcloud.client.network.ConnectivityService;
|
||||
|
@ -229,6 +230,8 @@ public class FileDisplayActivity extends FileActivity
|
|||
public static final String KEY_IS_SEARCH_OPEN = "IS_SEARCH_OPEN";
|
||||
public static final String KEY_SEARCH_QUERY = "SEARCH_QUERY";
|
||||
|
||||
public static final String REFRESH_FOLDER_EVENT_RECEIVER = "REFRESH_FOLDER_EVENT";
|
||||
|
||||
private String searchQuery = "";
|
||||
private boolean searchOpen;
|
||||
|
||||
|
@ -236,6 +239,7 @@ public class FileDisplayActivity extends FileActivity
|
|||
private PlayerServiceConnection mPlayerConnection;
|
||||
private Optional<User> lastDisplayedUser = Optional.empty();
|
||||
private int menuItemId = -1;
|
||||
|
||||
@Inject AppPreferences preferences;
|
||||
|
||||
@Inject AppInfo appInfo;
|
||||
|
@ -283,6 +287,7 @@ public class FileDisplayActivity extends FileActivity
|
|||
|
||||
initSyncBroadcastReceiver();
|
||||
observeWorkerState();
|
||||
registerRefreshFolderEventReceiver();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -2296,6 +2301,24 @@ public class FileDisplayActivity extends FileActivity
|
|||
checkForNewDevVersionNecessary(getApplicationContext());
|
||||
}
|
||||
|
||||
private void registerRefreshFolderEventReceiver() {
|
||||
IntentFilter filter = new IntentFilter(REFRESH_FOLDER_EVENT_RECEIVER);
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(refreshFolderEventReceiver, filter);
|
||||
}
|
||||
|
||||
private final BroadcastReceiver refreshFolderEventReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
syncAndUpdateFolder(true);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
LocalBroadcastManager.getInstance(this).unregisterReceiver(refreshFolderEventReceiver);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestart() {
|
||||
super.onRestart();
|
||||
|
|
|
@ -22,13 +22,11 @@
|
|||
package com.owncloud.android.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Base64;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.primitives.Bytes;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
@ -73,17 +71,14 @@ import org.apache.commons.httpclient.HttpStatus;
|
|||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
|
@ -114,7 +109,6 @@ import java.util.UUID;
|
|||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.CipherInputStream;
|
||||
import javax.crypto.CipherOutputStream;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.KeyGenerator;
|
||||
|
@ -127,7 +121,6 @@ import javax.crypto.spec.PBEKeySpec;
|
|||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
|
@ -516,8 +509,12 @@ public final class EncryptionUtils {
|
|||
new TypeToken<>() {
|
||||
});
|
||||
|
||||
if ("2.0".equals(v2.getVersion()) || "2".equals(v2.getVersion())) {
|
||||
return E2EVersion.V2_0;
|
||||
if (v2 != null) {
|
||||
if ("2.0".equals(v2.getVersion()) || "2".equals(v2.getVersion())) {
|
||||
return E2EVersion.V2_0;
|
||||
}
|
||||
} else {
|
||||
return E2EVersion.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -565,7 +562,8 @@ public final class EncryptionUtils {
|
|||
}
|
||||
|
||||
public static EncryptedFile encryptFile(File file, Cipher cipher) throws InvalidParameterSpecException {
|
||||
File encryptedFile = new File(file.getAbsolutePath() + ".enc");
|
||||
// FIXME this won't work on low or write-protected storage
|
||||
File encryptedFile = new File(file.getAbsolutePath() + ".enc.jpg");
|
||||
encryptFileWithGivenCipher(file, encryptedFile, cipher);
|
||||
String authenticationTagString = getAuthenticationTag(cipher);
|
||||
return new EncryptedFile(encryptedFile, authenticationTagString);
|
||||
|
|
Loading…
Reference in a new issue