aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/pixart/messenger/services/ImportBackupService.java
diff options
context:
space:
mode:
authorChristian Schneppe <christian@pix-art.de>2019-08-31 14:45:36 +0200
committerChristian Schneppe <christian@pix-art.de>2019-08-31 14:45:36 +0200
commit47c29e584229f1fe98d5456d66a32bb9f081afa5 (patch)
treefaafd4a0bfac960d66697512d96e8622b7fdcecb /src/main/java/de/pixart/messenger/services/ImportBackupService.java
parentf7c293387b84f9fc416529ed6c08217a35b0474e (diff)
allow backup to be restored from selected file
Diffstat (limited to 'src/main/java/de/pixart/messenger/services/ImportBackupService.java')
-rw-r--r--src/main/java/de/pixart/messenger/services/ImportBackupService.java82
1 files changed, 63 insertions, 19 deletions
diff --git a/src/main/java/de/pixart/messenger/services/ImportBackupService.java b/src/main/java/de/pixart/messenger/services/ImportBackupService.java
index 9a1ddece2..8bb912b8b 100644
--- a/src/main/java/de/pixart/messenger/services/ImportBackupService.java
+++ b/src/main/java/de/pixart/messenger/services/ImportBackupService.java
@@ -7,6 +7,7 @@ import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
@@ -16,7 +17,9 @@ import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
@@ -27,6 +30,7 @@ import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.zip.GZIPInputStream;
+import java.util.zip.ZipException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
@@ -80,14 +84,22 @@ public class ImportBackupService extends Service {
return START_NOT_STICKY;
}
final String password = intent.getStringExtra("password");
- final String file = intent.getStringExtra("file");
- if (password == null || file == null) {
+ final Uri data = intent.getData();
+ final Uri uri;
+ if (data == null) {
+ final String file = intent.getStringExtra("file");
+ uri = file == null ? null : Uri.fromFile(new File(file));
+ } else {
+ uri = data;
+ }
+
+ if (password == null || uri == null) {
return START_NOT_STICKY;
}
if (running.compareAndSet(false, true)) {
executor.execute(() -> {
startForegroundService();
- final boolean success = importBackup(new File(file), password);
+ final boolean success = importBackup(uri, password);
stopForeground(true);
running.set(false);
if (success) {
@@ -144,21 +156,41 @@ public class ImportBackupService extends Service {
startForeground(NOTIFICATION_ID, mBuilder.build());
}
- private boolean importBackup(File file, String password) {
- Log.d(Config.LOGTAG, "importing backup from file " + file.getAbsolutePath());
+ private boolean importBackup(Uri uri, String password) {
+ Log.d(Config.LOGTAG, "importing backup from " + uri);
+ if (password == null || password.isEmpty()) {
+ synchronized (mOnBackupProcessedListeners) {
+ for (OnBackupProcessed l : mOnBackupProcessedListeners) {
+ l.onBackupDecryptionFailed();
+ }
+ }
+ return false;
+ }
try {
SQLiteDatabase db = mDatabaseBackend.getWritableDatabase();
- final FileInputStream fileInputStream = new FileInputStream(file);
- final DataInputStream dataInputStream = new DataInputStream(fileInputStream);
- BackupFileHeader backupFileHeader = BackupFileHeader.read(dataInputStream);
+ final InputStream inputStream;
+ if ("file".equals(uri.getScheme())) {
+ inputStream = new FileInputStream(new File(uri.getPath()));
+ } else {
+ inputStream = getContentResolver().openInputStream(uri);
+ }
+ final DataInputStream dataInputStream = new DataInputStream(inputStream);
+ final BackupFileHeader backupFileHeader = BackupFileHeader.read(dataInputStream);
Log.d(Config.LOGTAG, backupFileHeader.toString());
-
+ if (mDatabaseBackend.getAccountJids(false).contains(backupFileHeader.getJid())) {
+ synchronized (mOnBackupProcessedListeners) {
+ for (OnBackupProcessed l : mOnBackupProcessedListeners) {
+ l.onAccountAlreadySetup();
+ }
+ }
+ return false;
+ }
final Cipher cipher = Compatibility.twentyEight() ? Cipher.getInstance(CIPHERMODE) : Cipher.getInstance(CIPHERMODE, PROVIDER);
byte[] key = ExportBackupService.getKey(password, backupFileHeader.getSalt());
SecretKeySpec keySpec = new SecretKeySpec(key, KEYTYPE);
IvParameterSpec ivSpec = new IvParameterSpec(backupFileHeader.getIv());
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
- CipherInputStream cipherInputStream = new CipherInputStream(fileInputStream, cipher);
+ CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);
GZIPInputStream gzipInputStream = new GZIPInputStream(cipherInputStream);
BufferedReader reader = new BufferedReader(new InputStreamReader(gzipInputStream, "UTF-8"));
@@ -196,8 +228,7 @@ public class ImportBackupService extends Service {
return true;
} catch (Exception e) {
Throwable throwable = e.getCause();
- final boolean reasonWasCrypto;
- reasonWasCrypto = throwable instanceof BadPaddingException;
+ final boolean reasonWasCrypto = throwable instanceof BadPaddingException || e instanceof ZipException;
synchronized (mOnBackupProcessedListeners) {
for (OnBackupProcessed l : mOnBackupProcessedListeners) {
if (reasonWasCrypto) {
@@ -207,7 +238,7 @@ public class ImportBackupService extends Service {
}
}
}
- Log.d(Config.LOGTAG, "error restoring backup " + file.getAbsolutePath(), e);
+ Log.d(Config.LOGTAG, "error restoring backup " + uri, e);
return false;
}
}
@@ -254,14 +285,16 @@ public class ImportBackupService extends Service {
void onBackupDecryptionFailed();
void onBackupRestoreFailed();
+
+ void onAccountAlreadySetup();
}
public static class BackupFile {
- private final File file;
+ private final Uri uri;
private final BackupFileHeader header;
- private BackupFile(File file, BackupFileHeader header) {
- this.file = file;
+ private BackupFile(Uri uri, BackupFileHeader header) {
+ this.uri = uri;
this.header = header;
}
@@ -270,15 +303,26 @@ public class ImportBackupService extends Service {
final DataInputStream dataInputStream = new DataInputStream(fileInputStream);
BackupFileHeader backupFileHeader = BackupFileHeader.read(dataInputStream);
fileInputStream.close();
- return new BackupFile(file, backupFileHeader);
+ return new BackupFile(Uri.fromFile(file), backupFileHeader);
+ }
+
+ public static BackupFile read(final Context context, final Uri uri) throws IOException {
+ final InputStream inputStream = context.getContentResolver().openInputStream(uri);
+ if (inputStream == null) {
+ throw new FileNotFoundException();
+ }
+ final DataInputStream dataInputStream = new DataInputStream(inputStream);
+ BackupFileHeader backupFileHeader = BackupFileHeader.read(dataInputStream);
+ inputStream.close();
+ return new BackupFile(uri, backupFileHeader);
}
public BackupFileHeader getHeader() {
return header;
}
- public File getFile() {
- return file;
+ public Uri getUri() {
+ return uri;
}
}