obtain crypto status through dry-run signencrypt call

This commit is contained in:
Vincent Breitmoser 2017-03-27 11:57:57 +02:00
parent 99786e0884
commit cfb7a53cd4
8 changed files with 236 additions and 115 deletions

View file

@ -647,12 +647,11 @@ public class MessageCompose extends K9Activity implements OnClickListener,
builder = SimpleMessageBuilder.newInstance();
}
recipientPresenter.builderSetProperties(builder);
builder.setSubject(Utility.stripNewLines(subjectView.getText().toString()))
.setSentDate(new Date())
.setHideTimeZone(K9.hideTimeZone())
.setTo(recipientPresenter.getToAddresses())
.setCc(recipientPresenter.getCcAddresses())
.setBcc(recipientPresenter.getBccAddresses())
.setInReplyTo(repliedToMessageId)
.setReferences(referencedMessageIds)
.setRequestReadReceipt(requestReadReceipt)

View file

@ -8,8 +8,8 @@ import com.fsck.k9.activity.compose.RecipientMvpView.CryptoSpecialModeDisplayTyp
import com.fsck.k9.activity.compose.RecipientMvpView.CryptoStatusDisplayType;
import com.fsck.k9.activity.compose.RecipientPresenter.CryptoMode;
import com.fsck.k9.activity.compose.RecipientPresenter.CryptoProviderState;
import com.fsck.k9.message.PgpMessageBuilder.CryptoProviderDryRunStatus;
import com.fsck.k9.view.RecipientSelectView.Recipient;
import com.fsck.k9.view.RecipientSelectView.RecipientCryptoStatus;
/** This is an immutable object which contains all relevant metadata entered
* during e-mail composition to apply cryptographic operations before sending
@ -19,25 +19,16 @@ public class ComposeCryptoStatus {
private CryptoProviderState cryptoProviderState;
private CryptoMode cryptoMode;
private boolean allKeysAvailable;
private boolean allKeysVerified;
private boolean hasRecipients;
private Long signingKeyId;
private Long selfEncryptKeyId;
private String[] recipientAddresses;
private boolean enablePgpInline;
private CryptoMode cryptoMode;
private CryptoProviderDryRunStatus cryptoProviderDryRunStatus;
public long[] getEncryptKeyIds() {
if (selfEncryptKeyId == null) {
return null;
}
return new long[] { selfEncryptKeyId };
}
public String[] getRecipientAddresses() {
return recipientAddresses;
boolean isCryptoStatusRecipientDependent() {
return cryptoProviderState == CryptoProviderState.OK && cryptoMode != CryptoMode.DISABLE;
}
public Long getSigningKeyId() {
@ -60,22 +51,34 @@ public class ComposeCryptoStatus {
throw new AssertionError("all CryptoProviderStates must be handled!");
}
if (cryptoMode == CryptoMode.DISABLE) {
return CryptoStatusDisplayType.DISABLED;
}
if (cryptoProviderDryRunStatus == null) {
throw new IllegalStateException("Display type must be obtained from provider!");
}
if (cryptoProviderDryRunStatus == CryptoProviderDryRunStatus.ERROR) {
return CryptoStatusDisplayType.ERROR;
}
switch (cryptoMode) {
case PRIVATE:
if (!hasRecipients) {
if (cryptoProviderDryRunStatus == CryptoProviderDryRunStatus.NO_RECIPIENTS) {
return CryptoStatusDisplayType.PRIVATE_EMPTY;
} else if (allKeysAvailable && allKeysVerified) {
} else if (cryptoProviderDryRunStatus == CryptoProviderDryRunStatus.OK_KEYS_CONFIRMED) {
return CryptoStatusDisplayType.PRIVATE_TRUSTED;
} else if (allKeysAvailable) {
} else if (cryptoProviderDryRunStatus == CryptoProviderDryRunStatus.OK_KEYS_UNCONFIRMED) {
return CryptoStatusDisplayType.PRIVATE_UNTRUSTED;
}
return CryptoStatusDisplayType.PRIVATE_NOKEY;
case OPPORTUNISTIC:
if (!hasRecipients) {
if (cryptoProviderDryRunStatus == CryptoProviderDryRunStatus.NO_RECIPIENTS) {
return CryptoStatusDisplayType.OPPORTUNISTIC_EMPTY;
} else if (allKeysAvailable && allKeysVerified) {
} else if (cryptoProviderDryRunStatus == CryptoProviderDryRunStatus.OK_KEYS_CONFIRMED) {
return CryptoStatusDisplayType.OPPORTUNISTIC_TRUSTED;
} else if (allKeysAvailable) {
} else if (cryptoProviderDryRunStatus == CryptoProviderDryRunStatus.OK_KEYS_UNCONFIRMED) {
return CryptoStatusDisplayType.OPPORTUNISTIC_UNTRUSTED;
}
return CryptoStatusDisplayType.OPPORTUNISTIC_NOKEY;
@ -120,12 +123,12 @@ public class ComposeCryptoStatus {
return cryptoMode == CryptoMode.OPPORTUNISTIC;
}
public boolean isSignOnly() {
boolean isSignOnly() {
return cryptoMode == CryptoMode.SIGN_ONLY;
}
public boolean isSigningEnabled() {
return cryptoMode != CryptoMode.DISABLE && signingKeyId != null;
return cryptoMode != CryptoMode.DISABLE;
}
public boolean isPgpInlineModeEnabled() {
@ -140,6 +143,14 @@ public class ComposeCryptoStatus {
return cryptoProviderState == CryptoProviderState.OK;
}
public String[] getRecipientAddresses() {
return recipientAddresses;
}
public boolean hasRecipients() {
return recipientAddresses.length > 0;
}
public static class ComposeCryptoStatusBuilder {
private CryptoProviderState cryptoProviderState;
@ -159,12 +170,12 @@ public class ComposeCryptoStatus {
return this;
}
public ComposeCryptoStatusBuilder setSigningKeyId(long signingKeyId) {
public ComposeCryptoStatusBuilder setSigningKeyId(Long signingKeyId) {
this.signingKeyId = signingKeyId;
return this;
}
public ComposeCryptoStatusBuilder setSelfEncryptId(long selfEncryptKeyId) {
public ComposeCryptoStatusBuilder setSelfEncryptId(Long selfEncryptKeyId) {
this.selfEncryptKeyId = selfEncryptKeyId;
return this;
}
@ -194,28 +205,14 @@ public class ComposeCryptoStatus {
}
ArrayList<String> recipientAddresses = new ArrayList<>();
boolean allKeysAvailable = true;
boolean allKeysVerified = true;
boolean hasRecipients = !recipients.isEmpty();
for (Recipient recipient : recipients) {
RecipientCryptoStatus cryptoStatus = recipient.getCryptoStatus();
recipientAddresses.add(recipient.address.getAddress());
if (cryptoStatus.isAvailable()) {
if (cryptoStatus == RecipientCryptoStatus.AVAILABLE_UNTRUSTED) {
allKeysVerified = false;
}
} else {
allKeysAvailable = false;
}
}
ComposeCryptoStatus result = new ComposeCryptoStatus();
result.cryptoProviderState = cryptoProviderState;
result.cryptoMode = cryptoMode;
result.recipientAddresses = recipientAddresses.toArray(new String[0]);
result.allKeysAvailable = allKeysAvailable;
result.allKeysVerified = allKeysVerified;
result.hasRecipients = hasRecipients;
result.signingKeyId = signingKeyId;
result.selfEncryptKeyId = selfEncryptKeyId;
result.enablePgpInline = enablePgpInline;
@ -223,8 +220,20 @@ public class ComposeCryptoStatus {
}
}
ComposeCryptoStatus withCryptoProviderRecipientStatus(CryptoProviderDryRunStatus cryptoProviderDryRunStatus) {
ComposeCryptoStatus result = new ComposeCryptoStatus();
result.cryptoProviderState = cryptoProviderState;
result.cryptoMode = cryptoMode;
result.recipientAddresses = recipientAddresses;
result.signingKeyId = signingKeyId;
result.selfEncryptKeyId = selfEncryptKeyId;
result.enablePgpInline = enablePgpInline;
result.cryptoProviderDryRunStatus = cryptoProviderDryRunStatus;
return result;
}
public enum SendErrorState {
PROVIDER_ERROR, SIGN_KEY_NOT_CONFIGURED, PRIVATE_BUT_MISSING_KEYS
PROVIDER_ERROR
}
public SendErrorState getSendErrorStateOrNull() {
@ -232,14 +241,6 @@ public class ComposeCryptoStatus {
// TODO: be more specific about this error
return SendErrorState.PROVIDER_ERROR;
}
boolean isSignKeyMissing = signingKeyId == null;
if (isSignKeyMissing) {
return SendErrorState.SIGN_KEY_NOT_CONFIGURED;
}
boolean isPrivateModeAndNotAllKeysAvailable = cryptoMode == CryptoMode.PRIVATE && !allKeysAvailable;
if (isPrivateModeAndNotAllKeysAvailable) {
return SendErrorState.PRIVATE_BUT_MISSING_KEYS;
}
return null;
}

View file

@ -36,7 +36,9 @@ import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.Message.RecipientType;
import com.fsck.k9.message.ComposePgpInlineDecider;
import com.fsck.k9.message.MessageBuilder;
import com.fsck.k9.message.PgpMessageBuilder;
import com.fsck.k9.message.PgpMessageBuilder.CryptoProviderDryRunStatus;
import com.fsck.k9.view.RecipientSelectView.Recipient;
import org.openintents.openpgp.IOpenPgpService2;
import org.openintents.openpgp.util.OpenPgpApi;
@ -69,9 +71,9 @@ public class RecipientPresenter implements PermissionPingCallback {
private Account account;
private String openPgpProvider;
private Boolean hasContactPicker;
private ComposeCryptoStatus cachedCryptoStatus;
private PendingIntent pendingUserInteractionIntent;
private CryptoProviderState cryptoProviderState = CryptoProviderState.UNCONFIGURED;
private ComposeCryptoStatus cachedCryptoStatus;
private OpenPgpServiceConnection openPgpServiceConnection;
@ -352,38 +354,42 @@ public class RecipientPresenter implements PermissionPingCallback {
pendingUserInteractionIntent = null;
}
recipientMvpView.showCryptoStatus(getCurrentCryptoStatus().getCryptoStatusDisplayType());
recipientMvpView.showCryptoSpecialMode(getCurrentCryptoStatus().getCryptoSpecialModeDisplayType());
Long accountCryptoKey = account.getCryptoKey();
if (accountCryptoKey == Account.NO_OPENPGP_KEY) {
accountCryptoKey = null;
}
ComposeCryptoStatus composeCryptoStatus = new ComposeCryptoStatusBuilder()
.setCryptoProviderState(cryptoProviderState)
.setCryptoMode(currentCryptoMode)
.setEnablePgpInline(cryptoEnablePgpInline)
.setRecipients(getAllRecipients())
.setSigningKeyId(accountCryptoKey)
.setSelfEncryptId(accountCryptoKey)
.build();
if (composeCryptoStatus.isCryptoStatusRecipientDependent()) {
PgpMessageBuilder pgpMessageBuilder = PgpMessageBuilder.newInstance();
builderSetProperties(pgpMessageBuilder);
pgpMessageBuilder.setCryptoStatus(composeCryptoStatus);
CryptoProviderDryRunStatus cryptoProviderDryRunStatus =
pgpMessageBuilder.retrieveCryptoProviderRecipientStatus();
composeCryptoStatus = composeCryptoStatus.withCryptoProviderRecipientStatus(cryptoProviderDryRunStatus);
}
cachedCryptoStatus = composeCryptoStatus;
recipientMvpView.showCryptoStatus(composeCryptoStatus.getCryptoStatusDisplayType());
recipientMvpView.showCryptoSpecialMode(composeCryptoStatus.getCryptoSpecialModeDisplayType());
}
public ComposeCryptoStatus getCurrentCryptoStatus() {
if (cachedCryptoStatus == null) {
ComposeCryptoStatusBuilder builder = new ComposeCryptoStatusBuilder()
.setCryptoProviderState(cryptoProviderState)
.setCryptoMode(currentCryptoMode)
.setEnablePgpInline(cryptoEnablePgpInline)
.setRecipients(getAllRecipients());
long accountCryptoKey = account.getCryptoKey();
if (accountCryptoKey != Account.NO_OPENPGP_KEY) {
// TODO split these into individual settings? maybe after key is bound to identity
builder.setSigningKeyId(accountCryptoKey);
builder.setSelfEncryptId(accountCryptoKey);
}
cachedCryptoStatus = builder.build();
}
return cachedCryptoStatus;
}
public boolean isForceTextMessageFormat() {
if (cryptoEnablePgpInline) {
ComposeCryptoStatus cryptoStatus = getCurrentCryptoStatus();
return cryptoStatus.isEncryptionEnabled() || cryptoStatus.isSigningEnabled();
} else {
return false;
}
return cryptoEnablePgpInline;
}
void onToTokenAdded() {
@ -589,12 +595,6 @@ public class RecipientPresenter implements PermissionPingCallback {
case PROVIDER_ERROR:
recipientMvpView.showErrorOpenPgpConnection();
break;
case SIGN_KEY_NOT_CONFIGURED:
recipientMvpView.showErrorMissingSignKey();
break;
case PRIVATE_BUT_MISSING_KEYS:
recipientMvpView.showErrorPrivateButMissingKeys();
break;
default:
throw new AssertionError("not all error states handled, this is a bug!");
}
@ -720,9 +720,16 @@ public class RecipientPresenter implements PermissionPingCallback {
}
public void builderSetProperties(PgpMessageBuilder pgpBuilder) {
pgpBuilder.setOpenPgpApi(getOpenPgpApi());
pgpBuilder.setCryptoStatus(getCurrentCryptoStatus());
public void builderSetProperties(MessageBuilder messageBuilder) {
messageBuilder.setTo(getToAddresses());
messageBuilder.setCc(getCcAddresses());
messageBuilder.setBcc(getBccAddresses());
if (messageBuilder instanceof PgpMessageBuilder) {
PgpMessageBuilder pgpMessageBuilder = (PgpMessageBuilder) messageBuilder;
pgpMessageBuilder.setOpenPgpApi(getOpenPgpApi());
pgpMessageBuilder.setCryptoStatus(getCurrentCryptoStatus());
}
}
public void onMenuSetPgpInline(boolean enablePgpInline) {
@ -773,10 +780,9 @@ public class RecipientPresenter implements PermissionPingCallback {
}
void onClickCryptoSpecialModeIndicator() {
ComposeCryptoStatus currentCryptoStatus = getCurrentCryptoStatus();
if (currentCryptoStatus.isSignOnly()) {
if (currentCryptoMode == CryptoMode.SIGN_ONLY) {
recipientMvpView.showOpenPgpSignOnlyDialog(false);
} else if (currentCryptoStatus.isPgpInlineModeEnabled()) {
} else if (cryptoEnablePgpInline) {
recipientMvpView.showOpenPgpInlineDialog(false);
} else {
throw new IllegalStateException("This icon should not be clickable while no special mode is active!");
@ -804,7 +810,7 @@ public class RecipientPresenter implements PermissionPingCallback {
PRIVATE,
}
public static interface RecipientsChangedListener {
public void onRecipientsChanged();
public interface RecipientsChangedListener {
void onRecipientsChanged();
}
}

View file

@ -113,6 +113,10 @@ public class PgpMessageBuilder extends MessageBuilder {
throw new MessagingException("Attachments are not supported in PGP/INLINE format!");
}
if (shouldEncrypt && !cryptoStatus.hasRecipients()) {
throw new MessagingException("Must have recipients to build message!");
}
if (pgpApiIntent == null) {
pgpApiIntent = buildOpenPgpApiIntent(shouldSign, shouldEncrypt, isPgpInlineMode);
}
@ -131,8 +135,7 @@ public class PgpMessageBuilder extends MessageBuilder {
}
@NonNull
private Intent buildOpenPgpApiIntent(boolean shouldSign, boolean shouldEncrypt, boolean isPgpInlineMode)
throws MessagingException {
private Intent buildOpenPgpApiIntent(boolean shouldSign, boolean shouldEncrypt, boolean isPgpInlineMode) {
Intent pgpApiIntent;
if (shouldEncrypt) {
if (!shouldSign) {
@ -141,18 +144,8 @@ public class PgpMessageBuilder extends MessageBuilder {
// pgpApiIntent = new Intent(shouldSign ? OpenPgpApi.ACTION_SIGN_AND_ENCRYPT : OpenPgpApi.ACTION_ENCRYPT);
pgpApiIntent = new Intent(OpenPgpApi.ACTION_SIGN_AND_ENCRYPT);
long[] encryptKeyIds = cryptoStatus.getEncryptKeyIds();
if (encryptKeyIds != null) {
pgpApiIntent.putExtra(OpenPgpApi.EXTRA_KEY_IDS, encryptKeyIds);
}
if(!isDraft()) {
String[] encryptRecipientAddresses = cryptoStatus.getRecipientAddresses();
boolean hasRecipientAddresses = encryptRecipientAddresses != null && encryptRecipientAddresses.length > 0;
if (!hasRecipientAddresses) {
throw new MessagingException("encryption is enabled, but no recipient specified!");
}
pgpApiIntent.putExtra(OpenPgpApi.EXTRA_USER_IDS, encryptRecipientAddresses);
pgpApiIntent.putExtra(OpenPgpApi.EXTRA_USER_IDS, cryptoStatus.getRecipientAddresses());
pgpApiIntent.putExtra(OpenPgpApi.EXTRA_OPPORTUNISTIC_ENCRYPTION, cryptoStatus.isEncryptionOpportunistic());
}
} else {
@ -333,4 +326,47 @@ public class PgpMessageBuilder extends MessageBuilder {
public void setCryptoStatus(ComposeCryptoStatus cryptoStatus) {
this.cryptoStatus = cryptoStatus;
}
public CryptoProviderDryRunStatus retrieveCryptoProviderRecipientStatus() {
boolean shouldSign = cryptoStatus.isSigningEnabled();
boolean shouldEncrypt = cryptoStatus.isEncryptionEnabled();
boolean isPgpInlineMode = cryptoStatus.isPgpInlineModeEnabled();
Intent apiIntent = buildOpenPgpApiIntent(shouldSign, shouldEncrypt, isPgpInlineMode);
apiIntent.putExtra(OpenPgpApi.EXTRA_DRY_RUN, true);
Intent result = openPgpApi.executeApi(apiIntent, (InputStream) null, null);
switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) {
case OpenPgpApi.RESULT_CODE_SUCCESS:
if (result.getBooleanExtra(OpenPgpApi.RESULT_KEYS_CONFIRMED, false)) {
return CryptoProviderDryRunStatus.OK_KEYS_CONFIRMED;
} else {
return CryptoProviderDryRunStatus.OK_KEYS_UNCONFIRMED;
}
case OpenPgpApi.RESULT_CODE_ERROR:
OpenPgpError error = result.getParcelableExtra(OpenPgpApi.RESULT_ERROR);
if (error == null) {
return CryptoProviderDryRunStatus.ERROR;
}
switch (error.getErrorId()) {
case OpenPgpError.NO_USER_IDS:
return CryptoProviderDryRunStatus.NO_RECIPIENTS;
case OpenPgpError.OPPORTUNISTIC_MISSING_KEYS:
return CryptoProviderDryRunStatus.OK_KEYS_MISSING;
}
case OpenPgpApi.RESULT_CODE_USER_INTERACTION_REQUIRED:
// should never happen, so treat as error!
default:
return CryptoProviderDryRunStatus.ERROR;
}
}
public enum CryptoProviderDryRunStatus {
NO_RECIPIENTS,
OK_KEYS_MISSING,
OK_KEYS_UNCONFIRMED,
OK_KEYS_CONFIRMED,
ERROR
}
}

View file

@ -110,7 +110,7 @@
tools:visibility="visible"
android:inAnimation="@anim/fade_in"
android:outAnimation="@anim/fade_out"
custom:previewInitialChild="2">
custom:previewInitialChild="7">
<ImageView
android:layout_width="wrap_content"
@ -246,6 +246,14 @@
</FrameLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/status_lock_opportunistic"
android:tint="?attr/openpgp_grey"
/>
</com.fsck.k9.view.ToolableViewAnimator>
</LinearLayout>

View file

@ -26,6 +26,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openintents.openpgp.IOpenPgpService2;
import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.util.OpenPgpApi;
import org.openintents.openpgp.util.OpenPgpServiceConnection;
import org.openintents.openpgp.util.ShadowOpenPgpAsyncTask;
@ -60,6 +61,7 @@ public class RecipientPresenterTest {
private Account account;
private RecipientMvpView recipientMvpView;
private RecipientPresenter.RecipientsChangedListener listener;
private Intent noUserIdsResultIntent;
@Before
@ -76,6 +78,11 @@ public class RecipientPresenterTest {
recipientPresenter = new RecipientPresenter(
context, loaderManager, recipientMvpView, account, composePgpInlineDecider, replyToParser, listener);
recipientPresenter.updateCryptoStatus();
noUserIdsResultIntent = new Intent();
noUserIdsResultIntent.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
noUserIdsResultIntent.putExtra(
OpenPgpApi.RESULT_ERROR, new OpenPgpError(OpenPgpError.NO_USER_IDS, "dummy error msg"));
}
@Test
@ -124,7 +131,7 @@ public class RecipientPresenterTest {
@Test
public void getCurrentCryptoStatus_withCryptoProvider() throws Exception {
setupCryptoProvider();
setupCryptoProvider(noUserIdsResultIntent);
ComposeCryptoStatus status = recipientPresenter.getCurrentCryptoStatus();
@ -134,8 +141,8 @@ public class RecipientPresenterTest {
}
@Test
public void getCurrentCryptoStatus_withOpportunistic() throws Exception {
setupCryptoProvider();
public void getCurrentCryptoStatus_withOpportunisticEmpty() throws Exception {
setupCryptoProvider(noUserIdsResultIntent);
recipientPresenter.onCryptoModeChanged(CryptoMode.OPPORTUNISTIC);
ComposeCryptoStatus status = recipientPresenter.getCurrentCryptoStatus();
@ -145,9 +152,71 @@ public class RecipientPresenterTest {
assertTrue(status.shouldUsePgpMessageBuilder());
}
@Test
public void getCurrentCryptoStatus_withOpportunistic() throws Exception {
Intent resultIntent = new Intent();
resultIntent.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
resultIntent.putExtra(OpenPgpApi.RESULT_KEYS_CONFIRMED, false);
setupCryptoProvider(resultIntent);
recipientPresenter.onCryptoModeChanged(CryptoMode.OPPORTUNISTIC);
ComposeCryptoStatus status = recipientPresenter.getCurrentCryptoStatus();
assertEquals(CryptoStatusDisplayType.OPPORTUNISTIC_UNTRUSTED, status.getCryptoStatusDisplayType());
assertTrue(status.isProviderStateOk());
assertTrue(status.shouldUsePgpMessageBuilder());
}
@Test
public void getCurrentCryptoStatus_withOpportunistic__missingKeys() throws Exception {
Intent resultIntent = new Intent();
resultIntent.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
resultIntent.putExtra(OpenPgpApi.RESULT_ERROR, new OpenPgpError(OpenPgpError.OPPORTUNISTIC_MISSING_KEYS,
"dummy error msg"));
setupCryptoProvider(resultIntent);
recipientPresenter.onCryptoModeChanged(CryptoMode.OPPORTUNISTIC);
ComposeCryptoStatus status = recipientPresenter.getCurrentCryptoStatus();
assertEquals(CryptoStatusDisplayType.OPPORTUNISTIC_NOKEY, status.getCryptoStatusDisplayType());
assertTrue(status.isProviderStateOk());
assertTrue(status.shouldUsePgpMessageBuilder());
}
@Test
public void getCurrentCryptoStatus_withOpportunistic__privateMissingKeys() throws Exception {
Intent resultIntent = new Intent();
resultIntent.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR);
resultIntent.putExtra(OpenPgpApi.RESULT_ERROR, new OpenPgpError(OpenPgpError.OPPORTUNISTIC_MISSING_KEYS,
"dummy error msg"));
setupCryptoProvider(resultIntent);
recipientPresenter.onCryptoModeChanged(CryptoMode.PRIVATE);
ComposeCryptoStatus status = recipientPresenter.getCurrentCryptoStatus();
assertEquals(CryptoStatusDisplayType.PRIVATE_NOKEY, status.getCryptoStatusDisplayType());
assertTrue(status.isProviderStateOk());
assertTrue(status.shouldUsePgpMessageBuilder());
}
@Test
public void getCurrentCryptoStatus_withOpportunistic__confirmed() throws Exception {
Intent resultIntent = new Intent();
resultIntent.putExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_SUCCESS);
resultIntent.putExtra(OpenPgpApi.RESULT_KEYS_CONFIRMED, true);
setupCryptoProvider(resultIntent);
recipientPresenter.onCryptoModeChanged(CryptoMode.OPPORTUNISTIC);
ComposeCryptoStatus status = recipientPresenter.getCurrentCryptoStatus();
assertEquals(CryptoStatusDisplayType.OPPORTUNISTIC_TRUSTED, status.getCryptoStatusDisplayType());
assertTrue(status.isProviderStateOk());
assertTrue(status.shouldUsePgpMessageBuilder());
}
@Test
public void getCurrentCryptoStatus_withModeDisabled() throws Exception {
setupCryptoProvider();
setupCryptoProvider(noUserIdsResultIntent);
recipientPresenter.onCryptoModeChanged(CryptoMode.DISABLE);
ComposeCryptoStatus status = recipientPresenter.getCurrentCryptoStatus();
@ -159,7 +228,7 @@ public class RecipientPresenterTest {
@Test
public void getCurrentCryptoStatus_withModePrivate() throws Exception {
setupCryptoProvider();
setupCryptoProvider(noUserIdsResultIntent);
recipientPresenter.onCryptoModeChanged(CryptoMode.PRIVATE);
ComposeCryptoStatus status = recipientPresenter.getCurrentCryptoStatus();
@ -171,7 +240,7 @@ public class RecipientPresenterTest {
@Test
public void getCurrentCryptoStatus_withModeSignOnly() throws Exception {
setupCryptoProvider();
setupCryptoProvider(noUserIdsResultIntent);
recipientPresenter.onMenuSetSignOnly(true);
ComposeCryptoStatus status = recipientPresenter.getCurrentCryptoStatus();
@ -184,7 +253,7 @@ public class RecipientPresenterTest {
@Test
public void getCurrentCryptoStatus_withModeInline() throws Exception {
setupCryptoProvider();
setupCryptoProvider(noUserIdsResultIntent);
recipientPresenter.onMenuSetPgpInline(true);
ComposeCryptoStatus status = recipientPresenter.getCurrentCryptoStatus();
@ -248,7 +317,7 @@ public class RecipientPresenterTest {
verify(listener).onRecipientsChanged();
}
private void setupCryptoProvider() throws android.os.RemoteException {
private void setupCryptoProvider(Intent returnedIntent) throws android.os.RemoteException {
Account account = mock(Account.class);
OpenPgpServiceConnection openPgpServiceConnection = mock(OpenPgpServiceConnection.class);
IOpenPgpService2 openPgpService2 = mock(IOpenPgpService2.class);
@ -260,7 +329,7 @@ public class RecipientPresenterTest {
when(openPgpServiceConnection.isBound()).thenReturn(true);
when(openPgpServiceConnection.getService()).thenReturn(openPgpService2);
when(openPgpService2.execute(any(Intent.class), any(ParcelFileDescriptor.class), any(Integer.class)))
.thenReturn(permissionPingIntent);
.thenReturn(permissionPingIntent, returnedIntent);
Robolectric.getBackgroundThreadScheduler().pause();
recipientPresenter.setOpenPgpServiceConnection(openPgpServiceConnection, CRYPTO_PROVIDER);

View file

@ -275,7 +275,6 @@ public class PgpMessageBuilderTest {
Intent expectedApiIntent = new Intent(OpenPgpApi.ACTION_SIGN_AND_ENCRYPT);
expectedApiIntent.putExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, TEST_SIGN_KEY_ID);
expectedApiIntent.putExtra(OpenPgpApi.EXTRA_KEY_IDS, new long[] { TEST_SELF_ENCRYPT_KEY_ID });
expectedApiIntent.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
expectedApiIntent.putExtra(OpenPgpApi.EXTRA_OPPORTUNISTIC_ENCRYPTION, false);
expectedApiIntent.putExtra(OpenPgpApi.EXTRA_USER_IDS, cryptoStatus.getRecipientAddresses());
@ -328,7 +327,6 @@ public class PgpMessageBuilderTest {
Intent expectedApiIntent = new Intent(OpenPgpApi.ACTION_SIGN_AND_ENCRYPT);
expectedApiIntent.putExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, TEST_SIGN_KEY_ID);
expectedApiIntent.putExtra(OpenPgpApi.EXTRA_KEY_IDS, new long[] { TEST_SELF_ENCRYPT_KEY_ID });
expectedApiIntent.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
expectedApiIntent.putExtra(OpenPgpApi.EXTRA_OPPORTUNISTIC_ENCRYPTION, false);
expectedApiIntent.putExtra(OpenPgpApi.EXTRA_USER_IDS, cryptoStatus.getRecipientAddresses());

View file

@ -256,6 +256,10 @@ public class OpenPgpApi {
public static final int AUTOCRYPT_STATUS_AVAILABLE = 2;
public static final int AUTOCRYPT_STATUS_MUTUAL = 3;
// TODO remove again
public static final String EXTRA_DRY_RUN = "dry_run";
public static final String RESULT_KEYS_CONFIRMED = "keys_confirmed";
// optional extras:
public static final String EXTRA_PASSPHRASE = "passphrase";
public static final String EXTRA_ORIGINAL_FILENAME = "original_filename";