add tests for MessageCryptoHelper
This commit is contained in:
parent
8b1cfb0730
commit
4d580d539d
6 changed files with 290 additions and 15 deletions
|
@ -57,7 +57,7 @@ public abstract class Message implements Part, Body {
|
||||||
final int MULTIPLIER = 31;
|
final int MULTIPLIER = 31;
|
||||||
|
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = MULTIPLIER * result + mFolder.getName().hashCode();
|
result = MULTIPLIER * result + (mFolder != null ? mFolder.getName().hashCode() : 0);
|
||||||
result = MULTIPLIER * result + mUid.hashCode();
|
result = MULTIPLIER * result + mUid.hashCode();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ import android.os.Parcelable;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
|
|
||||||
|
import com.fsck.k9.ui.crypto.OpenPgpApiFactory;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
import com.fsck.k9.Account;
|
import com.fsck.k9.Account;
|
||||||
|
@ -268,7 +270,7 @@ public class MessageLoaderHelper {
|
||||||
messageCryptoHelper = retainCryptoHelperFragment.getData();
|
messageCryptoHelper = retainCryptoHelperFragment.getData();
|
||||||
}
|
}
|
||||||
if (messageCryptoHelper == null || messageCryptoHelper.isConfiguredForOutdatedCryptoProvider()) {
|
if (messageCryptoHelper == null || messageCryptoHelper.isConfiguredForOutdatedCryptoProvider()) {
|
||||||
messageCryptoHelper = new MessageCryptoHelper(context);
|
messageCryptoHelper = new MessageCryptoHelper(context, new OpenPgpApiFactory());
|
||||||
retainCryptoHelperFragment.setData(messageCryptoHelper);
|
retainCryptoHelperFragment.setData(messageCryptoHelper);
|
||||||
}
|
}
|
||||||
messageCryptoHelper.asyncStartOrResumeProcessingMessage(
|
messageCryptoHelper.asyncStartOrResumeProcessingMessage(
|
||||||
|
|
|
@ -200,13 +200,11 @@ public class MessageDecryptVerifier {
|
||||||
if (body instanceof Multipart) {
|
if (body instanceof Multipart) {
|
||||||
Multipart multi = (Multipart) body;
|
Multipart multi = (Multipart) body;
|
||||||
BodyPart signatureBody = multi.getBodyPart(1);
|
BodyPart signatureBody = multi.getBodyPart(1);
|
||||||
if (isSameMimeType(signatureBody.getMimeType(), APPLICATION_PGP_SIGNATURE)) {
|
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
signatureBody.getBody().writeTo(bos);
|
signatureBody.getBody().writeTo(bos);
|
||||||
return bos.toByteArray();
|
return bos.toByteArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ import android.content.Intent;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.annotation.WorkerThread;
|
import android.support.annotation.WorkerThread;
|
||||||
import timber.log.Timber;
|
|
||||||
|
|
||||||
import com.fsck.k9.K9;
|
import com.fsck.k9.K9;
|
||||||
import com.fsck.k9.crypto.MessageDecryptVerifier;
|
import com.fsck.k9.crypto.MessageDecryptVerifier;
|
||||||
|
@ -24,6 +23,7 @@ import com.fsck.k9.mail.Address;
|
||||||
import com.fsck.k9.mail.Body;
|
import com.fsck.k9.mail.Body;
|
||||||
import com.fsck.k9.mail.BodyPart;
|
import com.fsck.k9.mail.BodyPart;
|
||||||
import com.fsck.k9.mail.Flag;
|
import com.fsck.k9.mail.Flag;
|
||||||
|
import com.fsck.k9.mail.Message;
|
||||||
import com.fsck.k9.mail.MessagingException;
|
import com.fsck.k9.mail.MessagingException;
|
||||||
import com.fsck.k9.mail.Multipart;
|
import com.fsck.k9.mail.Multipart;
|
||||||
import com.fsck.k9.mail.Part;
|
import com.fsck.k9.mail.Part;
|
||||||
|
@ -34,7 +34,6 @@ import com.fsck.k9.mail.internet.SizeAware;
|
||||||
import com.fsck.k9.mail.internet.TextBody;
|
import com.fsck.k9.mail.internet.TextBody;
|
||||||
import com.fsck.k9.mailstore.CryptoResultAnnotation;
|
import com.fsck.k9.mailstore.CryptoResultAnnotation;
|
||||||
import com.fsck.k9.mailstore.CryptoResultAnnotation.CryptoError;
|
import com.fsck.k9.mailstore.CryptoResultAnnotation.CryptoError;
|
||||||
import com.fsck.k9.mailstore.LocalMessage;
|
|
||||||
import com.fsck.k9.mailstore.MessageHelper;
|
import com.fsck.k9.mailstore.MessageHelper;
|
||||||
import com.fsck.k9.mailstore.MimePartStreamParser;
|
import com.fsck.k9.mailstore.MimePartStreamParser;
|
||||||
import com.fsck.k9.mailstore.util.FileFactory;
|
import com.fsck.k9.mailstore.util.FileFactory;
|
||||||
|
@ -52,6 +51,7 @@ import org.openintents.openpgp.util.OpenPgpApi.OpenPgpDataSource;
|
||||||
import org.openintents.openpgp.util.OpenPgpServiceConnection;
|
import org.openintents.openpgp.util.OpenPgpServiceConnection;
|
||||||
import org.openintents.openpgp.util.OpenPgpServiceConnection.OnBound;
|
import org.openintents.openpgp.util.OpenPgpServiceConnection.OnBound;
|
||||||
import org.openintents.openpgp.util.OpenPgpUtils;
|
import org.openintents.openpgp.util.OpenPgpUtils;
|
||||||
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
|
||||||
public class MessageCryptoHelper {
|
public class MessageCryptoHelper {
|
||||||
|
@ -68,7 +68,7 @@ public class MessageCryptoHelper {
|
||||||
@Nullable
|
@Nullable
|
||||||
private MessageCryptoCallback callback;
|
private MessageCryptoCallback callback;
|
||||||
|
|
||||||
private LocalMessage currentMessage;
|
private Message currentMessage;
|
||||||
private OpenPgpDecryptionResult cachedDecryptionResult;
|
private OpenPgpDecryptionResult cachedDecryptionResult;
|
||||||
private MessageCryptoAnnotations queuedResult;
|
private MessageCryptoAnnotations queuedResult;
|
||||||
private PendingIntent queuedPendingIntent;
|
private PendingIntent queuedPendingIntent;
|
||||||
|
@ -84,15 +84,17 @@ public class MessageCryptoHelper {
|
||||||
|
|
||||||
private OpenPgpApi openPgpApi;
|
private OpenPgpApi openPgpApi;
|
||||||
private OpenPgpServiceConnection openPgpServiceConnection;
|
private OpenPgpServiceConnection openPgpServiceConnection;
|
||||||
|
private OpenPgpApiFactory openPgpApiFactory;
|
||||||
|
|
||||||
|
|
||||||
public MessageCryptoHelper(Context context) {
|
public MessageCryptoHelper(Context context, OpenPgpApiFactory openPgpApiFactory) {
|
||||||
this.context = context.getApplicationContext();
|
this.context = context.getApplicationContext();
|
||||||
|
|
||||||
if (!K9.isOpenPgpProviderConfigured()) {
|
if (!K9.isOpenPgpProviderConfigured()) {
|
||||||
throw new IllegalStateException("MessageCryptoHelper must only be called with a openpgp provider!");
|
throw new IllegalStateException("MessageCryptoHelper must only be called with a openpgp provider!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.openPgpApiFactory = openPgpApiFactory;
|
||||||
openPgpProviderPackage = K9.getOpenPgpProvider();
|
openPgpProviderPackage = K9.getOpenPgpProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +102,7 @@ public class MessageCryptoHelper {
|
||||||
return !openPgpProviderPackage.equals(K9.getOpenPgpProvider());
|
return !openPgpProviderPackage.equals(K9.getOpenPgpProvider());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void asyncStartOrResumeProcessingMessage(LocalMessage message, MessageCryptoCallback callback,
|
public void asyncStartOrResumeProcessingMessage(Message message, MessageCryptoCallback callback,
|
||||||
OpenPgpDecryptionResult cachedDecryptionResult) {
|
OpenPgpDecryptionResult cachedDecryptionResult) {
|
||||||
if (this.currentMessage != null) {
|
if (this.currentMessage != null) {
|
||||||
reattachCallback(message, callback);
|
reattachCallback(message, callback);
|
||||||
|
@ -215,9 +217,10 @@ public class MessageCryptoHelper {
|
||||||
private void connectToCryptoProviderService() {
|
private void connectToCryptoProviderService() {
|
||||||
openPgpServiceConnection = new OpenPgpServiceConnection(context, openPgpProviderPackage,
|
openPgpServiceConnection = new OpenPgpServiceConnection(context, openPgpProviderPackage,
|
||||||
new OnBound() {
|
new OnBound() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBound(IOpenPgpService2 service) {
|
public void onBound(IOpenPgpService2 service) {
|
||||||
openPgpApi = new OpenPgpApi(context, service);
|
openPgpApi = openPgpApiFactory.createOpenPgpApi(context, service);
|
||||||
|
|
||||||
decryptOrVerifyNextPart();
|
decryptOrVerifyNextPart();
|
||||||
}
|
}
|
||||||
|
@ -621,7 +624,7 @@ public class MessageCryptoHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reattachCallback(LocalMessage message, MessageCryptoCallback callback) {
|
private void reattachCallback(Message message, MessageCryptoCallback callback) {
|
||||||
if (!message.equals(currentMessage)) {
|
if (!message.equals(currentMessage)) {
|
||||||
throw new AssertionError("Callback may only be reattached for the same message!");
|
throw new AssertionError("Callback may only be reattached for the same message!");
|
||||||
}
|
}
|
||||||
|
@ -726,5 +729,4 @@ public class MessageCryptoHelper {
|
||||||
return NO_REPLACEMENT_PART;
|
return NO_REPLACEMENT_PART;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.fsck.k9.ui.crypto;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import org.openintents.openpgp.util.OpenPgpApi;
|
||||||
|
import org.openintents.openpgp.IOpenPgpService2;
|
||||||
|
|
||||||
|
|
||||||
|
public class OpenPgpApiFactory {
|
||||||
|
OpenPgpApi createOpenPgpApi(Context context, IOpenPgpService2 service) {
|
||||||
|
return new OpenPgpApi(context, service);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,259 @@
|
||||||
|
package com.fsck.k9.ui.crypto;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import com.fsck.k9.K9;
|
||||||
|
import com.fsck.k9.mail.Address;
|
||||||
|
import com.fsck.k9.mail.Body;
|
||||||
|
import com.fsck.k9.mail.BodyPart;
|
||||||
|
import com.fsck.k9.mail.Message;
|
||||||
|
import com.fsck.k9.mail.Multipart;
|
||||||
|
import com.fsck.k9.mail.internet.MimeBodyPart;
|
||||||
|
import com.fsck.k9.mail.internet.MimeMessage;
|
||||||
|
import com.fsck.k9.mail.internet.MimeMultipart;
|
||||||
|
import com.fsck.k9.mail.internet.TextBody;
|
||||||
|
import com.fsck.k9.mailstore.CryptoResultAnnotation;
|
||||||
|
import com.fsck.k9.mailstore.CryptoResultAnnotation.CryptoError;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.openintents.openpgp.IOpenPgpService2;
|
||||||
|
import org.openintents.openpgp.OpenPgpDecryptionResult;
|
||||||
|
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||||
|
import org.openintents.openpgp.util.OpenPgpApi;
|
||||||
|
import org.openintents.openpgp.util.OpenPgpApi.IOpenPgpSinkResultCallback;
|
||||||
|
import org.openintents.openpgp.util.OpenPgpApi.OpenPgpDataSink;
|
||||||
|
import org.openintents.openpgp.util.OpenPgpApi.OpenPgpDataSource;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
import static junit.framework.Assert.assertSame;
|
||||||
|
import static junit.framework.Assert.assertTrue;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
@Config(manifest = Config.NONE, sdk = 21)
|
||||||
|
public class MessageCryptoHelperTest {
|
||||||
|
private MessageCryptoHelper messageCryptoHelper;
|
||||||
|
private OpenPgpApi openPgpApi;
|
||||||
|
private Intent capturedApiIntent;
|
||||||
|
private IOpenPgpSinkResultCallback capturedCallback;
|
||||||
|
private MessageCryptoCallback messageCryptoCallback;
|
||||||
|
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
openPgpApi = mock(OpenPgpApi.class);
|
||||||
|
|
||||||
|
K9.setOpenPgpProvider("org.example.dummy");
|
||||||
|
|
||||||
|
OpenPgpApiFactory openPgpApiFactory = mock(OpenPgpApiFactory.class);
|
||||||
|
when(openPgpApiFactory.createOpenPgpApi(any(Context.class), any(IOpenPgpService2.class))).thenReturn(openPgpApi);
|
||||||
|
messageCryptoHelper = new MessageCryptoHelper(RuntimeEnvironment.application, openPgpApiFactory);
|
||||||
|
messageCryptoCallback = mock(MessageCryptoCallback.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void textPlain() throws Exception {
|
||||||
|
MimeMessage message = new MimeMessage();
|
||||||
|
message.setUid("msguid");
|
||||||
|
message.setHeader("Content-Type", "text/plain");
|
||||||
|
|
||||||
|
MessageCryptoCallback messageCryptoCallback = mock(MessageCryptoCallback.class);
|
||||||
|
messageCryptoHelper.asyncStartOrResumeProcessingMessage(message, messageCryptoCallback, null);
|
||||||
|
|
||||||
|
ArgumentCaptor<MessageCryptoAnnotations> captor = ArgumentCaptor.forClass(MessageCryptoAnnotations.class);
|
||||||
|
verify(messageCryptoCallback).onCryptoOperationsFinished(captor.capture());
|
||||||
|
MessageCryptoAnnotations annotations = captor.getValue();
|
||||||
|
assertTrue(annotations.isEmpty());
|
||||||
|
verifyNoMoreInteractions(messageCryptoCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void multipartSigned__withNullBody__shouldReturnSignedIncomplete() throws Exception {
|
||||||
|
MimeMessage message = new MimeMessage();
|
||||||
|
message.setUid("msguid");
|
||||||
|
message.setHeader("Content-Type", "multipart/signed");
|
||||||
|
|
||||||
|
MessageCryptoCallback messageCryptoCallback = mock(MessageCryptoCallback.class);
|
||||||
|
messageCryptoHelper.asyncStartOrResumeProcessingMessage(message, messageCryptoCallback, null);
|
||||||
|
|
||||||
|
assertPartAnnotationHasState(message, messageCryptoCallback, CryptoError.OPENPGP_SIGNED_BUT_INCOMPLETE, null,
|
||||||
|
null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void multipartEncrypted__withNullBody__shouldReturnEncryptedIncomplete() throws Exception {
|
||||||
|
MimeMessage message = new MimeMessage();
|
||||||
|
message.setUid("msguid");
|
||||||
|
message.setHeader("Content-Type", "multipart/encrypted");
|
||||||
|
|
||||||
|
MessageCryptoCallback messageCryptoCallback = mock(MessageCryptoCallback.class);
|
||||||
|
messageCryptoHelper.asyncStartOrResumeProcessingMessage(message, messageCryptoCallback, null);
|
||||||
|
|
||||||
|
assertPartAnnotationHasState(
|
||||||
|
message, messageCryptoCallback, CryptoError.OPENPGP_ENCRYPTED_BUT_INCOMPLETE, null, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void multipartEncrypted__withUnknownProtocol__shouldReturnEncryptedUnsupported() throws Exception {
|
||||||
|
MimeMessage message = new MimeMessage();
|
||||||
|
message.setUid("msguid");
|
||||||
|
message.setHeader("Content-Type", "multipart/encrypted; protocol=\"unknown protocol\"");
|
||||||
|
message.setBody(new MimeMultipart("multipart/encrypted", "--------"));
|
||||||
|
|
||||||
|
MessageCryptoCallback messageCryptoCallback = mock(MessageCryptoCallback.class);
|
||||||
|
messageCryptoHelper.asyncStartOrResumeProcessingMessage(message, messageCryptoCallback, null);
|
||||||
|
|
||||||
|
assertPartAnnotationHasState(message, messageCryptoCallback, CryptoError.ENCRYPTED_BUT_UNSUPPORTED, null, null,
|
||||||
|
null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void multipartSigned__withUnknownProtocol__shouldReturnSignedUnsupported() throws Exception {
|
||||||
|
MimeMessage message = new MimeMessage();
|
||||||
|
message.setUid("msguid");
|
||||||
|
message.setHeader("Content-Type", "multipart/signed; protocol=\"unknown protocol\"");
|
||||||
|
message.setBody(new MimeMultipart("multipart/encrypted", "--------"));
|
||||||
|
|
||||||
|
MessageCryptoCallback messageCryptoCallback = mock(MessageCryptoCallback.class);
|
||||||
|
messageCryptoHelper.asyncStartOrResumeProcessingMessage(message, messageCryptoCallback, null);
|
||||||
|
|
||||||
|
assertPartAnnotationHasState(message, messageCryptoCallback, CryptoError.SIGNED_BUT_UNSUPPORTED, null, null,
|
||||||
|
null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void multipartSigned__shouldCallOpenPgpApiAsync() throws Exception {
|
||||||
|
BodyPart signedBodyPart = spy(new MimeBodyPart(new TextBody("text")));
|
||||||
|
BodyPart signatureBodyPart = new MimeBodyPart(new TextBody("text"));
|
||||||
|
|
||||||
|
Multipart messageBody = new MimeMultipart("boundary1");
|
||||||
|
messageBody.addBodyPart(signedBodyPart);
|
||||||
|
messageBody.addBodyPart(signatureBodyPart);
|
||||||
|
|
||||||
|
MimeMessage message = new MimeMessage();
|
||||||
|
message.setUid("msguid");
|
||||||
|
message.setHeader("Content-Type", "multipart/signed; protocol=\"application/pgp-signature\"");
|
||||||
|
message.setFrom(Address.parse("Test <test@example.org>")[0]);
|
||||||
|
message.setBody(messageBody);
|
||||||
|
|
||||||
|
OutputStream outputStream = mock(OutputStream.class);
|
||||||
|
|
||||||
|
|
||||||
|
processSignedMessageAndCaptureMocks(message, signedBodyPart, outputStream);
|
||||||
|
|
||||||
|
|
||||||
|
assertEquals(OpenPgpApi.ACTION_DECRYPT_VERIFY, capturedApiIntent.getAction());
|
||||||
|
assertEquals("test@example.org", capturedApiIntent.getStringExtra(OpenPgpApi.EXTRA_SENDER_ADDRESS));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void multipartEncrypted__shouldCallOpenPgpApiAsync() throws Exception {
|
||||||
|
BodyPart dummyBodyPart = new MimeBodyPart(new TextBody("text"));
|
||||||
|
Body encryptedBody = spy(new TextBody("encrypted data"));
|
||||||
|
BodyPart encryptedBodyPart = spy(new MimeBodyPart(encryptedBody));
|
||||||
|
|
||||||
|
Multipart messageBody = new MimeMultipart("boundary1");
|
||||||
|
messageBody.addBodyPart(dummyBodyPart);
|
||||||
|
messageBody.addBodyPart(encryptedBodyPart);
|
||||||
|
|
||||||
|
MimeMessage message = new MimeMessage();
|
||||||
|
message.setUid("msguid");
|
||||||
|
message.setHeader("Content-Type", "multipart/encrypted; protocol=\"application/pgp-encrypted\"");
|
||||||
|
message.setFrom(Address.parse("Test <test@example.org>")[0]);
|
||||||
|
message.setBody(messageBody);
|
||||||
|
|
||||||
|
OutputStream outputStream = mock(OutputStream.class);
|
||||||
|
|
||||||
|
Intent resultIntent = new Intent();
|
||||||
|
resultIntent.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
|
||||||
|
OpenPgpDecryptionResult decryptionResult = mock(OpenPgpDecryptionResult.class);
|
||||||
|
resultIntent.putExtra(OpenPgpApi.RESULT_DECRYPTION, decryptionResult);
|
||||||
|
OpenPgpSignatureResult signatureResult = mock(OpenPgpSignatureResult.class);
|
||||||
|
resultIntent.putExtra(OpenPgpApi.RESULT_SIGNATURE, signatureResult);
|
||||||
|
PendingIntent pendingIntent = mock(PendingIntent.class);
|
||||||
|
resultIntent.putExtra(OpenPgpApi.RESULT_INTENT, pendingIntent);
|
||||||
|
|
||||||
|
|
||||||
|
processEncryptedMessageAndCaptureMocks(message, encryptedBody, outputStream);
|
||||||
|
|
||||||
|
MimeBodyPart decryptedPart = new MimeBodyPart(new TextBody("text"));
|
||||||
|
capturedCallback.onReturn(resultIntent, decryptedPart);
|
||||||
|
|
||||||
|
|
||||||
|
assertEquals(OpenPgpApi.ACTION_DECRYPT_VERIFY, capturedApiIntent.getAction());
|
||||||
|
assertEquals("test@example.org", capturedApiIntent.getStringExtra(OpenPgpApi.EXTRA_SENDER_ADDRESS));
|
||||||
|
assertPartAnnotationHasState(message, messageCryptoCallback, CryptoError.OPENPGP_OK, decryptedPart,
|
||||||
|
decryptionResult, signatureResult, pendingIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processEncryptedMessageAndCaptureMocks(Message message, Body encryptedBody, OutputStream outputStream)
|
||||||
|
throws Exception {
|
||||||
|
messageCryptoHelper.asyncStartOrResumeProcessingMessage(message, messageCryptoCallback, null);
|
||||||
|
|
||||||
|
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
|
||||||
|
ArgumentCaptor<OpenPgpDataSource> dataSourceCaptor = ArgumentCaptor.forClass(OpenPgpDataSource.class);
|
||||||
|
ArgumentCaptor<IOpenPgpSinkResultCallback> callbackCaptor = ArgumentCaptor.forClass(IOpenPgpSinkResultCallback.class);
|
||||||
|
verify(openPgpApi).executeApiAsync(intentCaptor.capture(), dataSourceCaptor.capture(),
|
||||||
|
any(OpenPgpDataSink.class), callbackCaptor.capture());
|
||||||
|
|
||||||
|
capturedApiIntent = intentCaptor.getValue();
|
||||||
|
capturedCallback = callbackCaptor.getValue();
|
||||||
|
|
||||||
|
OpenPgpDataSource dataSource = dataSourceCaptor.getValue();
|
||||||
|
dataSource.writeTo(outputStream);
|
||||||
|
verify(encryptedBody).writeTo(outputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processSignedMessageAndCaptureMocks(Message message, BodyPart signedBodyPart,
|
||||||
|
OutputStream outputStream) throws Exception {
|
||||||
|
messageCryptoHelper.asyncStartOrResumeProcessingMessage(message, messageCryptoCallback, null);
|
||||||
|
|
||||||
|
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
|
||||||
|
ArgumentCaptor<OpenPgpDataSource> dataSourceCaptor = ArgumentCaptor.forClass(OpenPgpDataSource.class);
|
||||||
|
ArgumentCaptor<IOpenPgpSinkResultCallback> callbackCaptor = ArgumentCaptor.forClass(IOpenPgpSinkResultCallback.class);
|
||||||
|
verify(openPgpApi).executeApiAsync(intentCaptor.capture(), dataSourceCaptor.capture(),
|
||||||
|
callbackCaptor.capture());
|
||||||
|
|
||||||
|
capturedApiIntent = intentCaptor.getValue();
|
||||||
|
capturedCallback = callbackCaptor.getValue();
|
||||||
|
|
||||||
|
OpenPgpDataSource dataSource = dataSourceCaptor.getValue();
|
||||||
|
dataSource.writeTo(outputStream);
|
||||||
|
verify(signedBodyPart).writeTo(outputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertPartAnnotationHasState(Message message, MessageCryptoCallback messageCryptoCallback,
|
||||||
|
CryptoError cryptoErrorState, MimeBodyPart replacementPart, OpenPgpDecryptionResult openPgpDecryptionResult,
|
||||||
|
OpenPgpSignatureResult openPgpSignatureResult, PendingIntent openPgpPendingIntent) {
|
||||||
|
ArgumentCaptor<MessageCryptoAnnotations> captor = ArgumentCaptor.forClass(MessageCryptoAnnotations.class);
|
||||||
|
verify(messageCryptoCallback).onCryptoOperationsFinished(captor.capture());
|
||||||
|
MessageCryptoAnnotations annotations = captor.getValue();
|
||||||
|
CryptoResultAnnotation cryptoResultAnnotation = annotations.get(message);
|
||||||
|
assertEquals(cryptoErrorState, cryptoResultAnnotation.getErrorType());
|
||||||
|
if (replacementPart != null) {
|
||||||
|
assertSame(replacementPart, cryptoResultAnnotation.getReplacementData());
|
||||||
|
}
|
||||||
|
assertSame(openPgpDecryptionResult, cryptoResultAnnotation.getOpenPgpDecryptionResult());
|
||||||
|
assertSame(openPgpSignatureResult, cryptoResultAnnotation.getOpenPgpSignatureResult());
|
||||||
|
assertSame(openPgpPendingIntent, cryptoResultAnnotation.getOpenPgpPendingIntent());
|
||||||
|
verifyNoMoreInteractions(messageCryptoCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue