mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-27 19:22:14 -05:00
DecryptTextActivity rework
This commit is contained in:
parent
5e090e6fb6
commit
9f67b0fe54
@ -96,7 +96,8 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".ui.CreateKeyActivity"
|
android:name=".ui.CreateKeyActivity"
|
||||||
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
||||||
android:label="@string/title_create_key">
|
android:label="@string/title_create_key"
|
||||||
|
android:parentActivityName=".ui.KeyListActivity">
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
android:value=".ui.KeyListActivity" />
|
android:value=".ui.KeyListActivity" />
|
||||||
@ -198,7 +199,11 @@
|
|||||||
android:name=".ui.DecryptTextActivity"
|
android:name=".ui.DecryptTextActivity"
|
||||||
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
||||||
android:label="@string/title_decrypt"
|
android:label="@string/title_decrypt"
|
||||||
android:windowSoftInputMode="stateHidden">
|
android:windowSoftInputMode="stateHidden"
|
||||||
|
android:parentActivityName=".ui.DecryptActivity">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
|
android:value=".ui.DecryptActivity" />
|
||||||
|
|
||||||
<!-- Keychain's own Actions -->
|
<!-- Keychain's own Actions -->
|
||||||
<!-- DECRYPT with text as extra -->
|
<!-- DECRYPT with text as extra -->
|
||||||
@ -221,7 +226,11 @@
|
|||||||
android:name=".ui.DecryptFilesActivity"
|
android:name=".ui.DecryptFilesActivity"
|
||||||
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
||||||
android:label="@string/title_decrypt"
|
android:label="@string/title_decrypt"
|
||||||
android:windowSoftInputMode="stateHidden">
|
android:windowSoftInputMode="stateHidden"
|
||||||
|
android:parentActivityName=".ui.DecryptActivity">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
|
android:value=".ui.DecryptActivity" />
|
||||||
|
|
||||||
<!-- VIEW with mimeType application/octet-stream, application/pgp and text/pgp -->
|
<!-- VIEW with mimeType application/octet-stream, application/pgp and text/pgp -->
|
||||||
<intent-filter android:label="@string/intent_send_decrypt">
|
<intent-filter android:label="@string/intent_send_decrypt">
|
||||||
|
@ -107,9 +107,8 @@ public class AccountSettingsActivity extends ActionBarActivity {
|
|||||||
|
|
||||||
private void save() {
|
private void save() {
|
||||||
new ProviderHelper(this).updateApiAccount(mAccountUri, mAccountSettingsFragment.getAccSettings());
|
new ProviderHelper(this).updateApiAccount(mAccountUri, mAccountSettingsFragment.getAccSettings());
|
||||||
// TODO: show "account saved" instead of "operation succeeded"
|
|
||||||
SingletonResult result = new SingletonResult(
|
SingletonResult result = new SingletonResult(
|
||||||
SingletonResult.RESULT_OK, LogLevel.OK, LogType.MSG_ACC_SAVED);
|
SingletonResult.RESULT_OK, LogType.MSG_ACC_SAVED);
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
intent.putExtra(SingletonResult.EXTRA_RESULT, result);
|
intent.putExtra(SingletonResult.EXTRA_RESULT, result);
|
||||||
setResult(RESULT_OK, intent);
|
setResult(RESULT_OK, intent);
|
||||||
|
@ -519,7 +519,9 @@ public abstract class OperationResult implements Parcelable {
|
|||||||
MSG_CRT_UPLOAD_SUCCESS (LogLevel.OK, R.string.msg_crt_upload_success),
|
MSG_CRT_UPLOAD_SUCCESS (LogLevel.OK, R.string.msg_crt_upload_success),
|
||||||
MSG_CRT_SUCCESS (LogLevel.OK, R.string.msg_crt_success),
|
MSG_CRT_SUCCESS (LogLevel.OK, R.string.msg_crt_success),
|
||||||
|
|
||||||
MSG_ACC_SAVED (LogLevel.INFO, R.string.api_settings_save)
|
MSG_ACC_SAVED (LogLevel.INFO, R.string.api_settings_save_msg),
|
||||||
|
|
||||||
|
MSG_NO_VALID_ENC (LogLevel.ERROR, R.string.error_invalid_data)
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ public class SingletonResult extends OperationResult {
|
|||||||
super(source);
|
super(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SingletonResult(int result, LogLevel level, LogType reason) {
|
public SingletonResult(int result, LogType reason) {
|
||||||
super(result, new OperationLog());
|
super(result, new OperationLog());
|
||||||
// Prepare the log
|
// Prepare the log
|
||||||
mLog.add(reason, 0);
|
mLog.add(reason, 0);
|
||||||
|
@ -330,7 +330,7 @@ public class CertifyKeyFragment extends LoaderFragment
|
|||||||
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
|
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
|
||||||
|
|
||||||
SingletonResult result = new SingletonResult(
|
SingletonResult result = new SingletonResult(
|
||||||
SingletonResult.RESULT_OK, LogLevel.OK, LogType.MSG_CRT_SUCCESS);
|
SingletonResult.RESULT_OK, LogType.MSG_CRT_SUCCESS);
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
intent.putExtra(SingletonResult.EXTRA_RESULT, result);
|
intent.putExtra(SingletonResult.EXTRA_RESULT, result);
|
||||||
mActivity.setResult(CertifyKeyActivity.RESULT_OK, intent);
|
mActivity.setResult(CertifyKeyActivity.RESULT_OK, intent);
|
||||||
@ -384,7 +384,7 @@ public class CertifyKeyFragment extends LoaderFragment
|
|||||||
|
|
||||||
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
|
if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
|
||||||
SingletonResult result = new SingletonResult(SingletonResult.RESULT_OK,
|
SingletonResult result = new SingletonResult(SingletonResult.RESULT_OK,
|
||||||
LogLevel.OK, LogType.MSG_CRT_UPLOAD_SUCCESS);
|
LogType.MSG_CRT_UPLOAD_SUCCESS);
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
intent.putExtra(SingletonResult.EXTRA_RESULT, result);
|
intent.putExtra(SingletonResult.EXTRA_RESULT, result);
|
||||||
mActivity.setResult(CertifyKeyActivity.RESULT_OK, intent);
|
mActivity.setResult(CertifyKeyActivity.RESULT_OK, intent);
|
||||||
|
@ -22,6 +22,7 @@ import android.os.Bundle;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
import org.sufficientlysecure.keychain.service.results.OperationResult;
|
||||||
|
|
||||||
public class DecryptActivity extends DrawerActivity {
|
public class DecryptActivity extends DrawerActivity {
|
||||||
|
|
||||||
@ -50,8 +51,19 @@ public class DecryptActivity extends DrawerActivity {
|
|||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Intent clipboardDecrypt = new Intent(DecryptActivity.this, DecryptTextActivity.class);
|
Intent clipboardDecrypt = new Intent(DecryptActivity.this, DecryptTextActivity.class);
|
||||||
clipboardDecrypt.setAction(DecryptTextActivity.ACTION_DECRYPT_FROM_CLIPBOARD);
|
clipboardDecrypt.setAction(DecryptTextActivity.ACTION_DECRYPT_FROM_CLIPBOARD);
|
||||||
startActivity(clipboardDecrypt);
|
startActivityForResult(clipboardDecrypt, 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
// if a result has been returned, display a notify
|
||||||
|
if (data != null && data.hasExtra(OperationResult.EXTRA_RESULT)) {
|
||||||
|
OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT);
|
||||||
|
result.createNotify(this).show();
|
||||||
|
} else {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,6 @@ import java.io.File;
|
|||||||
|
|
||||||
public class DecryptFilesFragment extends DecryptFragment {
|
public class DecryptFilesFragment extends DecryptFragment {
|
||||||
public static final String ARG_URI = "uri";
|
public static final String ARG_URI = "uri";
|
||||||
// public static final String ARG_FROM_VIEW_INTENT = "view_intent";
|
|
||||||
public static final String ARG_OPEN_DIRECTLY = "open_directly";
|
public static final String ARG_OPEN_DIRECTLY = "open_directly";
|
||||||
|
|
||||||
private static final int REQUEST_CODE_INPUT = 0x00007003;
|
private static final int REQUEST_CODE_INPUT = 0x00007003;
|
||||||
@ -71,7 +70,6 @@ public class DecryptFilesFragment extends DecryptFragment {
|
|||||||
|
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putParcelable(ARG_URI, uri);
|
args.putParcelable(ARG_URI, uri);
|
||||||
// args.putBoolean(ARG_FROM_VIEW_INTENT, fromViewIntent);
|
|
||||||
args.putBoolean(ARG_OPEN_DIRECTLY, openDirectly);
|
args.putBoolean(ARG_OPEN_DIRECTLY, openDirectly);
|
||||||
|
|
||||||
frag.setArguments(args);
|
frag.setArguments(args);
|
||||||
|
@ -27,6 +27,8 @@ import org.sufficientlysecure.keychain.R;
|
|||||||
import org.sufficientlysecure.keychain.api.OpenKeychainIntents;
|
import org.sufficientlysecure.keychain.api.OpenKeychainIntents;
|
||||||
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
||||||
|
import org.sufficientlysecure.keychain.service.results.OperationResult;
|
||||||
|
import org.sufficientlysecure.keychain.service.results.SingletonResult;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||||
|
|
||||||
@ -53,6 +55,48 @@ public class DecryptTextActivity extends ActionBarActivity {
|
|||||||
handleActions(savedInstanceState, getIntent());
|
handleActions(savedInstanceState, getIntent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fix the message a bit, trailing spaces and newlines break stuff,
|
||||||
|
* because GMail sends as HTML and such things break ASCII Armor
|
||||||
|
* TODO: things like "<" and ">" also make problems
|
||||||
|
* <p/>
|
||||||
|
* NOTE: Do not use on cleartext signatures, only on ASCII-armored ciphertext,
|
||||||
|
* it would change the signed message
|
||||||
|
*/
|
||||||
|
private String fixAsciiArmoredCiphertext(String message) {
|
||||||
|
message = message.replaceAll(" +\n", "\n");
|
||||||
|
message = message.replaceAll("\n\n+", "\n\n");
|
||||||
|
message = message.replaceFirst("^\n+", "");
|
||||||
|
// make sure there'll be exactly one newline at the end
|
||||||
|
message = message.replaceFirst("\n*$", "\n");
|
||||||
|
// replace non breakable spaces
|
||||||
|
message = message.replaceAll("\\xa0", " ");
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getPgpContent(String input) {
|
||||||
|
// only decrypt if clipboard content is available and a pgp message or cleartext signature
|
||||||
|
if (input != null) {
|
||||||
|
Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(input);
|
||||||
|
if (matcher.matches()) {
|
||||||
|
String message = matcher.group(1);
|
||||||
|
message = fixAsciiArmoredCiphertext(message);
|
||||||
|
return message;
|
||||||
|
} else {
|
||||||
|
matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(input);
|
||||||
|
if (matcher.matches()) {
|
||||||
|
// return cleartext signature
|
||||||
|
return matcher.group(1);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles all actions with this intent
|
* Handles all actions with this intent
|
||||||
*
|
*
|
||||||
@ -67,74 +111,59 @@ public class DecryptTextActivity extends ActionBarActivity {
|
|||||||
extras = new Bundle();
|
extras = new Bundle();
|
||||||
}
|
}
|
||||||
|
|
||||||
String textData = null;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Android's Action
|
|
||||||
*/
|
|
||||||
if (Intent.ACTION_SEND.equals(action) && type != null) {
|
if (Intent.ACTION_SEND.equals(action) && type != null) {
|
||||||
|
// Android action
|
||||||
|
|
||||||
// When sending to Keychain Decrypt via share menu
|
// When sending to Keychain Decrypt via share menu
|
||||||
if ("text/plain".equals(type)) {
|
if ("text/plain".equals(type)) {
|
||||||
// Plain text
|
|
||||||
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
|
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
|
||||||
|
sharedText = getPgpContent(sharedText);
|
||||||
|
|
||||||
if (sharedText != null) {
|
if (sharedText != null) {
|
||||||
// handle like normal text decryption, override action and extras to later
|
loadFragment(savedInstanceState, sharedText);
|
||||||
// executeServiceMethod ACTION_DECRYPT_TEXT in main actions
|
|
||||||
textData = sharedText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main Actions
|
|
||||||
*/
|
|
||||||
textData = extras.getString(EXTRA_TEXT);
|
|
||||||
if (ACTION_DECRYPT_TEXT.equals(action) && textData != null) {
|
|
||||||
Log.d(Constants.TAG, "textData not null, matching text ...");
|
|
||||||
Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(textData);
|
|
||||||
if (matcher.matches()) {
|
|
||||||
Log.d(Constants.TAG, "PGP_MESSAGE matched");
|
|
||||||
textData = matcher.group(1);
|
|
||||||
// replace non breakable spaces
|
|
||||||
textData = textData.replaceAll("\\xa0", " ");
|
|
||||||
} else {
|
|
||||||
matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(textData);
|
|
||||||
if (matcher.matches()) {
|
|
||||||
Log.d(Constants.TAG, "PGP_CLEARTEXT_SIGNATURE matched");
|
|
||||||
textData = matcher.group(1);
|
|
||||||
// replace non breakable spaces
|
|
||||||
textData = textData.replaceAll("\\xa0", " ");
|
|
||||||
} else {
|
|
||||||
Notify.showNotify(this, R.string.error_invalid_data, Notify.Style.ERROR);
|
|
||||||
Log.d(Constants.TAG, "Nothing matched!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (ACTION_DECRYPT_FROM_CLIPBOARD.equals(action)) {
|
|
||||||
CharSequence clipboardText = ClipboardReflection.getClipboardText(this);
|
|
||||||
|
|
||||||
// only decrypt if clipboard content is available and a pgp message or cleartext signature
|
|
||||||
if (clipboardText != null) {
|
|
||||||
Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(clipboardText);
|
|
||||||
if (!matcher.matches()) {
|
|
||||||
matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(clipboardText);
|
|
||||||
}
|
|
||||||
if (matcher.matches()) {
|
|
||||||
textData = matcher.group(1);
|
|
||||||
} else {
|
} else {
|
||||||
Notify.showNotify(this, R.string.error_invalid_data, Notify.Style.ERROR);
|
Notify.showNotify(this, R.string.error_invalid_data, Notify.Style.ERROR);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Notify.showNotify(this, R.string.error_invalid_data, Notify.Style.ERROR);
|
Log.e(Constants.TAG, "ACTION_SEND received non-plaintext, this should not happen in this activity!");
|
||||||
}
|
}
|
||||||
} else if (ACTION_DECRYPT_TEXT.equals(action)) {
|
} else if (ACTION_DECRYPT_TEXT.equals(action)) {
|
||||||
Log.e(Constants.TAG,
|
Log.d(Constants.TAG, "ACTION_DECRYPT_TEXT textData not null, matching text...");
|
||||||
"Include the extra 'text' in your Intent!");
|
|
||||||
|
String extraText = extras.getString(EXTRA_TEXT);
|
||||||
|
extraText = getPgpContent(extraText);
|
||||||
|
|
||||||
|
if (extraText != null) {
|
||||||
|
loadFragment(savedInstanceState, extraText);
|
||||||
|
} else {
|
||||||
|
Notify.showNotify(this, R.string.error_invalid_data, Notify.Style.ERROR);
|
||||||
|
}
|
||||||
|
} else if (ACTION_DECRYPT_FROM_CLIPBOARD.equals(action)) {
|
||||||
|
Log.d(Constants.TAG, "ACTION_DECRYPT_FROM_CLIPBOARD");
|
||||||
|
|
||||||
|
String clipboardText = ClipboardReflection.getClipboardText(this).toString();
|
||||||
|
clipboardText = getPgpContent(clipboardText);
|
||||||
|
|
||||||
|
if (clipboardText != null) {
|
||||||
|
loadFragment(savedInstanceState, clipboardText);
|
||||||
|
} else {
|
||||||
|
returnInvalidResult();
|
||||||
|
}
|
||||||
|
} else if (ACTION_DECRYPT_TEXT.equals(action)) {
|
||||||
|
Log.e(Constants.TAG, "Include the extra 'text' in your Intent!");
|
||||||
|
finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadFragment(savedInstanceState, textData);
|
private void returnInvalidResult() {
|
||||||
|
SingletonResult result = new SingletonResult(
|
||||||
|
SingletonResult.RESULT_ERROR, OperationResult.LogType.MSG_NO_VALID_ENC);
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.putExtra(SingletonResult.EXTRA_RESULT, result);
|
||||||
|
setResult(RESULT_OK, intent);
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void loadFragment(Bundle savedInstanceState, String ciphertext) {
|
private void loadFragment(Bundle savedInstanceState, String ciphertext) {
|
||||||
// However, if we're being restored from a previous state,
|
// However, if we're being restored from a previous state,
|
||||||
// then we don't need to do anything and should return or else
|
// then we don't need to do anything and should return or else
|
||||||
|
@ -654,7 +654,7 @@ public class EditKeyFragment extends LoaderFragment implements
|
|||||||
// Prepare an intent with an EXTRA_RESULT
|
// Prepare an intent with an EXTRA_RESULT
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
intent.putExtra(OperationResult.EXTRA_RESULT,
|
intent.putExtra(OperationResult.EXTRA_RESULT,
|
||||||
new SingletonResult(SingletonResult.RESULT_ERROR, LogLevel.ERROR, reason));
|
new SingletonResult(SingletonResult.RESULT_ERROR, reason));
|
||||||
|
|
||||||
// Finish with result
|
// Finish with result
|
||||||
getActivity().setResult(EditKeyActivity.RESULT_OK, intent);
|
getActivity().setResult(EditKeyActivity.RESULT_OK, intent);
|
||||||
|
@ -241,7 +241,7 @@
|
|||||||
<string name="error_key_needs_a_user_id">"need at least one identity"</string>
|
<string name="error_key_needs_a_user_id">"need at least one identity"</string>
|
||||||
<string name="error_no_signature_passphrase">"no passphrase given"</string>
|
<string name="error_no_signature_passphrase">"no passphrase given"</string>
|
||||||
<string name="error_no_signature_key">"no signature key given"</string>
|
<string name="error_no_signature_key">"no signature key given"</string>
|
||||||
<string name="error_invalid_data">"not valid encryption data"</string>
|
<string name="error_invalid_data">"No valid encrypted or signed OpenPGP content!"</string>
|
||||||
<string name="error_integrity_check_failed">"integrity check failed! Data has been modified!"</string>
|
<string name="error_integrity_check_failed">"integrity check failed! Data has been modified!"</string>
|
||||||
<string name="error_wrong_passphrase">"wrong passphrase"</string>
|
<string name="error_wrong_passphrase">"wrong passphrase"</string>
|
||||||
<string name="error_could_not_extract_private_key">"could not extract private key"</string>
|
<string name="error_could_not_extract_private_key">"could not extract private key"</string>
|
||||||
@ -424,6 +424,7 @@
|
|||||||
<string name="api_settings_select_key">"Select key"</string>
|
<string name="api_settings_select_key">"Select key"</string>
|
||||||
<string name="api_settings_create_key">"Create new key for this account"</string>
|
<string name="api_settings_create_key">"Create new key for this account"</string>
|
||||||
<string name="api_settings_save">"Save"</string>
|
<string name="api_settings_save">"Save"</string>
|
||||||
|
<string name="api_settings_save_msg">"Account has been saved"</string>
|
||||||
<string name="api_settings_cancel">"Cancel"</string>
|
<string name="api_settings_cancel">"Cancel"</string>
|
||||||
<string name="api_settings_revoke">"Revoke access"</string>
|
<string name="api_settings_revoke">"Revoke access"</string>
|
||||||
<string name="api_settings_start">"Start application"</string>
|
<string name="api_settings_start">"Start application"</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user