mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-04-27 09:16:08 +00:00
Show dialog when trying to import from a recent Google Auth version
This commit is contained in:
parent
ac123918c2
commit
49b334ff70
5 changed files with 54 additions and 22 deletions
|
@ -13,6 +13,7 @@ import com.topjohnwu.superuser.io.SuFileInputStream;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -59,6 +60,10 @@ public abstract class DatabaseImporter {
|
|||
return new SuFile(man.getApplicationInfo(pkgName, 0).dataDir, subPath);
|
||||
}
|
||||
|
||||
public boolean isInstalledAppVersionSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected abstract State read(InputStream stream, boolean isInternal) throws DatabaseImporterException;
|
||||
|
||||
public State read(InputStream stream) throws DatabaseImporterException {
|
||||
|
@ -91,7 +96,7 @@ public abstract class DatabaseImporter {
|
|||
return Collections.unmodifiableList(_importers);
|
||||
}
|
||||
|
||||
public static class Definition {
|
||||
public static class Definition implements Serializable {
|
||||
private final String _name;
|
||||
private final Class<? extends DatabaseImporter> _type;
|
||||
private final @StringRes int _help;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.beemdevelopment.aegis.importers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
|
||||
|
@ -32,7 +33,19 @@ public class GoogleAuthImporter extends DatabaseImporter {
|
|||
protected SuFile getAppPath() throws PackageManager.NameNotFoundException {
|
||||
return getAppPath(_pkgName, _subPath);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isInstalledAppVersionSupported() {
|
||||
PackageInfo info;
|
||||
try {
|
||||
info = requireContext().getPackageManager().getPackageInfo(_pkgName, 0);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return info.versionCode <= 5000100;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State read(InputStream stream, boolean isInternal) throws DatabaseImporterException {
|
||||
final Context context = requireContext();
|
||||
|
|
|
@ -83,21 +83,35 @@ public class ImportEntriesActivity extends AegisActivity {
|
|||
});
|
||||
_fabScrollHelper = new FabScrollHelper(fab);
|
||||
|
||||
Class<? extends DatabaseImporter> importerType = (Class<? extends DatabaseImporter>) getIntent().getSerializableExtra("importerType");
|
||||
startImport(importerType, (File) getIntent().getSerializableExtra("file"));
|
||||
DatabaseImporter.Definition importerDef = (DatabaseImporter.Definition) getIntent().getSerializableExtra("importerDef");
|
||||
startImport(importerDef, (File) getIntent().getSerializableExtra("file"));
|
||||
}
|
||||
|
||||
private void startImport(@NonNull Class<? extends DatabaseImporter> importerType, @Nullable File file) {
|
||||
private void startImport(DatabaseImporter.Definition importerDef, @Nullable File file) {
|
||||
DatabaseImporter importer = DatabaseImporter.create(this, importerDef.getType());
|
||||
if (file == null) {
|
||||
startImportApp(importerType);
|
||||
if (importer.isInstalledAppVersionSupported()) {
|
||||
startImportApp(importer);
|
||||
} else {
|
||||
Dialogs.showSecureDialog(new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.warning)
|
||||
.setMessage(getString(R.string.app_version_error, importerDef.getName()))
|
||||
.setCancelable(false)
|
||||
.setPositiveButton(R.string.yes, (dialog1, which) -> {
|
||||
startImportApp(importer);
|
||||
})
|
||||
.setNegativeButton(R.string.no, (dialog1, which) -> {
|
||||
finish();
|
||||
})
|
||||
.create());
|
||||
}
|
||||
} else {
|
||||
startImportFile(importerType, file);
|
||||
startImportFile(importer, file);
|
||||
}
|
||||
}
|
||||
|
||||
private void startImportFile(@NonNull Class<? extends DatabaseImporter> importerType, @NonNull File file) {
|
||||
private void startImportFile(@NonNull DatabaseImporter importer, @NonNull File file) {
|
||||
try (InputStream stream = new FileInputStream(file)) {
|
||||
DatabaseImporter importer = DatabaseImporter.create(this, importerType);
|
||||
DatabaseImporter.State state = importer.read(stream);
|
||||
processImporterState(state);
|
||||
} catch (FileNotFoundException e) {
|
||||
|
@ -108,9 +122,7 @@ public class ImportEntriesActivity extends AegisActivity {
|
|||
}
|
||||
}
|
||||
|
||||
private void startImportApp(@NonNull Class<? extends DatabaseImporter> importerType) {
|
||||
DatabaseImporter importer = DatabaseImporter.create(this, importerType);
|
||||
|
||||
private void startImportApp(@NonNull DatabaseImporter importer) {
|
||||
// obtain the global root shell and close it immediately after we're done
|
||||
// TODO: find a way to use SuFileInputStream with Shell.newInstance()
|
||||
try (Shell shell = Shell.getShell()) {
|
||||
|
|
|
@ -42,7 +42,7 @@ import javax.crypto.Cipher;
|
|||
|
||||
public class ImportExportPreferencesFragment extends PreferencesFragment {
|
||||
// keep a reference to the type of database converter that was selected
|
||||
private Class<? extends DatabaseImporter> _importerType;
|
||||
private DatabaseImporter.Definition _importerDef;
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
|
@ -50,13 +50,13 @@ public class ImportExportPreferencesFragment extends PreferencesFragment {
|
|||
addPreferencesFromResource(R.xml.preferences_import_export);
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
_importerType = (Class<? extends DatabaseImporter>) savedInstanceState.getSerializable("importerType");
|
||||
_importerDef = (DatabaseImporter.Definition) savedInstanceState.getSerializable("importerDef");
|
||||
}
|
||||
|
||||
Preference importPreference = requirePreference("pref_import");
|
||||
importPreference.setOnPreferenceClickListener(preference -> {
|
||||
Dialogs.showImportersDialog(requireContext(), false, definition -> {
|
||||
_importerType = definition.getType();
|
||||
_importerDef = definition;
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intent.setType("*/*");
|
||||
|
@ -68,7 +68,7 @@ public class ImportExportPreferencesFragment extends PreferencesFragment {
|
|||
Preference importAppPreference = requirePreference("pref_import_app");
|
||||
importAppPreference.setOnPreferenceClickListener(preference -> {
|
||||
Dialogs.showImportersDialog(requireContext(), true, definition -> {
|
||||
startImportEntriesActivity(definition.getType(), null);
|
||||
startImportEntriesActivity(definition, null);
|
||||
});
|
||||
return true;
|
||||
});
|
||||
|
@ -83,7 +83,7 @@ public class ImportExportPreferencesFragment extends PreferencesFragment {
|
|||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putSerializable("importerType", _importerType);
|
||||
outState.putSerializable("importerDef", _importerDef);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -115,7 +115,7 @@ public class ImportExportPreferencesFragment extends PreferencesFragment {
|
|||
ImportFileTask.Params params = new ImportFileTask.Params(uri, "import", null);
|
||||
ImportFileTask task = new ImportFileTask(requireContext(), result -> {
|
||||
if (result.getException() == null) {
|
||||
startImportEntriesActivity(_importerType, result.getFile());
|
||||
startImportEntriesActivity(_importerDef, result.getFile());
|
||||
} else {
|
||||
Dialogs.showErrorDialog(requireContext(), R.string.reading_file_error, result.getException());
|
||||
}
|
||||
|
@ -123,9 +123,9 @@ public class ImportExportPreferencesFragment extends PreferencesFragment {
|
|||
task.execute(getLifecycle(), params);
|
||||
}
|
||||
|
||||
private void startImportEntriesActivity(Class<? extends DatabaseImporter> importerType, File file) {
|
||||
private void startImportEntriesActivity(DatabaseImporter.Definition importerDef, File file) {
|
||||
Intent intent = new Intent(requireActivity(), ImportEntriesActivity.class);
|
||||
intent.putExtra("importerType", importerType);
|
||||
intent.putExtra("importerDef", importerDef);
|
||||
intent.putExtra("file", file);
|
||||
startActivityForResult(intent, CODE_IMPORT);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
<string name="yandex_pin">PIN (4–16 digits)</string>
|
||||
<string name="suggested">Suggested</string>
|
||||
<string name="usage_count">Usage count</string>
|
||||
<string name="warning">Warning</string>
|
||||
|
||||
<string name="pref_cat_appearance_app">App</string>
|
||||
<string name="pref_cat_appearance_entries">Entries</string>
|
||||
|
@ -205,6 +206,7 @@
|
|||
<string name="file_not_found">Error: File not found</string>
|
||||
<string name="reading_file_error">An error occurred while trying to read the file</string>
|
||||
<string name="app_lookup_error">Error: App is not installed</string>
|
||||
<string name="app_version_error">The version of %s that\'s installed is not supported. Attempting to import may result in an error. Would you like to continue anyway?</string>
|
||||
<string name="root_error">Error: unable to obtain root access</string>
|
||||
<plurals name="imported_entries_count">
|
||||
<item quantity="one">Imported %d entry</item>
|
||||
|
@ -381,14 +383,14 @@
|
|||
<string name="importer_help_duo">Supply a copy of <b>/data/data/com.duosecurity.duomobile/files/duokit/accounts.json</b>, located in the internal storage directory of DUO.</string>
|
||||
<string name="importer_help_freeotp">Supply a copy of <b>/data/data/org.fedorahosted.freeotp/shared_prefs/tokens.xml</b>, located in the internal storage directory of FreeOTP.</string>
|
||||
<string name="importer_help_freeotp_plus">Supply a FreeOTP+ export file.</string>
|
||||
<string name="importer_help_google_authenticator">Supply a copy of <b>/data/data/com.google.android.apps.authenticator2/databases/databases</b>, located in the internal storage directory of Google Authenticator.</string>
|
||||
<string name="importer_help_google_authenticator"><b>Only database files from Google Authenticator v5.10 and prior are supported</b>.\n\nSupply a copy of <b>/data/data/com.google.android.apps.authenticator2/databases/databases</b>, located in the internal storage directory of Google Authenticator.</string>
|
||||
<string name="importer_help_microsoft_authenticator">Supply a copy of <b>/data/data/com.azure.authenticator/databases/PhoneFactor</b>, located in the internal storage directory of Microsoft Authenticator.</string>
|
||||
<string name="importer_help_plain_text">Supply a plain text file with a Google Authenticator URI on each line.</string>
|
||||
<string name="importer_help_steam">Supply a copy of <b>/data/data/com.valvesoftware.android.steam.community/files/Steamguard-*.json</b>, located in the internal storage directory of Steam.</string>
|
||||
<string name="importer_help_totp_authenticator">Supply a TOTP Authenticator export file.</string>
|
||||
<string name="importer_help_winauth">Supply a WinAuth export file.</string>
|
||||
|
||||
<string name="importer_encrypted_exception_google_authenticator">"Encrypted entry was skipped: %s"</string>
|
||||
<string name="importer_encrypted_exception_google_authenticator">Encrypted entry was skipped: %s</string>
|
||||
|
||||
<string name="importer_help_direct">Import entries directly from %s. This requires the app to be installed on this device and for root access to be granted to Aegis.</string>
|
||||
<string name="groups">Groups</string>
|
||||
|
|
Loading…
Add table
Reference in a new issue