Make the user select the app to import a db from (drop autodetect for now)

This commit is contained in:
Alexander Bakker 2018-05-13 21:58:41 +02:00
parent 7422b0cf53
commit 2400977629
5 changed files with 59 additions and 59 deletions

View file

@ -61,9 +61,4 @@ public class AegisImporter extends DatabaseImporter {
public DatabaseFile getFile() {
return _file;
}
@Override
public String getName() {
return "Aegis";
}
}

View file

@ -75,9 +75,4 @@ public class AndOTPImporter extends DatabaseImporter {
public boolean isEncrypted() {
return false;
}
@Override
public String getName() {
return "andOTP";
}
}

View file

@ -2,21 +2,24 @@ package me.impy.aegis.importers;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import me.impy.aegis.db.DatabaseEntry;
import me.impy.aegis.util.ByteInputStream;
public abstract class DatabaseImporter {
private static List<Class<? extends DatabaseImporter>> _converters = Collections.unmodifiableList(
new ArrayList<>(Arrays.asList(
AegisImporter.class,
FreeOTPImporter.class,
AndOTPImporter.class
))
);
private static Map<String, Class<? extends DatabaseImporter>> _importers;
static {
// note: keep this list sorted alphabetically
LinkedHashMap<String, Class<? extends DatabaseImporter>> importers = new LinkedHashMap<>();
importers.put("Aegis", AegisImporter.class);
importers.put("andOTP", AndOTPImporter.class);
importers.put("FreeOTP", FreeOTPImporter.class);
_importers = Collections.unmodifiableMap(importers);
}
protected ByteInputStream _stream;
@ -30,8 +33,6 @@ public abstract class DatabaseImporter {
public abstract boolean isEncrypted();
public abstract String getName();
public static DatabaseImporter create(ByteInputStream stream, Class<? extends DatabaseImporter> type) {
try {
return type.getConstructor(ByteInputStream.class).newInstance(stream);
@ -43,9 +44,13 @@ public abstract class DatabaseImporter {
public static List<DatabaseImporter> create(ByteInputStream stream) {
List<DatabaseImporter> list = new ArrayList<>();
for (Class<? extends DatabaseImporter> type : _converters) {
for (Class<? extends DatabaseImporter> type : _importers.values()) {
list.add(create(stream, type));
}
return list;
}
public static Map<String, Class<? extends DatabaseImporter>> getImporters() {
return _importers;
}
}

View file

@ -50,11 +50,6 @@ public class FreeOTPImporter extends DatabaseImporter {
return false;
}
@Override
public String getName() {
return "FreeOTP";
}
private static List<DatabaseEntry> parse(XmlPullParser parser)
throws IOException, XmlPullParserException, JSONException, KeyInfoException {
List<Entry> entries = new ArrayList<>();

View file

@ -20,6 +20,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import me.impy.aegis.AegisApplication;
import me.impy.aegis.R;
@ -49,7 +50,8 @@ public class PreferencesFragment extends PreferenceFragment {
// this is used to keep a reference to a database converter
// while the user provides credentials to decrypt it
private DatabaseImporter _converter;
private DatabaseImporter _importer;
private Class<? extends DatabaseImporter> _importerType;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -185,30 +187,46 @@ public class PreferencesFragment extends PreferenceFragment {
}
private void onImport() {
if (PermissionHelper.request(getActivity(), CODE_PERM_IMPORT, Manifest.permission.READ_EXTERNAL_STORAGE)) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
startActivityForResult(intent, CODE_IMPORT);
}
Map<String, Class<? extends DatabaseImporter>> importers = DatabaseImporter.getImporters();
String[] names = importers.keySet().toArray(new String[importers.size()]);
new AlertDialog.Builder(getActivity())
.setTitle("Select the application you'd like to import a database from")
.setSingleChoiceItems(names, 0, null)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
int i = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
_importerType = importers.get(names[i]);
if (PermissionHelper.request(getActivity(), CODE_PERM_IMPORT, Manifest.permission.READ_EXTERNAL_STORAGE)) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
startActivityForResult(intent, CODE_IMPORT);
}
}
})
.show();
}
private void onImportDecryptResult(int resultCode, Intent data) {
if (resultCode != Activity.RESULT_OK) {
_converter = null;
_importer = null;
return;
}
MasterKey key = (MasterKey) data.getSerializableExtra("key");
((AegisImporter)_converter).setKey(key);
((AegisImporter)_importer).setKey(key);
try {
importDatabase(_converter);
importDatabase(_importer);
} catch (DatabaseImporterException e) {
e.printStackTrace();
Toast.makeText(getActivity(), "An error occurred while trying to parse the file", Toast.LENGTH_SHORT).show();
}
_converter = null;
_importer = null;
}
private void onImportResult(int resultCode, Intent data) {
@ -239,37 +257,29 @@ public class PreferencesFragment extends PreferenceFragment {
}
}
boolean imported = false;
for (DatabaseImporter converter : DatabaseImporter.create(stream)) {
try {
converter.parse();
try {
DatabaseImporter importer = DatabaseImporter.create(stream, _importerType);
importer.parse();
// special case to decrypt encrypted aegis databases
if (converter.isEncrypted() && converter instanceof AegisImporter) {
_converter = converter;
// special case to decrypt encrypted aegis databases
if (importer.isEncrypted() && importer instanceof AegisImporter) {
_importer = importer;
Intent intent = new Intent(getActivity(), AuthActivity.class);
intent.putExtra("slots", ((AegisImporter)_converter).getFile().getSlots());
startActivityForResult(intent, CODE_IMPORT_DECRYPT);
return;
}
importDatabase(converter);
imported = true;
break;
} catch (DatabaseImporterException e) {
e.printStackTrace();
stream.reset();
Intent intent = new Intent(getActivity(), AuthActivity.class);
intent.putExtra("slots", ((AegisImporter)_importer).getFile().getSlots());
startActivityForResult(intent, CODE_IMPORT_DECRYPT);
return;
}
}
if (!imported) {
importDatabase(importer);
} catch (DatabaseImporterException e) {
e.printStackTrace();
Toast.makeText(getActivity(), "An error occurred while trying to parse the file", Toast.LENGTH_SHORT).show();
}
}
private void importDatabase(DatabaseImporter converter) throws DatabaseImporterException {
List<DatabaseEntry> entries = converter.convert();
private void importDatabase(DatabaseImporter importer) throws DatabaseImporterException {
List<DatabaseEntry> entries = importer.convert();
for (DatabaseEntry entry : entries) {
_db.addKey(entry);
}