show Snackbar if clipboard contains key data

This commit is contained in:
Vincent Breitmoser 2018-06-14 16:26:40 +02:00 committed by Dominik Schürmann
parent 700e06dcb9
commit 89aa99a13f
6 changed files with 115 additions and 24 deletions

View file

@ -34,6 +34,9 @@ public class ClipboardReflection {
return null;
}
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
if (clipboard == null) {
return null;
}
ClipData clip = clipboard.getPrimaryClip();
if (clip == null || clip.getItemCount() == 0) {
@ -48,4 +51,16 @@ public class ClipboardReflection {
}
return null;
}
public static void clearClipboard(@Nullable Context context) {
if (context == null) {
return;
}
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
if (clipboard == null) {
return;
}
clipboard.setPrimaryClip(ClipData.newPlainText("", ""));
}
}

View file

@ -84,22 +84,16 @@ public class PgpHelper {
}
public static String getPgpMessageContent(@NonNull CharSequence input) {
Timber.d("input: %s");
Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(input);
if (matcher.matches()) {
String text = matcher.group(1);
text = fixPgpMessage(text);
Timber.d("input fixed: %s", text);
return text;
} else {
matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(input);
if (matcher.matches()) {
String text = matcher.group(1);
text = fixPgpCleartextSignature(text);
Timber.d("input fixed: %s", text);
return text;
} else {
return null;
@ -108,8 +102,6 @@ public class PgpHelper {
}
public static String getPgpPublicKeyContent(@NonNull CharSequence input) {
Timber.d("input: %s", input);
Matcher matcher = PgpHelper.PGP_PUBLIC_KEY.matcher(input);
if (!matcher.matches()) {
return null;

View file

@ -117,25 +117,23 @@ public class EncryptDecryptFragment extends Fragment {
public void onResume() {
super.onResume();
// get text from clipboard
final CharSequence clipboardText = ClipboardReflection.getClipboardText(getActivity());
checkClipboardForEncryptedText();
}
// if it's null, nothing to do here /o/
if (clipboardText == null) {
return;
}
private void checkClipboardForEncryptedText() {
CharSequence clipboardText = ClipboardReflection.getClipboardText(getActivity());
new AsyncTask<String, Void, Boolean>() {
new AsyncTask<Void, Void, Boolean>() {
@Override
protected Boolean doInBackground(String... clipboardText) {
protected Boolean doInBackground(Void... voids) {
// see if it looks like a pgp thing
Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(clipboardText[0]);
Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(clipboardText);
boolean animate = matcher.matches();
// see if it looks like another pgp thing
if (!animate) {
matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(clipboardText[0]);
matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(clipboardText);
animate = matcher.matches();
}
return animate;
@ -150,7 +148,7 @@ public class EncryptDecryptFragment extends Fragment {
SubtleAttentionSeeker.tada(mClipboardIcon, 1.5f).start();
}
}
}.execute(clipboardText.toString());
}.execute();
}
@Override

View file

@ -17,6 +17,11 @@
package org.sufficientlysecure.keychain.ui;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
@ -25,10 +30,11 @@ import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.view.ViewGroup;
import android.text.TextUtils;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import org.sufficientlysecure.keychain.keyimport.FacebookKeyserverClient;
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress;
import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry;
@ -38,19 +44,17 @@ import org.sufficientlysecure.keychain.keyimport.processing.ImportKeysOperationC
import org.sufficientlysecure.keychain.keyimport.processing.LoaderState;
import org.sufficientlysecure.keychain.operations.ImportOperation;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
import org.sufficientlysecure.keychain.ui.base.BaseActivity;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.ui.util.Notify.Style;
import org.sufficientlysecure.keychain.util.ParcelableFileCache;
import org.sufficientlysecure.keychain.util.Preferences;
import timber.log.Timber;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class ImportKeysActivity extends BaseActivity implements ImportKeysListener {
public static final String ACTION_IMPORT_KEY = Constants.IMPORT_KEY;
@ -69,6 +73,8 @@ public class ImportKeysActivity extends BaseActivity implements ImportKeysListen
+ "IMPORT_KEY_FROM_FILE";
public static final String ACTION_SEARCH_KEYSERVER_FROM_URL = Constants.INTENT_PREFIX
+ "SEARCH_KEYSERVER_FROM_URL";
public static final String ACTION_IMPORT_KEY_FROM_CLIPBOARD = Constants.INTENT_PREFIX
+ "IMPORT_KEY_FROM_CLIPBOARD";
public static final String EXTRA_RESULT = "result";
// only used by ACTION_IMPORT_KEY
@ -257,6 +263,10 @@ public class ImportKeysActivity extends BaseActivity implements ImportKeysListen
startListFragment(null, null, null, null);
break;
}
case ACTION_IMPORT_KEY_FROM_CLIPBOARD: {
startListFragmentFromClipboard();
break;
}
default: {
startTopCloudFragment(null, null);
startListFragment(null, null, null, null);
@ -265,6 +275,22 @@ public class ImportKeysActivity extends BaseActivity implements ImportKeysListen
}
}
private void startListFragmentFromClipboard() {
CharSequence clipboardText = ClipboardReflection.getClipboardText(this);
if (TextUtils.isEmpty(clipboardText)) {
Notify.create(this, R.string.error_clipboard_empty, Style.ERROR).show();
return;
}
String keyText = PgpHelper.getPgpPublicKeyContent(clipboardText);
if (keyText == null) {
Notify.create(this, R.string.error_clipboard_bad, Style.ERROR).show();
return;
}
startListFragment(keyText.getBytes(), null, null, null);
}
/**
* Shows the list of keys to be imported.
* If the fragment is started with non-null bytes/dataUri/serverQuery, it will immediately
@ -387,6 +413,10 @@ public class ImportKeysActivity extends BaseActivity implements ImportKeysListen
setResult(Activity.RESULT_OK, intent);
finish();
} else if (result.isOkNew() || result.isOkUpdated()) {
if (ACTION_IMPORT_KEY_FROM_CLIPBOARD.equals(intentAction)) {
ClipboardReflection.clearClipboard(getApplicationContext());
}
// User has successfully imported a key, hide first time dialog
Preferences.getPreferences(this).setFirstTime(false);

View file

@ -26,6 +26,7 @@ import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
@ -50,11 +51,13 @@ import com.getbase.floatingactionbutton.FloatingActionsMenu;
import com.tonicartos.superslim.LayoutManager;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
import org.sufficientlysecure.keychain.operations.results.BenchmarkResult;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.provider.KeyRepository;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
@ -66,6 +69,8 @@ import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
import org.sufficientlysecure.keychain.ui.base.RecyclerFragment;
import org.sufficientlysecure.keychain.ui.keyview.ViewKeyActivity;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.ui.util.Notify.ActionListener;
import org.sufficientlysecure.keychain.ui.util.Notify.Style;
import org.sufficientlysecure.keychain.util.FabContainer;
import org.sufficientlysecure.keychain.util.Preferences;
import timber.log.Timber;
@ -254,6 +259,54 @@ public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
getLoaderManager().initLoader(0, null, this);
}
@Override
public void onStart() {
super.onStart();
checkClipboardForPublicKeyMaterial();
}
private void checkClipboardForPublicKeyMaterial() {
CharSequence clipboardText = ClipboardReflection.getClipboardText(getActivity());
new AsyncTask<Void, Void, Boolean>() {
@Override
protected Boolean doInBackground(Void... voids) {
if (clipboardText == null) {
return false;
}
// see if it looks like a pgp thing
String publicKeyContent = PgpHelper.getPgpPublicKeyContent(clipboardText);
return publicKeyContent != null;
}
@Override
protected void onPostExecute(Boolean clipboardDataFound) {
super.onPostExecute(clipboardDataFound);
if (clipboardDataFound) {
showClipboardDataSnackbar();
}
}
}.execute();
}
private void showClipboardDataSnackbar() {
Activity activity = getActivity();
if (activity == null) {
return;
}
Notify.create(activity, R.string.snack_keylist_clipboard_title, Notify.LENGTH_INDEFINITE, Style.OK,
() -> {
Intent intentImportExisting = new Intent(getActivity(), ImportKeysActivity.class);
intentImportExisting.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_CLIPBOARD);
startActivity(intentImportExisting);
}, R.string.snack_keylist_clipboard_action).show(this);
}
private void startSearchForQuery() {
Activity activity = getActivity();
if (activity == null) {

View file

@ -2021,4 +2021,7 @@
<string name="button_goto_openkeychain">Go to OpenKeychain</string>
<string name="backup_code_checkbox">I have written down this backup code. Without it, I will be unable to restore the backup.</string>
<string name="msg_get_query_not_implemented">The server does not support the current query! Some servers only accept mailaddresses. Please redefine or try a different server.</string>
<string name="snack_keylist_clipboard_title">Found key data in clipboard!</string>
<string name="snack_keylist_clipboard_action">View</string>
</resources>